[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");
|
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:
|
||||||
|
|||||||
3
test.vb
3
test.vb
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user