Skip to content

Commit

Permalink
allow for returning non int literals in functions
Browse files Browse the repository at this point in the history
  • Loading branch information
dosisod committed Dec 7, 2020
1 parent 5e0c942 commit 2afe52d
Show file tree
Hide file tree
Showing 7 changed files with 26 additions and 6 deletions.
13 changes: 9 additions & 4 deletions skull/llvm/flow.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,19 +28,24 @@ bool node_to_llvm_ir(AstNode *);
Builds an return statement from `node`.
*/
void llvm_make_return(AstNode *node) {
if (node->token->next->token_type == TOKEN_IDENTIFIER) {
SCOPE_FIND_VAR(found_var, node->token->next, var_name);
const Token *const token_val = node->token->next;
if (token_val->token_type == TOKEN_IDENTIFIER) {
SCOPE_FIND_VAR(found_var, token_val, var_name);
free(var_name);

if (CURRENT_FUNC == MAIN_FUNC && found_var->type != &TYPE_INT) {
PANIC("returning non-int variable \"%s\" from main\n", { .var = found_var });
}

LLVMBuildRet(BUILDER, llvm_var_get_value(found_var));
return;
}
else {
LLVMBuildRet(BUILDER, LLVM_INT(eval_integer(node->token->next)));

if (CURRENT_FUNC == MAIN_FUNC && token_val->token_type != TOKEN_INT_CONST) {
PANIC("returning non-int value \"%s\" from main\n", { .tok = token_val });
}

LLVMBuildRet(BUILDER, llvm_parse_token(token_val));
}

LLVMValueRef llvm_make_cond(AstNode *);
Expand Down
2 changes: 1 addition & 1 deletion skull/parse/ast/node.c
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ AstNode *make_ast_tree_(Token *token, unsigned indent_lvl, Token **token_last) {
if (token->token_type == TOKEN_KW_RETURN &&
token->next && (
token->next->token_type == TOKEN_IDENTIFIER ||
token->next->token_type == TOKEN_INT_CONST)
is_const_literal(token->next))
) {
token = token->next;
push_ast_node(token, &last, AST_NODE_RETURN, &node);
Expand Down
1 change: 1 addition & 0 deletions test/sh/error/_non_int_return.sk.out
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Compilation error: returning non-int value "1.0" from main
1 change: 1 addition & 0 deletions test/sh/error/non_int_return.sk
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
return 1.0
8 changes: 8 additions & 0 deletions test/sh/function/_non_int_return.sk.ll
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@ entry:
}

define private double @func() {
entry:
%ret = alloca double
store double 3.140000e+00, double* %ret
%0 = load double, double* %ret
ret double %0
}

define private double @func2() {
entry:
ret double 3.140000e+00
}
6 changes: 5 additions & 1 deletion test/sh/function/non_int_return.sk
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
func() float {
ret := 3.14
mut ret := 3.14
return ret
}

func2() float {
return 3.14
}
1 change: 1 addition & 0 deletions test/sh/main.sh
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ test_error "unexpected_code_block.sk"
test_error "unreachable_return.sk"
test_error "invalid_identifier.sk"
test_error "main_reserved.sk"
test_error "non_int_return.sk"

touch test/sh/error/read_protected.sk
chmod 200 test/sh/error/read_protected.sk
Expand Down

0 comments on commit 2afe52d

Please sign in to comment.