mirror of
https://github.com/Ed94/WATL_Exercise.git
synced 2025-08-04 22:32:43 -07:00
begin to translate C version to Odin variant.
This commit is contained in:
131
Odin/watl.v0.odin
Normal file
131
Odin/watl.v0.odin
Normal file
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
WATL Exercise
|
||||
Version: 0 (From Scratch, 1-Stage Compilation, MSVC & WinAPI Only, Win CRT Multi-threaded Static Linkage)
|
||||
Host: Windows 11 (x86-64)
|
||||
Toolchain: odin-lang/Odin dev-2025-06
|
||||
*/
|
||||
package odin
|
||||
|
||||
import "base:builtin"
|
||||
import "base:intrinsics"
|
||||
|
||||
//#region("Package Mappings")
|
||||
abs :: builtin.abs
|
||||
min :: builtin.min
|
||||
max :: builtin.max
|
||||
clamp :: builtin.clamp
|
||||
|
||||
copy :: proc {
|
||||
memory_copy,
|
||||
slice_copy,
|
||||
}
|
||||
copy_non_overlapping :: proc {
|
||||
memory_copy_non_overlapping,
|
||||
slice_copy_non_overlapping,
|
||||
}
|
||||
end :: proc {
|
||||
slice_end,
|
||||
}
|
||||
zero :: proc {
|
||||
memory_zero,
|
||||
slice_zero,
|
||||
}
|
||||
zero_explicit :: proc {
|
||||
memory_zero_explicit,
|
||||
}
|
||||
//#endregion("Package Mappings")
|
||||
|
||||
//#region("Memory")
|
||||
align_pow2 :: proc(x: int, b: int) -> int {
|
||||
assert(b != 0)
|
||||
assert((b & (b - 1)) == 0) // Check power of 2
|
||||
return ((x + b - 1) & ~(b - 1))
|
||||
}
|
||||
memory_zero :: proc "contextless" (data: rawptr, len: int) -> rawptr {
|
||||
intrinsics.mem_zero(data, len)
|
||||
return data
|
||||
}
|
||||
memory_zero_explicit :: proc "contextless" (data: rawptr, len: int) -> rawptr {
|
||||
intrinsics.mem_zero_volatile(data, len) // Use the volatile mem_zero
|
||||
intrinsics.atomic_thread_fence(.Seq_Cst) // Prevent reordering
|
||||
return data
|
||||
}
|
||||
memory_copy :: proc "contextless" (dst, src: rawptr, len: int) -> rawptr {
|
||||
intrinsics.mem_copy(dst, src, len)
|
||||
return dst
|
||||
}
|
||||
memory_copy_non_overlapping :: proc "contextless" (dst, src: rawptr, len: int) -> rawptr {
|
||||
intrinsics.mem_copy_non_overlapping(dst, src, len)
|
||||
return dst
|
||||
}
|
||||
|
||||
Raw_Slice :: struct {
|
||||
data: rawptr,
|
||||
len: int,
|
||||
}
|
||||
|
||||
slice_assert :: proc "contextless" (s: $Type / []$SliceType) -> Type {
|
||||
return assert(len(s) > 0) && s != nil
|
||||
}
|
||||
slice_end :: proc "contextless" (s : $Type / []$SliceType) -> Type {
|
||||
return s[len(s) - 1]
|
||||
}
|
||||
size_of_slice_type :: proc(slice: $Type / []$SliceType) -> int {
|
||||
return size_of(E)
|
||||
}
|
||||
|
||||
@(require_results)
|
||||
to_bytes :: proc "contextless" (s: []$Type) -> []byte {
|
||||
return ([^]byte)(raw_data(s))[:len(s) * size_of(T)]
|
||||
}
|
||||
|
||||
slice_zero :: proc "contextless" (data: $Type / []$SliceType) -> Type {
|
||||
zero(raw_data(data), size_of(E) * len(data))
|
||||
return data
|
||||
}
|
||||
slice_copy :: proc "contextless" (dst, src: $Ttype / []$SliceType) -> int {
|
||||
n := max(0, min(len(dst), len(src)))
|
||||
if n > 0 {
|
||||
intrinsics.mem_copy(raw_data(dst), raw_data(src), n*size_of(E))
|
||||
}
|
||||
return n
|
||||
}
|
||||
slice_copy_non_overlapping :: proc "contextless" (dst, src: $Type / []$SliceType) -> int {
|
||||
n := max(0, min(len(dst), len(src)))
|
||||
if n > 0 {
|
||||
intrinsics.mem_copy_non_overlapping(raw_data(dst), raw_data(src), n*size_of(E))
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
sll_stack_push_n :: proc(first: ^$SLL_NodeType, n: ^SLL_NodeType) {
|
||||
n.next = first^
|
||||
first^ = n
|
||||
}
|
||||
sll_queue_push_nz :: proc(nil_val: ^$SLL_NodeType, first: ^SLL_NodeType, last: ^SLL_NodeType, n: ^SLL_NodeType) {
|
||||
if first^ == nil_val {
|
||||
first^ = n
|
||||
last^ = n
|
||||
n.next = nil_val
|
||||
} else {
|
||||
last^.next = n
|
||||
last^ = n
|
||||
n.next = nil_val
|
||||
}
|
||||
}
|
||||
sll_queue_push_n :: proc(first: ^$SLL_NodeType, last: ^SLL_NodeType, n: ^SLL_NodeType) {
|
||||
sll_queue_push_nz(nil, first, last, n)
|
||||
}
|
||||
//#endregion("Memory")
|
||||
|
||||
//#region("Strings")
|
||||
Raw_String :: struct {
|
||||
data: [^]byte,
|
||||
len: int,
|
||||
}
|
||||
//#endregion("Strings")
|
||||
|
||||
main :: proc()
|
||||
{
|
||||
|
||||
}
|
120
scripts/build.odin.odin
Normal file
120
scripts/build.odin.odin
Normal file
@@ -0,0 +1,120 @@
|
||||
package build
|
||||
|
||||
//region Script Grime
|
||||
import mem "core:mem"
|
||||
import vmem "core:mem/virtual"
|
||||
import os "core:os/os2"
|
||||
import "core:fmt"
|
||||
import _strings "core:strings"
|
||||
StrGen :: _strings.Builder
|
||||
strgen_init :: _strings.builder_init
|
||||
strgen_join :: _strings.join
|
||||
|
||||
join_path :: #force_inline proc(elems : ..string) -> string { res, _ := os.join_path(transmute([]string)elems, context.allocator); return transmute(string)res }
|
||||
get_working_dir :: #force_inline proc() -> string { res, _ := os.get_working_directory(context.allocator); return transmute(string)res }
|
||||
|
||||
join_str :: #force_inline proc(elems : ..string) -> string {
|
||||
gen : StrGen; strgen_init(& gen, context.allocator)
|
||||
res, _ := strgen_join(elems, "")
|
||||
return res
|
||||
}
|
||||
|
||||
// For a beakdown of any flag, type <odin_compiler> <command> -help
|
||||
command_build :: "build"
|
||||
command_check :: "check"
|
||||
command_query :: "query"
|
||||
command_report :: "report"
|
||||
command_run :: "run"
|
||||
|
||||
flag_build_mode :: "-build-mode:"
|
||||
flag_build_mode_dll :: "-build-mode:dll"
|
||||
flag_collection :: "-collection:"
|
||||
flag_file :: "-file"
|
||||
flag_debug :: "-debug"
|
||||
flag_define :: "-define:"
|
||||
flag_default_allocator_nil :: "-default-to-nil-allocator"
|
||||
flag_disable_assert :: "-disable-assert"
|
||||
flag_dynamic_map_calls :: "-dynamic-map-calls"
|
||||
flag_extra_assembler_flags :: "-extra_assembler-flags:"
|
||||
flag_extra_linker_flags :: "-extra-linker-flags:"
|
||||
flag_ignore_unknown_attributes :: "-ignore-unknown-attributes"
|
||||
flag_keep_temp_files :: "-keep-temp-files"
|
||||
flag_max_error_count :: "-max-error-count:"
|
||||
flag_micro_architecture_native :: "-microarch:native"
|
||||
flag_no_bounds_check :: "-no-bounds-check"
|
||||
flag_no_crt :: "-no-crt"
|
||||
flag_no_entrypoint :: "-no-entry-point"
|
||||
flag_no_thread_local :: "-no-thread-local"
|
||||
flag_no_thread_checker :: "-no-threaded-checker"
|
||||
flag_output_path :: "-out="
|
||||
flag_optimization_level :: "-opt:"
|
||||
flag_optimize_none :: "-o:none"
|
||||
flag_optimize_minimal :: "-o:minimal"
|
||||
flag_optimize_size :: "-o:size"
|
||||
flag_optimize_speed :: "-o:speed"
|
||||
falg_optimize_aggressive :: "-o:aggressive"
|
||||
flag_pdb_name :: "-pdb-name:"
|
||||
flag_sanitize_address :: "-sanitize:address"
|
||||
flag_sanitize_memory :: "-sanitize:memory"
|
||||
flag_sanitize_thread :: "-sanitize:thread"
|
||||
flag_subsystem :: "-subsystem:"
|
||||
flag_show_debug_messages :: "-show-debug-messages"
|
||||
flag_show_timings :: "-show-timings"
|
||||
flag_show_more_timings :: "-show-more-timings"
|
||||
flag_show_system_calls :: "-show-system-calls"
|
||||
flag_target :: "-target:"
|
||||
flag_thread_count :: "-thread-count:"
|
||||
flag_use_lld :: "-linker:lld"
|
||||
flag_use_rad_link :: "-linker:radlink"
|
||||
flag_use_separate_modules :: "-use-separate-modules"
|
||||
flag_vet_all :: "-vet"
|
||||
flag_vet_unused_entities :: "-vet-unused"
|
||||
flag_vet_semicolon :: "-vet-semicolon"
|
||||
flag_vet_shadow_vars :: "-vet-shadowing"
|
||||
flag_vet_using_stmt :: "-vet-using-stmt"
|
||||
|
||||
flag_microarch_zen5 :: "--microarch:znver5"
|
||||
|
||||
flag_msvc_link_disable_dynamic_base :: "/DYNAMICBASE:NO"
|
||||
flag_msvc_link_base_address :: "/BASE:"
|
||||
flag_msvc_link_fixed_base_address :: "/FIXED"
|
||||
flag_msvc_link_stack_size :: "/STACK"
|
||||
flag_msvc_link_debug :: "/DEBUG"
|
||||
|
||||
msvc_link_default_base_address :: 0x180000000
|
||||
//endregion Script Grime
|
||||
|
||||
build :: proc(working_dir : string, args : []string) -> (stdout : string, stderr : string) {
|
||||
fmt.println("Building:", args)
|
||||
res, errs : []byte; _, res, errs, _ = os.process_exec({ working_dir = working_dir, command = args}, context.allocator)
|
||||
return transmute(string)res, transmute(string)errs;
|
||||
}
|
||||
|
||||
main :: proc() {
|
||||
varena : vmem.Arena; _ = vmem.arena_init_growing(& varena, mem.Megabyte * 64 ); context.allocator = vmem.arena_allocator(& varena)
|
||||
exe_odin :: "odin.exe"
|
||||
|
||||
path_root := get_working_dir()
|
||||
path_build := join_path(path_root, "build")
|
||||
path_odin_src := join_path(path_root, "Odin")
|
||||
file_source := join_path(path_odin_src, "watl.v0.odin")
|
||||
file_exe := join_path(path_build, "watl.v0.exe")
|
||||
|
||||
res, errs := build(path_build, {
|
||||
exe_odin,
|
||||
command_build,
|
||||
file_source,
|
||||
flag_file,
|
||||
join_str(flag_output_path, file_exe),
|
||||
flag_optimize_none,
|
||||
flag_default_allocator_nil,
|
||||
flag_debug,
|
||||
flag_microarch_zen5,
|
||||
flag_no_thread_checker,
|
||||
flag_show_timings,
|
||||
flag_use_rad_link,
|
||||
join_str(flag_subsystem, "console"),
|
||||
})
|
||||
fmt.println(res)
|
||||
fmt.println(errs)
|
||||
}
|
41
scripts/build.odin.ps1
Normal file
41
scripts/build.odin.ps1
Normal file
@@ -0,0 +1,41 @@
|
||||
$path_root = split-path -Path $PSScriptRoot -Parent
|
||||
$path_build = join-path $path_root 'build'
|
||||
$path_code = join-path $path_root 'code'
|
||||
|
||||
$path_source = join-path $PSScriptRoot 'build.odin.odin'
|
||||
$exe = join-path $path_build 'build_win32.exe'
|
||||
|
||||
if ((test-path $path_build) -eq $false) {
|
||||
new-item -itemtype directory -path $path_build
|
||||
}
|
||||
|
||||
$odin = 'odin.exe'
|
||||
|
||||
$command_build = 'build'
|
||||
|
||||
$flag_debug = '-debug'
|
||||
$flag_file = '-file'
|
||||
$flag_dyn_map_calls = '-dynamic-map-calls'
|
||||
$flag_no_bounds_check = '-no-bounds-check'
|
||||
$flag_no_threaded_checker = '-no-threaded-checker'
|
||||
$flag_no_type_assert = '-no-type-assert'
|
||||
$flag_optimize_none = '-o:none'
|
||||
$flag_output_path = '-out='
|
||||
$flag_default_allocator_nil = '-default-to-nil-allocator'
|
||||
|
||||
push-location $path_root
|
||||
$build_args = @()
|
||||
$build_args += $command_build
|
||||
$build_args += $path_source
|
||||
$build_args += $flag_file
|
||||
# $build_args += $flag_debug
|
||||
$build_args += $flag_optimize_none
|
||||
$build_args += $flag_no_bounds_check
|
||||
$build_args += $flag_no_threaded_checker
|
||||
$build_args += $flag_no_type_assert
|
||||
$build_args += $flag_dyn_map_calls
|
||||
$build_args += $flag_default_allocator_nil
|
||||
$build_args += $flag_output_path + $exe
|
||||
# & $odin $build_args
|
||||
& $exe
|
||||
pop-location
|
Reference in New Issue
Block a user