diff --git a/.github/test.c b/.github/test.c index 28651ea..eb352f2 100644 --- a/.github/test.c +++ b/.github/test.c @@ -1,21 +1,24 @@ /* ** EPITECH PROJECT, 2026 -** mncc +** test.c ** File description: -** test +** Test file for the MNCC project */ -//this file is used to test the lexer and the tokenization of the input string - -#include "main.h" -#include "lexer/lexer.h" -#include "lexer/token.h" #include -#include -int main() +int get_ages_addition() { - return 4; + int william = 18; + int alessandro = 18; + return william + alessandro; } -//again a test file to test the lexer and the tokenization of the input string +int main() +{ + int factor = 0; + int diff = 3; + + factor = 2; + return diff + get_ages_addition() * factor; +} diff --git a/include/gen/gen.h b/include/gen/gen.h index fd6a293..b80ec95 100644 --- a/include/gen/gen.h +++ b/include/gen/gen.h @@ -11,20 +11,15 @@ #include "parser/parser.h" #include "utils/array.h" -typedef struct stack_data_s { +typedef struct variable_s { char *name; int offset; -} stack_data_t; - -typedef struct stack_s { - array_t *variables; - struct stack_s *parent; -} stack_t; +} variable_t; typedef struct gen_s { parser_t *parser; FILE *out; - stack_t *stack; + array_t *variables; } gen_t; gen_t *gen_create(char *filename, parser_t *parser); @@ -39,6 +34,7 @@ int gen_declaration(gen_t *gen, node_t *node); int gen_assignement(gen_t *gen, node_t *node); int gen_return(gen_t *gen, node_t *node); int gen_block(gen_t *gen, node_t *node); +int gen_call(gen_t *gen, node_t *node); // expression generation int gen_expression(gen_t *gen, node_t *node); diff --git a/include/parser/parser.h b/include/parser/parser.h index 718a908..1751148 100644 --- a/include/parser/parser.h +++ b/include/parser/parser.h @@ -38,6 +38,7 @@ node_t *parse_assignment(parser_t *parser); node_t *parse_function(parser_t *parser); node_t *parse_declaration(parser_t *parser); node_t *parse_block(parser_t *parser); +node_t *parse_call(parser_t *parser); // expression node_t *parse_expression(parser_t *parser); diff --git a/src/gen/expression/gen_call.c b/src/gen/expression/gen_call.c new file mode 100644 index 0000000..fca7097 --- /dev/null +++ b/src/gen/expression/gen_call.c @@ -0,0 +1,23 @@ +/* +** EPITECH PROJECT, 2026 +** gen_value.c +** File description: +** Generation of value nodes to assembly code +*/ +#include +#include "gen/gen.h" +#include "main.h" +#include "parser/node.h" + +int gen_call(gen_t *gen, node_t *node) +{ + for (int i = node->childs->count - 1; i >= 0; i--) { + if (gen_expression(gen, node->childs->data[i]) != SUCCESS) + return ERROR; + fprintf(gen->out, " push rax\n"); + } + fprintf(gen->out, " call %s\n", node->name); + + fprintf(gen->out, " add rsp, 0x%X\n", node->childs->count * 8); + return SUCCESS; +} diff --git a/src/gen/expression/gen_expression.c b/src/gen/expression/gen_expression.c index 8c664b8..19be911 100644 --- a/src/gen/expression/gen_expression.c +++ b/src/gen/expression/gen_expression.c @@ -17,8 +17,10 @@ int gen_expression(gen_t *gen, node_t *node) return gen_value(gen, node); case NODE_OPERATOR: return gen_operator(gen, node); + case NODE_CALL: + return gen_call(gen, node); default: - return get_error(EPAR, + return get_error(EGEN, "unsupported node type in expression: '%s'", node->name); } diff --git a/src/gen/expression/gen_operator.c b/src/gen/expression/gen_operator.c index 774615f..68fdf58 100644 --- a/src/gen/expression/gen_operator.c +++ b/src/gen/expression/gen_operator.c @@ -31,13 +31,18 @@ int gen_operator(gen_t *gen, node_t *node) char *op_str = get_operator_str(node->op); if (!op_str) { - get_error(EPAR, "invalid operator in code generation"); + get_error(EGEN, "invalid operator in code generation"); return ERROR; } - gen_expression(gen, node->left); - fprintf(gen->out, " push rax\n"); gen_expression(gen, node->right); + fprintf(gen->out, " push rax\n"); + gen_expression(gen, node->left); fprintf(gen->out, " pop rbx\n"); + if (node->op == OP_DIV) { + fprintf(gen->out, " xor rdx, rdx\n"); + fprintf(gen->out, " div rbx\n"); + return SUCCESS; + } fprintf(gen->out, " %s rax, rbx\n", op_str); return SUCCESS; } diff --git a/src/gen/expression/gen_value.c b/src/gen/expression/gen_value.c index 2abb0f7..793ec92 100644 --- a/src/gen/expression/gen_value.c +++ b/src/gen/expression/gen_value.c @@ -13,14 +13,14 @@ static int get_offset(gen_t *gen, const char *name) { - stack_data_t *data = NULL; + variable_t *data = NULL; - for (int i = 0; i < gen->stack->variables->count; i++) { - data = gen->stack->variables->data[i]; + for (int i = 0; i < gen->variables->count; i++) { + data = gen->variables->data[i]; if (strcmp(data->name, name) == 0) return data->offset; } - get_error(EPAR, "variable '%s' not found in stack", name); + get_error(EGEN, "variable '%s' not found in stack", name); return -1; } @@ -28,14 +28,18 @@ int gen_value(gen_t *gen, node_t *node) { int offset = 0; - if (node->type == NODE_CONST) + if (node->type == NODE_CONST) { fprintf(gen->out, " mov rax, %d\n", node->value); - return SUCCESS; + return SUCCESS; + } if (node->type == NODE_VAR) { offset = get_offset(gen, node->name); if (offset < 0) return ERROR; - fprintf(gen->out, " mov rax, [rbp - %d]\n", offset); + if (offset > 0) + fprintf(gen->out, " mov rax, [rbp - %d]\n", offset); + else + fprintf(gen->out, " mov rax, [rbp]\n"); } return SUCCESS; } diff --git a/src/gen/gen_create.c b/src/gen/gen_create.c index 8417576..0453aa1 100644 --- a/src/gen/gen_create.c +++ b/src/gen/gen_create.c @@ -9,22 +9,6 @@ #include "gen/gen.h" #include "utils/utils.h" -static stack_t *stack_create(void) -{ - stack_t *stack = malloc(sizeof(stack_t)); - - if (!stack) - return NULL; - stack->parent = NULL; - stack->variables = array_create((array_element_destroy_t)free); - if (!stack->variables) { - free(stack); - get_error(ENOMEM, "code generation stack allocation"); - return NULL; - } - return stack; -} - static FILE *open_file(const char *filename) { FILE *out = fopen(filename, "w"); @@ -50,10 +34,6 @@ gen_t *gen_create(char *filename, parser_t *parser) free(gen); return NULL; } - gen->stack = stack_create(); - if (!gen->stack) { - free(gen); - return NULL; - } + gen->variables = NULL; return gen; } diff --git a/src/gen/gen_destroy.c b/src/gen/gen_destroy.c index f7e3926..930c426 100644 --- a/src/gen/gen_destroy.c +++ b/src/gen/gen_destroy.c @@ -4,24 +4,13 @@ ** File description: ** Generation context destruction and memory cleanup */ -#include #include #include "gen/gen.h" -#include "utils/array.h" void gen_destroy(gen_t *gen) { - stack_t *stack = NULL; - if (!gen) return; - while (gen->stack) { - if (gen->stack->variables) - array_destroy(gen->stack->variables, 1); - stack = gen->stack->parent; - free(gen->stack); - gen->stack = stack; - } if (gen->out) fclose(gen->out); free(gen); diff --git a/src/gen/gen_function.c b/src/gen/gen_function.c index 2eb68b5..3e60a1d 100644 --- a/src/gen/gen_function.c +++ b/src/gen/gen_function.c @@ -4,17 +4,31 @@ ** File description: ** Generation of function node to assembly code */ +#include #include +#include #include "gen/gen.h" #include "main.h" #include "parser/node.h" +#include "utils/utils.h" int gen_function(gen_t *gen, node_t *node) { + variable_t *data = NULL; + + gen->variables = array_create((array_element_destroy_t)free); + if (!gen->variables) + return get_error(ENOMEM, "generator function variables allocation"); fprintf(gen->out, "%s:\n", node->name); fprintf(gen->out, " push rbp\n mov rbp, rsp\n"); gen_block(gen, node->childs->data[0]); - fprintf(gen->out, " pop rbp\n ret\n"); + fprintf(gen->out, " leave\n ret\n"); fprintf(gen->out, "\n"); + for (int i = 0; i < gen->variables->count; i++) { + data = gen->variables->data[i]; + free(data->name); + } + array_destroy(gen->variables, 1); + gen->variables = NULL; return SUCCESS; } diff --git a/src/gen/gen_header.c b/src/gen/gen_header.c index 5948b69..55c5c4f 100644 --- a/src/gen/gen_header.c +++ b/src/gen/gen_header.c @@ -10,7 +10,6 @@ int gen_header(gen_t *gen) { - printf("header\n"); if (fprintf(gen->out, "section .text\n") < 0) return ERROR; if (fprintf(gen->out, "\t\tglobal _start\n\n") < 0) diff --git a/src/gen/gen_run.c b/src/gen/gen_run.c index 4a6251e..e75ee8e 100644 --- a/src/gen/gen_run.c +++ b/src/gen/gen_run.c @@ -20,7 +20,7 @@ int gen_run(gen_t *gen) if (node->type == NODE_FUNCTION && gen_function(gen, node) != SUCCESS) return ERROR; if (node->type != NODE_FUNCTION) { - get_error(EPAR, + get_error(EGEN, "unsupported node type in global scope: '%s'", node->name); return ERROR; diff --git a/src/gen/instruction/gen_assignement.c b/src/gen/instruction/gen_assignement.c index 6ab263d..4a91510 100644 --- a/src/gen/instruction/gen_assignement.c +++ b/src/gen/instruction/gen_assignement.c @@ -13,25 +13,25 @@ static int get_offset(gen_t *gen, const char *name) { - stack_data_t *data = NULL; + variable_t *data = NULL; - for (int i = 0; i < gen->stack->variables->count; i++) { - data = gen->stack->variables->data[i]; + for (int i = 0; i < gen->variables->count; i++) { + data = gen->variables->data[i]; if (strcmp(data->name, name) == 0) return data->offset; } - get_error(EPAR, "variable '%s' not found in stack", name); + get_error(EGEN, "variable '%s' not found in stack", name); return -1; } int gen_assignement(gen_t *gen, node_t *node) { - int offset = get_offset(gen, node->name); + int offset = get_offset(gen, node->left->name); if (offset < 0) return ERROR; - if (gen_expression(gen, node->childs->data[0]) != SUCCESS) + if (gen_expression(gen, node->right) != SUCCESS) return ERROR; - fprintf(gen->out, " mov [rbp - %d], rax\n", offset); + fprintf(gen->out, " mov [rbp - 0x%X], rax\n", offset); return SUCCESS; } diff --git a/src/gen/instruction/gen_declaration.c b/src/gen/instruction/gen_declaration.c index ff914a7..2297d9a 100644 --- a/src/gen/instruction/gen_declaration.c +++ b/src/gen/instruction/gen_declaration.c @@ -7,29 +7,56 @@ #include #include #include +#include #include "gen/gen.h" #include "main.h" #include "parser/node.h" #include "utils/utils.h" +static int get_offset(gen_t *gen, const char *name) +{ + variable_t *data = NULL; + + for (int i = 0; i < gen->variables->count; i++) { + data = gen->variables->data[i]; + if (strcmp(data->name, name) == 0) + return data->offset; + } + get_error(EGEN, "variable '%s' not found in stack", name); + return -1; +} + static int create_variable(gen_t *gen, char *name) { - stack_data_t *data = malloc(sizeof(stack_data_t)); + variable_t *data = malloc(sizeof(variable_t)); if (!data) return get_error(ENOMEM, "stack variable allocation"); - data->name = name; - data->offset = gen->stack->variables->count * 8; - array_push(gen->stack->variables, data); + data->name = strdup(name); + data->offset = (gen->variables->count + 1) * 8; + array_push(gen->variables, data); return SUCCESS; } int gen_declaration(gen_t *gen, node_t *node) { + int offset = 0; + fprintf(gen->out, " sub rsp, 8\n"); - if (create_variable(gen, node->name) != SUCCESS) + if (!node->left || !node->left->name) + return get_error(EGEN, "declaration node missing variable name"); + if (create_variable(gen, node->left->name) != SUCCESS) return ERROR; - if (node->childs->count > 0) + if (!node->right) { + offset = get_offset(gen, node->left->name); + if (offset < 0) + return ERROR; + if (offset > 0) + fprintf(gen->out, " mov [rbp - 0x%X], 0\n", offset); + else + fprintf(gen->out, " mov [rbp], 0\n"); + } + if (node->right) return gen_assignement(gen, node); return SUCCESS; } diff --git a/src/gen/instruction/gen_instruction.c b/src/gen/instruction/gen_instruction.c index da71235..6bb5884 100644 --- a/src/gen/instruction/gen_instruction.c +++ b/src/gen/instruction/gen_instruction.c @@ -21,7 +21,7 @@ int gen_instruction(gen_t *gen, node_t *node) case NODE_BLOCK: return gen_block(gen, node); default: - return get_error(EPAR, + return get_error(EGEN, "unsupported node type in instruction: '%s'", node->name); } diff --git a/src/lexer/lexer_run.c b/src/lexer/lexer_run.c index 54c7e5a..0c2411b 100644 --- a/src/lexer/lexer_run.c +++ b/src/lexer/lexer_run.c @@ -12,87 +12,6 @@ #include #include -static const char *get_keyword_token_str(token_type_t type) -{ - if (type == TOK_INT) - return "TOK_INT"; - if (type == TOK_RETURN) - return "TOK_RETURN"; - if (type == TOK_IF) - return "TOK_IF"; - if (type == TOK_ELSE) - return "TOK_ELSE"; - if (type == TOK_WHILE) - return "TOK_WHILE"; - if (type == TOK_FOR) - return "TOK_FOR"; - if (type == TOK_IDENT) - return "TOK_IDENT"; - return NULL; -} - -static const char *get_operator_token_str(token_type_t type) -{ - if (type == TOK_EQ) - return "TOK_EQ"; - if (type == TOK_PLUS) - return "TOK_PLUS"; - if (type == TOK_MINUS) - return "TOK_MINUS"; - if (type == TOK_MUL) - return "TOK_MUL"; - if (type == TOK_DIV) - return "TOK_DIV"; - return NULL; -} - -static const char *get_punctuation_token_str(token_type_t type) -{ - if (type == TOK_SEMI) - return "TOK_SEMI"; - if (type == TOK_LPAREN) - return "TOK_LPAREN"; - if (type == TOK_RPAREN) - return "TOK_RPAREN"; - if (type == TOK_LBRACE) - return "TOK_LBRACE"; - if (type == TOK_RBRACE) - return "TOK_RBRACE"; - if (type == TOK_COMMA) - return "TOK_COMMA"; - if (type == TOK_EOF) - return "TOK_EOF"; - if (type == TOK_VOID) - return "TOK_VOID"; - if (type == TOK_NUMBER) - return "TOK_NUMBER"; - return "TOK_UNKNOWN"; -} - -static const char *get_token_type_str(token_type_t type) -{ - const char *str = get_keyword_token_str(type); - - if (!str) - str = get_operator_token_str(type); - if (!str) - str = get_punctuation_token_str(type); - return str; -} - -static int print_lexer(lexer_t *lexer) -{ - token_t *token = NULL; - - for (int i = 0; i < lexer->tokens->count; i++) { - token = (token_t *)lexer->tokens->data[i]; - printf("Token %d: Type=%s, Value='%s'\n", i, - get_token_type_str(token->type), token->value ? token->value : - "NULL"); - } - return SUCCESS; -} - int lexer_run(char *buffer, lexer_t *lexer) { if (lexer_tokenize(lexer, buffer) == ERROR) { @@ -100,5 +19,5 @@ int lexer_run(char *buffer, lexer_t *lexer) return ERROR; } free(buffer); - return print_lexer(lexer); + return SUCCESS; } diff --git a/src/parser/expression/parse_expression.c b/src/parser/expression/parse_expression.c index cf81b7b..56e88a9 100644 --- a/src/parser/expression/parse_expression.c +++ b/src/parser/expression/parse_expression.c @@ -25,8 +25,16 @@ static int is_value_token(token_t *token) return token->type == TOK_NUMBER || token->type == TOK_IDENT; } -static int is_expression_token(token_t *token) +static int is_expression_token(token_t *token, int *depth) { + if (token->type == TOK_LPAREN) { + (*depth)++; + return true; + } + if (token->type == TOK_RPAREN) { + (*depth)--; + return *depth >= 0; + } return is_operator_token(token) || is_value_token(token); } @@ -35,10 +43,11 @@ static int expression_size(parser_t *parser) int size = 0; int cursor = parser->cursor; token_t *token = NULL; + int depth = 0; while (true) { token = parser_peek(parser); - if (!token || !is_expression_token(token)) + if (!token || !is_expression_token(token, &depth)) break; size++; parser_next(parser); @@ -47,14 +56,39 @@ static int expression_size(parser_t *parser) return size; } +static bool contains_operator(parser_t *parser, int size) +{ + int cursor = parser->cursor; + token_t *token = NULL; + bool result = false; + + for (int i = 0; i < size; i++) { + token = parser_peek(parser); + if (is_operator_token(token)) { + result = true; + break; + } + parser_next(parser); + } + parser->cursor = cursor; + return result; +} + node_t *parse_sized_expression(parser_t *parser, int size) { node_t *node = NULL; + bool is_operator = contains_operator(parser, size); - if (size == 1) - node = parse_value(parser); - else + if (is_operator) { node = parse_operator(parser, size); + if (!node) { + get_error(EPAR, "invalid operator in expression '%s'", + parser_peek(parser) ? parser_peek(parser)->value + : "end of input"); + return NULL; + } + } else + node = parse_value(parser); if (!node) { get_error(EPAR, "invalid expression '%s'", diff --git a/src/parser/expression/parse_value.c b/src/parser/expression/parse_value.c index 0ec14dd..5c17d47 100644 --- a/src/parser/expression/parse_value.c +++ b/src/parser/expression/parse_value.c @@ -51,7 +51,9 @@ static node_t *get_value_node(parser_t *parser) if (token->type == TOK_NUMBER) node = create_const_node(token); if (token->type == TOK_IDENT && - parser_at(parser, parser->cursor + 1)->type == TOK_EQ) + parser_at(parser, parser->cursor + 1)->type == TOK_LPAREN) + node = parse_call(parser); + else if (token->type == TOK_IDENT) node = create_var_node(token); if (!node) { get_error(EPAR, diff --git a/src/parser/instruction/parse_assignment.c b/src/parser/instruction/parse_assignment.c index a2aa5f6..eff7484 100644 --- a/src/parser/instruction/parse_assignment.c +++ b/src/parser/instruction/parse_assignment.c @@ -5,6 +5,7 @@ ** Assignment instruction parsing function with static helpers */ #include +#include #include "lexer/token.h" #include "main.h" #include "parser/node.h" @@ -18,11 +19,6 @@ static int parse_lhs(parser_t *parser, node_t *assign_node) if (!lhs) return get_error(ENOMEM, "parser assignment node allocation"); - if (lhs->type != NODE_VAR) { - node_destroy(lhs); - return get_error(EPAR, - "invalid assignment left-hand side: expected variable"); - } assign_node->left = lhs; return SUCCESS; } @@ -33,7 +29,7 @@ static int parse_rhs(parser_t *parser, node_t *assign_node) if (!rhs) return get_error(ENOMEM, "parser assignment node allocation"); - assign_node->left = rhs; + assign_node->right = rhs; return SUCCESS; } diff --git a/src/parser/instruction/parse_call.c b/src/parser/instruction/parse_call.c new file mode 100644 index 0000000..021c5da --- /dev/null +++ b/src/parser/instruction/parse_call.c @@ -0,0 +1,84 @@ +/* +** EPITECH PROJECT, 2026 +** parse_call.c +** File description: +** Call instruction parsing function with static helpers +*/ +#include +#include +#include "lexer/token.h" +#include "main.h" +#include "parser/node.h" +#include "parser/parser.h" +#include "utils/utils.h" + +static char *handle_call_name(parser_t *parser, node_t *node) +{ + char *name = NULL; + + if (!parser_match(parser, TOK_IDENT)) { + node_destroy(node); + get_error(EPAR, + "expected function name identifier, got '%s'", + parser_peek(parser)->value); + return NULL; + } + name = strdup(parser_at(parser, parser->cursor - 1)->value); + if (!name) { + node_destroy(node); + get_error(ENOMEM, "parser call name allocation"); + return NULL; + } + return name; +} + +static bool handle_call_argument(parser_t *parser, node_t *node) +{ + node_t *arg = parse_expression(parser); + + if (!arg) { + node_destroy(node); + return false; + } + if (array_push(node->childs, arg) == ERROR) { + node_destroy(arg); + node_destroy(node); + get_error(ENOMEM, "parser call argument implementation"); + return false; + } + return true; +} + +static bool handle_call_arguments(parser_t *parser, node_t *node) +{ + if (!parser_match(parser, TOK_LPAREN)) { + node_destroy(node); + get_error(EPAR, "expected '(', got '%s'", parser_peek(parser)->value); + return false; + } + while (parser_peek(parser)->type != TOK_RPAREN) { + if (!handle_call_argument(parser, node)) { + node_destroy(node); + return false; + } + if (parser_peek(parser)->type == TOK_COMMA) + parser_next(parser); + } + return true; +} + +node_t *parse_call(parser_t *parser) +{ + node_t *node = node_create(NODE_CALL); + + if (!node) { + get_error(ENOMEM, "parser call node allocation"); + return NULL; + } + node->name = handle_call_name(parser, node); + if (!node->name) + return NULL; + if (!handle_call_arguments(parser, node)) + return NULL; + return node; +} diff --git a/src/parser/instruction/parse_declaration.c b/src/parser/instruction/parse_declaration.c index 93b3790..d94c9f1 100644 --- a/src/parser/instruction/parse_declaration.c +++ b/src/parser/instruction/parse_declaration.c @@ -5,6 +5,7 @@ ** Assignment instruction parsing function with static helpers */ #include +#include #include #include "lexer/token.h" #include "main.h" @@ -43,9 +44,10 @@ node_t *parse_declaration(parser_t *parser) if (type == DATA_INVALID) return NULL; - if (parser_at(parser, parser->cursor + 1)->type == TOK_EQ) + if (parser_at(parser, parser->cursor + 1)->type == TOK_EQ) { node = parse_assignment(parser); - else + printf("Parsed assignement with name '%s'\n", node->left->name); + } else node = handle_empty_declaration(parser); if (!node) return NULL; diff --git a/src/parser/instruction/parse_instruction.c b/src/parser/instruction/parse_instruction.c index c01172e..867dcfc 100644 --- a/src/parser/instruction/parse_instruction.c +++ b/src/parser/instruction/parse_instruction.c @@ -10,6 +10,11 @@ #include "parser/parser.h" #include "utils/utils.h" +static int is_data_type_token(token_t *token) +{ + return token->type == TOK_INT || token->type == TOK_VOID; +} + static int get_instruction_size(parser_t *parser) { int size = 0; @@ -27,8 +32,29 @@ static int get_instruction_size(parser_t *parser) return size; } -static bool is_assignement(parser_t *parser, token_t *token, int size) +static bool is_declaration(parser_t *parser, int size) +{ + token_t *token = parser_peek(parser); + int cursor = parser->cursor; + bool result = false; + + if (size < 3 || !(is_data_type_token(token))) { + parser->cursor = cursor; + return false; + } + if (parser_next(parser)->type != TOK_IDENT) { + parser->cursor = cursor; + return false; + } + if (parser_next(parser)->type == TOK_EQ) + result = true; + parser->cursor = cursor; + return result; +} + +static bool is_asignement(parser_t *parser, int size) { + token_t *token = parser_peek(parser); int cursor = parser->cursor; bool result = false; @@ -36,8 +62,24 @@ static bool is_assignement(parser_t *parser, token_t *token, int size) parser->cursor = cursor; return false; } + if (parser_next(parser)->type == TOK_EQ) + result = true; + parser->cursor = cursor; + return result; +} + +static bool is_function_call(parser_t *parser) +{ + token_t *token = parser_peek(parser); + int cursor = parser->cursor; + bool result = false; + + if (token->type != TOK_IDENT) { + parser->cursor = cursor; + return false; + } parser_next(parser); - if (parser_peek(parser)->type == TOK_EQ) + if (parser_peek(parser)->type == TOK_LPAREN) result = true; parser->cursor = cursor; return result; @@ -50,9 +92,13 @@ static node_t *get_instruction_node(parser_t *parser) if (token->type == TOK_RETURN) return parse_return(parser); - if (is_assignement(parser, token, size)) + if (is_declaration(parser, size)) + return parse_declaration(parser); + if (is_function_call(parser)) + return parse_call(parser); + if (is_asignement(parser, size)) return parse_assignment(parser); - get_error(EPAR, "expected 'return' or identifier: got '%s'", token->value); + get_error(EPAR, "expected instruction: got '%s'", token->value); return NULL; } @@ -72,9 +118,7 @@ node_t *parse_instruction(parser_t *parser) return NULL; if (!parser_match(parser, TOK_SEMI)) { node_destroy(node); - get_error(EPAR, - "missing semicolon", - "expected ';' at the end of instruction"); + get_error(EPAR, "missing semicolon"); return NULL; } return node;