Module relative folders working

This commit is contained in:
Krzosa Karol
2022-06-27 10:24:58 +02:00
parent 6644a2c5ae
commit 15d452cae3
8 changed files with 42 additions and 21 deletions

152
programs/modules/base.kl Normal file
View File

@@ -0,0 +1,152 @@
Os :: #import "os_windows.kl"
SizeU :: U64
arena_di: U64
Arena :: struct
di: U64 // @debug_id
memory: Os.Memory
alignment: U64
len: U64
ADDITIONAL_COMMIT_SIZE :: 1024*1024
DEFAULT_RESERVE_SIZE :: 1024*1024*1024
DEFAULT_ALIGNMENT :: 8
clamp_top_sizeu :: (val: SizeU, max: SizeU): SizeU
if val > max
return max
return val
get_align_offset :: (size: SizeU, align: SizeU): SizeU
mask := align - 1
val := size & mask
if val != 0
val = align - val
return val
align_up :: (size: SizeU, align: SizeU): SizeU
result := size + get_align_offset(size, align)
return result
arena_init :: (a: *Arena)
a.memory = Os.reserve(a.DEFAULT_RESERVE_SIZE)
a.alignment = a.DEFAULT_ALIGNMENT
a.di = arena_di++
// a.allocator.proc = arena_allocator_proc
arena_push_size :: (a: *Arena, size: SizeU): *void
generous_size := size + a.alignment
if a.len + generous_size > a.memory.commit
if a.memory.reserve == 0
arena_init(a)
result := Os.commit(&a.memory, generous_size + a.ADDITIONAL_COMMIT_SIZE)
assert(result == true)
a.len = align_up(a.len, a.alignment)
assert(a.memory.reserve > a.len + a.memory.commit)
result: *void = a.memory.data + a.len
a.len += size
return result
// @todo: Make this compile time thing!!!
// This probably will wait till polymorphism stuff
// something like this:
// arena_push_type :: (a: *Arena, type: $T): *T
//
arena_push_type :: (a: *Arena, type: Type): *void
type_info := get_type_info(type)
assert(type_info != 0)
return arena_push_size(a, type_info.size->SizeU)
arena_release :: (a: *Arena)
Os.release(&a.memory)
//
// Unicode
//
question_mark16 :: 0x003f
String32 :: struct;; str: *U32; len: S64
String16 :: struct;; str: *U16; len: S64
utf8_to_utf32 :: (c: *U8, max_advance: S64): U32, S64
out_str: U32
advance: S64
if (c[0] & 0b10000000) == 0
if max_advance >= 1
c0 := c[0]->U32
out_str = c0
advance = 1
elif (c[0] & 0b11100000) == 0b11000000
if (c[1] & 0b11000000) == 0b10000000 // Continuation byte required
if max_advance >= 2
c0 := c[0]->U32; c1 := c[1]->U32
out_str = (c0 & 0b00011111) << 6 | (c1 & 0b00111111)
advance = 2
elif (c[0] & 0b11110000) == 0b11100000
if (c[1] & 0b11000000) == 0b10000000 && (c[2] & 0b11000000) == 0b10000000 // Two continuation bytes required
if max_advance >= 3
c0 := c[0]->U32; c1 := c[1]->U32; c2 := c[2]->U32
out_str = (c0 & 0b00001111) << 12 | (c1 & 0b00111111) << 6 | (c2 & 0b00111111)
advance = 3
elif (c[0] & 0b11111000) == 0b11110000
if (c[1] & 0b11000000) == 0b10000000 && (c[2] & 0b11000000) == 0b10000000 && (c[3] & 0b11000000) == 0b10000000 // Three continuation bytes required
if max_advance >= 4
c0 := c[0]->U32; c1 := c[1]->U32; c2 := c[2]->U32; c3 := c[3]->U32
out_str = (c0 & 0b00001111) << 18 | (c1 & 0b00111111) << 12 | (c2 & 0b00111111) << 6 | (c3 & 0b00111111)
advance = 4
return out_str, advance
utf32_to_utf16 :: (codepoint: U32): [2]U16, S64
str: [2]U16
len := 0
if codepoint < 0x10000
str[0] = codepoint->U16
len = 1
elif codepoint <= 0x10FFFF
code: U32 = (codepoint - 0x10000)
str[0] = (0xD800 | (code >> 10))->U16
str[1] = (0xDC00 | (code & 0x3FF))->U16
len = 2
return str, len
string_to_string16 :: (arena: *Arena, in: String): String16
in_str := &in[0]
// @Note(Krzosa): Should be more then enough space
alloc_size := (length_of(in)*2)+1
result := String16{str = arena_push_size(arena, alloc_size->U64)}
for i := 0, i < length_of(in)
s32, s32_len := utf8_to_utf32(in_str + i, length_of(in) - i)
if s32_len != 0
i += s32_len
s16, s16_len := utf32_to_utf16(s32)
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
else
result.str[result.len++] = question_mark16
break
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")

View File

@@ -0,0 +1,75 @@
/*
String :: struct
str: *U8
len: S64
Slice :: struct
data: *void
len : S64
*/
Dynamic_Array :: struct
data: *void
len : S64
cap : S64
Any :: struct
data: *void
type: Type
Type_Info_Kind :: enum
S64 // FIRST_NUMERIC
S32
S16
S8
INT
CHAR
U64
U32
U16
U8
F32
F64
POINTER
BOOL // LAST_NUMERIC
STRING
VOID
ARRAY
LAMBDA
STRUCT
UNION
ENUM
TYPE
SLICE
TUPLE
Type_Info_Struct_Member :: struct
name: String
type: Type
offset: S64
Type_Info :: struct
kind: Type_Info_Kind
size: S64
align: S64
is_unsigned: Bool
type: Type
base_type: Type
array_size: S64
struct_member_count: S64
struct_members: *Type_Info_Struct_Member
lambda_argument_count: S64
lambda_arguments: *Type_Info
lambda_return: Type
type_infos_len: S64 #foreign
type_infos : *Type_Info #foreign
get_type_info :: (type: Type): *Type_Info
id := type->S64
if id >= type_infos_len
return 0
return type_infos + id

View File

@@ -0,0 +1,115 @@
#import "kernel32.kl"
#import "base.kl"
PAGE_SIZE :: 4096
Memory :: struct
commit : SizeU
reserve: SizeU
data : *U8
process_heap: HANDLE
allocate :: (size: U64): *void
if process_heap == 0
process_heap = GetProcessHeap()
return HeapAlloc(process_heap, 0, size)
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
write_console :: (string: String16)
handle := GetStdHandle(STD_OUTPUT_HANDLE)
WriteConsoleW(handle, string.str->*void, string.len->DWORD, 0, 0)
performance_frequency: F64
time :: (): F64
query: LARGE_INTEGER
if !performance_frequency
err := QueryPerformanceFrequency(&query)
assert(err != 0)
performance_frequency = query->F64
err := QueryPerformanceCounter(&query)
assert(err != 0)
result := query->F64 / performance_frequency
return result
/**
* C++ version 0.4 char* style "itoa":
* Written by Lukás Chmela
* Released under GPLv3.
*/
itoa :: (value: S64, result: *U8, base: S64): *U8
// check that the base if valid
if (base < 2) || (base > 36)
*result = 0 // '
return result
ptr := result
ptr1 := result
tmp_char: U8
tmp_value: S64
for value != 0
tmp_value = value
value /= base
*ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz" [35 + (tmp_value - value * base)]
// Apply negative sign
if tmp_value < 0
*ptr++ = '- // '
*ptr-- = 0
for ptr1 < ptr
tmp_char = *ptr
*ptr-- = *ptr1
*ptr1++ = tmp_char
return result
print :: (string: String, args: ..)
buffer: [1024]U8
buffer_len: S64
arg_counter := 0
for i := 0, i < length_of(string), i+=1
if string[i] == '% // '
assert(arg_counter < length_of(args), "Passing too many [%] to a print lambda")
arg := args[arg_counter++]
if arg.type == S64
value := *(arg.data->*S64)
itoa_buff: [64]U8
p := itoa(value, &itoa_buff[0], 10)
for *p != 0
buffer[buffer_len++] = *p++
else;; assert(false)
else
buffer[buffer_len++] = string[i]