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