From 7212ea877ed85d3b85af90c902639df44fc493f2 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Sat, 24 Aug 2019 00:48:40 +0200 Subject: Add exported variable (only functions for now), export main func, start execution from main func --- src/parser.c | 38 +++++++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 11 deletions(-) (limited to 'src/parser.c') diff --git a/src/parser.c b/src/parser.c index 85165d7..ff34663 100644 --- a/src/parser.c +++ b/src/parser.c @@ -267,12 +267,13 @@ void parser_parse_var_type_def(Parser *self, VariableType *result) { } /* -LHS_DECLARATION = 'extern'? 'pub'? 'const'|'var' TOK_IDENTIFIER VAR_TYPE_DEF? +LHS_DECLARATION = ('extern'|'export')? 'pub'? 'const'|'var' TOK_IDENTIFIER VAR_TYPE_DEF? */ static CHECK_RESULT LhsExpr* parser_parse_declaration_lhs(Parser *self) { LhsExpr *result; DeclFlag decl_flag; bool is_extern; + bool is_export; bool is_pub; bool is_const; BufferView var_name; @@ -283,10 +284,21 @@ static CHECK_RESULT LhsExpr* parser_parse_declaration_lhs(Parser *self) { decl_flag |= DECL_FLAG_EXTERN; if(self->has_func_parent) { self->error = tokenizer_create_error(&self->tokenizer, - tokenizer_get_code_reference_index(&self->tokenizer, self->tokenizer.value.identifier.data), + tokenizer_get_error_index(&self->tokenizer), "Only declarations in global structs can be extern"); throw(PARSER_UNEXPECTED_TOKEN); } + } else { + throw_if_error(tokenizer_consume_if(&self->tokenizer, TOK_EXPORT, &is_export)); + if(is_export) { + decl_flag |= DECL_FLAG_EXPORT; + if(self->has_func_parent) { + self->error = tokenizer_create_error(&self->tokenizer, + tokenizer_get_error_index(&self->tokenizer), + "Only declarations in global structs can be exported"); + throw(PARSER_UNEXPECTED_TOKEN); + } + } } throw_if_error(tokenizer_consume_if(&self->tokenizer, TOK_PUB, &is_pub)); @@ -294,7 +306,7 @@ static CHECK_RESULT LhsExpr* parser_parse_declaration_lhs(Parser *self) { decl_flag |= DECL_FLAG_PUB; if(self->has_func_parent) { self->error = tokenizer_create_error(&self->tokenizer, - tokenizer_get_code_reference_index(&self->tokenizer, self->tokenizer.value.identifier.data), + tokenizer_get_error_index(&self->tokenizer), "Only declarations in global structs can be public"); throw(PARSER_UNEXPECTED_TOKEN); } @@ -306,10 +318,10 @@ static CHECK_RESULT LhsExpr* parser_parse_declaration_lhs(Parser *self) { } else { bool isVar; - if(is_extern) { + if(is_extern || is_export) { self->error = tokenizer_create_error(&self->tokenizer, - tokenizer_get_code_reference_index(&self->tokenizer, self->tokenizer.value.identifier.data), - "Extern variable have to be declared with \"const\""); + tokenizer_get_error_index(&self->tokenizer), + "Extern and exported variables have to be declared with \"const\""); throw(PARSER_UNEXPECTED_TOKEN); } @@ -732,10 +744,10 @@ static Ast* parser_parse_lhs_rhs(Parser *self, LhsExpr *lhs_expr) { func_decl = parser_parse_closure(self); if(func_decl) { - if(buffer_get_size(&func_decl->signature->return_types, FunctionReturnType) > 1 && LHS_EXPR_IS_EXTERN(lhs_expr)) { + if(buffer_get_size(&func_decl->signature->return_types, FunctionReturnType) > 1 && (LHS_EXPR_IS_EXTERN(lhs_expr) || LHS_EXPR_IS_EXPORT(lhs_expr))) { self->error = tokenizer_create_error(&self->tokenizer, tokenizer_get_code_reference_index(&self->tokenizer, lhs_expr->var_name.data), - "Extern closure can only have one return value"); + "Extern and export closures can only have one return value"); throw(PARSER_ERR); } throw_if_error(ast_create(self->allocator, func_decl, AST_FUNCTION_DECL, &result)); @@ -796,7 +808,7 @@ Ast* parser_parse_body(Parser *self) { if(LHS_EXPR_IS_EXTERN(lhs_expr)) { throw_if_error(tokenizer_accept(&self->tokenizer, TOK_SEMICOLON)); if (lhs_expr->type.type == VARIABLE_TYPE_NONE) { - self->error = tokenizer_create_error(&self->tokenizer, self->tokenizer.prev_index, "A variable can't be declared without a type or assignment"); + self->error = tokenizer_create_error(&self->tokenizer, tokenizer_get_code_reference_index(&self->tokenizer, lhs_expr->var_name.data), "An extern variable can't be declared without a type"); throw(PARSER_UNEXPECTED_TOKEN); } return result; @@ -804,10 +816,14 @@ Ast* parser_parse_body(Parser *self) { throw_if_error(tokenizer_consume_if(&self->tokenizer, TOK_SEMICOLON, &match)); if(match) { if(lhs_expr->type.type == VARIABLE_TYPE_SIGNATURE) { - self->error = tokenizer_create_error(&self->tokenizer, self->tokenizer.prev_index, "Expected function declaration. Only extern functions can have empty declarations."); + self->error = tokenizer_create_error(&self->tokenizer, tokenizer_get_code_reference_index(&self->tokenizer, lhs_expr->var_name.data), "Expected function declaration. Only extern functions can have empty declarations."); throw(PARSER_UNEXPECTED_TOKEN); } else if (lhs_expr->type.type == VARIABLE_TYPE_NONE) { - self->error = tokenizer_create_error(&self->tokenizer, self->tokenizer.prev_index, "A variable can't be declared without a type or assignment"); + /* TODO: Allow this for non-const variables */ + self->error = tokenizer_create_error(&self->tokenizer, tokenizer_get_code_reference_index(&self->tokenizer, lhs_expr->var_name.data), "A variable can't be declared without a type or assignment"); + throw(PARSER_UNEXPECTED_TOKEN); + } else if(LHS_EXPR_IS_CONST(lhs_expr)) { + self->error = tokenizer_create_error(&self->tokenizer, tokenizer_get_code_reference_index(&self->tokenizer, lhs_expr->var_name.data), "A const variable can't be declared without assignment"); throw(PARSER_UNEXPECTED_TOKEN); } return result; -- cgit v1.2.3