diff --git a/libs/ast/include/pslang/ast/statement.hpp b/libs/ast/include/pslang/ast/statement.hpp index a5c3649..f968469 100644 --- a/libs/ast/include/pslang/ast/statement.hpp +++ b/libs/ast/include/pslang/ast/statement.hpp @@ -28,6 +28,7 @@ namespace pslang::ast struct return_statement { + // can be null, which means "return unit" expression_ptr value; }; diff --git a/libs/ast/source/print.cpp b/libs/ast/source/print.cpp index 3e50c46..187dfac 100644 --- a/libs/ast/source/print.cpp +++ b/libs/ast/source/print.cpp @@ -267,7 +267,8 @@ namespace pslang::ast put_indent(out, options); out << "return"; newline(out); - print(out, node.value, child(options)); + if (node.value) + print(out, node.value, child(options)); } void print(std::ostream & out, statement_ptr const & node, print_options const & options) diff --git a/libs/interpreter/source/interpreter.cpp b/libs/interpreter/source/interpreter.cpp index 19b7f13..18a27ad 100644 --- a/libs/interpreter/source/interpreter.cpp +++ b/libs/interpreter/source/interpreter.cpp @@ -180,7 +180,7 @@ namespace pslang::interpreter void execute_impl(context & context, ast::return_statement const & return_statement) { - auto value = eval(context, return_statement.value); + auto value = return_statement.value ? eval(context, return_statement.value) : unit_value{}; for (auto it = context.scope_stack.rbegin(); it != context.scope_stack.rend(); ++it) { if (it->is_function_scope) diff --git a/libs/parser/rules/pslang.y b/libs/parser/rules/pslang.y index f1514d5..ec3ae24 100644 --- a/libs/parser/rules/pslang.y +++ b/libs/parser/rules/pslang.y @@ -188,6 +188,7 @@ statement | while expression colon { $$ = ast::while_block{std::make_unique($2), {}}; } | func name lparen function_definition_argument_list rparen function_return_type colon { $$ = ast::function_definition{$2, $4, $6, {}}; } | return expression { $$ = ast::return_statement{std::make_unique($2)}; } +| return { $$ = ast::return_statement{nullptr}; } ; function_definition_argument_list