diff --git a/core_codegen_c_language.cpp b/core_codegen_c_language.cpp index 594db68..ed391c0 100644 --- a/core_codegen_c_language.cpp +++ b/core_codegen_c_language.cpp @@ -63,7 +63,7 @@ get_ctype_name_for_type(Ast_Type *type){ switch(type->kind){ case TYPE_VOID: return "void"; case TYPE_BOOL: return "bool"; - case TYPE_STRING: return "String"; + case TYPE_STRING: return "CORE_String"; case TYPE_CHAR: return "char"; case TYPE_F32: return "float"; case TYPE_F64: return "double"; @@ -224,7 +224,7 @@ gen_value(Token *pos, Value a){ }break; case TYPE_STRING:{ int length = 0; - gen("(String){(uint8_t *)\""); + gen("(CORE_String){(uint8_t *)\""); for(int i = 0; i < a.intern_val.len; i++){ if(a.intern_val.str[i] == '\n'){length += 2; gen("\\n");} else if(a.intern_val.str[i] == '\r'){length += 2; gen("\\r");} @@ -789,10 +789,10 @@ compile_to_c_code(){ #define CORE_AssertMessage(x,...) CORE_Assert(x) #define CORE_BufferSize(x) (sizeof(x)/sizeof((x)[0])) -typedef struct String{ +typedef struct CORE_String{ uint8_t *str; int64_t len; -}String; +}CORE_String; static void CORE_MemoryCopy(void *dst, void *src, size_t size){ @@ -873,55 +873,59 @@ CORE_MemoryCopy(void *dst, void *src, size_t size){ compiler_error(0, "Entry point is not defined! Try main or WinMain"); } - // Generate language.core - for(S32 i = 0; i < pctx->base_language_ordered_decl_len; i++){ - Ast_Decl *it = get(&pctx->ordered_decls, i); - genln(""); - gen_ast(it); - } - // Generate type info - genln("int64_t type_infos_len = %d;", length(&pctx->all_types)); - genln("Type_Info *type_infos = (Type_Info[]){"); - global_indent++; - Iter(&pctx->all_types){ - Ast_Type *t = it.item[0]; - genln("{/*%Q*/.kind = %d, .size = %d, .align = %d, .is_unsigned = %s, .type = %d, ", typestring(t), - (S32)t->kind, (S32)t->size, (S32)t->align, t->is_unsigned ? "true" : "false", t->type_id); - switch(t->kind){ - case TYPE_POINTER: - case TYPE_SLICE: { - gen(".base_type = %d", t->base->type_id); - } break; - case TYPE_ARRAY: { - gen(".base_type = %d, ", t->base->type_id); - gen(".array_size = %d", t->arr.size); - }break; - case TYPE_LAMBDA: { - gen(".lambda_return = %d, ", t->func.ret->type_id); - gen(".lambda_argument_count = %d, ", t->func.args.len); - gen(".lambda_arguments = (Type_Info[%d]){", t->func.args.len); - For_Named(t->func.args, arg){ - gen("{.type = %d}, ", arg->type_id); - } - gen("}"); - } break; - case TYPE_STRUCT:{ - gen(".struct_member_count = %d, ", t->agg.members.len); - gen(".struct_members = (Type_Info_Struct_Member[]){"); - For_Named(t->agg.members, m){ - gen("{.name = (String){(uint8_t *)\"%Q\", %d}, .type = %d, .offset = %d}, ", m.name, m.name.len, m.type->type_id, m.offset); - - } - gen("}"); - }break; - default: {} - // invalid_default_case; + if(emit_type_info){ + // Generate language.core + for(S32 i = 0; i < pctx->base_language_ordered_decl_len; i++){ + Ast_Decl *it = get(&pctx->ordered_decls, i); + genln(""); + gen_ast(it); } - gen("},"); + + // Generate type info + genln("int64_t type_infos_len = %d;", length(&pctx->all_types)); + genln("Type_Info *type_infos = (Type_Info[]){"); + global_indent++; + Iter(&pctx->all_types){ + Ast_Type *t = it.item[0]; + genln("{/*%Q*/.kind = %d, .size = %d, .align = %d, .is_unsigned = %s, .type = %d, ", typestring(t), + (S32)t->kind, (S32)t->size, (S32)t->align, t->is_unsigned ? "true" : "false", t->type_id); + switch(t->kind){ + case TYPE_POINTER: + case TYPE_SLICE: { + gen(".base_type = %d", t->base->type_id); + } break; + case TYPE_ARRAY: { + gen(".base_type = %d, ", t->base->type_id); + gen(".array_size = %d", t->arr.size); + }break; + case TYPE_LAMBDA: { + gen(".lambda_return = %d, ", t->func.ret->type_id); + gen(".lambda_argument_count = %d, ", t->func.args.len); + gen(".lambda_arguments = (Type_Info[%d]){", t->func.args.len); + For_Named(t->func.args, arg){ + gen("{.type = %d}, ", arg->type_id); + } + gen("}"); + } break; + case TYPE_STRUCT:{ + gen(".struct_member_count = %d, ", t->agg.members.len); + gen(".struct_members = (Type_Info_Struct_Member[]){"); + For_Named(t->agg.members, m){ + gen("{.name = (CORE_String){(uint8_t *)\"%Q\", %d}, .type = %d, .offset = %d}, ", m.name, m.name.len, m.type->type_id, m.offset); + + } + gen("}"); + }break; + default: {} + // invalid_default_case; + } + gen("},"); + } + global_indent--; + gen("};"); + } - global_indent--; - gen("};"); // Generate actual code Iter(&pctx->ordered_decls){ diff --git a/core_globals.cpp b/core_globals.cpp index 86347e9..aa7442d 100644 --- a/core_globals.cpp +++ b/core_globals.cpp @@ -1,5 +1,10 @@ +global B32 emit_line_directives = true; +global B32 emit_type_info = true; +global String symbol_prefix = ""_s; + + + thread_local Parse_Ctx *pctx; -thread_local B32 emit_line_directives; Allocator *bigint_allocator; global S64 bigint_allocation_count; diff --git a/core_main.cpp b/core_main.cpp index cf1dc1a..126c056 100644 --- a/core_main.cpp +++ b/core_main.cpp @@ -13,6 +13,8 @@ In the future - [ ] Complicated c declaration generation - [ ] The fact that symbols from main file get introduced to the loaded files might be kind of confusing, need to watch out for that + - [ ] Define some pragama that forces lambda evaluation in module #force_evaluate + - [ ] - [ ] Conditional compilation - [ ] Expand macros @@ -291,7 +293,9 @@ int main(int argument_count, char **arguments){ test_string_builder(); test_intern_table(); - emit_line_directives = true; + emit_line_directives = false; + emit_type_info = false; + symbol_prefix = "Ray_"_s; if(argument_count > 1){ String program_name = string_from_cstring(arguments[1]); compile_file(program_name, COMPILE_PRINT_STATS); diff --git a/examples/any_and_variadic_args.core b/examples/any_and_variadic_args.core index 7a60c05..b89c5e4 100644 --- a/examples/any_and_variadic_args.core +++ b/examples/any_and_variadic_args.core @@ -8,14 +8,14 @@ AnyArguments :: (values: []Any) Assert(*(values[0].data->*S64) == 10) Assert(*(values[1].data->*S64) == 20) -printf :: #foreign (string: *char, args: ..): int +// printf :: #foreign (string: *char, args: ..): int main :: (): int a := 10 b := 20 values := []Any{a, b} - printf("Test %d", {a}) + // printf("Test %d", {a}) for values Assert(it.type == S64) diff --git a/examples/constant_expressions.core b/examples/constant_expressions.core index aa6a78e..8732af8 100644 --- a/examples/constant_expressions.core +++ b/examples/constant_expressions.core @@ -1,11 +1,12 @@ // We can bind module to a name M :: #import "Multimedia.core" -// We can bind a struct to a name -Mu :: M.Mu +// You can bind struct to a name +MU :: M.MU // We can bind a lambda to a name Start :: M.StartMultimedia +Update :: M.UpdateMultimedia // Other example of binding a lambda to a name SomeOtherLambda :: () ;; pass @@ -33,7 +34,7 @@ main :: (): int #Assert(NewInt == int) #Assert(StrictInt != int) - mu: Mu = Start(x = 1280, y = 720) - Assert(mu.x == 1280 && mu.y == 720) + Start(x = 1280, y = 720) + Update() return 0 \ No newline at end of file diff --git a/examples/using_multimedia.core b/examples/using_multimedia.core index 8340686..43e65e7 100644 --- a/examples/using_multimedia.core +++ b/examples/using_multimedia.core @@ -3,9 +3,8 @@ WinMain :: (hInstance: HINSTANCE, hPrevInstance: HINSTANCE, lpCmdLine: LPSTR, nShowCmd: int): int StartMultimedia(title = "Hello, people!") for UpdateMultimedia() - if Mu.key[Key.Escape].is_down - Mu.quit = true + if Mu.key[Key.Escape].down ;; Mu.quit = true - for y := 0, y < Mu.y, y+=1 - for x := 0, x < Mu.x, x+=1 - Mu.scrn[x + y*Mu.x] = 0xFFFFFF00 \ No newline at end of file + for y := 0, y < Mu.window.y, y+=1 + for x := 0, x < Mu.window.x, x+=1 + Mu.screen[x + y*Mu.window.x] = 0xFFFFFF00 \ No newline at end of file diff --git a/modules/Multimedia.core b/modules/Multimedia.core index c38bd33..4e3e487 100644 --- a/modules/Multimedia.core +++ b/modules/Multimedia.core @@ -1,20 +1,25 @@ -#import "Base.core" -#import "Math.core" -#import "Arena.core" -W32 :: #load "win32_multimedia.core" - /* + +Library for making games/graphical applications +* The api is very simple, very few function calls +* You retrieve information about the state of application from "Mu" struct +* Data is available in many different formats to avoid format conversions in user code + API and name inspired by one of Per Vognsen streams https://www.youtube.com/watch?v=NG_mUhc8LRw&list=PLU94OURih-CjrtFuazwZ5GYzTrupOMDL7&index=19 All of his channel is recommended watch for programmers. + */ +StartMultimedia :: W32.StartMultimedia +UpdateMultimedia :: W32.UpdateMultimedia Mu: MU + MU :: struct - scrn: *U32 - x : S64 - y : S64 + screen: *U32 + window: MUWindow key: [Key.Count]KeyState + mouse: Mouse frame_count: U64 time: MUTime quit: Bool @@ -22,6 +27,12 @@ MU :: struct frame_arena: Arena os: W32.OS +MUWindow :: struct + x: S64 + y: S64 + sizef: Vec2 + + MUTime :: struct total : F64 delta : F64 // @modifiable @@ -29,7 +40,7 @@ MUTime :: struct frame_start: F64 KeyState :: struct - is_down: Bool + down: Bool Key :: enum Nil @@ -41,5 +52,13 @@ Key :: enum K2;K3;K4;K5;K6;K7;K8;K9 Count -StartMultimedia :: W32.StartMultimedia -UpdateMultimedia :: W32.UpdateMultimedia +Mouse :: struct + left: KeyState + right: KeyState + middle: KeyState + wheel: S64 + +#import "Base.core" +#import "Math.core" +#import "Arena.core" +W32 :: #load "win32_multimedia.core" diff --git a/modules/USER32.core b/modules/USER32.core index 29f6b76..19428b8 100644 --- a/modules/USER32.core +++ b/modules/USER32.core @@ -103,21 +103,24 @@ WM_SYSKEYUP :: 0x0105 WM_SYSCHAR :: 0x0106 WM_SYSDEADCHAR :: 0x0107 +WM_MOUSEFIRST :: 0x0200 +WM_MOUSEMOVE :: 0x0200 +WM_LBUTTONDOWN :: 0x0201 +WM_LBUTTONUP :: 0x0202 +WM_LBUTTONDBLCLK :: 0x0203 +WM_RBUTTONDOWN :: 0x0204 +WM_RBUTTONUP :: 0x0205 +WM_RBUTTONDBLCLK :: 0x0206 +WM_MBUTTONDOWN :: 0x0207 +WM_MBUTTONUP :: 0x0208 +WM_MBUTTONDBLCLK :: 0x0209 +WM_MOUSEWHEEL :: 0x020A + VK_BACK :: 0x08 VK_TAB :: 0x09 - -/* - * 0x0A - 0x0B : reserved - */ - VK_CLEAR :: 0x0C VK_RETURN :: 0x0D - -/* - * 0x0E - 0x0F : unassigned - */ - VK_SHIFT :: 0x10 VK_CONTROL :: 0x11 VK_MENU :: 0x12 @@ -135,12 +138,10 @@ VK_KANJI :: 0x19 VK_IME_OFF :: 0x1A VK_ESCAPE :: 0x1B - VK_CONVERT :: 0x1C VK_NONCONVERT :: 0x1D VK_ACCEPT :: 0x1E VK_MODECHANGE :: 0x1F - VK_SPACE :: 0x20 VK_PRIOR :: 0x21 VK_NEXT :: 0x22 @@ -167,13 +168,7 @@ VK_HELP :: 0x2F VK_LWIN :: 0x5B VK_RWIN :: 0x5C VK_APPS :: 0x5D - -/* - * 0x5E : reserved - */ - VK_SLEEP :: 0x5F - VK_NUMPAD0 :: 0x60 VK_NUMPAD1 :: 0x61 VK_NUMPAD2 :: 0x62 diff --git a/modules/win32_multimedia.core b/modules/win32_multimedia.core index 064ce7d..1a0e14c 100644 --- a/modules/win32_multimedia.core +++ b/modules/win32_multimedia.core @@ -132,9 +132,11 @@ StartMultimedia :: (x: S64 = 1280, y: S64 = 720, title: String = "Hello people!" Mu.os.window_dc = GetDC(Mu.os.window) Mu.os.bitmap = W32.CreateBitmap(Mu.os.window_dc, size) - Mu.scrn = Mu.os.bitmap.data - Mu.x = size.x - Mu.y = size.y + Mu.screen = Mu.os.bitmap.data + Mu.window.x = size.x + Mu.window.y = size.y + Mu.window.sizef.x = Mu.window.x->F32 + Mu.window.sizef.y = Mu.window.y->F32 UpdateMultimedia :: (): Bool DrawBitmapInCompatibleDC(&Mu.os.bitmap) @@ -145,12 +147,16 @@ UpdateMultimedia :: (): Bool DispatchMessageW(&msg) size := GetWindowSize(Mu.os.window) - if size.x != Mu.x || size.y != Mu.y + if size.x != Mu.window.x || size.y != Mu.window.y DestroyBitmap(&Mu.os.bitmap) CreateBitmap(Mu.os.window_dc, size) - Mu.x = size.x - Mu.y = size.y + Mu.screen = Mu.os.bitmap.data + Mu.window.x = size.x + Mu.window.y = size.y + Mu.window.sizef.x = Mu.window.x->F32 + Mu.window.sizef.y = Mu.window.y->F32 + Mu.frame_count += 1 frame_time := Time() - Mu.time.frame_start @@ -177,10 +183,29 @@ WindowProc :: (hwnd: HWND, msg: UINT, wparam: WPARAM, lparam: LPARAM): LRESULT return 0 elif msg == WM_KEYDOWN || msg == WM_SYSKEYDOWN key := MapVKToKey(wparam) - Mu.key[key].is_down = true + Mu.key[key].down = true elif msg == WM_KEYUP || msg == WM_SYSKEYUP key := MapVKToKey(wparam) - Mu.key[key].is_down = false + Mu.key[key].down = false + elif msg == WM_LBUTTONDOWN ;; Mu.mouse.left.down = true + elif msg == WM_LBUTTONUP ;; Mu.mouse.left.down = false + elif msg == WM_RBUTTONDOWN ;; Mu.mouse.right.down = true + elif msg == WM_RBUTTONUP ;; Mu.mouse.right.down = false + elif msg == WM_MBUTTONDOWN ;; Mu.mouse.middle.down = true + elif msg == WM_MBUTTONUP ;; Mu.mouse.middle.down = false + elif msg == WM_MOUSEWHEEL + if wparam->int > 0 + Mu.mouse.wheel = 1 + else + Mu.mouse.wheel = -1 + // Case(WM_CHAR){ + // Utf32Result utf32 = Utf16ToUtf32((u16 *)&wparam, 1); + // if(!utf32.error){ + // int index = OS->input_count; + // OS->input_count = ClampTop(OS->input_count + 1, (int)(ArrayCount(OS->input) - 1)); + // OS->input[index] = utf32.out_str; + // } + // }Break; else;; result = DefWindowProcW(hwnd, msg, wparam, lparam)