[FEAT] Implemented 'for'. More tests needed

This commit is contained in:
2021-05-05 22:12:37 +02:00
parent f1c1b3e396
commit e3cea9d3b0
2 changed files with 35 additions and 30 deletions

View File

@@ -642,53 +642,53 @@ static const bool parse_if() {
if (!else_visited) error_raise("Expected 'ELSE', 'END' or a statement"); else error_raise("Expected 'END' or a statement"); if (!else_visited) error_raise("Expected 'ELSE', 'END' or a statement"); else error_raise("Expected 'END' or a statement");
return false; return false;
} }
/*
static void parse_for() { static const bool parse_for() {
char* previous_breaklabel = breaklabel; const std::string previous_breaklabel = breaklabel;
char* previous_contlabel = contlabel; const std::string previous_contlabel = contlabel;
EXPECT(TOKEN_IDENTIFIER, "Expected variable"); EXPECT2(TOKEN_IDENTIFIER, "Expected variable");
int ivar = get_variable_index(tkn_get_string()); if (scope_variable_exists(tkn_get_string(), true)) HALT2("Identifier already used");
tkn_next(); const uint32_t var_address = scope_declare_variable(tkn_get_string(), 0, 0);
EXPECT(TOKEN_EQ, "Expected '='"); tkn_next(); EXPECT2(TOKEN_EQ, "Expected '='");
tkn_next(); tkn_next();
parse_expression(); parse_expression();
emmit(OP_STORE); emmit(OP_STL);
emmit_w(ivar); emmit_dw(var_address);
char forlabel[8]; const std::string forlabel = generate_anonymous_labelname();
generate_anonymous_labelname(forlabel); const std::string endlabel = generate_anonymous_labelname();
char endlabel[8]; const std::string continuelabel = generate_anonymous_labelname();
generate_anonymous_labelname(endlabel);
char continuelabel[8];
generate_anonymous_labelname(continuelabel);
breaklabel = endlabel; breaklabel = endlabel;
contlabel = continuelabel; contlabel = continuelabel;
register_label_address(forlabel); register_label_address(forlabel);
EXPECT(TOKEN_TO, "Expected 'TO'"); EXPECT2(TOKEN_TO, "Expected 'TO'");
tkn_next(); tkn_next();
parse_expression(); parse_expression();
emmit(OP_LOAD); emmit(OP_LDL);
emmit_w(ivar); emmit_dw(var_address);
emmit(OP_EQ); emmit(OP_EQ);
emmit(OP_JTR); emmit(OP_JTR);
emmit_w(get_label_address(endlabel)); emmit_dw(get_label_address(endlabel));
//int endLabel = GetCurrentAddress(); //int endLabel = GetCurrentAddress();
parse_statements(); scope_open_block();
EXPECT(TOKEN_END, "Expected 'END'"); const bool ret_called = parse_statements();
scope_close_block();
EXPECT2(TOKEN_END, "Expected 'END'");
tkn_next(); tkn_next();
register_label_address(continuelabel); register_label_address(continuelabel);
emmit(OP_LOAD); emmit(OP_LDL);
emmit_w(ivar); emmit_dw(var_address);
emmit(OP_INC); emmit(OP_INC);
emmit(OP_STORE); emmit(OP_STL);
emmit_w(ivar); emmit_dw(var_address);
emmit(OP_JMP); emmit(OP_JMP);
emmit_w(get_label_address(forlabel)); emmit_dw(get_label_address(forlabel));
register_label_address(endlabel); register_label_address(endlabel);
//Patch(endLabel, GetCurrentAddress()); //Patch(endLabel, GetCurrentAddress());
breaklabel = previous_breaklabel; breaklabel = previous_breaklabel;
contlabel = previous_contlabel; contlabel = previous_contlabel;
return ret_called;
} }
/*
static void parse_break() { static void parse_break() {
if (breaklabel == nullptr) { parser_finished = true; error_raise("Can't break outside of a loop or condition"); return; } if (breaklabel == nullptr) { parser_finished = true; error_raise("Can't break outside of a loop or condition"); return; }
emmit(OP_JMP); emmit(OP_JMP);
@@ -780,9 +780,11 @@ static const bool parse_statements() {
tkn_next(); tkn_next();
if (local_return && !already_warned) { error_warning("Unreachable code"); already_warned = true; } if (local_return && !already_warned) { error_warning("Unreachable code"); already_warned = true; }
if (parse_if()) { return_called = true; } break; if (parse_if()) { return_called = true; } break;
/*
case TOKEN_FOR: case TOKEN_FOR:
tkn_next(); parse_for(); break; tkn_next();
if (local_return && !already_warned) { error_warning("Unreachable code"); already_warned = true; }
if (parse_for()) { return_called = true; } break;
/*
case TOKEN_BREAK: case TOKEN_BREAK:
tkn_next(); parse_break(); break; tkn_next(); parse_break(); break;
case TOKEN_CONTINUE: case TOKEN_CONTINUE:

View File

@@ -17,6 +17,9 @@ function tarari(a as number, b as number) as number
var local1 as number var local1 as number
if local1 > 0 then if local1 > 0 then
var local1 as number = 1 var local1 as number = 1
for i = 0 to 10
var local1 as number = local1 + 1
end
return local1 return local1
else else
var local3 as number = 2 var local3 as number = 2