moved argument parsing code to core
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Fri, 14 Jan 2022 18:55:09 +0000 (12:55 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Fri, 14 Jan 2022 18:55:09 +0000 (12:55 -0600)
core/alloc.onyx
core/arg_parse.onyx [new file with mode: 0644]
core/std.onyx
scripts/run_tests.onyx

index 5c8729f1fd9669061d2fab28b0988f0a233d5c1f..72a202f52ddeff860319c12c031c2940feffa16f 100644 (file)
@@ -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 (file)
index 0000000..31e2e2e
--- /dev/null
@@ -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
index e4db463608fd9fbc754b187960186b95925fe8ff..5861d6c9595afbee5b1fc456290d05d3fde1e396 100644 (file)
@@ -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"
index 2e8783ad52f9c0064c0273ca4913b62c02d711c3..c0490a79afe5c49405c9cf48d2c10cd70cdbe7d7 100644 (file)
@@ -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 {