From 15e4ebd68234116464addf81cd4ee62e3f8f790f Mon Sep 17 00:00:00 2001 From: Krzosa Karol Date: Sat, 8 Oct 2022 10:02:50 +0200 Subject: [PATCH] Added conditional compilation and Const namespace with OS name --- base.cpp | 93 ++++++++++++++++++++-------------- base_string.cpp | 23 +++++++-- core_ast.cpp | 23 +++------ core_codegen_c_language.cpp | 5 +- core_compiler.cpp | 68 ++++++++++++++++--------- core_main.cpp | 1 + core_parsing.cpp | 20 ++++++-- core_typechecking.cpp | 7 ++- examples/raymarcher.core | 65 ++++++++++++------------ examples/using_multimedia.core | 2 +- modules/Math.core | 12 +++++ modules/MathVec3.core | 8 ++- modules/Multimedia.core | 3 +- 13 files changed, 201 insertions(+), 129 deletions(-) diff --git a/base.cpp b/base.cpp index 78b4fef..879a65c 100644 --- a/base.cpp +++ b/base.cpp @@ -62,7 +62,7 @@ typedef double F64; #define kib(x) ((x)*1024llu) #define mib(x) (kib(x)*1024llu) #define gib(x) (mib(x)*1024llu) -#define JOIN1(X,Y) X##Y +#define JOIN1(X,Y) X##Y #define JOIN(X,Y) JOIN1(X,Y) #define string_expand(x) (int)x.len, x.str @@ -106,6 +106,19 @@ typedef double F64; # define OS_MAC 0 #endif +#if OS_WINDOWS +#define OS_NAME "Win32"_s +#define OS_NAME_LOWER "win32"_s +#elif OS_LINUX +#define OS_NAME "Linux"_s +#define OS_NAME_LOWER "linux"_s +#elif OS_MAC +#define OS_NAME "Mac"_s +#define OS_NAME_LOWER "mac"_s +#else +#error Couldnt figure out the OS with C macros! +#endif + struct String{ U8 *str; S64 len; @@ -794,44 +807,6 @@ thread_ctx_init(){ os_process_heap.kind = Allocator_OSHeap; } -#include "base_string.cpp" -//----------------------------------------------------------------------------- -// Logging -//----------------------------------------------------------------------------- -#define log_info(...) handle_log_message(Log_Kind_Normal, __LINE__, __FILE__,##__VA_ARGS__) -#define log_trace(...) handle_log_message(Log_Kind_Trace, __LINE__, __FILE__,##__VA_ARGS__) -#define log_error(...) handle_log_message(Log_Kind_Error, __LINE__, __FILE__,##__VA_ARGS__) -function void -handle_log_message(Log_Kind kind, int line, const char *file, const char *str, ...){ - if(kind == Log_Kind_Trace) return; - - Scratch scratch; - STRING_FMT(scratch, str, message); - if(thread_ctx.log_proc) thread_ctx.log_proc(kind, message, (char *)file, line); - else{ - printf("%s", message.str); - } -} - -//----------------------------------------------------------------------------- -// Defer -// http://www.gingerbill.org/article/2015/08/19/defer-in-cpp/ -//----------------------------------------------------------------------------- -template -struct Defer_Scope { - F f; - Defer_Scope(F f) : f(f) {} - ~Defer_Scope() { f(); } -}; - -template -Defer_Scope defer_func(F f) { - return Defer_Scope(f); -} -#define DEFER_1(x, y) x##y -#define DEFER_2(x, y) DEFER_1(x, y) -#define DEFER_3(x) DEFER_2(x, __COUNTER__) -#define defer(code) auto DEFER_3(_defer_) = defer_func([&](){code;}) //----------------------------------------------------------------------------- // Array @@ -987,6 +962,46 @@ test_array(){ assert(thread_ctx.scratch->memory.data != 0); } + +#include "base_string.cpp" +//----------------------------------------------------------------------------- +// Logging +//----------------------------------------------------------------------------- +#define log_info(...) handle_log_message(Log_Kind_Normal, __LINE__, __FILE__,##__VA_ARGS__) +#define log_trace(...) handle_log_message(Log_Kind_Trace, __LINE__, __FILE__,##__VA_ARGS__) +#define log_error(...) handle_log_message(Log_Kind_Error, __LINE__, __FILE__,##__VA_ARGS__) +function void +handle_log_message(Log_Kind kind, int line, const char *file, const char *str, ...){ + if(kind == Log_Kind_Trace) return; + + Scratch scratch; + STRING_FMT(scratch, str, message); + if(thread_ctx.log_proc) thread_ctx.log_proc(kind, message, (char *)file, line); + else{ + printf("%s", message.str); + } +} + +//----------------------------------------------------------------------------- +// Defer +// http://www.gingerbill.org/article/2015/08/19/defer-in-cpp/ +//----------------------------------------------------------------------------- +template +struct Defer_Scope { + F f; + Defer_Scope(F f) : f(f) {} + ~Defer_Scope() { f(); } +}; + +template +Defer_Scope defer_func(F f) { + return Defer_Scope(f); +} +#define DEFER_1(x, y) x##y +#define DEFER_2(x, y) DEFER_1(x, y) +#define DEFER_3(x) DEFER_2(x, __COUNTER__) +#define defer(code) auto DEFER_3(_defer_) = defer_func([&](){code;}) + //----------------------------------------------------------------------------- // Map //----------------------------------------------------------------------------- diff --git a/base_string.cpp b/base_string.cpp index cf64f6f..ec47bcb 100644 --- a/base_string.cpp +++ b/base_string.cpp @@ -476,9 +476,22 @@ struct String_Replace { String replace; }; -// function String -// string_replace(String string, Array pairs){ -// for(int i = 0; i < string.len; i++){ +function String +string_replace(Arena *arena, String string, Array pairs){ + Scratch scratch(arena); + String_Builder builder = {scratch}; + for(int i = 0; i < string.len; i++){ + For(pairs){ + String current = string_skip(string, i); + current = string_get_prefix(current, it.find.len); + if(current == it.find){ + builder.append_data(it.replace.str, it.replace.len); + i += it.find.len; + continue; + } + } -// } -// } \ No newline at end of file + builder.append_data(string.str + i, 1); + } + return string_flatten(arena, &builder); +} \ No newline at end of file diff --git a/core_ast.cpp b/core_ast.cpp index dc4a6a5..5b8270c 100644 --- a/core_ast.cpp +++ b/core_ast.cpp @@ -5,8 +5,7 @@ enum Ast_Kind: U32{ AST_NONE, - AST_FILE_NAMESPACE, - AST_MODULE_NAMESPACE, + AST_NAMESPACE, AST_MODULE, AST_FILE, @@ -236,13 +235,13 @@ How does current declaration order resolver works: struct Ast_Scope: Ast{ String debug_name; // Dont use - List implicit_imports; - Array decls; - Array stmts; + List implicit_imports; + Array decls; + Array stmts; U32 visit_id; U32 scope_id; - Ast_Scope *file; // Self referential for scope and module + Ast_Scope *file; // Self referential for file and module Ast_Module *module; }; @@ -569,16 +568,8 @@ ast_decl_scope(Token *pos, Allocator *allocator, Ast_File *file){ } function Ast_Decl * -ast_file_namespace(Token *pos, Ast_File *file, Intern_String name){ - AST_NEW(Decl, FILE_NAMESPACE, pos, AST_DECL); - result->scope = file; - result->name = name; - return result; -} - -function Ast_Decl * -ast_module_namespace(Token *pos, Ast_Module *module, Intern_String name){ - AST_NEW(Decl, MODULE_NAMESPACE, pos, AST_DECL); +ast_namespace(Token *pos, Ast_Scope *module, Intern_String name){ + AST_NEW(Decl, NAMESPACE, pos, AST_DECL); result->scope = module; result->name = name; return result; diff --git a/core_codegen_c_language.cpp b/core_codegen_c_language.cpp index 2b5a8b4..85fbd6f 100644 --- a/core_codegen_c_language.cpp +++ b/core_codegen_c_language.cpp @@ -342,7 +342,7 @@ function bool gen_expr(Ast_Expr *ast){ switch(ast->kind){ CASE(IDENT, Atom){ - if(node->resolved_decl->kind == AST_MODULE_NAMESPACE || node->resolved_decl->kind == AST_FILE_NAMESPACE) + if(node->resolved_decl->kind == AST_NAMESPACE) return false; if(node->resolved_decl->kind == AST_LAMBDA){ @@ -751,8 +751,7 @@ gen_ast(Ast *ast){ } case AST_CONSTANT_ASSERT: - case AST_MODULE_NAMESPACE: - CASE(FILE_NAMESPACE, File_Namespace){unused(node); BREAK();} + case AST_NAMESPACE:break; default: { assert(is_flag_set(ast->flags, AST_EXPR)); diff --git a/core_compiler.cpp b/core_compiler.cpp index 9ad9a02..f836889 100644 --- a/core_compiler.cpp +++ b/core_compiler.cpp @@ -112,7 +112,7 @@ destroy_compiler(){ } function void -insert_builtin_into_scope(Ast_Scope *p, String name, Ast_Type *type){ +insert_builtin_type_into_scope(Ast_Scope *p, String name, Ast_Type *type){ Intern_String string = pctx->intern(name); Ast_Decl *decl = ast_type(0, string, type); type->type_id = pctx->type_ids++; @@ -122,27 +122,6 @@ insert_builtin_into_scope(Ast_Scope *p, String name, Ast_Type *type){ add(pctx->perm, &pctx->all_types, type); } -function void -insert_builtin_types_into_scope(Ast_Scope *p){ - insert_builtin_into_scope(p, "S64"_s, type_s64); - insert_builtin_into_scope(p, "S32"_s, type_s32); - insert_builtin_into_scope(p, "S16"_s, type_s16); - insert_builtin_into_scope(p, "S8"_s, type_s8); - insert_builtin_into_scope(p, "int"_s, type_int); - insert_builtin_into_scope(p, "char"_s, type_char); - insert_builtin_into_scope(p, "U64"_s, type_u64); - insert_builtin_into_scope(p, "U32"_s, type_u32); - insert_builtin_into_scope(p, "U16"_s, type_u16); - insert_builtin_into_scope(p, "U8"_s, type_u8); - insert_builtin_into_scope(p, "F64"_s, type_f64); - insert_builtin_into_scope(p, "F32"_s, type_f32); - - insert_builtin_into_scope(p, "void"_s , type_void); - insert_builtin_into_scope(p, "Bool"_s , type_bool); - insert_builtin_into_scope(p, "String"_s, type_string); - insert_builtin_into_scope(p, "Type"_s, type_type); -} - global F64 parsing_time_begin; global F64 parsing_time_end; function void @@ -249,7 +228,48 @@ compile_file_to_string(String filename){ begin_compilation(); { Ast_Module *module = add_module(0, pctx->intern("Language.core"_s)); - insert_builtin_types_into_scope(module); + { + insert_builtin_type_into_scope(module, "S64"_s, type_s64); + insert_builtin_type_into_scope(module, "S32"_s, type_s32); + insert_builtin_type_into_scope(module, "S16"_s, type_s16); + insert_builtin_type_into_scope(module, "S8"_s, type_s8); + insert_builtin_type_into_scope(module, "int"_s, type_int); + insert_builtin_type_into_scope(module, "char"_s, type_char); + insert_builtin_type_into_scope(module, "U64"_s, type_u64); + insert_builtin_type_into_scope(module, "U32"_s, type_u32); + insert_builtin_type_into_scope(module, "U16"_s, type_u16); + insert_builtin_type_into_scope(module, "U8"_s, type_u8); + insert_builtin_type_into_scope(module, "F64"_s, type_f64); + insert_builtin_type_into_scope(module, "F32"_s, type_f32); + insert_builtin_type_into_scope(module, "void"_s , type_void); + insert_builtin_type_into_scope(module, "Bool"_s , type_bool); + insert_builtin_type_into_scope(module, "String"_s, type_string); + insert_builtin_type_into_scope(module, "Type"_s, type_type); + } + + { + Ast_Scope *scope = ast_decl_scope(&null_token, pctx->perm, get(&module->all_loaded_files, 0)); + Ast_Decl *decl = ast_namespace(&null_token, scope, pctx->intern("Const"_s)); + decl->state = DECL_RESOLVED; + + Value v1 = {}; + v1.type = untyped_string; + v1.intern_val = pctx->intern(OS_NAME); + Ast_Decl *const_os1 = ast_const(&null_token, pctx->intern("OSName"_s), v1); + const_os1->state = DECL_RESOLVED; + insert_into_scope(scope, const_os1); + + Value v2 = {}; + v1.type = untyped_string; + v1.intern_val = pctx->intern(OS_NAME_LOWER); + Ast_Decl *const_os2 = ast_const(&null_token, pctx->intern("OSNameLower"_s), v2); + const_os2->state = DECL_RESOLVED; + insert_into_scope(scope, const_os2); + + insert_into_scope(module, decl); + } + + pctx->language_base_module = module; parse_all_modules(); @@ -260,6 +280,8 @@ compile_file_to_string(String filename){ Ast_Decl *any_decl = search_for_single_decl(module, pctx->intern("Any"_s)); assert(any_decl->type == type_type); type_any = any_decl->type_val; + + } diff --git a/core_main.cpp b/core_main.cpp index c4571c4..55c65c6 100644 --- a/core_main.cpp +++ b/core_main.cpp @@ -2,6 +2,7 @@ First doable version: +- [ ] Imports are leaking names ! Multimedia leaks windows stuff - [ ] Test and bulletproof any, slices In the future diff --git a/core_parsing.cpp b/core_parsing.cpp index 309a829..69fd1c2 100644 --- a/core_parsing.cpp +++ b/core_parsing.cpp @@ -768,10 +768,23 @@ register_ast_file(Token *pos, String absolute_file_path, Ast_Module *module, B32 return file; } +function Intern_String +preprocess_filename(Token *token_filename){ + Scratch scratch; + String filename = token_filename->intern_val.s; + Array replace = {scratch}; + replace.add({"$OS"_s, OS_NAME}); + replace.add({"$os"_s, OS_NAME_LOWER}); + String result0 = string_replace(scratch, filename, replace); + Intern_String result = pctx->intern(result0); + return result; +} + function Ast_File * parse_load(B32 global_implicit_load){ Token *file = token_expect(TK_StringLit); - String absolute_path = string_fmt(pctx->perm, "%Q/%Q", pctx->currently_parsed_file->module->absolute_base_folder, file->intern_val); + Intern_String filename = preprocess_filename(file); + String absolute_path = string_fmt(pctx->perm, "%Q/%Q", pctx->currently_parsed_file->module->absolute_base_folder, filename); Ast_File *result = register_ast_file(file, absolute_path, pctx->currently_parsed_file->module, global_implicit_load); return result; } @@ -780,7 +793,8 @@ function Ast_Module *add_module(Token *pos, Intern_String filename, B32 command_ function Ast_Module * parse_import(B32 global_implicit_import){ Token *file = token_expect(TK_StringLit); - Ast_Module *result = add_module(file, file->intern_val); + Intern_String filename = preprocess_filename(file); + Ast_Module *result = add_module(file, filename); if(global_implicit_import){ add_implicit_import(pctx->currently_parsed_file->module, result); } @@ -823,7 +837,7 @@ parse_decl(B32 is_global){ else if(token_match_pound(pctx->intern("import"_s))){ Ast_Module *module = parse_import(false); - result = ast_module_namespace(tname, module, tname->intern_val); + result = ast_namespace(tname, module, tname->intern_val); } else{ diff --git a/core_typechecking.cpp b/core_typechecking.cpp index fe8921b..0512edd 100644 --- a/core_typechecking.cpp +++ b/core_typechecking.cpp @@ -714,7 +714,7 @@ require_const_int(Ast_Expr *expr, Resolve_Flag flags){ function void resolve_stmt(Ast *ast, Ast_Type *ret){ if(!ast) return; - assert(ast->parent_scope->kind == AST_SCOPE || ast->parent_scope->kind == AST_FILE_NAMESPACE); + assert(ast->parent_scope->kind == AST_SCOPE); switch(ast->kind){ @@ -751,7 +751,6 @@ resolve_stmt(Ast *ast, Ast_Type *ret){ BREAK(); } - case AST_FILE_NAMESPACE: case AST_LAMBDA: case AST_VAR: CASE(CONST, Decl){ @@ -1250,7 +1249,7 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_and_const_str Ast_Scope *scope = 0; Ast_Decl *decl = left.resolved_decl; - if(decl && (decl->kind == AST_FILE_NAMESPACE || decl->kind == AST_MODULE_NAMESPACE)){ + if(decl && decl->kind == AST_NAMESPACE){ scope = decl->scope; } @@ -1678,7 +1677,7 @@ resolve_decl(Ast_Decl *ast){ BREAK(); } - case AST_MODULE_NAMESPACE: CASE(FILE_NAMESPACE, File_Namespace){unused(node);BREAK();} + case AST_NAMESPACE: break; CASE(ENUM, Decl){ Ast_Type *type_of_enum = resolve_typespec(node->typespec, AST_CAN_BE_NULL); diff --git a/examples/raymarcher.core b/examples/raymarcher.core index b981b4a..6a5cb4b 100644 --- a/examples/raymarcher.core +++ b/examples/raymarcher.core @@ -100,37 +100,6 @@ Raymarcher_Update :: () #import "USER32.core" #import "WINMM.core" -Windows_Bitmap :: struct - size: Vec2I - data: *U32 - hdc: HDC - dib: HBITMAP - -CreateBitmap :: (size: Vec2I, bottom_up: Bool = true): Windows_Bitmap - result: Windows_Bitmap = {size = size} - if bottom_up == false - result.size.y = -result.size.y - - header_size: U32 = SizeOf(BITMAPINFOHEADER) - Assert(header_size == 40) - bminfo := BITMAPINFO{ - BITMAPINFOHEADER{ - biSize = header_size, - biWidth = size.x->LONG, - biHeight = size.y->LONG, - biPlanes = 1, - biBitCount = 32, - biCompression = BI_RGB, - biXPelsPerMeter = 1, - biYPelsPerMeter = 1, - } - } - - hdc := GetDC(0) - result.dib = CreateDIBSection(hdc, &bminfo, DIB_RGB_COLORS, (&result.data)->**void, 0, 0) - result.hdc = CreateCompatibleDC(hdc) - return result - AppIsRunning := true WindowProc :: (hwnd: HWND, msg: UINT, wparam: WPARAM, lparam: LPARAM): LRESULT @@ -206,4 +175,36 @@ WinMain :: (hInstance: HINSTANCE, hPrevInstance: HINSTANCE, lpCmdLine: LPSTR, nS if CStringCompare(lpCmdLine, "testing") return 0 - return 0 \ No newline at end of file + return 0 + + +Windows_Bitmap :: struct + size: Vec2I + data: *U32 + hdc: HDC + dib: HBITMAP + +CreateBitmap :: (size: Vec2I, bottom_up: Bool = true): Windows_Bitmap + result: Windows_Bitmap = {size = size} + if bottom_up == false + result.size.y = -result.size.y + + header_size: U32 = SizeOf(BITMAPINFOHEADER) + Assert(header_size == 40) + bminfo := BITMAPINFO{ + BITMAPINFOHEADER{ + biSize = header_size, + biWidth = size.x->LONG, + biHeight = size.y->LONG, + biPlanes = 1, + biBitCount = 32, + biCompression = BI_RGB, + biXPelsPerMeter = 1, + biYPelsPerMeter = 1, + } + } + + hdc := GetDC(0) + result.dib = CreateDIBSection(hdc, &bminfo, DIB_RGB_COLORS, (&result.data)->**void, 0, 0) + result.hdc = CreateCompatibleDC(hdc) + return result diff --git a/examples/using_multimedia.core b/examples/using_multimedia.core index 0c3a152..9fc7367 100644 --- a/examples/using_multimedia.core +++ b/examples/using_multimedia.core @@ -1,7 +1,7 @@ #import "Multimedia.core" WinMain :: (hInstance: HINSTANCE, hPrevInstance: HINSTANCE, lpCmdLine: LPSTR, nShowCmd: int): int - StartMultimedia(title = "Hello, people!") + StartMultimedia(title = "Hello people!") for UpdateMultimedia() if Mu.key[Key.Escape].down ;; Mu.quit = true diff --git a/modules/Math.core b/modules/Math.core index 57fe6a5..10d10d4 100644 --- a/modules/Math.core +++ b/modules/Math.core @@ -4,6 +4,18 @@ sinf :: #foreign (value: F32): F32 Vec2I :: struct;; x: S64; y: S64 Vec2 :: struct;; x: F32; y: F32 +"*" :: (a: Vec2, b: Vec2): Vec2 ;; return {a.x*b.x, a.y*b.y} +"*" :: (a: Vec2, b: F32) : Vec2 ;; return {a.x*b, a.y*b} +"*" :: (a: F32, b: Vec2) : Vec2 ;; return {a*b.x, a*b.y} +"-" :: (a: Vec2, b: Vec2): Vec2 ;; return {a.x-b.x, a.y-b.y} +"-" :: (a: Vec2, b: F32) : Vec2 ;; return {a.x-b, a.y-b} +"-" :: (a: F32, b: Vec2) : Vec2 ;; return {a-b.x, a-b.y} +"+" :: (a: Vec2, b: Vec2): Vec2 ;; return {a.x+b.x, a.y+b.y} +"+" :: (a: Vec2, b: F32) : Vec2 ;; return {a.x+b, a.y+b} +"+" :: (a: F32, b: Vec2) : Vec2 ;; return {a+b.x, a+b.y} +"/" :: (a: Vec2, b: Vec2): Vec2 ;; return {a.x/b.x, a.y/b.y} +"/" :: (a: Vec2, b: F32) : Vec2 ;; return {a.x/b, a.y/b} +"/" :: (a: F32, b: Vec2) : Vec2 ;; return {a/b.x, a/b.y} F32_Clamp :: (min: F32, value: F32, max: F32): F32 if value > max;; return max diff --git a/modules/MathVec3.core b/modules/MathVec3.core index c51ed7c..7bfb3f9 100644 --- a/modules/MathVec3.core +++ b/modules/MathVec3.core @@ -6,10 +6,16 @@ Negate :: (a: Vec3): Vec3 ;; return {-a.x, -a.y, -a.z} Dot :: (a: Vec3, b: Vec3): F32 ;; return a.x*b.x + a.y*b.y + a.z*b.z "*" :: (a: Vec3, b: Vec3): Vec3 ;; return {a.x*b.x, a.y*b.y, a.z*b.z} "*" :: (a: Vec3, b: F32) : Vec3 ;; return {a.x*b, a.y*b, a.z*b} +"*" :: (a: F32, b: Vec3) : Vec3 ;; return {a*b.x, a*b.y, a*b.z} +"-" :: (a: Vec3, b: Vec3): Vec3 ;; return {a.x-b.x, a.y-b.y, a.z-b.z} +"-" :: (a: Vec3, b: F32) : Vec3 ;; return {a.x-b, a.y-b, a.z-b} +"-" :: (a: F32, b: Vec3) : Vec3 ;; return {a-b.x, a-b.y, a-b.z} "+" :: (a: Vec3, b: Vec3): Vec3 ;; return {a.x+b.x, a.y+b.y, a.z+b.z} +"+" :: (a: Vec3, b: F32) : Vec3 ;; return {a.x+b, a.y+b, a.z+b} +"+" :: (a: F32, b: Vec3) : Vec3 ;; return {a+b.x, a+b.y, a+b.z} "/" :: (a: Vec3, b: Vec3): Vec3 ;; return {a.x/b.x, a.y/b.y, a.z/b.z} "/" :: (a: Vec3, b: F32) : Vec3 ;; return {a.x/b, a.y/b, a.z/b} -"-" :: (a: Vec3, b: Vec3): Vec3 ;; return {a.x-b.x, a.y-b.y, a.z-b.z} +"/" :: (a: F32, b: Vec3) : Vec3 ;; return {a/b.x, a/b.y, a/b.z} Cross :: (a: Vec3, b: Vec3): Vec3 result := Vec3{ diff --git a/modules/Multimedia.core b/modules/Multimedia.core index c56f5b4..e0b7e53 100644 --- a/modules/Multimedia.core +++ b/modules/Multimedia.core @@ -30,7 +30,6 @@ MUWindow :: struct y: S64 sizef: Vec2 - MUTime :: struct total : F64 delta : F64 // @modifiable @@ -59,4 +58,4 @@ Mouse :: struct #import "Base.core" #import "Math.core" #import "Arena.core" -#load "win32_multimedia.core" +#load "$os_multimedia.core"