Calling functions is working, same syntax as compound stmts
This commit is contained in:
52
ccodegen.cpp
52
ccodegen.cpp
@@ -134,30 +134,40 @@ gen_expr(Ast_Expr *ast){
|
|||||||
BREAK();
|
BREAK();
|
||||||
}
|
}
|
||||||
|
|
||||||
CASE(COMPOUND, Compound){
|
CASE(CALL, Call){
|
||||||
gen("(");
|
if(node->type == type_type){
|
||||||
gen_simple_decl(node->type, {});
|
gen("(");
|
||||||
gen(")");
|
gen_simple_decl(node->type, {});
|
||||||
|
gen(")");
|
||||||
|
|
||||||
gen("{");
|
gen("{");
|
||||||
For(node->exprs){
|
For(node->exprs){
|
||||||
auto comp = it[0];
|
auto comp = it[0];
|
||||||
if(comp->name){
|
if(comp->name){
|
||||||
gen("[");
|
gen("[");
|
||||||
gen_expr(comp->name);
|
gen_expr(comp->name);
|
||||||
gen("] = ");
|
gen("] = ");
|
||||||
}
|
}
|
||||||
if(comp->index){
|
if(comp->index){
|
||||||
gen("[");
|
gen("[");
|
||||||
gen_expr(comp->index);
|
gen_expr(comp->index);
|
||||||
gen("] = ");
|
gen("] = ");
|
||||||
}
|
}
|
||||||
assert(comp->item);
|
assert(comp->item);
|
||||||
gen_expr(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();
|
BREAK();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
4
main.cpp
4
main.cpp
@@ -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();
|
||||||
|
|||||||
30
new_ast.cpp
30
new_ast.cpp
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user