Functions have unique names now unless they are foreign, probably will

need a keyword to not mangle the names.
This commit is contained in:
Krzosa Karol
2022-09-28 14:55:56 +02:00
parent 83ffc82f79
commit aa1da4e926
12 changed files with 69 additions and 31 deletions

View File

@@ -264,6 +264,7 @@ enum Ast_Decl_State{
struct Ast_Decl: Ast{
Ast_Decl_State state;
Intern_String name;
Intern_String unique_name; // For code generation
Ast_Scope *scope;
Ast_Expr *typespec;

View File

@@ -249,10 +249,6 @@ gen_var(Ast_Decl *decl, B32 emit_value, B32 scope_names){
function void
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("(");
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)
return false;
if(type_of_var){
if(is_slice(type_of_var) && is_array(node->resolved_decl->type)){
gen("{%d, ", (int)node->resolved_decl->type->arr.size);
gen("%Q}", node->intern_val);
}
else if(!is_any(ast->resolved_type) && is_any(type_of_var)){
gen("(Any){&");
gen_expr(ast);
gen(", %d}", ast->resolved_type->type_id);
}
else goto otherwise;
if(type_of_var && is_slice(type_of_var) && is_array(node->resolved_decl->type)){
gen("{%d, ", (int)node->resolved_decl->type->arr.size);
gen("%Q}", node->intern_val);
}
else{
otherwise:
else if(type_of_var && !is_any(ast->resolved_type) && is_any(type_of_var)){
gen("(Any){&");
gen_expr(ast);
gen(", %d}", ast->resolved_type->type_id);
}
else if(node->resolved_decl->kind == AST_LAMBDA){
gen("%Q", node->resolved_decl->unique_name);
}
else {
gen("%Q", node->intern_val);
}
BREAK();
}
@@ -388,8 +387,7 @@ gen_expr(Ast_Expr *ast, Ast_Type *type_of_var){
}
CASE(CALL, Call){
gen_expr(node->name);
gen("(");
gen("%Q(", node->resolved_decl->unique_name);
For(node->exprs){
gen_expr(it->item, it->resolved_type);
if(!node->exprs.is_last(&it)) gen(", ");
@@ -583,10 +581,11 @@ gen_ast(Ast *ast){
CASE(LAMBDA, Decl){
gen_line(node);
genln("");
if(is_flag_set(node->expr->flags, AST_FOREIGN)){
gen("/*foreign*/");
}
gen_lambda(node->name, node->lambda);
gen_lambda(node->unique_name, node->lambda);
BREAK();
}
@@ -648,7 +647,7 @@ gen_ast(Ast *ast){
}break;
case TYPE_LAMBDA:{
gen("// ");
gen_lambda(node->name, node->lambda);
gen_lambda(node->unique_name, node->lambda);
} break;
invalid_default_case;
}
@@ -790,14 +789,34 @@ 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
For(pctx->ordered_decls){
if(it->kind == AST_LAMBDA){
if(it->name == intern_main){
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->name, it->lambda, false);
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
for(S32 i = 0; i < pctx->base_language_ordered_decl_len; i++){
Ast_Decl *it = pctx->ordered_decls[i];

View File

@@ -187,6 +187,7 @@ struct Parse_Ctx:Lexer{
Array<Ast_Type *> all_types;
S32 type_ids;
int lambda_ids;
U64 unique_ids; // @Debug
Map type_map;

View File

@@ -1,10 +1,9 @@
/*
- [ ] Basic
- [ ] Pass size and alignment calculations to C ?
- [ ] Detecting if return was called
- [ ] Fix . operator lookups
- [ ] Combining casts with . operator
- [ ] Disable .len for Strings, are there other things that use this convention?
- [ ] Builtin data structures
- [ ] 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
- [ ] Programming constructs
- [ ] Defer statement
- [ ] Using language construct
- [ ] Function polimorphism
- [ ] Operator Overloading
@@ -38,6 +38,9 @@
- [ ] Var args using any
- [ ] Slice of Any should work well
Maybe later
- [ ] Optionally pass size and alignment calculations to C ?
-------------------------------------------------------------------------------
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
- [x] Disable .len for Strings, are there other things that use this convention?
- [x] Calculate size and alignment of struct data types
- [x] Consider changing syntax of scopes to use braces { } NO
- [x] Disable ability to parse inner structs, functions, constants etc. ?

View File

@@ -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
try_resolving_lambda_scope(&result, lambda, node->type);
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();
}

View File

@@ -11,6 +11,7 @@ be nice if handling of that was simplified.
*/
main :: (): int
static_array: [8]int
@@ -50,4 +51,5 @@ main :: (): int
// example in a single line
for slice;; *it = 2
Assert(static_array[2] == 2)
Assert(static_array[2] == 2)
return 0

View File

@@ -82,10 +82,6 @@ WinMain :: (hInstance: HINSTANCE, hPrevInstance: HINSTANCE, lpCmdLine: LPSTR, nS
window_dc := GetDC(window)
bitmap := CreateBitmap(screen_size)
requested_time_per_frame := 1.0 / 60.0
frame_start_time := Time()
frame_number: S64
total_time: F64
for AppIsRunning
msg: MSG
for PeekMessageW(&msg, window, 0, 0, PM_REMOVE) > 0
@@ -101,4 +97,5 @@ WinMain :: (hInstance: HINSTANCE, hPrevInstance: HINSTANCE, lpCmdLine: LPSTR, nS
Sleep(100)
if CStringCompare(lpCmdLine, "testing")
ExitProcess(0)
return 0
return 0

View File

@@ -80,6 +80,8 @@ main :: (): int
Assert(data2.c == 0)
Assert(data2.d == 0)
return 0
Data :: struct
a: S64
b: S32

View File

@@ -37,6 +37,7 @@ main :: (): int
asset1 := make_sound()
asset2 := make_sound()
asset1.next_asset = &asset2
return 0
// @todo: This does not work
// asset := []Asset{make_sound(), make_sound()}

View File

@@ -203,4 +203,5 @@ WinMain :: (hInstance: HINSTANCE, hPrevInstance: HINSTANCE, lpCmdLine: LPSTR, nS
frame_time = new_frame_time
if CStringCompare(lpCmdLine, "testing")
ExitProcess(0)
return 0
return 0

View File

@@ -47,6 +47,7 @@ main :: (): int
letter := GetFirstLetterOfType(value_to_be_wrapped)
Assert(letter == 'I')
return 0
GetFirstLetterOfType :: (a: Any): U8
type_info := GetTypeInfo(a.type)

View File

@@ -41,6 +41,8 @@ main :: (): int
elif some_type_implicit == char
pass
return 0