diff --git a/build.bat b/build.bat index ba83207..7e89c7a 100644 --- a/build.bat +++ b/build.bat @@ -1,5 +1,7 @@ @echo off + + pushd %~dp0\programs rem cl main.cpp -I.. user32.lib clang ../main.cpp -O0 -I.. -I../.. -Wall -Wno-unused-function -fno-exceptions -fdiagnostics-absolute-paths -g -o main.exe -Wl,user32.lib diff --git a/ccodegen.cpp b/ccodegen.cpp index 3bc1ff1..369cc1e 100644 --- a/ccodegen.cpp +++ b/ccodegen.cpp @@ -432,7 +432,11 @@ gen_ast(Ast *ast){ CASE(IF, If){ For(node->ifs){ - if(it->init) gen_expr(it->init); + if(it->init) { + gen_expr(it->init); + gen(";"); + genln(""); + } if(node->ifs.is_first(&it)){ gen("if("); gen_expr(it->expr); diff --git a/main.cpp b/main.cpp index b1294da..176730a 100644 --- a/main.cpp +++ b/main.cpp @@ -41,27 +41,30 @@ want to export all the symbols, we can namespace them optionally. ------------------------------------------------------------------------------- @todo +[ ] - #test construct that would gather all tests and run them on start of program or something +[ ] - Error message when file not found +[ ] - Foreign import that would link library [ ] - Better error messages when type difference [ ] - Kilobyte, Megabyte, Gigabyte [ ] - Mixing loads and imports leads to code duplication, is that what we want??? [ ] - Fix field access, cant cast, cant index -[ ] - Add parent_scope to Ast_Type +[ ] - Add parent_scope to Ast_Type, Add name to Ast_Type? [ ] - Switch [ ] - Some way to take slice of data [ ] - Optional function renaming in codegen [ ] - Using in structs to embed members, then casting offsets to that embedded member +[ ] - Type as a parameter to a function, alloc :: (size: U64, type: Type) -[ ] - Comma notation when declaring variables thing1, thing2: S32 -[ ] - Array of inferred size +[ ] - Comma notation when declaring variables thing1, thing2: S32 :: probably want to unify it with var unpacking [ ] - Add single line lambda expressions [ ] - Ternary operator [ ] - Disable ability to parse inner structs, functions, constants etc. ? [ ] - Write up on order independent declarations +[ ] - Order independent declarations in structs ? [ ] - constructor => thing :: (i: S32) -> {i = i, thing = 10} [ ] - Casting to basic types by call S64(x) [ ] - Default values in structs??? Should compound stmts bring values from default values?? Maybe not? Whats the alternative -[ ] - Type aliases :: should probably be strictly typed, but assigning constant values should work @ideas [ ] - Var args using Any array - args: []Any - delete vargs @@ -71,8 +74,12 @@ want to export all the symbols, we can namespace them optionally. [ ] - Compound that zeros values - .{} , Compound that assumes defaults from struct definition - {} [ ] - Inject stack traces into the program [ ] - Conditional compilation #if +[ ] - I would love for String, slice, Any etc. to have their struct declarations in source files, I also would want for stuff like string.str to work without weird special cases +[ ] - Polymorphism - create declaration of a polymorphic thing, when it's called just copy it, replace types and typecheck normally, when someone calls again you just search for the instantiation again @donzo +[x] - Type aliases :: should probably be strictly typed, but assigning constant values should work +[x] - Array of inferred size [x] - Casting pointers to and from void should be implicit [x] - Multiple return values [x] - Add c string @@ -146,14 +153,12 @@ want to export all the symbols, we can namespace them optionally. #include "typechecking.h" #include "typechecking.cpp" #include "ccodegen.cpp" -#include "tests.cpp" int main(int argument_count, char **arguments){ test_os_memory(); thread_ctx_init(); test_unicode(); - test_types(); map_test(); test_array(); @@ -178,7 +183,7 @@ int main(int argument_count, char **arguments){ { Scratch scratch; F64 begin = os_time(); - String compiler_call = string_fmt(scratch, "clang.exe program.c -Wall -Wno-parentheses-equality -g -o a.exe -lgdi32 -luser32"); + String compiler_call = string_fmt(scratch, "clang.exe program.c -Wall -Wno-parentheses-equality -g -o a.exe -lgdi32 -luser32 -lwinmm"); system((const char *)compiler_call.str); printf("\nclang = %f", os_time() - begin); } diff --git a/programs/Windows.kl b/programs/Windows.kl deleted file mode 100644 index c32956b..0000000 --- a/programs/Windows.kl +++ /dev/null @@ -1,54 +0,0 @@ -DWORD :: U32 -LPCSTR :: *char -LPSTR :: *char -LPCWSTR :: *U16 -HWND :: *void -HMENU :: *void -HINSTANCE :: *void -HBITMAP :: *void -HDC :: *void -LPVOID :: *void -SIZE_T :: U64 -BOOL :: int -HANDLE :: *void -VOID :: void -HICON :: HANDLE -HCURSOR :: HANDLE -HBRUSH :: HANDLE -LPDWORD :: *DWORD -LRESULT :: S64 -WPARAM :: U64 -LPARAM :: S64 -BYTE :: U8 // @todo? unsigned char -WORD :: S16 // short -LONG :: S32 // @todo long -UINT :: U32 // @todo uint -ATOM :: WORD - -MEM_COMMIT :: 0x00001000 -MEM_RESERVE :: 0x00002000 -MEM_RESET :: 0x00080000 -MEM_RESET_UNDO :: 0x1000000 -MEM_DECOMMIT :: 0x00004000 -MEM_RELEASE :: 0x00008000 - -PAGE_NOACCESS :: 1 -PAGE_READONLY :: 2 -PAGE_READWRITE :: 4 -PAGE_WRITECOPY :: 8 -PAGE_EXECUTE :: 0x10; PAGE_EXECUTE_READ :: 0x20; PAGE_EXECUTE_READWRITE :: 0x40; PAGE_EXECUTE_WRITECOPY :: 0x80 -VirtualAlloc :: #foreign (lpAddress: LPVOID, dwSize: SIZE_T, flAllocationType: DWORD, flProtect: DWORD): LPVOID -VirtualFree :: #foreign (lpAddress: LPVOID, dwSize: SIZE_T, dwFreeType: DWORD): BOOL - -HEAP_ZERO_MEMORY :: 0x8; HEAP_NO_SERIALIZE :: 0x1; HEAP_GENERATE_EXCEPTIONS :: 0x4 -GetProcessHeap :: #foreign (): HANDLE -HeapAlloc :: #foreign (hHeap: HANDLE, dwFlags: DWORD, dwByte: SIZE_T): LPVOID -HeapFree :: #foreign (hHeap: HANDLE, dwFlags: DWORD, lpMe: LPVOID): BOOL - -STD_INPUT_HANDLE :: 4294967286//(-10)->DWORD -STD_OUTPUT_HANDLE :: 4294967285//(-11)->DWORD -//STD_ERROR_HANDLE :: (-12)->DWORD -GetStdHandle :: #foreign (nStdHandle: DWORD): HANDLE -WriteConsoleA :: #foreign (hConsoleOutput: HANDLE,lpBuffer: *VOID,nNumberOfCharsToWrite: DWORD,lpNumberOfCharsWritten: LPDWORD,lpReserve: LPVOID): BOOL -WriteConsoleW :: #foreign (hConsoleOutput: HANDLE,lpBuffer: *VOID,nNumberOfCharsToWrite: DWORD,lpNumberOfCharsWritten: LPDWORD,lpReserve: LPVOID): BOOL -GetLastError :: #foreign (): DWORD \ No newline at end of file diff --git a/programs/base.kl b/programs/base.kl index 4618fcd..fcd0870 100644 --- a/programs/base.kl +++ b/programs/base.kl @@ -1,4 +1,4 @@ -Os :: #import "os.kl" +Os :: #import "os_windows.kl" SizeU :: #strict U64 arena_di: U64 @@ -150,3 +150,17 @@ string_to_string16 :: (arena: *Arena, in: String): String16 result.str[result.len] = 0 return result + +test_unicode :: (arena: *Arena) + string := " 豈 更 車 賈 滑 串 句 龜 龜 契 金 喇 奈 懶 癩 羅 蘿 螺 裸 邏 樂 洛 烙 珞 落 酪 駱 亂 卵 欄 爛 蘭 鸞 嵐 濫 藍 襤 拉 臘 蠟 廊 朗 浪 狼 郎 來 冷 勞 擄 櫓 爐 盧 老 蘆 虜 路 露 魯 鷺 碌 祿 綠 菉 錄 鹿 論 壟 弄 籠 聾 牢 磊 賂 雷 壘 屢 樓 淚 漏 累 縷 陋 勒 肋 凜 凌 稜 綾 菱 陵 讀 拏 樂 諾 丹 寧 怒 率 異 北 磻 便 復 不 泌 數 索 參 塞 省 葉 說 殺 辰 沈 拾 若 掠 略 亮 兩 凉 梁 糧 良 諒 量 勵 ..." + string_result := string_to_string16(arena, string) + print(string_result) + + s32, s32_len := utf8_to_utf32(&"A"[0], 1) + assert(s32 == 'A, "Invalid decode") // ' + + s32_2, s32_len_2 := utf8_to_utf32(&"ć"[0], 2) + assert(s32_2 == 0x107, "Invalid decode") + + s32_3, s32_len_3 := utf8_to_utf32(&"ó"[0], 2) + assert(s32_3 == 0xF3, "Invalid decode") diff --git a/programs/gdi32.kl b/programs/gdi32.kl index a833bc7..47e2055 100644 --- a/programs/gdi32.kl +++ b/programs/gdi32.kl @@ -1,4 +1,4 @@ -#import "Windows.kl" +#import "kernel32.kl" RBGQUAD :: struct;; rgbBlue: BYTE; rgbGreen: BYTE; rgbRed: BYTE; rgbReserved: BYTE BITMAPINFOHEADER :: struct;; biSize: DWORD; biWidth: LONG; biHeight: LONG; biPlanes: WORD; biBitCount: WORD; biCompression: DWORD; biSizeImage: DWORD; biXPelsPerMeter: LONG; biYPelsPerMeter: LONG; biClrUsed: DWORD; biClrImportant: DWORD BITMAPINFO :: struct;; bmiHeader: BITMAPINFOHEADER; bmiColors: [1]RBGQUAD diff --git a/programs/main.kl b/programs/main.kl index 58adf2b..beb8d76 100644 --- a/programs/main.kl +++ b/programs/main.kl @@ -1,31 +1,13 @@ #import "base.kl" +#import "os_windows.kl" +#import "kernel32.kl" #import "gdi32.kl" #import "user32.kl" -#import "os.kl" -#import "Windows.kl" - -process_heap: HANDLE -allocate :: (size: U64): *void - if process_heap == 0 - process_heap = GetProcessHeap() - return HeapAlloc(process_heap, 0, size) - -test_unicode :: (arena: *Arena) - string := " 豈 更 車 賈 滑 串 句 龜 龜 契 金 喇 奈 懶 癩 羅 蘿 螺 裸 邏 樂 洛 烙 珞 落 酪 駱 亂 卵 欄 爛 蘭 鸞 嵐 濫 藍 襤 拉 臘 蠟 廊 朗 浪 狼 郎 來 冷 勞 擄 櫓 爐 盧 老 蘆 虜 路 露 魯 鷺 碌 祿 綠 菉 錄 鹿 論 壟 弄 籠 聾 牢 磊 賂 雷 壘 屢 樓 淚 漏 累 縷 陋 勒 肋 凜 凌 稜 綾 菱 陵 讀 拏 樂 諾 丹 寧 怒 率 異 北 磻 便 復 不 泌 數 索 參 塞 省 葉 說 殺 辰 沈 拾 若 掠 略 亮 兩 凉 梁 糧 良 諒 量 勵 ..." - string_result := string_to_string16(arena, string) - print(string_result) - - s32, s32_len := utf8_to_utf32(&"A"[0], 1) - assert(s32 == 'A, "Invalid decode") // ' - - s32_2, s32_len_2 := utf8_to_utf32(&"ć"[0], 2) - assert(s32_2 == 0x107, "Invalid decode") - - s32_3, s32_len_3 := utf8_to_utf32(&"ó"[0], 2) - assert(s32_3 == 0xF3, "Invalid decode") +#import "winmm.kl" Vec2I :: struct;; x: S64; y: S64 Vec2 :: struct;; x: F32; y: F32 + Windows_Bitmap :: struct size: Vec2I data: *U32 @@ -67,7 +49,11 @@ window_procedure :: (hwnd: HWND, msg: UINT, wparam: WPARAM, lparam: LPARAM): LRE return 0 else;; return DefWindowProcW(hwnd, msg, wparam, lparam) +_gcvt :: #foreign (value: F64, digits: int, buffer: *char): *char WinMain :: (hInstance: HINSTANCE, hPrevInstance: HINSTANCE, lpCmdLine: LPSTR, nShowCmd: int): int + if good_scheduling := false, timeBeginPeriod(1) == TIMERR_NOERROR + good_scheduling = true + arena: Arena window_name := string_to_string16(&arena, "Have a wonderful day! 豈 更 車 賈 滑 串 句 龜 ") w := WNDCLASSW{ @@ -77,6 +63,8 @@ WinMain :: (hInstance: HINSTANCE, hPrevInstance: HINSTANCE, lpCmdLine: LPSTR, nS } assert(RegisterClassW(&w) != 0) + buff: *char = allocate(100) + screen_size: Vec2I = {1280, 720} window := CreateWindowExW( dwExStyle = 0, hWndParent = 0, hMenu = 0, lpParam = 0, @@ -91,6 +79,11 @@ WinMain :: (hInstance: HINSTANCE, hPrevInstance: HINSTANCE, lpCmdLine: LPSTR, nS window_dc := GetDC(window) bitmap := create_bitmap(screen_size) + + requested_time_per_frame := 1.0 / 60.0 + frame_start_time := time() + frame_number: S64 + total_time: F64 for app_is_running msg: MSG for PeekMessageW(&msg, window, 0, 0, PM_REMOVE) > 0 @@ -104,3 +97,23 @@ WinMain :: (hInstance: HINSTANCE, hPrevInstance: HINSTANCE, lpCmdLine: LPSTR, nS SelectObject(bitmap.hdc, bitmap.dib) BitBlt(window_dc, 0, 0, (bitmap.size.x)->int, (bitmap.size.y)->int, bitmap.hdc, 0, 0, SRCCOPY) + + frame_time := time() - frame_start_time + _gcvt(frame_time, 10, buff) + OutputDebugStringA("\n") + OutputDebugStringA(buff) + if frame_time < requested_time_per_frame + if good_scheduling + time_to_sleep := (requested_time_per_frame - frame_time) * 1000 + if time_to_sleep > 0 + time_to_sleep_dword := time_to_sleep->DWORD + // @check if time_to_sleep_dword truncates down + Sleep(time_to_sleep_dword) + + new_frame_time := time() + for new_frame_time < requested_time_per_frame + new_frame_time = time() - frame_start_time + + frame_time = new_frame_time + frame_number += 1 + total_time += frame_time \ No newline at end of file diff --git a/programs/os.kl b/programs/os.kl deleted file mode 100644 index 43c6e37..0000000 --- a/programs/os.kl +++ /dev/null @@ -1,44 +0,0 @@ -#import "Windows.kl" -#import "base.kl" - -PAGE_SIZE :: 4096 -Memory :: struct - commit : SizeU - reserve: SizeU - data : *U8 - -reserve :: (size: SizeU): Memory - result := Memory{reserve=align_up(size, PAGE_SIZE)} - result.data = VirtualAlloc( - flProtect = PAGE_READWRITE, - dwSize = result.reserve, - flAllocationType = MEM_RESERVE, - lpAddress = 0)->*U8 - return result - -commit :: (m: *Memory, size: SizeU): Bool - commit_size := align_up(size, PAGE_SIZE) - total_commit := m.commit + commit_size - clamped_commit := clamp_top_sizeu(total_commit, m.reserve) - adjusted_commit := clamped_commit - m.commit - if adjusted_commit != 0 - result := VirtualAlloc( - lpAddress = (m.data + m.commit)->*void, - dwSize = adjusted_commit, - flAllocationType = MEM_COMMIT, - flProtect = PAGE_READWRITE, - ) - m.commit += adjusted_commit - return true - return false - -release :: (m: *Memory) - result := VirtualFree(m.data->*void, 0, MEM_RELEASE) - if result != 0 - m.data = 0 - m.commit = 0 - m.reserve = 0 - -print :: (string: String16) - handle := GetStdHandle(STD_OUTPUT_HANDLE) - WriteConsoleW(handle, (string.str)->*void, string.len->DWORD, 0, 0) diff --git a/programs/user32.kl b/programs/user32.kl index d8df06e..b256366 100644 --- a/programs/user32.kl +++ b/programs/user32.kl @@ -1,4 +1,4 @@ -#import "Windows.kl" +#import "kernel32.kl" WNDPROC :: (hwnd: HWND, uMsg: UINT, wParam: WPARAM, lParam: LPARAM): LRESULT WNDCLASSW :: struct;; style: UINT; lpfnWndProc: WNDPROC; cbClsExtra: int; cbWndExtra: int; hInstance: HINSTANCE; hIcon: HICON; hCursor: HCURSOR; hbrBackground: HBRUSH; lpszMenuName: LPCWSTR; lpszClassName: LPCWSTR MSG :: struct;; hwnd: HWND; message: UINT; wParam: WPARAM; lParam: LPARAM; time: DWORD; pt: POINT; lPrivate: DWORD