From: Brendan Hansen Date: Fri, 14 Jan 2022 18:55:09 +0000 (-0600) Subject: moved argument parsing code to core X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=ecd53dda1f5cc8b2ddb2ce982795e1de7b78be34;p=onyx.git moved argument parsing code to core --- diff --git a/core/alloc.onyx b/core/alloc.onyx index 5c8729f1..72a202f5 100644 --- a/core/alloc.onyx +++ b/core/alloc.onyx @@ -13,6 +13,8 @@ as_allocator :: #match { // This is similar to alloca in C. from_stack :: macro (size: u32) -> rawptr { + // This should do something about the alignment... + // Everything so far has assume that the stack is aligned to 16 bytes. defer __stack_top = ~~(cast(^u8) __stack_top + size); return __stack_top; } diff --git a/core/arg_parse.onyx b/core/arg_parse.onyx new file mode 100644 index 00000000..31e2e2e8 --- /dev/null +++ b/core/arg_parse.onyx @@ -0,0 +1,58 @@ +package core.arg_parse + +use package core + +arg_parse :: (c_args: [] cstr, output: any) -> bool { + arg_iter := iter.as_iterator(c_args) + |> iter.map((x) => string.from_cstr(*x)); + defer arg_iter.close(arg_iter.data); + + use type_info; + + ptr_type := cast(^Type_Info_Pointer) get_type_info(output.type); + if ptr_type.kind != .Pointer do return false; + + arg_type := cast(^Type_Info_Struct) get_type_info(ptr_type.to); + if arg_type.kind != .Struct do return false; + + data_base := *cast(^rawptr) output.data; + + for #no_close arg: arg_iter { + for ^member: arg_type.members { + for ^tag: member.tags { + if tag.type != str do continue; + + to_match := *cast(^str) tag.data; + if arg != to_match do continue; + + switch member.type { + case bool { + *(cast(^bool) (cast(^u8) data_base + member.offset)) = !*(cast(^bool) (cast(^u8) data_base + member.offset)); + } + + case i32 { + value_str, success := iter.take_one(arg_iter, no_close=true); + if !success do return false; + + value := conv.str_to_i64(value_str); + *(cast(^i32) (cast(^u8) data_base + member.offset)) = ~~value; + } + + case str { + value, success := iter.take_one(arg_iter, no_close=true); + if !success do return false; + + *(cast(^str) (cast(^u8) data_base + member.offset)) = value; + } + + case #default { + printf("Unsupported argument type, {}.\n", output.type); + return false; + } + } + } + } + } + + return true; +} \ No newline at end of file diff --git a/core/std.onyx b/core/std.onyx index e4db4636..5861d6c9 100644 --- a/core/std.onyx +++ b/core/std.onyx @@ -37,6 +37,8 @@ package core #load "./type_info/helper" +#load "./arg_parse" + #local runtime :: package runtime #if runtime.runtime == .Wasi || runtime.runtime == .Onyx { #load "./os/file" diff --git a/scripts/run_tests.onyx b/scripts/run_tests.onyx index 2e8783ad..c0490a79 100644 --- a/scripts/run_tests.onyx +++ b/scripts/run_tests.onyx @@ -88,61 +88,8 @@ Settings :: struct { compile_only := false; } -args_parse :: (c_args: [] cstr, output: ^Settings) -> bool { - arg_iter := iter.as_iterator(c_args) - |> iter.map((x) => string.from_cstr(*x)); - - use type_info; - - arg_type := cast(^Type_Info_Struct) get_type_info(typeof *output); - if arg_type.kind != .Struct do return false; - - for #no_close arg: arg_iter { - for ^member: arg_type.members { - for ^tag: member.tags { - if tag.type != str do continue; - - to_match := *cast(^str) tag.data; - if arg != to_match do continue; - - switch member.type { - case bool { - // Should there be a way to specify a variable to be false? - *(cast(^bool) (cast(^u8) output + member.offset)) = true; - } - - case i32 { - value_str, success := iter.take_one(arg_iter); - if !success do return false; - - value := conv.str_to_i64(value_str); - *(cast(^i32) (cast(^u8) output + member.offset)) = ~~value; - } - - case str { - value, success := iter.take_one(arg_iter); - if !success do return false; - - *(cast(^str) (cast(^u8) output + member.offset)) = value; - } - - case #default { - println("Unsupported argument type."); - return false; - } - } - } - } - } - - // This has to be done explicitly beacuse the iter.take_one function - // can close the iterator if it runs out during the taking. - arg_iter.close(arg_iter.data); - return true; -} - main :: (args) => { - args_parse(args, ^settings); + arg_parse.arg_parse(args, ^settings); printf("Using {p*}\n", ^settings); Execution_Context :: struct {