[FEAT] Implemented 'for'. More tests needed
This commit is contained in:
62
parser.cpp
62
parser.cpp
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user