Browse Source

Merge pull request #343 from bynect/nect-args

Add a way to pass command line arguments
Marco Bambini 4 years ago
parent
commit
11efd1596a
4 changed files with 44 additions and 3 deletions
  1. 6 0
      docs/env.md
  2. 4 0
      src/cli/gravity.c
  3. 33 3
      src/optionals/gravity_opt_env.c
  4. 1 0
      src/optionals/gravity_opt_env.h

+ 6 - 0
docs/env.md

@@ -12,3 +12,9 @@ ENV.set("VAR_KEY", "VAR_VALUE")
 // list all env variables
 var list = ENV.keys()
 ```
+
+### Class Constants
+```swift
+var max_arg = ENV.argc - 1 
+var my_arg = ENV.argv[max_arg]
+```

+ 4 - 0
src/cli/gravity.c

@@ -11,6 +11,7 @@
 #include "gravity_utils.h"
 #include "gravity_core.h"
 #include "gravity_vm.h"
+#include "gravity_opt_env.h"
 
 #define DEFAULT_OUTPUT "gravity.g"
 
@@ -421,6 +422,9 @@ int main (int argc, const char* argv[]) {
     // create VM
     gravity_vm *vm = gravity_vm_new(&delegate);
 
+    // pass argc and argv to the ENV class
+    gravity_env_register_args(vm, argc, argv);
+
     // check if input file is source code that needs to be compiled
     if ((type == OP_COMPILE) || (type == OP_COMPILE_RUN) || (type == OP_INLINE_RUN)) {
 

+ 33 - 3
src/optionals/gravity_opt_env.c

@@ -27,6 +27,9 @@
 static gravity_class_t              *gravity_class_env = NULL;
 static uint32_t                     refcount = 0;
 
+static int                          argc = -1;
+static gravity_list_t               *argv = NULL;
+
 /**
  * Wraps `getenv()` to be used with Gravity.
  *
@@ -96,6 +99,16 @@ static bool gravity_env_keys(gravity_vm *vm, gravity_value_t *args, uint16_t npa
     RETURN_VALUE(VALUE_FROM_OBJECT(keys), rindex);
 }
 
+static bool gravity_env_argc(gravity_vm *vm, gravity_value_t *args, uint16_t nargs, uint32_t rindex) {
+   #pragma unused(vm, args, nargs)
+   RETURN_VALUE((argc != -1) ? VALUE_FROM_INT(argc) : VALUE_FROM_NULL, rindex);
+}
+
+static bool gravity_env_argv(gravity_vm *vm, gravity_value_t *args, uint16_t nargs, uint32_t rindex) {
+   #pragma unused(vm, args, nargs)
+   RETURN_VALUE((argv) ? VALUE_FROM_OBJECT(argv) : VALUE_FROM_NULL, rindex);
+}
+
 // MARK: - Internals -
 
 static void create_optional_class (void) {
@@ -110,7 +123,13 @@ static void create_optional_class (void) {
     // Allow map-access
     gravity_class_bind(meta, GRAVITY_INTERNAL_LOADAT_NAME, NEW_CLOSURE_VALUE(gravity_env_get));
     gravity_class_bind(meta, GRAVITY_INTERNAL_STOREAT_NAME, NEW_CLOSURE_VALUE(gravity_env_set));
-    
+
+    gravity_closure_t *closure = NULL;
+    closure = computed_property_create(NULL, NEW_FUNCTION(gravity_env_argc), NULL);
+    gravity_class_bind(meta, "argc", VALUE_FROM_OBJECT(closure));
+    closure = computed_property_create(NULL, NEW_FUNCTION(gravity_env_argv), NULL);
+    gravity_class_bind(meta, "argv", VALUE_FROM_OBJECT(closure));
+
     SETMETA_INITED(gravity_class_env);
 }
 
@@ -124,14 +143,25 @@ void gravity_env_register(gravity_vm *vm) {
     gravity_vm_setvalue(vm, GRAVITY_CLASS_ENV_NAME, VALUE_FROM_OBJECT(gravity_class_env));
 }
 
+void gravity_env_register_args(gravity_vm *vm, uint32_t _argc, const char **_argv) {
+    argc = _argc;
+    argv = gravity_list_new(vm, argc);
+    for (int i = 0; i < _argc; ++i) {
+        gravity_value_t arg = VALUE_FROM_CSTRING(vm, _argv[i]);
+        marray_push(gravity_value_t, argv->array, arg);
+    }
+}
+
 void gravity_env_free (void) {
     if (!gravity_class_env) return;
     if (--refcount) return;
-    
+
     gravity_class_t *meta = gravity_class_get_meta(gravity_class_env);
+    computed_property_free(meta, "argc", true);
+    computed_property_free(meta, "argv", true);
     gravity_class_free_core(NULL, meta);
     gravity_class_free_core(NULL, gravity_class_env);
-    
+
     gravity_class_env = NULL;
 }
 

+ 1 - 0
src/optionals/gravity_opt_env.h

@@ -6,6 +6,7 @@
 #include "gravity_value.h"
 
 void gravity_env_register (gravity_vm *vm);
+void gravity_env_register_args(gravity_vm *vm, uint32_t _argc, const char **_argv);
 void gravity_env_free (void);
 bool gravity_isenv_class (gravity_class_t *c);
 const char *gravity_env_name (void);