aboutsummaryrefslogtreecommitdiff
path: root/src/parser.c
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2019-03-23 16:16:59 +0100
committerdec05eba <dec05eba@protonmail.com>2020-07-25 14:36:46 +0200
commitdc90305a767feaacc3430aaee0928b745a8e5b0f (patch)
tree6d85df4245a84820dfdf6425f0aa095a563cabbe /src/parser.c
parent4f308829ad0e81a59971e172284c018cf2bdca3d (diff)
Use ast pointers to fix resolving, remove try/throwing macros
Diffstat (limited to 'src/parser.c')
-rw-r--r--src/parser.c312
1 files changed, 151 insertions, 161 deletions
diff --git a/src/parser.c b/src/parser.c
index b1764a1..9e92ddd 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -11,19 +11,6 @@
#include <stdlib.h>
#include <assert.h>
-#ifdef AMAL_PEDANTIC
- #define throw_debug_msg do {} while(0)
-#else
- #define throw_debug_msg do { amal_log_info("Throwing from %s:%d", __FUNCTION__, __LINE__); } while(0)
-#endif
-
-#define THROWABLE CHECK_RESULT int
-#define try(result) \
-do { \
- int return_if_result; \
- return_if_result = (result); \
- (void)return_if_result; \
-} while(0)
#define throw(result) do { throw_debug_msg; longjmp(self->parse_env, (result)); } while(0)
#define throw_if_error(result) \
do { \
@@ -33,10 +20,10 @@ do { \
throw(return_if_result); \
} while(0)
-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);
+static CHECK_RESULT Ast* parser_parse_rhs_start(Parser *self, bool is_standalone);
+static CHECK_RESULT Ast* parser_parse_body(Parser *self);
+static CHECK_RESULT Ast* parser_parse_struct_body(Parser *self);
+static void parser_queue_file(Parser *self, BufferView path, FileScopeReference **file_scope);
int parser_thread_data_init(ParserThreadData *self) {
am_memset(&self->allocator, 0, sizeof(self->allocator));
@@ -82,23 +69,23 @@ static bool parser_is_global_scope(Parser *self) {
/*
BODY_LOOP = BODY* @end_token
*/
-static THROWABLE parser_parse_body_loop(Parser *self, Scope *scope, Token end_token) {
+static void parser_parse_body_loop(Parser *self, Scope *scope, Token end_token) {
int result;
for(;;) {
- Ast body_obj;
+ Ast *body_obj;
bool is_end_token;
throw_if_error(tokenizer_consume_if(&self->tokenizer, end_token, &is_end_token));
if(is_end_token)
break;
- try(parser_parse_body(self, &body_obj));
- result = scope_add_child(scope, &body_obj);
+ body_obj = parser_parse_body(self);
+ result = scope_add_child(scope, body_obj);
if(result == 0) {
continue;
} else if(result == AST_ERR_DEF_DUP) {
/* TODO: Convert ast type to string for error message */
BufferView obj_name;
- obj_name = ast_get_name(&body_obj);
+ obj_name = ast_get_name(body_obj);
self->error = tokenizer_create_error(&self->tokenizer,
tokenizer_get_code_reference_index(&self->tokenizer, obj_name.data),
"Variable with the name %.*s was declared twice in the same scope", obj_name.size, obj_name.data);
@@ -108,30 +95,29 @@ static THROWABLE parser_parse_body_loop(Parser *self, Scope *scope, Token end_to
throw(result);
}
}
- return PARSER_OK;
}
/*
STRUCT_BODY_LOOP = '{' STRUCT_BODY* '}'
*/
-static THROWABLE parser_parse_struct_body_loop(Parser *self, Scope *scope) {
+static void parser_parse_struct_body_loop(Parser *self, Scope *scope) {
int result;
throw_if_error(tokenizer_accept(&self->tokenizer, TOK_OPEN_BRACE));
for(;;) {
- Ast body_obj;
+ Ast *body_obj;
bool is_end_token;
throw_if_error(tokenizer_consume_if(&self->tokenizer, TOK_CLOSING_BRACE, &is_end_token));
if(is_end_token)
break;
- try(parser_parse_struct_body(self, &body_obj));
- result = scope_add_child(scope, &body_obj);
+ body_obj = parser_parse_struct_body(self);
+ result = scope_add_child(scope, body_obj);
if(result == 0) {
continue;
} else if(result == AST_ERR_DEF_DUP) {
/* TODO: Convert ast type to string for error message */
BufferView obj_name;
- obj_name = ast_get_name(&body_obj);
+ obj_name = ast_get_name(body_obj);
self->error = tokenizer_create_error(&self->tokenizer,
tokenizer_get_code_reference_index(&self->tokenizer, obj_name.data),
"Variable with the name %.*s was declared twice in the struct", obj_name.size, obj_name.data);
@@ -141,32 +127,32 @@ static THROWABLE parser_parse_struct_body_loop(Parser *self, Scope *scope) {
throw(result);
}
}
- return PARSER_OK;
}
/*
VAR_TYPE_DEF = ':' TOK_IDENTIFIER
*/
-static THROWABLE parser_parse_var_type_def(Parser *self, BufferView *type_name) {
+static void parser_parse_var_type_def(Parser *self, BufferView *type_name) {
bool match;
throw_if_error(tokenizer_consume_if(&self->tokenizer, TOK_COLON, &match));
if(match) {
throw_if_error(tokenizer_accept(&self->tokenizer, TOK_IDENTIFIER));
*type_name = self->tokenizer.value.identifier;
}
- return PARSER_OK;
}
/*
-LHS = ('const' TOK_IDENTIFIER VAR_TYPE_DEF? '=') |
- ('var' TOK_IDENTIFIER VAR_TYPE_DEF? '='|';')
+LHS = ('pub'? 'const' TOK_IDENTIFIER VAR_TYPE_DEF? '=') |
+ ('pub'? 'var' TOK_IDENTIFIER VAR_TYPE_DEF? '='|';')
*/
-static THROWABLE parser_parse_lhs(Parser *self, LhsExpr **result, bool *assignment_or_rhs) {
+static CHECK_RESULT LhsExpr* parser_parse_lhs(Parser *self, bool *assignment_or_rhs) {
+ LhsExpr *result;
bool is_pub;
bool is_const;
bool match;
BufferView var_name;
- *result = NULL;
+
+ result = NULL;
*assignment_or_rhs = bool_true;
throw_if_error(tokenizer_consume_if(&self->tokenizer, TOK_PUB, &is_pub));
@@ -182,23 +168,23 @@ static THROWABLE parser_parse_lhs(Parser *self, LhsExpr **result, bool *assignme
bool isVar;
throw_if_error(tokenizer_consume_if(&self->tokenizer, TOK_VAR, &isVar));
if(!isVar)
- return PARSER_OK;
+ return result;
}
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));
- throw_if_error(lhsexpr_init(*result, is_pub, is_const, var_name, self->allocator));
+ throw_if_error(scoped_allocator_alloc(self->allocator, sizeof(LhsExpr), (void**)&result));
+ throw_if_error(lhsexpr_init(result, is_pub, is_const, var_name, self->allocator));
- try(parser_parse_var_type_def(self, &(*result)->type.name));
+ parser_parse_var_type_def(self, &result->type.name);
throw_if_error(tokenizer_consume_if(&self->tokenizer, TOK_EQUALS, &match));
if(match) {
*assignment_or_rhs = bool_true;
- return PARSER_OK;
+ return result;
}
- if(!(*result)->type.name.data) {
+ if(!result->type.name.data) {
self->error = tokenizer_create_error(&self->tokenizer,
tokenizer_get_error_index(&self->tokenizer),
"Variable declaration requires type or right-hand side expression (Expected ':' or '=')");
@@ -219,20 +205,21 @@ static THROWABLE parser_parse_lhs(Parser *self, LhsExpr **result, bool *assignme
"Expected ';'");
throw(PARSER_UNEXPECTED_TOKEN);
}
- return PARSER_OK;
+ return result;
}
/*
-TODO: Implement params
+TODO: Implement params and return types
CLOSURE = 'fn' ('(' PARAM* ')')? '{' BODY_LOOP '}'
*/
-static THROWABLE parser_parse_function_decl(Parser *self, FunctionDecl **func_decl) {
+static CHECK_RESULT FunctionDecl* parser_parse_closure(Parser *self) {
+ FunctionDecl *result;
bool match;
- *func_decl = NULL;
+ result = NULL;
throw_if_error(tokenizer_consume_if(&self->tokenizer, TOK_FN, &match));
if(!match)
- return PARSER_OK;
+ return result;
throw_if_error(tokenizer_consume_if(&self->tokenizer, TOK_OPEN_BRACE, &match));
if(!match) {
@@ -243,46 +230,47 @@ static THROWABLE parser_parse_function_decl(Parser *self, FunctionDecl **func_de
throw_if_error(tokenizer_accept(&self->tokenizer, TOK_OPEN_BRACE));
}
- throw_if_error(scoped_allocator_alloc(self->allocator, sizeof(FunctionDecl), (void**)func_decl));
- throw_if_error(funcdecl_init(*func_decl, self->current_scope, self->allocator));
+ throw_if_error(scoped_allocator_alloc(self->allocator, sizeof(FunctionDecl), (void**)&result));
+ throw_if_error(funcdecl_init(result, self->current_scope, self->allocator));
- self->current_scope = &(*func_decl)->body;
- try(parser_parse_body_loop(self, self->current_scope, TOK_CLOSING_BRACE));
- self->current_scope = (*func_decl)->body.parent;
- return PARSER_OK;
+ self->current_scope = &result->body;
+ parser_parse_body_loop(self, self->current_scope, TOK_CLOSING_BRACE);
+ self->current_scope = result->body.parent;
+ return result;
}
/*
STRUCT = 'struct' '{' STRUCT_BODY_LOOP '}'
*/
-static THROWABLE parser_parse_struct_decl(Parser *self, StructDecl **struct_decl) {
+static CHECK_RESULT StructDecl* parser_parse_struct_decl(Parser *self) {
+ StructDecl *result;
bool match;
- *struct_decl = NULL;
+ result = NULL;
throw_if_error(tokenizer_consume_if(&self->tokenizer, TOK_STRUCT, &match));
if(!match)
- return PARSER_OK;
+ return result;
- throw_if_error(scoped_allocator_alloc(self->allocator, sizeof(StructDecl), (void**)struct_decl));
- throw_if_error(structdecl_init(*struct_decl, self->current_scope, self->allocator));
+ throw_if_error(scoped_allocator_alloc(self->allocator, sizeof(StructDecl), (void**)&result));
+ throw_if_error(structdecl_init(result, self->current_scope, self->allocator));
- self->current_scope = &(*struct_decl)->body;
- try(parser_parse_struct_body_loop(self, self->current_scope));
- self->current_scope = (*struct_decl)->body.parent;
- return PARSER_OK;
+ self->current_scope = &result->body;
+ parser_parse_struct_body_loop(self, self->current_scope);
+ self->current_scope = result->body.parent;
+ return result;
}
/*
FUNC_ARGS = (RHS_START)? (',' RHS_START)* ')'
*/
-static THROWABLE parser_parse_function_args(Parser *self, FunctionCall *func_call) {
+static void parser_parse_function_args(Parser *self, FunctionCall *func_call) {
bool first_arg;
first_arg = bool_true;
for(;;) {
- Ast arg_expr;
+ Ast *arg_expr;
bool is_end_token;
- arg_expr = ast_none();
+ arg_expr = NULL;
throw_if_error(tokenizer_consume_if(&self->tokenizer, TOK_CLOSING_PAREN, &is_end_token));
if(is_end_token)
@@ -292,25 +280,25 @@ 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, bool_false));
+ arg_expr = parser_parse_rhs_start(self, bool_false);
throw_if_error(buffer_append(&func_call->args, &arg_expr, sizeof(arg_expr)));
}
-
- return PARSER_OK;
}
/*
VARIABLE = TOK_IDENTIFIER
FUNC_CALL_OR_VARIABLE = VARIABLE '(' FUNC_ARGS ')'
*/
-static THROWABLE parser_parse_function_call_or_variable(Parser *self, Ast *expr) {
+static CHECK_RESULT Ast* parser_parse_function_call_or_variable(Parser *self) {
+ Ast *result;
bool match;
BufferView identifier;
FunctionCall *func_call;
+ result = NULL;
throw_if_error(tokenizer_consume_if(&self->tokenizer, TOK_IDENTIFIER, &match));
if(!match)
- return PARSER_OK;
+ return result;
identifier = self->tokenizer.value.identifier;
throw_if_error(tokenizer_consume_if(&self->tokenizer, TOK_OPEN_PAREN, &match));
@@ -318,70 +306,74 @@ static THROWABLE parser_parse_function_call_or_variable(Parser *self, Ast *expr)
Variable *variable;
throw_if_error(scoped_allocator_alloc(self->allocator, sizeof(Variable), (void**)&variable));
variable_init(variable, identifier);
- ast_init(expr, variable, AST_VARIABLE);
- return PARSER_OK;
+ throw_if_error(ast_create(self->allocator, variable, AST_VARIABLE, &result));
+ return result;
}
throw_if_error(scoped_allocator_alloc(self->allocator, sizeof(FunctionCall), (void**)&func_call));
throw_if_error(funccall_init(func_call, self->tokenizer.value.identifier, self->allocator));
- ast_init(expr, func_call, AST_FUNCTION_CALL);
- try(parser_parse_function_args(self, func_call));
- return PARSER_OK;
+ throw_if_error(ast_create(self->allocator, func_call, AST_FUNCTION_CALL, &result));
+ parser_parse_function_args(self, func_call);
+ return result;
}
/*
IMPORT = IMPORT_SYMBOL
*/
-static THROWABLE parser_parse_import(Parser *self, Import **import) {
+static CHECK_RESULT Import* parser_parse_import(Parser *self) {
+ Import *result;
bool match;
- *import = NULL;
+ result = NULL;
throw_if_error(tokenizer_consume_if(&self->tokenizer, TOK_IMPORT, &match));
if(!match)
- return PARSER_OK;
+ return result;
- throw_if_error(scoped_allocator_alloc(self->allocator, sizeof(Import), (void**)import));
- import_init(*import, self->tokenizer.value.string);
- return PARSER_OK;
+ throw_if_error(scoped_allocator_alloc(self->allocator, sizeof(Import), (void**)&result));
+ import_init(result, self->tokenizer.value.string);
+ return result;
}
-static THROWABLE parser_parse_number(Parser *self, Ast *rhs_expr) {
+static CHECK_RESULT Ast* parser_parse_number(Parser *self) {
+ Ast *result;
bool match;
Number *number;
+ result = NULL;
throw_if_error(tokenizer_consume_if(&self->tokenizer, TOK_NUMBER, &match));
if(!match)
- return PARSER_OK;
+ return result;
throw_if_error(scoped_allocator_alloc(self->allocator, sizeof(Number), (void**)&number));
number_init(number, self->tokenizer.value.integer, self->tokenizer.number_is_integer);
- ast_init(rhs_expr, number, AST_NUMBER);
- return PARSER_OK;
+ throw_if_error(ast_create(self->allocator, number, AST_NUMBER, &result));
+ return result;
}
/*
RHS_S = STRING | NUMBER | FUNC_CALL_OR_VARIABLE
*/
-static THROWABLE parser_parse_rhs_single_expr(Parser *self, Ast *rhs_expr) {
+static Ast* parser_parse_rhs_single_expr(Parser *self) {
+ Ast *result;
bool match;
- *rhs_expr = ast_none();
+ result = NULL;
throw_if_error(tokenizer_consume_if(&self->tokenizer, TOK_STRING, &match));
if(match) {
String *string;
throw_if_error(scoped_allocator_alloc(self->allocator, sizeof(String), (void**)&string));
throw_if_error(string_init(string, self->tokenizer.value.string));
- ast_init(rhs_expr, string, AST_STRING);
- return PARSER_OK;
+ throw_if_error(ast_create(self->allocator, string, AST_STRING, &result));
+ return result;
}
- try(parser_parse_number(self, rhs_expr));
- if(rhs_expr->type != AST_NONE)
- return PARSER_OK;
+ result = parser_parse_number(self);
+ if(result)
+ return result;
- try(parser_parse_function_call_or_variable(self, rhs_expr));
- if(rhs_expr->type != AST_NONE)
- return PARSER_OK;
+ result = parser_parse_function_call_or_variable(self);
+ if(result)
+ return result;
self->error = tokenizer_create_error(&self->tokenizer,
tokenizer_get_error_index(&self->tokenizer),
@@ -389,25 +381,24 @@ static THROWABLE parser_parse_rhs_single_expr(Parser *self, Ast *rhs_expr) {
throw(PARSER_UNEXPECTED_TOKEN);
}
-static THROWABLE parser_parse_rhs_binop(Parser *self, Ast *expr);
+static CHECK_RESULT Ast* parser_parse_rhs_binop(Parser *self);
/*
RHS_BINOP_OPT_PAREN = RHS_S | '(' RHS_BINOP ')'
*/
-static THROWABLE parser_parse_rhs_binop_opt_paren(Parser *self, Ast *expr) {
+static CHECK_RESULT Ast* parser_parse_rhs_binop_opt_paren(Parser *self) {
+ Ast *result;
bool match;
+
throw_if_error(tokenizer_consume_if(&self->tokenizer, TOK_OPEN_PAREN, &match));
- if(!match) {
- try(parser_parse_rhs_single_expr(self, expr));
- return PARSER_OK;
- }
+ if(!match)
+ return parser_parse_rhs_single_expr(self);
- try(parser_parse_rhs_binop(self, expr));
+ result = parser_parse_rhs_binop(self);
throw_if_error(tokenizer_accept(&self->tokenizer, TOK_CLOSING_PAREN));
- if(expr->type == AST_BINOP)
- expr->value.binop->grouped = bool_true;
-
- return PARSER_OK;
+ if(result->type == AST_BINOP)
+ result->value.binop->grouped = bool_true;
+ return result;
}
/*
@@ -415,29 +406,28 @@ RHS_BINOP = RHS_BINOP_OPT_PAREN (TOK_BINOP RHS_BINOP_OPT_PAREN)?
Note: Parantheses count has to match for the beginning paranthesis and the ending parenthesis.
*/
-int parser_parse_rhs_binop(Parser *self, Ast *expr) {
+Ast* parser_parse_rhs_binop(Parser *self) {
bool match;
- Ast lhs;
- Ast rhs;
+ Ast *result;
+ Ast *lhs;
+ Ast *rhs;
BinopType binop_type;
Binop *binop;
- try(parser_parse_rhs_binop_opt_paren(self, &lhs));
+ lhs = parser_parse_rhs_binop_opt_paren(self);
throw_if_error(tokenizer_consume_if(&self->tokenizer, TOK_BINOP, &match));
- if(!match) {
- *expr = lhs;
- return PARSER_OK;
- }
+ if(!match)
+ return lhs;
binop_type = self->tokenizer.value.binop_type;
- try(parser_parse_rhs_binop(self, &rhs));
+ rhs = parser_parse_rhs_binop(self);
throw_if_error(scoped_allocator_alloc(self->allocator, sizeof(Binop), (void**)&binop));
binop_init(binop);
binop->type = binop_type;
binop->lhs = lhs;
binop->rhs = rhs;
- ast_init(expr, binop, AST_BINOP);
- return PARSER_OK;
+ throw_if_error(ast_create(self->allocator, binop, AST_BINOP, &result));
+ return result;
}
/*
@@ -445,48 +435,51 @@ RHS = RHS_BINOP ';'
Note: Parantheses count has to match for the beginning paranthesis and the ending parenthesis.
*/
-static THROWABLE parser_parse_rhs(Parser *self, Ast *rhs_expr) {
+static CHECK_RESULT Ast* parser_parse_rhs(Parser *self) {
/* TODO: If binop only contains one expression, then use that directly for @rhs_expr */
- try(parser_parse_rhs_binop(self, rhs_expr));
+ Ast *result;
+ result = parser_parse_rhs_binop(self);
/* TODO: Implement this */
/*binop_reorder_by_precedence(binop);*/
- return PARSER_OK;
+ return result;
}
/*
RHS_START = CLOSURE | IMPORT | RHS
*/
-int parser_parse_rhs_start(Parser *self, Ast *rhs_expr, bool is_standalone) {
- FunctionDecl *func_decl;
- StructDecl *struct_decl;
- Import *import;
+Ast* parser_parse_rhs_start(Parser *self, bool is_standalone) {
+ Ast *result;
if(!is_standalone) {
- try(parser_parse_function_decl(self, &func_decl));
+ FunctionDecl *func_decl;
+ StructDecl *struct_decl;
+ Import *import;
+
+ func_decl = parser_parse_closure(self);
if(func_decl) {
- ast_init(rhs_expr, func_decl, AST_FUNCTION_DECL);
- return PARSER_OK;
+ throw_if_error(ast_create(self->allocator, func_decl, AST_FUNCTION_DECL, &result));
+ return result;
}
- try(parser_parse_struct_decl(self, &struct_decl));
+ struct_decl = parser_parse_struct_decl(self);
if(struct_decl) {
- ast_init(rhs_expr, struct_decl, AST_STRUCT_DECL);
- return PARSER_OK;
+ throw_if_error(ast_create(self->allocator, struct_decl, AST_STRUCT_DECL, &result));
+ return result;
}
- try(parser_parse_import(self, &import));
+ import = parser_parse_import(self);
if(import) {
- try(parser_queue_file(self, import->path, &import->file_scope));
- ast_init(rhs_expr, import, AST_IMPORT);
- return PARSER_OK;
+ parser_queue_file(self, import->path, &import->file_scope);
+ throw_if_error(ast_create(self->allocator, import, AST_IMPORT, &result));
+ return result;
}
self->error_context = ERROR_CONTEXT_RHS_STANDALONE;
}
- try(parser_parse_rhs(self, rhs_expr));
+ result = parser_parse_rhs(self);
self->error_context = ERROR_CONTEXT_NONE;
- return PARSER_OK;
+ return result;
}
/*
@@ -494,7 +487,7 @@ BODY_SEMICOLON = ';'
Note: Semicolon is not required for closures, structs and tables
*/
-static THROWABLE parser_parse_body_semicolon(Parser *self, Ast *expr) {
+static void parser_parse_body_semicolon(Parser *self, Ast *expr) {
if(expr->type == AST_BINOP) {
bool match;
throw_if_error(tokenizer_consume_if(&self->tokenizer, TOK_SEMICOLON, &match));
@@ -505,14 +498,12 @@ static THROWABLE parser_parse_body_semicolon(Parser *self, Ast *expr) {
"Expected ';' or binop");
throw(PARSER_UNEXPECTED_TOKEN);
}
- return PARSER_OK;
+ return;
}
/* TODO: Check for tables */
if(expr->type != AST_FUNCTION_DECL && expr->type != AST_STRUCT_DECL)
throw_if_error(tokenizer_accept(&self->tokenizer, TOK_SEMICOLON));
-
- return PARSER_OK;
}
/*
@@ -520,37 +511,38 @@ BODY = LHS ';' |
(LHS '=' RHS_START BODY_SEMICOLON) |
(RHS_START BODY_SEMICOLON)
*/
-int parser_parse_body(Parser *self, Ast *ast) {
+Ast* parser_parse_body(Parser *self) {
bool assignment_or_rhs;
+ Ast *result;
LhsExpr *lhs_expr;
- Ast rhs_expr;
- rhs_expr = ast_none();
+ Ast *rhs_expr;
- try(parser_parse_lhs(self, &lhs_expr, &assignment_or_rhs));
+ lhs_expr = parser_parse_lhs(self, &assignment_or_rhs);
if(!assignment_or_rhs) {
- ast_init(ast, lhs_expr, AST_LHS);
- return PARSER_OK;
+ throw_if_error(ast_create(self->allocator, lhs_expr, AST_LHS, &result));
+ return result;
}
if(!lhs_expr)
self->error_context = ERROR_CONTEXT_NO_LHS;
- try(parser_parse_rhs_start(self, &rhs_expr, lhs_expr == NULL));
+ rhs_expr = parser_parse_rhs_start(self, !lhs_expr);
if(lhs_expr) {
lhs_expr->rhs_expr = rhs_expr;
- ast_init(ast, lhs_expr, AST_LHS);
+ throw_if_error(ast_create(self->allocator, lhs_expr, AST_LHS, &result));
} else {
- *ast = rhs_expr;
+ result = rhs_expr;
}
- try(parser_parse_body_semicolon(self, &rhs_expr));
- return PARSER_OK;
+ parser_parse_body_semicolon(self, rhs_expr);
+ return result;
}
/*
-STRUCT_BODY = LHS ';'
+STRUCT_BODY = TOK_IDENTIFIER ':' TOK_IDENTIFIER ';'
*/
-int parser_parse_struct_body(Parser *self, Ast *ast) {
+Ast* parser_parse_struct_body(Parser *self) {
+ Ast *result;
BufferView var_name;
BufferView type_name;
StructField *struct_field;
@@ -563,8 +555,8 @@ int parser_parse_struct_body(Parser *self, Ast *ast) {
throw_if_error(tokenizer_accept(&self->tokenizer, TOK_SEMICOLON));
throw_if_error(scoped_allocator_alloc(self->allocator, sizeof(LhsExpr), (void**)&struct_field));
structfield_init(struct_field, var_name, type_name);
- ast_init(ast, struct_field, AST_STRUCT_FIELD);
- return PARSER_OK;
+ throw_if_error(ast_create(self->allocator, struct_field, AST_STRUCT_FIELD, &result));
+ return result;
}
/*
@@ -575,7 +567,7 @@ int parser_parse_buffer(Parser *self, BufferView code_buffer, BufferView buffer_
throw_if_error(tokenizer_init(&self->tokenizer, self->allocator, code_buffer, buffer_name));
result = setjmp(self->parse_env);
if(result == 0)
- try(parser_parse_body_loop(self, &self->scope, TOK_END_OF_FILE));
+ parser_parse_body_loop(self, &self->scope, TOK_END_OF_FILE);
else if(self->error.str != NULL) {
switch(self->error_context) {
case ERROR_CONTEXT_NONE:
@@ -592,9 +584,8 @@ int parser_parse_buffer(Parser *self, BufferView code_buffer, BufferView buffer_
break;
}
}
- if(result != 0) {
- amal_log_info("Failed, reason: %d", result);
- }
+ if(result != 0)
+ amal_log_error("Failed, reason: %d", result);
return result;
}
@@ -626,14 +617,14 @@ static CHECK_RESULT int file_path_join(BufferView directory, BufferView file, ch
Path can be path to included library path (or system library path) in which case
the path separator is a dot, otherwise the path separator is forward slash '/'
*/
-int parser_queue_file(Parser *self, BufferView path, FileScopeReference **file_scope) {
+void parser_queue_file(Parser *self, BufferView path, FileScopeReference **file_scope) {
/* TODO: Parse special path (to include library path with dots) */
BufferView file_directory;
char *path_relative;
int result;
file_directory = file_get_parent_directory(self->tokenizer.code_name);
- return_if_error(file_path_join(file_directory, path, &path_relative));
+ throw_if_error(file_path_join(file_directory, path, &path_relative));
/* We want buffer to be null-terminated but null character should not be included for the size */
result = amal_compiler_load_file(self->compiler, path_relative, file_scope);
if(result != 0) {
@@ -644,5 +635,4 @@ int parser_queue_file(Parser *self, BufferView path, FileScopeReference **file_s
throw(result);
}
am_free(path_relative);
- return PARSER_OK;
}