From c305d4da44704d5fec592bfb1421166a3874af5c Mon Sep 17 00:00:00 2001 From: Krzosa Karol Date: Mon, 30 May 2022 09:04:34 +0200 Subject: [PATCH] Calling functions is working, same syntax as compound stmts --- ccodegen.cpp | 52 +++++++++++++++++------------ lambdas.kl | 4 ++- main.cpp | 4 +-- new_ast.cpp | 30 ++++++++--------- new_parse.cpp | 89 ++++++++++++++++++++++++------------------------- new_resolve.cpp | 34 +++++++++++++------ 6 files changed, 118 insertions(+), 95 deletions(-) diff --git a/ccodegen.cpp b/ccodegen.cpp index 9d10b8f..7636140 100644 --- a/ccodegen.cpp +++ b/ccodegen.cpp @@ -134,30 +134,40 @@ gen_expr(Ast_Expr *ast){ BREAK(); } - CASE(COMPOUND, Compound){ - gen("("); - gen_simple_decl(node->type, {}); - gen(")"); + CASE(CALL, Call){ + if(node->type == type_type){ + gen("("); + gen_simple_decl(node->type, {}); + gen(")"); - gen("{"); - For(node->exprs){ - auto comp = it[0]; - if(comp->name){ - gen("["); - gen_expr(comp->name); - gen("] = "); - } - if(comp->index){ - gen("["); - gen_expr(comp->index); - gen("] = "); - } - assert(comp->item); - gen_expr(comp->item); + gen("{"); + For(node->exprs){ + auto comp = it[0]; + if(comp->name){ + gen("["); + gen_expr(comp->name); + gen("] = "); + } + if(comp->index){ + gen("["); + gen_expr(comp->index); + gen("] = "); + } + assert(comp->item); + gen_expr(comp->item); - if(!node->exprs.is_last(it)) gen(", "); + if(!node->exprs.is_last(it)) gen(", "); + } + gen("}"); + } + else{ + gen_expr(node->name); + gen("("); + For(node->exprs){ + gen_expr(it[0]->item); + } + gen(")"); } - gen("}"); BREAK(); } diff --git a/lambdas.kl b/lambdas.kl index 997dfdc..0c1cbb7 100644 --- a/lambdas.kl +++ b/lambdas.kl @@ -21,13 +21,15 @@ add_10 :: (size: int): int return 20 constant :: 20; result := constant + 10 - return result + return add_20(result) return_constant :: (): int constant :: 10 return constant returning_void :: (insert: int) + val1: int = return_constant() + val2: int = add_10(val1) return diff --git a/main.cpp b/main.cpp index 53ded93..f25e771 100644 --- a/main.cpp +++ b/main.cpp @@ -51,9 +51,9 @@ int main(){ String result = {}; // result = compile_file("order1.kl"_s); - // result = compile_file("lambdas.kl"_s); + result = compile_file("lambdas.kl"_s); // result = compile_file("order2.kl"_s); - result = compile_file("globals.kl"_s); + // result = compile_file("globals.kl"_s); printf("%s", result.str); __debugbreak(); diff --git a/new_ast.cpp b/new_ast.cpp index 744402d..55822fc 100644 --- a/new_ast.cpp +++ b/new_ast.cpp @@ -88,8 +88,8 @@ enum Ast_Kind: U32{ AST_INDEX, AST_UNARY, AST_BINARY, - AST_COMPOUND_ITEM, - AST_COMPOUND, + AST_CALL_ITEM, + AST_CALL, AST_POINTER, AST_ARRAY, @@ -133,16 +133,16 @@ struct Ast_Atom: Ast_Expr{ }; }; -struct Ast_Compound_Item: Ast_Expr{ +struct Ast_Call_Item: Ast_Expr{ Ast_Atom *name; // index | name Ast_Expr *index; Ast_Expr *item; }; -struct Ast_Compound: Ast_Expr{ - Ast_Resolved_Type *type; - Ast_Expr *typespec; - Array exprs; +struct Ast_Call: Ast_Expr{ + Ast_Resolved_Type *type; // @todo: to map + Ast_Expr *name; + Array exprs; }; struct Ast_Unary: Ast_Expr{ @@ -283,19 +283,19 @@ ast_expr_binary(Ast_Expr *left, Ast_Expr *right, Token *op){ return result; } -function Ast_Compound * -ast_expr_compound(Token *pos, Ast_Expr *typespec, Array exprs){ - AST_NEW(Compound, COMPOUND, pos, AST_EXPR); - result->typespec = typespec; +function Ast_Call * +ast_call(Token *pos, Ast_Expr *name, Array exprs){ + AST_NEW(Call, CALL, pos, AST_EXPR); + result->name = name; result->exprs = exprs.tight_copy(pctx->perm); - if(result->typespec) result->typespec->parent = result; + if(result->name) result->name->parent = result; For(result->exprs) it[0]->parent = result; return result; } -function Ast_Compound_Item * -ast_expr_compound_item(Token *pos, Ast_Expr *index, Ast_Atom *name, Ast_Expr *item){ - AST_NEW(Compound_Item, COMPOUND_ITEM, pos, AST_EXPR); +function Ast_Call_Item * +ast_call_item(Token *pos, Ast_Expr *index, Ast_Atom *name, Ast_Expr *item){ + AST_NEW(Call_Item, CALL_ITEM, pos, AST_EXPR); result->name = name; result->index = index; result->item = item; diff --git a/new_parse.cpp b/new_parse.cpp index c4bf5bc..76b5639 100644 --- a/new_parse.cpp +++ b/new_parse.cpp @@ -116,9 +116,9 @@ atom_expr = Int | 'cast' '(' typespec ',' expr ')' | 'size_type' '(' typespec ')' | 'size_expr' '(' expr ')' -| '{' compound_expr '}' +| '{' call_expr '}' | '(' expr ')' -| '(' ':' typespec ')' '{' compound_expr '}' +| '(' ':' typespec ')' '{' call_expr '}' postfix_expr = atom_expr ('[' expr ']' | '.' Identifier | ++ | -- | '(' expr_list ')')* unary_expr = unary ? unary_expr : atom_expr mul_expr = atom_expr (mul atom_expr)* @@ -135,48 +135,6 @@ Compound literals */ function Ast_Expr *parse_expr(S64 rbp = 0); -function Ast_Compound * -parse_expr_compound(Ast_Expr *left){ - Scratch scratch; - Token *pos = token_get(); - Array exprs = {scratch}; - - while(!token_is(TK_CloseParen)){ - Token *token = token_get(); - Ast_Expr *index = 0; - Ast_Atom *name = 0; - if(token_match(TK_OpenBracket)){ - index = parse_expr(); - token_expect(TK_CloseBracket); - token_expect(TK_Assign); - } - else if(token_is(TK_Identifier)){ - token = token_next(); - name = ast_ident(token, token->intern_val); - token_expect(TK_Assign); - } - - Ast_Expr *item = parse_expr(); - Ast_Compound_Item *item_comp = ast_expr_compound_item(token, index, name, item); - exprs.add(item_comp); - - if(!token_match(TK_Comma)){ - break; - } - } - token_expect(TK_CloseParen); - - Ast_Compound *result = ast_expr_compound(pos, left, exprs); - return result; -} - -function Ast_Expr * -parse_optional_type(){ - Ast_Expr *result = 0; - if(token_match(TK_Colon)) result = parse_expr(); - return result; -} - function Ast_Init * parse_init_stmt(Ast_Expr *expr){ Token *token = token_get(); @@ -192,6 +150,44 @@ parse_init_stmt(Ast_Expr *expr){ return 0; } +function Ast_Call * +parse_expr_call(Ast_Expr *left){ + Scratch scratch; + Token *pos = token_get(); + Array exprs = {scratch}; + + while(!token_is(TK_CloseParen)){ + Token *token = token_get(); + Ast_Expr *index = 0; + Ast_Atom *name = 0; + if(token_match(TK_OpenBracket)){ + index = parse_expr(); + token_expect(TK_CloseBracket); + token_expect(TK_Assign); + } + + + Ast_Expr *item = parse_expr(); + Ast_Call_Item *item_comp = ast_call_item(token, index, name, item); + exprs.add(item_comp); + + if(!token_match(TK_Comma)){ + break; + } + } + token_expect(TK_CloseParen); + + Ast_Call *result = ast_call(pos, left, exprs); + return result; +} + +function Ast_Expr * +parse_optional_type(){ + Ast_Expr *result = 0; + if(token_match(TK_Colon)) result = parse_expr(); + return result; +} + function Ast_Named *parse_named(B32); function Ast_Block * parse_block(){ @@ -358,9 +354,9 @@ parse_expr(S64 rbp){ for(;;){ token = token_get(); + // @note: parse postfix if(postfix_binding_power(token->kind) > rbp){ token_next(); - // @note: parse postfix switch(token->kind){ case TK_OpenBracket:{ Ast_Expr *index = parse_expr(); @@ -368,7 +364,7 @@ parse_expr(S64 rbp){ token_expect(TK_CloseBracket); }break; case TK_OpenParen:{ - left = parse_expr_compound(left); + left = parse_expr_call(left); }break; default:{ if(token->kind == TK_Increment) token->kind = TK_PostIncrement; @@ -378,6 +374,7 @@ parse_expr(S64 rbp){ } } + // @note: parse right else if(rbp < left_binding_power(token->kind)){ token = token_next(); left = left_denotation(token, left); diff --git a/new_resolve.cpp b/new_resolve.cpp index 5ec02ee..17b70b4 100644 --- a/new_resolve.cpp +++ b/new_resolve.cpp @@ -350,11 +350,13 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){ BREAK(); } - CASE(COMPOUND, Compound){ - Ast_Resolved_Type *type = resolve_typespec(node->typespec, AST_CAN_BE_NULL); - if(!type && expected_type) type = expected_type; - else if(!expected_type && type); - else if(expected_type != type) parsing_error(node->pos, "Variable type different from explicit compound type"); + CASE(CALL, Call){ + Operand name = resolve_expr(node->name); + Ast_Resolved_Type *type = name.type; + if(name.type == type_type){ + type = name.type_val; + if(expected_type && expected_type != type) parsing_error(node->pos, "Variable type different from explicit compound type"); + } node->type = type; if(type->kind == TYPE_ARRAY){ @@ -362,9 +364,8 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){ Ast_Resolved_Type *item_type = type->arr.base; For(node->exprs){ - assert(it[0]->kind == AST_COMPOUND_ITEM); - Ast_Compound_Item *i = (Ast_Compound_Item *)it[0]; - assert(i->kind == AST_COMPOUND_ITEM); + Ast_Call_Item *i = (Ast_Call_Item *)it[0]; + assert(i->kind == AST_CALL_ITEM); if(i->name) parsing_error(i->pos, "Invalid indexing kind in a compound expression of type %s", type_names[type->kind]); if(i->index){ Operand index_op = resolve_expr(i->index); @@ -376,7 +377,20 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){ resolve_type_pair(i->pos, expr.type, item_type); } } - else parsing_error(node->pos, "Invalid compound expression type"); + else if(type->kind == TYPE_LAMBDA){ + if(type->func.args.len != node->exprs.len) parsing_error(node->pos, "Invalid number of arguments"); + For(node->exprs){ + Ast_Call_Item *i = (Ast_Call_Item *)it[0]; + assert(i->kind == AST_CALL_ITEM); + + S64 index = node->exprs.get_index(it); + Operand expr = resolve_expr(i->item); + if(expr.type != type->func.args[index]) parsing_error(i->pos, "Type is not matching function definition"); + } + + type = type->func.ret; + } + else parsing_error(node->pos, "Invalid function call type"); Operand result = {type, false}; return result; @@ -457,7 +471,7 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){ BREAK(); } - // @todo: add const prepass? expecting only structs, exprs, lambdas + // @todo: add const first level function? expecting only structs, exprs, lambdas CASE(STRUCT, Struct){ assert(const_sym);