aboutsummaryrefslogtreecommitdiff
path: root/src/parser.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/parser.c')
-rw-r--r--src/parser.c54
1 files changed, 31 insertions, 23 deletions
diff --git a/src/parser.c b/src/parser.c
index 57606b5..b1764a1 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -33,7 +33,7 @@ do { \
throw(return_if_result); \
} while(0)
-static THROWABLE parser_parse_rhs_start(Parser *self, Ast *rhs_expr);
+static THROWABLE parser_parse_rhs_start(Parser *self, Ast *rhs_expr, bool is_standalone);
static THROWABLE parser_parse_body(Parser *self, Ast *ast);
static THROWABLE parser_parse_struct_body(Parser *self, Ast *ast);
static THROWABLE parser_queue_file(Parser *self, BufferView path, FileScopeReference **file_scope);
@@ -188,7 +188,7 @@ static THROWABLE parser_parse_lhs(Parser *self, LhsExpr **result, bool *assignme
throw_if_error(tokenizer_accept(&self->tokenizer, TOK_IDENTIFIER));
var_name = self->tokenizer.value.identifier;
throw_if_error(scoped_allocator_alloc(self->allocator, sizeof(LhsExpr), (void**)result));
- lhsexpr_init(*result, is_pub, is_const, var_name);
+ throw_if_error(lhsexpr_init(*result, is_pub, is_const, var_name, self->allocator));
try(parser_parse_var_type_def(self, &(*result)->type.name));
@@ -292,7 +292,7 @@ static THROWABLE parser_parse_function_args(Parser *self, FunctionCall *func_cal
throw_if_error(tokenizer_accept(&self->tokenizer, TOK_COMMA));
first_arg = bool_false;
- try(parser_parse_rhs_start(self, &arg_expr));
+ try(parser_parse_rhs_start(self, &arg_expr, bool_false));
throw_if_error(buffer_append(&func_call->args, &arg_expr, sizeof(arg_expr)));
}
@@ -457,31 +457,33 @@ static THROWABLE parser_parse_rhs(Parser *self, Ast *rhs_expr) {
/*
RHS_START = CLOSURE | IMPORT | RHS
*/
-int parser_parse_rhs_start(Parser *self, Ast *rhs_expr) {
+int parser_parse_rhs_start(Parser *self, Ast *rhs_expr, bool is_standalone) {
FunctionDecl *func_decl;
StructDecl *struct_decl;
Import *import;
- try(parser_parse_function_decl(self, &func_decl));
- if(func_decl) {
- ast_init(rhs_expr, func_decl, AST_FUNCTION_DECL);
- return PARSER_OK;
- }
-
- try(parser_parse_struct_decl(self, &struct_decl));
- if(struct_decl) {
- ast_init(rhs_expr, struct_decl, AST_STRUCT_DECL);
- return PARSER_OK;
- }
+ if(!is_standalone) {
+ try(parser_parse_function_decl(self, &func_decl));
+ if(func_decl) {
+ ast_init(rhs_expr, func_decl, AST_FUNCTION_DECL);
+ return PARSER_OK;
+ }
+
+ try(parser_parse_struct_decl(self, &struct_decl));
+ if(struct_decl) {
+ ast_init(rhs_expr, struct_decl, AST_STRUCT_DECL);
+ return PARSER_OK;
+ }
- try(parser_parse_import(self, &import));
- if(import) {
- try(parser_queue_file(self, import->path, &import->file_scope));
- ast_init(rhs_expr, import, AST_IMPORT);
- return PARSER_OK;
+ try(parser_parse_import(self, &import));
+ if(import) {
+ try(parser_queue_file(self, import->path, &import->file_scope));
+ ast_init(rhs_expr, import, AST_IMPORT);
+ return PARSER_OK;
+ }
+ self->error_context = ERROR_CONTEXT_RHS_STANDALONE;
}
- self->error_context = ERROR_CONTEXT_RHS_START;
try(parser_parse_rhs(self, rhs_expr));
self->error_context = ERROR_CONTEXT_NONE;
return PARSER_OK;
@@ -530,7 +532,10 @@ int parser_parse_body(Parser *self, Ast *ast) {
return PARSER_OK;
}
- try(parser_parse_rhs_start(self, &rhs_expr));
+ if(!lhs_expr)
+ self->error_context = ERROR_CONTEXT_NO_LHS;
+
+ try(parser_parse_rhs_start(self, &rhs_expr, lhs_expr == NULL));
if(lhs_expr) {
lhs_expr->rhs_expr = rhs_expr;
ast_init(ast, lhs_expr, AST_LHS);
@@ -576,9 +581,12 @@ int parser_parse_buffer(Parser *self, BufferView code_buffer, BufferView buffer_
case ERROR_CONTEXT_NONE:
tokenizer_print_error_object(&self->tokenizer, &self->error);
break;
- case ERROR_CONTEXT_RHS_START:
+ case ERROR_CONTEXT_RHS_STANDALONE:
tokenizer_print_error(&self->tokenizer, self->tokenizer.prev_index, "Expected string, variable, closure, struct, function call or import");
break;
+ case ERROR_CONTEXT_NO_LHS:
+ tokenizer_print_error(&self->tokenizer, self->tokenizer.prev_index, "Expected variable declaration, string, variable or function call");
+ break;
default:
assert(bool_false && "Error context handling not implemented");
break;