From 66d7c8ca52943584c4c244eb0eb791b4caaa7b1b Mon Sep 17 00:00:00 2001 From: Krzosa Karol Date: Thu, 16 Jun 2022 13:16:27 +0200 Subject: [PATCH] Switched to using memory copy in order to implement multiple returns --- ccodegen.cpp | 49 +++++++++++++++++++++++++++++---------------- programs/main.kl | 52 +++++++++++++++++++++++------------------------- 2 files changed, 57 insertions(+), 44 deletions(-) diff --git a/ccodegen.cpp b/ccodegen.cpp index b13a407..95886e2 100644 --- a/ccodegen.cpp +++ b/ccodegen.cpp @@ -394,18 +394,29 @@ gen_ast(Ast *ast){ } CASE(RETURN, Return){ - gen("return "); if(is_tuple(node->resolved_type)) { - gen("("); - gen_simple_decl(node->resolved_type); - gen("){"); + Scratch scratch; + Intern_String var_name = pctx->intern(unique_name(scratch, node)); + gen_simple_decl(node->resolved_type, var_name); + gen(";"); + + int i = 0; + For(node->expr){ + genln("memcpy(&%Q.m%d, ", var_name, i); + if(!is_array(it->resolved_type)) gen("&"); + gen("("); + gen_expr(it); + gen(")"); + gen(", sizeof(%Q.m%d));", var_name, i++); + } + + genln("return %Q;", var_name); + return; } - For(node->expr){ - gen_expr(it); // @todo multiple_returns - if(!node->expr.is_last(&it)) - gen(", "); - } - if(is_tuple(node->resolved_type)) gen("}"); + + assert(node->expr.len <= 1); + gen("return "); + For(node->expr) gen_expr(it); gen(";"); BREAK(); } @@ -552,16 +563,16 @@ gen_ast(Ast *ast){ gen_ast(it); Scratch scratch; - gen_simple_decl(node->resolved_type); - String var_name = unique_name(scratch, node); - gen("%Q", var_name); + Intern_String var_name = pctx->intern(unique_name(scratch, node)); + gen_simple_decl(node->resolved_type, var_name); gen(" = "); gen_expr(node->expr); gen(";"); int i = 0; - For(node->vars) - gen("%Q = %Q.m%d;", it->name, var_name, i++); + For(node->vars){ + gen("memcpy((void *)&%Q, (void *)&%Q.m%d, sizeof(%Q));", it->name, var_name, i++, it->name); + } BREAK(); } @@ -718,6 +729,7 @@ end_compilation(){ gen(R"==( #include #include +#include typedef int8_t S8; typedef int16_t S16; typedef int32_t S32; @@ -755,6 +767,7 @@ typedef struct String{ } } + Scratch scratch; for(S64 i = 0; i < pctx->type_map.cap; i++){ Map_Key_Value *it = pctx->type_map.data + i; if(!it->occupied) continue; @@ -776,8 +789,10 @@ typedef struct String{ global_indent++; For(type->agg.members){ genln(""); - gen_simple_decl(it.type); - gen(" m%llu;", type->agg.members.get_index(&it)); + // @todo remove intern from gen + Intern_String name = pctx->intern(string_fmt(scratch, "m%llu", type->agg.members.get_index(&it))); + gen_simple_decl(it.type, name); + gen(";"); } global_indent--; genln("} Tuple%llu;", type->type_id); diff --git a/programs/main.kl b/programs/main.kl index c5644c3..983a1a1 100644 --- a/programs/main.kl +++ b/programs/main.kl @@ -10,10 +10,6 @@ UTF32_Result :: struct out_str: U32 advance: S64 error : S64 -UTF16_Result :: struct - out_str: [2]U16 - len : S64 - error : S64 utf8_to_utf32 :: (c: *U8, max_advance: S64): UTF32_Result @@ -55,21 +51,23 @@ utf8_to_utf32 :: (c: *U8, max_advance: S64): UTF32_Result return result -utf32_to_utf16 :: (codepoint: U32): UTF16_Result - result: UTF16_Result +UTF16_Result :: struct + out_str: [2]U16 + len : S64 + error : S64 +utf32_to_utf16 :: (codepoint: U32): [2]U16, S64 + str: [2]U16 + len := 0 if codepoint < 0x10000 - result.out_str[0] = codepoint->U16 - result.out_str[1] = 0 - result.len = 1 + str[0] = codepoint->U16 + len = 1 elif codepoint <= 0x10FFFF code: U32 = (codepoint - 0x10000) - result.out_str[0] = (0xD800 | (code >> 10))->U16 - result.out_str[1] = (0xDC00 | (code & 0x3FF))->U16 - result.len = 2 - else - result.error = 1 + str[0] = (0xD800 | (code >> 10))->U16 + str[1] = (0xDC00 | (code & 0x3FF))->U16 + len = 2 - return result + return str, len process_heap: HANDLE allocate :: (size: U64): *void @@ -77,7 +75,7 @@ allocate :: (size: U64): *void process_heap = GetProcessHeap() return HeapAlloc(process_heap, 0, size) -string_to_string16 :: (in: String): *U16, S64 +string_to_string16 :: (in: String): String16 in_str := &in[0] // @Note(Krzosa): Should be more then enough space alloc_size := (length_of(in)*2)+1 @@ -86,10 +84,10 @@ string_to_string16 :: (in: String): *U16, S64 decode := utf8_to_utf32(in_str + i, length_of(in) - i) if !decode.error i += decode.advance - encode := utf32_to_utf16(decode.out_str) - if !encode.error - for j := 0, j < encode.len, j++ - result.str[result.len++] = encode.out_str[j] + s16, s16_len := utf32_to_utf16(decode.out_str) + if s16_len != 0 + for j := 0, j < s16_len, j++ + result.str[result.len++] = s16[j] else result.str[result.len++] = question_mark16 break @@ -98,12 +96,12 @@ string_to_string16 :: (in: String): *U16, S64 break result.str[result.len] = 0 - return result.str, result.len + return result test_unicode :: () string := " 豈 更 車 賈 滑 串 句 龜 龜 契 金 喇 奈 懶 癩 羅 蘿 螺 裸 邏 樂 洛 烙 珞 落 酪 駱 亂 卵 欄 爛 蘭 鸞 嵐 濫 藍 襤 拉 臘 蠟 廊 朗 浪 狼 郎 來 冷 勞 擄 櫓 爐 盧 老 蘆 虜 路 露 魯 鷺 碌 祿 綠 菉 錄 鹿 論 壟 弄 籠 聾 牢 磊 賂 雷 壘 屢 樓 淚 漏 累 縷 陋 勒 肋 凜 凌 稜 綾 菱 陵 讀 拏 樂 諾 丹 寧 怒 率 異 北 磻 便 復 不 泌 數 索 參 塞 省 葉 說 殺 辰 沈 拾 若 掠 略 亮 兩 凉 梁 糧 良 諒 量 勵 ..." - string_result, string_result_len := string_to_string16(string) - // print(string_result) + string_result := string_to_string16(string) + print(string_result) result := utf8_to_utf32(&"A"[0], 1) assert(result.out_str == 'A, "Invalid decode") // ' @@ -154,19 +152,19 @@ window_procedure :: (hwnd: HWND, msg: UINT, wparam: WPARAM, lparam: LPARAM): LRE else;; return DefWindowProcW(hwnd, msg, wparam, lparam) WinMain :: (hInstance: HINSTANCE, hPrevInstance: HINSTANCE, lpCmdLine: LPSTR, nShowCmd: int): int - window_name, window_name_len := string_to_string16("Have a wonderful day! 豈 更 車 賈 滑 串 句 龜 ") + window_name := string_to_string16("Have a wonderful day! 豈 更 車 賈 滑 串 句 龜 ") w := WNDCLASSW{ lpfnWndProc = window_procedure, hInstance = hInstance, - lpszClassName = window_name, + lpszClassName = window_name.str, } assert(RegisterClassW(&w) != 0) window := CreateWindowExW( dwExStyle = 0, hWndParent = 0, hMenu = 0, lpParam = 0, X = CW_USEDEFAULT, Y = CW_USEDEFAULT, nWidth = 1280, nHeight = 720, - lpClassName = window_name, - lpWindowName = window_name, + lpClassName = window_name.str, + lpWindowName = window_name.str, dwStyle = WS_OVERLAPPEDWINDOW, hInstance = hInstance )