Compiling global, work on AST_LAMBDA_EXPR
This commit is contained in:
5
ast.cpp
5
ast.cpp
@@ -152,7 +152,7 @@ struct Ast_Lambda : Ast_Expr {
|
|||||||
Array<Ast_Decl *> args;
|
Array<Ast_Decl *> args;
|
||||||
Ast_Expr *ret;
|
Ast_Expr *ret;
|
||||||
Ast_Scope *scope;
|
Ast_Scope *scope;
|
||||||
B32 has_var_args;
|
Ast_Resolved_Type *type;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Ast_Array: Ast_Expr{
|
struct Ast_Array: Ast_Expr{
|
||||||
@@ -327,13 +327,12 @@ ast_expr_index(Token *pos, Ast_Expr *expr, Ast_Expr *index){
|
|||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Lambda *
|
function Ast_Lambda *
|
||||||
ast_lambda(Token *pos, Array<Ast_Decl *> params, B32 has_var_args, Ast_Expr *ret, Ast_Scope *scope){
|
ast_lambda(Token *pos, Array<Ast_Decl *> params, Ast_Expr *ret, Ast_Scope *scope){
|
||||||
AST_NEW(Lambda, LAMBDA_EXPR, pos, AST_EXPR);
|
AST_NEW(Lambda, LAMBDA_EXPR, pos, AST_EXPR);
|
||||||
result->flags = AST_EXPR;
|
result->flags = AST_EXPR;
|
||||||
result->args = params.tight_copy(pctx->perm);
|
result->args = params.tight_copy(pctx->perm);
|
||||||
result->scope = scope;
|
result->scope = scope;
|
||||||
result->ret = ret;
|
result->ret = ret;
|
||||||
result->has_var_args = has_var_args;
|
|
||||||
if(!ret) result->ret = ast_ident(result->pos, intern_void);
|
if(!ret) result->ret = ast_ident(result->pos, intern_void);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
137
ccodegen.cpp
137
ccodegen.cpp
@@ -5,12 +5,19 @@ global S32 global_indent;
|
|||||||
global S32 is_inside_struct;
|
global S32 is_inside_struct;
|
||||||
|
|
||||||
function void gen_ast(Ast *ast);
|
function void gen_ast(Ast *ast);
|
||||||
|
function void gen_expr(Ast_Expr *ast);
|
||||||
|
|
||||||
function void
|
function void
|
||||||
gen_indent(){
|
gen_indent(){
|
||||||
for(S32 i = 0; i < global_indent; i++) gen(" ");
|
for(S32 i = 0; i < global_indent; i++) gen(" ");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function void
|
||||||
|
gen_line(Ast *node){
|
||||||
|
if(emit_line_directives)
|
||||||
|
genln("#line %d", node->pos->line+1);
|
||||||
|
}
|
||||||
|
|
||||||
// @todo: Gen complicated decl
|
// @todo: Gen complicated decl
|
||||||
//array 10 ( pointer (pointer array 5 int a))
|
//array 10 ( pointer (pointer array 5 int a))
|
||||||
// int (*(*(a[5])))[10]
|
// int (*(*(a[5])))[10]
|
||||||
@@ -91,6 +98,60 @@ gen_value(Value a){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function void
|
||||||
|
gen_stmt_scope(Ast_Scope *scope){
|
||||||
|
gen("{");
|
||||||
|
global_indent++;
|
||||||
|
For(scope->stmts) {
|
||||||
|
gen_line(it);
|
||||||
|
genln("");
|
||||||
|
gen_ast(it);
|
||||||
|
}
|
||||||
|
global_indent--;
|
||||||
|
genln("}");
|
||||||
|
}
|
||||||
|
|
||||||
|
enum {
|
||||||
|
ALWAYS_EMIT_VALUE = 0,
|
||||||
|
DONT_EMIT_VALUE = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
function void
|
||||||
|
gen_var(Intern_String name, Ast_Resolved_Type *type, Ast_Expr *expr, B32 emit_value){
|
||||||
|
gen_simple_decl(type, name);
|
||||||
|
|
||||||
|
if(emit_value == DONT_EMIT_VALUE){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(expr){
|
||||||
|
gen(" = ");
|
||||||
|
gen_expr(expr);
|
||||||
|
} else { // Default zero
|
||||||
|
if(is_numeric(type)){
|
||||||
|
gen(" = 0");
|
||||||
|
} else {
|
||||||
|
gen(" = {}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function void
|
||||||
|
gen_lambda(Intern_String name, Ast_Lambda *lambda){
|
||||||
|
gen_simple_decl(lambda->type->func.ret, name);
|
||||||
|
gen("(");
|
||||||
|
For(lambda->args){
|
||||||
|
gen_var(it->name, it->type, 0, DONT_EMIT_VALUE);
|
||||||
|
if(&it != (lambda->args.end() - 1)) gen(", ");
|
||||||
|
}
|
||||||
|
gen(")");
|
||||||
|
|
||||||
|
if(lambda->scope) {
|
||||||
|
gen_stmt_scope(lambda->scope);
|
||||||
|
}
|
||||||
|
else gen(";");
|
||||||
|
}
|
||||||
|
|
||||||
function void
|
function void
|
||||||
gen_expr(Ast_Expr *ast){
|
gen_expr(Ast_Expr *ast){
|
||||||
switch(ast->kind){
|
switch(ast->kind){
|
||||||
@@ -115,6 +176,11 @@ gen_expr(Ast_Expr *ast){
|
|||||||
BREAK();
|
BREAK();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CASE(LAMBDA_EXPR, Lambda){
|
||||||
|
gen_lambda({}, node);
|
||||||
|
BREAK();
|
||||||
|
}
|
||||||
|
|
||||||
CASE(BINARY, Binary){
|
CASE(BINARY, Binary){
|
||||||
if(node->op == TK_Dot){
|
if(node->op == TK_Dot){
|
||||||
gen_expr(node->left);
|
gen_expr(node->left);
|
||||||
@@ -172,50 +238,6 @@ gen_expr(Ast_Expr *ast){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
|
||||||
gen_line(Ast *node){
|
|
||||||
if(emit_line_directives)
|
|
||||||
genln("#line %d", node->pos->line+1);
|
|
||||||
}
|
|
||||||
|
|
||||||
function void
|
|
||||||
gen_stmt_scope(Ast_Scope *scope){
|
|
||||||
gen("{");
|
|
||||||
global_indent++;
|
|
||||||
For(scope->stmts) {
|
|
||||||
gen_line(it);
|
|
||||||
genln("");
|
|
||||||
gen_ast(it);
|
|
||||||
}
|
|
||||||
global_indent--;
|
|
||||||
genln("}");
|
|
||||||
}
|
|
||||||
|
|
||||||
enum {
|
|
||||||
ALWAYS_EMIT_VALUE = 0,
|
|
||||||
DONT_EMIT_VALUE = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
function void
|
|
||||||
gen_var(Intern_String name, Ast_Resolved_Type *type, Ast_Expr *expr, B32 emit_value){
|
|
||||||
gen_simple_decl(type, name);
|
|
||||||
|
|
||||||
if(emit_value == DONT_EMIT_VALUE){
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(expr){
|
|
||||||
gen(" = ");
|
|
||||||
gen_expr(expr);
|
|
||||||
} else { // Default zero
|
|
||||||
if(is_numeric(type)){
|
|
||||||
gen(" = 0");
|
|
||||||
} else {
|
|
||||||
gen(" = {}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function void
|
function void
|
||||||
gen_ast(Ast *ast){
|
gen_ast(Ast *ast){
|
||||||
switch(ast->kind){
|
switch(ast->kind){
|
||||||
@@ -283,31 +305,10 @@ gen_ast(Ast *ast){
|
|||||||
}
|
}
|
||||||
|
|
||||||
CASE(LAMBDA, Decl){
|
CASE(LAMBDA, Decl){
|
||||||
if(node->kind == AST_LAMBDA){
|
if(is_flag_set(node->flags, AST_FOREIGN)){
|
||||||
if(is_flag_set(node->flags, AST_FOREIGN)){
|
gen("/*foreign*/");
|
||||||
return;
|
|
||||||
}
|
|
||||||
Ast_Lambda *lambda = node->lambda;
|
|
||||||
Ast_Resolved_Type *ret = node->type->func.ret;
|
|
||||||
gen_simple_decl(ret, node->name);
|
|
||||||
gen("(");
|
|
||||||
For(lambda->args){
|
|
||||||
gen_var(it->name, it->type, 0, DONT_EMIT_VALUE);
|
|
||||||
if(&it != (lambda->args.end() - 1)) gen(", ");
|
|
||||||
}
|
|
||||||
gen(")");
|
|
||||||
|
|
||||||
if(lambda->scope) {
|
|
||||||
gen_stmt_scope(lambda->scope);
|
|
||||||
}
|
|
||||||
else gen(";");
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
gen_simple_decl(node->type, node->name);
|
|
||||||
gen(" = ");
|
|
||||||
gen_expr((Ast_Expr *)node->expr);
|
|
||||||
gen(";");
|
|
||||||
}
|
}
|
||||||
|
gen_lambda(node->name, node->lambda);
|
||||||
BREAK();
|
BREAK();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
11
globals.kl
11
globals.kl
@@ -21,16 +21,7 @@ Boolean: Bool = true
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Compound expressions
|
// Compound expressions
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
array1: [4]S64 = [4]S64(1,2,3,4)
|
array1: [4]S64
|
||||||
array2 := [32]S64(1,2,3,4)
|
|
||||||
array3 := [32]S64(
|
|
||||||
[0] = 0,
|
|
||||||
[1] = 1,
|
|
||||||
[2] = 2,
|
|
||||||
[31] = 31,
|
|
||||||
)
|
|
||||||
array_item := array1[0]
|
|
||||||
array_item_imp: S64 = array2[2]
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Pointers
|
// Pointers
|
||||||
|
|||||||
11
main.cpp
11
main.cpp
@@ -201,17 +201,7 @@ int main(int argument_count, char **arguments){
|
|||||||
system((const char *)run_program.str);
|
system((const char *)run_program.str);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
String result = {};
|
|
||||||
#if 1
|
|
||||||
result = compile_file("globals.kl"_s);
|
|
||||||
printf("%s", result.str);
|
|
||||||
result = compile_file("enums.kl"_s);
|
|
||||||
printf("%s", result.str);
|
|
||||||
|
|
||||||
|
|
||||||
result = compile_file("new_types.kl"_s);
|
|
||||||
printf("%s", result.str);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
Scratch scratch;
|
Scratch scratch;
|
||||||
@@ -221,6 +211,7 @@ int main(int argument_count, char **arguments){
|
|||||||
files.add("order2.kl"_s);
|
files.add("order2.kl"_s);
|
||||||
files.add("new_types.kl"_s);
|
files.add("new_types.kl"_s);
|
||||||
files.add("enums.kl"_s);
|
files.add("enums.kl"_s);
|
||||||
|
files.add("globals.kl"_s);
|
||||||
String result = compile_files(files);
|
String result = compile_files(files);
|
||||||
printf("%s", result.str);
|
printf("%s", result.str);
|
||||||
__debugbreak();
|
__debugbreak();
|
||||||
|
|||||||
@@ -321,7 +321,7 @@ parse_lambda(Token *token){
|
|||||||
|
|
||||||
Ast_Expr *ret = parse_optional_type();
|
Ast_Expr *ret = parse_optional_type();
|
||||||
Ast_Scope *scope = token_is(OPEN_SCOPE) ? parse_stmt_scope() : 0;
|
Ast_Scope *scope = token_is(OPEN_SCOPE) ? parse_stmt_scope() : 0;
|
||||||
Ast_Lambda *result = ast_lambda(token, params, has_var_args, ret, scope);
|
Ast_Lambda *result = ast_lambda(token, params, ret, scope);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -496,6 +496,41 @@ resolve_stmt(Ast *ast, Ast_Resolved_Type *ret){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function Ast_Resolved_Type *
|
||||||
|
resolve_lambda_type(Ast_Lambda *lambda){
|
||||||
|
Scratch scratch;
|
||||||
|
Ast_Resolved_Type *ret_type = resolve_typespec(lambda->ret, AST_CANT_BE_NULL);
|
||||||
|
Array<Ast_Resolved_Type *> args = {scratch};
|
||||||
|
|
||||||
|
For(lambda->args){
|
||||||
|
Ast_Resolved_Type *type = resolve_typespec(it->typespec, AST_CANT_BE_NULL);
|
||||||
|
Operand default_value = resolve_expr(it->expr, AST_CAN_BE_NULL);
|
||||||
|
make_sure_value_is_compatible_with_type(it->pos, &default_value, type, EXPR_CAN_BE_NULL);
|
||||||
|
it->type = type;
|
||||||
|
args.add(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
return type_lambda(lambda, ret_type, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
function void
|
||||||
|
try_resolving_lambda_scope(Operand *op, Ast_Lambda *lambda, Ast_Resolved_Type *lambda_type){
|
||||||
|
if(lambda->scope){
|
||||||
|
For(lambda->args){
|
||||||
|
insert_into_scope(lambda->scope, it);
|
||||||
|
}
|
||||||
|
For(lambda->scope->stmts){
|
||||||
|
resolve_stmt(it, lambda_type->func.ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
*op = operand_lambda(lambda_type);
|
||||||
|
}
|
||||||
|
else if(is_flag_set(lambda->flags, AST_FOREIGN)){
|
||||||
|
// @todo: Add foreign
|
||||||
|
*op = operand_lambda(lambda_type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function Operand
|
function Operand
|
||||||
resolve_cast(Ast_Cast *node){
|
resolve_cast(Ast_Cast *node){
|
||||||
Operand expr = resolve_expr(node->expr, AST_CANT_BE_NULL);
|
Operand expr = resolve_expr(node->expr, AST_CANT_BE_NULL);
|
||||||
@@ -637,6 +672,14 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags){
|
|||||||
BREAK();
|
BREAK();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CASE(LAMBDA_EXPR, Lambda){
|
||||||
|
node->type = resolve_lambda_type(node);
|
||||||
|
Operand result = operand_type(node->type);
|
||||||
|
try_resolving_lambda_scope(&result, node, node->type);
|
||||||
|
return result;
|
||||||
|
BREAK();
|
||||||
|
}
|
||||||
|
|
||||||
CASE(INDEX, Index){
|
CASE(INDEX, Index){
|
||||||
Operand left = resolve_expr(node->expr, AST_CANT_BE_NULL);
|
Operand left = resolve_expr(node->expr, AST_CANT_BE_NULL);
|
||||||
Operand index = resolve_expr(node->index, AST_CANT_BE_NULL);
|
Operand index = resolve_expr(node->index, AST_CANT_BE_NULL);
|
||||||
@@ -811,45 +854,16 @@ resolve_decl(Ast_Decl *ast){
|
|||||||
switch(ast->kind){
|
switch(ast->kind){
|
||||||
CASE(LAMBDA, Decl){
|
CASE(LAMBDA, Decl){
|
||||||
Ast_Lambda *lambda = node->lambda;
|
Ast_Lambda *lambda = node->lambda;
|
||||||
|
lambda->type = resolve_lambda_type(lambda);
|
||||||
Scratch scratch;
|
Operand result = operand_type(lambda->type);
|
||||||
Ast_Resolved_Type *lambda_type = 0;
|
|
||||||
Ast_Resolved_Type *ret_type = resolve_typespec(lambda->ret, AST_CANT_BE_NULL);
|
|
||||||
Array<Ast_Resolved_Type *> args = {scratch};
|
|
||||||
|
|
||||||
For(lambda->args){
|
|
||||||
Ast_Resolved_Type *type = resolve_typespec(it->typespec, AST_CANT_BE_NULL);
|
|
||||||
Operand default_value = resolve_expr(it->expr, AST_CAN_BE_NULL);
|
|
||||||
make_sure_value_is_compatible_with_type(it->pos, &default_value, type, EXPR_CAN_BE_NULL);
|
|
||||||
it->type = type;
|
|
||||||
args.add(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
lambda_type = type_lambda(lambda, ret_type, args);
|
|
||||||
Operand result = operand_type(lambda_type);
|
|
||||||
|
|
||||||
// @note: top level lambda needs to get marked as resolved
|
// @note: top level lambda needs to get marked as resolved
|
||||||
// so that the cyclic dependency wont trigger
|
// so that the cyclic dependency wont trigger
|
||||||
node->type = lambda_type;
|
node->type = lambda->type;
|
||||||
node->state = DECL_RESOLVED;
|
node->state = DECL_RESOLVED;
|
||||||
|
|
||||||
// @todo: We also need to make sure there is a return value when ret type is not void
|
// @todo: We also need to make sure there is a return value when ret type is not void
|
||||||
// @note: then try resolving the block of lambda
|
try_resolving_lambda_scope(&result, lambda, node->type);
|
||||||
if(lambda->scope){
|
|
||||||
For(lambda->args){
|
|
||||||
insert_into_scope(lambda->scope, it);
|
|
||||||
}
|
|
||||||
For(lambda->scope->stmts){
|
|
||||||
resolve_stmt(it, ret_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
result = operand_lambda(lambda_type);
|
|
||||||
}
|
|
||||||
else if(is_flag_set(lambda->flags, AST_FOREIGN)){
|
|
||||||
// @todo: Add foreign
|
|
||||||
result = operand_lambda(lambda_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
node->value = result.value;
|
node->value = result.value;
|
||||||
BREAK();
|
BREAK();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user