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,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();
}

View File

@@ -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

View File

@@ -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();

View File

@@ -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<Ast_Compound_Item *> exprs;
struct Ast_Call: Ast_Expr{
Ast_Resolved_Type *type; // @todo: to map
Ast_Expr *name;
Array<Ast_Call_Item *> 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<Ast_Compound_Item *> exprs){
AST_NEW(Compound, COMPOUND, pos, AST_EXPR);
result->typespec = typespec;
function Ast_Call *
ast_call(Token *pos, Ast_Expr *name, Array<Ast_Call_Item *> 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;

View File

@@ -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<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 *
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<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_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);

View File

@@ -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);