Functions have unique names now unless they are foreign, probably will
need a keyword to not mangle the names.
This commit is contained in:
@@ -264,6 +264,7 @@ enum Ast_Decl_State{
|
|||||||
struct Ast_Decl: Ast{
|
struct Ast_Decl: Ast{
|
||||||
Ast_Decl_State state;
|
Ast_Decl_State state;
|
||||||
Intern_String name;
|
Intern_String name;
|
||||||
|
Intern_String unique_name; // For code generation
|
||||||
|
|
||||||
Ast_Scope *scope;
|
Ast_Scope *scope;
|
||||||
Ast_Expr *typespec;
|
Ast_Expr *typespec;
|
||||||
|
|||||||
@@ -249,10 +249,6 @@ gen_var(Ast_Decl *decl, B32 emit_value, B32 scope_names){
|
|||||||
|
|
||||||
function void
|
function void
|
||||||
gen_lambda(Intern_String name, Ast_Lambda *lambda, B32 generate_block = true){
|
gen_lambda(Intern_String name, Ast_Lambda *lambda, B32 generate_block = true){
|
||||||
bool is_foreign = is_flag_set(lambda->flags, AST_FOREIGN);
|
|
||||||
if(name == pctx->intern("main"_s) || name == pctx->intern("WinMain"_s)){
|
|
||||||
is_foreign = true;
|
|
||||||
}
|
|
||||||
gen_simple_decl(lambda->resolved_type->func.ret, name);
|
gen_simple_decl(lambda->resolved_type->func.ret, name);
|
||||||
gen("(");
|
gen("(");
|
||||||
For(lambda->args){
|
For(lambda->args){
|
||||||
@@ -275,23 +271,26 @@ gen_expr(Ast_Expr *ast, Ast_Type *type_of_var){
|
|||||||
if(node->resolved_decl->kind == AST_MODULE_NAMESPACE || node->resolved_decl->kind == AST_FILE_NAMESPACE)
|
if(node->resolved_decl->kind == AST_MODULE_NAMESPACE || node->resolved_decl->kind == AST_FILE_NAMESPACE)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if(type_of_var){
|
if(type_of_var && is_slice(type_of_var) && is_array(node->resolved_decl->type)){
|
||||||
if(is_slice(type_of_var) && is_array(node->resolved_decl->type)){
|
|
||||||
gen("{%d, ", (int)node->resolved_decl->type->arr.size);
|
gen("{%d, ", (int)node->resolved_decl->type->arr.size);
|
||||||
gen("%Q}", node->intern_val);
|
gen("%Q}", node->intern_val);
|
||||||
}
|
}
|
||||||
else if(!is_any(ast->resolved_type) && is_any(type_of_var)){
|
|
||||||
|
else if(type_of_var && !is_any(ast->resolved_type) && is_any(type_of_var)){
|
||||||
gen("(Any){&");
|
gen("(Any){&");
|
||||||
gen_expr(ast);
|
gen_expr(ast);
|
||||||
gen(", %d}", ast->resolved_type->type_id);
|
gen(", %d}", ast->resolved_type->type_id);
|
||||||
}
|
}
|
||||||
else goto otherwise;
|
|
||||||
|
else if(node->resolved_decl->kind == AST_LAMBDA){
|
||||||
|
gen("%Q", node->resolved_decl->unique_name);
|
||||||
}
|
}
|
||||||
else{
|
|
||||||
otherwise:
|
else {
|
||||||
gen("%Q", node->intern_val);
|
gen("%Q", node->intern_val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BREAK();
|
BREAK();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -388,8 +387,7 @@ gen_expr(Ast_Expr *ast, Ast_Type *type_of_var){
|
|||||||
}
|
}
|
||||||
|
|
||||||
CASE(CALL, Call){
|
CASE(CALL, Call){
|
||||||
gen_expr(node->name);
|
gen("%Q(", node->resolved_decl->unique_name);
|
||||||
gen("(");
|
|
||||||
For(node->exprs){
|
For(node->exprs){
|
||||||
gen_expr(it->item, it->resolved_type);
|
gen_expr(it->item, it->resolved_type);
|
||||||
if(!node->exprs.is_last(&it)) gen(", ");
|
if(!node->exprs.is_last(&it)) gen(", ");
|
||||||
@@ -583,10 +581,11 @@ gen_ast(Ast *ast){
|
|||||||
CASE(LAMBDA, Decl){
|
CASE(LAMBDA, Decl){
|
||||||
gen_line(node);
|
gen_line(node);
|
||||||
genln("");
|
genln("");
|
||||||
|
|
||||||
if(is_flag_set(node->expr->flags, AST_FOREIGN)){
|
if(is_flag_set(node->expr->flags, AST_FOREIGN)){
|
||||||
gen("/*foreign*/");
|
gen("/*foreign*/");
|
||||||
}
|
}
|
||||||
gen_lambda(node->name, node->lambda);
|
gen_lambda(node->unique_name, node->lambda);
|
||||||
BREAK();
|
BREAK();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -648,7 +647,7 @@ gen_ast(Ast *ast){
|
|||||||
}break;
|
}break;
|
||||||
case TYPE_LAMBDA:{
|
case TYPE_LAMBDA:{
|
||||||
gen("// ");
|
gen("// ");
|
||||||
gen_lambda(node->name, node->lambda);
|
gen_lambda(node->unique_name, node->lambda);
|
||||||
} break;
|
} break;
|
||||||
invalid_default_case;
|
invalid_default_case;
|
||||||
}
|
}
|
||||||
@@ -790,12 +789,32 @@ typedef struct String{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Intern_String intern_main = pctx->intern("main"_s);
|
||||||
|
Intern_String intern_win_main = pctx->intern("WinMain"_s);
|
||||||
|
|
||||||
|
Ast_Decl *main = 0;
|
||||||
|
Ast_Decl *win_main = 0;
|
||||||
|
|
||||||
// Generate lambda forward decls
|
// Generate lambda forward decls
|
||||||
For(pctx->ordered_decls){
|
For(pctx->ordered_decls){
|
||||||
if(it->kind == AST_LAMBDA){
|
if(it->kind == AST_LAMBDA){
|
||||||
genln("");
|
if(it->name == intern_main){
|
||||||
gen_lambda(it->name, it->lambda, false);
|
main = it;
|
||||||
|
it->unique_name = it->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(it->name == intern_win_main){
|
||||||
|
win_main = it;
|
||||||
|
it->unique_name = it->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
genln("");
|
||||||
|
gen_lambda(it->unique_name, it->lambda, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!main && !win_main){
|
||||||
|
compiler_error(0, "Entry point is not defined! Try main or WinMain");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate language.kl
|
// Generate language.kl
|
||||||
|
|||||||
@@ -187,6 +187,7 @@ struct Parse_Ctx:Lexer{
|
|||||||
|
|
||||||
Array<Ast_Type *> all_types;
|
Array<Ast_Type *> all_types;
|
||||||
S32 type_ids;
|
S32 type_ids;
|
||||||
|
int lambda_ids;
|
||||||
U64 unique_ids; // @Debug
|
U64 unique_ids; // @Debug
|
||||||
Map type_map;
|
Map type_map;
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
/*
|
/*
|
||||||
|
|
||||||
- [ ] Basic
|
- [ ] Basic
|
||||||
- [ ] Pass size and alignment calculations to C ?
|
- [ ] Detecting if return was called
|
||||||
- [ ] Fix . operator lookups
|
- [ ] Fix . operator lookups
|
||||||
- [ ] Combining casts with . operator
|
- [ ] Combining casts with . operator
|
||||||
- [ ] Disable .len for Strings, are there other things that use this convention?
|
|
||||||
|
|
||||||
- [ ] Builtin data structures
|
- [ ] Builtin data structures
|
||||||
- [ ] Fix Length etc. they should be function calls not operators
|
- [ ] Fix Length etc. they should be function calls not operators
|
||||||
@@ -19,6 +18,7 @@
|
|||||||
- [ ] Function renaming to prevent colissions, we can't really touch other stuff cause I want it to be easily debuggable
|
- [ ] Function renaming to prevent colissions, we can't really touch other stuff cause I want it to be easily debuggable
|
||||||
|
|
||||||
- [ ] Programming constructs
|
- [ ] Programming constructs
|
||||||
|
- [ ] Defer statement
|
||||||
- [ ] Using language construct
|
- [ ] Using language construct
|
||||||
- [ ] Function polimorphism
|
- [ ] Function polimorphism
|
||||||
- [ ] Operator Overloading
|
- [ ] Operator Overloading
|
||||||
@@ -38,6 +38,9 @@
|
|||||||
- [ ] Var args using any
|
- [ ] Var args using any
|
||||||
- [ ] Slice of Any should work well
|
- [ ] Slice of Any should work well
|
||||||
|
|
||||||
|
Maybe later
|
||||||
|
- [ ] Optionally pass size and alignment calculations to C ?
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
2022.05.28 - On lambda expressions
|
2022.05.28 - On lambda expressions
|
||||||
@@ -129,6 +132,7 @@ For modules it's a bit different cause they should be distributed as valid.
|
|||||||
|
|
||||||
## Done
|
## Done
|
||||||
|
|
||||||
|
- [x] Disable .len for Strings, are there other things that use this convention?
|
||||||
- [x] Calculate size and alignment of struct data types
|
- [x] Calculate size and alignment of struct data types
|
||||||
- [x] Consider changing syntax of scopes to use braces { } NO
|
- [x] Consider changing syntax of scopes to use braces { } NO
|
||||||
- [x] Disable ability to parse inner structs, functions, constants etc. ?
|
- [x] Disable ability to parse inner structs, functions, constants etc. ?
|
||||||
|
|||||||
@@ -1422,6 +1422,13 @@ resolve_decl(Ast_Decl *ast){
|
|||||||
// @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
|
||||||
try_resolving_lambda_scope(&result, lambda, node->type);
|
try_resolving_lambda_scope(&result, lambda, node->type);
|
||||||
node->value = result.value;
|
node->value = result.value;
|
||||||
|
|
||||||
|
node->unique_name = node->name;
|
||||||
|
if(!is_flag_set(node->expr->flags, AST_FOREIGN)){
|
||||||
|
Scratch scratch;
|
||||||
|
node->unique_name = pctx->intern(string_fmt(scratch, "%Q%d", node->name, pctx->lambda_ids++));
|
||||||
|
}
|
||||||
|
|
||||||
BREAK();
|
BREAK();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ be nice if handling of that was simplified.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
main :: (): int
|
main :: (): int
|
||||||
static_array: [8]int
|
static_array: [8]int
|
||||||
|
|
||||||
@@ -51,3 +52,4 @@ main :: (): int
|
|||||||
for slice;; *it = 2
|
for slice;; *it = 2
|
||||||
|
|
||||||
Assert(static_array[2] == 2)
|
Assert(static_array[2] == 2)
|
||||||
|
return 0
|
||||||
@@ -82,10 +82,6 @@ WinMain :: (hInstance: HINSTANCE, hPrevInstance: HINSTANCE, lpCmdLine: LPSTR, nS
|
|||||||
window_dc := GetDC(window)
|
window_dc := GetDC(window)
|
||||||
bitmap := CreateBitmap(screen_size)
|
bitmap := CreateBitmap(screen_size)
|
||||||
|
|
||||||
requested_time_per_frame := 1.0 / 60.0
|
|
||||||
frame_start_time := Time()
|
|
||||||
frame_number: S64
|
|
||||||
total_time: F64
|
|
||||||
for AppIsRunning
|
for AppIsRunning
|
||||||
msg: MSG
|
msg: MSG
|
||||||
for PeekMessageW(&msg, window, 0, 0, PM_REMOVE) > 0
|
for PeekMessageW(&msg, window, 0, 0, PM_REMOVE) > 0
|
||||||
@@ -101,4 +97,5 @@ WinMain :: (hInstance: HINSTANCE, hPrevInstance: HINSTANCE, lpCmdLine: LPSTR, nS
|
|||||||
Sleep(100)
|
Sleep(100)
|
||||||
|
|
||||||
if CStringCompare(lpCmdLine, "testing")
|
if CStringCompare(lpCmdLine, "testing")
|
||||||
ExitProcess(0)
|
return 0
|
||||||
|
return 0
|
||||||
|
|||||||
@@ -80,6 +80,8 @@ main :: (): int
|
|||||||
Assert(data2.c == 0)
|
Assert(data2.c == 0)
|
||||||
Assert(data2.d == 0)
|
Assert(data2.d == 0)
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
Data :: struct
|
Data :: struct
|
||||||
a: S64
|
a: S64
|
||||||
b: S32
|
b: S32
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ main :: (): int
|
|||||||
asset1 := make_sound()
|
asset1 := make_sound()
|
||||||
asset2 := make_sound()
|
asset2 := make_sound()
|
||||||
asset1.next_asset = &asset2
|
asset1.next_asset = &asset2
|
||||||
|
return 0
|
||||||
|
|
||||||
// @todo: This does not work
|
// @todo: This does not work
|
||||||
// asset := []Asset{make_sound(), make_sound()}
|
// asset := []Asset{make_sound(), make_sound()}
|
||||||
|
|||||||
@@ -203,4 +203,5 @@ WinMain :: (hInstance: HINSTANCE, hPrevInstance: HINSTANCE, lpCmdLine: LPSTR, nS
|
|||||||
frame_time = new_frame_time
|
frame_time = new_frame_time
|
||||||
|
|
||||||
if CStringCompare(lpCmdLine, "testing")
|
if CStringCompare(lpCmdLine, "testing")
|
||||||
ExitProcess(0)
|
return 0
|
||||||
|
return 0
|
||||||
@@ -47,6 +47,7 @@ main :: (): int
|
|||||||
|
|
||||||
letter := GetFirstLetterOfType(value_to_be_wrapped)
|
letter := GetFirstLetterOfType(value_to_be_wrapped)
|
||||||
Assert(letter == 'I')
|
Assert(letter == 'I')
|
||||||
|
return 0
|
||||||
|
|
||||||
GetFirstLetterOfType :: (a: Any): U8
|
GetFirstLetterOfType :: (a: Any): U8
|
||||||
type_info := GetTypeInfo(a.type)
|
type_info := GetTypeInfo(a.type)
|
||||||
|
|||||||
@@ -42,5 +42,7 @@ main :: (): int
|
|||||||
elif some_type_implicit == char
|
elif some_type_implicit == char
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user