diff --git a/examples/a.glx b/examples/a.glx index 0ebca6f..4783100 100644 --- a/examples/a.glx +++ b/examples/a.glx @@ -1 +1,18 @@ -bool isBigger := 3 > 2 ? 1 : 0; \ No newline at end of file +extern int printf( string ) ; +extern int putchar( string ) ; + +def pedidor_de_socorrokk( string nome) -> int: + + printf( "socorro") ; + putchar( "\n" ) ; + + return 0 ; +end; + +def main( ) -> int: + pedidor_de_socorrokk( "natan" ) ; + pedidor_de_socorrokk( "bruno" ) ; + pedidor_de_socorrokk( "casado" ) ; + + return 0 ; +end; diff --git a/include/frontend/ast/definitions.h b/include/frontend/ast/definitions.h index 60453fd..5c4ad24 100644 --- a/include/frontend/ast/definitions.h +++ b/include/frontend/ast/definitions.h @@ -70,8 +70,8 @@ typedef struct { } CallNode; typedef struct { - char *reference; - TokenType type; + AstNode *object; + AstNode *property; } MemberPropertyNode; typedef struct { diff --git a/include/frontend/parser/expressions/parse_member_expr.h b/include/frontend/parser/expressions/parse_member_expr.h new file mode 100644 index 0000000..34086d4 --- /dev/null +++ b/include/frontend/parser/expressions/parse_member_expr.h @@ -0,0 +1,8 @@ +#ifndef PARSE_MEMBER_EXPR_H +#define PARSE_MEMBER_EXPR_H + +#include "frontend/parser/core.h" + +AstNode *parse_member_expr(Parser *parser); + +#endif // PARSE_MEMBER_EXPR_H \ No newline at end of file diff --git a/src/frontend/parser/expressions/parse_call_member_expr.c b/src/frontend/parser/expressions/parse_call_member_expr.c index 26a8899..ae9a543 100644 --- a/src/frontend/parser/expressions/parse_call_member_expr.c +++ b/src/frontend/parser/expressions/parse_call_member_expr.c @@ -4,6 +4,8 @@ #include "frontend/parser/expressions/parse_call_expr.h" #include "frontend/parser/expressions/parse_array_access_expr.h" #include "frontend/parser/expressions/parse_primary_expr.h" +#include "frontend/parser/expressions/parse_member_expr.h" +#include "frontend/parser/expressions/parse_expr.h" #include "frontend/parser/core.h" #include "utils.h" @@ -13,66 +15,17 @@ AstNode *parse_call_member_expr(Parser *parser, AstNode *statement) { if (statement) { expr = statement; } else { - expr = parse_primary_expr(parser); + expr = parse_member_expr(parser); } switch (at(parser).type) { - case TOKEN_DOT: { - int line = at(parser).line; - int column_start_member = at(parser).column_start; - int column_end_member = at(parser).column_end; - int position_start_member = at(parser).position_start; - int position_end_member = at(parser).position_end; - - eat(parser); - - int column_start_val = at(parser).column_start; - int column_end_val = at(parser).column_end; - - if (at(parser).type != TOKEN_IDENTIFIER && at(parser).type != TOKEN_NUMBER) { - error(parser, "Expected identifier or integer on member expression."); - exit(EXIT_FAILURE); - } - - char *property = strdup(at(parser).lexeme); - TokenType prop_type = eat(parser).type; - - int position_start_val = at(parser).position_start; - int position_end_val = at(parser).position_end; - - MemberPropertyNode *prop_data = MALLOC_S(sizeof(MemberPropertyNode)); - prop_data->reference = property; - prop_data->type = prop_type; - - AstNode *prop_node = create_ast_node( - NODE_MEMBER_PROPERTY, - prop_data, - line, - column_start_val, - position_start_val, - column_end_val, - position_end_val - ); - - MemberNode *member_data = MALLOC_S(sizeof(MemberNode)); - member_data->member = expr; - member_data->property = prop_node; - - AstNode *member_node = create_ast_node( - NODE_MEMBER, - member_data, - line, - column_start_member, - position_start_member, - column_end_member, - position_end_member - ); - - return member_node; - } - case TOKEN_OPAREN: { expr = parse_call_expr(parser, expr); + + if (at(parser).type == TOKEN_SEMICOLON) { + eat(parser); + return expr; + } } break; case TOKEN_OBRACKET: { diff --git a/src/frontend/parser/expressions/parse_member_expr.c b/src/frontend/parser/expressions/parse_member_expr.c new file mode 100644 index 0000000..73c1362 --- /dev/null +++ b/src/frontend/parser/expressions/parse_member_expr.c @@ -0,0 +1,67 @@ +#include "frontend/parser/expressions/parse_member_expr.h" +#include "frontend/parser/expressions/parse_expr.h" +#include "frontend/parser/expressions/parse_primary_expr.h" +#include "utils.h" + +AstNode *parse_member_expr(Parser *parser) { + int line = at(parser).line; + int column_start_member = at(parser).column_start; + int position_start_member = at(parser).position_start; + + AstNode *object = parse_primary_expr(parser); + + AstNode *current_member = object; + + while (at(parser).type == TOKEN_DOT) { + eat(parser); + + if (at(parser).type != TOKEN_IDENTIFIER && at(parser).type != TOKEN_NUMBER) { + error(parser, "Expected identifier or number after '.' in member expression."); + exit(EXIT_FAILURE); + } + + int column_start_val = at(parser).column_start; + int position_start_val = at(parser).position_start; + + AstNode *property = parse_expr(parser); + if (!property) { + error(parser, "Failed to parse property in member expression."); + exit(EXIT_FAILURE); + } + + int column_end_val = at(parser).column_end - 1; + int position_end_val = at(parser).position_end - 1; + + MemberPropertyNode *prop_data = MALLOC_S(sizeof(MemberPropertyNode)); + prop_data->object = current_member; + prop_data->property = property; + + AstNode *prop_node = create_ast_node( + NODE_MEMBER_PROPERTY, + prop_data, + line, + column_start_val, + position_start_val, + column_end_val, + position_end_val + ); + + current_member = prop_node; + } + + MemberNode *member_data = MALLOC_S(sizeof(MemberNode)); + member_data->member = object; + member_data->property = current_member; + + AstNode *member_node = create_ast_node( + NODE_MEMBER, + member_data, + line, + column_start_member, + position_start_member, + at(parser).column_end - 1, + at(parser).position_end - 1 + ); + + return member_node; +}