[FEAT] Typed functions must return a value

This commit is contained in:
2021-05-05 17:21:32 +02:00
parent 835cae35bb
commit b62cbd2cda
3 changed files with 26 additions and 16 deletions

View File

@@ -9,12 +9,18 @@
0024: RET 0024: RET
0025: STL 4 0025: STL 4
0030: STL 0 0030: STL 0
0035: LDL 8 0035: PUSH 1
0040: PUSH 0 0040: RET
0045: GT 0041: LDL 8
0046: JNT 66 0046: PUSH 0
0051: PUSH 1 0051: GT
0056: STL 12 0052: JNT 78
0061: JMP 76 0057: PUSH 1
0066: PUSH 2 0062: STL 12
0071: STL 16 0067: LDL 8
0072: RET
0073: JMP 94
0078: PUSH 2
0083: STL 16
0088: PUSH 1
0093: RET

View File

@@ -509,7 +509,7 @@ static void parse_function() {
function_set_type(type_num); function_set_type(type_num);
tkn_next(); tkn_next();
} }
if (!parse_statements() && (function_get_type() != -1)) HALT("Function must return a value"); if (!parse_statements() && (function_get_type() != -1)) HALT("Not all paths return a value");
scope_close_local(); scope_close_local();
EXPECT(TOKEN_END, "Expected statement or 'end'"); EXPECT(TOKEN_END, "Expected statement or 'end'");
tkn_next(); tkn_next();
@@ -606,10 +606,11 @@ static void parse_dec() {
}*/ }*/
static void parse_if() { static const bool parse_if() {
bool ret_at_else = true;
const std::string previous_breaklabel = breaklabel; const std::string previous_breaklabel = breaklabel;
parse_expression(); parse_expression();
EXPECT(TOKEN_THEN, "Expected 'THEN'"); EXPECT2(TOKEN_THEN, "Expected 'THEN'");
tkn_next(); tkn_next();
emmit(OP_JNT); emmit(OP_JNT);
const std::string elselabel = generate_anonymous_labelname(); const std::string elselabel = generate_anonymous_labelname();
@@ -618,7 +619,7 @@ static void parse_if() {
bool else_visited = false; bool else_visited = false;
emmit_dw(get_label_address(elselabel)); emmit_dw(get_label_address(elselabel));
scope_open_block(); scope_open_block();
parse_statements(); const bool ret_at_then = parse_statements();
scope_close_block(); scope_close_block();
if (tkn_get_token() == TOKEN_ELSE) { if (tkn_get_token() == TOKEN_ELSE) {
else_visited = true; else_visited = true;
@@ -627,7 +628,7 @@ static void parse_if() {
register_label_address(elselabel); register_label_address(elselabel);
tkn_next(); tkn_next();
scope_open_block(); scope_open_block();
parse_statements(); ret_at_else = parse_statements();
scope_close_block(); scope_close_block();
} }
if (tkn_get_token() == TOKEN_END) { if (tkn_get_token() == TOKEN_END) {
@@ -635,10 +636,11 @@ static void parse_if() {
register_label_address(endlabel); register_label_address(endlabel);
tkn_next(); tkn_next();
breaklabel = previous_breaklabel; breaklabel = previous_breaklabel;
return; return ret_at_else && ret_at_then;
} }
parser_finished = true; parser_finished = true;
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;
} }
/* /*
static void parse_for() { static void parse_for() {
@@ -767,7 +769,7 @@ static const bool parse_statements() {
case TOKEN_VAR: case TOKEN_VAR:
tkn_next(); parse_var(); break; tkn_next(); parse_var(); break;
case TOKEN_IF: case TOKEN_IF:
tkn_next(); parse_if(); break; tkn_next(); if (parse_if()) { return_called = true; } break;
/* /*
case TOKEN_FOR: case TOKEN_FOR:
tkn_next(); parse_for(); break; tkn_next(); parse_for(); break;

View File

@@ -15,8 +15,10 @@ const perico as number = 4-peiv[1].a.x * peiv[0].c.y[2]
function tarari(a as number, b as number) as number function tarari(a as number, b as number) as number
var local1 as number var local1 as number
return 1
if local1 > 0 then if local1 > 0 then
var local1 as number = 1 var local1 as number = 1
return local1
else else
var local3 as number = 2 var local3 as number = 2
end end