diff --git a/parser.cpp b/parser.cpp index 18389f5..59c6601 100644 --- a/parser.cpp +++ b/parser.cpp @@ -231,7 +231,9 @@ static void parse_getcolor(); */ #define EXPECT(X, Y) if (tkn_get_token() != X) { parser_finished = true; error_raise(Y); return; } +#define EXPECT2(X, Y) if (tkn_get_token() != X) { parser_finished = true; error_raise(Y); return -1; } #define HALT(Y) { parser_finished = true; error_raise(Y); return; } +#define HALT2(Y) { parser_finished = true; error_raise(Y); return -1; } /* static void parse_concat_atom() { @@ -279,17 +281,31 @@ static void parse_concatenation() { static int get_variable_address() { int address = scope_get_variable_address(); - const uint32_t var_length = scope_get_variable_size(); - const uint32_t var_type = scope_get_variable_type(); - if (var_length > 1) { - tkn_next(); EXPECT(TOKEN_LBRACKET, "Expected '['"); - tkn_next(); EXPECT(TOKEN_NUMBER, "Expected number"); - const float index = tkn_get_value(); - tkn_next(); EXPECT(TOKEN_LBRACKET, "Expected ']'"); - address += index * types_get_length(var_type); - } - if (var_type >= 2) { - + uint32_t var_length = scope_get_variable_size(); + uint32_t var_type = scope_get_variable_type(); + + while (true) { + // Si es un array... + if (var_length > 1) { + tkn_next(); EXPECT2(TOKEN_LBRACKET, "Expected '['"); + tkn_next(); EXPECT2(TOKEN_NUMBER, "Expected number"); + const float index = tkn_get_value(); + tkn_next(); EXPECT2(TOKEN_RBRACKET, "Expected ']'"); + address += index * types_get_length(var_type); + } + // Si es un struct... + if (var_type >= 2) { + tkn_next(); EXPECT2(TOKEN_DOT, "Expected '.'"); + tkn_next(); EXPECT2(TOKEN_IDENTIFIER, "Expected identifier"); + const std::string member_name = tkn_get_string(); + const int member_num = types_member_exists(var_type, member_name); + if (member_num == -1) HALT2("Unknown member"); + address += types_get_member_offset(var_type, member_num); + var_length = types_get_member_length(var_type, member_num); + var_type = types_get_member_type(var_type, member_num); + } else { + return address; + } } } @@ -303,9 +319,10 @@ static void parse_expr_atom() { } if (tkn_get_token() == TOKEN_IDENTIFIER) { if (scope_variable_exists(tkn_get_string())) { - // TODO [RZC 03/05/2021] Revisar si hi ha que navegar un struct o array + const int address = get_variable_address(); + if (address == -1) return; emmit(scope_is_local() ? OP_LDL : OP_LD); - emmit(scope_get_variable_address()); + emmit(address); tkn_next(); return; } else { diff --git a/test.vb b/test.vb index 444e263..2decc2a 100644 --- a/test.vb +++ b/test.vb @@ -11,4 +11,4 @@ struct triangle end var peiv as array of 2 triangle -const perico as number = 4-peiv +const perico as number = 4-peiv[0].a.x diff --git a/types.cpp b/types.cpp index 56b39fe..8dc7afe 100644 --- a/types.cpp +++ b/types.cpp @@ -57,4 +57,10 @@ const int types_get_member_length(const uint32_t type, const uint32_t member) { if (type >= types.size()) return -1; // ERROR INTERN: No deuria donar-se mai if (member >= types[type].members.size()) return -1; // ERROR INTERN: No deuria donar-se mai return types[type].members[member].length; -} \ No newline at end of file +} + +const int types_get_member_offset(const uint32_t type, const uint32_t member) { + if (type >= types.size()) return -1; // ERROR INTERN: No deuria donar-se mai + if (member >= types[type].members.size()) return -1; // ERROR INTERN: No deuria donar-se mai + return types[type].members[member].address; +} diff --git a/types.h b/types.h index a213a0e..b51a655 100644 --- a/types.h +++ b/types.h @@ -11,3 +11,4 @@ const int types_add_member(const uint32_t type, const std::string name, const ui const int types_member_exists(const uint32_t type, const std::string name); const int types_get_member_type(const uint32_t type, const uint32_t member); const int types_get_member_length(const uint32_t type, const uint32_t member); +const int types_get_member_offset(const uint32_t type, const uint32_t member);