Calling functions is working, same syntax as compound stmts

This commit is contained in:
Krzosa Karol
2022-05-30 09:04:34 +02:00
parent 802dce749e
commit c305d4da44
6 changed files with 118 additions and 95 deletions

View File

@@ -134,7 +134,8 @@ gen_expr(Ast_Expr *ast){
BREAK(); BREAK();
} }
CASE(COMPOUND, Compound){ CASE(CALL, Call){
if(node->type == type_type){
gen("("); gen("(");
gen_simple_decl(node->type, {}); gen_simple_decl(node->type, {});
gen(")"); gen(")");
@@ -158,6 +159,15 @@ gen_expr(Ast_Expr *ast){
if(!node->exprs.is_last(it)) gen(", "); if(!node->exprs.is_last(it)) gen(", ");
} }
gen("}"); gen("}");
}
else{
gen_expr(node->name);
gen("(");
For(node->exprs){
gen_expr(it[0]->item);
}
gen(")");
}
BREAK(); BREAK();
} }

View File

@@ -21,13 +21,15 @@ add_10 :: (size: int): int
return 20 return 20
constant :: 20; result := constant + 10 constant :: 20; result := constant + 10
return result return add_20(result)
return_constant :: (): int return_constant :: (): int
constant :: 10 constant :: 10
return constant return constant
returning_void :: (insert: int) returning_void :: (insert: int)
val1: int = return_constant()
val2: int = add_10(val1)
return return

View File

@@ -51,9 +51,9 @@ int main(){
String result = {}; String result = {};
// result = compile_file("order1.kl"_s); // 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("order2.kl"_s);
result = compile_file("globals.kl"_s); // result = compile_file("globals.kl"_s);
printf("%s", result.str); printf("%s", result.str);
__debugbreak(); __debugbreak();

View File

@@ -88,8 +88,8 @@ enum Ast_Kind: U32{
AST_INDEX, AST_INDEX,
AST_UNARY, AST_UNARY,
AST_BINARY, AST_BINARY,
AST_COMPOUND_ITEM, AST_CALL_ITEM,
AST_COMPOUND, AST_CALL,
AST_POINTER, AST_POINTER,
AST_ARRAY, 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_Atom *name; // index | name
Ast_Expr *index; Ast_Expr *index;
Ast_Expr *item; Ast_Expr *item;
}; };
struct Ast_Compound: Ast_Expr{ struct Ast_Call: Ast_Expr{
Ast_Resolved_Type *type; Ast_Resolved_Type *type; // @todo: to map
Ast_Expr *typespec; Ast_Expr *name;
Array<Ast_Compound_Item *> exprs; Array<Ast_Call_Item *> exprs;
}; };
struct Ast_Unary: Ast_Expr{ struct Ast_Unary: Ast_Expr{
@@ -283,19 +283,19 @@ ast_expr_binary(Ast_Expr *left, Ast_Expr *right, Token *op){
return result; return result;
} }
function Ast_Compound * function Ast_Call *
ast_expr_compound(Token *pos, Ast_Expr *typespec, Array<Ast_Compound_Item *> exprs){ ast_call(Token *pos, Ast_Expr *name, Array<Ast_Call_Item *> exprs){
AST_NEW(Compound, COMPOUND, pos, AST_EXPR); AST_NEW(Call, CALL, pos, AST_EXPR);
result->typespec = typespec; result->name = name;
result->exprs = exprs.tight_copy(pctx->perm); 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; For(result->exprs) it[0]->parent = result;
return result; return result;
} }
function Ast_Compound_Item * function Ast_Call_Item *
ast_expr_compound_item(Token *pos, Ast_Expr *index, Ast_Atom *name, Ast_Expr *item){ ast_call_item(Token *pos, Ast_Expr *index, Ast_Atom *name, Ast_Expr *item){
AST_NEW(Compound_Item, COMPOUND_ITEM, pos, AST_EXPR); AST_NEW(Call_Item, CALL_ITEM, pos, AST_EXPR);
result->name = name; result->name = name;
result->index = index; result->index = index;
result->item = item; result->item = item;

View File

@@ -116,9 +116,9 @@ atom_expr = Int
| 'cast' '(' typespec ',' expr ')' | 'cast' '(' typespec ',' expr ')'
| 'size_type' '(' typespec ')' | 'size_type' '(' typespec ')'
| 'size_expr' '(' expr ')' | 'size_expr' '(' expr ')'
| '{' compound_expr '}' | '{' call_expr '}'
| '(' expr ')' | '(' expr ')'
| '(' ':' typespec ')' '{' compound_expr '}' | '(' ':' typespec ')' '{' call_expr '}'
postfix_expr = atom_expr ('[' expr ']' | '.' Identifier | ++ | -- | '(' expr_list ')')* postfix_expr = atom_expr ('[' expr ']' | '.' Identifier | ++ | -- | '(' expr_list ')')*
unary_expr = unary ? unary_expr : atom_expr unary_expr = unary ? unary_expr : atom_expr
mul_expr = atom_expr (mul 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_Expr *parse_expr(S64 rbp = 0);
function Ast_Compound *
parse_expr_compound(Ast_Expr *left){
Scratch scratch;
Token *pos = token_get();
Array<Ast_Compound_Item *> 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 * function Ast_Init *
parse_init_stmt(Ast_Expr *expr){ parse_init_stmt(Ast_Expr *expr){
Token *token = token_get(); Token *token = token_get();
@@ -192,6 +150,44 @@ parse_init_stmt(Ast_Expr *expr){
return 0; return 0;
} }
function Ast_Call *
parse_expr_call(Ast_Expr *left){
Scratch scratch;
Token *pos = token_get();
Array<Ast_Call_Item *> 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_Named *parse_named(B32);
function Ast_Block * function Ast_Block *
parse_block(){ parse_block(){
@@ -358,9 +354,9 @@ parse_expr(S64 rbp){
for(;;){ for(;;){
token = token_get(); token = token_get();
// @note: parse postfix
if(postfix_binding_power(token->kind) > rbp){ if(postfix_binding_power(token->kind) > rbp){
token_next(); token_next();
// @note: parse postfix
switch(token->kind){ switch(token->kind){
case TK_OpenBracket:{ case TK_OpenBracket:{
Ast_Expr *index = parse_expr(); Ast_Expr *index = parse_expr();
@@ -368,7 +364,7 @@ parse_expr(S64 rbp){
token_expect(TK_CloseBracket); token_expect(TK_CloseBracket);
}break; }break;
case TK_OpenParen:{ case TK_OpenParen:{
left = parse_expr_compound(left); left = parse_expr_call(left);
}break; }break;
default:{ default:{
if(token->kind == TK_Increment) token->kind = TK_PostIncrement; 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)){ else if(rbp < left_binding_power(token->kind)){
token = token_next(); token = token_next();
left = left_denotation(token, left); left = left_denotation(token, left);

View File

@@ -350,11 +350,13 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){
BREAK(); BREAK();
} }
CASE(COMPOUND, Compound){ CASE(CALL, Call){
Ast_Resolved_Type *type = resolve_typespec(node->typespec, AST_CAN_BE_NULL); Operand name = resolve_expr(node->name);
if(!type && expected_type) type = expected_type; Ast_Resolved_Type *type = name.type;
else if(!expected_type && type); if(name.type == type_type){
else if(expected_type != type) parsing_error(node->pos, "Variable type different from explicit compound 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; node->type = type;
if(type->kind == TYPE_ARRAY){ 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; Ast_Resolved_Type *item_type = type->arr.base;
For(node->exprs){ For(node->exprs){
assert(it[0]->kind == AST_COMPOUND_ITEM); Ast_Call_Item *i = (Ast_Call_Item *)it[0];
Ast_Compound_Item *i = (Ast_Compound_Item *)it[0]; assert(i->kind == AST_CALL_ITEM);
assert(i->kind == AST_COMPOUND_ITEM);
if(i->name) parsing_error(i->pos, "Invalid indexing kind in a compound expression of type %s", type_names[type->kind]); if(i->name) parsing_error(i->pos, "Invalid indexing kind in a compound expression of type %s", type_names[type->kind]);
if(i->index){ if(i->index){
Operand index_op = resolve_expr(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); 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}; Operand result = {type, false};
return result; return result;
@@ -457,7 +471,7 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){
BREAK(); BREAK();
} }
// @todo: add const prepass? expecting only structs, exprs, lambdas // @todo: add const first level function? expecting only structs, exprs, lambdas
CASE(STRUCT, Struct){ CASE(STRUCT, Struct){
assert(const_sym); assert(const_sym);