diff --git a/build/rtsgame/main.core b/build/rtsgame/main.core index 631e543..31eec04 100644 --- a/build/rtsgame/main.core +++ b/build/rtsgame/main.core @@ -45,17 +45,9 @@ guys: Array(Guy) Add(&guys, {100, 100}) */ -/* @language_todo: Namespacing - -this requires parent_decl in scopes, we use first namespace(main module has precedence) declaration to -prefix all functions, globals etc. in a given file / module. - -*/ - #import "raylib.core" #load "array.core" MAP :: #load "map.core" - sqrtf :: #foreign (value: F32): F32 V2I :: struct diff --git a/build/rtsgame/map.core b/build/rtsgame/map.core index c19f596..e17abfe 100644 --- a/build/rtsgame/map.core +++ b/build/rtsgame/map.core @@ -75,7 +75,7 @@ SetTargetP :: (s: *Actor, p: V2I) Reset(&s.close_paths) GetRandomP :: (m: *Map): V2I - result := V2I{GetRandomValue(0, CurrentMap.x - 1), GetRandomValue(0, CurrentMap.y - 1)} + result: V2I = {GetRandomValue(0, CurrentMap.x - 1), GetRandomValue(0, CurrentMap.y - 1)} return result GetRandomUnblockedP :: (m: *Map): V2I diff --git a/core_ast.cpp b/core_ast.cpp index 7871c41..9afe036 100644 --- a/core_ast.cpp +++ b/core_ast.cpp @@ -116,7 +116,7 @@ ast_lambda(Token *pos, Array params, Array ret, Ast_Scop result->args = params.tight_copy(pctx->perm); result->ret = ret.tight_copy(pctx->perm); result->scope = scope; - scope->parent_ast = result; + if (scope) scope->parent_ast = result; For(params) { if (is_flag_set(it->flags, AST_POLYMORPH)) { @@ -158,6 +158,12 @@ ast_break(Token *pos) { return result; } +CORE_Static Ast_Break * +ast_compiler_breakpoint(Token *pos) { + AST_NEW(Break, COMPILER_BREAKPOINT, pos, AST_STMT); + return result; +} + CORE_Static Ast_Pass * ast_continue(Token *pos) { AST_NEW(Pass, CONTINUE, pos, AST_STMT); @@ -259,6 +265,7 @@ CORE_Static Ast_Decl * ast_var(Token *pos, Ast_Expr *typespec, Intern_String name, Ast_Expr *expr) { AST_NEW(Decl, VAR, pos, AST_DECL); result->name = name; + result->unique_name = name; result->typespec = typespec; set_flag_typespec(typespec); result->expr = expr; @@ -270,6 +277,7 @@ ast_const(Token *pos, Intern_String name, Value value) { AST_NEW(Decl, CONST, pos, AST_DECL); result->value = value; result->name = name; + result->unique_name = name; return result; } @@ -278,6 +286,7 @@ ast_const(Token *pos, Intern_String name, Ast_Expr *expr) { AST_NEW(Decl, CONST, pos, AST_DECL); result->expr = expr; result->name = name; + result->unique_name = name; return result; } @@ -287,6 +296,7 @@ ast_type(Token *pos, Intern_String name, Ast_Type *type) { result->type = pctx->type_type; result->type_val = type; result->name = name; + result->unique_name = name; return result; } @@ -305,6 +315,7 @@ ast_namespace(Token *pos, Ast_Scope *module, Intern_String name) { AST_NEW(Decl, NAMESPACE, pos, AST_DECL); result->scope = module; result->name = name; + result->unique_name = name; return result; } @@ -554,7 +565,8 @@ void next(Ast_Iter *iter) { case AST_BREAK: case AST_PASS: - case AST_CONTINUE: { + case AST_CONTINUE: + case AST_COMPILER_BREAKPOINT: { Ast *node = (Ast *)ast; } break; diff --git a/core_codegen_c_language.cpp b/core_codegen_c_language.cpp index 17ef26b..f0ef90d 100644 --- a/core_codegen_c_language.cpp +++ b/core_codegen_c_language.cpp @@ -371,9 +371,8 @@ gen_try_any_or_slice(Ast_Expr *expr, Ast_Type *decl_type) { CORE_Static void gen_var(Ast_Decl *decl, B32 emit_value, B32 scope_names) { - if (decl->name == pctx->internf("HERE_IT_IS")) __debugbreak(); if (is_flag_set(decl->flags, AST_FOREIGN)) gen("extern "); - gen_simple_decl(decl->type, decl->name); + gen_simple_decl(decl->type, decl->unique_name); if (is_flag_set(decl->flags, AST_FOREIGN)) return; if (emit_value == DONT_EMIT_VALUE) { @@ -428,7 +427,8 @@ gen_expr(Ast_Expr *ast) { if (node->resolved_decl->kind == AST_NAMESPACE) return false; - if (node->resolved_decl->kind == AST_LAMBDA) { + bool is_global_variable = is_flag_set(node->resolved_decl->flags, AST_GLOBAL); + if (is_global_variable) { gen("%Q", node->resolved_decl->unique_name); } @@ -661,13 +661,18 @@ gen_ast(Ast *ast) { gen("continue;"); BREAK(); } - CASE(BREAK, Break) { unused(node); gen("break;"); BREAK(); } + CASE(COMPILER_BREAKPOINT, Break) { + unused(node); + __debugbreak(); + BREAK(); + } + CASE(PASS, Pass) { unused(node); gen("//pass"); diff --git a/core_compiler.cpp b/core_compiler.cpp index a9b6dfb..c816049 100644 --- a/core_compiler.cpp +++ b/core_compiler.cpp @@ -66,8 +66,9 @@ for i in meta.token_simple_expr: pctx->keyword_else = pctx->intern("else"_s); pctx->keyword_for = pctx->intern("for"_s); pctx->keyword_enum = pctx->intern("enum"_s); + pctx->keyword___compilerbreakpoint = pctx->intern("__CompilerBreakpoint"_s); pctx->interns.first_keyword = pctx->keyword_struct.str; - pctx->interns.last_keyword = pctx->keyword_enum.str; + pctx->interns.last_keyword = pctx->keyword___compilerbreakpoint.str; pctx->intern_typeof = pctx->intern("typeof"_s); pctx->intern_sizeof = pctx->intern("sizeof"_s); pctx->intern_len = pctx->intern("Len"_s); diff --git a/core_compiler.h b/core_compiler.h index daab2cd..39d23fc 100644 --- a/core_compiler.h +++ b/core_compiler.h @@ -38,7 +38,7 @@ struct Core_Ctx { // Types List all_types; S32 type_ids; - int lambda_ids; + int global_decl_ids; U64 unique_ids; // @Debug Map type_map; @@ -107,6 +107,7 @@ for i in meta.interns: print(f'Intern_String intern_{i.lower()};') Intern_String keyword_else; Intern_String keyword_for; Intern_String keyword_enum; + Intern_String keyword___compilerbreakpoint; Intern_String intern_typeof; Intern_String intern_sizeof; Intern_String intern_len; diff --git a/core_compiler_interface.hpp b/core_compiler_interface.hpp index 3b1e978..8aacfa9 100644 --- a/core_compiler_interface.hpp +++ b/core_compiler_interface.hpp @@ -339,6 +339,7 @@ enum Ast_Kind : uint32_t { AST_SWITCH_CASE, AST_VAR_UNPACK, AST_BREAK, + AST_COMPILER_BREAKPOINT, AST_CONTINUE, AST_COMPOUND, AST_TYPE, @@ -569,6 +570,8 @@ struct Ast_Switch : Ast { struct Ast_Scope : Ast { String debug_name; // Only for debug purposes, dont depend on it + Intern_String first_namespace_name; + List implicit_imports; List decls; Array stmts; diff --git a/core_parsing.cpp b/core_parsing.cpp index 549386b..23fbc41 100644 --- a/core_parsing.cpp +++ b/core_parsing.cpp @@ -298,6 +298,10 @@ parse_stmt_scope(Ast_Scope *scope_defined_outside = 0) { scope->stmts.add(ast_continue(token)); } + else if (token_match_keyword(pctx->keyword___compilerbreakpoint)) { + scope->stmts.add(ast_compiler_breakpoint(token)); + } + else if (token_match_keyword(pctx->keyword_break)) { scope->stmts.add(ast_break(token)); } @@ -483,6 +487,7 @@ parse_parameter_list(Arena *arena) { Ast_Decl *param = ast_new(Ast_Decl, AST_VAR, name, AST_DECL); param->name = name->intern_val; + param->unique_name = name->intern_val; param->typespec = parse_expr(); set_flag_typespec(param->typespec); if (is_typespec_polymorphic(param->typespec)) { @@ -921,11 +926,13 @@ parse_decl(B32 is_global) { else if (token_match_pound(pctx->intern_load)) { Ast_File *file = parse_load(false); + if (file->first_namespace_name.len == 0) file->first_namespace_name = tname->intern_val; result = ast_namespace(tname, file, tname->intern_val); } else if (token_match_pound(pctx->intern_import)) { Ast_Module *module = parse_import(false); + if (module->first_namespace_name.len == 0) module->first_namespace_name = tname->intern_val; result = ast_namespace(tname, module, tname->intern_val); } @@ -940,7 +947,7 @@ parse_decl(B32 is_global) { auto lambda = (Ast_Lambda *)expr; if (lambda->scope || is_flag_set(flags, AST_FOREIGN)) { result->kind = AST_LAMBDA; - lambda->scope->parent_decl = result; + if (lambda->scope) lambda->scope->parent_decl = result; if (is_flag_set(lambda->flags, AST_POLYMORPH)) { set_flag(result->flags, AST_POLYMORPH); set_flag(result->flags, AST_PARENT_POLYMORPH); diff --git a/core_polymorph.cpp b/core_polymorph.cpp index 1d17eae..5041d2a 100644 --- a/core_polymorph.cpp +++ b/core_polymorph.cpp @@ -325,7 +325,8 @@ Ast *ast_copy(Ast *ast, Ast_Scope *parent_scope, Array *repl) case AST_BREAK: case AST_PASS: - case AST_CONTINUE: { + case AST_CONTINUE: + case AST_COMPILER_BREAKPOINT: { Ast *src = (Ast *)ast; Ast *dst = ast_create_copy(parent_scope, Ast, ast); result = dst; diff --git a/core_typechecking.cpp b/core_typechecking.cpp index 4fa3214..ee1db3d 100644 --- a/core_typechecking.cpp +++ b/core_typechecking.cpp @@ -776,6 +776,10 @@ resolve_stmt(Ast *ast, Ast_Type *ret) { BREAK(); } + case AST_COMPILER_BREAKPOINT: { + __debugbreak(); + } break; + case AST_CONTINUE: case AST_BREAK: CASE(PASS, Pass) { @@ -816,6 +820,7 @@ resolve_stmt(Ast *ast, Ast_Type *ret) { var->state = DECL_RESOLVED; var->type = type_pointer(op.type->base); var->name = pctx->intern_it; + var->unique_name = var->name; insert_into_scope(node->scope, var); node->array_traversal_var = var; } @@ -1814,6 +1819,26 @@ get_type_base(Ast_Type *type) { } } +CORE_Static void +resolve_name_for_global_decl(Ast_Decl *node) { + if (node->kind == AST_LAMBDA && is_flag_set(node->expr->flags, AST_FOREIGN)) return; // @cleanup ? + if (is_flag_set(node->flags, AST_FOREIGN)) return; + if (!is_flag_set(node->flags, AST_GLOBAL)) return; + + Ast_Scope *s = node->parent_scope; + Intern_String namespace_name = {}; + for (; s; s = s->parent_scope) { + if (s->first_namespace_name.len) { + namespace_name = s->first_namespace_name; + break; + } + } + if (namespace_name.len) { + node->unique_name = pctx->internf("%Q_%Q", namespace_name, node->unique_name); + } + // printf("%.*s\n", (int)node->unique_name.len, node->unique_name.str); +} + CORE_Static void resolve_decl(Ast_Decl *ast) { if (ast->state == DECL_RESOLVED) @@ -1826,10 +1851,11 @@ resolve_decl(Ast_Decl *ast) { assert(ast->state == DECL_NOT_RESOLVED); ast->state = DECL_RESOLVING; + Ast_Decl *node = (Ast_Decl *)ast; + node->unique_name = node->name; { - switch (ast->kind) { - CASE(LAMBDA, Decl) { + case AST_LAMBDA: { Ast_Lambda *lambda = node->lambda; lambda->resolved_type = resolve_lambda_type(lambda); Operand result = operand_type(lambda->resolved_type); @@ -1845,19 +1871,18 @@ resolve_decl(Ast_Decl *ast) { Scoped_Arena scratch(pctx->scratch); - node->unique_name = node->name; - if (!is_flag_set(node->expr->flags, AST_FOREIGN)) { - node->unique_name = pctx->internf("%Q%d", node->name, pctx->lambda_ids++); - } - if (is_flag_set(node->flags, AST_OPERATOR_OVERLOAD)) { - node->unique_name = pctx->internf("OPERATOR_%Q%d", node->overload_op_info->name, pctx->lambda_ids++); + node->unique_name = pctx->internf("OPERATOR_%Q%d", node->overload_op_info->name, pctx->global_decl_ids++); } + else { + if (node->flags & AST_POLYMORPH_INSTANCE) { + node->unique_name = pctx->internf("%Q%d", node->name, pctx->global_decl_ids++); + } + resolve_name_for_global_decl(node); + } + } break; - BREAK(); - } - - CASE(CONST, Decl) { + case AST_CONST: { // @warning: if in the future we add type here then pass it to resolve expr for // compound Operand op = resolve_expr(node->expr, AST_CANT_BE_NULL, 0, 0); @@ -1872,14 +1897,12 @@ resolve_decl(Ast_Decl *ast) { node->type_val = type_copy(pctx->perm, node->type_val); } } + resolve_name_for_global_decl(node); - // if(is_lambda(op.type)){ - // node->unique_name = node->resolved_decl->unique_name; - // } - BREAK(); + break; } - CASE(VAR, Decl) { + case AST_VAR: { Ast_Type *type = node->type; if (!type) type = resolve_typespec(node->typespec, AST_CAN_BE_NULL | RESOLVE_TYPESPEC_COMPLETE); Operand op = resolve_expr(node->expr, AST_CAN_BE_NULL, type, 0); @@ -1897,41 +1920,43 @@ resolve_decl(Ast_Decl *ast) { if (op.is_const) { set_flag(node->flags, AST_VAR_IS_CONST); } - BREAK(); + // if (node->name == pctx->internf("CurrentMap")) __debugbreak(); + resolve_name_for_global_decl(node); + break; } case AST_NAMESPACE: break; - CASE(ENUM, Decl) { - Ast_Type *type_of_enum = resolve_typespec(node->typespec, AST_CAN_BE_NULL); + case AST_ENUM: { + Ast_Type *type_of_enum = resolve_typespec(node->typespec, AST_CAN_BE_NULL); - node->type = pctx->type_type; - node->type_val = type_enum(node, type_of_enum); + node->type = pctx->type_type; + node->type_val = type_enum(node, type_of_enum); - S64 value = 1; - For2(node->scope->decls, decl) { - Operand op = {}; - if (decl->expr) { - op = require_const_int(decl->expr, AST_CANT_BE_NULL); - value = bigint_as_signed(&op.big_int_val) + 1; + S64 value = 1; + For2(node->scope->decls, decl) { + Operand op = {}; + if (decl->expr) { + op = require_const_int(decl->expr, AST_CANT_BE_NULL); + value = bigint_as_signed(&op.big_int_val) + 1; + } + else { + decl->state = DECL_RESOLVED; + op.type = node->type_val; + bigint_init_signed(&op.big_int_val, value); + if (is_flag_set(node->flags, AST_FLAG)) { + value = value << 1; } else { - decl->state = DECL_RESOLVED; - op.type = node->type_val; - bigint_init_signed(&op.big_int_val, value); - if (is_flag_set(node->flags, AST_FLAG)) { - value = value << 1; - } - else { - value += 1; - } + value += 1; } - - decl->value = op.value; } - BREAK(); + + decl->value = op.value; } + resolve_name_for_global_decl(node); + } break; invalid_default_case; } diff --git a/core_types.cpp b/core_types.cpp index 01ec4d3..10e8379 100644 --- a/core_types.cpp +++ b/core_types.cpp @@ -238,6 +238,7 @@ type_incomplete(Ast *ast) { return result; } +CORE_Static void resolve_name_for_global_decl(Ast_Decl *node); CORE_Static void type_complete(Ast_Type *type); CORE_Static void type_struct_complete(Ast_Type *type, Ast_Decl *node) { @@ -301,6 +302,7 @@ type_struct_complete(Ast_Type *type, Ast_Decl *node) { type->agg.members = members.tight_copy(pctx->perm); type->kind = TYPE_UNION; } + resolve_name_for_global_decl(node); } CORE_Static void diff --git a/meta.py b/meta.py index 3fbd48b..15bbf58 100644 --- a/meta.py +++ b/meta.py @@ -115,6 +115,7 @@ keywords = [ "else", "for", "enum", + "__CompilerBreakpoint", # @language_todo: maybe make a #compiler_breakpoint instead that you can attach to anything ] interns = [