Browse Source

Replaced all TABs with 4 spaces (now official indentation setting).

Marco Bambini 7 years ago
parent
commit
a387695a1a
51 changed files with 8832 additions and 8798 deletions
  1. 118 118
      api/exec_c.c
  2. 65 65
      api/exec_gravity.c
  3. 9 9
      gravity_visualstudio/unistd.h
  4. 198 198
      src/cli/gravity.c
  5. 32 32
      src/compiler/debug_macros.h
  6. 427 424
      src/compiler/gravity_ast.c
  7. 173 173
      src/compiler/gravity_ast.h
  8. 705 705
      src/compiler/gravity_codegen.c
  9. 133 133
      src/compiler/gravity_compiler.c
  10. 8 8
      src/compiler/gravity_compiler.h
  11. 354 354
      src/compiler/gravity_ircode.c
  12. 62 62
      src/compiler/gravity_ircode.h
  13. 446 446
      src/compiler/gravity_lexer.c
  14. 32 32
      src/compiler/gravity_lexer.h
  15. 443 443
      src/compiler/gravity_optimizer.c
  16. 435 435
      src/compiler/gravity_parser.c
  17. 13 13
      src/compiler/gravity_parser.h
  18. 108 108
      src/compiler/gravity_semacheck1.c
  19. 21 21
      src/compiler/gravity_semacheck1.h
  20. 433 433
      src/compiler/gravity_semacheck2.c
  21. 26 26
      src/compiler/gravity_semacheck2.h
  22. 88 88
      src/compiler/gravity_symboltable.c
  23. 11 11
      src/compiler/gravity_symboltable.h
  24. 250 250
      src/compiler/gravity_token.c
  25. 115 115
      src/compiler/gravity_token.h
  26. 36 36
      src/compiler/gravity_visitor.c
  27. 30 30
      src/compiler/gravity_visitor.h
  28. 413 413
      src/runtime/gravity_core.c
  29. 1 1
      src/runtime/gravity_core.h
  30. 864 864
      src/runtime/gravity_vm.c
  31. 43 43
      src/runtime/gravity_vm.h
  32. 188 188
      src/runtime/gravity_vmmacros.h
  33. 29 29
      src/shared/gravity_array.h
  34. 45 45
      src/shared/gravity_delegate.h
  35. 298 298
      src/shared/gravity_hash.c
  36. 29 29
      src/shared/gravity_hash.h
  37. 113 113
      src/shared/gravity_macros.h
  38. 240 240
      src/shared/gravity_memory.c
  39. 14 14
      src/shared/gravity_memory.h
  40. 198 198
      src/shared/gravity_opcodes.h
  41. 427 427
      src/shared/gravity_value.c
  42. 322 322
      src/shared/gravity_value.h
  43. 184 184
      src/utils/gravity_debug.c
  44. 206 206
      src/utils/gravity_json.c
  45. 18 18
      src/utils/gravity_json.h
  46. 364 364
      src/utils/gravity_utils.c
  47. 32 32
      src/utils/gravity_utils.h
  48. 17 0
      test/unittest/list_split_2.gravity
  49. 1 1
      test/unittest/string/no-split.gravity
  50. 1 1
      test/unittest/string/split.gravity
  51. 14 0
      test/unittest/string_contains.gravity

+ 118 - 118
api/exec_c.c

@@ -11,179 +11,179 @@
 #include "gravity_core.h"
 #include "gravity_core.h"
 #include "gravity_vm.h"
 #include "gravity_vm.h"
 
 
-#define CLASS_NAME	"Math"
+#define CLASS_NAME    "Math"
 
 
 // gravity func source code
 // gravity func source code
 // Math is declared as extern because it will be later defined in C
 // Math is declared as extern because it will be later defined in C
-static const char *source =	"	extern var Math;				\
-								func main() {					\
-									var pi = Math.pi;			\
-									var n1 = Math.log(pi);		\
-									var n2 = Math.pow(pi,2.12);	\
-									return n1 + n2;				\
-								}";
+static const char *source =    " extern var Math;                   \
+                                func main() {                       \
+                                    var pi = Math.pi;               \
+                                    var n1 = Math.log(pi);          \
+                                    var n2 = Math.pow(pi,2.12);     \
+                                    return n1 + n2;                 \
+                                }";
 
 
 // error callback
 // error callback
 static void report_error (gravity_vm *vm, error_type_t error_type, const char *message,
 static void report_error (gravity_vm *vm, error_type_t error_type, const char *message,
-						  error_desc_t error_desc, void *xdata) {
+                          error_desc_t error_desc, void *xdata) {
     #pragma unused(vm, xdata)
     #pragma unused(vm, xdata)
-	const char *type = "N/A";
-	switch (error_type) {
-		case GRAVITY_ERROR_NONE: type = "NONE"; break;
-		case GRAVITY_ERROR_SYNTAX: type = "SYNTAX"; break;
-		case GRAVITY_ERROR_SEMANTIC: type = "SEMANTIC"; break;
-		case GRAVITY_ERROR_RUNTIME: type = "RUNTIME"; break;
-		case GRAVITY_WARNING: type = "WARNING"; break;
-		case GRAVITY_ERROR_IO: type = "I/O"; break;
-	}
-
-	if (error_type == GRAVITY_ERROR_RUNTIME) printf("RUNTIME ERROR: ");
-	else printf("%s ERROR on %d (%d,%d): ", type, error_desc.fileid, error_desc.lineno, error_desc.colno);
-	printf("%s\n", message);
+    const char *type = "N/A";
+    switch (error_type) {
+        case GRAVITY_ERROR_NONE: type = "NONE"; break;
+        case GRAVITY_ERROR_SYNTAX: type = "SYNTAX"; break;
+        case GRAVITY_ERROR_SEMANTIC: type = "SEMANTIC"; break;
+        case GRAVITY_ERROR_RUNTIME: type = "RUNTIME"; break;
+        case GRAVITY_WARNING: type = "WARNING"; break;
+        case GRAVITY_ERROR_IO: type = "I/O"; break;
+    }
+
+    if (error_type == GRAVITY_ERROR_RUNTIME) printf("RUNTIME ERROR: ");
+    else printf("%s ERROR on %d (%d,%d): ", type, error_desc.fileid, error_desc.lineno, error_desc.colno);
+    printf("%s\n", message);
 }
 }
 
 
 // MARK: -
 // MARK: -
 
 
 static bool math_pi (gravity_vm *vm, gravity_value_t *args, uint16_t nargs, uint32_t rindex) {
 static bool math_pi (gravity_vm *vm, gravity_value_t *args, uint16_t nargs, uint32_t rindex) {
-	#pragma unused (args, nargs)
-	gravity_vm_setslot(vm, VALUE_FROM_FLOAT(3.1315f), rindex);
-	return true;
+    #pragma unused (args, nargs)
+    gravity_vm_setslot(vm, VALUE_FROM_FLOAT(3.1315f), rindex);
+    return true;
 }
 }
 
 
 static bool math_log (gravity_vm *vm, gravity_value_t *args, uint16_t nargs, uint32_t rindex) {
 static bool math_log (gravity_vm *vm, gravity_value_t *args, uint16_t nargs, uint32_t rindex) {
-	// missing parameters check here
-	// 1. number of args
-	// 2. args type
-
-	// assuming arg of type float (in a real example there should be a conversion if not float)
-	gravity_float_t n = VALUE_AS_FLOAT(args[1]);
-
-	// gravity can be compiled with FLOAT as 32 or 64 bit
-	#if GRAVITY_ENABLE_DOUBLE
-	gravity_float_t result = (gravity_float_t)log(n);
-	#else
-	gravity_float_t result = (gravity_float_t)logf(n);
-	#endif
-
-	gravity_vm_setslot(vm, VALUE_FROM_FLOAT(result), rindex);
-	return true;
+    // missing parameters check here
+    // 1. number of args
+    // 2. args type
+
+    // assuming arg of type float (in a real example there should be a conversion if not float)
+    gravity_float_t n = VALUE_AS_FLOAT(args[1]);
+
+    // gravity can be compiled with FLOAT as 32 or 64 bit
+    #if GRAVITY_ENABLE_DOUBLE
+    gravity_float_t result = (gravity_float_t)log(n);
+    #else
+    gravity_float_t result = (gravity_float_t)logf(n);
+    #endif
+
+    gravity_vm_setslot(vm, VALUE_FROM_FLOAT(result), rindex);
+    return true;
 }
 }
 
 
 static bool math_pow (gravity_vm *vm, gravity_value_t *args, uint16_t nargs, uint32_t rindex) {
 static bool math_pow (gravity_vm *vm, gravity_value_t *args, uint16_t nargs, uint32_t rindex) {
-	// missing parameters check here
-	// 1. number of args
-	// 2. args type
+    // missing parameters check here
+    // 1. number of args
+    // 2. args type
 
 
-	// assuming arg 1 of type float (in a real example there should be a conversion if not float)
-	gravity_float_t n1 = VALUE_AS_FLOAT(args[1]);
+    // assuming arg 1 of type float (in a real example there should be a conversion if not float)
+    gravity_float_t n1 = VALUE_AS_FLOAT(args[1]);
 
 
-	// assuming arg 2 of type float (in a real example there should be a conversion if not float)
-	gravity_float_t n2 = VALUE_AS_FLOAT(args[2]);
+    // assuming arg 2 of type float (in a real example there should be a conversion if not float)
+    gravity_float_t n2 = VALUE_AS_FLOAT(args[2]);
 
 
-	double result = pow((double)n1, (double)n2);
+    double result = pow((double)n1, (double)n2);
 
 
-	gravity_vm_setslot(vm, VALUE_FROM_FLOAT((gravity_float_t)result), rindex);
-	return true;
+    gravity_vm_setslot(vm, VALUE_FROM_FLOAT((gravity_float_t)result), rindex);
+    return true;
 }
 }
 
 
 // MARK: -
 // MARK: -
 
 
 static void create_math_class (gravity_vm *vm) {
 static void create_math_class (gravity_vm *vm) {
-	// create a new class (a pair of classes since we are creating a class and its meta-class)
-	gravity_class_t *c = gravity_class_new_pair(NULL, CLASS_NAME, NULL, 0, 0);
+    // create a new class (a pair of classes since we are creating a class and its meta-class)
+    gravity_class_t *c = gravity_class_new_pair(NULL, CLASS_NAME, NULL, 0, 0);
 
 
-	// we want to register properties and methods callback to its meta-class
-	// so user can access Math.property and Math.method without the need to instantiate it
+    // we want to register properties and methods callback to its meta-class
+    // so user can access Math.property and Math.method without the need to instantiate it
 
 
-	// get its meta-class
-	gravity_class_t *meta = gravity_class_get_meta(c);
+    // get its meta-class
+    gravity_class_t *meta = gravity_class_get_meta(c);
 
 
-	// start binding methods and properties (special methods) to the meta class
+    // start binding methods and properties (special methods) to the meta class
 
 
-	// *** LOG METHOD ***
-	// 1. create a gravity_function_t from the c function
-	gravity_function_t *logf = gravity_function_new_internal(NULL, NULL, math_log, 0);
+    // *** LOG METHOD ***
+    // 1. create a gravity_function_t from the c function
+    gravity_function_t *logf = gravity_function_new_internal(NULL, NULL, math_log, 0);
 
 
-	// 2. create a closure from the gravity_function_t
-	gravity_closure_t *logc = gravity_closure_new(NULL, logf);
+    // 2. create a closure from the gravity_function_t
+    gravity_closure_t *logc = gravity_closure_new(NULL, logf);
 
 
-	// 3. bind closure VALUE to meta class
-	gravity_class_bind(meta, "log", VALUE_FROM_OBJECT(logc));
+    // 3. bind closure VALUE to meta class
+    gravity_class_bind(meta, "log", VALUE_FROM_OBJECT(logc));
 
 
-	// *** POW METHOD ***
-	// 1. create a gravity_function_t from the c function
-	gravity_function_t *powf = gravity_function_new_internal(NULL, NULL, math_pow, 0);
+    // *** POW METHOD ***
+    // 1. create a gravity_function_t from the c function
+    gravity_function_t *powf = gravity_function_new_internal(NULL, NULL, math_pow, 0);
 
 
-	// 2. create a closure from the gravity_function_t
-	gravity_closure_t *powc = gravity_closure_new(NULL, powf);
+    // 2. create a closure from the gravity_function_t
+    gravity_closure_t *powc = gravity_closure_new(NULL, powf);
 
 
-	// 3. bind closure VALUE to meta class
-	gravity_class_bind(meta, "pow", VALUE_FROM_OBJECT(powc));
+    // 3. bind closure VALUE to meta class
+    gravity_class_bind(meta, "pow", VALUE_FROM_OBJECT(powc));
 
 
-	// *** PI PROPERTY (getter only) ***
-	// 1. create a gravity_function_t from the c function
-	gravity_function_t *pif = gravity_function_new_internal(NULL, NULL, math_pi, 0);
+    // *** PI PROPERTY (getter only) ***
+    // 1. create a gravity_function_t from the c function
+    gravity_function_t *pif = gravity_function_new_internal(NULL, NULL, math_pi, 0);
 
 
-	// 2. create a closure from the gravity_function_t
-	gravity_closure_t *pi_getter = gravity_closure_new(NULL, pif);
+    // 2. create a closure from the gravity_function_t
+    gravity_closure_t *pi_getter = gravity_closure_new(NULL, pif);
 
 
-	// 3. create a new special function to represents getter and setter (NULL in this case)
-	gravity_function_t *f = gravity_function_new_special(vm, NULL, GRAVITY_COMPUTED_INDEX, pi_getter, NULL);
+    // 3. create a new special function to represents getter and setter (NULL in this case)
+    gravity_function_t *f = gravity_function_new_special(vm, NULL, GRAVITY_COMPUTED_INDEX, pi_getter, NULL);
 
 
-	// 4. create a closure for the special function
-	gravity_closure_t *closure_property = gravity_closure_new(NULL, f);
+    // 4. create a closure for the special function
+    gravity_closure_t *closure_property = gravity_closure_new(NULL, f);
 
 
-	// 5. bind closure VALUE to meta class
-	gravity_class_bind(meta, "pi", VALUE_FROM_OBJECT(closure_property));
+    // 5. bind closure VALUE to meta class
+    gravity_class_bind(meta, "pi", VALUE_FROM_OBJECT(closure_property));
 
 
-	// LAST STEP
-	// register newly defined C class into Gravity VM
-	gravity_vm_setvalue(vm, CLASS_NAME, VALUE_FROM_OBJECT(c));
+    // LAST STEP
+    // register newly defined C class into Gravity VM
+    gravity_vm_setvalue(vm, CLASS_NAME, VALUE_FROM_OBJECT(c));
 }
 }
 
 
 // MARK: -
 // MARK: -
 
 
 int main(int argc, const char * argv[]) {
 int main(int argc, const char * argv[]) {
 
 
-	// setup a minimal delegate
-	gravity_delegate_t delegate = {
-		.error_callback = report_error
-	};
+    // setup a minimal delegate
+    gravity_delegate_t delegate = {
+        .error_callback = report_error
+    };
 
 
-	// compile source into a closure
-	gravity_compiler_t *compiler = gravity_compiler_create(&delegate);
-	gravity_closure_t *closure = gravity_compiler_run(compiler, source, strlen(source), 0, true);
-	if (!closure) return -1;
+    // compile source into a closure
+    gravity_compiler_t *compiler = gravity_compiler_create(&delegate);
+    gravity_closure_t *closure = gravity_compiler_run(compiler, source, strlen(source), 0, true);
+    if (!closure) return -1;
 
 
-	// setup a new VM and a new fiber
-	gravity_vm *vm = gravity_vm_new(&delegate);
+    // setup a new VM and a new fiber
+    gravity_vm *vm = gravity_vm_new(&delegate);
 
 
-	// transfer memory from compiler to VM and then free compiler
-	gravity_compiler_transfer(compiler, vm);
-	gravity_compiler_free(compiler);
+    // transfer memory from compiler to VM and then free compiler
+    gravity_compiler_transfer(compiler, vm);
+    gravity_compiler_free(compiler);
 
 
-	// create a new math class with methods and properties and register it to the VM
-	create_math_class(vm);
+    // create a new math class with methods and properties and register it to the VM
+    create_math_class(vm);
 
 
-	// expected result: 12.387436
-	// pi = 3.1415
-	// n1 = log(pi) => 1.1447
-	// n2 = pow(pi, 2.12) => 11.3221
+    // expected result: 12.387436
+    // pi = 3.1415
+    // n1 = log(pi) => 1.1447
+    // n2 = pow(pi, 2.12) => 11.3221
 
 
-	// Math class is now available from Gravity code so we can start excuting previously compiled closure
-	if (gravity_vm_runmain(vm, closure)) {
-		gravity_value_t result = gravity_vm_result(vm);
-		double t = gravity_vm_time(vm);
+    // Math class is now available from Gravity code so we can start excuting previously compiled closure
+    if (gravity_vm_runmain(vm, closure)) {
+        gravity_value_t result = gravity_vm_result(vm);
+        double t = gravity_vm_time(vm);
 
 
-		char buffer[512];
-		gravity_value_dump(vm, result, buffer, sizeof(buffer));
-		printf("RESULT: %s (in %.4f ms)\n\n", buffer, t);
-	}
+        char buffer[512];
+        gravity_value_dump(vm, result, buffer, sizeof(buffer));
+        printf("RESULT: %s (in %.4f ms)\n\n", buffer, t);
+    }
 
 
-	// our Math C class was not exposed to the GC (we passed NULL as vm parameter) so we would need to manually free it here
-	// free class and its methods here
+    // our Math C class was not exposed to the GC (we passed NULL as vm parameter) so we would need to manually free it here
+    // free class and its methods here
 
 
-	// free vm and base classes
-	if (vm) gravity_vm_free(vm);
-	gravity_core_free();
+    // free vm and base classes
+    if (vm) gravity_vm_free(vm);
+    gravity_core_free();
 }
 }

+ 65 - 65
api/exec_gravity.c

@@ -15,76 +15,76 @@ static const char *source = "func add (a, b) {return a + b;}; \
 
 
 // error callback
 // error callback
 static void report_error (gravity_vm *vm, error_type_t error_type, const char *message,
 static void report_error (gravity_vm *vm, error_type_t error_type, const char *message,
-						  error_desc_t error_desc, void *xdata) {
-	#pragma unused(vm, xdata)
-	const char *type = "N/A";
-	switch (error_type) {
-		case GRAVITY_ERROR_NONE: type = "NONE"; break;
-		case GRAVITY_ERROR_SYNTAX: type = "SYNTAX"; break;
-		case GRAVITY_ERROR_SEMANTIC: type = "SEMANTIC"; break;
-		case GRAVITY_ERROR_RUNTIME: type = "RUNTIME"; break;
-		case GRAVITY_WARNING: type = "WARNING"; break;
-		case GRAVITY_ERROR_IO: type = "I/O"; break;
-	}
-
-	if (error_type == GRAVITY_ERROR_RUNTIME) printf("RUNTIME ERROR: ");
-	else printf("%s ERROR on %d (%d,%d): ", type, error_desc.fileid, error_desc.lineno, error_desc.colno);
-	printf("%s\n", message);
+                          error_desc_t error_desc, void *xdata) {
+    #pragma unused(vm, xdata)
+    const char *type = "N/A";
+    switch (error_type) {
+        case GRAVITY_ERROR_NONE: type = "NONE"; break;
+        case GRAVITY_ERROR_SYNTAX: type = "SYNTAX"; break;
+        case GRAVITY_ERROR_SEMANTIC: type = "SEMANTIC"; break;
+        case GRAVITY_ERROR_RUNTIME: type = "RUNTIME"; break;
+        case GRAVITY_WARNING: type = "WARNING"; break;
+        case GRAVITY_ERROR_IO: type = "I/O"; break;
+    }
+
+    if (error_type == GRAVITY_ERROR_RUNTIME) printf("RUNTIME ERROR: ");
+    else printf("%s ERROR on %d (%d,%d): ", type, error_desc.fileid, error_desc.lineno, error_desc.colno);
+    printf("%s\n", message);
 }
 }
 
 
 
 
 int main(int argc, const char * argv[]) {
 int main(int argc, const char * argv[]) {
 
 
-	// setup a minimal delegate
-	gravity_delegate_t delegate = {
-		.error_callback = report_error
-	};
-
-	// compile source into a closure
-	gravity_compiler_t *compiler = gravity_compiler_create(&delegate);
-	gravity_closure_t *closure = gravity_compiler_run(compiler, source, strlen(source), 0, true);
-	if (!closure) return -1;
-
-	// setup a new VM and a new fiber
-	gravity_vm *vm = gravity_vm_new(&delegate);
-
-	// transfer memory from compiler to VM and then free compiler
-	gravity_compiler_transfer(compiler, vm);
-	gravity_compiler_free(compiler);
-
-	// load closure into VM context
-	gravity_vm_loadclosure(vm, closure);
-
-	// create parameters (that must be boxed) for the closure
-	gravity_value_t n1 = VALUE_FROM_INT(30);
-	gravity_value_t n2 = VALUE_FROM_INT(50);
-	gravity_value_t params[2] = {n1, n2};
-
-	// lookup add closure
-	gravity_value_t add = gravity_vm_getvalue(vm, "add", strlen("add"));
-	if (!VALUE_ISA_CLOSURE(add)) return -2;
-
-	// execute add closure and print result
-	if (gravity_vm_runclosure(vm, VALUE_AS_CLOSURE(add), add, params, 2)) {
-		gravity_value_t result = gravity_vm_result(vm);
-		printf("add result ");
-		gravity_value_dump(vm, result, NULL, 0);
-	}
-
-	// lookup mul closure
-	gravity_value_t mul = gravity_vm_getvalue(vm, "mul", strlen("mul"));
-	if (!VALUE_ISA_CLOSURE(mul)) return -3;
-
-	// execute mul closure and print result
-	if (gravity_vm_runclosure(vm, VALUE_AS_CLOSURE(mul), mul, params, 2)) {
-		gravity_value_t result = gravity_vm_result(vm);
-		printf("mul result ");
-		gravity_value_dump(vm, result, NULL, 0);
-	}
-
-	// free vm and core classes
-	gravity_vm_free(vm);
-	gravity_core_free();
+    // setup a minimal delegate
+    gravity_delegate_t delegate = {
+        .error_callback = report_error
+    };
+
+    // compile source into a closure
+    gravity_compiler_t *compiler = gravity_compiler_create(&delegate);
+    gravity_closure_t *closure = gravity_compiler_run(compiler, source, strlen(source), 0, true);
+    if (!closure) return -1;
+
+    // setup a new VM and a new fiber
+    gravity_vm *vm = gravity_vm_new(&delegate);
+
+    // transfer memory from compiler to VM and then free compiler
+    gravity_compiler_transfer(compiler, vm);
+    gravity_compiler_free(compiler);
+
+    // load closure into VM context
+    gravity_vm_loadclosure(vm, closure);
+
+    // create parameters (that must be boxed) for the closure
+    gravity_value_t n1 = VALUE_FROM_INT(30);
+    gravity_value_t n2 = VALUE_FROM_INT(50);
+    gravity_value_t params[2] = {n1, n2};
+
+    // lookup add closure
+    gravity_value_t add = gravity_vm_getvalue(vm, "add", strlen("add"));
+    if (!VALUE_ISA_CLOSURE(add)) return -2;
+
+    // execute add closure and print result
+    if (gravity_vm_runclosure(vm, VALUE_AS_CLOSURE(add), add, params, 2)) {
+        gravity_value_t result = gravity_vm_result(vm);
+        printf("add result ");
+        gravity_value_dump(vm, result, NULL, 0);
+    }
+
+    // lookup mul closure
+    gravity_value_t mul = gravity_vm_getvalue(vm, "mul", strlen("mul"));
+    if (!VALUE_ISA_CLOSURE(mul)) return -3;
+
+    // execute mul closure and print result
+    if (gravity_vm_runclosure(vm, VALUE_AS_CLOSURE(mul), mul, params, 2)) {
+        gravity_value_t result = gravity_vm_result(vm);
+        printf("mul result ");
+        gravity_value_dump(vm, result, NULL, 0);
+    }
+
+    // free vm and core classes
+    gravity_vm_free(vm);
+    gravity_core_free();
 
 
     return 0;
     return 0;
 }
 }

+ 9 - 9
gravity_visualstudio/unistd.h

@@ -7,15 +7,15 @@
 
 
 #define bzero(b, len) memset((b), 0, (len))
 #define bzero(b, len) memset((b), 0, (len))
 
 
-typedef SSIZE_T ssize_t;
-typedef int mode_t;
+typedef SSIZE_T     ssize_t;
+typedef int         mode_t;
 
 
-#define open _open
-#define close _close
-#define read _read
-#define write _write
+#define open        _open
+#define close       _close
+#define read        _read
+#define write       _write
 
 
-#define snprintf _snprintf
-#define __func__ __FUNCTION__
+#define snprintf    _snprintf
+#define __func__    __FUNCTION__
 
 
-// Fix for Visual Studio
+// Fix for Visual Studio

+ 198 - 198
src/cli/gravity.c

@@ -15,25 +15,25 @@
 #define DEFAULT_OUTPUT "gravity.g"
 #define DEFAULT_OUTPUT "gravity.g"
 
 
 typedef struct {
 typedef struct {
-    bool            processed;
-    bool            is_fuzzy;
+    bool                processed;
+    bool                is_fuzzy;
     
     
-    uint32_t        ncount;
-    uint32_t        nsuccess;
-    uint32_t        nfailure;
+    uint32_t            ncount;
+    uint32_t            nsuccess;
+    uint32_t            nfailure;
     
     
-    error_type_t    expected_error;
-    gravity_value_t expected_value;
-    int32_t         expected_row;
-    int32_t         expected_col;
+    error_type_t        expected_error;
+    gravity_value_t     expected_value;
+    int32_t             expected_row;
+    int32_t             expected_col;
 } unittest_data;
 } unittest_data;
 
 
 typedef enum  {
 typedef enum  {
-	OP_COMPILE,			// just compile source code and exit
-	OP_RUN,				// just run an already compiled file
-	OP_COMPILE_RUN,		// compile source code and run it
+    OP_COMPILE,         // just compile source code and exit
+    OP_RUN,             // just run an already compiled file
+    OP_COMPILE_RUN,     // compile source code and run it
     OP_INLINE_RUN,      // compile and execure source passed inline
     OP_INLINE_RUN,      // compile and execure source passed inline
-	OP_REPL,			// run a read eval print loop
+    OP_REPL,            // run a read eval print loop
     OP_UNITTEST         // unit test mode
     OP_UNITTEST         // unit test mode
 } op_type;
 } op_type;
 
 
@@ -44,50 +44,50 @@ static const char *test_folder_path = NULL;
 static bool quiet_flag = false;
 static bool quiet_flag = false;
 
 
 static void report_error (gravity_vm *vm, error_type_t error_type, const char *message, error_desc_t error_desc, void *xdata) {
 static void report_error (gravity_vm *vm, error_type_t error_type, const char *message, error_desc_t error_desc, void *xdata) {
-	#pragma unused(vm, xdata)
-	const char *type = "N/A";
-	switch (error_type) {
-		case GRAVITY_ERROR_NONE: type = "NONE"; break;
-		case GRAVITY_ERROR_SYNTAX: type = "SYNTAX"; break;
-		case GRAVITY_ERROR_SEMANTIC: type = "SEMANTIC"; break;
-		case GRAVITY_ERROR_RUNTIME: type = "RUNTIME"; break;
-		case GRAVITY_WARNING: type = "WARNING"; break;
-		case GRAVITY_ERROR_IO: type = "I/O"; break;
-	}
-
-	if (error_type == GRAVITY_ERROR_RUNTIME) printf("RUNTIME ERROR: ");
-	else printf("%s ERROR on %d (%d,%d): ", type, error_desc.fileid, error_desc.lineno, error_desc.colno);
-	printf("%s\n", message);
+    #pragma unused(vm, xdata)
+    const char *type = "N/A";
+    switch (error_type) {
+        case GRAVITY_ERROR_NONE: type = "NONE"; break;
+        case GRAVITY_ERROR_SYNTAX: type = "SYNTAX"; break;
+        case GRAVITY_ERROR_SEMANTIC: type = "SEMANTIC"; break;
+        case GRAVITY_ERROR_RUNTIME: type = "RUNTIME"; break;
+        case GRAVITY_WARNING: type = "WARNING"; break;
+        case GRAVITY_ERROR_IO: type = "I/O"; break;
+    }
+
+    if (error_type == GRAVITY_ERROR_RUNTIME) printf("RUNTIME ERROR: ");
+    else printf("%s ERROR on %d (%d,%d): ", type, error_desc.fileid, error_desc.lineno, error_desc.colno);
+    printf("%s\n", message);
 }
 }
 
 
 static const char *load_file (const char *file, size_t *size, uint32_t *fileid, void *xdata) {
 static const char *load_file (const char *file, size_t *size, uint32_t *fileid, void *xdata) {
-	#pragma unused(fileid, xdata)
-
-	// this callback is called each time an import statement is parsed
-	// file arg represents what user wrote after the import keyword, for example:
-	// import "file2"
-	// import "file2.gravity"
-	// import "../file2"
-	// import "/full_path_to_file2"
-
-	// it is callback's responsability to resolve file path based on current working directory
-	// or based on user defined search paths
-	// and returns:
-	// size of file in *size
-	// fileid (if any) in *fileid
-	// content of file as return value of the function
-
-	// fileid will then be used each time an error is reported by the compiler
-	// so it is responsability of this function to map somewhere the association
-	// between fileid and real file/path name
-
-	// fileid is not used in this example
-	// xdata not used here but it the xdata field set in the delegate
-	// please note than in this simple example the imported file must be
-	// in the same folder as the main input file
-
-	if (!file_exists(file)) return NULL;
-	return file_read(file, size);
+    #pragma unused(fileid, xdata)
+
+    // this callback is called each time an import statement is parsed
+    // file arg represents what user wrote after the import keyword, for example:
+    // import "file2"
+    // import "file2.gravity"
+    // import "../file2"
+    // import "/full_path_to_file2"
+
+    // it is callback's responsability to resolve file path based on current working directory
+    // or based on user defined search paths
+    // and returns:
+    // size of file in *size
+    // fileid (if any) in *fileid
+    // content of file as return value of the function
+
+    // fileid will then be used each time an error is reported by the compiler
+    // so it is responsability of this function to map somewhere the association
+    // between fileid and real file/path name
+
+    // fileid is not used in this example
+    // xdata not used here but it the xdata field set in the delegate
+    // please note than in this simple example the imported file must be
+    // in the same folder as the main input file
+
+    if (!file_exists(file)) return NULL;
+    return file_read(file, size);
 }
 }
 
 
 // MARK: - Unit Test -
 // MARK: - Unit Test -
@@ -247,96 +247,96 @@ static void unittest_scan (const char *folder_path, unittest_data *data) {
 // MARK: - General -
 // MARK: - General -
 
 
 static void print_version (void) {
 static void print_version (void) {
-	printf("Gravity version %s (%s)\n", GRAVITY_VERSION, GRAVITY_BUILD_DATE);
+    printf("Gravity version %s (%s)\n", GRAVITY_VERSION, GRAVITY_BUILD_DATE);
 }
 }
 
 
 static void print_help (void) {
 static void print_help (void) {
-	printf("usage: gravity [options]\n");
-	printf("no options means enter interactive mode (not yet supported)\n");
-	printf("Available options are:\n");
-	printf("--version          show version information and exit\n");
-	printf("--help             show command line usage and exit\n");
-	printf("-c input_file      compile input_file (default to gravity.json)\n");
-	printf("-o output_file     specify output file name\n");
-	printf("-x input_file      execute input_file (JSON format expected)\n");
-	printf("-i source_code     compile and execute source_code string\n");
-	printf("-q                 don't print result and execution time\n");
-	printf("file_name          compile file_name and executes it\n");
+    printf("usage: gravity [options]\n");
+    printf("no options means enter interactive mode (not yet supported)\n");
+    printf("Available options are:\n");
+    printf("--version          show version information and exit\n");
+    printf("--help             show command line usage and exit\n");
+    printf("-c input_file      compile input_file (default to gravity.json)\n");
+    printf("-o output_file     specify output file name\n");
+    printf("-x input_file      execute input_file (JSON format expected)\n");
+    printf("-i source_code     compile and execute source_code string\n");
+    printf("-q                 don't print result and execution time\n");
+    printf("file_name          compile file_name and executes it\n");
 }
 }
 
 
 static op_type parse_args (int argc, const char* argv[]) {
 static op_type parse_args (int argc, const char* argv[]) {
-	if (argc == 1) return OP_REPL;
-
-	if (argc == 2 && strcmp(argv[1], "--version") == 0) {
-		print_version();
-		exit(0);
-	}
-
-	if (argc == 2 && strcmp(argv[1], "--help") == 0) {
-		print_help();
-		exit(0);
-	}
-
-	op_type type = OP_RUN;
-	for (int i=1; i<argc; ++i) {
-		if ((strcmp(argv[i], "-c") == 0) && (i+1 < argc)) {
-			input_file = argv[++i];
-			type = OP_COMPILE;
-		}
-		else if ((strcmp(argv[i], "-o") == 0) && (i+1 < argc)) {
-			output_file = argv[++i];
-		}
-		else if ((strcmp(argv[i], "-x") == 0) && (i+1 < argc)) {
-			input_file = argv[++i];
-			type = OP_RUN;
-		}
-		else if ((strcmp(argv[i], "-i") == 0) && (i+1 < argc)) {
-			input_file = argv[++i];
-			type = OP_INLINE_RUN;
-		}
-		else if (strcmp(argv[i], "-q") == 0) {
-			quiet_flag = true;
-		}
+    if (argc == 1) return OP_REPL;
+
+    if (argc == 2 && strcmp(argv[1], "--version") == 0) {
+        print_version();
+        exit(0);
+    }
+
+    if (argc == 2 && strcmp(argv[1], "--help") == 0) {
+        print_help();
+        exit(0);
+    }
+
+    op_type type = OP_RUN;
+    for (int i=1; i<argc; ++i) {
+        if ((strcmp(argv[i], "-c") == 0) && (i+1 < argc)) {
+            input_file = argv[++i];
+            type = OP_COMPILE;
+        }
+        else if ((strcmp(argv[i], "-o") == 0) && (i+1 < argc)) {
+            output_file = argv[++i];
+        }
+        else if ((strcmp(argv[i], "-x") == 0) && (i+1 < argc)) {
+            input_file = argv[++i];
+            type = OP_RUN;
+        }
+        else if ((strcmp(argv[i], "-i") == 0) && (i+1 < argc)) {
+            input_file = argv[++i];
+            type = OP_INLINE_RUN;
+        }
+        else if (strcmp(argv[i], "-q") == 0) {
+            quiet_flag = true;
+        }
         else if ((strcmp(argv[i], "-t") == 0) && (i+1 < argc)) {
         else if ((strcmp(argv[i], "-t") == 0) && (i+1 < argc)) {
             unittest_folder = argv[++i];
             unittest_folder = argv[++i];
             type = OP_UNITTEST;
             type = OP_UNITTEST;
         }
         }
-		else {
-			input_file = argv[i];
-			type = OP_COMPILE_RUN;
-		}
-	}
+        else {
+            input_file = argv[i];
+            type = OP_COMPILE_RUN;
+        }
+    }
 
 
-	return type;
+    return type;
 }
 }
 
 
 // MARK: - Special Modes
 // MARK: - Special Modes
 
 
 static void gravity_repl (void) {
 static void gravity_repl (void) {
-	printf("REPL not yet implemented.\n");
-	exit(0);
-
-	/*
-	// setup compiler/VM delegate
-	gravity_delegate_t delegate = {
-		.error_callback = report_error,
-	};
-
-	gravity_compiler_t	*compiler = gravity_compiler_create(&delegate);
-	gravity_vm	*vm = gravity_vm_new(&delegate);
-	char		*line = NULL;
-	int			length = 0;
-
-	printf("Welcome to Gravity v%s\n", GRAVITY_VERSION);
-	while((line = readline("> ", &length)) != NULL) {
-		// to be implemented
-		//	gravity_compiler_eval(compiler, vm, line, length);
-		free(line);
-	}
-
-	gravity_compiler_free(compiler);
-	gravity_vm_free(vm);
-	 */
+    printf("REPL not yet implemented.\n");
+    exit(0);
+
+    /*
+    // setup compiler/VM delegate
+    gravity_delegate_t delegate = {
+        .error_callback = report_error,
+    };
+
+    gravity_compiler_t    *compiler = gravity_compiler_create(&delegate);
+    gravity_vm    *vm = gravity_vm_new(&delegate);
+    char        *line = NULL;
+    int            length = 0;
+
+    printf("Welcome to Gravity v%s\n", GRAVITY_VERSION);
+    while((line = readline("> ", &length)) != NULL) {
+        // to be implemented
+        //    gravity_compiler_eval(compiler, vm, line, length);
+        free(line);
+    }
+
+    gravity_compiler_free(compiler);
+    gravity_vm_free(vm);
+     */
 }
 }
 
 
 static void gravity_unittest (void) {
 static void gravity_unittest (void) {
@@ -386,37 +386,37 @@ static void gravity_unittest (void) {
 // MARK: -
 // MARK: -
 
 
 int main (int argc, const char* argv[]) {
 int main (int argc, const char* argv[]) {
-	// parse arguments and return operation type
-	op_type type = parse_args(argc, argv);
+    // parse arguments and return operation type
+    op_type type = parse_args(argc, argv);
 
 
-	// special repl case
-	if (type == OP_REPL) gravity_repl();
+    // special repl case
+    if (type == OP_REPL) gravity_repl();
     
     
     // special unit test mode
     // special unit test mode
     if (type == OP_UNITTEST) gravity_unittest();
     if (type == OP_UNITTEST) gravity_unittest();
 
 
-	// initialize memory debugger (if activated)
-	mem_init();
+    // initialize memory debugger (if activated)
+    mem_init();
 
 
-	// closure to execute/serialize
-	gravity_closure_t *closure = NULL;
+    // closure to execute/serialize
+    gravity_closure_t *closure = NULL;
 
 
-	// optional compiler
-	gravity_compiler_t *compiler = NULL;
+    // optional compiler
+    gravity_compiler_t *compiler = NULL;
 
 
-	// setup compiler/VM delegate
-	gravity_delegate_t delegate = {
-		.error_callback = report_error,
-		.loadfile_callback = load_file
-	};
+    // setup compiler/VM delegate
+    gravity_delegate_t delegate = {
+        .error_callback = report_error,
+        .loadfile_callback = load_file
+    };
 
 
-	// create VM
-	gravity_vm *vm = gravity_vm_new(&delegate);
+    // create VM
+    gravity_vm *vm = gravity_vm_new(&delegate);
 
 
-	// check if input file is source code that needs to be compiled
-	if ((type == OP_COMPILE) || (type == OP_COMPILE_RUN) || (type == OP_INLINE_RUN)) {
+    // check if input file is source code that needs to be compiled
+    if ((type == OP_COMPILE) || (type == OP_COMPILE_RUN) || (type == OP_INLINE_RUN)) {
 
 
-		// load source code
+        // load source code
         size_t size = 0;
         size_t size = 0;
         const char *source_code = NULL;
         const char *source_code = NULL;
 
 
@@ -441,60 +441,60 @@ int main (int argc, const char* argv[]) {
             source_code = buffer;
             source_code = buffer;
         }
         }
 
 
-		// create compiler
-		compiler = gravity_compiler_create(&delegate);
-
-		// compile source code into a closure
-		closure = gravity_compiler_run(compiler, source_code, size, 0, false);
-		if (!closure) goto cleanup;
-
-		// check if closure needs to be serialized
-		if (type == OP_COMPILE) {
-			bool result = gravity_compiler_serialize_infile(compiler, closure, output_file);
-			if (!result) printf("Error serializing file %s\n", output_file);
-			goto cleanup;
-		}
-
-		// op is OP_COMPILE_RUN so transfer memory from compiler to VM
-		gravity_compiler_transfer(compiler, vm);
-
-	} else if (type == OP_RUN) {
-		// unserialize file
-		closure = gravity_vm_loadfile(vm, input_file);
-		if (!closure) {
-			printf("Error while loading compile file %s\n", input_file);
-			goto cleanup;
-		}
+        // create compiler
+        compiler = gravity_compiler_create(&delegate);
+
+        // compile source code into a closure
+        closure = gravity_compiler_run(compiler, source_code, size, 0, false);
+        if (!closure) goto cleanup;
+
+        // check if closure needs to be serialized
+        if (type == OP_COMPILE) {
+            bool result = gravity_compiler_serialize_infile(compiler, closure, output_file);
+            if (!result) printf("Error serializing file %s\n", output_file);
+            goto cleanup;
+        }
+
+        // op is OP_COMPILE_RUN so transfer memory from compiler to VM
+        gravity_compiler_transfer(compiler, vm);
+
+    } else if (type == OP_RUN) {
+        // unserialize file
+        closure = gravity_vm_loadfile(vm, input_file);
+        if (!closure) {
+            printf("Error while loading compile file %s\n", input_file);
+            goto cleanup;
+        }
     }
     }
 
 
-	// sanity check
-	assert(closure);
+    // sanity check
+    assert(closure);
 
 
-	if (gravity_vm_runmain(vm, closure)) {
-		gravity_value_t result = gravity_vm_result(vm);
-		double t = gravity_vm_time(vm);
+    if (gravity_vm_runmain(vm, closure)) {
+        gravity_value_t result = gravity_vm_result(vm);
+        double t = gravity_vm_time(vm);
 
 
-		char buffer[512];
-		gravity_value_dump(vm, result, buffer, sizeof(buffer));
-		if (!quiet_flag) {
-			printf("RESULT: %s (in %.4f ms)\n\n", buffer, t);
-		}
-	}
+        char buffer[512];
+        gravity_value_dump(vm, result, buffer, sizeof(buffer));
+        if (!quiet_flag) {
+            printf("RESULT: %s (in %.4f ms)\n\n", buffer, t);
+        }
+    }
 
 
 cleanup:
 cleanup:
-	if (compiler) gravity_compiler_free(compiler);
-	if (vm) gravity_vm_free(vm);
-	gravity_core_free();
-
-	#if GRAVITY_MEMORY_DEBUG
-	size_t current_memory = mem_leaks();
-	if (current_memory != 0) {
-		printf("--> VM leaks: %zu bytes\n", current_memory);
-		mem_stat();
-	} else {
-		printf("\tNo VM leaks found!\n");
-	}
-	#endif
-
-	return 0;
+    if (compiler) gravity_compiler_free(compiler);
+    if (vm) gravity_vm_free(vm);
+    gravity_core_free();
+
+    #if GRAVITY_MEMORY_DEBUG
+    size_t current_memory = mem_leaks();
+    if (current_memory != 0) {
+        printf("--> VM leaks: %zu bytes\n", current_memory);
+        mem_stat();
+    } else {
+        printf("\tNo VM leaks found!\n");
+    }
+    #endif
+
+    return 0;
 }
 }

+ 32 - 32
src/compiler/debug_macros.h

@@ -22,40 +22,40 @@
 #include <math.h>
 #include <math.h>
 #include "gravity_memory.h"
 #include "gravity_memory.h"
 
 
-#define GRAVITY_LEXEM_DEBUG			0
-#define GRAVITY_LEXER_DEGUB			0
-#define GRAVITY_PARSER_DEBUG		0
-#define GRAVITY_SEMA1_DEBUG         0
-#define GRAVITY_SEMA2_DEBUG		    0
-#define GRAVITY_AST_DEBUG			0
-#define GRAVITY_LOOKUP_DEBUG		0
-#define GRAVITY_SYMTABLE_DEBUG		0
-#define GRAVITY_CODEGEN_DEBUG		0
-#define GRAVITY_OPCODE_DEBUG		0
-#define GRAVITY_BYTECODE_DEBUG		0
-#define GRAVITY_REGISTER_DEBUG		0
-#define GRAVITY_FREE_DEBUG			0
-#define GRAVITY_DESERIALIZE_DEBUG	0
-
-#define PRINT_LINE(...)				printf(__VA_ARGS__);printf("\n");fflush(stdout)
+#define GRAVITY_LEXEM_DEBUG             0
+#define GRAVITY_LEXER_DEGUB             0
+#define GRAVITY_PARSER_DEBUG            0
+#define GRAVITY_SEMA1_DEBUG             0
+#define GRAVITY_SEMA2_DEBUG             0
+#define GRAVITY_AST_DEBUG               0
+#define GRAVITY_LOOKUP_DEBUG            0
+#define GRAVITY_SYMTABLE_DEBUG          0
+#define GRAVITY_CODEGEN_DEBUG           0
+#define GRAVITY_OPCODE_DEBUG            0
+#define GRAVITY_BYTECODE_DEBUG          0
+#define GRAVITY_REGISTER_DEBUG          0
+#define GRAVITY_FREE_DEBUG              0
+#define GRAVITY_DESERIALIZE_DEBUG       0
+
+#define PRINT_LINE(...)                 printf(__VA_ARGS__);printf("\n");fflush(stdout)
 
 
 #if GRAVITY_LEXER_DEGUB
 #if GRAVITY_LEXER_DEGUB
-#define DEBUG_LEXER(l)				gravity_lexer_debug(l)
+#define DEBUG_LEXER(l)                  gravity_lexer_debug(l)
 #else
 #else
 #define DEBUG_LEXER(...)
 #define DEBUG_LEXER(...)
 #endif
 #endif
 
 
 #if GRAVITY_LEXEM_DEBUG
 #if GRAVITY_LEXEM_DEBUG
-#define DEBUG_LEXEM(...)			do { if (!lexer->peeking) { \
-										printf("(%03d, %03d, %02d) ", lexer->token.lineno, lexer->token.colno, lexer->token.position); \
-										PRINT_LINE(__VA_ARGS__);} \
-									} while(0)
+#define DEBUG_LEXEM(...)                do { if (!lexer->peeking) { \
+                                            printf("(%03d, %03d, %02d) ", lexer->token.lineno, lexer->token.colno, lexer->token.position); \
+                                            PRINT_LINE(__VA_ARGS__);} \
+                                        } while(0)
 #else
 #else
 #define DEBUG_LEXEM(...)
 #define DEBUG_LEXEM(...)
 #endif
 #endif
 
 
 #if GRAVITY_PARSER_DEBUG
 #if GRAVITY_PARSER_DEBUG
-#define DEBUG_PARSER(...)			PRINT_LINE(__VA_ARGS__)
+#define DEBUG_PARSER(...)           PRINT_LINE(__VA_ARGS__)
 #else
 #else
 #define gravity_parser_debug(p)
 #define gravity_parser_debug(p)
 #define DEBUG_PARSER(...)
 #define DEBUG_PARSER(...)
@@ -68,59 +68,59 @@
 #endif
 #endif
 
 
 #if GRAVITY_SEMA2_DEBUG
 #if GRAVITY_SEMA2_DEBUG
-#define DEBUG_SEMA2(...)			PRINT_LINE(__VA_ARGS__)
+#define DEBUG_SEMA2(...)            PRINT_LINE(__VA_ARGS__)
 #else
 #else
 #define DEBUG_SEMA2(...)
 #define DEBUG_SEMA2(...)
 #endif
 #endif
 
 
 #if GRAVITY_LOOKUP_DEBUG
 #if GRAVITY_LOOKUP_DEBUG
-#define DEBUG_LOOKUP(...)			PRINT_LINE(__VA_ARGS__)
+#define DEBUG_LOOKUP(...)            PRINT_LINE(__VA_ARGS__)
 #else
 #else
 #define DEBUG_LOOKUP(...)
 #define DEBUG_LOOKUP(...)
 #endif
 #endif
 
 
 #if GRAVITY_SYMTABLE_DEBUG
 #if GRAVITY_SYMTABLE_DEBUG
-#define DEBUG_SYMTABLE(...)			printf("%*s",ident*4," ");PRINT_LINE(__VA_ARGS__)
+#define DEBUG_SYMTABLE(...)         printf("%*s",ident*4," ");PRINT_LINE(__VA_ARGS__)
 #else
 #else
 #define DEBUG_SYMTABLE(...)
 #define DEBUG_SYMTABLE(...)
 #endif
 #endif
 
 
 #if GRAVITY_CODEGEN_DEBUG
 #if GRAVITY_CODEGEN_DEBUG
-#define DEBUG_CODEGEN(...)			PRINT_LINE(__VA_ARGS__)
+#define DEBUG_CODEGEN(...)          PRINT_LINE(__VA_ARGS__)
 #else
 #else
 #define DEBUG_CODEGEN(...)
 #define DEBUG_CODEGEN(...)
 #endif
 #endif
 
 
 #if GRAVITY_OPCODE_DEBUG
 #if GRAVITY_OPCODE_DEBUG
-#define DEBUG_OPCODE(...)			PRINT_LINE(__VA_ARGS__)
+#define DEBUG_OPCODE(...)           PRINT_LINE(__VA_ARGS__)
 #else
 #else
 #define DEBUG_OPCODE(...)
 #define DEBUG_OPCODE(...)
 #endif
 #endif
 
 
 #if GRAVITY_BYTECODE_DEBUG
 #if GRAVITY_BYTECODE_DEBUG
-#define DEBUG_BYTECODE(...)			PRINT_LINE(__VA_ARGS__)
+#define DEBUG_BYTECODE(...)         PRINT_LINE(__VA_ARGS__)
 #else
 #else
 #define DEBUG_BYTECODE(...)
 #define DEBUG_BYTECODE(...)
 #endif
 #endif
 
 
 #if GRAVITY_REGISTER_DEBUG
 #if GRAVITY_REGISTER_DEBUG
-#define DEBUG_REGISTER(...)			PRINT_LINE(__VA_ARGS__)
+#define DEBUG_REGISTER(...)         PRINT_LINE(__VA_ARGS__)
 #else
 #else
 #define DEBUG_REGISTER(...)
 #define DEBUG_REGISTER(...)
 #endif
 #endif
 
 
 #if GRAVITY_FREE_DEBUG
 #if GRAVITY_FREE_DEBUG
-#define DEBUG_FREE(...)				PRINT_LINE(__VA_ARGS__)
+#define DEBUG_FREE(...)             PRINT_LINE(__VA_ARGS__)
 #else
 #else
 #define DEBUG_FREE(...)
 #define DEBUG_FREE(...)
 #endif
 #endif
 
 
 #if GRAVITY_DESERIALIZE_DEBUG
 #if GRAVITY_DESERIALIZE_DEBUG
-#define DEBUG_DESERIALIZE(...)		PRINT_LINE(__VA_ARGS__)
+#define DEBUG_DESERIALIZE(...)      PRINT_LINE(__VA_ARGS__)
 #else
 #else
 #define DEBUG_DESERIALIZE(...)
 #define DEBUG_DESERIALIZE(...)
 #endif
 #endif
 
 
-#define DEBUG_ALWAYS(...)			PRINT_LINE(__VA_ARGS__)
+#define DEBUG_ALWAYS(...)           PRINT_LINE(__VA_ARGS__)
 
 
 #endif
 #endif

+ 427 - 424
src/compiler/gravity_ast.c

@@ -15,476 +15,479 @@
 
 
 #define SETBASE(node,tagv,_tok,_meta)   node->base.tag = tagv; node->base.token = _tok; node->base.meta = _meta
 #define SETBASE(node,tagv,_tok,_meta)   node->base.tag = tagv; node->base.token = _tok; node->base.meta = _meta
 #define SETDECL(node,_decl)             node->base.decl = _decl
 #define SETDECL(node,_decl)             node->base.decl = _decl
-#define CHECK_REFCOUNT(_node)			if (_node->base.refcount > 0) {--_node->base.refcount; return;}
+#define CHECK_REFCOUNT(_node)           if (_node->base.refcount > 0) {--_node->base.refcount; return;}
 
 
 // MARK: -
 // MARK: -
 
 
 void_r *void_array_create (void) {
 void_r *void_array_create (void) {
-	void_r *r = mem_alloc(NULL, sizeof(void_r));
-	marray_init(*r);
-	return r;
+    void_r *r = mem_alloc(NULL, sizeof(void_r));
+    marray_init(*r);
+    return r;
 }
 }
 
 
 cstring_r *cstring_array_create (void) {
 cstring_r *cstring_array_create (void) {
-	cstring_r *r = mem_alloc(NULL, sizeof(cstring_r));
-	gnode_array_init(r);
-	return r;
+    cstring_r *r = mem_alloc(NULL, sizeof(cstring_r));
+    gnode_array_init(r);
+    return r;
 }
 }
 
 
 gnode_r *gnode_array_create (void) {
 gnode_r *gnode_array_create (void) {
-	gnode_r *r = mem_alloc(NULL, sizeof(gnode_r));
-	gnode_array_init(r);
-	return r;
+    gnode_r *r = mem_alloc(NULL, sizeof(gnode_r));
+    gnode_array_init(r);
+    return r;
 }
 }
 
 
 void gnode_array_sethead(gnode_r *list, gnode_t *node) {
 void gnode_array_sethead(gnode_r *list, gnode_t *node) {
     if (!list || !node) return;
     if (!list || !node) return;
 
 
-	// get old size
-	size_t list_size = gnode_array_size(list);
+    // get old size
+    size_t list_size = gnode_array_size(list);
 
 
-	// push node at the end to trigger memory allocation (if needed)
-	gnode_array_push(list, node);
+    // push node at the end to trigger memory allocation (if needed)
+    gnode_array_push(list, node);
 
 
-	// shift elements in array
-	for (size_t i=list_size; i>0; --i) {
-		list->p[i] = list->p[i-1];
-	}
+    // shift elements in array
+    for (size_t i=list_size; i>0; --i) {
+        list->p[i] = list->p[i-1];
+    }
 
 
-	// set new array head
-	list->p[0] = node;
+    // set new array head
+    list->p[0] = node;
 }
 }
 
 
 gnode_r *gnode_array_remove_byindex(gnode_r *old_list, size_t index) {
 gnode_r *gnode_array_remove_byindex(gnode_r *old_list, size_t index) {
-	// get old size
-	size_t list_size = gnode_array_size(old_list);
-	if (index >= list_size) return NULL;
-
-	gnode_r *new_list = gnode_array_create();
-	for (size_t i=0; i<list_size; ++i) {
-		if (i == index) continue;
-		gnode_t *node = gnode_array_get(old_list, i);
-		gnode_array_push(new_list, node);
-	}
-	gnode_array_free(old_list);
-	return new_list;
+    // get old size
+    size_t list_size = gnode_array_size(old_list);
+    if (index >= list_size) return NULL;
+
+    gnode_r *new_list = gnode_array_create();
+    for (size_t i=0; i<list_size; ++i) {
+        if (i == index) continue;
+        gnode_t *node = gnode_array_get(old_list, i);
+        gnode_array_push(new_list, node);
+    }
+    gnode_array_free(old_list);
+    return new_list;
 }
 }
 
 
 gupvalue_t *gnode_function_add_upvalue(gnode_function_decl_t *f, gnode_var_t *symbol, uint16_t n) {
 gupvalue_t *gnode_function_add_upvalue(gnode_function_decl_t *f, gnode_var_t *symbol, uint16_t n) {
-	// create uplist if necessary
-	if (!f->uplist) {
-		f->uplist = mem_alloc(NULL, sizeof(gupvalue_r));
-		gnode_array_init(f->uplist);
-	}
-
-	// lookup symbol in uplist (if any)
-	gtype_array_each(f->uplist, {
-		// symbol already found in uplist so return its index
-		gnode_var_t *node = (gnode_var_t *)val->node;
-		if (strcmp(node->identifier, symbol->identifier) == 0) return val;
-	}, gupvalue_t *);
-
-	// symbol not found in uplist so add it
-	gupvalue_t *upvalue = mem_alloc(NULL, sizeof(gupvalue_t));
-	upvalue->node = (gnode_t *)symbol;
-	upvalue->index = (n == 1) ? symbol->index : (uint32_t)gnode_array_size(f->uplist);
-	upvalue->selfindex = (uint32_t)gnode_array_size(f->uplist);
-	upvalue->is_direct = (n == 1);
-	marray_push(gupvalue_t*, *f->uplist, upvalue);
-
-	// return symbol position in uplist
-	return upvalue;
+    // create uplist if necessary
+    if (!f->uplist) {
+        f->uplist = mem_alloc(NULL, sizeof(gupvalue_r));
+        gnode_array_init(f->uplist);
+    }
+
+    // lookup symbol in uplist (if any)
+    gtype_array_each(f->uplist, {
+        // symbol already found in uplist so return its index
+        gnode_var_t *node = (gnode_var_t *)val->node;
+        if (strcmp(node->identifier, symbol->identifier) == 0) return val;
+    }, gupvalue_t *);
+
+    // symbol not found in uplist so add it
+    gupvalue_t *upvalue = mem_alloc(NULL, sizeof(gupvalue_t));
+    upvalue->node = (gnode_t *)symbol;
+    upvalue->index = (n == 1) ? symbol->index : (uint32_t)gnode_array_size(f->uplist);
+    upvalue->selfindex = (uint32_t)gnode_array_size(f->uplist);
+    upvalue->is_direct = (n == 1);
+    marray_push(gupvalue_t*, *f->uplist, upvalue);
+
+    // return symbol position in uplist
+    return upvalue;
 }
 }
 
 
 // MARK: - Statements initializers -
 // MARK: - Statements initializers -
 
 
 gnode_t *gnode_jump_stat_create (gtoken_s token, gnode_t *expr, gnode_t *decl) {
 gnode_t *gnode_jump_stat_create (gtoken_s token, gnode_t *expr, gnode_t *decl) {
-	gnode_jump_stmt_t *node = (gnode_jump_stmt_t *)mem_alloc(NULL, sizeof(gnode_jump_stmt_t));
+    gnode_jump_stmt_t *node = (gnode_jump_stmt_t *)mem_alloc(NULL, sizeof(gnode_jump_stmt_t));
 
 
-	SETBASE(node, NODE_JUMP_STAT, token, NULL);
+    SETBASE(node, NODE_JUMP_STAT, token, NULL);
     SETDECL(node, decl);
     SETDECL(node, decl);
-	node->expr = expr;
-	return (gnode_t *)node;
+    node->expr = expr;
+    return (gnode_t *)node;
 }
 }
 
 
 gnode_t *gnode_label_stat_create (gtoken_s token, gnode_t *expr, gnode_t *stmt, gnode_t *decl) {
 gnode_t *gnode_label_stat_create (gtoken_s token, gnode_t *expr, gnode_t *stmt, gnode_t *decl) {
-	gnode_label_stmt_t *node = (gnode_label_stmt_t *)mem_alloc(NULL, sizeof(gnode_label_stmt_t));
+    gnode_label_stmt_t *node = (gnode_label_stmt_t *)mem_alloc(NULL, sizeof(gnode_label_stmt_t));
 
 
-	SETBASE(node, NODE_LABEL_STAT, token, NULL);
+    SETBASE(node, NODE_LABEL_STAT, token, NULL);
     SETDECL(node, decl);
     SETDECL(node, decl);
-	node->expr = expr;
-	node->stmt = stmt;
-	return (gnode_t *)node;
+    node->expr = expr;
+    node->stmt = stmt;
+    return (gnode_t *)node;
 }
 }
 
 
 gnode_t *gnode_flow_stat_create (gtoken_s token, gnode_t *cond, gnode_t *stmt1, gnode_t *stmt2, gnode_t *decl) {
 gnode_t *gnode_flow_stat_create (gtoken_s token, gnode_t *cond, gnode_t *stmt1, gnode_t *stmt2, gnode_t *decl) {
-	gnode_flow_stmt_t *node = (gnode_flow_stmt_t *)mem_alloc(NULL, sizeof(gnode_flow_stmt_t));
+    gnode_flow_stmt_t *node = (gnode_flow_stmt_t *)mem_alloc(NULL, sizeof(gnode_flow_stmt_t));
 
 
-	SETBASE(node, NODE_FLOW_STAT, token, NULL);
+    SETBASE(node, NODE_FLOW_STAT, token, NULL);
     SETDECL(node, decl);
     SETDECL(node, decl);
-	node->cond = cond;
-	node->stmt = stmt1;
-	node->elsestmt = stmt2;
-	return (gnode_t *)node;
+    node->cond = cond;
+    node->stmt = stmt1;
+    node->elsestmt = stmt2;
+    return (gnode_t *)node;
 }
 }
 
 
 gnode_t *gnode_loop_stat_create (gtoken_s token, gnode_t *cond, gnode_t *stmt, gnode_t *expr, gnode_t *decl) {
 gnode_t *gnode_loop_stat_create (gtoken_s token, gnode_t *cond, gnode_t *stmt, gnode_t *expr, gnode_t *decl) {
-	gnode_loop_stmt_t *node = (gnode_loop_stmt_t *)mem_alloc(NULL, sizeof(gnode_loop_stmt_t));
+    gnode_loop_stmt_t *node = (gnode_loop_stmt_t *)mem_alloc(NULL, sizeof(gnode_loop_stmt_t));
 
 
-	SETBASE(node, NODE_LOOP_STAT, token, NULL);
+    SETBASE(node, NODE_LOOP_STAT, token, NULL);
     SETDECL(node, decl);
     SETDECL(node, decl);
-	node->cond = cond;
-	node->stmt = stmt;
-	node->expr = expr;
-	node->nclose = UINT32_MAX;
-	return (gnode_t *)node;
+    node->cond = cond;
+    node->stmt = stmt;
+    node->expr = expr;
+    node->nclose = UINT32_MAX;
+    return (gnode_t *)node;
 }
 }
 
 
 gnode_t *gnode_block_stat_create (gnode_n type, gtoken_s token, gnode_r *stmts, gnode_t *decl) {
 gnode_t *gnode_block_stat_create (gnode_n type, gtoken_s token, gnode_r *stmts, gnode_t *decl) {
-	gnode_compound_stmt_t *node = (gnode_compound_stmt_t *)mem_alloc(NULL, sizeof(gnode_compound_stmt_t));
+    gnode_compound_stmt_t *node = (gnode_compound_stmt_t *)mem_alloc(NULL, sizeof(gnode_compound_stmt_t));
 
 
-	SETBASE(node, type, token, NULL);
+    SETBASE(node, type, token, NULL);
     SETDECL(node, decl);
     SETDECL(node, decl);
-	node->stmts = stmts;
-	node->nclose = UINT32_MAX;
-	return (gnode_t *)node;
+    node->stmts = stmts;
+    node->nclose = UINT32_MAX;
+    return (gnode_t *)node;
 }
 }
 
 
 gnode_t *gnode_empty_stat_create (gtoken_s token, gnode_t *decl) {
 gnode_t *gnode_empty_stat_create (gtoken_s token, gnode_t *decl) {
-	gnode_empty_stmt_t *node = (gnode_empty_stmt_t *)mem_alloc(NULL, sizeof(gnode_empty_stmt_t));
+    gnode_empty_stmt_t *node = (gnode_empty_stmt_t *)mem_alloc(NULL, sizeof(gnode_empty_stmt_t));
 
 
-	SETBASE(node, NODE_EMPTY_STAT, token, NULL);
+    SETBASE(node, NODE_EMPTY_STAT, token, NULL);
     SETDECL(node, decl);
     SETDECL(node, decl);
-	return (gnode_t *)node;
+    return (gnode_t *)node;
 }
 }
 
 
 // MARK: - Declarations initializers -
 // MARK: - Declarations initializers -
 
 
-gnode_t *gnode_class_decl_create (gtoken_s token, const char *identifier, gtoken_t access_specifier, gtoken_t storage_specifier, gnode_t *superclass, gnode_r *protocols, gnode_r *declarations, bool is_struct, void *meta, gnode_t *decl) {
-	gnode_class_decl_t *node = (gnode_class_decl_t *)mem_alloc(NULL, sizeof(gnode_class_decl_t));
-	node->is_struct = is_struct;
+gnode_t *gnode_class_decl_create (gtoken_s token, const char *identifier, gtoken_t access_specifier, gtoken_t storage_specifier, gnode_t *superclass,
+                                  gnode_r *protocols, gnode_r *declarations, bool is_struct, void *meta, gnode_t *decl) {
+    gnode_class_decl_t *node = (gnode_class_decl_t *)mem_alloc(NULL, sizeof(gnode_class_decl_t));
+    node->is_struct = is_struct;
 
 
-	SETBASE(node, NODE_CLASS_DECL, token, meta);
+    SETBASE(node, NODE_CLASS_DECL, token, meta);
     SETDECL(node, decl);
     SETDECL(node, decl);
-	node->bridge = false;
-	node->identifier = identifier;
-	node->access = access_specifier;
-	node->storage = storage_specifier;
-	node->superclass = superclass;
-	node->protocols = protocols;
-	node->decls = declarations;
-	node->nivar = 0;
-	node->nsvar = 0;
+    node->bridge = false;
+    node->identifier = identifier;
+    node->access = access_specifier;
+    node->storage = storage_specifier;
+    node->superclass = superclass;
+    node->protocols = protocols;
+    node->decls = declarations;
+    node->nivar = 0;
+    node->nsvar = 0;
 
 
-	return (gnode_t *)node;
+    return (gnode_t *)node;
 }
 }
 
 
 gnode_t *gnode_module_decl_create (gtoken_s token, const char *identifier, gtoken_t access_specifier, gtoken_t storage_specifier, gnode_r *declarations, void *meta, gnode_t *decl) {
 gnode_t *gnode_module_decl_create (gtoken_s token, const char *identifier, gtoken_t access_specifier, gtoken_t storage_specifier, gnode_r *declarations, void *meta, gnode_t *decl) {
-	gnode_module_decl_t *node = (gnode_module_decl_t *)mem_alloc(NULL, sizeof(gnode_module_decl_t));
+    gnode_module_decl_t *node = (gnode_module_decl_t *)mem_alloc(NULL, sizeof(gnode_module_decl_t));
 
 
-	SETBASE(node, NODE_MODULE_DECL, token, meta);
+    SETBASE(node, NODE_MODULE_DECL, token, meta);
     SETDECL(node, decl);
     SETDECL(node, decl);
-	node->identifier = identifier;
-	node->access = access_specifier;
-	node->storage = storage_specifier;
-	node->decls = declarations;
+    node->identifier = identifier;
+    node->access = access_specifier;
+    node->storage = storage_specifier;
+    node->decls = declarations;
 
 
-	return (gnode_t *)node;
+    return (gnode_t *)node;
 }
 }
 
 
 gnode_t *gnode_enum_decl_create (gtoken_s token, const char *identifier, gtoken_t access_specifier, gtoken_t storage_specifier, symboltable_t *symtable, void *meta, gnode_t *decl) {
 gnode_t *gnode_enum_decl_create (gtoken_s token, const char *identifier, gtoken_t access_specifier, gtoken_t storage_specifier, symboltable_t *symtable, void *meta, gnode_t *decl) {
-	gnode_enum_decl_t *node = (gnode_enum_decl_t *)mem_alloc(NULL, sizeof(gnode_enum_decl_t));
+    gnode_enum_decl_t *node = (gnode_enum_decl_t *)mem_alloc(NULL, sizeof(gnode_enum_decl_t));
 
 
-	SETBASE(node, NODE_ENUM_DECL, token, meta);
+    SETBASE(node, NODE_ENUM_DECL, token, meta);
     SETDECL(node, decl);
     SETDECL(node, decl);
-	node->identifier = identifier;
-	node->access = access_specifier;
-	node->storage = storage_specifier;
-	node->symtable= symtable;
+    node->identifier = identifier;
+    node->access = access_specifier;
+    node->storage = storage_specifier;
+    node->symtable= symtable;
 
 
-	return (gnode_t *)node;
+    return (gnode_t *)node;
 }
 }
 
 
-gnode_t *gnode_function_decl_create (gtoken_s token, const char *identifier, gtoken_t access_specifier, gtoken_t storage_specifier, gnode_r *params, gnode_compound_stmt_t *block, void *meta, gnode_t *decl) {
-	gnode_function_decl_t *node = (gnode_function_decl_t *)mem_alloc(NULL, sizeof(gnode_function_decl_t));
+gnode_t *gnode_function_decl_create (gtoken_s token, const char *identifier, gtoken_t access_specifier, gtoken_t storage_specifier, gnode_r *params,
+                                     gnode_compound_stmt_t *block, void *meta, gnode_t *decl) {
+    gnode_function_decl_t *node = (gnode_function_decl_t *)mem_alloc(NULL, sizeof(gnode_function_decl_t));
 
 
-	SETBASE(node, NODE_FUNCTION_DECL, token, meta);
+    SETBASE(node, NODE_FUNCTION_DECL, token, meta);
     SETDECL(node, decl);
     SETDECL(node, decl);
-	node->identifier = identifier;
-	node->access = access_specifier;
-	node->storage = storage_specifier;
-	node->params = params;
-	node->block = block;
-	node->nlocals = 0;
-	node->uplist = NULL;
+    node->identifier = identifier;
+    node->access = access_specifier;
+    node->storage = storage_specifier;
+    node->params = params;
+    node->block = block;
+    node->nlocals = 0;
+    node->uplist = NULL;
 
 
-	return (gnode_t *)node;
+    return (gnode_t *)node;
 }
 }
 
 
-gnode_t *gnode_variable_decl_create (gtoken_s token, gtoken_t type, gtoken_t access_specifier, gtoken_t storage_specifier, gnode_r *declarations, void *meta, gnode_t *decl) {
-	gnode_variable_decl_t *node = (gnode_variable_decl_t *)mem_alloc(NULL, sizeof(gnode_variable_decl_t));
+gnode_t *gnode_variable_decl_create (gtoken_s token, gtoken_t type, gtoken_t access_specifier, gtoken_t storage_specifier, gnode_r *declarations,
+                                     void *meta, gnode_t *decl) {
+    gnode_variable_decl_t *node = (gnode_variable_decl_t *)mem_alloc(NULL, sizeof(gnode_variable_decl_t));
 
 
-	SETBASE(node, NODE_VARIABLE_DECL, token, meta);
+    SETBASE(node, NODE_VARIABLE_DECL, token, meta);
     SETDECL(node, decl);
     SETDECL(node, decl);
-	node->type = type;
-	node->access = access_specifier;
-	node->storage = storage_specifier;
-	node->decls = declarations;
+    node->type = type;
+    node->access = access_specifier;
+    node->storage = storage_specifier;
+    node->decls = declarations;
 
 
-	return (gnode_t *)node;
+    return (gnode_t *)node;
 }
 }
 
 
 gnode_t *gnode_variable_create (gtoken_s token, const char *identifier, const char *annotation_type, gtoken_t access_specifier, gnode_t *expr, gnode_t *decl) {
 gnode_t *gnode_variable_create (gtoken_s token, const char *identifier, const char *annotation_type, gtoken_t access_specifier, gnode_t *expr, gnode_t *decl) {
-	gnode_var_t *node = (gnode_var_t *)mem_alloc(NULL, sizeof(gnode_var_t));
+    gnode_var_t *node = (gnode_var_t *)mem_alloc(NULL, sizeof(gnode_var_t));
 
 
-	SETBASE(node, NODE_VARIABLE, token, NULL);
+    SETBASE(node, NODE_VARIABLE, token, NULL);
     SETDECL(node, decl);
     SETDECL(node, decl);
-	node->identifier = identifier;
-	node->annotation_type = annotation_type;
-	node->expr = expr;
-	node->access = access_specifier;
+    node->identifier = identifier;
+    node->annotation_type = annotation_type;
+    node->expr = expr;
+    node->access = access_specifier;
     node->iscomputed = false;
     node->iscomputed = false;
-	return (gnode_t *)node;
+    return (gnode_t *)node;
 }
 }
 
 
 // MARK: - Expressions initializers -
 // MARK: - Expressions initializers -
 
 
 bool gnode_is_equal (gnode_t *node1, gnode_t *node2) {
 bool gnode_is_equal (gnode_t *node1, gnode_t *node2) {
-	// very simple gnode verification for map key uniqueness
-	gnode_base_t *_node1 = (gnode_base_t *)node1;
-	gnode_base_t *_node2 = (gnode_base_t *)node2;
-	if (_node1->base.tag != _node2->base.tag) return false;
-	if (gnode_is_literal(node1)) {
-		gnode_literal_expr_t *e1 = (gnode_literal_expr_t *)node1;
-		gnode_literal_expr_t *e2 = (gnode_literal_expr_t *)node2;
-		if (e1->type != e2->type) return false;
-		// LITERAL_STRING, LITERAL_FLOAT, LITERAL_INT, LITERAL_BOOL, LITERAL_STRING_INTERPOLATED
-		if (e1->type == LITERAL_BOOL) return (e1->value.n64 == e2->value.n64);
-		if (e1->type == LITERAL_INT) return (e1->value.n64 == e2->value.n64);
-		if (e1->type == LITERAL_FLOAT) return (e1->value.d == e2->value.d);
-		if (e1->type == LITERAL_STRING) return (strcmp(e1->value.str, e2->value.str)==0);
-		// there is no way to check node equality for a LITERAL_STRING_INTERPOLATED at compile time
-	}
-	return false;
+    // very simple gnode verification for map key uniqueness
+    gnode_base_t *_node1 = (gnode_base_t *)node1;
+    gnode_base_t *_node2 = (gnode_base_t *)node2;
+    if (_node1->base.tag != _node2->base.tag) return false;
+    if (gnode_is_literal(node1)) {
+        gnode_literal_expr_t *e1 = (gnode_literal_expr_t *)node1;
+        gnode_literal_expr_t *e2 = (gnode_literal_expr_t *)node2;
+        if (e1->type != e2->type) return false;
+        // LITERAL_STRING, LITERAL_FLOAT, LITERAL_INT, LITERAL_BOOL, LITERAL_STRING_INTERPOLATED
+        if (e1->type == LITERAL_BOOL) return (e1->value.n64 == e2->value.n64);
+        if (e1->type == LITERAL_INT) return (e1->value.n64 == e2->value.n64);
+        if (e1->type == LITERAL_FLOAT) return (e1->value.d == e2->value.d);
+        if (e1->type == LITERAL_STRING) return (strcmp(e1->value.str, e2->value.str)==0);
+        // there is no way to check node equality for a LITERAL_STRING_INTERPOLATED at compile time
+    }
+    return false;
 }
 }
 
 
 bool gnode_is_expression (gnode_t *node) {
 bool gnode_is_expression (gnode_t *node) {
-	gnode_base_t *_node = (gnode_base_t *)node;
-	return ((_node->base.tag >= NODE_BINARY_EXPR) && (_node->base.tag <= NODE_KEYWORD_EXPR));
+    gnode_base_t *_node = (gnode_base_t *)node;
+    return ((_node->base.tag >= NODE_BINARY_EXPR) && (_node->base.tag <= NODE_KEYWORD_EXPR));
 }
 }
 
 
 bool gnode_is_literal (gnode_t *node) {
 bool gnode_is_literal (gnode_t *node) {
-	gnode_base_t *_node = (gnode_base_t *)node;
-	return (_node->base.tag == NODE_LITERAL_EXPR);
+    gnode_base_t *_node = (gnode_base_t *)node;
+    return (_node->base.tag == NODE_LITERAL_EXPR);
 }
 }
 
 
 bool gnode_is_literal_int (gnode_t *node) {
 bool gnode_is_literal_int (gnode_t *node) {
-	if (gnode_is_literal(node) == false) return false;
-	gnode_literal_expr_t *_node = (gnode_literal_expr_t *)node;
-	return (_node->type == LITERAL_INT);
+    if (gnode_is_literal(node) == false) return false;
+    gnode_literal_expr_t *_node = (gnode_literal_expr_t *)node;
+    return (_node->type == LITERAL_INT);
 }
 }
 
 
 bool gnode_is_literal_string (gnode_t *node) {
 bool gnode_is_literal_string (gnode_t *node) {
-	if (gnode_is_literal(node) == false) return false;
-	gnode_literal_expr_t *_node = (gnode_literal_expr_t *)node;
-	return (_node->type == LITERAL_STRING);
+    if (gnode_is_literal(node) == false) return false;
+    gnode_literal_expr_t *_node = (gnode_literal_expr_t *)node;
+    return (_node->type == LITERAL_STRING);
 }
 }
 
 
 bool gnode_is_literal_number (gnode_t *node) {
 bool gnode_is_literal_number (gnode_t *node) {
-	if (gnode_is_literal(node) == false) return false;
-	gnode_literal_expr_t *_node = (gnode_literal_expr_t *)node;
-	return (_node->type != LITERAL_STRING && _node->type != LITERAL_STRING_INTERPOLATED);
+    if (gnode_is_literal(node) == false) return false;
+    gnode_literal_expr_t *_node = (gnode_literal_expr_t *)node;
+    return (_node->type != LITERAL_STRING && _node->type != LITERAL_STRING_INTERPOLATED);
 }
 }
 
 
 gnode_t *gnode_binary_expr_create (gtoken_t op, gnode_t *left, gnode_t *right, gnode_t *decl) {
 gnode_t *gnode_binary_expr_create (gtoken_t op, gnode_t *left, gnode_t *right, gnode_t *decl) {
-	if (!left || !right) return NULL;
+    if (!left || !right) return NULL;
 
 
-	gnode_binary_expr_t	*node = (gnode_binary_expr_t *)mem_alloc(NULL, sizeof(gnode_binary_expr_t));
-	SETBASE(node, NODE_BINARY_EXPR, left->token, NULL);
+    gnode_binary_expr_t    *node = (gnode_binary_expr_t *)mem_alloc(NULL, sizeof(gnode_binary_expr_t));
+    SETBASE(node, NODE_BINARY_EXPR, left->token, NULL);
     SETDECL(node, decl);
     SETDECL(node, decl);
-	node->op = op;
-	node->left = left;
-	node->right = right;
-	return (gnode_t *)node;
+    node->op = op;
+    node->left = left;
+    node->right = right;
+    return (gnode_t *)node;
 }
 }
 
 
 gnode_t *gnode_unary_expr_create (gtoken_t op, gnode_t *expr, gnode_t *decl) {
 gnode_t *gnode_unary_expr_create (gtoken_t op, gnode_t *expr, gnode_t *decl) {
-	if (!expr) return NULL;
+    if (!expr) return NULL;
 
 
-	gnode_unary_expr_t *node = (gnode_unary_expr_t *)mem_alloc(NULL, sizeof(gnode_unary_expr_t));
-	SETBASE(node, NODE_UNARY_EXPR, expr->token, NULL);
+    gnode_unary_expr_t *node = (gnode_unary_expr_t *)mem_alloc(NULL, sizeof(gnode_unary_expr_t));
+    SETBASE(node, NODE_UNARY_EXPR, expr->token, NULL);
     SETDECL(node, decl);
     SETDECL(node, decl);
-	node->op = op;
-	node->expr = expr;
-	return (gnode_t *)node;
+    node->op = op;
+    node->expr = expr;
+    return (gnode_t *)node;
 }
 }
 
 
 gnode_t *gnode_file_expr_create (gtoken_s token, cstring_r *list, gnode_t *decl) {
 gnode_t *gnode_file_expr_create (gtoken_s token, cstring_r *list, gnode_t *decl) {
-	if (!list) return NULL;
+    if (!list) return NULL;
 
 
-	gnode_file_expr_t *node = (gnode_file_expr_t *)mem_alloc(NULL, sizeof(gnode_file_expr_t));
-	SETBASE(node, NODE_FILE_EXPR, token, NULL);
+    gnode_file_expr_t *node = (gnode_file_expr_t *)mem_alloc(NULL, sizeof(gnode_file_expr_t));
+    SETBASE(node, NODE_FILE_EXPR, token, NULL);
     SETDECL(node, decl);
     SETDECL(node, decl);
-	node->identifiers = list;
-	return (gnode_t *)node;
+    node->identifiers = list;
+    return (gnode_t *)node;
 }
 }
 
 
 gnode_t *gnode_identifier_expr_create (gtoken_s token, const char *identifier, const char *identifier2, gnode_t *decl) {
 gnode_t *gnode_identifier_expr_create (gtoken_s token, const char *identifier, const char *identifier2, gnode_t *decl) {
-	if (!identifier) return NULL;
+    if (!identifier) return NULL;
 
 
-	gnode_identifier_expr_t *node = (gnode_identifier_expr_t *)mem_alloc(NULL, sizeof(gnode_identifier_expr_t));
-	SETBASE(node, NODE_IDENTIFIER_EXPR, token, NULL);
+    gnode_identifier_expr_t *node = (gnode_identifier_expr_t *)mem_alloc(NULL, sizeof(gnode_identifier_expr_t));
+    SETBASE(node, NODE_IDENTIFIER_EXPR, token, NULL);
     SETDECL(node, decl);
     SETDECL(node, decl);
-	node->value = identifier;
-	node->value2 = identifier2;
-	return (gnode_t *)node;
+    node->value = identifier;
+    node->value2 = identifier2;
+    return (gnode_t *)node;
 }
 }
 
 
 void gnode_literal_dump (gnode_literal_expr_t *node, char *buffer, int buffersize) {
 void gnode_literal_dump (gnode_literal_expr_t *node, char *buffer, int buffersize) {
-	switch (node->type) {
-		case LITERAL_STRING_INTERPOLATED: snprintf(buffer, buffersize, "INTERPOLATED: %d", (uint32_t)gnode_array_size(node->value.r)); break;
-		case LITERAL_STRING: snprintf(buffer, buffersize, "STRING: %.*s", node->len, node->value.str); break;
-		case LITERAL_FLOAT: snprintf(buffer, buffersize, "FLOAT: %.2f", node->value.d); break;
-		case LITERAL_INT: snprintf(buffer, buffersize, "INT: %" PRId64, (int64_t)node->value.n64); break;
-		case LITERAL_BOOL: snprintf(buffer, buffersize, "BOOL: %d", (int32_t)node->value.n64); break;
-		default: assert(0); // should never reach this point
-	}
+    switch (node->type) {
+        case LITERAL_STRING_INTERPOLATED: snprintf(buffer, buffersize, "INTERPOLATED: %d", (uint32_t)gnode_array_size(node->value.r)); break;
+        case LITERAL_STRING: snprintf(buffer, buffersize, "STRING: %.*s", node->len, node->value.str); break;
+        case LITERAL_FLOAT: snprintf(buffer, buffersize, "FLOAT: %.2f", node->value.d); break;
+        case LITERAL_INT: snprintf(buffer, buffersize, "INT: %" PRId64, (int64_t)node->value.n64); break;
+        case LITERAL_BOOL: snprintf(buffer, buffersize, "BOOL: %d", (int32_t)node->value.n64); break;
+        default: assert(0); // should never reach this point
+    }
 }
 }
 
 
 static gnode_t *gnode_literal_value_expr_create (gtoken_s token, gliteral_t type, const char *s, double d, int64_t n64, gnode_t *decl) {
 static gnode_t *gnode_literal_value_expr_create (gtoken_s token, gliteral_t type, const char *s, double d, int64_t n64, gnode_t *decl) {
-	gnode_literal_expr_t *node = (gnode_literal_expr_t *)mem_alloc(NULL, sizeof(gnode_literal_expr_t));
+    gnode_literal_expr_t *node = (gnode_literal_expr_t *)mem_alloc(NULL, sizeof(gnode_literal_expr_t));
 
 
-	SETBASE(node, NODE_LITERAL_EXPR, token, NULL);
+    SETBASE(node, NODE_LITERAL_EXPR, token, NULL);
     SETDECL(node, decl);
     SETDECL(node, decl);
-	node->type = type;
-	node->len = 0;
-
-	switch (type) {
-		case LITERAL_STRING: node->value.str = (char *)s; break;
-		case LITERAL_FLOAT: node->value.d = d; node->len = (d < FLT_MAX) ? 32 : 64; break;
-		case LITERAL_INT: node->value.n64 = n64; node->len = (n64 < 2147483647) ? 32 : 64; break;
-		case LITERAL_BOOL: node->value.n64 = n64; node->len = 32; break;
-		case LITERAL_STRING_INTERPOLATED: break;
-		default: assert(0); // should never reach this point
-	}
+    node->type = type;
+    node->len = 0;
+
+    switch (type) {
+        case LITERAL_STRING: node->value.str = (char *)s; break;
+        case LITERAL_FLOAT: node->value.d = d; node->len = (d < FLT_MAX) ? 32 : 64; break;
+        case LITERAL_INT: node->value.n64 = n64; node->len = (n64 < 2147483647) ? 32 : 64; break;
+        case LITERAL_BOOL: node->value.n64 = n64; node->len = 32; break;
+        case LITERAL_STRING_INTERPOLATED: break;
+        default: assert(0); // should never reach this point
+    }
 
 
-	return (gnode_t *)node;
+    return (gnode_t *)node;
 }
 }
 
 
 gnode_t *gnode_string_interpolation_create (gtoken_s token, gnode_r *r, gnode_t *decl) {
 gnode_t *gnode_string_interpolation_create (gtoken_s token, gnode_r *r, gnode_t *decl) {
-	gnode_literal_expr_t *node = (gnode_literal_expr_t *)gnode_literal_value_expr_create(token, LITERAL_STRING_INTERPOLATED, NULL, 0, 0, decl);
-	node->value.r = r;
-	return (gnode_t *)node;
+    gnode_literal_expr_t *node = (gnode_literal_expr_t *)gnode_literal_value_expr_create(token, LITERAL_STRING_INTERPOLATED, NULL, 0, 0, decl);
+    node->value.r = r;
+    return (gnode_t *)node;
 }
 }
 
 
 gnode_t *gnode_literal_string_expr_create (gtoken_s token, char *s, uint32_t len, bool allocated, gnode_t *decl) {
 gnode_t *gnode_literal_string_expr_create (gtoken_s token, char *s, uint32_t len, bool allocated, gnode_t *decl) {
-	gnode_literal_expr_t *node = (gnode_literal_expr_t *)gnode_literal_value_expr_create(token, LITERAL_STRING, NULL, 0, 0, decl);
-
-	node->len = len;
-	if (allocated) {
-		node->value.str = s;
-	} else {
-		node->value.str = (char *)mem_alloc(NULL, len+1);
-		memcpy((void *)node->value.str, (const void *)s, len);
-	}
+    gnode_literal_expr_t *node = (gnode_literal_expr_t *)gnode_literal_value_expr_create(token, LITERAL_STRING, NULL, 0, 0, decl);
+
+    node->len = len;
+    if (allocated) {
+        node->value.str = s;
+    } else {
+        node->value.str = (char *)mem_alloc(NULL, len+1);
+        memcpy((void *)node->value.str, (const void *)s, len);
+    }
 
 
-	return (gnode_t *)node;
+    return (gnode_t *)node;
 }
 }
 
 
 gnode_t *gnode_literal_float_expr_create (gtoken_s token, double d, gnode_t *decl) {
 gnode_t *gnode_literal_float_expr_create (gtoken_s token, double d, gnode_t *decl) {
-	return gnode_literal_value_expr_create(token, LITERAL_FLOAT, NULL, d, 0, decl);
+    return gnode_literal_value_expr_create(token, LITERAL_FLOAT, NULL, d, 0, decl);
 }
 }
 
 
 gnode_t *gnode_literal_int_expr_create (gtoken_s token, int64_t n, gnode_t *decl) {
 gnode_t *gnode_literal_int_expr_create (gtoken_s token, int64_t n, gnode_t *decl) {
-	return gnode_literal_value_expr_create(token, LITERAL_INT, NULL, 0, n, decl);
+    return gnode_literal_value_expr_create(token, LITERAL_INT, NULL, 0, n, decl);
 }
 }
 
 
 gnode_t *gnode_literal_bool_expr_create (gtoken_s token, int32_t n, gnode_t *decl) {
 gnode_t *gnode_literal_bool_expr_create (gtoken_s token, int32_t n, gnode_t *decl) {
-	return gnode_literal_value_expr_create(token, LITERAL_BOOL, NULL, 0, n, decl);
+    return gnode_literal_value_expr_create(token, LITERAL_BOOL, NULL, 0, n, decl);
 }
 }
 
 
 gnode_t *gnode_keyword_expr_create (gtoken_s token, gnode_t *decl) {
 gnode_t *gnode_keyword_expr_create (gtoken_s token, gnode_t *decl) {
-	gnode_keyword_expr_t *node = (gnode_keyword_expr_t *)mem_alloc(NULL, sizeof(gnode_keyword_expr_t));
+    gnode_keyword_expr_t *node = (gnode_keyword_expr_t *)mem_alloc(NULL, sizeof(gnode_keyword_expr_t));
 
 
-	SETBASE(node, NODE_KEYWORD_EXPR, token, NULL);
+    SETBASE(node, NODE_KEYWORD_EXPR, token, NULL);
     SETDECL(node, decl);
     SETDECL(node, decl);
-	return (gnode_t *)node;
+    return (gnode_t *)node;
 }
 }
 
 
 gnode_t *gnode_postfix_subexpr_create (gtoken_s token, gnode_n type, gnode_t *expr, gnode_r *list, gnode_t *decl) {
 gnode_t *gnode_postfix_subexpr_create (gtoken_s token, gnode_n type, gnode_t *expr, gnode_r *list, gnode_t *decl) {
-	gnode_postfix_subexpr_t *node = (gnode_postfix_subexpr_t *)mem_alloc(NULL, sizeof(gnode_postfix_subexpr_t));
+    gnode_postfix_subexpr_t *node = (gnode_postfix_subexpr_t *)mem_alloc(NULL, sizeof(gnode_postfix_subexpr_t));
 
 
     SETBASE(node, type, token, NULL);
     SETBASE(node, type, token, NULL);
     SETDECL(node, decl);
     SETDECL(node, decl);
-	if (type == NODE_CALL_EXPR)
-		node->args = list;
-	else
-		node->expr = expr;
-	return (gnode_t *)node;
+    if (type == NODE_CALL_EXPR)
+        node->args = list;
+    else
+        node->expr = expr;
+    return (gnode_t *)node;
 }
 }
 
 
 gnode_t *gnode_postfix_expr_create (gtoken_s token, gnode_t *id, gnode_r *list, gnode_t *decl) {
 gnode_t *gnode_postfix_expr_create (gtoken_s token, gnode_t *id, gnode_r *list, gnode_t *decl) {
-	gnode_postfix_expr_t *node = (gnode_postfix_expr_t *)mem_alloc(NULL, sizeof(gnode_postfix_expr_t));
+    gnode_postfix_expr_t *node = (gnode_postfix_expr_t *)mem_alloc(NULL, sizeof(gnode_postfix_expr_t));
 
 
-	SETBASE(node, NODE_POSTFIX_EXPR, token, NULL);
+    SETBASE(node, NODE_POSTFIX_EXPR, token, NULL);
     SETDECL(node, decl);
     SETDECL(node, decl);
     node->id = id;
     node->id = id;
     node->list = list;
     node->list = list;
-	return (gnode_t *)node;
+    return (gnode_t *)node;
 }
 }
 
 
 gnode_t *gnode_list_expr_create (gtoken_s token, gnode_r *list1, gnode_r *list2, bool ismap, gnode_t *decl) {
 gnode_t *gnode_list_expr_create (gtoken_s token, gnode_r *list1, gnode_r *list2, bool ismap, gnode_t *decl) {
-	gnode_list_expr_t *node = (gnode_list_expr_t *)mem_alloc(NULL, sizeof(gnode_list_expr_t));
+    gnode_list_expr_t *node = (gnode_list_expr_t *)mem_alloc(NULL, sizeof(gnode_list_expr_t));
 
 
-	SETBASE(node, NODE_LIST_EXPR, token, NULL);
+    SETBASE(node, NODE_LIST_EXPR, token, NULL);
     SETDECL(node, decl);
     SETDECL(node, decl);
-	node->ismap = ismap;
-	node->list1 = list1;
-	node->list2 = list2;
-	return (gnode_t *)node;
+    node->ismap = ismap;
+    node->list1 = list1;
+    node->list2 = list2;
+    return (gnode_t *)node;
 }
 }
 
 
 // MARK: -
 // MARK: -
 
 
 gnode_t *gnode_duplicate (gnode_t *node, bool deep) {
 gnode_t *gnode_duplicate (gnode_t *node, bool deep) {
-	if (!node) return NULL;
-
-	if (deep == true) {
-		// deep is true so I need to examine node and perform a real duplication (only of the outer nodes)
-		// deep is true ONLY when node can also be part of an assignment and its assignment flag can be
-		// true is node is on the left and false when node is on the right
-		// true flag is used only by adjust_assignment_expression in parser.c
-
-		// node can be: identifier, file or postfix
-		if (NODE_ISA(node, NODE_IDENTIFIER_EXPR)) {
-			gnode_identifier_expr_t *expr = (gnode_identifier_expr_t *)node;
-			return gnode_identifier_expr_create(expr->base.token, string_dup(expr->value), (expr->value2) ? string_dup(expr->value2) : NULL, expr->base.decl);
-		} else if (NODE_ISA(node, NODE_FILE_EXPR)) {
-			gnode_file_expr_t *expr = (gnode_file_expr_t *)node;
-			cstring_r *list = cstring_array_create();
-			size_t count = gnode_array_size(expr->identifiers);
-			for (size_t i=0; i<count; ++i) {
-				const char *identifier = gnode_array_get(expr->identifiers, i);
-				cstring_array_push(list, string_dup(identifier));
-			}
-			return gnode_file_expr_create(expr->base.token, list, expr->base.decl);
-		} else if (NODE_ISA(node, NODE_POSTFIX_EXPR)) {
-			gnode_postfix_expr_t *expr = (gnode_postfix_expr_t *)node;
-			gnode_t *id = gnode_duplicate(expr->id, false);
-			gnode_r *list = gnode_array_create();
-			gnode_array_each(expr->list, {gnode_array_push(list, gnode_duplicate(val, false));});
-			return gnode_postfix_expr_create(expr->base.token, id, list, expr->base.decl);
-		} else {
-			// gnode_duplicate UNHANDLED case
-			return NULL;
-		}
-		// just return the original node and since it is invalid for an assignment a semantic error will be generated
-	}
-
-	// it means that I can perform a light duplication where
-	// duplicating a node means increase its refcount so it isn't freed more than once
-	++node->refcount;
-	return node;
+    if (!node) return NULL;
+
+    if (deep == true) {
+        // deep is true so I need to examine node and perform a real duplication (only of the outer nodes)
+        // deep is true ONLY when node can also be part of an assignment and its assignment flag can be
+        // true is node is on the left and false when node is on the right
+        // true flag is used only by adjust_assignment_expression in parser.c
+
+        // node can be: identifier, file or postfix
+        if (NODE_ISA(node, NODE_IDENTIFIER_EXPR)) {
+            gnode_identifier_expr_t *expr = (gnode_identifier_expr_t *)node;
+            return gnode_identifier_expr_create(expr->base.token, string_dup(expr->value), (expr->value2) ? string_dup(expr->value2) : NULL, expr->base.decl);
+        } else if (NODE_ISA(node, NODE_FILE_EXPR)) {
+            gnode_file_expr_t *expr = (gnode_file_expr_t *)node;
+            cstring_r *list = cstring_array_create();
+            size_t count = gnode_array_size(expr->identifiers);
+            for (size_t i=0; i<count; ++i) {
+                const char *identifier = gnode_array_get(expr->identifiers, i);
+                cstring_array_push(list, string_dup(identifier));
+            }
+            return gnode_file_expr_create(expr->base.token, list, expr->base.decl);
+        } else if (NODE_ISA(node, NODE_POSTFIX_EXPR)) {
+            gnode_postfix_expr_t *expr = (gnode_postfix_expr_t *)node;
+            gnode_t *id = gnode_duplicate(expr->id, false);
+            gnode_r *list = gnode_array_create();
+            gnode_array_each(expr->list, {gnode_array_push(list, gnode_duplicate(val, false));});
+            return gnode_postfix_expr_create(expr->base.token, id, list, expr->base.decl);
+        } else {
+            // gnode_duplicate UNHANDLED case
+            return NULL;
+        }
+        // just return the original node and since it is invalid for an assignment a semantic error will be generated
+    }
+
+    // it means that I can perform a light duplication where
+    // duplicating a node means increase its refcount so it isn't freed more than once
+    ++node->refcount;
+    return node;
 }
 }
 
 
 void *meta_from_node (gnode_t *node) {
 void *meta_from_node (gnode_t *node) {
@@ -499,219 +502,219 @@ void *meta_from_node (gnode_t *node) {
 
 
 // STATEMENTS
 // STATEMENTS
 static void free_list_stmt (gvisitor_t *self, gnode_compound_stmt_t *node) {
 static void free_list_stmt (gvisitor_t *self, gnode_compound_stmt_t *node) {
-	CHECK_REFCOUNT(node);
-	gnode_array_each(node->stmts, {visit(val);});
-	if (node->stmts) gnode_array_free(node->stmts);
+    CHECK_REFCOUNT(node);
+    gnode_array_each(node->stmts, {visit(val);});
+    if (node->stmts) gnode_array_free(node->stmts);
 
 
-	if (node->symtable) symboltable_free(node->symtable);
-	mem_free((gnode_t*)node);
+    if (node->symtable) symboltable_free(node->symtable);
+    mem_free((gnode_t*)node);
 }
 }
 
 
 static void free_compound_stmt (gvisitor_t *self, gnode_compound_stmt_t *node) {
 static void free_compound_stmt (gvisitor_t *self, gnode_compound_stmt_t *node) {
-	CHECK_REFCOUNT(node);
-	gnode_array_each(node->stmts, {visit(val);});
-	if (node->stmts) gnode_array_free(node->stmts);
+    CHECK_REFCOUNT(node);
+    gnode_array_each(node->stmts, {visit(val);});
+    if (node->stmts) gnode_array_free(node->stmts);
 
 
-	if (node->symtable) symboltable_free(node->symtable);
-	mem_free((gnode_t*)node);
+    if (node->symtable) symboltable_free(node->symtable);
+    mem_free((gnode_t*)node);
 }
 }
 
 
 static void free_label_stmt (gvisitor_t *self, gnode_label_stmt_t *node) {
 static void free_label_stmt (gvisitor_t *self, gnode_label_stmt_t *node) {
-	CHECK_REFCOUNT(node);
-	if (node->expr) visit(node->expr);
-	if (node->stmt) visit(node->stmt);
-	mem_free((gnode_t*)node);
+    CHECK_REFCOUNT(node);
+    if (node->expr) visit(node->expr);
+    if (node->stmt) visit(node->stmt);
+    mem_free((gnode_t*)node);
 }
 }
 
 
 static void free_flow_stmt (gvisitor_t *self, gnode_flow_stmt_t *node) {
 static void free_flow_stmt (gvisitor_t *self, gnode_flow_stmt_t *node) {
-	CHECK_REFCOUNT(node);
-	if (node->cond) visit(node->cond);
-	if (node->stmt) visit(node->stmt);
-	if (node->elsestmt) visit(node->elsestmt);
-	mem_free((gnode_t*)node);
+    CHECK_REFCOUNT(node);
+    if (node->cond) visit(node->cond);
+    if (node->stmt) visit(node->stmt);
+    if (node->elsestmt) visit(node->elsestmt);
+    mem_free((gnode_t*)node);
 }
 }
 
 
 static void free_loop_stmt (gvisitor_t *self, gnode_loop_stmt_t *node) {
 static void free_loop_stmt (gvisitor_t *self, gnode_loop_stmt_t *node) {
-	CHECK_REFCOUNT(node);
-	if (node->stmt) visit(node->stmt);
-	if (node->cond) visit(node->cond);
-	if (node->expr) visit(node->expr);
-	mem_free((gnode_t*)node);
+    CHECK_REFCOUNT(node);
+    if (node->stmt) visit(node->stmt);
+    if (node->cond) visit(node->cond);
+    if (node->expr) visit(node->expr);
+    mem_free((gnode_t*)node);
 }
 }
 
 
 static void free_jump_stmt (gvisitor_t *self, gnode_jump_stmt_t *node) {
 static void free_jump_stmt (gvisitor_t *self, gnode_jump_stmt_t *node) {
-	CHECK_REFCOUNT(node);
-	if (node->expr) visit(node->expr);
-	mem_free((gnode_t*)node);
+    CHECK_REFCOUNT(node);
+    if (node->expr) visit(node->expr);
+    mem_free((gnode_t*)node);
 }
 }
 
 
 static void free_empty_stmt (gvisitor_t *self, gnode_empty_stmt_t *node) {
 static void free_empty_stmt (gvisitor_t *self, gnode_empty_stmt_t *node) {
-	#pragma unused(self)
-	CHECK_REFCOUNT(node);
-	mem_free((gnode_t*)node);
+    #pragma unused(self)
+    CHECK_REFCOUNT(node);
+    mem_free((gnode_t*)node);
 }
 }
 
 
 static void free_variable (gvisitor_t *self, gnode_var_t *p) {
 static void free_variable (gvisitor_t *self, gnode_var_t *p) {
-	CHECK_REFCOUNT(p);
-	if (p->identifier) mem_free((void *)p->identifier);
-	if (p->annotation_type) mem_free((void *)p->annotation_type);
-	if (p->expr) visit(p->expr);
-	mem_free((void *)p);
+    CHECK_REFCOUNT(p);
+    if (p->identifier) mem_free((void *)p->identifier);
+    if (p->annotation_type) mem_free((void *)p->annotation_type);
+    if (p->expr) visit(p->expr);
+    mem_free((void *)p);
 }
 }
 
 
 static void free_function_decl (gvisitor_t *self, gnode_function_decl_t *node) {
 static void free_function_decl (gvisitor_t *self, gnode_function_decl_t *node) {
-	CHECK_REFCOUNT(node);
-	if (node->symtable) symboltable_free(node->symtable);
-	if (node->identifier) mem_free((void *)node->identifier);
-	if (node->params) {
-		gnode_array_each(node->params, {free_variable(self, (gnode_var_t *)val);});
-		gnode_array_free(node->params);
-	}
-
-	if (node->block) visit((gnode_t *)node->block);
-	if (node->uplist) {
-		gtype_array_each(node->uplist, {mem_free(val);}, gupvalue_t*);
-		gnode_array_free(node->uplist);
-	}
+    CHECK_REFCOUNT(node);
+    if (node->symtable) symboltable_free(node->symtable);
+    if (node->identifier) mem_free((void *)node->identifier);
+    if (node->params) {
+        gnode_array_each(node->params, {free_variable(self, (gnode_var_t *)val);});
+        gnode_array_free(node->params);
+    }
+
+    if (node->block) visit((gnode_t *)node->block);
+    if (node->uplist) {
+        gtype_array_each(node->uplist, {mem_free(val);}, gupvalue_t*);
+        gnode_array_free(node->uplist);
+    }
     // free meta ONLY if node is not a getter/setter (for getter/setter meta is set to var)
     // free meta ONLY if node is not a getter/setter (for getter/setter meta is set to var)
     if (node->base.meta && node->storage != TOK_KEY_VAR) gravity_hash_free(node->base.meta);
     if (node->base.meta && node->storage != TOK_KEY_VAR) gravity_hash_free(node->base.meta);
-	mem_free((gnode_t*)node);
+    mem_free((gnode_t*)node);
 }
 }
 
 
 static void free_variable_decl (gvisitor_t *self, gnode_variable_decl_t *node) {
 static void free_variable_decl (gvisitor_t *self, gnode_variable_decl_t *node) {
-	CHECK_REFCOUNT(node);
-	if (node->decls) {
-		gnode_array_each(node->decls, {free_variable(self, (gnode_var_t *)val);});
-		gnode_array_free(node->decls);
-	}
+    CHECK_REFCOUNT(node);
+    if (node->decls) {
+        gnode_array_each(node->decls, {free_variable(self, (gnode_var_t *)val);});
+        gnode_array_free(node->decls);
+    }
     if (node->base.meta) gravity_hash_free(node->base.meta);
     if (node->base.meta) gravity_hash_free(node->base.meta);
-	mem_free((gnode_t*)node);
+    mem_free((gnode_t*)node);
 }
 }
 
 
 static void free_enum_decl (gvisitor_t *self, gnode_enum_decl_t *node) {
 static void free_enum_decl (gvisitor_t *self, gnode_enum_decl_t *node) {
-	#pragma unused(self)
-	CHECK_REFCOUNT(node);
-	if (node->identifier) mem_free((void *)node->identifier);
-	if (node->symtable) symboltable_free(node->symtable);
+    #pragma unused(self)
+    CHECK_REFCOUNT(node);
+    if (node->identifier) mem_free((void *)node->identifier);
+    if (node->symtable) symboltable_free(node->symtable);
     if (node->base.meta) gravity_hash_free(node->base.meta);
     if (node->base.meta) gravity_hash_free(node->base.meta);
-	mem_free((gnode_t*)node);
+    mem_free((gnode_t*)node);
 }
 }
 
 
 static void free_class_decl (gvisitor_t *self, gnode_class_decl_t *node) {
 static void free_class_decl (gvisitor_t *self, gnode_class_decl_t *node) {
-	CHECK_REFCOUNT(node);
-	if (node->identifier) mem_free((void *)node->identifier);
-	if (node->decls) {
-		gnode_array_each(node->decls, {visit(val);});
-		gnode_array_free(node->decls);
-	}
-	if (node->symtable) symboltable_free(node->symtable);
+    CHECK_REFCOUNT(node);
+    if (node->identifier) mem_free((void *)node->identifier);
+    if (node->decls) {
+        gnode_array_each(node->decls, {visit(val);});
+        gnode_array_free(node->decls);
+    }
+    if (node->symtable) symboltable_free(node->symtable);
     if (node->base.meta) gravity_hash_free(node->base.meta);
     if (node->base.meta) gravity_hash_free(node->base.meta);
-	mem_free((gnode_t*)node);
+    mem_free((gnode_t*)node);
 }
 }
 
 
 static void free_module_decl (gvisitor_t *self, gnode_module_decl_t *node) {
 static void free_module_decl (gvisitor_t *self, gnode_module_decl_t *node) {
-	CHECK_REFCOUNT(node);
-	if (node->identifier) mem_free((void *)node->identifier);
-	if (node->decls) {
-		gnode_array_each(node->decls, {visit(val);});
-		gnode_array_free(node->decls);
-	}
-	if (node->symtable) symboltable_free(node->symtable);
+    CHECK_REFCOUNT(node);
+    if (node->identifier) mem_free((void *)node->identifier);
+    if (node->decls) {
+        gnode_array_each(node->decls, {visit(val);});
+        gnode_array_free(node->decls);
+    }
+    if (node->symtable) symboltable_free(node->symtable);
     if (node->base.meta) gravity_hash_free(node->base.meta);
     if (node->base.meta) gravity_hash_free(node->base.meta);
-	mem_free((gnode_t*)node);
+    mem_free((gnode_t*)node);
 }
 }
 
 
 static void free_binary_expr (gvisitor_t *self, gnode_binary_expr_t *node) {
 static void free_binary_expr (gvisitor_t *self, gnode_binary_expr_t *node) {
-	CHECK_REFCOUNT(node);
-	if (node->left) visit(node->left);
-	if (node->right) visit(node->right);
-	mem_free((gnode_t*)node);
+    CHECK_REFCOUNT(node);
+    if (node->left) visit(node->left);
+    if (node->right) visit(node->right);
+    mem_free((gnode_t*)node);
 }
 }
 
 
 static void free_unary_expr (gvisitor_t *self, gnode_unary_expr_t *node) {
 static void free_unary_expr (gvisitor_t *self, gnode_unary_expr_t *node) {
-	CHECK_REFCOUNT(node);
-	if (node->expr) visit(node->expr);
-	mem_free((gnode_t*)node);
+    CHECK_REFCOUNT(node);
+    if (node->expr) visit(node->expr);
+    mem_free((gnode_t*)node);
 }
 }
 
 
 static void free_postfix_subexpr (gvisitor_t *self, gnode_postfix_subexpr_t *subnode) {
 static void free_postfix_subexpr (gvisitor_t *self, gnode_postfix_subexpr_t *subnode) {
-	CHECK_REFCOUNT(subnode);
-
-	gnode_n tag = subnode->base.tag;
-	if (tag == NODE_CALL_EXPR) {
-		if (subnode->args) {
-			gnode_array_each(subnode->args, visit(val););
-			gnode_array_free(subnode->args);
-		}
-	} else {
-		visit(subnode->expr);
-	}
+    CHECK_REFCOUNT(subnode);
+
+    gnode_n tag = subnode->base.tag;
+    if (tag == NODE_CALL_EXPR) {
+        if (subnode->args) {
+            gnode_array_each(subnode->args, visit(val););
+            gnode_array_free(subnode->args);
+        }
+    } else {
+        visit(subnode->expr);
+    }
 
 
-	mem_free((gnode_t*)subnode);
+    mem_free((gnode_t*)subnode);
 }
 }
 
 
 static void free_postfix_expr (gvisitor_t *self, gnode_postfix_expr_t *node) {
 static void free_postfix_expr (gvisitor_t *self, gnode_postfix_expr_t *node) {
-	CHECK_REFCOUNT(node);
+    CHECK_REFCOUNT(node);
 
 
-	visit(node->id);
+    visit(node->id);
 
 
-	// node->list can be NULL due to enum static conversion
-	size_t count = gnode_array_size(node->list);
-	for (size_t i=0; i<count; ++i) {
-		gnode_postfix_subexpr_t *subnode = (gnode_postfix_subexpr_t *) gnode_array_get(node->list, i);
-		free_postfix_subexpr(self, subnode);
-	}
-	if (node->list) gnode_array_free(node->list);
-	mem_free((gnode_t*)node);
+    // node->list can be NULL due to enum static conversion
+    size_t count = gnode_array_size(node->list);
+    for (size_t i=0; i<count; ++i) {
+        gnode_postfix_subexpr_t *subnode = (gnode_postfix_subexpr_t *) gnode_array_get(node->list, i);
+        free_postfix_subexpr(self, subnode);
+    }
+    if (node->list) gnode_array_free(node->list);
+    mem_free((gnode_t*)node);
 }
 }
 
 
 static void free_file_expr (gvisitor_t *self, gnode_file_expr_t *node) {
 static void free_file_expr (gvisitor_t *self, gnode_file_expr_t *node) {
-	#pragma unused(self)
-	CHECK_REFCOUNT(node);
-	cstring_array_each(node->identifiers, {
-		mem_free((void *)val);
-	});
+    #pragma unused(self)
+    CHECK_REFCOUNT(node);
+    cstring_array_each(node->identifiers, {
+        mem_free((void *)val);
+    });
 
 
-	if (node->identifiers) gnode_array_free(node->identifiers);
-	mem_free((void *)node);
+    if (node->identifiers) gnode_array_free(node->identifiers);
+    mem_free((void *)node);
 }
 }
 
 
 static void free_literal_expr (gvisitor_t *self, gnode_literal_expr_t *node) {
 static void free_literal_expr (gvisitor_t *self, gnode_literal_expr_t *node) {
-	#pragma unused(self)
-	CHECK_REFCOUNT(node);
-	if (node->type == LITERAL_STRING) mem_free((void *)node->value.str);
-	else if (node->type == LITERAL_STRING_INTERPOLATED) {
-		gnode_array_each(node->value.r, {visit(val);})
-		gnode_array_free(node->value.r);
-	}
-	mem_free((void *)node);
+    #pragma unused(self)
+    CHECK_REFCOUNT(node);
+    if (node->type == LITERAL_STRING) mem_free((void *)node->value.str);
+    else if (node->type == LITERAL_STRING_INTERPOLATED) {
+        gnode_array_each(node->value.r, {visit(val);})
+        gnode_array_free(node->value.r);
+    }
+    mem_free((void *)node);
 }
 }
 
 
 static void free_identifier_expr (gvisitor_t *self, gnode_identifier_expr_t *node) {
 static void free_identifier_expr (gvisitor_t *self, gnode_identifier_expr_t *node) {
-	#pragma unused(self, node)
-	CHECK_REFCOUNT(node);
-	if (node->value) mem_free((void *)node->value);
-	if (node->value2) mem_free((void *)node->value2);
-	mem_free((void *)node);
+    #pragma unused(self, node)
+    CHECK_REFCOUNT(node);
+    if (node->value) mem_free((void *)node->value);
+    if (node->value2) mem_free((void *)node->value2);
+    mem_free((void *)node);
 }
 }
 
 
 static void free_keyword_expr (gvisitor_t *self, gnode_keyword_expr_t *node) {
 static void free_keyword_expr (gvisitor_t *self, gnode_keyword_expr_t *node) {
-	#pragma unused(self)
-	CHECK_REFCOUNT(node);
-	mem_free((void *)node);
+    #pragma unused(self)
+    CHECK_REFCOUNT(node);
+    mem_free((void *)node);
 }
 }
 
 
 static void free_list_expr (gvisitor_t *self, gnode_list_expr_t *node) {
 static void free_list_expr (gvisitor_t *self, gnode_list_expr_t *node) {
-	CHECK_REFCOUNT(node);
-	if (node->list1) {
-		gnode_array_each(node->list1, {visit(val);});
-		gnode_array_free(node->list1);
-	}
-	if (node->list2) {
-		gnode_array_each(node->list2, {visit(val);});
-		gnode_array_free(node->list2);
-	}
-	mem_free((gnode_t*)node);
+    CHECK_REFCOUNT(node);
+    if (node->list1) {
+        gnode_array_each(node->list1, {visit(val);});
+        gnode_array_free(node->list1);
+    }
+    if (node->list2) {
+        gnode_array_each(node->list2, {visit(val);});
+        gnode_array_free(node->list2);
+    }
+    mem_free((gnode_t*)node);
 }
 }
 
 
 // MARK: -
 // MARK: -

+ 173 - 173
src/compiler/gravity_ast.h

@@ -14,244 +14,244 @@
 #include "gravity_token.h"
 #include "gravity_token.h"
 
 
 /*
 /*
-	AST can be uniform (the same data struct is used for all expressions/statements/declarations) or
-	non-uniform. I choosed a non-uniform AST node implementation with a common base struct.
-	It requires more work but design and usage is much more cleaner and we benefit from static check.
+    AST can be uniform (the same data struct is used for all expressions/statements/declarations) or
+    non-uniform. I choosed a non-uniform AST node implementation with a common base struct.
+    It requires more work but design and usage is much more cleaner and we benefit from static check.
  */
  */
 
 
 typedef enum {
 typedef enum {
-	// statements: 7
-	NODE_LIST_STAT, NODE_COMPOUND_STAT, NODE_LABEL_STAT, NODE_FLOW_STAT, NODE_JUMP_STAT, NODE_LOOP_STAT, NODE_EMPTY_STAT,
+    // statements: 7
+    NODE_LIST_STAT, NODE_COMPOUND_STAT, NODE_LABEL_STAT, NODE_FLOW_STAT, NODE_JUMP_STAT, NODE_LOOP_STAT, NODE_EMPTY_STAT,
 
 
-	// declarations: 6
-	NODE_ENUM_DECL, NODE_FUNCTION_DECL, NODE_VARIABLE_DECL, NODE_CLASS_DECL, NODE_MODULE_DECL, NODE_VARIABLE,
+    // declarations: 6
+    NODE_ENUM_DECL, NODE_FUNCTION_DECL, NODE_VARIABLE_DECL, NODE_CLASS_DECL, NODE_MODULE_DECL, NODE_VARIABLE,
 
 
-	// expressions: 8
-	NODE_BINARY_EXPR, NODE_UNARY_EXPR, NODE_FILE_EXPR, NODE_LIST_EXPR, NODE_LITERAL_EXPR, NODE_IDENTIFIER_EXPR,
-	NODE_POSTFIX_EXPR, NODE_KEYWORD_EXPR,
+    // expressions: 8
+    NODE_BINARY_EXPR, NODE_UNARY_EXPR, NODE_FILE_EXPR, NODE_LIST_EXPR, NODE_LITERAL_EXPR, NODE_IDENTIFIER_EXPR,
+    NODE_POSTFIX_EXPR, NODE_KEYWORD_EXPR,
 
 
-	// postfix subexpression type
-	NODE_CALL_EXPR, NODE_SUBSCRIPT_EXPR, NODE_ACCESS_EXPR
+    // postfix subexpression type
+    NODE_CALL_EXPR, NODE_SUBSCRIPT_EXPR, NODE_ACCESS_EXPR
 } gnode_n;
 } gnode_n;
 
 
 typedef enum {
 typedef enum {
-	LOCATION_LOCAL,
-	LOCATION_GLOBAL,
-	LOCATION_UPVALUE,
-	LOCATION_CLASS_IVAR_SAME,
-	LOCATION_CLASS_IVAR_OUTER
+    LOCATION_LOCAL,
+    LOCATION_GLOBAL,
+    LOCATION_UPVALUE,
+    LOCATION_CLASS_IVAR_SAME,
+    LOCATION_CLASS_IVAR_OUTER
 } gnode_location_type;
 } gnode_location_type;
 
 
 // BASE NODE
 // BASE NODE
 typedef struct {
 typedef struct {
-	gnode_n		tag;						// node type from gnode_n enum
-	uint32_t	refcount;					// reference count to manage duplicated nodes
-	gtoken_s	token;						// token type and location
-	bool		is_assignment;				// flag to check if it is an assignment node
+    gnode_n     tag;                        // node type from gnode_n enum
+    uint32_t    refcount;                   // reference count to manage duplicated nodes
+    gtoken_s    token;                      // token type and location
+    bool        is_assignment;              // flag to check if it is an assignment node
     void        *meta;                      // meta decoration (used only in decl nodes in this version but added here in order to prepare for a more complete solution)
     void        *meta;                      // meta decoration (used only in decl nodes in this version but added here in order to prepare for a more complete solution)
     void        *decl;                      // enclosing declaration node
     void        *decl;                      // enclosing declaration node
 } gnode_t;
 } gnode_t;
 
 
 // UPVALUE STRUCT
 // UPVALUE STRUCT
 typedef struct {
 typedef struct {
-	gnode_t		*node;						// reference to the original var node
-	uint32_t	index;						// can be an index in the stack or in the upvalue list (depending on the is_direct flag)
-	uint32_t	selfindex;					// always index inside uplist
-	bool		is_direct;					// flag to check if var is local to the direct enclosing func
+    gnode_t     *node;                      // reference to the original var node
+    uint32_t    index;                      // can be an index in the stack or in the upvalue list (depending on the is_direct flag)
+    uint32_t    selfindex;                  // always index inside uplist
+    bool        is_direct;                  // flag to check if var is local to the direct enclosing func
 } gupvalue_t;
 } gupvalue_t;
 
 
 // shortcut for array of common structs
 // shortcut for array of common structs
-typedef marray_t(gnode_t *)					gnode_r;
-typedef marray_t(gupvalue_t *)				gupvalue_r;
+typedef marray_t(gnode_t *)                 gnode_r;
+typedef marray_t(gupvalue_t *)              gupvalue_r;
 
 
 #ifndef GRAVITY_SYMBOLTABLE_DEFINED
 #ifndef GRAVITY_SYMBOLTABLE_DEFINED
 #define GRAVITY_SYMBOLTABLE_DEFINED
 #define GRAVITY_SYMBOLTABLE_DEFINED
-typedef struct symboltable_t				symboltable_t;
+typedef struct symboltable_t                symboltable_t;
 #endif
 #endif
 
 
 // LOCATION
 // LOCATION
 typedef struct {
 typedef struct {
-	gnode_location_type	type;				// location type
-	uint16_t			index;				// symbol index
-	uint16_t			nup;				// upvalue index or outer index
+    gnode_location_type type;               // location type
+    uint16_t            index;              // symbol index
+    uint16_t            nup;                // upvalue index or outer index
 } gnode_location_t;
 } gnode_location_t;
 
 
 // STATEMENTS
 // STATEMENTS
 typedef struct {
 typedef struct {
-	gnode_t				base;				// NODE_LIST_STAT | NODE_COMPOUND_STAT
-	symboltable_t		*symtable;			// node internal symbol table
-	gnode_r				*stmts;				// array of statements node
-	uint32_t			nclose;				// initialized to UINT32_MAX
+    gnode_t             base;               // NODE_LIST_STAT | NODE_COMPOUND_STAT
+    symboltable_t       *symtable;          // node internal symbol table
+    gnode_r             *stmts;             // array of statements node
+    uint32_t            nclose;             // initialized to UINT32_MAX
 } gnode_compound_stmt_t;
 } gnode_compound_stmt_t;
 typedef gnode_compound_stmt_t gnode_list_stmt_t;
 typedef gnode_compound_stmt_t gnode_list_stmt_t;
 
 
 typedef struct {
 typedef struct {
-	gnode_t				base;				// CASE or DEFAULT
-	gnode_t				*expr;				// expression in case of CASE
-	gnode_t				*stmt;				// common statement
+    gnode_t             base;               // CASE or DEFAULT
+    gnode_t             *expr;              // expression in case of CASE
+    gnode_t             *stmt;              // common statement
 } gnode_label_stmt_t;
 } gnode_label_stmt_t;
 
 
 typedef struct {
 typedef struct {
-	gnode_t				base;				// IF, SWITCH, TOK_OP_TERNARY
-	gnode_t				*cond;				// common condition (it's an expression)
-	gnode_t				*stmt;				// common statement
-	gnode_t				*elsestmt;			// optional else statement in case of IF
+    gnode_t             base;               // IF, SWITCH, TOK_OP_TERNARY
+    gnode_t             *cond;              // common condition (it's an expression)
+    gnode_t             *stmt;              // common statement
+    gnode_t             *elsestmt;          // optional else statement in case of IF
 } gnode_flow_stmt_t;
 } gnode_flow_stmt_t;
 
 
 typedef struct {
 typedef struct {
-	gnode_t				base;				// WHILE, REPEAT or FOR
-	gnode_t				*cond;				// used in WHILE and FOR
-	gnode_t				*stmt;				// common statement
-	gnode_t				*expr;				// used in REPEAT and FOR
-	uint32_t			nclose;				// initialized to UINT32_MAX
+    gnode_t             base;               // WHILE, REPEAT or FOR
+    gnode_t             *cond;              // used in WHILE and FOR
+    gnode_t             *stmt;              // common statement
+    gnode_t             *expr;              // used in REPEAT and FOR
+    uint32_t            nclose;             // initialized to UINT32_MAX
 } gnode_loop_stmt_t;
 } gnode_loop_stmt_t;
 
 
 typedef struct {
 typedef struct {
-	gnode_t				base;				// BREAK, CONTINUE or RETURN
-	gnode_t				*expr;				// optional expression in case of RETURN
+    gnode_t             base;               // BREAK, CONTINUE or RETURN
+    gnode_t             *expr;              // optional expression in case of RETURN
 } gnode_jump_stmt_t;
 } gnode_jump_stmt_t;
 
 
 // DECLARATIONS
 // DECLARATIONS
 typedef struct {
 typedef struct {
-	gnode_t				base;				// FUNCTION_DECL or FUNCTION_EXPR
-	gnode_t				*env;				// shortcut to node where function is declared
-	gtoken_t			access;				// TOK_KEY_PRIVATE | TOK_KEY_INTERNAL | TOK_KEY_PUBLIC
-	gtoken_t			storage;			// TOK_KEY_STATIC | TOK_KEY_EXTERN
-	symboltable_t		*symtable;			// function internal symbol table
-	const char			*identifier;		// function name
-	gnode_r				*params;			// function params
-	gnode_compound_stmt_t *block;			// internal function statements
-	uint16_t			nlocals;			// locals counter
-	uint16_t			nparams;			// formal parameters counter
+    gnode_t             base;               // FUNCTION_DECL or FUNCTION_EXPR
+    gnode_t             *env;               // shortcut to node where function is declared
+    gtoken_t            access;             // TOK_KEY_PRIVATE | TOK_KEY_INTERNAL | TOK_KEY_PUBLIC
+    gtoken_t            storage;            // TOK_KEY_STATIC | TOK_KEY_EXTERN
+    symboltable_t       *symtable;          // function internal symbol table
+    const char          *identifier;        // function name
+    gnode_r             *params;            // function params
+    gnode_compound_stmt_t *block;           // internal function statements
+    uint16_t            nlocals;            // locals counter
+    uint16_t            nparams;            // formal parameters counter
     bool                has_defaults;       // flag set if parmas has default values
     bool                has_defaults;       // flag set if parmas has default values
     bool                is_closure;         // flag to check if function is a closure
     bool                is_closure;         // flag to check if function is a closure
-	gupvalue_r			*uplist;			// list of upvalues used in function (can be empty)
+    gupvalue_r          *uplist;            // list of upvalues used in function (can be empty)
 } gnode_function_decl_t;
 } gnode_function_decl_t;
 typedef gnode_function_decl_t gnode_function_expr_t;
 typedef gnode_function_decl_t gnode_function_expr_t;
 
 
 typedef struct {
 typedef struct {
-	gnode_t				base;				// VARIABLE
-	gnode_t				*env;				// shortcut to node where variable is declared
-	const char			*identifier;		// variable name
-	const char			*annotation_type;	// optional annotation type
-	gnode_t				*expr;				// optional assignment expression/declaration
-	gtoken_t			access;				// optional access token (duplicated value from its gnode_variable_decl_t)
-	uint16_t			index;				// local variable index (if local)
-	bool				upvalue;			// flag set if this variable is used as an upvalue
+    gnode_t             base;               // VARIABLE
+    gnode_t             *env;               // shortcut to node where variable is declared
+    const char          *identifier;        // variable name
+    const char          *annotation_type;   // optional annotation type
+    gnode_t             *expr;              // optional assignment expression/declaration
+    gtoken_t            access;             // optional access token (duplicated value from its gnode_variable_decl_t)
+    uint16_t            index;              // local variable index (if local)
+    bool                upvalue;            // flag set if this variable is used as an upvalue
     bool                iscomputed;         // flag set is variable must not be backed
     bool                iscomputed;         // flag set is variable must not be backed
 } gnode_var_t;
 } gnode_var_t;
 
 
 typedef struct {
 typedef struct {
-	gnode_t				base;				// VARIABLE_DECL
-	gtoken_t			type;				// TOK_KEY_VAR | TOK_KEY_CONST
-	gtoken_t			access;				// TOK_KEY_PRIVATE | TOK_KEY_INTERNAL | TOK_KEY_PUBLIC
-	gtoken_t			storage;			// TOK_KEY_STATIC | TOK_KEY_EXTERN
-	gnode_r				*decls;				// variable declarations list (gnode_var_t)
+    gnode_t             base;               // VARIABLE_DECL
+    gtoken_t            type;               // TOK_KEY_VAR | TOK_KEY_CONST
+    gtoken_t            access;             // TOK_KEY_PRIVATE | TOK_KEY_INTERNAL | TOK_KEY_PUBLIC
+    gtoken_t            storage;            // TOK_KEY_STATIC | TOK_KEY_EXTERN
+    gnode_r             *decls;             // variable declarations list (gnode_var_t)
 } gnode_variable_decl_t;
 } gnode_variable_decl_t;
 
 
 typedef struct {
 typedef struct {
-	gnode_t				base;				// ENUM_DECL
-	gnode_t				*env;				// shortcut to node where enum is declared
-	gtoken_t			access;				// TOK_KEY_PRIVATE | TOK_KEY_INTERNAL | TOK_KEY_PUBLIC
-	gtoken_t			storage;			// TOK_KEY_STATIC | TOK_KEY_EXTERN
-	symboltable_t		*symtable;			// enum internal hash table
-	const char			*identifier;		// enum name
+    gnode_t             base;               // ENUM_DECL
+    gnode_t             *env;               // shortcut to node where enum is declared
+    gtoken_t            access;             // TOK_KEY_PRIVATE | TOK_KEY_INTERNAL | TOK_KEY_PUBLIC
+    gtoken_t            storage;            // TOK_KEY_STATIC | TOK_KEY_EXTERN
+    symboltable_t       *symtable;          // enum internal hash table
+    const char          *identifier;        // enum name
 } gnode_enum_decl_t;
 } gnode_enum_decl_t;
 
 
 typedef struct {
 typedef struct {
-	gnode_t				base;				// CLASS_DECL
-	bool				bridge;				// flag to check of a bridged class
-	bool				is_struct;			// flag to mark the class as a struct
-	gnode_t				*env;				// shortcut to node where class is declared
-	gtoken_t			access;				// TOK_KEY_PRIVATE | TOK_KEY_INTERNAL | TOK_KEY_PUBLIC
-	gtoken_t			storage;			// TOK_KEY_STATIC | TOK_KEY_EXTERN
-	const char			*identifier;		// class name
-	gnode_t				*superclass;		// super class ptr
-	gnode_r				*protocols;			// array of protocols (currently unused)
-	gnode_r				*decls;				// class declarations list
-	symboltable_t		*symtable;			// class internal symbol table
-	void				*data;				// used to keep track of super classes
-	uint32_t			nivar;				// instance variables counter
-	uint32_t			nsvar;				// static variables counter
+    gnode_t             base;               // CLASS_DECL
+    bool                bridge;             // flag to check of a bridged class
+    bool                is_struct;          // flag to mark the class as a struct
+    gnode_t             *env;               // shortcut to node where class is declared
+    gtoken_t            access;             // TOK_KEY_PRIVATE | TOK_KEY_INTERNAL | TOK_KEY_PUBLIC
+    gtoken_t            storage;            // TOK_KEY_STATIC | TOK_KEY_EXTERN
+    const char          *identifier;        // class name
+    gnode_t             *superclass;        // super class ptr
+    gnode_r             *protocols;         // array of protocols (currently unused)
+    gnode_r             *decls;             // class declarations list
+    symboltable_t       *symtable;          // class internal symbol table
+    void                *data;              // used to keep track of super classes
+    uint32_t            nivar;              // instance variables counter
+    uint32_t            nsvar;              // static variables counter
 } gnode_class_decl_t;
 } gnode_class_decl_t;
 
 
 typedef struct {
 typedef struct {
-	gnode_t				base;				// MODULE_DECL
-	gnode_t				*env;				// shortcut to node where module is declared
-	gtoken_t			access;				// TOK_KEY_PRIVATE | TOK_KEY_INTERNAL | TOK_KEY_PUBLIC
-	gtoken_t			storage;			// TOK_KEY_STATIC | TOK_KEY_EXTERN
-	const char			*identifier;		// module name
-	gnode_r				*decls;				// module declarations list
-	symboltable_t		*symtable;			// module internal symbol table
+    gnode_t             base;               // MODULE_DECL
+    gnode_t             *env;               // shortcut to node where module is declared
+    gtoken_t            access;             // TOK_KEY_PRIVATE | TOK_KEY_INTERNAL | TOK_KEY_PUBLIC
+    gtoken_t            storage;            // TOK_KEY_STATIC | TOK_KEY_EXTERN
+    const char          *identifier;        // module name
+    gnode_r             *decls;             // module declarations list
+    symboltable_t       *symtable;          // module internal symbol table
 } gnode_module_decl_t;
 } gnode_module_decl_t;
 
 
 // EXPRESSIONS
 // EXPRESSIONS
 typedef struct {
 typedef struct {
-	gnode_t				base;				// BINARY_EXPR
-	gtoken_t			op;					// operation
-	gnode_t				*left;				// left node
-	gnode_t				*right;				// right node
+    gnode_t             base;               // BINARY_EXPR
+    gtoken_t            op;                 // operation
+    gnode_t             *left;              // left node
+    gnode_t             *right;             // right node
 } gnode_binary_expr_t;
 } gnode_binary_expr_t;
 
 
 typedef struct {
 typedef struct {
-	gnode_t				base;				// UNARY_EXPR
-	gtoken_t			op;					// operation
-	gnode_t				*expr;				// node
+    gnode_t             base;               // UNARY_EXPR
+    gtoken_t            op;                 // operation
+    gnode_t             *expr;              // node
 } gnode_unary_expr_t;
 } gnode_unary_expr_t;
 
 
 typedef struct {
 typedef struct {
-	gnode_t				base;				// FILE
-	cstring_r			*identifiers;		// identifier name
-	gnode_location_t	location;			// identifier location
+    gnode_t             base;               // FILE
+    cstring_r           *identifiers;       // identifier name
+    gnode_location_t    location;           // identifier location
 } gnode_file_expr_t;
 } gnode_file_expr_t;
 
 
 typedef struct {
 typedef struct {
-	gnode_t				base;				// LITERAL
-	gliteral_t			type;				// LITERAL_STRING, LITERAL_FLOAT, LITERAL_INT, LITERAL_BOOL, LITERAL_INTERPOLATION
-	uint32_t			len;				// used only for TYPE_STRING
-	union {
-		char			*str;				// LITERAL_STRING
-		double			d;					// LITERAL_FLOAT
-		int64_t			n64;				// LITERAL_INT or LITERAL_BOOL
-		gnode_r			*r;					// LITERAL_STRING_INTERPOLATED
-	} value;
+    gnode_t             base;               // LITERAL
+    gliteral_t          type;               // LITERAL_STRING, LITERAL_FLOAT, LITERAL_INT, LITERAL_BOOL, LITERAL_INTERPOLATION
+    uint32_t            len;                // used only for TYPE_STRING
+    union {
+        char            *str;               // LITERAL_STRING
+        double          d;                  // LITERAL_FLOAT
+        int64_t         n64;                // LITERAL_INT or LITERAL_BOOL
+        gnode_r         *r;                 // LITERAL_STRING_INTERPOLATED
+    } value;
 } gnode_literal_expr_t;
 } gnode_literal_expr_t;
 
 
 typedef struct {
 typedef struct {
-	gnode_t				base;				// IDENTIFIER or ID
-	const char			*value;				// identifier name
-	const char			*value2;			// NULL for IDENTIFIER (check if just one value or an array)
-	gnode_t				*symbol;			// pointer to identifier declaration (if any)
-	gnode_location_t	location;			// location coordinates
-	gupvalue_t			*upvalue;			// upvalue location reference
+    gnode_t             base;               // IDENTIFIER or ID
+    const char          *value;             // identifier name
+    const char          *value2;            // NULL for IDENTIFIER (check if just one value or an array)
+    gnode_t             *symbol;            // pointer to identifier declaration (if any)
+    gnode_location_t    location;           // location coordinates
+    gupvalue_t          *upvalue;           // upvalue location reference
 } gnode_identifier_expr_t;
 } gnode_identifier_expr_t;
 
 
 typedef struct {
 typedef struct {
-	gnode_t				base;				// KEYWORD token
+    gnode_t             base;               // KEYWORD token
 } gnode_keyword_expr_t;
 } gnode_keyword_expr_t;
 
 
 typedef gnode_keyword_expr_t gnode_empty_stmt_t;
 typedef gnode_keyword_expr_t gnode_empty_stmt_t;
 typedef gnode_keyword_expr_t gnode_base_t;
 typedef gnode_keyword_expr_t gnode_base_t;
 
 
 typedef struct {
 typedef struct {
-	gnode_t				base;				// NODE_CALLFUNC_EXPR, NODE_SUBSCRIPT_EXPR, NODE_ACCESS_EXPR
-	gnode_t				*id;				// id(...) or id[...] or id.
-	gnode_r				*list;				// list of postfix_subexpr
+    gnode_t             base;               // NODE_CALLFUNC_EXPR, NODE_SUBSCRIPT_EXPR, NODE_ACCESS_EXPR
+    gnode_t             *id;                // id(...) or id[...] or id.
+    gnode_r             *list;              // list of postfix_subexpr
 } gnode_postfix_expr_t;
 } gnode_postfix_expr_t;
 
 
 typedef struct {
 typedef struct {
-	gnode_t				base;				// NODE_CALLFUNC_EXPR, NODE_SUBSCRIPT_EXPR, NODE_ACCESS_EXPR
-	union {
-		gnode_t			*expr;				// used in case of NODE_SUBSCRIPT_EXPR or NODE_ACCESS_EXPR
-		gnode_r			*args;				// used in case of NODE_CALLFUNC_EXPR
-	};
+    gnode_t             base;               // NODE_CALLFUNC_EXPR, NODE_SUBSCRIPT_EXPR, NODE_ACCESS_EXPR
+    union {
+        gnode_t         *expr;              // used in case of NODE_SUBSCRIPT_EXPR or NODE_ACCESS_EXPR
+        gnode_r         *args;              // used in case of NODE_CALLFUNC_EXPR
+    };
 } gnode_postfix_subexpr_t;
 } gnode_postfix_subexpr_t;
 
 
 typedef struct {
 typedef struct {
-	gnode_t				base;				// LIST_EXPR
-	bool				ismap;				// flag to check if the node represents a map (otherwise it is a list)
-	gnode_r				*list1;				// node items (cannot use a symtable here because order is mandatory in array)
-	gnode_r				*list2;				// used only in case of map
+    gnode_t             base;               // LIST_EXPR
+    bool                ismap;              // flag to check if the node represents a map (otherwise it is a list)
+    gnode_r             *list1;             // node items (cannot use a symtable here because order is mandatory in array)
+    gnode_r             *list2;             // used only in case of map
 } gnode_list_expr_t;
 } gnode_list_expr_t;
 
 
 gnode_t *gnode_jump_stat_create (gtoken_s token, gnode_t *expr, gnode_t *decl);
 gnode_t *gnode_jump_stat_create (gtoken_s token, gnode_t *expr, gnode_t *decl);
@@ -284,49 +284,49 @@ gnode_t *gnode_postfix_expr_create (gtoken_s token, gnode_t *id, gnode_r *list,
 gnode_t *gnode_list_expr_create (gtoken_s token, gnode_r *list1, gnode_r *list2, bool ismap, gnode_t *decl);
 gnode_t *gnode_list_expr_create (gtoken_s token, gnode_r *list1, gnode_r *list2, bool ismap, gnode_t *decl);
 
 
 gnode_t *gnode_duplicate (gnode_t *node, bool deep);
 gnode_t *gnode_duplicate (gnode_t *node, bool deep);
-gnode_r	*gnode_array_create (void);
+gnode_r *gnode_array_create (void);
 gnode_r *gnode_array_remove_byindex(gnode_r *list, size_t index);
 gnode_r *gnode_array_remove_byindex(gnode_r *list, size_t index);
 gupvalue_t *gnode_function_add_upvalue(gnode_function_decl_t *f, gnode_var_t *symbol, uint16_t n);
 gupvalue_t *gnode_function_add_upvalue(gnode_function_decl_t *f, gnode_var_t *symbol, uint16_t n);
 cstring_r  *cstring_array_create (void);
 cstring_r  *cstring_array_create (void);
-void_r	*void_array_create (void);
-void	gnode_array_sethead(gnode_r *list, gnode_t *node);
-
-bool	gnode_is_equal (gnode_t *node1, gnode_t *node2);
-bool	gnode_is_expression (gnode_t *node);
-bool	gnode_is_literal (gnode_t *node);
-bool	gnode_is_literal_int (gnode_t *node);
-bool	gnode_is_literal_number (gnode_t *node);
-bool	gnode_is_literal_string (gnode_t *node);
-void	gnode_literal_dump (gnode_literal_expr_t *node, char *buffer, int buffersize);
-void	gnode_free (gnode_t *node);
+void_r  *void_array_create (void);
+void    gnode_array_sethead(gnode_r *list, gnode_t *node);
+
+bool    gnode_is_equal (gnode_t *node1, gnode_t *node2);
+bool    gnode_is_expression (gnode_t *node);
+bool    gnode_is_literal (gnode_t *node);
+bool    gnode_is_literal_int (gnode_t *node);
+bool    gnode_is_literal_number (gnode_t *node);
+bool    gnode_is_literal_string (gnode_t *node);
+void    gnode_literal_dump (gnode_literal_expr_t *node, char *buffer, int buffersize);
+void    gnode_free (gnode_t *node);
 
 
 void    *meta_from_node (gnode_t *node);
 void    *meta_from_node (gnode_t *node);
 
 
 // MARK: -
 // MARK: -
 
 
-#define gnode_array_init(r)					marray_init(*r)
-#define gnode_array_size(r)					((r) ? marray_size(*r) : 0)
-#define gnode_array_push(r, node)			marray_push(gnode_t*,*r,node)
-#define gnode_array_pop(r)					(marray_size(*r) ? marray_pop(*r) : NULL)
-#define gnode_array_get(r, i)				(((i) >= 0 && (i) < marray_size(*r)) ? marray_get(*r, (i)) : NULL)
-#define gnode_array_free(r)					do {marray_destroy(*r); mem_free((void*)r);} while (0)
-#define gtype_array_each(r, block, type)	{	size_t _len = gnode_array_size(r);				\
-												for (size_t _i=0; _i<_len; ++_i) {				\
-													type val = (type)gnode_array_get(r, _i);	\
-													block;} \
-											}
-#define gnode_array_each(r, block)			gtype_array_each(r, block, gnode_t*)
-#define gnode_array_eachbase(r, block)		gtype_array_each(r, block, gnode_base_t*)
-
-#define cstring_array_free(r)				marray_destroy(*r)
-#define cstring_array_push(r, s)			marray_push(const char*,*r,s)
-#define cstring_array_each(r, block)		gtype_array_each(r, block, const char*)
-
-#define NODE_TOKEN_TYPE(_node)				_node->base.token.type
-#define NODE_TAG(_node)						((gnode_base_t *)_node)->base.tag
-#define NODE_ISA(_node,_tag)				((_node) && NODE_TAG(_node) == _tag)
-#define NODE_ISA_FUNCTION(_node)			(NODE_ISA(_node, NODE_FUNCTION_DECL))
-#define NODE_ISA_CLASS(_node)				(NODE_ISA(_node, NODE_CLASS_DECL))
+#define gnode_array_init(r)                 marray_init(*r)
+#define gnode_array_size(r)                 ((r) ? marray_size(*r) : 0)
+#define gnode_array_push(r, node)           marray_push(gnode_t*,*r,node)
+#define gnode_array_pop(r)                  (marray_size(*r) ? marray_pop(*r) : NULL)
+#define gnode_array_get(r, i)               (((i) >= 0 && (i) < marray_size(*r)) ? marray_get(*r, (i)) : NULL)
+#define gnode_array_free(r)                 do {marray_destroy(*r); mem_free((void*)r);} while (0)
+#define gtype_array_each(r, block, type)    {   size_t _len = gnode_array_size(r);                \
+                                                for (size_t _i=0; _i<_len; ++_i) {                \
+                                                    type val = (type)gnode_array_get(r, _i);    \
+                                                    block;} \
+                                            }
+#define gnode_array_each(r, block)          gtype_array_each(r, block, gnode_t*)
+#define gnode_array_eachbase(r, block)      gtype_array_each(r, block, gnode_base_t*)
+
+#define cstring_array_free(r)               marray_destroy(*r)
+#define cstring_array_push(r, s)            marray_push(const char*,*r,s)
+#define cstring_array_each(r, block)        gtype_array_each(r, block, const char*)
+
+#define NODE_TOKEN_TYPE(_node)              _node->base.token.type
+#define NODE_TAG(_node)                     ((gnode_base_t *)_node)->base.tag
+#define NODE_ISA(_node,_tag)                ((_node) && NODE_TAG(_node) == _tag)
+#define NODE_ISA_FUNCTION(_node)            (NODE_ISA(_node, NODE_FUNCTION_DECL))
+#define NODE_ISA_CLASS(_node)               (NODE_ISA(_node, NODE_CLASS_DECL))
 
 
 #define NODE_SET_ENCLOSING(_node,_enc)      (((gnode_base_t *)_node)->base.enclosing = _enc)
 #define NODE_SET_ENCLOSING(_node,_enc)      (((gnode_base_t *)_node)->base.enclosing = _enc)
 #define NODE_GET_ENCLOSING(_node)           ((gnode_base_t *)_node)->base.enclosing
 #define NODE_GET_ENCLOSING(_node)           ((gnode_base_t *)_node)->base.enclosing

File diff suppressed because it is too large
+ 705 - 705
src/compiler/gravity_codegen.c


+ 133 - 133
src/compiler/gravity_compiler.c

@@ -19,190 +19,190 @@
 #include "gravity_core.h"
 #include "gravity_core.h"
 
 
 struct gravity_compiler_t {
 struct gravity_compiler_t {
-	gravity_parser_t		*parser;
-	gravity_delegate_t		*delegate;
-	cstring_r				*storage;
-	gravity_vm				*vm;
-	gnode_t					*ast;
-	void_r					*objects;
+    gravity_parser_t        *parser;
+    gravity_delegate_t      *delegate;
+    cstring_r               *storage;
+    gravity_vm              *vm;
+    gnode_t                 *ast;
+    void_r                  *objects;
 };
 };
 
 
 static void internal_vm_transfer (gravity_vm *vm, gravity_object_t *obj) {
 static void internal_vm_transfer (gravity_vm *vm, gravity_object_t *obj) {
-	gravity_compiler_t *compiler = (gravity_compiler_t *)gravity_vm_getdata(vm);
-	marray_push(void*, *compiler->objects, obj);
+    gravity_compiler_t *compiler = (gravity_compiler_t *)gravity_vm_getdata(vm);
+    marray_push(void*, *compiler->objects, obj);
 }
 }
 
 
 static void internal_free_class (gravity_hash_t *hashtable, gravity_value_t key, gravity_value_t value, void *data) {
 static void internal_free_class (gravity_hash_t *hashtable, gravity_value_t key, gravity_value_t value, void *data) {
-	#pragma unused (hashtable, data)
-
-	// sanity checks
-	if (!VALUE_ISA_FUNCTION(value)) return;
-	if (!VALUE_ISA_STRING(key)) return;
-
-	// check for special function
-	gravity_function_t *f = VALUE_AS_FUNCTION(value);
-	if (f->tag == EXEC_TYPE_SPECIAL) {
-		if (f->special[0]) gravity_function_free(NULL, (gravity_function_t *)f->special[0]);
-		if (f->special[1]) gravity_function_free(NULL, (gravity_function_t *)f->special[1]);
-	}
-
-	// a super special init constructor is a string that begins with $init AND it is longer than strlen($init)
-	gravity_string_t *s = VALUE_AS_STRING(key);
-	bool is_super_function = ((s->len > 5) && (string_casencmp(s->s, CLASS_INTERNAL_INIT_NAME, 5) == 0));
-	if (!is_super_function) gravity_function_free(NULL, VALUE_AS_FUNCTION(value));
+    #pragma unused (hashtable, data)
+
+    // sanity checks
+    if (!VALUE_ISA_FUNCTION(value)) return;
+    if (!VALUE_ISA_STRING(key)) return;
+
+    // check for special function
+    gravity_function_t *f = VALUE_AS_FUNCTION(value);
+    if (f->tag == EXEC_TYPE_SPECIAL) {
+        if (f->special[0]) gravity_function_free(NULL, (gravity_function_t *)f->special[0]);
+        if (f->special[1]) gravity_function_free(NULL, (gravity_function_t *)f->special[1]);
+    }
+
+    // a super special init constructor is a string that begins with $init AND it is longer than strlen($init)
+    gravity_string_t *s = VALUE_AS_STRING(key);
+    bool is_super_function = ((s->len > 5) && (string_casencmp(s->s, CLASS_INTERNAL_INIT_NAME, 5) == 0));
+    if (!is_super_function) gravity_function_free(NULL, VALUE_AS_FUNCTION(value));
 }
 }
 
 
 static void internal_vm_cleanup (gravity_vm *vm) {
 static void internal_vm_cleanup (gravity_vm *vm) {
-	gravity_compiler_t *compiler = (gravity_compiler_t *)gravity_vm_getdata(vm);
-	size_t count = marray_size(*compiler->objects);
-	for (size_t i=0; i<count; ++i) {
-		gravity_object_t *obj = marray_pop(*compiler->objects);
-		if (OBJECT_ISA_CLASS(obj)) {
-			gravity_class_t *c = (gravity_class_t *)obj;
-			gravity_hash_iterate(c->htable, internal_free_class, NULL);
-		}
-		gravity_object_free(vm, obj);
-	}
+    gravity_compiler_t *compiler = (gravity_compiler_t *)gravity_vm_getdata(vm);
+    size_t count = marray_size(*compiler->objects);
+    for (size_t i=0; i<count; ++i) {
+        gravity_object_t *obj = marray_pop(*compiler->objects);
+        if (OBJECT_ISA_CLASS(obj)) {
+            gravity_class_t *c = (gravity_class_t *)obj;
+            gravity_hash_iterate(c->htable, internal_free_class, NULL);
+        }
+        gravity_object_free(vm, obj);
+    }
 }
 }
 
 
 // MARK: -
 // MARK: -
 
 
 gravity_compiler_t *gravity_compiler_create (gravity_delegate_t *delegate) {
 gravity_compiler_t *gravity_compiler_create (gravity_delegate_t *delegate) {
-	gravity_compiler_t *compiler = mem_alloc(NULL, sizeof(gravity_compiler_t));
-	if (!compiler) return NULL;
+    gravity_compiler_t *compiler = mem_alloc(NULL, sizeof(gravity_compiler_t));
+    if (!compiler) return NULL;
 
 
-	compiler->ast = NULL;
-	compiler->objects = void_array_create();
-	compiler->delegate = delegate;
-	return compiler;
+    compiler->ast = NULL;
+    compiler->objects = void_array_create();
+    compiler->delegate = delegate;
+    return compiler;
 }
 }
 
 
 static void gravity_compiler_reset (gravity_compiler_t *compiler, bool free_core) {
 static void gravity_compiler_reset (gravity_compiler_t *compiler, bool free_core) {
-	// free memory for array of strings storage
-	if (compiler->storage) {
-		cstring_array_each(compiler->storage, {mem_free((void *)val);});
-		gnode_array_free(compiler->storage);
-	}
-
-	// first ast then parser, don't change the release order
-	if (compiler->ast) gnode_free(compiler->ast);
-	if (compiler->parser) gravity_parser_free(compiler->parser);
-
-	// at the end free mini VM and objects array
-	if (compiler->vm) gravity_vm_free(compiler->vm);
-	if (compiler->objects) {
-		marray_destroy(*compiler->objects);
-		mem_free((void*)compiler->objects);
-	}
-
-	// feel free to free core if someone requires it
+    // free memory for array of strings storage
+    if (compiler->storage) {
+        cstring_array_each(compiler->storage, {mem_free((void *)val);});
+        gnode_array_free(compiler->storage);
+    }
+
+    // first ast then parser, don't change the release order
+    if (compiler->ast) gnode_free(compiler->ast);
+    if (compiler->parser) gravity_parser_free(compiler->parser);
+
+    // at the end free mini VM and objects array
+    if (compiler->vm) gravity_vm_free(compiler->vm);
+    if (compiler->objects) {
+        marray_destroy(*compiler->objects);
+        mem_free((void*)compiler->objects);
+    }
+
+    // feel free to free core if someone requires it
     if (free_core) gravity_core_free();
     if (free_core) gravity_core_free();
 
 
-	// reset internal pointers
-	compiler->vm = NULL;
-	compiler->ast = NULL;
-	compiler->parser = NULL;
-	compiler->objects = NULL;
-	compiler->storage = NULL;
+    // reset internal pointers
+    compiler->vm = NULL;
+    compiler->ast = NULL;
+    compiler->parser = NULL;
+    compiler->objects = NULL;
+    compiler->storage = NULL;
 }
 }
 
 
 void gravity_compiler_free (gravity_compiler_t *compiler) {
 void gravity_compiler_free (gravity_compiler_t *compiler) {
-	gravity_compiler_reset(compiler, true);
-	mem_free(compiler);
+    gravity_compiler_reset(compiler, true);
+    mem_free(compiler);
 }
 }
 
 
 gnode_t *gravity_compiler_ast (gravity_compiler_t *compiler) {
 gnode_t *gravity_compiler_ast (gravity_compiler_t *compiler) {
-	return compiler->ast;
+    return compiler->ast;
 }
 }
 
 
 void gravity_compiler_transfer(gravity_compiler_t *compiler, gravity_vm *vm) {
 void gravity_compiler_transfer(gravity_compiler_t *compiler, gravity_vm *vm) {
-	if (!compiler->objects) return;
-
-	// transfer each object from compiler mini VM to exec VM
-	gravity_gc_setenabled(vm, false);
-	size_t count = marray_size(*compiler->objects);
-	for (size_t i=0; i<count; ++i) {
-		gravity_object_t *obj = marray_pop(*compiler->objects);
-		gravity_vm_transfer(vm, obj);
-		if (!OBJECT_ISA_CLOSURE(obj)) continue;
-
-		// $moduleinit closure needs to be explicitly initialized
-		gravity_closure_t *closure = (gravity_closure_t *)obj;
-		if ((closure->f->identifier) && strcmp(closure->f->identifier, INITMODULE_NAME) == 0) {
-			// code is here because it does not make sense to add this overhead (that needs to be executed only once)
-			// inside the gravity_vm_transfer callback which is called for each allocated object inside the VM
-			gravity_vm_initmodule(vm, closure->f);
-		}
-	}
-
-	gravity_gc_setenabled(vm, true);
+    if (!compiler->objects) return;
+
+    // transfer each object from compiler mini VM to exec VM
+    gravity_gc_setenabled(vm, false);
+    size_t count = marray_size(*compiler->objects);
+    for (size_t i=0; i<count; ++i) {
+        gravity_object_t *obj = marray_pop(*compiler->objects);
+        gravity_vm_transfer(vm, obj);
+        if (!OBJECT_ISA_CLOSURE(obj)) continue;
+
+        // $moduleinit closure needs to be explicitly initialized
+        gravity_closure_t *closure = (gravity_closure_t *)obj;
+        if ((closure->f->identifier) && strcmp(closure->f->identifier, INITMODULE_NAME) == 0) {
+            // code is here because it does not make sense to add this overhead (that needs to be executed only once)
+            // inside the gravity_vm_transfer callback which is called for each allocated object inside the VM
+            gravity_vm_initmodule(vm, closure->f);
+        }
+    }
+
+    gravity_gc_setenabled(vm, true);
 }
 }
 
 
 // MARK: -
 // MARK: -
 
 
 gravity_closure_t *gravity_compiler_run (gravity_compiler_t *compiler, const char *source, size_t len, uint32_t fileid, bool is_static) {
 gravity_closure_t *gravity_compiler_run (gravity_compiler_t *compiler, const char *source, size_t len, uint32_t fileid, bool is_static) {
-	if ((source == NULL) || (len == 0)) return NULL;
+    if ((source == NULL) || (len == 0)) return NULL;
 
 
-	// CHECK cleanup first
-	if (compiler->ast) gnode_free(compiler->ast);
-	if (!compiler->objects) compiler->objects = void_array_create();
+    // CHECK cleanup first
+    if (compiler->ast) gnode_free(compiler->ast);
+    if (!compiler->objects) compiler->objects = void_array_create();
 
 
-	// CODEGEN requires a mini vm in order to be able to handle garbage collector
-	compiler->vm = gravity_vm_newmini();
-	gravity_vm_setdata(compiler->vm, (void *)compiler);
-	gravity_vm_set_callbacks(compiler->vm, internal_vm_transfer, internal_vm_cleanup);
-	gravity_core_register(compiler->vm);
+    // CODEGEN requires a mini vm in order to be able to handle garbage collector
+    compiler->vm = gravity_vm_newmini();
+    gravity_vm_setdata(compiler->vm, (void *)compiler);
+    gravity_vm_set_callbacks(compiler->vm, internal_vm_transfer, internal_vm_cleanup);
+    gravity_core_register(compiler->vm);
 
 
-	// STEP 0: CREATE PARSER
-	compiler->parser = gravity_parser_create(source, len, fileid, is_static);
-	if (!compiler->parser) return NULL;
+    // STEP 0: CREATE PARSER
+    compiler->parser = gravity_parser_create(source, len, fileid, is_static);
+    if (!compiler->parser) return NULL;
 
 
-	// STEP 1: SYNTAX CHECK
-	compiler->ast = gravity_parser_run(compiler->parser, compiler->delegate);
-	if (!compiler->ast) goto abort_compilation;
-	gravity_parser_free(compiler->parser);
-	compiler->parser = NULL;
+    // STEP 1: SYNTAX CHECK
+    compiler->ast = gravity_parser_run(compiler->parser, compiler->delegate);
+    if (!compiler->ast) goto abort_compilation;
+    gravity_parser_free(compiler->parser);
+    compiler->parser = NULL;
 
 
-	// STEP 2a: SEMANTIC CHECK (NON-LOCAL DECLARATIONS)
-	bool b1 = gravity_semacheck1(compiler->ast, compiler->delegate);
-	if (!b1) goto abort_compilation;
+    // STEP 2a: SEMANTIC CHECK (NON-LOCAL DECLARATIONS)
+    bool b1 = gravity_semacheck1(compiler->ast, compiler->delegate);
+    if (!b1) goto abort_compilation;
 
 
-	// STEP 2b: SEMANTIC CHECK (LOCAL DECLARATIONS)
-	bool b2 = gravity_semacheck2(compiler->ast, compiler->delegate);
-	if (!b2) goto abort_compilation;
+    // STEP 2b: SEMANTIC CHECK (LOCAL DECLARATIONS)
+    bool b2 = gravity_semacheck2(compiler->ast, compiler->delegate);
+    if (!b2) goto abort_compilation;
 
 
-	// STEP 3: INTERMEDIATE CODE GENERATION (stack based VM)
-	gravity_function_t *f = gravity_codegen(compiler->ast, compiler->delegate, compiler->vm);
-	if (!f) goto abort_compilation;
+    // STEP 3: INTERMEDIATE CODE GENERATION (stack based VM)
+    gravity_function_t *f = gravity_codegen(compiler->ast, compiler->delegate, compiler->vm);
+    if (!f) goto abort_compilation;
 
 
-	// STEP 4: CODE GENERATION (register based VM)
-	f = gravity_optimizer(f);
-	if (f) return gravity_closure_new(compiler->vm, f);
+    // STEP 4: CODE GENERATION (register based VM)
+    f = gravity_optimizer(f);
+    if (f) return gravity_closure_new(compiler->vm, f);
 
 
 abort_compilation:
 abort_compilation:
-	gravity_compiler_reset(compiler, false);
-	return NULL;
+    gravity_compiler_reset(compiler, false);
+    return NULL;
 }
 }
 
 
 json_t *gravity_compiler_serialize (gravity_compiler_t *compiler, gravity_closure_t *closure) {
 json_t *gravity_compiler_serialize (gravity_compiler_t *compiler, gravity_closure_t *closure) {
-	#pragma unused(compiler)
-	if (!closure) return NULL;
+    #pragma unused(compiler)
+    if (!closure) return NULL;
 
 
-	json_t *json = json_new();
-	json_begin_object(json, NULL);
+    json_t *json = json_new();
+    json_begin_object(json, NULL);
 
 
-	gravity_function_serialize(closure->f, json);
+    gravity_function_serialize(closure->f, json);
 
 
-	json_end_object(json);
-	return json;
+    json_end_object(json);
+    return json;
 }
 }
 
 
 bool gravity_compiler_serialize_infile (gravity_compiler_t *compiler, gravity_closure_t *closure, const char *path) {
 bool gravity_compiler_serialize_infile (gravity_compiler_t *compiler, gravity_closure_t *closure, const char *path) {
-	if (!closure) return false;
-	json_t *json = gravity_compiler_serialize(compiler, closure);
-	if (!json) return false;
-	
-	json_write_file(json, path);
-	json_free(json);
-	return true;
+    if (!closure) return false;
+    json_t *json = gravity_compiler_serialize(compiler, closure);
+    if (!json) return false;
+    
+    json_write_file(json, path);
+    json_free(json);
+    return true;
 }
 }

+ 8 - 8
src/compiler/gravity_compiler.h

@@ -20,15 +20,15 @@ extern "C" {
 #endif
 #endif
 
 
 // opaque compiler data type
 // opaque compiler data type
-typedef struct gravity_compiler_t	gravity_compiler_t;
+typedef struct gravity_compiler_t   gravity_compiler_t;
 
 
-GRAVITY_API gravity_compiler_t	*gravity_compiler_create (gravity_delegate_t *delegate);
-GRAVITY_API gravity_closure_t	*gravity_compiler_run (gravity_compiler_t *compiler, const char *source, size_t len, uint32_t fileid, bool is_static);
-GRAVITY_API json_t				*gravity_compiler_serialize (gravity_compiler_t *compiler, gravity_closure_t *closure);
-GRAVITY_API bool				gravity_compiler_serialize_infile (gravity_compiler_t *compiler, gravity_closure_t *closure, const char *path);
-GRAVITY_API void				gravity_compiler_transfer (gravity_compiler_t *compiler, gravity_vm *vm);
-GRAVITY_API gnode_t				*gravity_compiler_ast (gravity_compiler_t *compiler);
-GRAVITY_API void				gravity_compiler_free (gravity_compiler_t *compiler);
+GRAVITY_API gravity_compiler_t  *gravity_compiler_create (gravity_delegate_t *delegate);
+GRAVITY_API gravity_closure_t   *gravity_compiler_run (gravity_compiler_t *compiler, const char *source, size_t len, uint32_t fileid, bool is_static);
+GRAVITY_API json_t  *gravity_compiler_serialize (gravity_compiler_t *compiler, gravity_closure_t *closure);
+GRAVITY_API bool    gravity_compiler_serialize_infile (gravity_compiler_t *compiler, gravity_closure_t *closure, const char *path);
+GRAVITY_API void    gravity_compiler_transfer (gravity_compiler_t *compiler, gravity_vm *vm);
+GRAVITY_API gnode_t *gravity_compiler_ast (gravity_compiler_t *compiler);
+GRAVITY_API void    gravity_compiler_free (gravity_compiler_t *compiler);
 
 
 #ifdef __cplusplus
 #ifdef __cplusplus
 }
 }

+ 354 - 354
src/compiler/gravity_ircode.c

@@ -11,471 +11,471 @@
 #include "gravity_debug.h"
 #include "gravity_debug.h"
 #include <inttypes.h>
 #include <inttypes.h>
 
 
-typedef marray_t(inst_t *)		code_r;
-typedef marray_t(bool *)		context_r;
+typedef marray_t(inst_t *)      code_r;
+typedef marray_t(bool *)        context_r;
 
 
 struct ircode_t {
 struct ircode_t {
-	code_r		*list;						// array of ircode instructions
+    code_r      *list;                      // array of ircode instructions
 
 
-	uint32_r	label_true;					// labels used in loops
-	uint32_r	label_false;
-	uint32_t	label_counter;
+    uint32_r    label_true;                 // labels used in loops
+    uint32_r    label_false;
+    uint32_t    label_counter;
 
 
-	uint32_t	maxtemp;					// maximum number of temp registers used in this ircode
-	uint32_t	ntemps;						// current number of temp registers in use
-	uint16_t	nlocals;					// number of local registers (params + local variables)
-	bool		error;						// error flag set when no more registers are availables
+    uint32_t    maxtemp;                    // maximum number of temp registers used in this ircode
+    uint32_t    ntemps;                     // current number of temp registers in use
+    uint16_t    nlocals;                    // number of local registers (params + local variables)
+    bool        error;                      // error flag set when no more registers are availables
 
 
-	bool		state[MAX_REGISTERS];		// registers mask
-	bool		skipclear[MAX_REGISTERS];	// registers protection for temps used in for loop
-	uint32_r	registers;					// registers stack
-	context_r	context;					// context array
+    bool        state[MAX_REGISTERS];       // registers mask
+    bool        skipclear[MAX_REGISTERS];   // registers protection for temps used in for loop
+    uint32_r    registers;                  // registers stack
+    context_r   context;                    // context array
 };
 };
 
 
 ircode_t *ircode_create (uint16_t nlocals) {
 ircode_t *ircode_create (uint16_t nlocals) {
-	ircode_t *code = (ircode_t *)mem_alloc(NULL, sizeof(ircode_t));
+    ircode_t *code = (ircode_t *)mem_alloc(NULL, sizeof(ircode_t));
     if (!code) return NULL;
     if (!code) return NULL;
-	code->label_counter = 0;
-	code->nlocals = nlocals;
-	code->ntemps = 0;
-	code->maxtemp = 0;
-	code->error = false;
+    code->label_counter = 0;
+    code->nlocals = nlocals;
+    code->ntemps = 0;
+    code->maxtemp = 0;
+    code->error = false;
 
 
-	code->list = mem_alloc(NULL, sizeof(code_r));
+    code->list = mem_alloc(NULL, sizeof(code_r));
     if (!code->list) return NULL;
     if (!code->list) return NULL;
-	marray_init(*code->list);
-	marray_init(code->label_true);
-	marray_init(code->label_false);
-	marray_init(code->registers);
-	marray_init(code->context);
-
-	// init state array (register 0 is reserved)
-	bzero(code->state, MAX_REGISTERS * sizeof(bool));
-	code->state[0] = true;
-	for (uint32_t i=0; i<nlocals; ++i) {
-		code->state[i] = true;
-	}
-	return code;
+    marray_init(*code->list);
+    marray_init(code->label_true);
+    marray_init(code->label_false);
+    marray_init(code->registers);
+    marray_init(code->context);
+
+    // init state array (register 0 is reserved)
+    bzero(code->state, MAX_REGISTERS * sizeof(bool));
+    code->state[0] = true;
+    for (uint32_t i=0; i<nlocals; ++i) {
+        code->state[i] = true;
+    }
+    return code;
 }
 }
 
 
 void ircode_free (ircode_t *code) {
 void ircode_free (ircode_t *code) {
-	uint32_t count = ircode_count(code);
-	for (uint32_t i=0; i<count; ++i) {
-		inst_t *inst = marray_get(*code->list, i);
-		mem_free(inst);
-	}
+    uint32_t count = ircode_count(code);
+    for (uint32_t i=0; i<count; ++i) {
+        inst_t *inst = marray_get(*code->list, i);
+        mem_free(inst);
+    }
 
 
-	marray_destroy(*code->list);
+    marray_destroy(*code->list);
     marray_destroy(code->context);
     marray_destroy(code->context);
-	marray_destroy(code->registers);
-	marray_destroy(code->label_true);
-	marray_destroy(code->label_false);
-	mem_free(code->list);
-	mem_free(code);
+    marray_destroy(code->registers);
+    marray_destroy(code->label_true);
+    marray_destroy(code->label_false);
+    mem_free(code->list);
+    mem_free(code);
 }
 }
 
 
 uint32_t ircode_ntemps (ircode_t *code) {
 uint32_t ircode_ntemps (ircode_t *code) {
-	return code->ntemps;
+    return code->ntemps;
 }
 }
 
 
 uint32_t ircode_count (ircode_t *code) {
 uint32_t ircode_count (ircode_t *code) {
-	return (uint32_t)marray_size(*code->list);
+    return (uint32_t)marray_size(*code->list);
 }
 }
 
 
 inst_t *ircode_get (ircode_t *code, uint32_t index) {
 inst_t *ircode_get (ircode_t *code, uint32_t index) {
-	uint32_t n = (uint32_t)marray_size(*code->list);
-	return (index >= n) ? NULL : marray_get(*code->list, index);
+    uint32_t n = (uint32_t)marray_size(*code->list);
+    return (index >= n) ? NULL : marray_get(*code->list, index);
 }
 }
 
 
 bool ircode_iserror (ircode_t *code) {
 bool ircode_iserror (ircode_t *code) {
-	return code->error;
+    return code->error;
 }
 }
 // MARK: -
 // MARK: -
 
 
 static inst_t *inst_new (opcode_t op, uint32_t p1, uint32_t p2, uint32_t p3, optag_t tag, int64_t n, double d) {
 static inst_t *inst_new (opcode_t op, uint32_t p1, uint32_t p2, uint32_t p3, optag_t tag, int64_t n, double d) {
 
 
-	// debug code
-	#if GRAVITY_OPCODE_DEBUG
-	if (tag == LABEL_TAG) {
-		DEBUG_OPCODE("LABEL %d", p1);
-	} else if (tag != PRAGMA_MOVE_OPTIMIZATION){
-		const char *op_name = opcode_name(op);
-
-		if (op == LOADI) {
-			if (tag == DOUBLE_TAG)
-				printf("%s %d %.2f\n", op_name, p1, d);
-			else
-				printf("%s %d %lld\n", op_name, p1, n);
-		} else {
-			int nop = opcode_numop(op);
-			if (nop == 0) {
-				DEBUG_OPCODE("%s", op_name);
-			} else if (nop == 1) {
-				DEBUG_OPCODE("%s %d", op_name, p1);
-			} else if (nop == 2) {
-				DEBUG_OPCODE("%s %d %d", op_name, p1, p2);
-			} else if (nop == 3) {
-				DEBUG_OPCODE("%s %d %d %d", opcode_name(op), p1, p2, p3);
-			}
-		}
-	}
-	#endif
-
-	inst_t *inst = (inst_t *)mem_alloc(NULL, sizeof(inst_t));
-	inst->op = op;
-	inst->tag = tag;
-	inst->p1 = p1;
-	inst->p2 = p2;
-	inst->p3 = p3;
-
-	if (tag == DOUBLE_TAG) inst->d = d;
-	else if (tag == INT_TAG) inst->n = n;
-
-	assert(inst);
-	return inst;
+    // debug code
+    #if GRAVITY_OPCODE_DEBUG
+    if (tag == LABEL_TAG) {
+        DEBUG_OPCODE("LABEL %d", p1);
+    } else if (tag != PRAGMA_MOVE_OPTIMIZATION){
+        const char *op_name = opcode_name(op);
+
+        if (op == LOADI) {
+            if (tag == DOUBLE_TAG)
+                printf("%s %d %.2f\n", op_name, p1, d);
+            else
+                printf("%s %d %lld\n", op_name, p1, n);
+        } else {
+            int nop = opcode_numop(op);
+            if (nop == 0) {
+                DEBUG_OPCODE("%s", op_name);
+            } else if (nop == 1) {
+                DEBUG_OPCODE("%s %d", op_name, p1);
+            } else if (nop == 2) {
+                DEBUG_OPCODE("%s %d %d", op_name, p1, p2);
+            } else if (nop == 3) {
+                DEBUG_OPCODE("%s %d %d %d", opcode_name(op), p1, p2, p3);
+            }
+        }
+    }
+    #endif
+
+    inst_t *inst = (inst_t *)mem_alloc(NULL, sizeof(inst_t));
+    inst->op = op;
+    inst->tag = tag;
+    inst->p1 = p1;
+    inst->p2 = p2;
+    inst->p3 = p3;
+
+    if (tag == DOUBLE_TAG) inst->d = d;
+    else if (tag == INT_TAG) inst->n = n;
+
+    assert(inst);
+    return inst;
 }
 }
 
 
 void inst_setskip (inst_t *inst) {
 void inst_setskip (inst_t *inst) {
-	inst->tag = SKIP_TAG;
+    inst->tag = SKIP_TAG;
 }
 }
 
 
 void ircode_patch_init (ircode_t *code, uint16_t index) {
 void ircode_patch_init (ircode_t *code, uint16_t index) {
-	// prepend call instructions to code
-	// LOADK temp index
-	// LOAD  temp 0 temp
-	// MOVE  temp+1 0
-	// CALL  temp temp 1
-
-	// load constant
-	uint32_t dest = ircode_register_push_temp(code);
-	inst_t *inst1 = inst_new(LOADK, dest, index, 0, NO_TAG, 0, 0.0);
-
-	// load from lookup
-	inst_t *inst2 = inst_new(LOAD, dest, 0, dest, NO_TAG, 0, 0.0);
-
-	// prepare parameter
-	uint32_t dest2 = ircode_register_push_temp(code);
-	inst_t *inst3 = inst_new(MOVE, dest2, 0, 0, NO_TAG, 0, 0.0);
-	ircode_register_pop(code);
-
-	// execute call
-	inst_t *inst4 = inst_new(CALL, dest, dest, 1, NO_TAG, 0, 0.0);
-
-	// pop temps used
-	ircode_register_pop(code);
-
-	// create new instruction list
-	code_r		*list = mem_alloc(NULL, sizeof(code_r));
-	marray_init(*list);
-
-	// add newly create instructions
-	marray_push(inst_t*, *list, inst1);
-	marray_push(inst_t*, *list, inst2);
-	marray_push(inst_t*, *list, inst3);
-	marray_push(inst_t*, *list, inst4);
-
-	// then copy original instructions
-	code_r *orig_list = code->list;
-	uint32_t count = ircode_count(code);
-	for (uint32_t i=0; i<count; ++i) {
-		inst_t *inst = marray_get(*orig_list, i);
-		marray_push(inst_t*, *list, inst);
-	}
+    // prepend call instructions to code
+    // LOADK temp index
+    // LOAD  temp 0 temp
+    // MOVE  temp+1 0
+    // CALL  temp temp 1
+
+    // load constant
+    uint32_t dest = ircode_register_push_temp(code);
+    inst_t *inst1 = inst_new(LOADK, dest, index, 0, NO_TAG, 0, 0.0);
+
+    // load from lookup
+    inst_t *inst2 = inst_new(LOAD, dest, 0, dest, NO_TAG, 0, 0.0);
+
+    // prepare parameter
+    uint32_t dest2 = ircode_register_push_temp(code);
+    inst_t *inst3 = inst_new(MOVE, dest2, 0, 0, NO_TAG, 0, 0.0);
+    ircode_register_pop(code);
+
+    // execute call
+    inst_t *inst4 = inst_new(CALL, dest, dest, 1, NO_TAG, 0, 0.0);
+
+    // pop temps used
+    ircode_register_pop(code);
+
+    // create new instruction list
+    code_r        *list = mem_alloc(NULL, sizeof(code_r));
+    marray_init(*list);
+
+    // add newly create instructions
+    marray_push(inst_t*, *list, inst1);
+    marray_push(inst_t*, *list, inst2);
+    marray_push(inst_t*, *list, inst3);
+    marray_push(inst_t*, *list, inst4);
+
+    // then copy original instructions
+    code_r *orig_list = code->list;
+    uint32_t count = ircode_count(code);
+    for (uint32_t i=0; i<count; ++i) {
+        inst_t *inst = marray_get(*orig_list, i);
+        marray_push(inst_t*, *list, inst);
+    }
 
 
-	// free dest list
-	marray_destroy(*orig_list);
-	mem_free(code->list);
+    // free dest list
+    marray_destroy(*orig_list);
+    mem_free(code->list);
 
 
-	// replace dest list with the newly created list
-	code->list = list;
+    // replace dest list with the newly created list
+    code->list = list;
 }
 }
 
 
 uint8_t opcode_numop (opcode_t op) {
 uint8_t opcode_numop (opcode_t op) {
-	switch (op) {
-		case HALT: return 0;
-		case NOP: return 0;
-		case RET0: return 0;
-		case RET: return 1;
-		case CALL: return 3;
-		case SETLIST: return 3;
-		case LOADK: return 2;
-		case LOADG: return 2;
-		case LOADI: return 2;
-		case LOADAT: return 3;
-		case LOADS: return 3;
-		case LOAD: return 3;
-		case LOADU: return 2;
-		case MOVE: return 2;
-		case STOREG: return 2;
-		case STOREAT: return 3;
-		case STORE: return 3;
-		case STOREU: return 2;
-		case JUMP: return 1;
-		case JUMPF: return 2;
-		case SWITCH: return 1;
-		case ADD: return 3;
-		case SUB: return 3;
-		case DIV: return 3;
-		case MUL: return 3;
-		case REM: return 3;
-		case AND: return 3;
-		case OR: return 3;
-		case LT: return 3;
-		case GT: return 3;
-		case EQ: return 3;
-		case ISA: return 3;
-		case MATCH: return 3;
-		case EQQ: return 3;
-		case LEQ: return 3;
-		case GEQ: return 3;
-		case NEQ: return 3;
-		case NEQQ: return 3;
-		case NEG: return 2;
-		case NOT: return 2;
-		case LSHIFT: return 3;
-		case RSHIFT: return 3;
-		case BAND: return 3;
-		case BOR: return 3;
-		case BXOR: return 3;
-		case BNOT: return 2;
-		case MAPNEW: return 2;
-		case LISTNEW: return 2;
-		case RANGENEW: return 3;
-		case CLOSURE: return 2;
-		case CLOSE: return 1;
-		case RESERVED1:
-		case RESERVED2:
-		case RESERVED3:
-		case RESERVED4:
-		case RESERVED5:
-		case RESERVED6: return 0;
-	}
-
-	assert(0);
-	return 0;
+    switch (op) {
+        case HALT: return 0;
+        case NOP: return 0;
+        case RET0: return 0;
+        case RET: return 1;
+        case CALL: return 3;
+        case SETLIST: return 3;
+        case LOADK: return 2;
+        case LOADG: return 2;
+        case LOADI: return 2;
+        case LOADAT: return 3;
+        case LOADS: return 3;
+        case LOAD: return 3;
+        case LOADU: return 2;
+        case MOVE: return 2;
+        case STOREG: return 2;
+        case STOREAT: return 3;
+        case STORE: return 3;
+        case STOREU: return 2;
+        case JUMP: return 1;
+        case JUMPF: return 2;
+        case SWITCH: return 1;
+        case ADD: return 3;
+        case SUB: return 3;
+        case DIV: return 3;
+        case MUL: return 3;
+        case REM: return 3;
+        case AND: return 3;
+        case OR: return 3;
+        case LT: return 3;
+        case GT: return 3;
+        case EQ: return 3;
+        case ISA: return 3;
+        case MATCH: return 3;
+        case EQQ: return 3;
+        case LEQ: return 3;
+        case GEQ: return 3;
+        case NEQ: return 3;
+        case NEQQ: return 3;
+        case NEG: return 2;
+        case NOT: return 2;
+        case LSHIFT: return 3;
+        case RSHIFT: return 3;
+        case BAND: return 3;
+        case BOR: return 3;
+        case BXOR: return 3;
+        case BNOT: return 2;
+        case MAPNEW: return 2;
+        case LISTNEW: return 2;
+        case RANGENEW: return 3;
+        case CLOSURE: return 2;
+        case CLOSE: return 1;
+        case RESERVED1:
+        case RESERVED2:
+        case RESERVED3:
+        case RESERVED4:
+        case RESERVED5:
+        case RESERVED6: return 0;
+    }
+
+    assert(0);
+    return 0;
 }
 }
 
 
 void ircode_dump  (void *_code) {
 void ircode_dump  (void *_code) {
-	ircode_t	*code = (ircode_t *)_code;
-	code_r		*list = code->list;
-	uint32_t	count = ircode_count(code);
-
-	if (count == 0) {
-		printf("NONE\n");
-		return;
-	}
-
-	for (uint32_t i=0, line=0; i<count; ++i) {
-		inst_t *inst = marray_get(*list, i);
-		opcode_t	op = inst->op;
-		int32_t		p1 = inst->p1;
-		int32_t		p2 = inst->p2;
-		int32_t		p3 = inst->p3;
-		if (inst->tag == SKIP_TAG) continue;
-		if (inst->tag == PRAGMA_MOVE_OPTIMIZATION) continue;
-		if (inst->tag == LABEL_TAG) {printf("LABEL %d:\n", p1); continue;}
-
-		uint8_t n = opcode_numop(op);
-		if ((op == SETLIST) && (p2 == 0)) n = 2;
-
-		switch (n) {
-			case 0: {
-				printf("%05d\t%s\n", line, opcode_name(op));
-			}
-
-			case 1: {
-				printf("%05d\t%s %d\n", line, opcode_name(op), p1);
-			} break;
-
-			case 2: {
-				if (op == LOADI) {
-					if (inst->tag == DOUBLE_TAG) printf("%05d\t%s %d %.2f\n", line, opcode_name(op), p1, inst->d);
-					#if defined(_WIN32)
-					else printf("%05d\t%s %d %I64d\n", line, opcode_name(op), p1, inst->n);
-					#else
-					else printf("%05d\t%s %d %"PRId64"\n", line, opcode_name(op), p1, inst->n);
-					#endif
-				} else if (op == LOADK) {
-					if (p2 < CPOOL_INDEX_MAX) printf("%05d\t%s %d %d\n", line, opcode_name(op), p1, p2);
-					else printf("%05d\t%s %d %s\n", line, opcode_name(op), p1, opcode_constname(p2));
-				} else {
-					printf("%05d\t%s %d %d\n", line, opcode_name(op), p1, p2);
-				}
-			} break;
-
-			case 3: {
-				printf("%05d\t%s %d %d %d\n", line, opcode_name(op), p1, p2, p3);
-			} break;
-
-			default: assert(0);
-		}
-		++line;
-	}
+    ircode_t    *code = (ircode_t *)_code;
+    code_r        *list = code->list;
+    uint32_t    count = ircode_count(code);
+
+    if (count == 0) {
+        printf("NONE\n");
+        return;
+    }
+
+    for (uint32_t i=0, line=0; i<count; ++i) {
+        inst_t *inst = marray_get(*list, i);
+        opcode_t    op = inst->op;
+        int32_t        p1 = inst->p1;
+        int32_t        p2 = inst->p2;
+        int32_t        p3 = inst->p3;
+        if (inst->tag == SKIP_TAG) continue;
+        if (inst->tag == PRAGMA_MOVE_OPTIMIZATION) continue;
+        if (inst->tag == LABEL_TAG) {printf("LABEL %d:\n", p1); continue;}
+
+        uint8_t n = opcode_numop(op);
+        if ((op == SETLIST) && (p2 == 0)) n = 2;
+
+        switch (n) {
+            case 0: {
+                printf("%05d\t%s\n", line, opcode_name(op));
+            }
+
+            case 1: {
+                printf("%05d\t%s %d\n", line, opcode_name(op), p1);
+            } break;
+
+            case 2: {
+                if (op == LOADI) {
+                    if (inst->tag == DOUBLE_TAG) printf("%05d\t%s %d %.2f\n", line, opcode_name(op), p1, inst->d);
+                    #if defined(_WIN32)
+                    else printf("%05d\t%s %d %I64d\n", line, opcode_name(op), p1, inst->n);
+                    #else
+                    else printf("%05d\t%s %d %"PRId64"\n", line, opcode_name(op), p1, inst->n);
+                    #endif
+                } else if (op == LOADK) {
+                    if (p2 < CPOOL_INDEX_MAX) printf("%05d\t%s %d %d\n", line, opcode_name(op), p1, p2);
+                    else printf("%05d\t%s %d %s\n", line, opcode_name(op), p1, opcode_constname(p2));
+                } else {
+                    printf("%05d\t%s %d %d\n", line, opcode_name(op), p1, p2);
+                }
+            } break;
+
+            case 3: {
+                printf("%05d\t%s %d %d %d\n", line, opcode_name(op), p1, p2, p3);
+            } break;
+
+            default: assert(0);
+        }
+        ++line;
+    }
 }
 }
 
 
 // MARK: -
 // MARK: -
 
 
 uint32_t ircode_newlabel (ircode_t *code) {
 uint32_t ircode_newlabel (ircode_t *code) {
-	return ++code->label_counter;
+    return ++code->label_counter;
 }
 }
 
 
 void ircode_setlabel_true (ircode_t *code, uint32_t nlabel) {
 void ircode_setlabel_true (ircode_t *code, uint32_t nlabel) {
-	marray_push(uint32_t, code->label_true, nlabel);
+    marray_push(uint32_t, code->label_true, nlabel);
 }
 }
 
 
 void ircode_setlabel_false (ircode_t *code, uint32_t nlabel) {
 void ircode_setlabel_false (ircode_t *code, uint32_t nlabel) {
-	marray_push(uint32_t, code->label_false, nlabel);
+    marray_push(uint32_t, code->label_false, nlabel);
 }
 }
 
 
 void ircode_unsetlabel_true (ircode_t *code) {
 void ircode_unsetlabel_true (ircode_t *code) {
-	marray_pop(code->label_true);
+    marray_pop(code->label_true);
 }
 }
 
 
 void ircode_unsetlabel_false (ircode_t *code) {
 void ircode_unsetlabel_false (ircode_t *code) {
-	marray_pop(code->label_false);
+    marray_pop(code->label_false);
 }
 }
 
 
 uint32_t ircode_getlabel_true (ircode_t *code) {
 uint32_t ircode_getlabel_true (ircode_t *code) {
-	size_t n = marray_size(code->label_true);
-	uint32_t v = marray_get(code->label_true, n-1);
-	return v;
+    size_t n = marray_size(code->label_true);
+    uint32_t v = marray_get(code->label_true, n-1);
+    return v;
 }
 }
 
 
 uint32_t ircode_getlabel_false (ircode_t *code) {
 uint32_t ircode_getlabel_false (ircode_t *code) {
-	size_t n = marray_size(code->label_false);
-	uint32_t v = marray_get(code->label_false, n-1);
-	return v;
+    size_t n = marray_size(code->label_false);
+    uint32_t v = marray_get(code->label_false, n-1);
+    return v;
 }
 }
 
 
 void ircode_marklabel (ircode_t *code, uint32_t nlabel) {
 void ircode_marklabel (ircode_t *code, uint32_t nlabel) {
-	inst_t *inst = inst_new(0, nlabel, 0, 0, LABEL_TAG, 0, 0.0);
-	marray_push(inst_t*, *code->list, inst);
+    inst_t *inst = inst_new(0, nlabel, 0, 0, LABEL_TAG, 0, 0.0);
+    marray_push(inst_t*, *code->list, inst);
 }
 }
 
 
 // MARK: -
 // MARK: -
 void ircode_pragma (ircode_t *code, optag_t tag, uint32_t value) {
 void ircode_pragma (ircode_t *code, optag_t tag, uint32_t value) {
-	ircode_add_tag(code, 0, value, 0, 0, tag);
+    ircode_add_tag(code, 0, value, 0, 0, tag);
 }
 }
 
 
 // MARK: -
 // MARK: -
 
 
 void ircode_set_index (uint32_t index, ircode_t *code, opcode_t op, uint32_t p1, uint32_t p2, uint32_t p3) {
 void ircode_set_index (uint32_t index, ircode_t *code, opcode_t op, uint32_t p1, uint32_t p2, uint32_t p3) {
-	inst_t *inst = marray_get(*code->list, index);
-	inst->op = op;
-	inst->p1 = p1;
-	inst->p2 = p2;
-	inst->p3 = p3;
-	inst->tag = NO_TAG;
+    inst_t *inst = marray_get(*code->list, index);
+    inst->op = op;
+    inst->p1 = p1;
+    inst->p2 = p2;
+    inst->p3 = p3;
+    inst->tag = NO_TAG;
 }
 }
 
 
 void ircode_add (ircode_t *code, opcode_t op, uint32_t p1, uint32_t p2, uint32_t p3) {
 void ircode_add (ircode_t *code, opcode_t op, uint32_t p1, uint32_t p2, uint32_t p3) {
-	ircode_add_tag(code, op, p1, p2, p3, 0);
+    ircode_add_tag(code, op, p1, p2, p3, 0);
 }
 }
 
 
 void ircode_add_tag (ircode_t *code, opcode_t op, uint32_t p1, uint32_t p2, uint32_t p3, optag_t tag) {
 void ircode_add_tag (ircode_t *code, opcode_t op, uint32_t p1, uint32_t p2, uint32_t p3, optag_t tag) {
-	inst_t *inst = inst_new(op, p1, p2, p3, tag, 0, 0.0);
-	marray_push(inst_t*, *code->list, inst);
+    inst_t *inst = inst_new(op, p1, p2, p3, tag, 0, 0.0);
+    marray_push(inst_t*, *code->list, inst);
 }
 }
 
 
 void ircode_add_double (ircode_t *code, double d) {
 void ircode_add_double (ircode_t *code, double d) {
-	uint32_t regnum = ircode_register_push_temp(code);
-	inst_t *inst = inst_new(LOADI, regnum, 0, 0, DOUBLE_TAG, 0, d);
-	marray_push(inst_t*, *code->list, inst);
+    uint32_t regnum = ircode_register_push_temp(code);
+    inst_t *inst = inst_new(LOADI, regnum, 0, 0, DOUBLE_TAG, 0, d);
+    marray_push(inst_t*, *code->list, inst);
 }
 }
 
 
 void ircode_add_constant (ircode_t *code, uint32_t index) {
 void ircode_add_constant (ircode_t *code, uint32_t index) {
-	uint32_t regnum = ircode_register_push_temp(code);
-	inst_t *inst = inst_new(LOADK, regnum, index, 0, NO_TAG, 0, 0);
-	marray_push(inst_t*, *code->list, inst);
+    uint32_t regnum = ircode_register_push_temp(code);
+    inst_t *inst = inst_new(LOADK, regnum, index, 0, NO_TAG, 0, 0);
+    marray_push(inst_t*, *code->list, inst);
 }
 }
 
 
 void ircode_add_int (ircode_t *code, int64_t n) {
 void ircode_add_int (ircode_t *code, int64_t n) {
-	uint32_t regnum = ircode_register_push_temp(code);
-	inst_t *inst = inst_new(LOADI, regnum, 0, 0, INT_TAG, n, 0);
-	marray_push(inst_t*, *code->list, inst);
+    uint32_t regnum = ircode_register_push_temp(code);
+    inst_t *inst = inst_new(LOADI, regnum, 0, 0, INT_TAG, n, 0);
+    marray_push(inst_t*, *code->list, inst);
 }
 }
 
 
 void ircode_add_skip (ircode_t *code) {
 void ircode_add_skip (ircode_t *code) {
-	inst_t *inst = inst_new(0, 0, 0, 0, NO_TAG, 0, 0);
-	inst_setskip(inst);
-	marray_push(inst_t*, *code->list, inst);
+    inst_t *inst = inst_new(0, 0, 0, 0, NO_TAG, 0, 0);
+    inst_setskip(inst);
+    marray_push(inst_t*, *code->list, inst);
 }
 }
 
 
 // MARK: - Context based functions -
 // MARK: - Context based functions -
 
 
 #if 0
 #if 0
 static void dump_context(bool *context) {
 static void dump_context(bool *context) {
-	for (uint32_t i=0; i<MAX_REGISTERS; ++i) {
-		printf("%d ", context[i]);
-	}
-	printf("\n");
+    for (uint32_t i=0; i<MAX_REGISTERS; ++i) {
+        printf("%d ", context[i]);
+    }
+    printf("\n");
 }
 }
 #endif
 #endif
 
 
 void ircode_push_context (ircode_t *code) {
 void ircode_push_context (ircode_t *code) {
-	bool *context = mem_alloc(NULL, sizeof(bool) * MAX_REGISTERS);
-	marray_push(bool *, code->context, context);
+    bool *context = mem_alloc(NULL, sizeof(bool) * MAX_REGISTERS);
+    marray_push(bool *, code->context, context);
 }
 }
 
 
 void ircode_pop_context (ircode_t *code) {
 void ircode_pop_context (ircode_t *code) {
-	bool *context = marray_pop(code->context);
-	// apply context mask
-	for (uint32_t i=0; i<MAX_REGISTERS; ++i) {
-		if (context[i]) code->state[i] = false;
-	}
-	mem_free(context);
+    bool *context = marray_pop(code->context);
+    // apply context mask
+    for (uint32_t i=0; i<MAX_REGISTERS; ++i) {
+        if (context[i]) code->state[i] = false;
+    }
+    mem_free(context);
 }
 }
 
 
 uint32_t ircode_register_pop_context_protect (ircode_t *code, bool protect) {
 uint32_t ircode_register_pop_context_protect (ircode_t *code, bool protect) {
-	if (marray_size(code->registers) == 0) return REGISTER_ERROR;
-	uint32_t value = (uint32_t)marray_pop(code->registers);
+    if (marray_size(code->registers) == 0) return REGISTER_ERROR;
+    uint32_t value = (uint32_t)marray_pop(code->registers);
 
 
-	if (protect) code->state[value] = true;
-	else if (value >= code->nlocals) code->state[value] = false;
+    if (protect) code->state[value] = true;
+    else if (value >= code->nlocals) code->state[value] = false;
 
 
-	if (protect && value >= code->nlocals) {
-		bool *context = marray_last(code->context);
-		context[value] = true;
-	}
+    if (protect && value >= code->nlocals) {
+        bool *context = marray_last(code->context);
+        context[value] = true;
+    }
 
 
-	DEBUG_REGISTER("POP REGISTER %d", value);
-	return value;
+    DEBUG_REGISTER("POP REGISTER %d", value);
+    return value;
 }
 }
 
 
 bool ircode_register_protect_outside_context (ircode_t *code, uint32_t nreg) {
 bool ircode_register_protect_outside_context (ircode_t *code, uint32_t nreg) {
-	if (nreg < code->nlocals) return true;
+    if (nreg < code->nlocals) return true;
     if (!code->state[nreg]) return false;
     if (!code->state[nreg]) return false;
-	bool *context = marray_last(code->context);
-	context[nreg] = false;
+    bool *context = marray_last(code->context);
+    context[nreg] = false;
     return true;
     return true;
 }
 }
 
 
 void ircode_register_protect_in_context (ircode_t *code, uint32_t nreg) {
 void ircode_register_protect_in_context (ircode_t *code, uint32_t nreg) {
-	assert(code->state[nreg]);
-	bool *context = marray_last(code->context);
-	context[nreg] = true;
+    assert(code->state[nreg]);
+    bool *context = marray_last(code->context);
+    context[nreg] = true;
 }
 }
 
 
 // MARK: -
 // MARK: -
 
 
 static uint32_t ircode_register_new (ircode_t *code) {
 static uint32_t ircode_register_new (ircode_t *code) {
-	for (uint32_t i=0; i<MAX_REGISTERS; ++i) {
-		if (code->state[i] == false) {
-			code->state[i] = true;
-			return i;
-		}
-	}
-	// 0 means no registers available
-	code->error = true;
-	return 0;
+    for (uint32_t i=0; i<MAX_REGISTERS; ++i) {
+        if (code->state[i] == false) {
+            code->state[i] = true;
+            return i;
+        }
+    }
+    // 0 means no registers available
+    code->error = true;
+    return 0;
 }
 }
 
 
 uint32_t ircode_register_push (ircode_t *code, uint32_t nreg) {
 uint32_t ircode_register_push (ircode_t *code, uint32_t nreg) {
-	marray_push(uint32_t, code->registers, nreg);
-	if (ircode_register_istemp(code, nreg)) ++code->ntemps;
+    marray_push(uint32_t, code->registers, nreg);
+    if (ircode_register_istemp(code, nreg)) ++code->ntemps;
 
 
-	DEBUG_REGISTER("PUSH REGISTER %d", nreg);
-	return nreg;
+    DEBUG_REGISTER("PUSH REGISTER %d", nreg);
+    return nreg;
 }
 }
 
 
 uint32_t ircode_register_first_temp_available (ircode_t *code) {
 uint32_t ircode_register_first_temp_available (ircode_t *code) {
@@ -490,22 +490,22 @@ uint32_t ircode_register_first_temp_available (ircode_t *code) {
 }
 }
 
 
 uint32_t ircode_register_push_temp (ircode_t *code) {
 uint32_t ircode_register_push_temp (ircode_t *code) {
-	uint32_t value = ircode_register_new(code);
-	marray_push(uint32_t, code->registers, value);
-	if (value > code->maxtemp) {code->maxtemp = value; ++code->ntemps;}
+    uint32_t value = ircode_register_new(code);
+    marray_push(uint32_t, code->registers, value);
+    if (value > code->maxtemp) {code->maxtemp = value; ++code->ntemps;}
 
 
-	DEBUG_REGISTER("PUSH REGISTER %d", value);
-	return value;
+    DEBUG_REGISTER("PUSH REGISTER %d", value);
+    return value;
 }
 }
 
 
 uint32_t ircode_register_pop (ircode_t *code) {
 uint32_t ircode_register_pop (ircode_t *code) {
-	return ircode_register_pop_context_protect(code, false);
+    return ircode_register_pop_context_protect(code, false);
 }
 }
 
 
 void ircode_register_clear (ircode_t *code, uint32_t nreg) {
 void ircode_register_clear (ircode_t *code, uint32_t nreg) {
-	if (nreg == REGISTER_ERROR) return;
-	// cleanup busy mask only if it is a temp register
-	if (nreg >= code->nlocals) code->state[nreg] = false;
+    if (nreg == REGISTER_ERROR) return;
+    // cleanup busy mask only if it is a temp register
+    if (nreg >= code->nlocals) code->state[nreg] = false;
 }
 }
 
 
 void ircode_register_set (ircode_t *code, uint32_t nreg) {
 void ircode_register_set (ircode_t *code, uint32_t nreg) {
@@ -515,40 +515,40 @@ void ircode_register_set (ircode_t *code, uint32_t nreg) {
 }
 }
 
 
 uint32_t ircode_register_last (ircode_t *code) {
 uint32_t ircode_register_last (ircode_t *code) {
-	if (marray_size(code->registers) == 0) return REGISTER_ERROR;
-	return (uint32_t)marray_last(code->registers);
+    if (marray_size(code->registers) == 0) return REGISTER_ERROR;
+    return (uint32_t)marray_last(code->registers);
 }
 }
 
 
 bool ircode_register_istemp (ircode_t *code, uint32_t nreg) {
 bool ircode_register_istemp (ircode_t *code, uint32_t nreg) {
-	return (nreg >= (uint32_t)code->nlocals);
+    return (nreg >= (uint32_t)code->nlocals);
 }
 }
 
 
 void ircode_register_dump (ircode_t *code) {
 void ircode_register_dump (ircode_t *code) {
-	uint32_t n = (uint32_t)marray_size(code->registers);
-	if (n == 0) printf("EMPTY\n");
-	for (uint32_t i=0; i<n; ++i) {
-		uint32_t value = marray_get(code->registers, i);
-		printf("[%d]\t%d\n", i, value);
-	}
+    uint32_t n = (uint32_t)marray_size(code->registers);
+    if (n == 0) printf("EMPTY\n");
+    for (uint32_t i=0; i<n; ++i) {
+        uint32_t value = marray_get(code->registers, i);
+        printf("[%d]\t%d\n", i, value);
+    }
 }
 }
 
 
 uint32_t ircode_register_count (ircode_t *code) {
 uint32_t ircode_register_count (ircode_t *code) {
-	return (uint32_t)marray_size(code->registers);
+    return (uint32_t)marray_size(code->registers);
 }
 }
 
 
 // MARK: -
 // MARK: -
 
 
 void ircode_register_set_skip_clear (ircode_t *code, uint32_t nreg) {
 void ircode_register_set_skip_clear (ircode_t *code, uint32_t nreg) {
-	code->skipclear[nreg] = true;
+    code->skipclear[nreg] = true;
 }
 }
 
 
 void ircode_register_unset_skip_clear (ircode_t *code, uint32_t nreg) {
 void ircode_register_unset_skip_clear (ircode_t *code, uint32_t nreg) {
-	code->skipclear[nreg] = false;
+    code->skipclear[nreg] = false;
 }
 }
 
 
 void ircode_register_clear_temps (ircode_t *code) {
 void ircode_register_clear_temps (ircode_t *code) {
-	// clear all temporary registers (if not protected)
-	for (uint32_t i=code->nlocals; i<=code->maxtemp; ++i) {
-		if (!code->skipclear[i]) code->state[i] = false;
-	}
+    // clear all temporary registers (if not protected)
+    for (uint32_t i=code->nlocals; i<=code->maxtemp; ++i) {
+        if (!code->skipclear[i]) code->state[i] = false;
+    }
 }
 }

+ 62 - 62
src/compiler/gravity_ircode.h

@@ -27,66 +27,66 @@
 #include "gravity_opcodes.h"
 #include "gravity_opcodes.h"
 #include "gravity_array.h"
 #include "gravity_array.h"
 
 
-#define REGISTER_ERROR	UINT32_MAX
+#define REGISTER_ERROR    UINT32_MAX
 
 
 typedef enum {
 typedef enum {
-		NO_TAG = 0,
-		INT_TAG,
-		DOUBLE_TAG,
-		LABEL_TAG,
-		SKIP_TAG,
-		RANGE_INCLUDE_TAG,
-		RANGE_EXCLUDE_TAG,
-		PRAGMA_MOVE_OPTIMIZATION
+        NO_TAG = 0,
+        INT_TAG,
+        DOUBLE_TAG,
+        LABEL_TAG,
+        SKIP_TAG,
+        RANGE_INCLUDE_TAG,
+        RANGE_EXCLUDE_TAG,
+        PRAGMA_MOVE_OPTIMIZATION
 } optag_t;
 } optag_t;
 
 
 typedef struct {
 typedef struct {
-	opcode_t	op;
-	optag_t		tag;
-	int32_t		p1;
-	int32_t		p2;
-	int32_t		p3;
-	union {
-		double		d;		//	tag is DOUBLE_TAG
-		int64_t		n;		//	tag is INT_TAG
-	};
+    opcode_t    op;
+    optag_t     tag;
+    int32_t     p1;
+    int32_t     p2;
+    int32_t     p3;
+    union {
+        double      d;  //    tag is DOUBLE_TAG
+        int64_t     n;  //    tag is INT_TAG
+    };
 } inst_t;
 } inst_t;
 
 
 typedef struct ircode_t ircode_t;
 typedef struct ircode_t ircode_t;
 
 
-ircode_t	*ircode_create (uint16_t nlocals);
-void		ircode_free (ircode_t *code);
-uint32_t	ircode_count (ircode_t *code);
-uint32_t	ircode_ntemps (ircode_t *code);
-inst_t		*ircode_get (ircode_t *code, uint32_t index);
-void		ircode_dump (void *code);
-void		ircode_push_context (ircode_t *code);
-void		ircode_pop_context (ircode_t *code);
-bool		ircode_iserror (ircode_t *code);
-void		ircode_patch_init (ircode_t *code, uint16_t index);
+ircode_t    *ircode_create (uint16_t nlocals);
+void        ircode_free (ircode_t *code);
+uint32_t    ircode_count (ircode_t *code);
+uint32_t    ircode_ntemps (ircode_t *code);
+inst_t      *ircode_get (ircode_t *code, uint32_t index);
+void        ircode_dump (void *code);
+void        ircode_push_context (ircode_t *code);
+void        ircode_pop_context (ircode_t *code);
+bool        ircode_iserror (ircode_t *code);
+void        ircode_patch_init (ircode_t *code, uint16_t index);
 
 
-uint32_t	ircode_newlabel (ircode_t *code);
-void		ircode_setlabel_true (ircode_t *code, uint32_t nlabel);
-void		ircode_setlabel_false (ircode_t *code, uint32_t nlabel);
-void		ircode_unsetlabel_true (ircode_t *code);
-void		ircode_unsetlabel_false (ircode_t *code);
-uint32_t	ircode_getlabel_true (ircode_t *code);
-uint32_t	ircode_getlabel_false (ircode_t *code);
-void		ircode_marklabel (ircode_t *code, uint32_t nlabel);
+uint32_t    ircode_newlabel (ircode_t *code);
+void        ircode_setlabel_true (ircode_t *code, uint32_t nlabel);
+void        ircode_setlabel_false (ircode_t *code, uint32_t nlabel);
+void        ircode_unsetlabel_true (ircode_t *code);
+void        ircode_unsetlabel_false (ircode_t *code);
+uint32_t    ircode_getlabel_true (ircode_t *code);
+uint32_t    ircode_getlabel_false (ircode_t *code);
+void        ircode_marklabel (ircode_t *code, uint32_t nlabel);
 
 
-void		inst_setskip (inst_t *inst);
-uint8_t		opcode_numop (opcode_t op);
+void        inst_setskip (inst_t *inst);
+uint8_t     opcode_numop (opcode_t op);
 
 
-void		ircode_pragma (ircode_t *code, optag_t tag, uint32_t value);
-void		ircode_add (ircode_t *code, opcode_t op, uint32_t p1, uint32_t p2, uint32_t p3);
-void		ircode_add_tag (ircode_t *code, opcode_t op, uint32_t p1, uint32_t p2, uint32_t p3, optag_t tag);
-void		ircode_add_array (ircode_t *code, opcode_t op, uint32_t p1, uint32_t p2, uint32_t p3, uint32_r r);
-void		ircode_add_double (ircode_t *code, double d);
-void		ircode_add_int (ircode_t *code, int64_t n);
-void		ircode_add_constant (ircode_t *code, uint32_t index);
-void		ircode_add_skip (ircode_t *code);
-void		ircode_set_index (uint32_t index, ircode_t *code, opcode_t op, uint32_t p1, uint32_t p2, uint32_t p3);
-void		ircode_setarray_index (uint32_t index, ircode_t *code, opcode_t op, uint32_t p1, uint32_t p2, uint32_t p3, uint32_r r);
+void        ircode_pragma (ircode_t *code, optag_t tag, uint32_t value);
+void        ircode_add (ircode_t *code, opcode_t op, uint32_t p1, uint32_t p2, uint32_t p3);
+void        ircode_add_tag (ircode_t *code, opcode_t op, uint32_t p1, uint32_t p2, uint32_t p3, optag_t tag);
+void        ircode_add_array (ircode_t *code, opcode_t op, uint32_t p1, uint32_t p2, uint32_t p3, uint32_r r);
+void        ircode_add_double (ircode_t *code, double d);
+void        ircode_add_int (ircode_t *code, int64_t n);
+void        ircode_add_constant (ircode_t *code, uint32_t index);
+void        ircode_add_skip (ircode_t *code);
+void        ircode_set_index (uint32_t index, ircode_t *code, opcode_t op, uint32_t p1, uint32_t p2, uint32_t p3);
+void        ircode_setarray_index (uint32_t index, ircode_t *code, opcode_t op, uint32_t p1, uint32_t p2, uint32_t p3, uint32_r r);
 
 
 // IMPORTANT NOTE
 // IMPORTANT NOTE
 //
 //
@@ -99,22 +99,22 @@ void		ircode_setarray_index (uint32_t index, ircode_t *code, opcode_t op, uint32
 // ircode_register_push_temp
 // ircode_register_push_temp
 //
 //
 
 
-bool		ircode_register_istemp (ircode_t *code, uint32_t n);
-uint32_t	ircode_register_push_temp (ircode_t *code);
-uint32_t	ircode_register_push (ircode_t *code, uint32_t nreg);
-uint32_t	ircode_register_pop (ircode_t *code);
+bool        ircode_register_istemp (ircode_t *code, uint32_t n);
+uint32_t    ircode_register_push_temp (ircode_t *code);
+uint32_t    ircode_register_push (ircode_t *code, uint32_t nreg);
+uint32_t    ircode_register_pop (ircode_t *code);
 uint32_t    ircode_register_first_temp_available (ircode_t *code);
 uint32_t    ircode_register_first_temp_available (ircode_t *code);
-uint32_t	ircode_register_pop_context_protect (ircode_t *code, bool protect);
-bool		ircode_register_protect_outside_context (ircode_t *code, uint32_t nreg);
-void		ircode_register_protect_in_context (ircode_t *code, uint32_t nreg);
-uint32_t	ircode_register_last (ircode_t *code);
-uint32_t	ircode_register_count (ircode_t *code);
-void		ircode_register_clear (ircode_t *code, uint32_t nreg);
+uint32_t    ircode_register_pop_context_protect (ircode_t *code, bool protect);
+bool        ircode_register_protect_outside_context (ircode_t *code, uint32_t nreg);
+void        ircode_register_protect_in_context (ircode_t *code, uint32_t nreg);
+uint32_t    ircode_register_last (ircode_t *code);
+uint32_t    ircode_register_count (ircode_t *code);
+void        ircode_register_clear (ircode_t *code, uint32_t nreg);
 void        ircode_register_set (ircode_t *code, uint32_t nreg);
 void        ircode_register_set (ircode_t *code, uint32_t nreg);
-void		ircode_register_dump (ircode_t *code);
+void        ircode_register_dump (ircode_t *code);
 
 
-void		ircode_register_set_skip_clear (ircode_t *code, uint32_t nreg);
-void		ircode_register_unset_skip_clear (ircode_t *code, uint32_t nreg);
-void		ircode_register_clear_temps (ircode_t *code);
+void        ircode_register_set_skip_clear (ircode_t *code, uint32_t nreg);
+void        ircode_register_unset_skip_clear (ircode_t *code, uint32_t nreg);
+void        ircode_register_clear_temps (ircode_t *code);
 
 
 #endif
 #endif

+ 446 - 446
src/compiler/gravity_lexer.c

@@ -13,641 +13,641 @@
 #include "gravity_utils.h"
 #include "gravity_utils.h"
 
 
 struct gravity_lexer_t {
 struct gravity_lexer_t {
-	const char					*buffer;		// buffer
-	uint32_t					offset;			// current buffer offset (in bytes)
-	uint32_t					position;		// current buffer position (in characters)
-	uint32_t					length;			// buffer length (in bytes)
-	uint32_t					lineno;			// line counter
-	uint32_t					colno;			// column counter
-	uint32_t					fileid;			// current file id
-
-	gtoken_s					token;			// current token
-	bool						peeking;		// flag to check if a peek operation is in progress
-	bool						is_static;		// flag to check if buffer is static and must not be freed
-	gravity_delegate_t			*delegate;		// delegate (if any)
+    const char                  *buffer;        // buffer
+    uint32_t                    offset;         // current buffer offset (in bytes)
+    uint32_t                    position;       // current buffer position (in characters)
+    uint32_t                    length;         // buffer length (in bytes)
+    uint32_t                    lineno;         // line counter
+    uint32_t                    colno;          // column counter
+    uint32_t                    fileid;         // current file id
+
+    gtoken_s                    token;          // current token
+    bool                        peeking;        // flag to check if a peek operation is in progress
+    bool                        is_static;      // flag to check if buffer is static and must not be freed
+    gravity_delegate_t          *delegate;      // delegate (if any)
     
     
     gtoken_t                    cache;
     gtoken_t                    cache;
 };
 };
 
 
 typedef enum {
 typedef enum {
-	NUMBER_INTEGER,
-	NUMBER_HEX,
-	NUMBER_BIN,
-	NUMBER_OCT
+    NUMBER_INTEGER,
+    NUMBER_HEX,
+    NUMBER_BIN,
+    NUMBER_OCT
 } gravity_number_type;
 } gravity_number_type;
 
 
 
 
 // LEXER macros
 // LEXER macros
-#define NEXT					lexer->buffer[lexer->offset++]; ++lexer->position; INC_COL
-#define PEEK_CURRENT			lexer->buffer[lexer->offset]
-#define PEEK_NEXT				((lexer->offset < lexer->length) ? lexer->buffer[lexer->offset+1] : 0)
-#define PEEK_NEXT2				((lexer->offset+1 < lexer->length) ? lexer->buffer[lexer->offset+2] : 0)
-#define INC_LINE				++lexer->lineno; RESET_COL
-#define INC_COL					++lexer->colno
-#define DEC_COL					--lexer->colno
-#define RESET_COL				lexer->colno = 1
-#define IS_EOF					(lexer->offset >= lexer->length)
-#define DEC_OFFSET				--lexer->offset; DEC_COL
-#define DEC_POSITION			--lexer->position
-#define DEC_OFFSET_POSITION		DEC_OFFSET; DEC_POSITION
-#define INC_OFFSET				++lexer->offset; INC_COL
-#define INC_POSITION			++lexer->position
-#define INC_OFFSET_POSITION		INC_OFFSET; INC_POSITION
+#define NEXT                    lexer->buffer[lexer->offset++]; ++lexer->position; INC_COL
+#define PEEK_CURRENT            lexer->buffer[lexer->offset]
+#define PEEK_NEXT               ((lexer->offset < lexer->length) ? lexer->buffer[lexer->offset+1] : 0)
+#define PEEK_NEXT2              ((lexer->offset+1 < lexer->length) ? lexer->buffer[lexer->offset+2] : 0)
+#define INC_LINE                ++lexer->lineno; RESET_COL
+#define INC_COL                 ++lexer->colno
+#define DEC_COL                 --lexer->colno
+#define RESET_COL               lexer->colno = 1
+#define IS_EOF                  (lexer->offset >= lexer->length)
+#define DEC_OFFSET              --lexer->offset; DEC_COL
+#define DEC_POSITION            --lexer->position
+#define DEC_OFFSET_POSITION     DEC_OFFSET; DEC_POSITION
+#define INC_OFFSET              ++lexer->offset; INC_COL
+#define INC_POSITION            ++lexer->position
+#define INC_OFFSET_POSITION     INC_OFFSET; INC_POSITION
 
 
 // TOKEN macros
 // TOKEN macros
-#define TOKEN_RESET				lexer->token = NO_TOKEN; lexer->token.position = lexer->position; lexer->token.value = lexer->buffer + lexer->offset;	\
-								lexer->token.lineno = lexer->lineno; lexer->token.colno = lexer->colno; lexer->token.builtin = 0
-#define TOKEN_FINALIZE(t)		lexer->token.type = t; lexer->token.fileid = lexer->fileid
-#define INC_TOKBYTES			++lexer->token.bytes
-#define INC_TOKUTF8LEN			++lexer->token.length
-#define INC_TOKLEN				INC_TOKBYTES; INC_TOKUTF8LEN
-#define DEC_TOKLEN				--lexer->token.bytes; --lexer->token.length
-#define SET_TOKTYPE(t)			lexer->token.type = t
-
-#define LEXER_CALL_CALLBACK()	if ((!lexer->peeking) && (lexer->delegate) && (lexer->delegate->parser_callback)) {	\
-									lexer->delegate->parser_callback(&lexer->token, lexer->delegate->xdata); }
+#define TOKEN_RESET             lexer->token = NO_TOKEN; lexer->token.position = lexer->position; lexer->token.value = lexer->buffer + lexer->offset;    \
+                                lexer->token.lineno = lexer->lineno; lexer->token.colno = lexer->colno; lexer->token.builtin = 0
+#define TOKEN_FINALIZE(t)       lexer->token.type = t; lexer->token.fileid = lexer->fileid
+#define INC_TOKBYTES            ++lexer->token.bytes
+#define INC_TOKUTF8LEN          ++lexer->token.length
+#define INC_TOKLEN              INC_TOKBYTES; INC_TOKUTF8LEN
+#define DEC_TOKLEN              --lexer->token.bytes; --lexer->token.length
+#define SET_TOKTYPE(t)          lexer->token.type = t
+
+#define LEXER_CALL_CALLBACK()   if ((!lexer->peeking) && (lexer->delegate) && (lexer->delegate->parser_callback)) {    \
+                                lexer->delegate->parser_callback(&lexer->token, lexer->delegate->xdata); }
 
 
 // MARK: -
 // MARK: -
 
 
 static inline bool is_whitespace (int c) {
 static inline bool is_whitespace (int c) {
-	return ((c == ' ') || (c == '\t') || (c == '\v') || (c == '\f'));
+    return ((c == ' ') || (c == '\t') || (c == '\v') || (c == '\f'));
 }
 }
 
 
 static inline bool is_newline (gravity_lexer_t *lexer, int c) {
 static inline bool is_newline (gravity_lexer_t *lexer, int c) {
-	// CR: Carriage Return, U+000D (UTF-8 in hex: 0D)
-	// LF: Line Feed, U+000A (UTF-8 in hex: 0A)
-	// CR+LF: CR (U+000D) followed by LF (U+000A) (UTF-8 in hex: 0D0A)
+    // CR: Carriage Return, U+000D (UTF-8 in hex: 0D)
+    // LF: Line Feed, U+000A (UTF-8 in hex: 0A)
+    // CR+LF: CR (U+000D) followed by LF (U+000A) (UTF-8 in hex: 0D0A)
 
 
-	// LF
-	if (c == 0x0A) return true;
+    // LF
+    if (c == 0x0A) return true;
 
 
-	// CR+LF or CR
-	if (c == 0x0D) {
-		if (PEEK_NEXT == 0x0A) {NEXT; return true;}
-		return true;
-	}
+    // CR+LF or CR
+    if (c == 0x0D) {
+        if (PEEK_NEXT == 0x0A) {NEXT; return true;}
+        return true;
+    }
 
 
-	// UTF-8 cases https://en.wikipedia.org/wiki/Newline#Unicode
+    // UTF-8 cases https://en.wikipedia.org/wiki/Newline#Unicode
 
 
-	// NEL: Next Line, U+0085 (UTF-8 in hex: C285)
-	if ((c == 0xC2) && (PEEK_NEXT == 0x85)) {
-		NEXT;
-		return true;
-	}
+    // NEL: Next Line, U+0085 (UTF-8 in hex: C285)
+    if ((c == 0xC2) && (PEEK_NEXT == 0x85)) {
+        NEXT;
+        return true;
+    }
 
 
-	// LS: Line Separator, U+2028 (UTF-8 in hex: E280A8)
-	if ((c == 0xE2) && (PEEK_NEXT == 0x80) && (PEEK_NEXT2 == 0xA8)) {
-		NEXT; NEXT;
-		return true;
-	}
+    // LS: Line Separator, U+2028 (UTF-8 in hex: E280A8)
+    if ((c == 0xE2) && (PEEK_NEXT == 0x80) && (PEEK_NEXT2 == 0xA8)) {
+        NEXT; NEXT;
+        return true;
+    }
 
 
-	// and probably more not handled here
-	return false;
+    // and probably more not handled here
+    return false;
 }
 }
 
 
 static inline bool is_comment (int c1, int c2) {
 static inline bool is_comment (int c1, int c2) {
-	return (c1 == '/') && ((c2 == '*') || (c2 == '/'));
+    return (c1 == '/') && ((c2 == '*') || (c2 == '/'));
 }
 }
 
 
 static inline bool is_semicolon (int c) {
 static inline bool is_semicolon (int c) {
-	return (c == ';');
+    return (c == ';');
 }
 }
 
 
 static inline bool is_alpha (int c) {
 static inline bool is_alpha (int c) {
-	if (c == '_') return true;
-	return isalpha(c);
+    if (c == '_') return true;
+    return isalpha(c);
 }
 }
 
 
 static inline bool is_digit (int c, gravity_number_type ntype) {
 static inline bool is_digit (int c, gravity_number_type ntype) {
-	if (ntype == NUMBER_BIN) return (c == '0' || (c == '1'));
-	if (ntype == NUMBER_OCT) return (c >= '0' && (c <= '7'));
-	if ((ntype == NUMBER_HEX) && ((toupper(c) >= 'A' && toupper(c) <= 'F'))) return true;
-	return isdigit(c);
+    if (ntype == NUMBER_BIN) return (c == '0' || (c == '1'));
+    if (ntype == NUMBER_OCT) return (c >= '0' && (c <= '7'));
+    if ((ntype == NUMBER_HEX) && ((toupper(c) >= 'A' && toupper(c) <= 'F'))) return true;
+    return isdigit(c);
 }
 }
 
 
 static inline bool is_string (int c) {
 static inline bool is_string (int c) {
-	return ((c == '"') || (c == '\''));
+    return ((c == '"') || (c == '\''));
 }
 }
 
 
 static inline bool is_special (int c) {
 static inline bool is_special (int c) {
-	return (c == '@');
+    return (c == '@');
 }
 }
 
 
 static inline bool is_builtin_operator (int c) {
 static inline bool is_builtin_operator (int c) {
-	// PARENTHESIS
-	// { } [ ] ( )
-	// PUNCTUATION
-	// . ; : ? ,
-	// OPERATORS
-	// + - * / < > ! = | & ^ % ~
+    // PARENTHESIS
+    // { } [ ] ( )
+    // PUNCTUATION
+    // . ; : ? ,
+    // OPERATORS
+    // + - * / < > ! = | & ^ % ~
 
 
-	return ((c == '+') || (c == '-') || (c == '*') || (c == '/') ||
-			(c == '<') || (c == '>') || (c == '!') || (c == '=') ||
-			(c == '|') || (c == '&') || (c == '^') || (c == '%') ||
-			(c == '~') || (c == '.') || (c == ';') || (c == ':') ||
-			(c == '?') || (c == ',') || (c == '{') || (c == '}') ||
-			(c == '[') || (c == ']') || (c == '(') || (c == ')') );
+    return ((c == '+') || (c == '-') || (c == '*') || (c == '/') ||
+            (c == '<') || (c == '>') || (c == '!') || (c == '=') ||
+            (c == '|') || (c == '&') || (c == '^') || (c == '%') ||
+            (c == '~') || (c == '.') || (c == ';') || (c == ':') ||
+            (c == '?') || (c == ',') || (c == '{') || (c == '}') ||
+            (c == '[') || (c == ']') || (c == '(') || (c == ')') );
 }
 }
 
 
 static inline bool is_preprocessor (int c) {
 static inline bool is_preprocessor (int c) {
-	return (c == '#');
+    return (c == '#');
 }
 }
 
 
 static inline bool is_identifier (int c) {
 static inline bool is_identifier (int c) {
-	// when called I am already sure first character is alpha so next valid characters are alpha, digit and _
-	return ((isalpha(c)) || (isdigit(c)) || (c == '_'));
+    // when called I am already sure first character is alpha so next valid characters are alpha, digit and _
+    return ((isalpha(c)) || (isdigit(c)) || (c == '_'));
 }
 }
 
 
 // MARK: -
 // MARK: -
 
 
 static gtoken_t lexer_error(gravity_lexer_t *lexer, const char *message) {
 static gtoken_t lexer_error(gravity_lexer_t *lexer, const char *message) {
-	if (!IS_EOF) {
-		INC_TOKLEN;
-		INC_OFFSET_POSITION;
-	}
-	TOKEN_FINALIZE(TOK_ERROR);
+    if (!IS_EOF) {
+        INC_TOKLEN;
+        INC_OFFSET_POSITION;
+    }
+    TOKEN_FINALIZE(TOK_ERROR);
 
 
-	lexer->token.value = (char *)message;
-	lexer->token.bytes = (uint32_t)strlen(message);
-	return TOK_ERROR;
+    lexer->token.value = (char *)message;
+    lexer->token.bytes = (uint32_t)strlen(message);
+    return TOK_ERROR;
 }
 }
 
 
 static inline bool next_utf8(gravity_lexer_t *lexer, int *result) {
 static inline bool next_utf8(gravity_lexer_t *lexer, int *result) {
-	int c = NEXT;
-	INC_TOKLEN;
+    int c = NEXT;
+    INC_TOKLEN;
 
 
     // the following explicit conversion fixes an issue with big-endian processor (like Motorola 68000, PowerPC, Sun Sparc and IBM S/390)
     // the following explicit conversion fixes an issue with big-endian processor (like Motorola 68000, PowerPC, Sun Sparc and IBM S/390)
     // was uint32_t len = utf8_charbytes((const char *)&c, 0);
     // was uint32_t len = utf8_charbytes((const char *)&c, 0);
     const char s = c;
     const char s = c;
-	uint32_t len = utf8_charbytes((const char *)&s, 0);
-	if (len == 0) return false;
+    uint32_t len = utf8_charbytes((const char *)&s, 0);
+    if (len == 0) return false;
 
 
-	switch(len) {
-		case 1: break;
-		case 2: INC_OFFSET; INC_TOKBYTES; break;
-		case 3: INC_OFFSET; INC_OFFSET; INC_TOKBYTES; INC_TOKBYTES; break;
-		case 4: INC_OFFSET; INC_OFFSET; INC_OFFSET; INC_TOKBYTES; INC_TOKBYTES; INC_TOKBYTES; INC_POSITION; INC_TOKUTF8LEN; break;
-	}
+    switch(len) {
+        case 1: break;
+        case 2: INC_OFFSET; INC_TOKBYTES; break;
+        case 3: INC_OFFSET; INC_OFFSET; INC_TOKBYTES; INC_TOKBYTES; break;
+        case 4: INC_OFFSET; INC_OFFSET; INC_OFFSET; INC_TOKBYTES; INC_TOKBYTES; INC_TOKBYTES; INC_POSITION; INC_TOKUTF8LEN; break;
+    }
 
 
-	if (result) *result = c;
-	return true;
+    if (result) *result = c;
+    return true;
 }
 }
 
 
 static gtoken_t lexer_scan_comment(gravity_lexer_t *lexer) {
 static gtoken_t lexer_scan_comment(gravity_lexer_t *lexer) {
-	bool isLineComment = (PEEK_NEXT == '/');
+    bool isLineComment = (PEEK_NEXT == '/');
 
 
-	TOKEN_RESET;
-	INC_OFFSET_POSITION;
-	INC_OFFSET_POSITION;
+    TOKEN_RESET;
+    INC_OFFSET_POSITION;
+    INC_OFFSET_POSITION;
 
 
-	// because I already scanned /* or //
-	lexer->token.bytes = lexer->token.length = 2;
+    // because I already scanned /* or //
+    lexer->token.bytes = lexer->token.length = 2;
 
 
-	// count variable used only to support nested comments
-	int count = 1;
-	while (!IS_EOF) {
-		int c = 0;
-		next_utf8(lexer, &c);
+    // count variable used only to support nested comments
+    int count = 1;
+    while (!IS_EOF) {
+        int c = 0;
+        next_utf8(lexer, &c);
 
 
-		if (isLineComment){
-			if (is_newline(lexer, c)) {INC_LINE; break;}
-		} else {
-			if (IS_EOF) break;
-			int c2 = PEEK_CURRENT;
-			if ((c == '/') && (c2 == '*')) ++count;
-			if ((c == '*') && (c2 == '/')) {--count; NEXT; INC_TOKLEN; if (count == 0) break;}
-			if (is_newline(lexer, c)) {INC_LINE;}
-		}
-	}
+        if (isLineComment){
+            if (is_newline(lexer, c)) {INC_LINE; break;}
+        } else {
+            if (IS_EOF) break;
+            int c2 = PEEK_CURRENT;
+            if ((c == '/') && (c2 == '*')) ++count;
+            if ((c == '*') && (c2 == '/')) {--count; NEXT; INC_TOKLEN; if (count == 0) break;}
+            if (is_newline(lexer, c)) {INC_LINE;}
+        }
+    }
 
 
-	// comment is from buffer->[nseek] and it is nlen length
-	TOKEN_FINALIZE(TOK_COMMENT);
+    // comment is from buffer->[nseek] and it is nlen length
+    TOKEN_FINALIZE(TOK_COMMENT);
 
 
-	// comments callback is called directly from the scan function and not from the main scan loop
-	if ((lexer->delegate) && (lexer->delegate->parser_callback)) {
-		lexer->delegate->parser_callback(&lexer->token, lexer->delegate->xdata);
-	}
+    // comments callback is called directly from the scan function and not from the main scan loop
+    if ((lexer->delegate) && (lexer->delegate->parser_callback)) {
+        lexer->delegate->parser_callback(&lexer->token, lexer->delegate->xdata);
+    }
 
 
-	DEBUG_LEXEM("Found comment");
-	return TOK_COMMENT;
+    DEBUG_LEXEM("Found comment");
+    return TOK_COMMENT;
 }
 }
 
 
 static gtoken_t lexer_scan_semicolon(gravity_lexer_t *lexer) {
 static gtoken_t lexer_scan_semicolon(gravity_lexer_t *lexer) {
-	TOKEN_RESET;
-	INC_TOKLEN;
-	INC_OFFSET_POSITION;
-	TOKEN_FINALIZE(TOK_OP_SEMICOLON);
+    TOKEN_RESET;
+    INC_TOKLEN;
+    INC_OFFSET_POSITION;
+    TOKEN_FINALIZE(TOK_OP_SEMICOLON);
 
 
-	return TOK_OP_SEMICOLON;
+    return TOK_OP_SEMICOLON;
 }
 }
 
 
 static gtoken_t lexer_scan_identifier(gravity_lexer_t *lexer) {
 static gtoken_t lexer_scan_identifier(gravity_lexer_t *lexer) {
-	TOKEN_RESET;
-	while (is_identifier(PEEK_CURRENT)) {
-		INC_OFFSET_POSITION;
-		INC_TOKLEN;
-	}
-	TOKEN_FINALIZE(TOK_IDENTIFIER);
+    TOKEN_RESET;
+    while (is_identifier(PEEK_CURRENT)) {
+        INC_OFFSET_POSITION;
+        INC_TOKLEN;
+    }
+    TOKEN_FINALIZE(TOK_IDENTIFIER);
 
 
     // check if identifier is a special built-in case
     // check if identifier is a special built-in case
     gtoken_t type = token_special_builtin(&lexer->token);
     gtoken_t type = token_special_builtin(&lexer->token);
     // then check if it is a reserved word (otherwise reports it as an identifier)
     // then check if it is a reserved word (otherwise reports it as an identifier)
     if (type == TOK_IDENTIFIER) type = token_keyword(lexer->token.value, lexer->token.bytes);
     if (type == TOK_IDENTIFIER) type = token_keyword(lexer->token.value, lexer->token.bytes);
-	SET_TOKTYPE(type);
+    SET_TOKTYPE(type);
 
 
-	#if GRAVITY_LEXEM_DEBUG
-	if (type == TOK_IDENTIFIER) DEBUG_LEXEM("Found identifier: %.*s", TOKEN_BYTES(lexer->token), TOKEN_VALUE(lexer->token));
-	else DEBUG_LEXEM("Found keyword: %s", token_name(type));
-	#endif
+    #if GRAVITY_LEXEM_DEBUG
+    if (type == TOK_IDENTIFIER) DEBUG_LEXEM("Found identifier: %.*s", TOKEN_BYTES(lexer->token), TOKEN_VALUE(lexer->token));
+    else DEBUG_LEXEM("Found keyword: %s", token_name(type));
+    #endif
 
 
-	return type;
+    return type;
 }
 }
 
 
 static gtoken_t lexer_scan_number(gravity_lexer_t *lexer) {
 static gtoken_t lexer_scan_number(gravity_lexer_t *lexer) {
-	bool		floatAllowed = true;
-	bool		expAllowed = true;
-	bool		signAllowed = false;
-	bool		dotFound = false;
-	bool		expFound = false;
-	int			c, expChar = 'e', floatChar = '.';
-	int			plusSign = '+', minusSign = '-';
-
-	gravity_number_type	ntype = NUMBER_INTEGER;
-	if (PEEK_CURRENT == '0') {
-		if (toupper(PEEK_NEXT) == 'X') {ntype = NUMBER_HEX; floatAllowed = false; expAllowed = false;}
-		else if (toupper(PEEK_NEXT) == 'B') {ntype = NUMBER_BIN; floatAllowed = false; expAllowed = false;}
-		else if (toupper(PEEK_NEXT) == 'O') {ntype = NUMBER_OCT; floatAllowed = false; expAllowed = false;}
-	}
-
-	TOKEN_RESET;
-	if (ntype != NUMBER_INTEGER) {
-		// skip first 0* number marker
-		INC_TOKLEN;
-		INC_TOKLEN;
-		INC_OFFSET_POSITION;
-		INC_OFFSET_POSITION;
-	}
-
-	// supported exp formats:
-	// 12345	// decimal
-	// 3.1415	// float
-	// 1.25e2 = 1.25 * 10^2 = 125.0		// scientific notation
-	// 1.25e-2 = 1.25 * 10^-2 = 0.0125	// scientific notation
-	// 0xFFFF	// hex
-	// 0B0101	// binary
-	// 0O7777	// octal
+    bool        floatAllowed = true;
+    bool        expAllowed = true;
+    bool        signAllowed = false;
+    bool        dotFound = false;
+    bool        expFound = false;
+    int            c, expChar = 'e', floatChar = '.';
+    int            plusSign = '+', minusSign = '-';
+
+    gravity_number_type    ntype = NUMBER_INTEGER;
+    if (PEEK_CURRENT == '0') {
+        if (toupper(PEEK_NEXT) == 'X') {ntype = NUMBER_HEX; floatAllowed = false; expAllowed = false;}
+        else if (toupper(PEEK_NEXT) == 'B') {ntype = NUMBER_BIN; floatAllowed = false; expAllowed = false;}
+        else if (toupper(PEEK_NEXT) == 'O') {ntype = NUMBER_OCT; floatAllowed = false; expAllowed = false;}
+    }
+
+    TOKEN_RESET;
+    if (ntype != NUMBER_INTEGER) {
+        // skip first 0* number marker
+        INC_TOKLEN;
+        INC_TOKLEN;
+        INC_OFFSET_POSITION;
+        INC_OFFSET_POSITION;
+    }
+
+    // supported exp formats:
+    // 12345    // decimal
+    // 3.1415    // float
+    // 1.25e2 = 1.25 * 10^2 = 125.0        // scientific notation
+    // 1.25e-2 = 1.25 * 10^-2 = 0.0125    // scientific notation
+    // 0xFFFF    // hex
+    // 0B0101    // binary
+    // 0O7777    // octal
 
 
 loop:
 loop:
-	c = PEEK_CURRENT;
-
-	// explicitly list all accepted cases
-	if (IS_EOF) goto report_token;
-	if (is_digit(c, ntype)) goto accept_char;
-	if (is_whitespace(c)) goto report_token;
-	if (is_newline(lexer, c)) goto report_token;
-
-	if (expAllowed) {
-		if ((c == expChar) && (!expFound)) {expFound = true; signAllowed = true; goto accept_char;}
-	}
-	if (floatAllowed) {
-		if ((c == floatChar) && (!is_digit(PEEK_NEXT, ntype))) goto report_token;
-		if ((c == floatChar) && (!dotFound))  {dotFound = true; goto accept_char;}
-	}
-	if (signAllowed) {
-		if ((c == plusSign) || (c == minusSign)) {signAllowed = false; goto accept_char;}
-	}
-	if (is_builtin_operator(c)) goto report_token;
-	if (is_semicolon(c)) goto report_token;
-
-	// any other case is an error
-	goto report_error;
+    c = PEEK_CURRENT;
+
+    // explicitly list all accepted cases
+    if (IS_EOF) goto report_token;
+    if (is_digit(c, ntype)) goto accept_char;
+    if (is_whitespace(c)) goto report_token;
+    if (is_newline(lexer, c)) goto report_token;
+
+    if (expAllowed) {
+        if ((c == expChar) && (!expFound)) {expFound = true; signAllowed = true; goto accept_char;}
+    }
+    if (floatAllowed) {
+        if ((c == floatChar) && (!is_digit(PEEK_NEXT, ntype))) goto report_token;
+        if ((c == floatChar) && (!dotFound))  {dotFound = true; goto accept_char;}
+    }
+    if (signAllowed) {
+        if ((c == plusSign) || (c == minusSign)) {signAllowed = false; goto accept_char;}
+    }
+    if (is_builtin_operator(c)) goto report_token;
+    if (is_semicolon(c)) goto report_token;
+
+    // any other case is an error
+    goto report_error;
 
 
 accept_char:
 accept_char:
-	INC_TOKLEN;
-	INC_OFFSET_POSITION;
-	goto loop;
+    INC_TOKLEN;
+    INC_OFFSET_POSITION;
+    goto loop;
 
 
 report_token:
 report_token:
-	// number is from buffer->[nseek] and it is bytes length
-	TOKEN_FINALIZE(TOK_NUMBER);
+    // number is from buffer->[nseek] and it is bytes length
+    TOKEN_FINALIZE(TOK_NUMBER);
 
 
-	DEBUG_LEXEM("Found number: %.*s", TOKEN_BYTES(lexer->token), TOKEN_VALUE(lexer->token));
-	return TOK_NUMBER;
+    DEBUG_LEXEM("Found number: %.*s", TOKEN_BYTES(lexer->token), TOKEN_VALUE(lexer->token));
+    return TOK_NUMBER;
 
 
 report_error:
 report_error:
-	return lexer_error(lexer, "Malformed number expression.");
+    return lexer_error(lexer, "Malformed number expression.");
 }
 }
 
 
 static gtoken_t lexer_scan_string(gravity_lexer_t *lexer) {
 static gtoken_t lexer_scan_string(gravity_lexer_t *lexer) {
-	int c, c2;
+    int c, c2;
 
 
-	// no memory allocation here
-	c = NEXT;					// save escaped character
-	TOKEN_RESET;				// save offset
+    // no memory allocation here
+    c = NEXT;                    // save escaped character
+    TOKEN_RESET;                // save offset
 
 
-	while ((c2 = (unsigned char)PEEK_CURRENT) != c) {
-		if (IS_EOF) return lexer_error(lexer, "Unexpected EOF inside a string literal");
-		if (is_newline(lexer, c2)) INC_LINE;
+    while ((c2 = (unsigned char)PEEK_CURRENT) != c) {
+        if (IS_EOF) return lexer_error(lexer, "Unexpected EOF inside a string literal");
+        if (is_newline(lexer, c2)) INC_LINE;
 
 
-		// handle escaped characters
-		if (c2 == '\\') {
-			INC_OFFSET_POSITION;
-			INC_OFFSET_POSITION;
-			INC_TOKLEN;
-			INC_TOKLEN;
+        // handle escaped characters
+        if (c2 == '\\') {
+            INC_OFFSET_POSITION;
+            INC_OFFSET_POSITION;
+            INC_TOKLEN;
+            INC_TOKLEN;
 
 
             // sanity check
             // sanity check
             if (IS_EOF) return lexer_error(lexer, "Unexpected EOF inside a string literal");
             if (IS_EOF) return lexer_error(lexer, "Unexpected EOF inside a string literal");
-			continue;
-		}
+            continue;
+        }
 
 
-		// scan next
-		if (!next_utf8(lexer, NULL)) return lexer_error(lexer, "Unknown character inside a string literal");
+        // scan next
+        if (!next_utf8(lexer, NULL)) return lexer_error(lexer, "Unknown character inside a string literal");
         if (IS_EOF) return lexer_error(lexer, "Unexpected EOF inside a string literal");
         if (IS_EOF) return lexer_error(lexer, "Unexpected EOF inside a string literal");
-	}
+    }
 
 
-	// skip last escape character
-	INC_OFFSET_POSITION;
+    // skip last escape character
+    INC_OFFSET_POSITION;
 
 
-	// string is from buffer->[nseek] and it is nlen length
-	TOKEN_FINALIZE(TOK_STRING);
+    // string is from buffer->[nseek] and it is nlen length
+    TOKEN_FINALIZE(TOK_STRING);
 
 
-	DEBUG_LEXEM("Found string: %.*s", TOKEN_BYTES(lexer->token), TOKEN_VALUE(lexer->token));
-	return TOK_STRING;
+    DEBUG_LEXEM("Found string: %.*s", TOKEN_BYTES(lexer->token), TOKEN_VALUE(lexer->token));
+    return TOK_STRING;
 }
 }
 
 
 static gtoken_t lexer_scan_operator(gravity_lexer_t *lexer) {
 static gtoken_t lexer_scan_operator(gravity_lexer_t *lexer) {
-	TOKEN_RESET;
-	INC_TOKLEN;
-
-	int c = NEXT;
-	int c2 = PEEK_CURRENT;
-	int tok = 0;
-
-	switch (c) {
-		case '=':
-			if (c2 == '=') {
-				INC_OFFSET_POSITION; INC_TOKLEN; c2 = PEEK_CURRENT;
-				if (c2 == '=') {INC_OFFSET_POSITION; INC_TOKLEN; tok = TOK_OP_ISIDENTICAL;}
-				else tok = TOK_OP_ISEQUAL;
-			}
-			else tok = TOK_OP_ASSIGN;
-			break;
-		case '+':
-			if (c2 == '=') {INC_OFFSET_POSITION; INC_TOKLEN; tok = TOK_OP_ADD_ASSIGN;}
-			else tok = TOK_OP_ADD;
-			break;
-		case '-':
-			if (c2 == '=') {INC_OFFSET_POSITION; INC_TOKLEN; tok = TOK_OP_SUB_ASSIGN;}
-			else tok = TOK_OP_SUB;
-			break;
-		case '*':
-			if (c2 == '=') {INC_OFFSET_POSITION; INC_TOKLEN; tok = TOK_OP_MUL_ASSIGN;}
-			else tok = TOK_OP_MUL;
-			break;
-		case '/':
-			if (c2 == '=') {INC_OFFSET_POSITION; INC_TOKLEN; tok = TOK_OP_DIV_ASSIGN;}
-			else tok = TOK_OP_DIV;
-			break;
-		case '%':
-			if (c2 == '=') {INC_OFFSET_POSITION; INC_TOKLEN; tok = TOK_OP_REM_ASSIGN;}
-			else tok = TOK_OP_REM;
-			break;
-		case '<':
-			if (c2 == '=') {INC_OFFSET_POSITION; INC_TOKLEN; tok = TOK_OP_LESS_EQUAL;}
-			else if (c2 == '<') {
-				INC_OFFSET_POSITION; INC_TOKLEN; c2 = PEEK_CURRENT;
-				if (c2 == '=') {INC_OFFSET_POSITION; INC_TOKLEN; tok = TOK_OP_SHIFT_LEFT_ASSIGN;}
-				else tok = TOK_OP_SHIFT_LEFT;
-			}
-			else tok = TOK_OP_LESS;
-			break;
-		case '>':
-			if (c2 == '=') {INC_OFFSET_POSITION; INC_TOKLEN; tok = TOK_OP_GREATER_EQUAL;}
-			else if (c2 == '>') {
-				INC_OFFSET_POSITION; INC_TOKLEN; c2 = PEEK_CURRENT;
-				if (c2 == '=') {INC_OFFSET_POSITION; INC_TOKLEN; tok = TOK_OP_SHIFT_RIGHT_ASSIGN;}
-				else tok = TOK_OP_SHIFT_RIGHT;
-			}
-			else tok = TOK_OP_GREATER;
-			break;
-		case '&':
-			if (c2 == '&') {INC_OFFSET_POSITION; INC_TOKLEN; tok = TOK_OP_AND;}
-			else if (c2 == '=') {INC_OFFSET_POSITION; INC_TOKLEN; tok = TOK_OP_BIT_AND_ASSIGN;}
-			else tok = TOK_OP_BIT_AND;
-			break;
-		case '|':
-			if (c2 == '|') {INC_OFFSET_POSITION; INC_TOKLEN; tok = TOK_OP_OR;}
-			else if (c2 == '=') {INC_OFFSET_POSITION; INC_TOKLEN; tok = TOK_OP_BIT_OR_ASSIGN;}
-			else tok = TOK_OP_BIT_OR;
-			break;
-		case '.': // check for special .digit case
-			if (is_digit(c2, false)) {DEC_OFFSET_POSITION; DEC_TOKLEN; tok = lexer_scan_number(lexer);}
-			else if (c2 == '.') {
-				// seems a range, now peek c2 again and decide range type
-				INC_OFFSET_POSITION; INC_TOKLEN; c2 = PEEK_CURRENT;
-				if ((c2 == '<') || (c2 == '.')) {
-					INC_OFFSET_POSITION; INC_TOKLEN;
-					tok = (c2 == '<') ? TOK_OP_RANGE_EXCLUDED : TOK_OP_RANGE_INCLUDED;
-				} else {
-					return lexer_error(lexer, "Unrecognized Range operator");
-				}
-			}
-			else tok = TOK_OP_DOT;
-			break;
-		case ',':
-			tok = TOK_OP_COMMA;
-			break;
-		case '!':
-			if (c2 == '=') {
-				INC_OFFSET_POSITION; INC_TOKLEN; c2 = PEEK_CURRENT;
-				if (c2 == '=') {INC_OFFSET_POSITION; INC_TOKLEN; tok = TOK_OP_ISNOTIDENTICAL;}
-				else tok = TOK_OP_ISNOTEQUAL;
-			}
-			else tok = TOK_OP_NOT;
-			break;
-		case '^':
-			if (c2 == '=') {INC_OFFSET_POSITION; INC_TOKLEN; tok = TOK_OP_BIT_XOR_ASSIGN;}
-			else tok = TOK_OP_BIT_XOR;
-			break;
-		case '~':
-			if (c2 == '=') {INC_OFFSET_POSITION; INC_TOKLEN; tok = TOK_OP_PATTERN_MATCH;}
-			else tok = TOK_OP_BIT_NOT;
-			break;
-		case ':':
-			tok = TOK_OP_COLON;
-			break;
-		case '{':
-			tok = TOK_OP_OPEN_CURLYBRACE;
-			break;
-		case '}':
-			tok = TOK_OP_CLOSED_CURLYBRACE;
-			break;
-		case '[':
-			tok = TOK_OP_OPEN_SQUAREBRACKET;
-			break;
-		case ']':
-			tok = TOK_OP_CLOSED_SQUAREBRACKET;
-			break;
-		case '(':
-			tok = TOK_OP_OPEN_PARENTHESIS;
-			break;
-		case ')':
-			tok = TOK_OP_CLOSED_PARENTHESIS;
-			break;
-		case '?':
-			tok = TOK_OP_TERNARY;
-			break;
-		default:
-			return lexer_error(lexer, "Unrecognized Operator");
-
-	}
-
-	TOKEN_FINALIZE(tok);
-
-	DEBUG_LEXEM("Found operator: %s", token_name(tok));
-	return tok;
+    TOKEN_RESET;
+    INC_TOKLEN;
+
+    int c = NEXT;
+    int c2 = PEEK_CURRENT;
+    int tok = 0;
+
+    switch (c) {
+        case '=':
+            if (c2 == '=') {
+                INC_OFFSET_POSITION; INC_TOKLEN; c2 = PEEK_CURRENT;
+                if (c2 == '=') {INC_OFFSET_POSITION; INC_TOKLEN; tok = TOK_OP_ISIDENTICAL;}
+                else tok = TOK_OP_ISEQUAL;
+            }
+            else tok = TOK_OP_ASSIGN;
+            break;
+        case '+':
+            if (c2 == '=') {INC_OFFSET_POSITION; INC_TOKLEN; tok = TOK_OP_ADD_ASSIGN;}
+            else tok = TOK_OP_ADD;
+            break;
+        case '-':
+            if (c2 == '=') {INC_OFFSET_POSITION; INC_TOKLEN; tok = TOK_OP_SUB_ASSIGN;}
+            else tok = TOK_OP_SUB;
+            break;
+        case '*':
+            if (c2 == '=') {INC_OFFSET_POSITION; INC_TOKLEN; tok = TOK_OP_MUL_ASSIGN;}
+            else tok = TOK_OP_MUL;
+            break;
+        case '/':
+            if (c2 == '=') {INC_OFFSET_POSITION; INC_TOKLEN; tok = TOK_OP_DIV_ASSIGN;}
+            else tok = TOK_OP_DIV;
+            break;
+        case '%':
+            if (c2 == '=') {INC_OFFSET_POSITION; INC_TOKLEN; tok = TOK_OP_REM_ASSIGN;}
+            else tok = TOK_OP_REM;
+            break;
+        case '<':
+            if (c2 == '=') {INC_OFFSET_POSITION; INC_TOKLEN; tok = TOK_OP_LESS_EQUAL;}
+            else if (c2 == '<') {
+                INC_OFFSET_POSITION; INC_TOKLEN; c2 = PEEK_CURRENT;
+                if (c2 == '=') {INC_OFFSET_POSITION; INC_TOKLEN; tok = TOK_OP_SHIFT_LEFT_ASSIGN;}
+                else tok = TOK_OP_SHIFT_LEFT;
+            }
+            else tok = TOK_OP_LESS;
+            break;
+        case '>':
+            if (c2 == '=') {INC_OFFSET_POSITION; INC_TOKLEN; tok = TOK_OP_GREATER_EQUAL;}
+            else if (c2 == '>') {
+                INC_OFFSET_POSITION; INC_TOKLEN; c2 = PEEK_CURRENT;
+                if (c2 == '=') {INC_OFFSET_POSITION; INC_TOKLEN; tok = TOK_OP_SHIFT_RIGHT_ASSIGN;}
+                else tok = TOK_OP_SHIFT_RIGHT;
+            }
+            else tok = TOK_OP_GREATER;
+            break;
+        case '&':
+            if (c2 == '&') {INC_OFFSET_POSITION; INC_TOKLEN; tok = TOK_OP_AND;}
+            else if (c2 == '=') {INC_OFFSET_POSITION; INC_TOKLEN; tok = TOK_OP_BIT_AND_ASSIGN;}
+            else tok = TOK_OP_BIT_AND;
+            break;
+        case '|':
+            if (c2 == '|') {INC_OFFSET_POSITION; INC_TOKLEN; tok = TOK_OP_OR;}
+            else if (c2 == '=') {INC_OFFSET_POSITION; INC_TOKLEN; tok = TOK_OP_BIT_OR_ASSIGN;}
+            else tok = TOK_OP_BIT_OR;
+            break;
+        case '.': // check for special .digit case
+            if (is_digit(c2, false)) {DEC_OFFSET_POSITION; DEC_TOKLEN; tok = lexer_scan_number(lexer);}
+            else if (c2 == '.') {
+                // seems a range, now peek c2 again and decide range type
+                INC_OFFSET_POSITION; INC_TOKLEN; c2 = PEEK_CURRENT;
+                if ((c2 == '<') || (c2 == '.')) {
+                    INC_OFFSET_POSITION; INC_TOKLEN;
+                    tok = (c2 == '<') ? TOK_OP_RANGE_EXCLUDED : TOK_OP_RANGE_INCLUDED;
+                } else {
+                    return lexer_error(lexer, "Unrecognized Range operator");
+                }
+            }
+            else tok = TOK_OP_DOT;
+            break;
+        case ',':
+            tok = TOK_OP_COMMA;
+            break;
+        case '!':
+            if (c2 == '=') {
+                INC_OFFSET_POSITION; INC_TOKLEN; c2 = PEEK_CURRENT;
+                if (c2 == '=') {INC_OFFSET_POSITION; INC_TOKLEN; tok = TOK_OP_ISNOTIDENTICAL;}
+                else tok = TOK_OP_ISNOTEQUAL;
+            }
+            else tok = TOK_OP_NOT;
+            break;
+        case '^':
+            if (c2 == '=') {INC_OFFSET_POSITION; INC_TOKLEN; tok = TOK_OP_BIT_XOR_ASSIGN;}
+            else tok = TOK_OP_BIT_XOR;
+            break;
+        case '~':
+            if (c2 == '=') {INC_OFFSET_POSITION; INC_TOKLEN; tok = TOK_OP_PATTERN_MATCH;}
+            else tok = TOK_OP_BIT_NOT;
+            break;
+        case ':':
+            tok = TOK_OP_COLON;
+            break;
+        case '{':
+            tok = TOK_OP_OPEN_CURLYBRACE;
+            break;
+        case '}':
+            tok = TOK_OP_CLOSED_CURLYBRACE;
+            break;
+        case '[':
+            tok = TOK_OP_OPEN_SQUAREBRACKET;
+            break;
+        case ']':
+            tok = TOK_OP_CLOSED_SQUAREBRACKET;
+            break;
+        case '(':
+            tok = TOK_OP_OPEN_PARENTHESIS;
+            break;
+        case ')':
+            tok = TOK_OP_CLOSED_PARENTHESIS;
+            break;
+        case '?':
+            tok = TOK_OP_TERNARY;
+            break;
+        default:
+            return lexer_error(lexer, "Unrecognized Operator");
+
+    }
+
+    TOKEN_FINALIZE(tok);
+
+    DEBUG_LEXEM("Found operator: %s", token_name(tok));
+    return tok;
 }
 }
 
 
 static gtoken_t lexer_scan_special(gravity_lexer_t *lexer) {
 static gtoken_t lexer_scan_special(gravity_lexer_t *lexer) {
-	TOKEN_RESET;
-	INC_TOKLEN;
-	INC_OFFSET_POSITION;
-	TOKEN_FINALIZE(TOK_SPECIAL);
+    TOKEN_RESET;
+    INC_TOKLEN;
+    INC_OFFSET_POSITION;
+    TOKEN_FINALIZE(TOK_SPECIAL);
 
 
-	return TOK_SPECIAL;
+    return TOK_SPECIAL;
 }
 }
 
 
 static gtoken_t lexer_scan_preprocessor(gravity_lexer_t *lexer) {
 static gtoken_t lexer_scan_preprocessor(gravity_lexer_t *lexer) {
-	TOKEN_RESET;
-	INC_TOKLEN;
-	INC_OFFSET_POSITION;
-	TOKEN_FINALIZE(TOK_MACRO);
+    TOKEN_RESET;
+    INC_TOKLEN;
+    INC_OFFSET_POSITION;
+    TOKEN_FINALIZE(TOK_MACRO);
 
 
-	return TOK_MACRO;
+    return TOK_MACRO;
 }
 }
 
 
 // MARK: -
 // MARK: -
 
 
 gravity_lexer_t *gravity_lexer_create (const char *source, size_t len, uint32_t fileid, bool is_static) {
 gravity_lexer_t *gravity_lexer_create (const char *source, size_t len, uint32_t fileid, bool is_static) {
-	gravity_lexer_t *lexer = mem_alloc(NULL, sizeof(gravity_lexer_t));
-	if (!lexer) return NULL;
-
-	bzero(lexer, sizeof(gravity_lexer_t));
-	lexer->is_static = is_static;
-	lexer->lineno = 1;
-	lexer->buffer = source;
-	lexer->length = (uint32_t)len;
-	lexer->fileid = fileid;
-	lexer->peeking = false;
+    gravity_lexer_t *lexer = mem_alloc(NULL, sizeof(gravity_lexer_t));
+    if (!lexer) return NULL;
+
+    bzero(lexer, sizeof(gravity_lexer_t));
+    lexer->is_static = is_static;
+    lexer->lineno = 1;
+    lexer->buffer = source;
+    lexer->length = (uint32_t)len;
+    lexer->fileid = fileid;
+    lexer->peeking = false;
     lexer->cache = TOK_END;
     lexer->cache = TOK_END;
     
     
-	return lexer;
+    return lexer;
 }
 }
 
 
 void gravity_lexer_setdelegate (gravity_lexer_t *lexer, gravity_delegate_t *delegate) {
 void gravity_lexer_setdelegate (gravity_lexer_t *lexer, gravity_delegate_t *delegate) {
-	lexer->delegate = delegate;
+    lexer->delegate = delegate;
 }
 }
 
 
 gtoken_t gravity_lexer_peek (gravity_lexer_t *lexer) {
 gtoken_t gravity_lexer_peek (gravity_lexer_t *lexer) {
     if (lexer->cache != TOK_END) return lexer->cache;
     if (lexer->cache != TOK_END) return lexer->cache;
     
     
-	lexer->peeking = true;
-	gravity_lexer_t saved = *lexer;
+    lexer->peeking = true;
+    gravity_lexer_t saved = *lexer;
 
 
-	gtoken_t result = gravity_lexer_next(lexer);
+    gtoken_t result = gravity_lexer_next(lexer);
 
 
-	*lexer = saved;
-	lexer->peeking = false;
+    *lexer = saved;
+    lexer->peeking = false;
 
 
     lexer->cache = result;
     lexer->cache = result;
-	return result;
+    return result;
 }
 }
 
 
 gtoken_t gravity_lexer_next (gravity_lexer_t *lexer) {
 gtoken_t gravity_lexer_next (gravity_lexer_t *lexer) {
-	int			c;
-	gtoken_t	token;
+    int            c;
+    gtoken_t    token;
 
 
     // reset cached value
     // reset cached value
     if (!lexer->peeking) lexer->cache = TOK_END;
     if (!lexer->peeking) lexer->cache = TOK_END;
-	
+    
 loop:
 loop:
-	if (IS_EOF) return TOK_EOF;
-	c = PEEK_CURRENT;
+    if (IS_EOF) return TOK_EOF;
+    c = PEEK_CURRENT;
 
 
-	if (is_whitespace(c)) {INC_OFFSET_POSITION; goto loop;}
-	if (is_newline(lexer, c)) {INC_OFFSET_POSITION; INC_LINE; goto loop;}
-	if (is_comment(c, PEEK_NEXT)) {lexer_scan_comment(lexer); goto loop;}
+    if (is_whitespace(c)) {INC_OFFSET_POSITION; goto loop;}
+    if (is_newline(lexer, c)) {INC_OFFSET_POSITION; INC_LINE; goto loop;}
+    if (is_comment(c, PEEK_NEXT)) {lexer_scan_comment(lexer); goto loop;}
 
 
-	if (is_semicolon(c)) {token = lexer_scan_semicolon(lexer); goto return_result;}
-	if (is_alpha(c)) {token = lexer_scan_identifier(lexer); goto return_result;}
-	if (is_digit(c, false)) {token = lexer_scan_number(lexer); goto return_result;}
-	if (is_string(c)) {token = lexer_scan_string(lexer); goto return_result;}
-	if (is_builtin_operator(c)) {token = lexer_scan_operator(lexer); goto return_result;}
-	if (is_special(c)) {token = lexer_scan_special(lexer); goto return_result;}
-	if (is_preprocessor(c)) {token = lexer_scan_preprocessor(lexer); goto return_result;}
+    if (is_semicolon(c)) {token = lexer_scan_semicolon(lexer); goto return_result;}
+    if (is_alpha(c)) {token = lexer_scan_identifier(lexer); goto return_result;}
+    if (is_digit(c, false)) {token = lexer_scan_number(lexer); goto return_result;}
+    if (is_string(c)) {token = lexer_scan_string(lexer); goto return_result;}
+    if (is_builtin_operator(c)) {token = lexer_scan_operator(lexer); goto return_result;}
+    if (is_special(c)) {token = lexer_scan_special(lexer); goto return_result;}
+    if (is_preprocessor(c)) {token = lexer_scan_preprocessor(lexer); goto return_result;}
 
 
-	return lexer_error(lexer, "Unrecognized token");
+    return lexer_error(lexer, "Unrecognized token");
 
 
 return_result:
 return_result:
-	LEXER_CALL_CALLBACK();
-	return token;
+    LEXER_CALL_CALLBACK();
+    return token;
 }
 }
 
 
 void gravity_lexer_free (gravity_lexer_t *lexer) {
 void gravity_lexer_free (gravity_lexer_t *lexer) {
-	if ((!lexer->is_static) && (lexer->buffer)) mem_free(lexer->buffer);
-	mem_free(lexer);
+    if ((!lexer->is_static) && (lexer->buffer)) mem_free(lexer->buffer);
+    mem_free(lexer);
 }
 }
 
 
 gtoken_s gravity_lexer_token (gravity_lexer_t *lexer) {
 gtoken_s gravity_lexer_token (gravity_lexer_t *lexer) {
-	return lexer->token;
+    return lexer->token;
 }
 }
 
 
 gtoken_s gravity_lexer_token_next (gravity_lexer_t *lexer) {
 gtoken_s gravity_lexer_token_next (gravity_lexer_t *lexer) {
-	gtoken_s token = lexer->token;
-	token.lineno = lexer->lineno;
-	token.colno = lexer->colno;
-	token.position = lexer->position;
-	return token;
+    gtoken_s token = lexer->token;
+    token.lineno = lexer->lineno;
+    token.colno = lexer->colno;
+    token.position = lexer->position;
+    return token;
 }
 }
 
 
 gtoken_t gravity_lexer_token_type (gravity_lexer_t *lexer) {
 gtoken_t gravity_lexer_token_type (gravity_lexer_t *lexer) {
-	return lexer->token.type;
+    return lexer->token.type;
 }
 }
 
 
 void gravity_lexer_skip_line (gravity_lexer_t *lexer) {
 void gravity_lexer_skip_line (gravity_lexer_t *lexer) {
-	while (!IS_EOF) {
-		int c = 0;
-		next_utf8(lexer, &c);
-		if (is_newline(lexer, c)) {
-			INC_LINE;
-			break;
-		}
-	}
+    while (!IS_EOF) {
+        int c = 0;
+        next_utf8(lexer, &c);
+        if (is_newline(lexer, c)) {
+            INC_LINE;
+            break;
+        }
+    }
 }
 }
 
 
 uint32_t gravity_lexer_lineno (gravity_lexer_t *lexer) {
 uint32_t gravity_lexer_lineno (gravity_lexer_t *lexer) {
-	return lexer->lineno;
+    return lexer->lineno;
 }
 }
 
 
 // MARK: -
 // MARK: -
 
 
 void gravity_lexer_token_dump (gtoken_s token) {
 void gravity_lexer_token_dump (gtoken_s token) {
-	printf("(%02d, %02d) %s: ", token.lineno, token.colno, token_name(token.type));
-	printf("%.*s\t(offset: %d len:%d)\n", token.bytes, token.value, token.position, token.bytes);
+    printf("(%02d, %02d) %s: ", token.lineno, token.colno, token_name(token.type));
+    printf("%.*s\t(offset: %d len:%d)\n", token.bytes, token.value, token.position, token.bytes);
 }
 }
 
 
 #if GRAVITY_LEXER_DEGUB
 #if GRAVITY_LEXER_DEGUB
 void gravity_lexer_debug (gravity_lexer_t *lexer) {
 void gravity_lexer_debug (gravity_lexer_t *lexer) {
-	static uint32_t offset = UINT32_MAX;
-	if (lexer->peeking) return;
+    static uint32_t offset = UINT32_MAX;
+    if (lexer->peeking) return;
     
     
-	gtoken_s token = lexer->token;
-	if ((token.lineno == 0) && (token.colno == 0)) return;
+    gtoken_s token = lexer->token;
+    if ((token.lineno == 0) && (token.colno == 0)) return;
     if (offset == token.position) return;
     if (offset == token.position) return;
     offset = token.position;
     offset = token.position;
     
     
-	printf("(%02d, %02d) %s: ", token.lineno, token.colno, token_name(token.type));
-	printf("%.*s\t(offset: %d)\n", token.bytes, token.value, token.position);
+    printf("(%02d, %02d) %s: ", token.lineno, token.colno, token_name(token.type));
+    printf("%.*s\t(offset: %d)\n", token.bytes, token.value, token.position);
 }
 }
 #endif
 #endif

+ 32 - 32
src/compiler/gravity_lexer.h

@@ -14,25 +14,25 @@
 #include "debug_macros.h"
 #include "debug_macros.h"
 
 
 /*
 /*
-	Lexer is built in such a way that no memory allocations are necessary during usage
-	(except for the gravity_lexer_t opaque datatype allocated within gravity_lexer_create).
-
-	Example:
-	gravity_lexer *lexer = gravity_lexer_create(...);
-	while (gravity_lexer_next(lexer)) {
-		// do something here
-	}
-	gravity_lexer_free(lexer);
-
-	gravity_lexer_next (and gravity_lexer_peek) returns an int token (gtoken_t)
-	which represents what has been currently scanned. When EOF is reached TOK_EOF is
-	returned (with value 0) and the while loop exits.
-
-	In order to have token details, gravity_lexer_token must be called.
-	In case of a scan error TOK_ERROR is returned and error details can be extracted
-	from the token itself. In order to be able to not allocate any memory during
-	tokenization STRINGs and NUMBERs are just sanity checked but not converted.
-	It is parser responsability to perform the right conversion.
+    Lexer is built in such a way that no memory allocations are necessary during usage
+    (except for the gravity_lexer_t opaque datatype allocated within gravity_lexer_create).
+
+    Example:
+    gravity_lexer *lexer = gravity_lexer_create(...);
+    while (gravity_lexer_next(lexer)) {
+        // do something here
+    }
+    gravity_lexer_free(lexer);
+
+    gravity_lexer_next (and gravity_lexer_peek) returns an int token (gtoken_t)
+    which represents what has been currently scanned. When EOF is reached TOK_EOF is
+    returned (with value 0) and the while loop exits.
+
+    In order to have token details, gravity_lexer_token must be called.
+    In case of a scan error TOK_ERROR is returned and error details can be extracted
+    from the token itself. In order to be able to not allocate any memory during
+    tokenization STRINGs and NUMBERs are just sanity checked but not converted.
+    It is parser responsability to perform the right conversion.
 
 
  */
  */
 
 
@@ -40,21 +40,21 @@
 typedef struct gravity_lexer_t gravity_lexer_t;
 typedef struct gravity_lexer_t gravity_lexer_t;
 
 
 // public functions
 // public functions
-gravity_lexer_t		*gravity_lexer_create (const char *source, size_t len, uint32_t fileid, bool is_static);
-void				gravity_lexer_setdelegate (gravity_lexer_t *lexer, gravity_delegate_t *delegate);
-void				gravity_lexer_free (gravity_lexer_t *lexer);
-
-gtoken_t			gravity_lexer_peek (gravity_lexer_t *lexer);
-gtoken_t			gravity_lexer_next (gravity_lexer_t *lexer);
-gtoken_s			gravity_lexer_token (gravity_lexer_t *lexer);
-gtoken_s			gravity_lexer_token_next (gravity_lexer_t *lexer);
-gtoken_t			gravity_lexer_token_type (gravity_lexer_t *lexer);
-void				gravity_lexer_token_dump (gtoken_s token);
-void				gravity_lexer_skip_line (gravity_lexer_t *lexer);
-uint32_t			gravity_lexer_lineno (gravity_lexer_t *lexer);
+gravity_lexer_t     *gravity_lexer_create (const char *source, size_t len, uint32_t fileid, bool is_static);
+void                gravity_lexer_setdelegate (gravity_lexer_t *lexer, gravity_delegate_t *delegate);
+void                gravity_lexer_free (gravity_lexer_t *lexer);
+
+gtoken_t            gravity_lexer_peek (gravity_lexer_t *lexer);
+gtoken_t            gravity_lexer_next (gravity_lexer_t *lexer);
+gtoken_s            gravity_lexer_token (gravity_lexer_t *lexer);
+gtoken_s            gravity_lexer_token_next (gravity_lexer_t *lexer);
+gtoken_t            gravity_lexer_token_type (gravity_lexer_t *lexer);
+void                gravity_lexer_token_dump (gtoken_s token);
+void                gravity_lexer_skip_line (gravity_lexer_t *lexer);
+uint32_t            gravity_lexer_lineno (gravity_lexer_t *lexer);
 
 
 #if GRAVITY_LEXER_DEGUB
 #if GRAVITY_LEXER_DEGUB
-void				gravity_lexer_debug (gravity_lexer_t *lexer);
+void                gravity_lexer_debug (gravity_lexer_t *lexer);
 #endif
 #endif
 
 
 #endif
 #endif

+ 443 - 443
src/compiler/gravity_optimizer.c

@@ -15,245 +15,245 @@
 #include "gravity_utils.h"
 #include "gravity_utils.h"
 #include "gravity_value.h"
 #include "gravity_value.h"
 
 
-#define IS_MOVE(inst)					((inst) && (inst->op == MOVE))
-#define IS_RET(inst)					((inst) && (inst->op == RET))
-#define IS_NEG(inst)					((inst) && (inst->op == NEG))
-#define IS_NUM(inst)					((inst) && (inst->op == LOADI))
-#define IS_MATH(inst)					((inst) && (inst->op >= ADD) && (inst->op <= REM))
-#define IS_SKIP(inst)					(inst->tag == SKIP_TAG)
-#define IS_LABEL(inst)					(inst->tag == LABEL_TAG)
-#define IS_NOTNULL(inst)				(inst)
-#define IS_PRAGMA_MOVE_OPT(inst)		((inst) && (inst->tag == PRAGMA_MOVE_OPTIMIZATION))
+#define IS_MOVE(inst)               ((inst) && (inst->op == MOVE))
+#define IS_RET(inst)                ((inst) && (inst->op == RET))
+#define IS_NEG(inst)                ((inst) && (inst->op == NEG))
+#define IS_NUM(inst)                ((inst) && (inst->op == LOADI))
+#define IS_MATH(inst)               ((inst) && (inst->op >= ADD) && (inst->op <= REM))
+#define IS_SKIP(inst)               (inst->tag == SKIP_TAG)
+#define IS_LABEL(inst)              (inst->tag == LABEL_TAG)
+#define IS_NOTNULL(inst)            (inst)
+#define IS_PRAGMA_MOVE_OPT(inst)    ((inst) && (inst->tag == PRAGMA_MOVE_OPTIMIZATION))
 
 
 // http://www.mathsisfun.com/binary-decimal-hexadecimal-converter.html
 // http://www.mathsisfun.com/binary-decimal-hexadecimal-converter.html
-#define OPCODE_SET(op,code)								op = (code & 0x3F) << 26
-#define OPCODE_SET_TWO8bit_ONE10bit(op,code,a,b,c)		op = (code & 0x3F) << 26; op += (a & 0xFF) << 18; op += (b & 0xFF) << 10; op += (c & 0x3FF)
-#define OPCODE_SET_FOUR8bit(op,a,b,c,d)					op = (a & 0xFF) << 24; op += (b & 0xFF) << 16; op += (c & 0xFF) << 8; op += (d & 0xFF)
-#define OPCODE_SET_ONE8bit_SIGN_ONE17bit(op,code,a,s,n)	op = (code & 0x3F) << 26; op += (a & 0xFF) << 18; op += (s & 0x01) << 17; op += (n & 0x1FFFF)
-#define OPCODE_SET_SIGN_ONE25bit(op,code,s,a)			op = (code & 0x3F) << 26; op += (s & 0x01) << 25; op += (a & 0x1FFFFFF)
-#define OPCODE_SET_ONE8bit_ONE18bit(op,code,a,n)		op = (code & 0x3F) << 26; op += (a & 0xFF) << 18; op += (n & 0x3FFFF)
-#define OPCODE_SET_ONE26bit(op,code,a)					op = (code & 0x3F) << 26; op += (a & 0x3FFFFFF)
-#define OPCODE_SET_THREE8bit(op,code,a,b,c)				OPCODE_SET_TWO8bit_ONE10bit(op,code,a,b,c)
-#define OPCODE_SET_ONE8bit_ONE10bit(op,code,a,b)		OPCODE_SET_TWO8bit_ONE10bit(op,code,a,0,b)
-#define OPCODE_SET_ONE8bit(op,code,a)					OPCODE_SET_TWO8bit_ONE10bit(op,code,a,0,0)
-#define OPCODE_SET_THREE8bit_ONE2bit(op,code,a,b,c,f)	op =(code & 0x3F)<<26; op+=(a & 0xFF)<<18; op+=(b & 0xFF)<<10; op+=(c & 0xFF)<<2; op+=(f & 0x03)
+#define OPCODE_SET(op,code)                             op = (code & 0x3F) << 26
+#define OPCODE_SET_TWO8bit_ONE10bit(op,code,a,b,c)      op = (code & 0x3F) << 26; op += (a & 0xFF) << 18; op += (b & 0xFF) << 10; op += (c & 0x3FF)
+#define OPCODE_SET_FOUR8bit(op,a,b,c,d)                 op = (a & 0xFF) << 24; op += (b & 0xFF) << 16; op += (c & 0xFF) << 8; op += (d & 0xFF)
+#define OPCODE_SET_ONE8bit_SIGN_ONE17bit(op,code,a,s,n) op = (code & 0x3F) << 26; op += (a & 0xFF) << 18; op += (s & 0x01) << 17; op += (n & 0x1FFFF)
+#define OPCODE_SET_SIGN_ONE25bit(op,code,s,a)           op = (code & 0x3F) << 26; op += (s & 0x01) << 25; op += (a & 0x1FFFFFF)
+#define OPCODE_SET_ONE8bit_ONE18bit(op,code,a,n)        op = (code & 0x3F) << 26; op += (a & 0xFF) << 18; op += (n & 0x3FFFF)
+#define OPCODE_SET_ONE26bit(op,code,a)                  op = (code & 0x3F) << 26; op += (a & 0x3FFFFFF)
+#define OPCODE_SET_THREE8bit(op,code,a,b,c)             OPCODE_SET_TWO8bit_ONE10bit(op,code,a,b,c)
+#define OPCODE_SET_ONE8bit_ONE10bit(op,code,a,b)        OPCODE_SET_TWO8bit_ONE10bit(op,code,a,0,b)
+#define OPCODE_SET_ONE8bit(op,code,a)                   OPCODE_SET_TWO8bit_ONE10bit(op,code,a,0,0)
+#define OPCODE_SET_THREE8bit_ONE2bit(op,code,a,b,c,f)   op =(code & 0x3F)<<26; op+=(a & 0xFF)<<18; op+=(b & 0xFF)<<10; op+=(c & 0xFF)<<2; op+=(f & 0x03)
 
 
 // MARK: -
 // MARK: -
 
 
 static bool hash_isequal (gravity_value_t v1, gravity_value_t v2) {
 static bool hash_isequal (gravity_value_t v1, gravity_value_t v2) {
-	return (v1.n == v2.n);
+    return (v1.n == v2.n);
 }
 }
 
 
 static uint32_t hash_compute (gravity_value_t v) {
 static uint32_t hash_compute (gravity_value_t v) {
-	return gravity_hash_compute_int(v.n);
+    return gravity_hash_compute_int(v.n);
 }
 }
 
 
 static void finalize_function (gravity_function_t *f) {
 static void finalize_function (gravity_function_t *f) {
-	ircode_t		*code = (ircode_t *)f->bytecode;
-	uint32_t		ninst = 0, count = ircode_count(code);
-	uint32_t		notpure = 0;
-	uint32_t		*bytecode = NULL;
-	gravity_hash_t	*labels = gravity_hash_create(0, hash_compute, hash_isequal, NULL, NULL);
-
-	// determine how big bytecode buffer must be
-	// and collect all LABEL instructions
-	for (uint32_t i=0; i<count; ++i) {
-		inst_t *inst = ircode_get(code, i);
-		if (IS_SKIP(inst)) continue;
-		if (IS_PRAGMA_MOVE_OPT(inst)) continue;
-		if (IS_LABEL(inst)) {
-			// insert key inst->p1 into hash table labels with value ninst (next instruction)
-			gravity_hash_insert(labels, VALUE_FROM_INT(inst->p1), VALUE_FROM_INT(ninst));
-			continue;
-		}
-		++ninst;
-	}
-
-	// +1 is just a trick so the VM switch loop terminates with an implicit RET0 instruction (RET0 has opcode 0)
-	f->ninsts = ninst;
-	bytecode = (uint32_t *)mem_alloc(NULL, (ninst+1) * sizeof(uint32_t));
-	assert(bytecode);
-
-	uint32_t j=0;
-	for (uint32_t i=0; i<count; ++i) {
-		inst_t *inst = ircode_get(code, i);
-		if (IS_SKIP(inst)) continue;
-		if (IS_LABEL(inst)) continue;
-		if (IS_PRAGMA_MOVE_OPT(inst)) continue;
-
-		uint32_t op = 0x0;
-		switch (inst->op) {
-			case HALT:
-			case RET0:
-			case NOP:
-				OPCODE_SET(op, inst->op);
-				break;
-
-			case LOAD:
-			case STORE:
-				++notpure;	// not sure here
-			case LOADS:
-			case LOADAT:
-			case STOREAT:
-			case EQQ:
-			case NEQQ:
-			case ISA:
-			case MATCH:
-			case LSHIFT:
-			case RSHIFT:
-			case BOR:
-			case BAND:
-			case BNOT:
-			case BXOR:
-			case ADD:
-			case SUB:
-			case DIV:
-			case MUL:
-			case REM:
-			case AND:
-			case OR:
-			case LT:
-			case GT:
-			case EQ:
-			case LEQ:
-			case GEQ:
-			case NEQ:
-			case NEG:
-			case NOT:
-				OPCODE_SET_TWO8bit_ONE10bit(op, inst->op, inst->p1, inst->p2, inst->p3);
-				break;
-
-			case LOADI:
-				OPCODE_SET_ONE8bit_SIGN_ONE17bit(op, inst->op, inst->p1, (inst->n < 0) ? 1 : 0, inst->n);
-				break;
-
-			case JUMPF: {
-				gravity_value_t *v = gravity_hash_lookup(labels, VALUE_FROM_INT(inst->p2));
-				assert(v); // key MUST exists!
-				uint32_t njump = (uint32_t)v->n;
-				uint32_t bflag = inst->p3;
-				OPCODE_SET_ONE8bit_SIGN_ONE17bit(op, inst->op, inst->p1, bflag, njump);
-				//OPCODE_SET_ONE8bit_ONE18bit(op, inst->op, inst->p1, njump);
-				break;
-			}
-
-			case RET:
-				OPCODE_SET_ONE8bit(op, inst->op, inst->p1);
-				break;
-
-			case JUMP: {
-				gravity_value_t *v = gravity_hash_lookup(labels, VALUE_FROM_INT(inst->p1));
-				assert(v); // key MUST exists!
-				uint32_t njump = (uint32_t)v->n;
-				OPCODE_SET_ONE26bit(op, inst->op, njump);
-				break;
-			}
-
-			case LOADG:
-			case STOREG:
-				++notpure;
-			case MOVE:
-			case LOADK:
-				OPCODE_SET_ONE8bit_ONE18bit(op, inst->op, inst->p1, inst->p2);
-				break;
-
-			case CALL:
-				OPCODE_SET_TWO8bit_ONE10bit(op, inst->op, inst->p1, inst->p2, inst->p3);
-				break;
-
-			case SETLIST:
-				OPCODE_SET_TWO8bit_ONE10bit(op, inst->op, inst->p1, inst->p2, inst->p3);
-				break;
-
-			case LOADU:
-			case STOREU:
-				++notpure;
-				OPCODE_SET_ONE8bit_ONE18bit(op, inst->op, inst->p1, inst->p2);
-				break;
-
-			case RANGENEW: {
-				uint8_t flag = (inst->tag == RANGE_INCLUDE_TAG) ? 0 : 1;
-				OPCODE_SET_THREE8bit_ONE2bit(op, inst->op, inst->p1, inst->p2, inst->p3, flag);
-				break;
-			}
-			case MAPNEW:
-			case LISTNEW:
-				OPCODE_SET_ONE8bit_ONE18bit(op, inst->op, inst->p1, inst->p2);
-				break;
-
-			case SWITCH:
-				assert(0);
-				break;
-
-			case CLOSURE:
-			case CLOSE:
-				OPCODE_SET_ONE8bit_ONE18bit(op, inst->op, inst->p1, inst->p2);
-				break;
-
-			case RESERVED1:
-			case RESERVED2:
-			case RESERVED3:
-			case RESERVED4:
-			case RESERVED5:
-			case RESERVED6:
-				assert(0);
-				break;
-		}
-
-		// store encoded instruction
-		bytecode[j++] = op;
-	}
-
-	ircode_free(code);
-	gravity_hash_free(labels);
-
-	f->bytecode = bytecode;
-	f->purity = (notpure == 0) ? 1.0f : ((float)(notpure * 100) / (float)ninst) / 100.0f;
+    ircode_t        *code = (ircode_t *)f->bytecode;
+    uint32_t        ninst = 0, count = ircode_count(code);
+    uint32_t        notpure = 0;
+    uint32_t        *bytecode = NULL;
+    gravity_hash_t    *labels = gravity_hash_create(0, hash_compute, hash_isequal, NULL, NULL);
+
+    // determine how big bytecode buffer must be
+    // and collect all LABEL instructions
+    for (uint32_t i=0; i<count; ++i) {
+        inst_t *inst = ircode_get(code, i);
+        if (IS_SKIP(inst)) continue;
+        if (IS_PRAGMA_MOVE_OPT(inst)) continue;
+        if (IS_LABEL(inst)) {
+            // insert key inst->p1 into hash table labels with value ninst (next instruction)
+            gravity_hash_insert(labels, VALUE_FROM_INT(inst->p1), VALUE_FROM_INT(ninst));
+            continue;
+        }
+        ++ninst;
+    }
+
+    // +1 is just a trick so the VM switch loop terminates with an implicit RET0 instruction (RET0 has opcode 0)
+    f->ninsts = ninst;
+    bytecode = (uint32_t *)mem_alloc(NULL, (ninst+1) * sizeof(uint32_t));
+    assert(bytecode);
+
+    uint32_t j=0;
+    for (uint32_t i=0; i<count; ++i) {
+        inst_t *inst = ircode_get(code, i);
+        if (IS_SKIP(inst)) continue;
+        if (IS_LABEL(inst)) continue;
+        if (IS_PRAGMA_MOVE_OPT(inst)) continue;
+
+        uint32_t op = 0x0;
+        switch (inst->op) {
+            case HALT:
+            case RET0:
+            case NOP:
+                OPCODE_SET(op, inst->op);
+                break;
+
+            case LOAD:
+            case STORE:
+                ++notpure;    // not sure here
+            case LOADS:
+            case LOADAT:
+            case STOREAT:
+            case EQQ:
+            case NEQQ:
+            case ISA:
+            case MATCH:
+            case LSHIFT:
+            case RSHIFT:
+            case BOR:
+            case BAND:
+            case BNOT:
+            case BXOR:
+            case ADD:
+            case SUB:
+            case DIV:
+            case MUL:
+            case REM:
+            case AND:
+            case OR:
+            case LT:
+            case GT:
+            case EQ:
+            case LEQ:
+            case GEQ:
+            case NEQ:
+            case NEG:
+            case NOT:
+                OPCODE_SET_TWO8bit_ONE10bit(op, inst->op, inst->p1, inst->p2, inst->p3);
+                break;
+
+            case LOADI:
+                OPCODE_SET_ONE8bit_SIGN_ONE17bit(op, inst->op, inst->p1, (inst->n < 0) ? 1 : 0, inst->n);
+                break;
+
+            case JUMPF: {
+                gravity_value_t *v = gravity_hash_lookup(labels, VALUE_FROM_INT(inst->p2));
+                assert(v); // key MUST exists!
+                uint32_t njump = (uint32_t)v->n;
+                uint32_t bflag = inst->p3;
+                OPCODE_SET_ONE8bit_SIGN_ONE17bit(op, inst->op, inst->p1, bflag, njump);
+                //OPCODE_SET_ONE8bit_ONE18bit(op, inst->op, inst->p1, njump);
+                break;
+            }
+
+            case RET:
+                OPCODE_SET_ONE8bit(op, inst->op, inst->p1);
+                break;
+
+            case JUMP: {
+                gravity_value_t *v = gravity_hash_lookup(labels, VALUE_FROM_INT(inst->p1));
+                assert(v); // key MUST exists!
+                uint32_t njump = (uint32_t)v->n;
+                OPCODE_SET_ONE26bit(op, inst->op, njump);
+                break;
+            }
+
+            case LOADG:
+            case STOREG:
+                ++notpure;
+            case MOVE:
+            case LOADK:
+                OPCODE_SET_ONE8bit_ONE18bit(op, inst->op, inst->p1, inst->p2);
+                break;
+
+            case CALL:
+                OPCODE_SET_TWO8bit_ONE10bit(op, inst->op, inst->p1, inst->p2, inst->p3);
+                break;
+
+            case SETLIST:
+                OPCODE_SET_TWO8bit_ONE10bit(op, inst->op, inst->p1, inst->p2, inst->p3);
+                break;
+
+            case LOADU:
+            case STOREU:
+                ++notpure;
+                OPCODE_SET_ONE8bit_ONE18bit(op, inst->op, inst->p1, inst->p2);
+                break;
+
+            case RANGENEW: {
+                uint8_t flag = (inst->tag == RANGE_INCLUDE_TAG) ? 0 : 1;
+                OPCODE_SET_THREE8bit_ONE2bit(op, inst->op, inst->p1, inst->p2, inst->p3, flag);
+                break;
+            }
+            case MAPNEW:
+            case LISTNEW:
+                OPCODE_SET_ONE8bit_ONE18bit(op, inst->op, inst->p1, inst->p2);
+                break;
+
+            case SWITCH:
+                assert(0);
+                break;
+
+            case CLOSURE:
+            case CLOSE:
+                OPCODE_SET_ONE8bit_ONE18bit(op, inst->op, inst->p1, inst->p2);
+                break;
+
+            case RESERVED1:
+            case RESERVED2:
+            case RESERVED3:
+            case RESERVED4:
+            case RESERVED5:
+            case RESERVED6:
+                assert(0);
+                break;
+        }
+
+        // store encoded instruction
+        bytecode[j++] = op;
+    }
+
+    ircode_free(code);
+    gravity_hash_free(labels);
+
+    f->bytecode = bytecode;
+    f->purity = (notpure == 0) ? 1.0f : ((float)(notpure * 100) / (float)ninst) / 100.0f;
 }
 }
 
 
 // MARK: -
 // MARK: -
 
 
 inline static bool pop1_instruction (ircode_t *code, uint32_t index, inst_t **inst1) {
 inline static bool pop1_instruction (ircode_t *code, uint32_t index, inst_t **inst1) {
-	*inst1 = NULL;
+    *inst1 = NULL;
 
 
-	for (int32_t i=index-1; i>=0; --i) {
-		inst_t *inst = ircode_get(code, i);
-		if ((inst != NULL) && (inst->tag != SKIP_TAG)) {
-			*inst1 = inst;
-			return true;
-		}
-	}
+    for (int32_t i=index-1; i>=0; --i) {
+        inst_t *inst = ircode_get(code, i);
+        if ((inst != NULL) && (inst->tag != SKIP_TAG)) {
+            *inst1 = inst;
+            return true;
+        }
+    }
 
 
-	return false;
+    return false;
 }
 }
 
 
 inline static bool pop2_instructions (ircode_t *code, uint32_t index, inst_t **inst1, inst_t **inst2) {
 inline static bool pop2_instructions (ircode_t *code, uint32_t index, inst_t **inst1, inst_t **inst2) {
-	*inst1 = NULL;
-	*inst2 = NULL;
-
-	for (int32_t i=index-1; i>=0; --i) {
-		inst_t *inst = ircode_get(code, i);
-		if ((inst != NULL) && (inst->tag != SKIP_TAG)) {
-			if (*inst1 == NULL) *inst1 = inst;
-			else if (*inst2 == NULL) {
-				*inst2 = inst;
-				return true;
-			}
-		}
-	}
-
-	return false;
+    *inst1 = NULL;
+    *inst2 = NULL;
+
+    for (int32_t i=index-1; i>=0; --i) {
+        inst_t *inst = ircode_get(code, i);
+        if ((inst != NULL) && (inst->tag != SKIP_TAG)) {
+            if (*inst1 == NULL) *inst1 = inst;
+            else if (*inst2 == NULL) {
+                *inst2 = inst;
+                return true;
+            }
+        }
+    }
+
+    return false;
 }
 }
 
 
 inline static inst_t *current_instruction (ircode_t *code, uint32_t i) {
 inline static inst_t *current_instruction (ircode_t *code, uint32_t i) {
-	while (1) {
-		inst_t *inst = ircode_get(code, i);
-		if (inst == NULL) return NULL;
-		if (inst->tag != SKIP_TAG) return inst;
-		++i;
-	}
-
-	return NULL;
+    while (1) {
+        inst_t *inst = ircode_get(code, i);
+        if (inst == NULL) return NULL;
+        if (inst->tag != SKIP_TAG) return inst;
+        ++i;
+    }
+
+    return NULL;
 }
 }
 
 
 // MARK: -
 // MARK: -
@@ -261,17 +261,17 @@ inline static inst_t *current_instruction (ircode_t *code, uint32_t i) {
 static bool optimize_const_instruction (inst_t *inst, inst_t *inst1, inst_t *inst2) {
 static bool optimize_const_instruction (inst_t *inst, inst_t *inst1, inst_t *inst2) {
     if (!inst2) return false;
     if (!inst2) return false;
     
     
-	// select type algorithm:
-	// two numeric types are supported here, int64 or double
-	// if types are equals then set the first one
-	// if types are not equals then set to double
-	optag_t	type;
-	double	d = 0.0, d1 = 0.0, d2 = 0.0;
-	int64_t	n = 0, n1 = 0, n2 = 0;
-
-	// compute types
-	if (inst1->tag == inst2->tag) type = inst1->tag;
-	else type = DOUBLE_TAG;
+    // select type algorithm:
+    // two numeric types are supported here, int64 or double
+    // if types are equals then set the first one
+    // if types are not equals then set to double
+    optag_t    type;
+    double    d = 0.0, d1 = 0.0, d2 = 0.0;
+    int64_t    n = 0, n1 = 0, n2 = 0;
+
+    // compute types
+    if (inst1->tag == inst2->tag) type = inst1->tag;
+    else type = DOUBLE_TAG;
 
 
     // check registers
     // check registers
     // code like:
     // code like:
@@ -288,248 +288,248 @@ static bool optimize_const_instruction (inst_t *inst, inst_t *inst1, inst_t *ins
     // so no optimizations must be performed
     // so no optimizations must be performed
     if (!(inst->p2 == inst1->p1 && inst->p3 == inst2->p2)) return false;
     if (!(inst->p2 == inst1->p1 && inst->p3 == inst2->p2)) return false;
     
     
-	// compute operands
-	if (type == DOUBLE_TAG) {
-		d1 = (inst1->tag == INT_TAG) ? (double)inst1->n : inst1->d;
-		d2 = (inst2->tag == INT_TAG) ? (double)inst2->n : inst2->d;
-	} else {
-		n1 = (inst1->tag == INT_TAG) ? inst1->n : (int64_t)inst1->d;
-		n2 = (inst2->tag == INT_TAG) ? inst2->n : (int64_t)inst2->d;
-	}
-
-	// perform operation
-	switch (inst->op) {
-		case ADD:
-			if (type == DOUBLE_TAG) d = d1 + d2;
-			else n = n1 + n2;
-			break;
-
-		case SUB:
-			if (type == DOUBLE_TAG) d = d1 - d2;
-			else n = n1 - n2;
-			break;
-
-		case MUL:
-			if (type == DOUBLE_TAG) d = d1 * d2;
-			else n = n1 * n2;
-			break;
-
-		case DIV:
-			// don't optimize in case of division by 0
-			if ((int64_t)d2 == 0) return false;
-			if (type == DOUBLE_TAG) d = d1 / d2;
-			else n = n1 / n2;
-			break;
-
-		case REM:
-			if ((int64_t)d2 == 0) return false;
-			if (type == DOUBLE_TAG) d = (double)((int64_t)d1 % (int64_t)d2);
-			else n = n1 % n2;
-			break;
-
-		default:
-			assert(0);
-	}
-
-	// adjust IRCODE
-	inst_setskip(inst1);
-	inst_setskip(inst2);
-
-	// convert an ADD instruction to a LOADI instruction
-	// ADD A B C	=> R(A) = R(B) + R(C)
-	// LOADI A B	=> R(A) = N
-	inst->op = LOADI;
-	inst->tag = type;
-	inst->p2 = inst->p3 = 0;
-	if (type == DOUBLE_TAG) inst->d = d;
-	else inst->n = n;
-
-	return true;
+    // compute operands
+    if (type == DOUBLE_TAG) {
+        d1 = (inst1->tag == INT_TAG) ? (double)inst1->n : inst1->d;
+        d2 = (inst2->tag == INT_TAG) ? (double)inst2->n : inst2->d;
+    } else {
+        n1 = (inst1->tag == INT_TAG) ? inst1->n : (int64_t)inst1->d;
+        n2 = (inst2->tag == INT_TAG) ? inst2->n : (int64_t)inst2->d;
+    }
+
+    // perform operation
+    switch (inst->op) {
+        case ADD:
+            if (type == DOUBLE_TAG) d = d1 + d2;
+            else n = n1 + n2;
+            break;
+
+        case SUB:
+            if (type == DOUBLE_TAG) d = d1 - d2;
+            else n = n1 - n2;
+            break;
+
+        case MUL:
+            if (type == DOUBLE_TAG) d = d1 * d2;
+            else n = n1 * n2;
+            break;
+
+        case DIV:
+            // don't optimize in case of division by 0
+            if ((int64_t)d2 == 0) return false;
+            if (type == DOUBLE_TAG) d = d1 / d2;
+            else n = n1 / n2;
+            break;
+
+        case REM:
+            if ((int64_t)d2 == 0) return false;
+            if (type == DOUBLE_TAG) d = (double)((int64_t)d1 % (int64_t)d2);
+            else n = n1 % n2;
+            break;
+
+        default:
+            assert(0);
+    }
+
+    // adjust IRCODE
+    inst_setskip(inst1);
+    inst_setskip(inst2);
+
+    // convert an ADD instruction to a LOADI instruction
+    // ADD A B C    => R(A) = R(B) + R(C)
+    // LOADI A B    => R(A) = N
+    inst->op = LOADI;
+    inst->tag = type;
+    inst->p2 = inst->p3 = 0;
+    if (type == DOUBLE_TAG) inst->d = d;
+    else inst->n = n;
+
+    return true;
 }
 }
 
 
 static bool optimize_neg_instruction (ircode_t *code, inst_t *inst, uint32_t i) {
 static bool optimize_neg_instruction (ircode_t *code, inst_t *inst, uint32_t i) {
-	inst_t *inst1 = NULL;
-	pop1_instruction(code, i, &inst1);
-	if (inst1 == NULL) return false;
-	if (inst1->op != LOADI) return false;
-	if (inst1->p1 != inst->p2) return false;
-	if (!ircode_register_istemp(code, inst1->p1)) return false;
-
-	uint64_t n = inst1->n;
-	if (n>131072) return false;
-	inst1->p1 = inst->p2;
-	inst1->n = -(int64_t)n;
-	inst_setskip(inst);
-	return true;
+    inst_t *inst1 = NULL;
+    pop1_instruction(code, i, &inst1);
+    if (inst1 == NULL) return false;
+    if (inst1->op != LOADI) return false;
+    if (inst1->p1 != inst->p2) return false;
+    if (!ircode_register_istemp(code, inst1->p1)) return false;
+
+    uint64_t n = inst1->n;
+    if (n>131072) return false;
+    inst1->p1 = inst->p2;
+    inst1->n = -(int64_t)n;
+    inst_setskip(inst);
+    return true;
 }
 }
 
 
 static bool optimize_math_instruction (ircode_t *code, inst_t *inst, uint32_t i) {
 static bool optimize_math_instruction (ircode_t *code, inst_t *inst, uint32_t i) {
-	uint8_t count = opcode_numop(inst->op) - 1;
-	inst_t *inst1 = NULL, *inst2 = NULL;
-	bool	flag = false;
-
-	if (count == 2) {
-		pop2_instructions(code, i, &inst2, &inst1);
-		if (IS_NUM(inst1) && IS_NUM(inst2)) flag = optimize_const_instruction(inst, inst1, inst2);
-
-		// process inst2
-		if (IS_MOVE(inst2)) {
-			bool b1 = ircode_register_istemp(code, inst->p3);
-			bool b2 = ((inst2) && ircode_register_istemp(code, inst2->p1));
-			if ((b1) && (b2) && (inst->p3 == inst2->p1)) {
-				inst->p3 = inst2->p2;
-				inst_setskip(inst2);
-				flag = true;
-			}
-		}
-
-		// process inst1
-		if (IS_MOVE(inst1)) {
-			bool b1 = ircode_register_istemp(code, inst->p2);
-			bool b2 = ((inst1) && ircode_register_istemp(code, inst1->p1));
-			if ((b1) && (b2) && (inst->p2 == inst1->p1)) {
-				inst->p2 = inst1->p2;
-				inst_setskip(inst1);
-				flag = true;
-			}
-		}
-
-	}
-	else {
-		pop1_instruction(code, i, &inst1);
-		if (IS_NUM(inst1)) flag = optimize_const_instruction(inst, inst1, NULL);
-	}
-
-	return flag;
+    uint8_t count = opcode_numop(inst->op) - 1;
+    inst_t *inst1 = NULL, *inst2 = NULL;
+    bool    flag = false;
+
+    if (count == 2) {
+        pop2_instructions(code, i, &inst2, &inst1);
+        if (IS_NUM(inst1) && IS_NUM(inst2)) flag = optimize_const_instruction(inst, inst1, inst2);
+
+        // process inst2
+        if (IS_MOVE(inst2)) {
+            bool b1 = ircode_register_istemp(code, inst->p3);
+            bool b2 = ((inst2) && ircode_register_istemp(code, inst2->p1));
+            if ((b1) && (b2) && (inst->p3 == inst2->p1)) {
+                inst->p3 = inst2->p2;
+                inst_setskip(inst2);
+                flag = true;
+            }
+        }
+
+        // process inst1
+        if (IS_MOVE(inst1)) {
+            bool b1 = ircode_register_istemp(code, inst->p2);
+            bool b2 = ((inst1) && ircode_register_istemp(code, inst1->p1));
+            if ((b1) && (b2) && (inst->p2 == inst1->p1)) {
+                inst->p2 = inst1->p2;
+                inst_setskip(inst1);
+                flag = true;
+            }
+        }
+
+    }
+    else {
+        pop1_instruction(code, i, &inst1);
+        if (IS_NUM(inst1)) flag = optimize_const_instruction(inst, inst1, NULL);
+    }
+
+    return flag;
 }
 }
 
 
 static bool optimize_move_instruction (ircode_t *code, inst_t *inst, uint32_t i) {
 static bool optimize_move_instruction (ircode_t *code, inst_t *inst, uint32_t i) {
-	inst_t *inst1 = NULL;
-	pop1_instruction(code, i, &inst1);
-	if (inst1 == NULL) return false;
-	if ((inst1->op != LOADI) && (inst1->op != LOADG) && (inst1->op != LOADK)) return false;
+    inst_t *inst1 = NULL;
+    pop1_instruction(code, i, &inst1);
+    if (inst1 == NULL) return false;
+    if ((inst1->op != LOADI) && (inst1->op != LOADG) && (inst1->op != LOADK)) return false;
 
 
-	bool b1 = ircode_register_istemp(code, inst->p2);
-	bool b2 = ((inst1) && ircode_register_istemp(code, inst1->p1));
+    bool b1 = ircode_register_istemp(code, inst->p2);
+    bool b2 = ((inst1) && ircode_register_istemp(code, inst1->p1));
 
 
-	if ((b1) && (b2) && (inst->p2 == inst1->p1)) {
-		inst1->p1 = inst->p1;
-		inst_setskip(inst);
-		return true;
-	}
+    if ((b1) && (b2) && (inst->p2 == inst1->p1)) {
+        inst1->p1 = inst->p1;
+        inst_setskip(inst);
+        return true;
+    }
 
 
-	return false;
+    return false;
 }
 }
 
 
 static bool optimize_return_instruction (ircode_t *code, inst_t *inst, uint32_t i) {
 static bool optimize_return_instruction (ircode_t *code, inst_t *inst, uint32_t i) {
-	inst_t *inst1 = NULL;
-	pop1_instruction(code, i, &inst1);
+    inst_t *inst1 = NULL;
+    pop1_instruction(code, i, &inst1);
 
 
-	if (!ircode_register_istemp(code, inst->p1)) return false;
-	if ((IS_MOVE(inst1)) && (inst->p1 == inst1->p1)) {
-		inst->p1 = inst1->p2;
-		inst_setskip(inst1);
-		return true;
-	}
+    if (!ircode_register_istemp(code, inst->p1)) return false;
+    if ((IS_MOVE(inst1)) && (inst->p1 == inst1->p1)) {
+        inst->p1 = inst1->p2;
+        inst_setskip(inst1);
+        return true;
+    }
 
 
-	return false;
+    return false;
 }
 }
 
 
 static bool optimize_num_instruction (inst_t *inst, gravity_function_t *f) {
 static bool optimize_num_instruction (inst_t *inst, gravity_function_t *f) {
 
 
-	// double values always added to constant pool
-	bool add_cpool = (inst->tag == DOUBLE_TAG);
-
-	// LOADI is a 32bit instruction
-	// 32 - 6 (OPCODE) - 8 (register) - 1 bit sign = 17
-	// range is from MAX_INLINE_INT-1 to MAX_INLINE_INT
-	// so max/min values are in the range -(2^17)-1/+2^17
-	// 2^17 = 131072 (MAX_INLINE_INT)
-	if (inst->tag == INT_TAG) {
-		int64_t n = inst->n;
-		add_cpool = ((n < -MAX_INLINE_INT + 1) || (n > MAX_INLINE_INT));
-	}
-
-	if (add_cpool) {
-		uint16_t index = 0;
-		if (inst->tag == INT_TAG) {
-			int64_t n = inst->n;
-			index = gravity_function_cpool_add(NULL, f, VALUE_FROM_INT(n));
-		} else {
-			// always add floating point values as double in constant pool (then VM will be configured to interpret it as float or double)
-			index = gravity_function_cpool_add(NULL, f, VALUE_FROM_FLOAT(inst->d));
-		}
-
-		// replace LOADI with a LOADK instruction
-		inst->op = LOADK;
-		inst->p2 = index;
-		inst->tag = NO_TAG;
-	}
-
-	return true;
+    // double values always added to constant pool
+    bool add_cpool = (inst->tag == DOUBLE_TAG);
+
+    // LOADI is a 32bit instruction
+    // 32 - 6 (OPCODE) - 8 (register) - 1 bit sign = 17
+    // range is from MAX_INLINE_INT-1 to MAX_INLINE_INT
+    // so max/min values are in the range -(2^17)-1/+2^17
+    // 2^17 = 131072 (MAX_INLINE_INT)
+    if (inst->tag == INT_TAG) {
+        int64_t n = inst->n;
+        add_cpool = ((n < -MAX_INLINE_INT + 1) || (n > MAX_INLINE_INT));
+    }
+
+    if (add_cpool) {
+        uint16_t index = 0;
+        if (inst->tag == INT_TAG) {
+            int64_t n = inst->n;
+            index = gravity_function_cpool_add(NULL, f, VALUE_FROM_INT(n));
+        } else {
+            // always add floating point values as double in constant pool (then VM will be configured to interpret it as float or double)
+            index = gravity_function_cpool_add(NULL, f, VALUE_FROM_FLOAT(inst->d));
+        }
+
+        // replace LOADI with a LOADK instruction
+        inst->op = LOADK;
+        inst->p2 = index;
+        inst->tag = NO_TAG;
+    }
+
+    return true;
 }
 }
 
 
 // MARK: -
 // MARK: -
 
 
 gravity_function_t *gravity_optimizer(gravity_function_t *f) {
 gravity_function_t *gravity_optimizer(gravity_function_t *f) {
-	if (f->bytecode == NULL) return f;
-
-	ircode_t	*code = (ircode_t *)f->bytecode;
-	uint32_t	count = ircode_count(code);
-	bool		optimizer = true;
-
-	f->ntemps = ircode_ntemps(code);
-
-	loop_neg:
-	for (uint32_t i=0; i<count; ++i) {
-		inst_t *inst = current_instruction(code, i);
-		if (IS_NEG(inst)) {
-			bool b = optimize_neg_instruction (code, inst, i);
-			if (b) goto loop_neg;
-		}
-	}
-
-	loop_math:
-	for (uint32_t i=0; i<count; ++i) {
-		inst_t *inst = current_instruction(code, i);
-		if (IS_MATH(inst)) {
-			bool b = optimize_math_instruction (code, inst, i);
-			if (b) goto loop_math;
-		}
-	}
-
-	loop_move:
-	optimizer = true;
-	for (uint32_t i=0; i<count; ++i) {
-		inst_t *inst = current_instruction(code, i);
-		if (IS_PRAGMA_MOVE_OPT(inst)) optimizer = (bool)inst->p1;
-		if (optimizer && IS_MOVE(inst)) {
-			bool b = optimize_move_instruction (code, inst, i);
-			if (b) goto loop_move;
-		}
-	}
-
-	loop_ret:
-	for (uint32_t i=0; i<count; ++i) {
-		inst_t *inst = current_instruction(code, i);
-		if (IS_RET(inst)) {
-			bool b = optimize_return_instruction (code, inst, i);
-			if (b) goto loop_ret;
-		}
-	}
-
-	for (uint32_t i=0; i<count; ++i) {
-		inst_t *inst = current_instruction(code, i);
-		if (IS_NUM(inst)) optimize_num_instruction (inst, f);
-	}
-
-	// dump optimized version
-	#if GRAVITY_BYTECODE_DEBUG
-	gravity_function_dump(f, ircode_dump);
-	#endif
-
-	// finalize function
-	finalize_function(f);
-
-	return f;
+    if (f->bytecode == NULL) return f;
+
+    ircode_t    *code = (ircode_t *)f->bytecode;
+    uint32_t    count = ircode_count(code);
+    bool        optimizer = true;
+
+    f->ntemps = ircode_ntemps(code);
+
+    loop_neg:
+    for (uint32_t i=0; i<count; ++i) {
+        inst_t *inst = current_instruction(code, i);
+        if (IS_NEG(inst)) {
+            bool b = optimize_neg_instruction (code, inst, i);
+            if (b) goto loop_neg;
+        }
+    }
+
+    loop_math:
+    for (uint32_t i=0; i<count; ++i) {
+        inst_t *inst = current_instruction(code, i);
+        if (IS_MATH(inst)) {
+            bool b = optimize_math_instruction (code, inst, i);
+            if (b) goto loop_math;
+        }
+    }
+
+    loop_move:
+    optimizer = true;
+    for (uint32_t i=0; i<count; ++i) {
+        inst_t *inst = current_instruction(code, i);
+        if (IS_PRAGMA_MOVE_OPT(inst)) optimizer = (bool)inst->p1;
+        if (optimizer && IS_MOVE(inst)) {
+            bool b = optimize_move_instruction (code, inst, i);
+            if (b) goto loop_move;
+        }
+    }
+
+    loop_ret:
+    for (uint32_t i=0; i<count; ++i) {
+        inst_t *inst = current_instruction(code, i);
+        if (IS_RET(inst)) {
+            bool b = optimize_return_instruction (code, inst, i);
+            if (b) goto loop_ret;
+        }
+    }
+
+    for (uint32_t i=0; i<count; ++i) {
+        inst_t *inst = current_instruction(code, i);
+        if (IS_NUM(inst)) optimize_num_instruction (inst, f);
+    }
+
+    // dump optimized version
+    #if GRAVITY_BYTECODE_DEBUG
+    gravity_function_dump(f, ircode_dump);
+    #endif
+
+    // finalize function
+    finalize_function(f);
+
+    return f;
 }
 }

File diff suppressed because it is too large
+ 435 - 435
src/compiler/gravity_parser.c


+ 13 - 13
src/compiler/gravity_parser.h

@@ -14,26 +14,26 @@
 #include "gravity_ast.h"
 #include "gravity_ast.h"
 
 
 /*
 /*
-	Parser is responsible to build the AST, convert strings and number from tokens and
-	implement syntax error recovery strategy.
+    Parser is responsible to build the AST, convert strings and number from tokens and
+    implement syntax error recovery strategy.
 
 
-	Notes about error recovery:
-	Each parse* function can return NULL in case of error but each function is RESPONSIBLE
-	to make appropriate actions in order to handle/recover errors.
+    Notes about error recovery:
+    Each parse* function can return NULL in case of error but each function is RESPONSIBLE
+    to make appropriate actions in order to handle/recover errors.
 
 
-	Error recovery techniques can be:
-	Shallow Error Recovery
-	Deep Error Recovery
-	https://javacc.java.net/doc/errorrecovery.html
+    Error recovery techniques can be:
+    Shallow Error Recovery
+    Deep Error Recovery
+    https://javacc.java.net/doc/errorrecovery.html
 
 
  */
  */
 
 
 // opaque datatype
 // opaque datatype
-typedef struct gravity_parser_t	gravity_parser_t;
+typedef struct gravity_parser_t    gravity_parser_t;
 
 
 // public functions
 // public functions
-gravity_parser_t	*gravity_parser_create (const char *source, size_t len, uint32_t fileid, bool is_static);
-gnode_t				*gravity_parser_run (gravity_parser_t *parser, gravity_delegate_t *delegate);
-void				gravity_parser_free (gravity_parser_t *parser);
+gravity_parser_t    *gravity_parser_create (const char *source, size_t len, uint32_t fileid, bool is_static);
+gnode_t             *gravity_parser_run (gravity_parser_t *parser, gravity_delegate_t *delegate);
+void                gravity_parser_free (gravity_parser_t *parser);
 
 
 #endif
 #endif

+ 108 - 108
src/compiler/gravity_semacheck1.c

@@ -11,17 +11,17 @@
 #include "gravity_compiler.h"
 #include "gravity_compiler.h"
 #include "gravity_visitor.h"
 #include "gravity_visitor.h"
 
 
-#define REPORT_ERROR(node,...)			{report_error(self, (gnode_t *)node, __VA_ARGS__); return;}
+#define REPORT_ERROR(node,...)          {report_error(self, (gnode_t *)node, __VA_ARGS__); return;}
 
 
-#define DECLARE_SYMTABLE()				symboltable_t *symtable = (symboltable_t *)self->data
-#define SAVE_SYMTABLE()					symboltable_t *saved = symtable
-#define CREATE_SYMTABLE(tag)			INC_IDENT; SAVE_SYMTABLE(); self->data = (void *)symboltable_create(tag);
-#define RESTORE_SYMTABLE()				DEC_IDENT; node->symtable = ((symboltable_t *)self->data); self->data = (void *)saved
+#define DECLARE_SYMTABLE()              symboltable_t *symtable = (symboltable_t *)self->data
+#define SAVE_SYMTABLE()                 symboltable_t *saved = symtable
+#define CREATE_SYMTABLE(tag)            INC_IDENT; SAVE_SYMTABLE(); self->data = (void *)symboltable_create(tag);
+#define RESTORE_SYMTABLE()              DEC_IDENT; node->symtable = ((symboltable_t *)self->data); self->data = (void *)saved
 
 
 #if GRAVITY_SYMTABLE_DEBUG
 #if GRAVITY_SYMTABLE_DEBUG
 static int ident =0;
 static int ident =0;
-#define INC_IDENT		++ident
-#define DEC_IDENT		--ident
+#define INC_IDENT        ++ident
+#define DEC_IDENT        --ident
 #else
 #else
 #define INC_IDENT
 #define INC_IDENT
 #define DEC_IDENT
 #define DEC_IDENT
@@ -30,56 +30,56 @@ static int ident =0;
 // MARK: -
 // MARK: -
 
 
 static void report_error (gvisitor_t *self, gnode_t *node, const char *format, ...) {
 static void report_error (gvisitor_t *self, gnode_t *node, const char *format, ...) {
-	// increment internal error counter
-	++self->nerr;
+    // increment internal error counter
+    ++self->nerr;
 
 
     // sanity check
     // sanity check
     if (!node) return;
     if (!node) return;
     
     
-	// get error callback (if any)
-	void *data = (self->delegate) ? ((gravity_delegate_t *)self->delegate)->xdata : NULL;
-	gravity_error_callback error_fn = (self->delegate) ? ((gravity_delegate_t *)self->delegate)->error_callback : NULL;
-
-	// build error message
-	char		buffer[1024];
-	va_list		arg;
-	if (format) {
-		va_start (arg, format);
-		vsnprintf(buffer, sizeof(buffer), format, arg);
-		va_end (arg);
-	}
-
-	// setup error struct
-	error_desc_t error_desc = {
-		.lineno = node->token.lineno,
-		.colno = node->token.colno,
-		.fileid = node->token.fileid,
-		.offset = node->token.position,
+    // get error callback (if any)
+    void *data = (self->delegate) ? ((gravity_delegate_t *)self->delegate)->xdata : NULL;
+    gravity_error_callback error_fn = (self->delegate) ? ((gravity_delegate_t *)self->delegate)->error_callback : NULL;
+
+    // build error message
+    char        buffer[1024];
+    va_list        arg;
+    if (format) {
+        va_start (arg, format);
+        vsnprintf(buffer, sizeof(buffer), format, arg);
+        va_end (arg);
+    }
+
+    // setup error struct
+    error_desc_t error_desc = {
+        .lineno = node->token.lineno,
+        .colno = node->token.colno,
+        .fileid = node->token.fileid,
+        .offset = node->token.position,
         .meta = meta_from_node(node)
         .meta = meta_from_node(node)
-	};
+    };
 
 
-	// finally call error callback
-	if (error_fn) error_fn(NULL, GRAVITY_ERROR_SEMANTIC, buffer, error_desc, data);
-	else printf("%s\n", buffer);
+    // finally call error callback
+    if (error_fn) error_fn(NULL, GRAVITY_ERROR_SEMANTIC, buffer, error_desc, data);
+    else printf("%s\n", buffer);
 }
 }
 
 
 // MARK: - Declarations -
 // MARK: - Declarations -
 
 
 static void visit_list_stmt (gvisitor_t *self, gnode_compound_stmt_t *node) {
 static void visit_list_stmt (gvisitor_t *self, gnode_compound_stmt_t *node) {
-	DECLARE_SYMTABLE();
+    DECLARE_SYMTABLE();
     DEBUG_SYMTABLE("GLOBALS");
     DEBUG_SYMTABLE("GLOBALS");
 
 
-	node->symtable = symtable;	// GLOBALS
-	gnode_array_each(node->stmts, {
+    node->symtable = symtable;    // GLOBALS
+    gnode_array_each(node->stmts, {
         visit(val);
         visit(val);
     });
     });
 }
 }
 
 
 static void visit_function_decl (gvisitor_t *self, gnode_function_decl_t *node) {
 static void visit_function_decl (gvisitor_t *self, gnode_function_decl_t *node) {
-	DECLARE_SYMTABLE();
-	DEBUG_SYMTABLE("function: %s", node->identifier);
+    DECLARE_SYMTABLE();
+    DEBUG_SYMTABLE("function: %s", node->identifier);
 
 
-	// function identifier
+    // function identifier
     const char *identifier = node->identifier;
     const char *identifier = node->identifier;
     
     
     // reserve a special name for static objects defined inside a class
     // reserve a special name for static objects defined inside a class
@@ -90,22 +90,22 @@ static void visit_function_decl (gvisitor_t *self, gnode_function_decl_t *node)
         identifier = (const char *)buffer;
         identifier = (const char *)buffer;
     }
     }
     
     
-	// function identifier
+    // function identifier
     if (!symboltable_insert(symtable, identifier, (void *)node)) {
     if (!symboltable_insert(symtable, identifier, (void *)node)) {
-		REPORT_ERROR(node, "Identifier %s redeclared.", node->identifier);
+        REPORT_ERROR(node, "Identifier %s redeclared.", node->identifier);
     }
     }
 
 
-	// we are just interested in non-local declarations so don't further scan function node
-	// node->symtable is NULL here and it will be created in semacheck2
+    // we are just interested in non-local declarations so don't further scan function node
+    // node->symtable is NULL here and it will be created in semacheck2
 }
 }
 
 
 static void visit_variable_decl (gvisitor_t *self, gnode_variable_decl_t *node) {
 static void visit_variable_decl (gvisitor_t *self, gnode_variable_decl_t *node) {
-	DECLARE_SYMTABLE();
+    DECLARE_SYMTABLE();
     char buffer[512];
     char buffer[512];
 
 
     bool is_static = (node->storage == TOK_KEY_STATIC);
     bool is_static = (node->storage == TOK_KEY_STATIC);
-	gnode_array_each(node->decls, {
-		gnode_var_t *p = (gnode_var_t *)val;
+    gnode_array_each(node->decls, {
+        gnode_var_t *p = (gnode_var_t *)val;
         
         
         // variable identifier
         // variable identifier
         const char  *identifier = p->identifier;
         const char  *identifier = p->identifier;
@@ -118,7 +118,7 @@ static void visit_variable_decl (gvisitor_t *self, gnode_variable_decl_t *node)
         }
         }
         
         
         if (!symboltable_insert(symtable, identifier, (void *)p)) {
         if (!symboltable_insert(symtable, identifier, (void *)p)) {
-			REPORT_ERROR(p, "Identifier %s redeclared.", p->identifier);
+            REPORT_ERROR(p, "Identifier %s redeclared.", p->identifier);
         }
         }
         
         
         // in CLASS case set a relative ivar index (if ivar is not computed)
         // in CLASS case set a relative ivar index (if ivar is not computed)
@@ -128,26 +128,26 @@ static void visit_variable_decl (gvisitor_t *self, gnode_variable_decl_t *node)
         } else {
         } else {
             DEBUG_SYMTABLE("variable: %s", p->identifier);
             DEBUG_SYMTABLE("variable: %s", p->identifier);
         }
         }
-	});
+    });
 }
 }
 
 
 static void visit_enum_decl (gvisitor_t *self, gnode_enum_decl_t *node) {
 static void visit_enum_decl (gvisitor_t *self, gnode_enum_decl_t *node) {
-	DECLARE_SYMTABLE();
+    DECLARE_SYMTABLE();
 
 
-	DEBUG_SYMTABLE("enum: %s", node->identifier);
+    DEBUG_SYMTABLE("enum: %s", node->identifier);
 
 
-	// check enum identifier uniqueness in current symbol table
+    // check enum identifier uniqueness in current symbol table
     if (!symboltable_insert(symtable, node->identifier, (void *)node)) {
     if (!symboltable_insert(symtable, node->identifier, (void *)node)) {
-		REPORT_ERROR(node, "Identifier %s redeclared.", node->identifier);
-	}
+        REPORT_ERROR(node, "Identifier %s redeclared.", node->identifier);
+    }
 }
 }
 
 
 static void visit_class_decl (gvisitor_t *self, gnode_class_decl_t *node) {
 static void visit_class_decl (gvisitor_t *self, gnode_class_decl_t *node) {
-	DECLARE_SYMTABLE();
+    DECLARE_SYMTABLE();
 
 
-	DEBUG_SYMTABLE("class: %s", node->identifier);
+    DEBUG_SYMTABLE("class: %s", node->identifier);
 
 
-	// class identifier
+    // class identifier
     const char *identifier = node->identifier;
     const char *identifier = node->identifier;
     
     
     // reserve a special name for static objects defined inside a class
     // reserve a special name for static objects defined inside a class
@@ -158,79 +158,79 @@ static void visit_class_decl (gvisitor_t *self, gnode_class_decl_t *node) {
         identifier = (const char *)buffer;
         identifier = (const char *)buffer;
     }
     }
     
     
-	// class identifier
+    // class identifier
     if (!symboltable_insert(symtable, identifier, (void *)node)) {
     if (!symboltable_insert(symtable, identifier, (void *)node)) {
-		REPORT_ERROR(node, "Identifier %s redeclared.", node->identifier);
+        REPORT_ERROR(node, "Identifier %s redeclared.", node->identifier);
     }
     }
 
 
-	CREATE_SYMTABLE(SYMTABLE_TAG_CLASS);
-	gnode_array_each(node->decls, {
-		visit(val);
-	});
-	RESTORE_SYMTABLE();
+    CREATE_SYMTABLE(SYMTABLE_TAG_CLASS);
+    gnode_array_each(node->decls, {
+        visit(val);
+    });
+    RESTORE_SYMTABLE();
 }
 }
 
 
 static void visit_module_decl (gvisitor_t *self, gnode_module_decl_t *node) {
 static void visit_module_decl (gvisitor_t *self, gnode_module_decl_t *node) {
-	DECLARE_SYMTABLE();
+    DECLARE_SYMTABLE();
 
 
-	DEBUG_SYMTABLE("module: %s", node->identifier);
+    DEBUG_SYMTABLE("module: %s", node->identifier);
 
 
-	// module identifier
+    // module identifier
     if (!symboltable_insert(symtable, node->identifier, (void *)node)) {
     if (!symboltable_insert(symtable, node->identifier, (void *)node)) {
-		REPORT_ERROR(node, "Identifier %s redeclared.", node->identifier);
+        REPORT_ERROR(node, "Identifier %s redeclared.", node->identifier);
     }
     }
 
 
-	CREATE_SYMTABLE(SYMTABLE_TAG_MODULE);
-	gnode_array_each(node->decls, {
-		visit(val);
-	});
-	RESTORE_SYMTABLE();
+    CREATE_SYMTABLE(SYMTABLE_TAG_MODULE);
+    gnode_array_each(node->decls, {
+        visit(val);
+    });
+    RESTORE_SYMTABLE();
 }
 }
 
 
 // MARK: -
 // MARK: -
 
 
 bool gravity_semacheck1 (gnode_t *node, gravity_delegate_t *delegate) {
 bool gravity_semacheck1 (gnode_t *node, gravity_delegate_t *delegate) {
-	symboltable_t *context = symboltable_create(SYMTABLE_TAG_GLOBAL);
+    symboltable_t *context = symboltable_create(SYMTABLE_TAG_GLOBAL);
 
 
-	gvisitor_t visitor = {
-		.nerr = 0,							// used to store number of found errors
-		.data = (void *)context,			// used to store a pointer to the global symbol table
-		.delegate = (void *)delegate,		// compiler delegate to report errors
+    gvisitor_t visitor = {
+        .nerr = 0,                            // used to store number of found errors
+        .data = (void *)context,            // used to store a pointer to the global symbol table
+        .delegate = (void *)delegate,        // compiler delegate to report errors
 
 
         // COMMON
         // COMMON
         .visit_pre = NULL,
         .visit_pre = NULL,
         .visit_post = NULL,
         .visit_post = NULL,
 
 
-		// STATEMENTS: 7
-		.visit_list_stmt = visit_list_stmt,
-		.visit_compound_stmt = NULL,
-		.visit_label_stmt = NULL,
-		.visit_flow_stmt = NULL,
-		.visit_loop_stmt = NULL,
-		.visit_jump_stmt = NULL,
-		.visit_empty_stmt = NULL,
-
-		// DECLARATIONS: 5
-		.visit_function_decl = visit_function_decl,
-		.visit_variable_decl = visit_variable_decl,
-		.visit_enum_decl = visit_enum_decl,
-		.visit_class_decl = visit_class_decl,
-		.visit_module_decl = visit_module_decl,
-
-		// EXPRESSIONS: 8
-		.visit_binary_expr = NULL,
-		.visit_unary_expr = NULL,
-		.visit_file_expr = NULL,
-		.visit_literal_expr = NULL,
-		.visit_identifier_expr = NULL,
-		.visit_keyword_expr = NULL,
-		.visit_list_expr = NULL,
-		.visit_postfix_expr = NULL,
-	};
-
-	DEBUG_SYMTABLE("=== SYMBOL TABLE ===");
-	gvisit(&visitor, node);
-	DEBUG_SYMTABLE("====================\n");
-
-	return (visitor.nerr == 0);
+        // STATEMENTS: 7
+        .visit_list_stmt = visit_list_stmt,
+        .visit_compound_stmt = NULL,
+        .visit_label_stmt = NULL,
+        .visit_flow_stmt = NULL,
+        .visit_loop_stmt = NULL,
+        .visit_jump_stmt = NULL,
+        .visit_empty_stmt = NULL,
+
+        // DECLARATIONS: 5
+        .visit_function_decl = visit_function_decl,
+        .visit_variable_decl = visit_variable_decl,
+        .visit_enum_decl = visit_enum_decl,
+        .visit_class_decl = visit_class_decl,
+        .visit_module_decl = visit_module_decl,
+
+        // EXPRESSIONS: 8
+        .visit_binary_expr = NULL,
+        .visit_unary_expr = NULL,
+        .visit_file_expr = NULL,
+        .visit_literal_expr = NULL,
+        .visit_identifier_expr = NULL,
+        .visit_keyword_expr = NULL,
+        .visit_list_expr = NULL,
+        .visit_postfix_expr = NULL,
+    };
+
+    DEBUG_SYMTABLE("=== SYMBOL TABLE ===");
+    gvisit(&visitor, node);
+    DEBUG_SYMTABLE("====================\n");
+
+    return (visitor.nerr == 0);
 }
 }

+ 21 - 21
src/compiler/gravity_semacheck1.h

@@ -20,35 +20,35 @@
 
 
 // Semantic Check Step 1 enables to resolve cases like:
 // Semantic Check Step 1 enables to resolve cases like:
 /*
 /*
-		function foo() {
-			return bar();
-		}
+        function foo() {
+            return bar();
+        }
 
 
-		function bar() {
-			...
-		}
+        function bar() {
+            ...
+        }
 
 
-		or
+        or
 
 
-		class foo:bar {
-			...
-		}
+        class foo:bar {
+            ...
+        }
 
 
-		class bar {
-			...
-		}
+        class bar {
+            ...
+        }
 
 
-		and
+        and
 
 
-		class foo {
-			var a;
+        class foo {
+            var a;
 
 
-			function bar() {
-				return a + b;
-			}
+            function bar() {
+                return a + b;
+            }
 
 
-			var b;
-		}
+            var b;
+        }
  */
  */
 
 
 // It's a mandatory step in order to account for forward references
 // It's a mandatory step in order to account for forward references

File diff suppressed because it is too large
+ 433 - 433
src/compiler/gravity_semacheck2.c


+ 26 - 26
src/compiler/gravity_semacheck2.h

@@ -19,43 +19,43 @@ bool gravity_semacheck2(gnode_t *node, gravity_delegate_t *delegate);
 
 
 /*
 /*
 
 
-	The following table summarizes what can be defined inside a declaration:
+    The following table summarizes what can be defined inside a declaration:
 
 
     -------+---------------------------------------------------------+
     -------+---------------------------------------------------------+
-	       |   func   |   var   |   enum   |   class   |   module    |
-	-------+---------------------------------------------------------+
-	func   |   YES    |   YES   |   NO     |   YES     |   YES       |
+           |   func   |   var   |   enum   |   class   |   module    |
     -------+---------------------------------------------------------+
     -------+---------------------------------------------------------+
-	var    |   YES    |   NO    |   NO     |   YES     |   YES       |
-	-------+---------------------------------------------------------+
-	enum   |   YES    |   NO    |   NO     |   YES     |   YES       |
+    func   |   YES    |   YES   |   NO     |   YES     |   YES       |
     -------+---------------------------------------------------------+
     -------+---------------------------------------------------------+
-	class  |   YES    |   NO    |   NO     |   YES     |   YES       |
+    var    |   YES    |   NO    |   NO     |   YES     |   YES       |
     -------+---------------------------------------------------------+
     -------+---------------------------------------------------------+
-	module |   NO     |   NO    |   NO     |   NO      |   NO        |
+    enum   |   YES    |   NO    |   NO     |   YES     |   YES       |
+    -------+---------------------------------------------------------+
+    class  |   YES    |   NO    |   NO     |   YES     |   YES       |
+    -------+---------------------------------------------------------+
+    module |   NO     |   NO    |   NO     |   NO      |   NO        |
     -------+---------------------------------------------------------+
     -------+---------------------------------------------------------+
 
 
-	Everything declared inside a func is a local, so for example:
+    Everything declared inside a func is a local, so for example:
 
 
-	func foo {
-		func a...;
-		enum b...;
-		class c..;
-	}
+    func foo {
+        func a...;
+        enum b...;
+        class c..;
+    }
 
 
-	is converted by codegen to:
+    is converted by codegen to:
 
 
-	func foo {
-		var a = func...;
-		var b = enum...;
-		var c = class..;
-	}
+    func foo {
+        var a = func...;
+        var b = enum...;
+        var c = class..;
+    }
 
 
-	Even if the ONLY valid syntax is anonymous func assignment, user will not be able
-	to assign an anonymous enum or class to a variable. Restriction is applied by parser
-	and reported as a syntax error.
-	Define a module inside a function is not allowed (no real technical reason but I found
-	it a very bad programming practice), restriction is applied by samantic checker.
+    Even if the ONLY valid syntax is anonymous func assignment, user will not be able
+    to assign an anonymous enum or class to a variable. Restriction is applied by parser
+    and reported as a syntax error.
+    Define a module inside a function is not allowed (no real technical reason but I found
+    it a very bad programming practice), restriction is applied by samantic checker.
 
 
  */
  */
 
 

+ 88 - 88
src/compiler/gravity_symboltable.c

@@ -12,23 +12,23 @@
 #include "gravity_hash.h"
 #include "gravity_hash.h"
 
 
 // symbol table implementation using a stack of hash tables
 // symbol table implementation using a stack of hash tables
-typedef marray_t(gravity_hash_t*)	ghash_r;
+typedef marray_t(gravity_hash_t*)       ghash_r;
 
 
-#define scope_stack_init(r)			marray_init(*r)
-#define scope_stack_size(r)			marray_size(*r)
-#define scope_stack_get(r,n)		marray_get(*r,n)
-#define scope_stack_free(r)			marray_destroy(*r)
-#define scope_stack_push(r,hash)	marray_push(gravity_hash_t*,*r,hash)
-#define scope_stack_pop(r)			(marray_size(*r) ? marray_pop(*r) : NULL)
+#define scope_stack_init(r)             marray_init(*r)
+#define scope_stack_size(r)             marray_size(*r)
+#define scope_stack_get(r,n)            marray_get(*r,n)
+#define scope_stack_free(r)             marray_destroy(*r)
+#define scope_stack_push(r,hash)        marray_push(gravity_hash_t*,*r,hash)
+#define scope_stack_pop(r)              (marray_size(*r) ? marray_pop(*r) : NULL)
 
 
-#define VALUE_FROM_NODE(x)			((gravity_value_t){.isa = NULL, .p = (gravity_object_t *)(x)})
-#define VALUE_AS_NODE(x)			((gnode_t *)VALUE_AS_OBJECT(x))
+#define VALUE_FROM_NODE(x)              ((gravity_value_t){.isa = NULL, .p = (gravity_object_t *)(x)})
+#define VALUE_AS_NODE(x)                ((gnode_t *)VALUE_AS_OBJECT(x))
 
 
 // MARK: -
 // MARK: -
 
 
 struct symboltable_t {
 struct symboltable_t {
-	ghash_r		*stack;
-	uint16_t	    count1;     // used for local var
+    ghash_r         *stack;
+    uint16_t        count1;     // used for local var
     uint16_t        count2;     // used for ivar
     uint16_t        count2;     // used for ivar
     uint16_t        count3;     // used for static ivar
     uint16_t        count3;     // used for static ivar
     uint16_t        unused;
     uint16_t        unused;
@@ -38,104 +38,104 @@ struct symboltable_t {
 // MARK: -
 // MARK: -
 
 
 static void check_upvalue_inscope (gravity_hash_t *hashtable, gravity_value_t key, gravity_value_t value, void *data) {
 static void check_upvalue_inscope (gravity_hash_t *hashtable, gravity_value_t key, gravity_value_t value, void *data) {
-	#pragma unused(hashtable, key)
+    #pragma unused(hashtable, key)
 
 
-	uint32_t index = *(uint32_t *)data;
-	gnode_t *node = VALUE_AS_NODE(value);
-	if (NODE_ISA(node, NODE_VARIABLE)) {
-		gnode_var_t *var = (gnode_var_t *)node;
-		if (var->upvalue) {
-			if ((index == UINT32_MAX) || (var->index < index)) *(uint32_t *)data = var->index;
-		}
-	}
+    uint32_t index = *(uint32_t *)data;
+    gnode_t *node = VALUE_AS_NODE(value);
+    if (NODE_ISA(node, NODE_VARIABLE)) {
+        gnode_var_t *var = (gnode_var_t *)node;
+        if (var->upvalue) {
+            if ((index == UINT32_MAX) || (var->index < index)) *(uint32_t *)data = var->index;
+        }
+    }
 }
 }
 
 
 // MARK: -
 // MARK: -
 
 
 static void symboltable_hash_free (gravity_hash_t *hashtable, gravity_value_t key, gravity_value_t value, void *data) {
 static void symboltable_hash_free (gravity_hash_t *hashtable, gravity_value_t key, gravity_value_t value, void *data) {
-	#pragma unused(hashtable, value, data)
-	// free key only because node is usually retained by other objects and freed in other points
-	gravity_value_free(NULL, key);
+    #pragma unused(hashtable, value, data)
+    // free key only because node is usually retained by other objects and freed in other points
+    gravity_value_free(NULL, key);
 }
 }
 
 
 static void symboltable_keyvalue_free (gravity_hash_t *hashtable, gravity_value_t key, gravity_value_t value, void *data) {
 static void symboltable_keyvalue_free (gravity_hash_t *hashtable, gravity_value_t key, gravity_value_t value, void *data) {
-	#pragma unused(hashtable, data)
-	// in enum nodes are retained by the symboltable
-	gnode_t *node = VALUE_AS_NODE(value);
-	gnode_free(node);
-	gravity_value_free(NULL, key);
+    #pragma unused(hashtable, data)
+    // in enum nodes are retained by the symboltable
+    gnode_t *node = VALUE_AS_NODE(value);
+    gnode_free(node);
+    gravity_value_free(NULL, key);
 }
 }
 
 
 symboltable_t *symboltable_create (symtable_tag tag) {
 symboltable_t *symboltable_create (symtable_tag tag) {
     bool is_enum = (tag == SYMTABLE_TAG_ENUM);
     bool is_enum = (tag == SYMTABLE_TAG_ENUM);
     
     
-	symboltable_t	*table = mem_alloc(NULL, sizeof(symboltable_t));
-	gravity_hash_t	*hash = gravity_hash_create(0, gravity_value_hash, gravity_value_equals,
-												(is_enum) ? symboltable_keyvalue_free : symboltable_hash_free, NULL);
-	if (!table) return NULL;
+    symboltable_t    *table = mem_alloc(NULL, sizeof(symboltable_t));
+    gravity_hash_t    *hash = gravity_hash_create(0, gravity_value_hash, gravity_value_equals,
+                                                (is_enum) ? symboltable_keyvalue_free : symboltable_hash_free, NULL);
+    if (!table) return NULL;
 
 
-	// init symbol table
+    // init symbol table
     table->tag = tag;
     table->tag = tag;
-	table->count1 = 0;
+    table->count1 = 0;
     table->count2 = 0;
     table->count2 = 0;
     table->count3 = 0;
     table->count3 = 0;
-	table->stack = mem_alloc(NULL, sizeof(ghash_r));
-	scope_stack_init(table->stack);
-	scope_stack_push(table->stack, hash);
+    table->stack = mem_alloc(NULL, sizeof(ghash_r));
+    scope_stack_init(table->stack);
+    scope_stack_push(table->stack, hash);
 
 
-	return table;
+    return table;
 }
 }
 
 
 void symboltable_free (symboltable_t *table) {
 void symboltable_free (symboltable_t *table) {
-	size_t i, n = scope_stack_size(table->stack);
+    size_t i, n = scope_stack_size(table->stack);
 
 
-	for (i=0; i<n; ++i) {
-		gravity_hash_t *h = scope_stack_get(table->stack, i);
-		gravity_hash_free(h);
-	}
+    for (i=0; i<n; ++i) {
+        gravity_hash_t *h = scope_stack_get(table->stack, i);
+        gravity_hash_free(h);
+    }
 
 
-	if (table->stack) {
-		scope_stack_free(table->stack);
-		mem_free(table->stack);
-	}
+    if (table->stack) {
+        scope_stack_free(table->stack);
+        mem_free(table->stack);
+    }
 
 
-	mem_free(table);
+    mem_free(table);
 }
 }
 
 
 bool symboltable_insert (symboltable_t *table, const char *identifier, gnode_t *node) {
 bool symboltable_insert (symboltable_t *table, const char *identifier, gnode_t *node) {
     if (!identifier) return false;
     if (!identifier) return false;
 
 
-	size_t			n = scope_stack_size(table->stack);
-	gravity_hash_t	*h = scope_stack_get(table->stack, n-1);
+    size_t            n = scope_stack_size(table->stack);
+    gravity_hash_t    *h = scope_stack_get(table->stack, n-1);
 
 
-	// insert node with key identifier into hash table (and check if already exists in current scope)
-	gravity_value_t key = VALUE_FROM_CSTRING(NULL, identifier);
-	if (gravity_hash_lookup(h, key) != NULL) {
-		gravity_value_free(NULL, key);
-		return false;
-	}
-	gravity_hash_insert(h, key, VALUE_FROM_NODE(node));
+    // insert node with key identifier into hash table (and check if already exists in current scope)
+    gravity_value_t key = VALUE_FROM_CSTRING(NULL, identifier);
+    if (gravity_hash_lookup(h, key) != NULL) {
+        gravity_value_free(NULL, key);
+        return false;
+    }
+    gravity_hash_insert(h, key, VALUE_FROM_NODE(node));
 
 
-	++table->count1;
-	return true;
+    ++table->count1;
+    return true;
 }
 }
 
 
 gnode_t *symboltable_lookup (symboltable_t *table, const char *identifier) {
 gnode_t *symboltable_lookup (symboltable_t *table, const char *identifier) {
-	STATICVALUE_FROM_STRING(key, identifier, strlen(identifier));
+    STATICVALUE_FROM_STRING(key, identifier, strlen(identifier));
 
 
-	size_t n = scope_stack_size(table->stack);
-	for (int i=(int)n-1; i>=0; --i) {
-		gravity_hash_t *h = scope_stack_get(table->stack, i);
-		gravity_value_t *v = gravity_hash_lookup(h, key);
-		if (v) return VALUE_AS_NODE(*v);
-	}
+    size_t n = scope_stack_size(table->stack);
+    for (int i=(int)n-1; i>=0; --i) {
+        gravity_hash_t *h = scope_stack_get(table->stack, i);
+        gravity_value_t *v = gravity_hash_lookup(h, key);
+        if (v) return VALUE_AS_NODE(*v);
+    }
 
 
-	return NULL;
+    return NULL;
 }
 }
 
 
 uint32_t symboltable_count (symboltable_t *table, uint32_t index) {
 uint32_t symboltable_count (symboltable_t *table, uint32_t index) {
-	gravity_hash_t *h = scope_stack_get(table->stack, index);
-	return gravity_hash_count(h);
+    gravity_hash_t *h = scope_stack_get(table->stack, index);
+    return gravity_hash_count(h);
 }
 }
 
 
 symtable_tag symboltable_tag (symboltable_t *table) {
 symtable_tag symboltable_tag (symboltable_t *table) {
@@ -149,39 +149,39 @@ uint16_t symboltable_setivar (symboltable_t *table, bool is_static) {
 // MARK: -
 // MARK: -
 
 
 gnode_t *symboltable_global_lookup (symboltable_t *table, const char *identifier) {
 gnode_t *symboltable_global_lookup (symboltable_t *table, const char *identifier) {
-	gravity_hash_t *h = scope_stack_get(table->stack, 0);
-	STATICVALUE_FROM_STRING(key, identifier, strlen(identifier));
+    gravity_hash_t *h = scope_stack_get(table->stack, 0);
+    STATICVALUE_FROM_STRING(key, identifier, strlen(identifier));
 
 
-	gravity_value_t *v = gravity_hash_lookup(h, key);
-	return (v) ? VALUE_AS_NODE(*v) : NULL;
+    gravity_value_t *v = gravity_hash_lookup(h, key);
+    return (v) ? VALUE_AS_NODE(*v) : NULL;
 }
 }
 
 
 void symboltable_enter_scope (symboltable_t *table) {
 void symboltable_enter_scope (symboltable_t *table) {
-	gravity_hash_t *h = gravity_hash_create(0, gravity_value_hash, gravity_value_equals, symboltable_hash_free, NULL);
-	scope_stack_push(table->stack, h);
+    gravity_hash_t *h = gravity_hash_create(0, gravity_value_hash, gravity_value_equals, symboltable_hash_free, NULL);
+    scope_stack_push(table->stack, h);
 }
 }
 
 
 uint32_t symboltable_local_index (symboltable_t *table) {
 uint32_t symboltable_local_index (symboltable_t *table) {
-	return table->count1 - 1;
+    return table->count1 - 1;
 }
 }
 
 
 uint32_t symboltable_exit_scope (symboltable_t *table, uint32_t *nlevel) {
 uint32_t symboltable_exit_scope (symboltable_t *table, uint32_t *nlevel) {
-	gravity_hash_t *h = (gravity_hash_t *)scope_stack_pop(table->stack);
-	if (nlevel) {
-		*nlevel = UINT32_MAX;
-		gravity_hash_iterate(h, check_upvalue_inscope, (void *)nlevel);
-	}
-	gravity_hash_free(h);
-	return table->count1;
+    gravity_hash_t *h = (gravity_hash_t *)scope_stack_pop(table->stack);
+    if (nlevel) {
+        *nlevel = UINT32_MAX;
+        gravity_hash_iterate(h, check_upvalue_inscope, (void *)nlevel);
+    }
+    gravity_hash_free(h);
+    return table->count1;
 }
 }
 
 
 void symboltable_dump (symboltable_t *table) {
 void symboltable_dump (symboltable_t *table) {
-	size_t n = scope_stack_size(table->stack);
+    size_t n = scope_stack_size(table->stack);
 
 
-	for (int i=(int)n-1; i>=0; --i) {
-		gravity_hash_t *h = (gravity_hash_t *)scope_stack_get(table->stack, i);
-		gravity_hash_dump(h);
-	}
+    for (int i=(int)n-1; i>=0; --i) {
+        gravity_hash_t *h = (gravity_hash_t *)scope_stack_get(table->stack, i);
+        gravity_hash_dump(h);
+    }
 }
 }
 
 
 void *symboltable_hash_atindex (symboltable_t *table, size_t n) {
 void *symboltable_hash_atindex (symboltable_t *table, size_t n) {

+ 11 - 11
src/compiler/gravity_symboltable.h

@@ -14,7 +14,7 @@
 
 
 #ifndef GRAVITY_SYMBOLTABLE_DEFINED
 #ifndef GRAVITY_SYMBOLTABLE_DEFINED
 #define GRAVITY_SYMBOLTABLE_DEFINED
 #define GRAVITY_SYMBOLTABLE_DEFINED
-typedef struct symboltable_t	symboltable_t;
+typedef struct symboltable_t    symboltable_t;
 #endif
 #endif
 
 
 typedef enum {
 typedef enum {
@@ -25,19 +25,19 @@ typedef enum {
     SYMTABLE_TAG_ENUM = 4
     SYMTABLE_TAG_ENUM = 4
 } symtable_tag;
 } symtable_tag;
 
 
-symboltable_t	*symboltable_create (symtable_tag tag);
-gnode_t			*symboltable_lookup (symboltable_t *table, const char *identifier);
-gnode_t			*symboltable_global_lookup (symboltable_t *table, const char *identifier);
-bool			symboltable_insert (symboltable_t *table, const char *identifier, gnode_t *node);
-uint32_t		symboltable_count (symboltable_t *table, uint32_t index);
+symboltable_t   *symboltable_create (symtable_tag tag);
+gnode_t         *symboltable_lookup (symboltable_t *table, const char *identifier);
+gnode_t         *symboltable_global_lookup (symboltable_t *table, const char *identifier);
+bool            symboltable_insert (symboltable_t *table, const char *identifier, gnode_t *node);
+uint32_t        symboltable_count (symboltable_t *table, uint32_t index);
 symtable_tag    symboltable_tag (symboltable_t *table);
 symtable_tag    symboltable_tag (symboltable_t *table);
 uint16_t        symboltable_setivar (symboltable_t *table, bool is_static);
 uint16_t        symboltable_setivar (symboltable_t *table, bool is_static);
 
 
-void			symboltable_enter_scope (symboltable_t *table);
-uint32_t		symboltable_exit_scope (symboltable_t *table, uint32_t *nlevel);
-uint32_t		symboltable_local_index (symboltable_t *table);
-void			symboltable_free (symboltable_t *table);
-void			symboltable_dump (symboltable_t *table);
+void            symboltable_enter_scope (symboltable_t *table);
+uint32_t        symboltable_exit_scope (symboltable_t *table, uint32_t *nlevel);
+uint32_t        symboltable_local_index (symboltable_t *table);
+void            symboltable_free (symboltable_t *table);
+void            symboltable_dump (symboltable_t *table);
 
 
 void            *symboltable_hash_atindex (symboltable_t *table, size_t n);
 void            *symboltable_hash_atindex (symboltable_t *table, size_t n);
 
 

+ 250 - 250
src/compiler/gravity_token.c

@@ -10,119 +10,119 @@
 #include "gravity_utils.h"
 #include "gravity_utils.h"
 
 
 const char *token_string (gtoken_s token, uint32_t *len) {
 const char *token_string (gtoken_s token, uint32_t *len) {
-	if (len) *len = token.bytes;
-	return token.value;
+    if (len) *len = token.bytes;
+    return token.value;
 }
 }
 
 
 const char *token_name (gtoken_t token) {
 const char *token_name (gtoken_t token) {
-	switch (token) {
-		case TOK_EOF: return "EOF";
-		case TOK_ERROR: return "ERROR";
-		case TOK_COMMENT: return "COMMENT";
-		case TOK_STRING: return "STRING";
-		case TOK_NUMBER: return "NUMBER";
-		case TOK_IDENTIFIER: return "IDENTIFIER";
-		case TOK_SPECIAL: return "SPECIAL";
-		case TOK_MACRO: return "MACRO";
-
-		// keywords
-		case TOK_KEY_FILE: return "file";
-		case TOK_KEY_FUNC: return "func";
-		case TOK_KEY_SUPER: return "super";
-		case TOK_KEY_DEFAULT: return "default";
-		case TOK_KEY_TRUE: return "true";
-		case TOK_KEY_FALSE: return "false";
-		case TOK_KEY_IF: return "if";
-		case TOK_KEY_ELSE: return "else";
-		case TOK_KEY_SWITCH: return "switch";
-		case TOK_KEY_BREAK: return "break";
-		case TOK_KEY_CONTINUE: return "continue";
-		case TOK_KEY_RETURN: return "return";
-		case TOK_KEY_WHILE: return "while";
-		case TOK_KEY_REPEAT: return "repeat";
-		case TOK_KEY_FOR: return "for";
-		case TOK_KEY_IN: return "in";
-		case TOK_KEY_ENUM: return "enum";
-		case TOK_KEY_CLASS: return "class";
-		case TOK_KEY_STRUCT: return "struct";
-		case TOK_KEY_PRIVATE: return "private";
-		case TOK_KEY_INTERNAL: return "internal";
-		case TOK_KEY_PUBLIC: return "public";
-		case TOK_KEY_STATIC: return "static";
-		case TOK_KEY_EXTERN: return "extern";
-		case TOK_KEY_LAZY: return "lazy";
-		case TOK_KEY_CONST: return "const";
-		case TOK_KEY_VAR: return "var";
-		case TOK_KEY_MODULE: return "module";
-		case TOK_KEY_IMPORT: return "import";
-		case TOK_KEY_CASE: return "case";
-		case TOK_KEY_EVENT: return "event";
-		case TOK_KEY_NULL: return "null";
-		case TOK_KEY_UNDEFINED: return "undefined";
-		case TOK_KEY_ISA: return "is";
-		case TOK_KEY_CURRARGS: return "_args";
-		case TOK_KEY_CURRFUNC: return "_func";
-
-		// operators
-		case TOK_OP_ADD: return "+";
-		case TOK_OP_SUB: return "-";
-		case TOK_OP_DIV: return "/";
-		case TOK_OP_MUL: return "*";
-		case TOK_OP_REM: return "%";
-		case TOK_OP_ASSIGN: return "=";
-		case TOK_OP_LESS: return "<";
-		case TOK_OP_GREATER: return ">";
-		case TOK_OP_LESS_EQUAL: return "<=";
-		case TOK_OP_GREATER_EQUAL: return ">=";
-		case TOK_OP_ADD_ASSIGN: return "+=";
-		case TOK_OP_SUB_ASSIGN: return "-=";
-		case TOK_OP_DIV_ASSIGN: return "/=";
-		case TOK_OP_MUL_ASSIGN: return "*=";
-		case TOK_OP_REM_ASSIGN: return "%=";
-		case TOK_OP_NOT: return "!";
-		case TOK_OP_AND: return "&&";
-		case TOK_OP_OR: return "||";
-		case TOK_OP_ISEQUAL: return "==";
-		case TOK_OP_ISNOTEQUAL: return "!=";
-		case TOK_OP_RANGE_INCLUDED: return "...";
-		case TOK_OP_RANGE_EXCLUDED: return "..<";
-		case TOK_OP_TERNARY: return "?";
-		case TOK_OP_SHIFT_LEFT: return "<<";
-		case TOK_OP_SHIFT_RIGHT: return ">>";
-		case TOK_OP_BIT_AND: return "&";
-		case TOK_OP_BIT_OR: return "|";
-		case TOK_OP_BIT_XOR: return "^";
-		case TOK_OP_BIT_NOT: return "~";
-		case TOK_OP_ISIDENTICAL: return "===";
-		case TOK_OP_ISNOTIDENTICAL: return "!==";
-		case TOK_OP_PATTERN_MATCH: return "~=";
-		case TOK_OP_SHIFT_LEFT_ASSIGN: return "<<=";
-		case TOK_OP_SHIFT_RIGHT_ASSIGN: return ">>=";
-		case TOK_OP_BIT_AND_ASSIGN: return "&=";
-		case TOK_OP_BIT_OR_ASSIGN: return "|=";
-		case TOK_OP_BIT_XOR_ASSIGN: return "^=";
-
-		case TOK_OP_OPEN_PARENTHESIS: return "(";
-		case TOK_OP_CLOSED_PARENTHESIS: return ")";
-		case TOK_OP_OPEN_SQUAREBRACKET: return "[";
-		case TOK_OP_CLOSED_SQUAREBRACKET: return "]";
-		case TOK_OP_OPEN_CURLYBRACE: return "{";
-		case TOK_OP_CLOSED_CURLYBRACE: return "}";
-		case TOK_OP_SEMICOLON: return ";";
-		case TOK_OP_COLON: return ":";
-		case TOK_OP_COMMA: return ",";
-		case TOK_OP_DOT: return ".";
-
-		case TOK_END: return "";
-	}
-
-	// should never reach this point
-	return "UNRECOGNIZED TOKEN";
+    switch (token) {
+        case TOK_EOF: return "EOF";
+        case TOK_ERROR: return "ERROR";
+        case TOK_COMMENT: return "COMMENT";
+        case TOK_STRING: return "STRING";
+        case TOK_NUMBER: return "NUMBER";
+        case TOK_IDENTIFIER: return "IDENTIFIER";
+        case TOK_SPECIAL: return "SPECIAL";
+        case TOK_MACRO: return "MACRO";
+
+        // keywords
+        case TOK_KEY_FILE: return "file";
+        case TOK_KEY_FUNC: return "func";
+        case TOK_KEY_SUPER: return "super";
+        case TOK_KEY_DEFAULT: return "default";
+        case TOK_KEY_TRUE: return "true";
+        case TOK_KEY_FALSE: return "false";
+        case TOK_KEY_IF: return "if";
+        case TOK_KEY_ELSE: return "else";
+        case TOK_KEY_SWITCH: return "switch";
+        case TOK_KEY_BREAK: return "break";
+        case TOK_KEY_CONTINUE: return "continue";
+        case TOK_KEY_RETURN: return "return";
+        case TOK_KEY_WHILE: return "while";
+        case TOK_KEY_REPEAT: return "repeat";
+        case TOK_KEY_FOR: return "for";
+        case TOK_KEY_IN: return "in";
+        case TOK_KEY_ENUM: return "enum";
+        case TOK_KEY_CLASS: return "class";
+        case TOK_KEY_STRUCT: return "struct";
+        case TOK_KEY_PRIVATE: return "private";
+        case TOK_KEY_INTERNAL: return "internal";
+        case TOK_KEY_PUBLIC: return "public";
+        case TOK_KEY_STATIC: return "static";
+        case TOK_KEY_EXTERN: return "extern";
+        case TOK_KEY_LAZY: return "lazy";
+        case TOK_KEY_CONST: return "const";
+        case TOK_KEY_VAR: return "var";
+        case TOK_KEY_MODULE: return "module";
+        case TOK_KEY_IMPORT: return "import";
+        case TOK_KEY_CASE: return "case";
+        case TOK_KEY_EVENT: return "event";
+        case TOK_KEY_NULL: return "null";
+        case TOK_KEY_UNDEFINED: return "undefined";
+        case TOK_KEY_ISA: return "is";
+        case TOK_KEY_CURRARGS: return "_args";
+        case TOK_KEY_CURRFUNC: return "_func";
+
+        // operators
+        case TOK_OP_ADD: return "+";
+        case TOK_OP_SUB: return "-";
+        case TOK_OP_DIV: return "/";
+        case TOK_OP_MUL: return "*";
+        case TOK_OP_REM: return "%";
+        case TOK_OP_ASSIGN: return "=";
+        case TOK_OP_LESS: return "<";
+        case TOK_OP_GREATER: return ">";
+        case TOK_OP_LESS_EQUAL: return "<=";
+        case TOK_OP_GREATER_EQUAL: return ">=";
+        case TOK_OP_ADD_ASSIGN: return "+=";
+        case TOK_OP_SUB_ASSIGN: return "-=";
+        case TOK_OP_DIV_ASSIGN: return "/=";
+        case TOK_OP_MUL_ASSIGN: return "*=";
+        case TOK_OP_REM_ASSIGN: return "%=";
+        case TOK_OP_NOT: return "!";
+        case TOK_OP_AND: return "&&";
+        case TOK_OP_OR: return "||";
+        case TOK_OP_ISEQUAL: return "==";
+        case TOK_OP_ISNOTEQUAL: return "!=";
+        case TOK_OP_RANGE_INCLUDED: return "...";
+        case TOK_OP_RANGE_EXCLUDED: return "..<";
+        case TOK_OP_TERNARY: return "?";
+        case TOK_OP_SHIFT_LEFT: return "<<";
+        case TOK_OP_SHIFT_RIGHT: return ">>";
+        case TOK_OP_BIT_AND: return "&";
+        case TOK_OP_BIT_OR: return "|";
+        case TOK_OP_BIT_XOR: return "^";
+        case TOK_OP_BIT_NOT: return "~";
+        case TOK_OP_ISIDENTICAL: return "===";
+        case TOK_OP_ISNOTIDENTICAL: return "!==";
+        case TOK_OP_PATTERN_MATCH: return "~=";
+        case TOK_OP_SHIFT_LEFT_ASSIGN: return "<<=";
+        case TOK_OP_SHIFT_RIGHT_ASSIGN: return ">>=";
+        case TOK_OP_BIT_AND_ASSIGN: return "&=";
+        case TOK_OP_BIT_OR_ASSIGN: return "|=";
+        case TOK_OP_BIT_XOR_ASSIGN: return "^=";
+
+        case TOK_OP_OPEN_PARENTHESIS: return "(";
+        case TOK_OP_CLOSED_PARENTHESIS: return ")";
+        case TOK_OP_OPEN_SQUAREBRACKET: return "[";
+        case TOK_OP_CLOSED_SQUAREBRACKET: return "]";
+        case TOK_OP_OPEN_CURLYBRACE: return "{";
+        case TOK_OP_CLOSED_CURLYBRACE: return "}";
+        case TOK_OP_SEMICOLON: return ";";
+        case TOK_OP_COLON: return ":";
+        case TOK_OP_COMMA: return ",";
+        case TOK_OP_DOT: return ".";
+
+        case TOK_END: return "";
+    }
+
+    // should never reach this point
+    return "UNRECOGNIZED TOKEN";
 }
 }
 
 
 void token_keywords_indexes (uint32_t *idx_start, uint32_t *idx_end) {
 void token_keywords_indexes (uint32_t *idx_start, uint32_t *idx_end) {
-	*idx_start = (uint32_t)TOK_KEY_FUNC;
-	*idx_end = (uint32_t)TOK_KEY_CURRARGS;
+    *idx_start = (uint32_t)TOK_KEY_FUNC;
+    *idx_end = (uint32_t)TOK_KEY_CURRARGS;
 };
 };
 
 
 gtoken_t token_special_builtin(gtoken_s *token) {
 gtoken_t token_special_builtin(gtoken_s *token) {
@@ -167,221 +167,221 @@ gtoken_t token_special_builtin(gtoken_s *token) {
 }
 }
 
 
 gtoken_t token_keyword (const char *buffer, int32_t len) {
 gtoken_t token_keyword (const char *buffer, int32_t len) {
-	switch (len) {
-		case 2:
-			if (string_casencmp(buffer, "if", len) == 0) return TOK_KEY_IF;
-			if (string_casencmp(buffer, "in", len) == 0) return TOK_KEY_IN;
-			if (string_casencmp(buffer, "or", len) == 0) return TOK_OP_OR;
-			if (string_casencmp(buffer, "is", len) == 0) return TOK_KEY_ISA;
-			break;
-
-		case 3:
-			if (string_casencmp(buffer, "for", len) == 0) return TOK_KEY_FOR;
-			if (string_casencmp(buffer, "var", len) == 0) return TOK_KEY_VAR;
-			if (string_casencmp(buffer, "and", len) == 0) return TOK_OP_AND;
-			if (string_casencmp(buffer, "not", len) == 0) return TOK_OP_NOT;
-			break;
-
-		case 4:
-			if (string_casencmp(buffer, "func", len) == 0) return TOK_KEY_FUNC;
-			if (string_casencmp(buffer, "else", len) == 0) return TOK_KEY_ELSE;
-			if (string_casencmp(buffer, "true", len) == 0) return TOK_KEY_TRUE;
-			if (string_casencmp(buffer, "enum", len) == 0) return TOK_KEY_ENUM;
-			if (string_casencmp(buffer, "case", len) == 0) return TOK_KEY_CASE;
-			if (string_casencmp(buffer, "null", len) == 0) return TOK_KEY_NULL;
-			if (string_casencmp(buffer, "file", len) == 0) return TOK_KEY_FILE;
-			if (string_casencmp(buffer, "lazy", len) == 0) return TOK_KEY_LAZY;
-			break;
-
-		case 5:
-			if (string_casencmp(buffer, "super", len) == 0) return TOK_KEY_SUPER;
-			if (string_casencmp(buffer, "false", len) == 0) return TOK_KEY_FALSE;
-			if (string_casencmp(buffer, "break", len) == 0) return TOK_KEY_BREAK;
-			if (string_casencmp(buffer, "while", len) == 0) return TOK_KEY_WHILE;
-			if (string_casencmp(buffer, "class", len) == 0) return TOK_KEY_CLASS;
-			if (string_casencmp(buffer, "const", len) == 0) return TOK_KEY_CONST;
-			if (string_casencmp(buffer, "event", len) == 0) return TOK_KEY_EVENT;
-			if (string_casencmp(buffer, "_func", len) == 0) return TOK_KEY_CURRFUNC;
-			if (string_casencmp(buffer, "_args", len) == 0) return TOK_KEY_CURRARGS;
-			break;
-
-		case 6:
-			if (string_casencmp(buffer, "struct", len) == 0) return TOK_KEY_STRUCT;
-			if (string_casencmp(buffer, "repeat", len) == 0) return TOK_KEY_REPEAT;
-			if (string_casencmp(buffer, "switch", len) == 0) return TOK_KEY_SWITCH;
-			if (string_casencmp(buffer, "return", len) == 0) return TOK_KEY_RETURN;
-			if (string_casencmp(buffer, "public", len) == 0) return TOK_KEY_PUBLIC;
-			if (string_casencmp(buffer, "static", len) == 0) return TOK_KEY_STATIC;
-			if (string_casencmp(buffer, "extern", len) == 0) return TOK_KEY_EXTERN;
-			if (string_casencmp(buffer, "import", len) == 0) return TOK_KEY_IMPORT;
-			if (string_casencmp(buffer, "module", len) == 0) return TOK_KEY_MODULE;
-			break;
-
-		case 7:
-			if (string_casencmp(buffer, "default", len) == 0) return TOK_KEY_DEFAULT;
-			if (string_casencmp(buffer, "private", len) == 0) return TOK_KEY_PRIVATE;
-			break;
-
-		case 8:
-			if (string_casencmp(buffer, "continue", len) == 0) return TOK_KEY_CONTINUE;
-			if (string_casencmp(buffer, "internal", len) == 0) return TOK_KEY_INTERNAL;
-			break;
-
-		case 9:
-			if (string_casencmp(buffer, "undefined", len) == 0) return TOK_KEY_UNDEFINED;
-			break;
-	}
-
-	return TOK_IDENTIFIER;
+    switch (len) {
+        case 2:
+            if (string_casencmp(buffer, "if", len) == 0) return TOK_KEY_IF;
+            if (string_casencmp(buffer, "in", len) == 0) return TOK_KEY_IN;
+            if (string_casencmp(buffer, "or", len) == 0) return TOK_OP_OR;
+            if (string_casencmp(buffer, "is", len) == 0) return TOK_KEY_ISA;
+            break;
+
+        case 3:
+            if (string_casencmp(buffer, "for", len) == 0) return TOK_KEY_FOR;
+            if (string_casencmp(buffer, "var", len) == 0) return TOK_KEY_VAR;
+            if (string_casencmp(buffer, "and", len) == 0) return TOK_OP_AND;
+            if (string_casencmp(buffer, "not", len) == 0) return TOK_OP_NOT;
+            break;
+
+        case 4:
+            if (string_casencmp(buffer, "func", len) == 0) return TOK_KEY_FUNC;
+            if (string_casencmp(buffer, "else", len) == 0) return TOK_KEY_ELSE;
+            if (string_casencmp(buffer, "true", len) == 0) return TOK_KEY_TRUE;
+            if (string_casencmp(buffer, "enum", len) == 0) return TOK_KEY_ENUM;
+            if (string_casencmp(buffer, "case", len) == 0) return TOK_KEY_CASE;
+            if (string_casencmp(buffer, "null", len) == 0) return TOK_KEY_NULL;
+            if (string_casencmp(buffer, "file", len) == 0) return TOK_KEY_FILE;
+            if (string_casencmp(buffer, "lazy", len) == 0) return TOK_KEY_LAZY;
+            break;
+
+        case 5:
+            if (string_casencmp(buffer, "super", len) == 0) return TOK_KEY_SUPER;
+            if (string_casencmp(buffer, "false", len) == 0) return TOK_KEY_FALSE;
+            if (string_casencmp(buffer, "break", len) == 0) return TOK_KEY_BREAK;
+            if (string_casencmp(buffer, "while", len) == 0) return TOK_KEY_WHILE;
+            if (string_casencmp(buffer, "class", len) == 0) return TOK_KEY_CLASS;
+            if (string_casencmp(buffer, "const", len) == 0) return TOK_KEY_CONST;
+            if (string_casencmp(buffer, "event", len) == 0) return TOK_KEY_EVENT;
+            if (string_casencmp(buffer, "_func", len) == 0) return TOK_KEY_CURRFUNC;
+            if (string_casencmp(buffer, "_args", len) == 0) return TOK_KEY_CURRARGS;
+            break;
+
+        case 6:
+            if (string_casencmp(buffer, "struct", len) == 0) return TOK_KEY_STRUCT;
+            if (string_casencmp(buffer, "repeat", len) == 0) return TOK_KEY_REPEAT;
+            if (string_casencmp(buffer, "switch", len) == 0) return TOK_KEY_SWITCH;
+            if (string_casencmp(buffer, "return", len) == 0) return TOK_KEY_RETURN;
+            if (string_casencmp(buffer, "public", len) == 0) return TOK_KEY_PUBLIC;
+            if (string_casencmp(buffer, "static", len) == 0) return TOK_KEY_STATIC;
+            if (string_casencmp(buffer, "extern", len) == 0) return TOK_KEY_EXTERN;
+            if (string_casencmp(buffer, "import", len) == 0) return TOK_KEY_IMPORT;
+            if (string_casencmp(buffer, "module", len) == 0) return TOK_KEY_MODULE;
+            break;
+
+        case 7:
+            if (string_casencmp(buffer, "default", len) == 0) return TOK_KEY_DEFAULT;
+            if (string_casencmp(buffer, "private", len) == 0) return TOK_KEY_PRIVATE;
+            break;
+
+        case 8:
+            if (string_casencmp(buffer, "continue", len) == 0) return TOK_KEY_CONTINUE;
+            if (string_casencmp(buffer, "internal", len) == 0) return TOK_KEY_INTERNAL;
+            break;
+
+        case 9:
+            if (string_casencmp(buffer, "undefined", len) == 0) return TOK_KEY_UNDEFINED;
+            break;
+    }
+
+    return TOK_IDENTIFIER;
 }
 }
 
 
 const char *token_literal_name (gliteral_t value) {
 const char *token_literal_name (gliteral_t value) {
-	if (value == LITERAL_STRING) return "STRING";
-	else if (value == LITERAL_FLOAT) return "FLOAT";
-	else if (value == LITERAL_INT) return "INTEGER";
-	else if (value == LITERAL_BOOL) return "BOOLEAN";
-	else if (value == LITERAL_STRING_INTERPOLATED) return "STRING INTERPOLATED";
-	return "N/A";
+    if (value == LITERAL_STRING) return "STRING";
+    else if (value == LITERAL_FLOAT) return "FLOAT";
+    else if (value == LITERAL_INT) return "INTEGER";
+    else if (value == LITERAL_BOOL) return "BOOLEAN";
+    else if (value == LITERAL_STRING_INTERPOLATED) return "STRING INTERPOLATED";
+    return "N/A";
 }
 }
 
 
 // MARK: -
 // MARK: -
 
 
 bool token_isidentifier (gtoken_t token) {
 bool token_isidentifier (gtoken_t token) {
-	return (token == TOK_IDENTIFIER);
+    return (token == TOK_IDENTIFIER);
 }
 }
 
 
 bool token_isvariable_declaration (gtoken_t token) {
 bool token_isvariable_declaration (gtoken_t token) {
-	return ((token == TOK_KEY_CONST) || (token == TOK_KEY_VAR));
+    return ((token == TOK_KEY_CONST) || (token == TOK_KEY_VAR));
 }
 }
 
 
 bool token_isstatement (gtoken_t token) {
 bool token_isstatement (gtoken_t token) {
-	if (token == TOK_EOF) return false;
-
-	// label_statement (case, default)
-	// expression_statement ('+' | '-' | '!' | 'not' | new | raise | file | isPrimaryExpression)
-	// flow_statement (if, select)
-	// loop_statement (while, loop, for)
-	// jump_statement (break, continue, return)
-	// compound_statement ({)
-	// declaration_statement (isDeclarationStatement)
-	// empty_statement (;)
-	// import_statement (import)
-
-	return (token_islabel_statement(token) || token_isexpression_statement(token) || token_isflow_statement(token) ||
-			token_isloop_statement(token) || token_isjump_statement(token) || token_iscompound_statement(token) ||
-			token_isdeclaration_statement(token) || token_isempty_statement(token) || token_isimport_statement(token) ||
+    if (token == TOK_EOF) return false;
+
+    // label_statement (case, default)
+    // expression_statement ('+' | '-' | '!' | 'not' | new | raise | file | isPrimaryExpression)
+    // flow_statement (if, select)
+    // loop_statement (while, loop, for)
+    // jump_statement (break, continue, return)
+    // compound_statement ({)
+    // declaration_statement (isDeclarationStatement)
+    // empty_statement (;)
+    // import_statement (import)
+
+    return (token_islabel_statement(token) || token_isexpression_statement(token) || token_isflow_statement(token) ||
+            token_isloop_statement(token) || token_isjump_statement(token) || token_iscompound_statement(token) ||
+            token_isdeclaration_statement(token) || token_isempty_statement(token) || token_isimport_statement(token) ||
             token_ismacro(token));
             token_ismacro(token));
 }
 }
 
 
 bool token_isassignment (gtoken_t token) {
 bool token_isassignment (gtoken_t token) {
-	return ((token == TOK_OP_ASSIGN) || (token == TOK_OP_MUL_ASSIGN) || (token == TOK_OP_DIV_ASSIGN) ||
-			(token == TOK_OP_REM_ASSIGN) || (token == TOK_OP_ADD_ASSIGN) || (token == TOK_OP_SUB_ASSIGN) ||
-			(token == TOK_OP_SHIFT_LEFT_ASSIGN) || (token == TOK_OP_SHIFT_RIGHT_ASSIGN) ||
-			(token == TOK_OP_BIT_AND_ASSIGN) || (token == TOK_OP_BIT_OR_ASSIGN) || (token == TOK_OP_BIT_XOR_ASSIGN));
+    return ((token == TOK_OP_ASSIGN) || (token == TOK_OP_MUL_ASSIGN) || (token == TOK_OP_DIV_ASSIGN) ||
+            (token == TOK_OP_REM_ASSIGN) || (token == TOK_OP_ADD_ASSIGN) || (token == TOK_OP_SUB_ASSIGN) ||
+            (token == TOK_OP_SHIFT_LEFT_ASSIGN) || (token == TOK_OP_SHIFT_RIGHT_ASSIGN) ||
+            (token == TOK_OP_BIT_AND_ASSIGN) || (token == TOK_OP_BIT_OR_ASSIGN) || (token == TOK_OP_BIT_XOR_ASSIGN));
 }
 }
 
 
 bool token_isvariable_assignment (gtoken_t token) {
 bool token_isvariable_assignment (gtoken_t token) {
-	return (token == TOK_OP_ASSIGN);
+    return (token == TOK_OP_ASSIGN);
 }
 }
 
 
 bool token_isaccess_specifier (gtoken_t token) {
 bool token_isaccess_specifier (gtoken_t token) {
-	return ((token == TOK_KEY_PRIVATE) || (token == TOK_KEY_INTERNAL) || (token == TOK_KEY_PUBLIC));
+    return ((token == TOK_KEY_PRIVATE) || (token == TOK_KEY_INTERNAL) || (token == TOK_KEY_PUBLIC));
 }
 }
 
 
 bool token_isstorage_specifier (gtoken_t token) {
 bool token_isstorage_specifier (gtoken_t token) {
-	return ((token == TOK_KEY_STATIC) || (token == TOK_KEY_EXTERN) || (token == TOK_KEY_LAZY));
+    return ((token == TOK_KEY_STATIC) || (token == TOK_KEY_EXTERN) || (token == TOK_KEY_LAZY));
 }
 }
 
 
 bool token_isprimary_expression (gtoken_t token) {
 bool token_isprimary_expression (gtoken_t token) {
-	// literal (number, string)
-	// true, false
-	// IDENTIFIER
-	// 'nil'
-	// 'super'
-	// 'func'
-	// 'undefined'
-	// 'file'
-	// '(' expression ')'
-	// function_expression
-	// list_expression
-	// map_expression
-
-	return ((token == TOK_NUMBER) || (token == TOK_STRING) || (token == TOK_KEY_TRUE) ||
-			(token == TOK_KEY_FALSE) || (token == TOK_IDENTIFIER) || (token == TOK_KEY_NULL) ||
-			(token == TOK_KEY_SUPER) || (token == TOK_KEY_FUNC) || (token == TOK_KEY_UNDEFINED) ||
-			(token == TOK_OP_OPEN_PARENTHESIS) || (token == TOK_OP_OPEN_SQUAREBRACKET) ||
-			(token == TOK_OP_OPEN_CURLYBRACE) || (token == TOK_KEY_FILE));
+    // literal (number, string)
+    // true, false
+    // IDENTIFIER
+    // 'nil'
+    // 'super'
+    // 'func'
+    // 'undefined'
+    // 'file'
+    // '(' expression ')'
+    // function_expression
+    // list_expression
+    // map_expression
+
+    return ((token == TOK_NUMBER) || (token == TOK_STRING) || (token == TOK_KEY_TRUE) ||
+            (token == TOK_KEY_FALSE) || (token == TOK_IDENTIFIER) || (token == TOK_KEY_NULL) ||
+            (token == TOK_KEY_SUPER) || (token == TOK_KEY_FUNC) || (token == TOK_KEY_UNDEFINED) ||
+            (token == TOK_OP_OPEN_PARENTHESIS) || (token == TOK_OP_OPEN_SQUAREBRACKET) ||
+            (token == TOK_OP_OPEN_CURLYBRACE) || (token == TOK_KEY_FILE));
 
 
 }
 }
 
 
 bool token_isexpression_statement (gtoken_t token) {
 bool token_isexpression_statement (gtoken_t token) {
-	// reduced to check for unary_expression
-	// postfix_expression: primary_expression | 'module' (was file)
-	// unary_operator: '+' | '-' | '!' | 'not'
-	// raise_expression: 'raise'
+    // reduced to check for unary_expression
+    // postfix_expression: primary_expression | 'module' (was file)
+    // unary_operator: '+' | '-' | '!' | 'not'
+    // raise_expression: 'raise'
 
 
-	return (token_isprimary_expression(token) || (token == TOK_OP_ADD) || (token == TOK_OP_SUB) ||
-			(token == TOK_OP_NOT) || (token == TOK_KEY_CURRARGS) || (token == TOK_KEY_CURRFUNC));
+    return (token_isprimary_expression(token) || (token == TOK_OP_ADD) || (token == TOK_OP_SUB) ||
+            (token == TOK_OP_NOT) || (token == TOK_KEY_CURRARGS) || (token == TOK_KEY_CURRFUNC));
 }
 }
 
 
 bool token_islabel_statement (gtoken_t token) {
 bool token_islabel_statement (gtoken_t token) {
-	return ((token == TOK_KEY_CASE) || (token == TOK_KEY_DEFAULT));
+    return ((token == TOK_KEY_CASE) || (token == TOK_KEY_DEFAULT));
 }
 }
 
 
 bool token_isflow_statement (gtoken_t token) {
 bool token_isflow_statement (gtoken_t token) {
-	return ((token == TOK_KEY_IF) || (token == TOK_KEY_SWITCH));
+    return ((token == TOK_KEY_IF) || (token == TOK_KEY_SWITCH));
 }
 }
 
 
 bool token_isloop_statement (gtoken_t token) {
 bool token_isloop_statement (gtoken_t token) {
-	return ((token == TOK_KEY_WHILE) || (token == TOK_KEY_REPEAT)  || (token == TOK_KEY_FOR));
+    return ((token == TOK_KEY_WHILE) || (token == TOK_KEY_REPEAT)  || (token == TOK_KEY_FOR));
 }
 }
 
 
 bool token_isjump_statement (gtoken_t token) {
 bool token_isjump_statement (gtoken_t token) {
-	return ((token == TOK_KEY_BREAK) || (token == TOK_KEY_CONTINUE) || (token == TOK_KEY_RETURN));
+    return ((token == TOK_KEY_BREAK) || (token == TOK_KEY_CONTINUE) || (token == TOK_KEY_RETURN));
 }
 }
 
 
 bool token_iscompound_statement (gtoken_t token) {
 bool token_iscompound_statement (gtoken_t token) {
-	return (token == TOK_OP_OPEN_CURLYBRACE);
+    return (token == TOK_OP_OPEN_CURLYBRACE);
 }
 }
 
 
 bool token_isdeclaration_statement (gtoken_t token) {
 bool token_isdeclaration_statement (gtoken_t token) {
-	// variable_declaration_statement (CONST, VAR)
-	// function_declaration (FUNC)
-	// class_declaration (CLASS | STRUCT)
-	// enum_declaration (ENUM)
-	// module_declaration (MODULE)
-	// event_declaration_statement (EVENT)
-	// empty_declaration (;)
-
-	return ((token_isaccess_specifier(token) || token_isstorage_specifier(token) || token_isvariable_declaration(token) ||
-			(token == TOK_KEY_FUNC)	|| (token == TOK_KEY_CLASS) || (token == TOK_KEY_STRUCT) || (token == TOK_KEY_ENUM) ||
-			(token == TOK_KEY_MODULE) || (token == TOK_KEY_EVENT)  || (token == TOK_OP_SEMICOLON)));
+    // variable_declaration_statement (CONST, VAR)
+    // function_declaration (FUNC)
+    // class_declaration (CLASS | STRUCT)
+    // enum_declaration (ENUM)
+    // module_declaration (MODULE)
+    // event_declaration_statement (EVENT)
+    // empty_declaration (;)
+
+    return ((token_isaccess_specifier(token) || token_isstorage_specifier(token) || token_isvariable_declaration(token) ||
+            (token == TOK_KEY_FUNC)    || (token == TOK_KEY_CLASS) || (token == TOK_KEY_STRUCT) || (token == TOK_KEY_ENUM) ||
+            (token == TOK_KEY_MODULE) || (token == TOK_KEY_EVENT)  || (token == TOK_OP_SEMICOLON)));
 }
 }
 
 
 bool token_isempty_statement (gtoken_t token) {
 bool token_isempty_statement (gtoken_t token) {
-	return (token == TOK_OP_SEMICOLON);
+    return (token == TOK_OP_SEMICOLON);
 }
 }
 
 
 bool token_isimport_statement (gtoken_t token) {
 bool token_isimport_statement (gtoken_t token) {
-	return (token == TOK_KEY_IMPORT);
+    return (token == TOK_KEY_IMPORT);
 }
 }
 
 
 bool token_isspecial_statement (gtoken_t token) {
 bool token_isspecial_statement (gtoken_t token) {
-	return (token == TOK_SPECIAL);
+    return (token == TOK_SPECIAL);
 }
 }
 
 
 bool token_isoperator (gtoken_t token) {
 bool token_isoperator (gtoken_t token) {
-	return ((token >= TOK_OP_SHIFT_LEFT) && (token <= TOK_OP_NOT));
+    return ((token >= TOK_OP_SHIFT_LEFT) && (token <= TOK_OP_NOT));
 }
 }
 
 
 bool token_ismacro (gtoken_t token) {
 bool token_ismacro (gtoken_t token) {
-	return (token == TOK_MACRO);
+    return (token == TOK_MACRO);
 }
 }
 
 
 bool token_iserror (gtoken_t token) {
 bool token_iserror (gtoken_t token) {
-	return (token == TOK_ERROR);
+    return (token == TOK_ERROR);
 }
 }
 
 
 bool token_iseof (gtoken_t token) {
 bool token_iseof (gtoken_t token) {
-	return (token == TOK_EOF);
+    return (token == TOK_EOF);
 }
 }

+ 115 - 115
src/compiler/gravity_token.h

@@ -12,85 +12,85 @@
 #include <stdint.h>
 #include <stdint.h>
 #include "debug_macros.h"
 #include "debug_macros.h"
 
 
-//	================
-//	PREFIX OPERATORS
-//	================
-//	+		Unary PLUS
-//	-		Unary MINUS
-//	!		Logical NOT
-//	~		Bitwise NOT
-
-//	================
-//	INFIX OPERATORS
-//	================
-//	<<		Bitwise left shift (160)
-//	>>		Bitwise right shift (160)
-//	*		Multiply (150) (associativity left)
-//	/		Divide (150) (associativity left)
-//	%		Remainder (150) (associativity left)
-//	&		Bitwise AND (150) (associativity left)
-//	+		Add (140) (associativity left)
-//	-		Subtract (140) (associativity left)
-//	|		Bitwise OR (140) (associativity left)
-//	^		Bitwise XOR (140) (associativity left)
-//	..<		Half-open range (135)
-//	...		Closed range (135)
-//	isa		Type check (132)
-//	<		Less than (130)
-//	<=		Less than or equal (130)
-//	>		Greater than (130)
-//	>=		Greater than or equal (130)
-//	==		Equal (130)
-//	!=		Not equal (130)
-//	===		Identical (130)
-//	!==		Not identical (130)
-//	~=		Pattern match (130)
-//	&&		Logical AND (120) (associativity left)
-//	||		Logical OR (110) (associativity left)
-//	?:		Ternary conditional (100) (associativity right)
-//	=		Assign (90) (associativity right)
-//	*=		Multiply and assign (90) (associativity right)
-//	/=		Divide and assign (90) (associativity right)
-//	%=		Remainder and assign (90) (associativity right)
-//	+=		Add and assign (90) (associativity right)
-//	-=		Subtract and assign (90) (associativity right)
-//	<<=		Left bit shift and assign (90) (associativity right)
-//	>>=		Right bit shift and assign (90) (associativity right)
-//	&=		Bitwise AND and assign (90) (associativity right)
-//	^=		Bitwise XOR and assign (90) (associativity right)
-//	|=		Bitwise OR and assign (90) (associativity right)
+//    ================
+//    PREFIX OPERATORS
+//    ================
+//    +         Unary PLUS
+//    -         Unary MINUS
+//    !         Logical NOT
+//    ~         Bitwise NOT
+
+//    ================
+//    INFIX OPERATORS
+//    ================
+//    <<        Bitwise left shift (160)
+//    >>        Bitwise right shift (160)
+//    *         Multiply (150) (associativity left)
+//    /         Divide (150) (associativity left)
+//    %         Remainder (150) (associativity left)
+//    &         Bitwise AND (150) (associativity left)
+//    +         Add (140) (associativity left)
+//    -         Subtract (140) (associativity left)
+//    |         Bitwise OR (140) (associativity left)
+//    ^         Bitwise XOR (140) (associativity left)
+//    ..<       Half-open range (135)
+//    ...       Closed range (135)
+//    is        Type check (132)
+//    <         Less than (130)
+//    <=        Less than or equal (130)
+//    >         Greater than (130)
+//    >=        Greater than or equal (130)
+//    ==        Equal (130)
+//    !=        Not equal (130)
+//    ===       Identical (130)
+//    !==       Not identical (130)
+//    ~=        Pattern match (130)
+//    &&        Logical AND (120) (associativity left)
+//    ||        Logical OR (110) (associativity left)
+//    ?:        Ternary conditional (100) (associativity right)
+//    =         Assign (90) (associativity right)
+//    *=        Multiply and assign (90) (associativity right)
+//    /=        Divide and assign (90) (associativity right)
+//    %=        Remainder and assign (90) (associativity right)
+//    +=        Add and assign (90) (associativity right)
+//    -=        Subtract and assign (90) (associativity right)
+//    <<=       Left bit shift and assign (90) (associativity right)
+//    >>=       Right bit shift and assign (90) (associativity right)
+//    &=        Bitwise AND and assign (90) (associativity right)
+//    ^=        Bitwise XOR and assign (90) (associativity right)
+//    |=        Bitwise OR and assign (90) (associativity right)
 
 
 typedef enum {
 typedef enum {
-	// General (8)
-	TOK_EOF	= 0, TOK_ERROR, TOK_COMMENT, TOK_STRING, TOK_NUMBER, TOK_IDENTIFIER, TOK_SPECIAL, TOK_MACRO,
-
-	// Keywords (36)
-	// remember to keep in sync functions token_keywords_indexes and token_name
-	TOK_KEY_FUNC, TOK_KEY_SUPER, TOK_KEY_DEFAULT, TOK_KEY_TRUE, TOK_KEY_FALSE, TOK_KEY_IF,
-	TOK_KEY_ELSE, TOK_KEY_SWITCH, TOK_KEY_BREAK, TOK_KEY_CONTINUE, TOK_KEY_RETURN, TOK_KEY_WHILE,
-	TOK_KEY_REPEAT, TOK_KEY_FOR, TOK_KEY_IN, TOK_KEY_ENUM, TOK_KEY_CLASS, TOK_KEY_STRUCT, TOK_KEY_PRIVATE,
-	TOK_KEY_FILE, TOK_KEY_INTERNAL, TOK_KEY_PUBLIC, TOK_KEY_STATIC, TOK_KEY_EXTERN, TOK_KEY_LAZY, TOK_KEY_CONST,
-	TOK_KEY_VAR, TOK_KEY_MODULE, TOK_KEY_IMPORT, TOK_KEY_CASE, TOK_KEY_EVENT, TOK_KEY_NULL, TOK_KEY_UNDEFINED,
-	TOK_KEY_ISA, TOK_KEY_CURRFUNC, TOK_KEY_CURRARGS,
-
-	// Operators (36)
-	TOK_OP_SHIFT_LEFT, TOK_OP_SHIFT_RIGHT, TOK_OP_MUL, TOK_OP_DIV, TOK_OP_REM, TOK_OP_BIT_AND, TOK_OP_ADD, TOK_OP_SUB,
-	TOK_OP_BIT_OR, TOK_OP_BIT_XOR, TOK_OP_BIT_NOT, TOK_OP_RANGE_EXCLUDED, TOK_OP_RANGE_INCLUDED, TOK_OP_LESS, TOK_OP_LESS_EQUAL,
-	TOK_OP_GREATER, TOK_OP_GREATER_EQUAL, TOK_OP_ISEQUAL, TOK_OP_ISNOTEQUAL, TOK_OP_ISIDENTICAL, TOK_OP_ISNOTIDENTICAL,
-	TOK_OP_PATTERN_MATCH, TOK_OP_AND, TOK_OP_OR, TOK_OP_TERNARY, TOK_OP_ASSIGN, TOK_OP_MUL_ASSIGN, TOK_OP_DIV_ASSIGN,
-	TOK_OP_REM_ASSIGN, TOK_OP_ADD_ASSIGN, TOK_OP_SUB_ASSIGN, TOK_OP_SHIFT_LEFT_ASSIGN, TOK_OP_SHIFT_RIGHT_ASSIGN,
-	TOK_OP_BIT_AND_ASSIGN, TOK_OP_BIT_OR_ASSIGN, TOK_OP_BIT_XOR_ASSIGN, TOK_OP_NOT,
-
-	// Punctuators (10)
-	TOK_OP_SEMICOLON, TOK_OP_OPEN_PARENTHESIS, TOK_OP_COLON, TOK_OP_COMMA, TOK_OP_DOT, TOK_OP_CLOSED_PARENTHESIS,
-	TOK_OP_OPEN_SQUAREBRACKET, TOK_OP_CLOSED_SQUAREBRACKET, TOK_OP_OPEN_CURLYBRACE, TOK_OP_CLOSED_CURLYBRACE,
-
-	// Mark end of tokens (1)
-	TOK_END
+    // General (8)
+    TOK_EOF    = 0, TOK_ERROR, TOK_COMMENT, TOK_STRING, TOK_NUMBER, TOK_IDENTIFIER, TOK_SPECIAL, TOK_MACRO,
+
+    // Keywords (36)
+    // remember to keep in sync functions token_keywords_indexes and token_name
+    TOK_KEY_FUNC, TOK_KEY_SUPER, TOK_KEY_DEFAULT, TOK_KEY_TRUE, TOK_KEY_FALSE, TOK_KEY_IF,
+    TOK_KEY_ELSE, TOK_KEY_SWITCH, TOK_KEY_BREAK, TOK_KEY_CONTINUE, TOK_KEY_RETURN, TOK_KEY_WHILE,
+    TOK_KEY_REPEAT, TOK_KEY_FOR, TOK_KEY_IN, TOK_KEY_ENUM, TOK_KEY_CLASS, TOK_KEY_STRUCT, TOK_KEY_PRIVATE,
+    TOK_KEY_FILE, TOK_KEY_INTERNAL, TOK_KEY_PUBLIC, TOK_KEY_STATIC, TOK_KEY_EXTERN, TOK_KEY_LAZY, TOK_KEY_CONST,
+    TOK_KEY_VAR, TOK_KEY_MODULE, TOK_KEY_IMPORT, TOK_KEY_CASE, TOK_KEY_EVENT, TOK_KEY_NULL, TOK_KEY_UNDEFINED,
+    TOK_KEY_ISA, TOK_KEY_CURRFUNC, TOK_KEY_CURRARGS,
+
+    // Operators (36)
+    TOK_OP_SHIFT_LEFT, TOK_OP_SHIFT_RIGHT, TOK_OP_MUL, TOK_OP_DIV, TOK_OP_REM, TOK_OP_BIT_AND, TOK_OP_ADD, TOK_OP_SUB,
+    TOK_OP_BIT_OR, TOK_OP_BIT_XOR, TOK_OP_BIT_NOT, TOK_OP_RANGE_EXCLUDED, TOK_OP_RANGE_INCLUDED, TOK_OP_LESS, TOK_OP_LESS_EQUAL,
+    TOK_OP_GREATER, TOK_OP_GREATER_EQUAL, TOK_OP_ISEQUAL, TOK_OP_ISNOTEQUAL, TOK_OP_ISIDENTICAL, TOK_OP_ISNOTIDENTICAL,
+    TOK_OP_PATTERN_MATCH, TOK_OP_AND, TOK_OP_OR, TOK_OP_TERNARY, TOK_OP_ASSIGN, TOK_OP_MUL_ASSIGN, TOK_OP_DIV_ASSIGN,
+    TOK_OP_REM_ASSIGN, TOK_OP_ADD_ASSIGN, TOK_OP_SUB_ASSIGN, TOK_OP_SHIFT_LEFT_ASSIGN, TOK_OP_SHIFT_RIGHT_ASSIGN,
+    TOK_OP_BIT_AND_ASSIGN, TOK_OP_BIT_OR_ASSIGN, TOK_OP_BIT_XOR_ASSIGN, TOK_OP_NOT,
+
+    // Punctuators (10)
+    TOK_OP_SEMICOLON, TOK_OP_OPEN_PARENTHESIS, TOK_OP_COLON, TOK_OP_COMMA, TOK_OP_DOT, TOK_OP_CLOSED_PARENTHESIS,
+    TOK_OP_OPEN_SQUAREBRACKET, TOK_OP_CLOSED_SQUAREBRACKET, TOK_OP_OPEN_CURLYBRACE, TOK_OP_CLOSED_CURLYBRACE,
+
+    // Mark end of tokens (1)
+    TOK_END
 } gtoken_t;
 } gtoken_t;
 
 
 typedef enum {
 typedef enum {
-	LITERAL_STRING, LITERAL_FLOAT, LITERAL_INT, LITERAL_BOOL, LITERAL_STRING_INTERPOLATED
+    LITERAL_STRING, LITERAL_FLOAT, LITERAL_INT, LITERAL_BOOL, LITERAL_STRING_INTERPOLATED
 } gliteral_t;
 } gliteral_t;
 
 
 typedef enum {
 typedef enum {
@@ -98,51 +98,51 @@ typedef enum {
 } gbuiltin_t;
 } gbuiltin_t;
 
 
 struct gtoken_s {
 struct gtoken_s {
-	gtoken_t			type;		// enum based token type
-	uint32_t			lineno;		// token line number (1-based)
-	uint32_t			colno;		// token column number (0-based) at the end of the token
-	uint32_t			position;	// offset of the first character of the token
-	uint32_t			bytes;		// token length in bytes
-	uint32_t			length;		// token length (UTF-8)
-	uint32_t			fileid;		// token file id
+    gtoken_t            type;       // enum based token type
+    uint32_t            lineno;     // token line number (1-based)
+    uint32_t            colno;      // token column number (0-based) at the end of the token
+    uint32_t            position;   // offset of the first character of the token
+    uint32_t            bytes;      // token length in bytes
+    uint32_t            length;     // token length (UTF-8)
+    uint32_t            fileid;     // token file id
     gbuiltin_t          builtin;    // builtin special identifier flag
     gbuiltin_t          builtin;    // builtin special identifier flag
-	const char			*value;		// token value (not null terminated)
+    const char          *value;     // token value (not null terminated)
 };
 };
-typedef struct gtoken_s	gtoken_s;
+typedef struct gtoken_s         gtoken_s;
 
 
-#define NO_TOKEN				(gtoken_s){0,0,0,0,0,0,0,0,NULL}
-#define UNDEF_TOKEN				(gtoken_s){TOK_KEY_UNDEFINED,0,0,0,0,0,0,0,NULL}
-#define TOKEN_BYTES(_tok)		_tok.bytes
-#define TOKEN_VALUE(_tok)		_tok.value
+#define NO_TOKEN                (gtoken_s){0,0,0,0,0,0,0,0,NULL}
+#define UNDEF_TOKEN             (gtoken_s){TOK_KEY_UNDEFINED,0,0,0,0,0,0,0,NULL}
+#define TOKEN_BYTES(_tok)       _tok.bytes
+#define TOKEN_VALUE(_tok)       _tok.value
 
 
-const char		*token_string (gtoken_s token, uint32_t *len);
-const char		*token_name (gtoken_t token);
-gtoken_t		token_keyword (const char *buffer, int32_t len);
+const char      *token_string (gtoken_s token, uint32_t *len);
+const char      *token_name (gtoken_t token);
+gtoken_t        token_keyword (const char *buffer, int32_t len);
 gtoken_t        token_special_builtin(gtoken_s *token);
 gtoken_t        token_special_builtin(gtoken_s *token);
-void			token_keywords_indexes (uint32_t *idx_start, uint32_t *idx_end);
-const char		*token_literal_name (gliteral_t value);
-
-bool			token_islabel_statement (gtoken_t token);
-bool			token_isflow_statement (gtoken_t token);
-bool			token_isloop_statement (gtoken_t token);
-bool			token_isjump_statement (gtoken_t token);
-bool			token_iscompound_statement (gtoken_t token);
-bool			token_isdeclaration_statement (gtoken_t token);
-bool			token_isempty_statement (gtoken_t token);
-bool			token_isimport_statement (gtoken_t token);
-bool			token_isspecial_statement (gtoken_t token);
-bool			token_isoperator (gtoken_t token);
-bool			token_ismacro (gtoken_t token);
-bool			token_iserror (gtoken_t token);
-bool			token_iseof (gtoken_t token);
-bool			token_isidentifier (gtoken_t token);
-bool			token_isvariable_declaration (gtoken_t token);
-bool			token_isstatement (gtoken_t token);
-bool			token_isassignment (gtoken_t token);
-bool			token_isvariable_assignment (gtoken_t token);
-bool			token_isaccess_specifier (gtoken_t token);
-bool			token_isstorage_specifier (gtoken_t token);
-bool			token_isprimary_expression (gtoken_t token);
-bool			token_isexpression_statement (gtoken_t token);
+void            token_keywords_indexes (uint32_t *idx_start, uint32_t *idx_end);
+const char      *token_literal_name (gliteral_t value);
+
+bool            token_islabel_statement (gtoken_t token);
+bool            token_isflow_statement (gtoken_t token);
+bool            token_isloop_statement (gtoken_t token);
+bool            token_isjump_statement (gtoken_t token);
+bool            token_iscompound_statement (gtoken_t token);
+bool            token_isdeclaration_statement (gtoken_t token);
+bool            token_isempty_statement (gtoken_t token);
+bool            token_isimport_statement (gtoken_t token);
+bool            token_isspecial_statement (gtoken_t token);
+bool            token_isoperator (gtoken_t token);
+bool            token_ismacro (gtoken_t token);
+bool            token_iserror (gtoken_t token);
+bool            token_iseof (gtoken_t token);
+bool            token_isidentifier (gtoken_t token);
+bool            token_isvariable_declaration (gtoken_t token);
+bool            token_isstatement (gtoken_t token);
+bool            token_isassignment (gtoken_t token);
+bool            token_isvariable_assignment (gtoken_t token);
+bool            token_isaccess_specifier (gtoken_t token);
+bool            token_isstorage_specifier (gtoken_t token);
+bool            token_isprimary_expression (gtoken_t token);
+bool            token_isexpression_statement (gtoken_t token);
 
 
 #endif
 #endif

+ 36 - 36
src/compiler/gravity_visitor.c

@@ -10,55 +10,55 @@
 
 
 // Visit a node invoking the associated callback.
 // Visit a node invoking the associated callback.
 
 
-#define VISIT(type)		if (!self->visit_##type) return; \
-						self->visit_##type(self, (gnode_##type##_t *) node); \
-						break;
+#define VISIT(type)     if (!self->visit_##type) return; \
+                        self->visit_##type(self, (gnode_##type##_t *) node); \
+                        break;
 
 
 static void default_action (gnode_t *node) {
 static void default_action (gnode_t *node) {
-	printf("Visitor unhandled case: %d\n", node->tag);
-	assert(0);
+    printf("Visitor unhandled case: %d\n", node->tag);
+    assert(0);
 }
 }
 
 
 void gvisit(gvisitor_t *self, gnode_t *node) {
 void gvisit(gvisitor_t *self, gnode_t *node) {
-	// this line added after implemented getter and setter,
-	// because they are functions inside a COMPOUND_STATEMENT and can be NULL
-	if (!node) return;
+    // this line added after implemented getter and setter,
+    // because they are functions inside a COMPOUND_STATEMENT and can be NULL
+    if (!node) return;
 
 
     // pre-visit
     // pre-visit
     if (self->visit_pre) self->visit_pre(self, node);
     if (self->visit_pre) self->visit_pre(self, node);
 
 
-	switch (node->tag) {
+    switch (node->tag) {
 
 
-		// statements (7)
-		case NODE_LIST_STAT: VISIT(list_stmt);
-		case NODE_COMPOUND_STAT: VISIT(compound_stmt);
-		case NODE_LABEL_STAT: VISIT(label_stmt);
-		case NODE_FLOW_STAT: VISIT(flow_stmt);
-		case NODE_JUMP_STAT: VISIT(jump_stmt);
-		case NODE_LOOP_STAT: VISIT(loop_stmt);
-		case NODE_EMPTY_STAT: VISIT(empty_stmt);
+        // statements (7)
+        case NODE_LIST_STAT: VISIT(list_stmt);
+        case NODE_COMPOUND_STAT: VISIT(compound_stmt);
+        case NODE_LABEL_STAT: VISIT(label_stmt);
+        case NODE_FLOW_STAT: VISIT(flow_stmt);
+        case NODE_JUMP_STAT: VISIT(jump_stmt);
+        case NODE_LOOP_STAT: VISIT(loop_stmt);
+        case NODE_EMPTY_STAT: VISIT(empty_stmt);
 
 
-		// declarations (5)
-		case NODE_ENUM_DECL: VISIT(enum_decl);
-		case NODE_FUNCTION_DECL: VISIT(function_decl);
-		case NODE_VARIABLE_DECL: VISIT(variable_decl);
-		case NODE_CLASS_DECL: VISIT(class_decl);
-		case NODE_MODULE_DECL: VISIT(module_decl);
-		// NODE_VARIABLE is handled by NODE_VARIABLE_DECL
+        // declarations (5)
+        case NODE_ENUM_DECL: VISIT(enum_decl);
+        case NODE_FUNCTION_DECL: VISIT(function_decl);
+        case NODE_VARIABLE_DECL: VISIT(variable_decl);
+        case NODE_CLASS_DECL: VISIT(class_decl);
+        case NODE_MODULE_DECL: VISIT(module_decl);
+        // NODE_VARIABLE is handled by NODE_VARIABLE_DECL
 
 
-		// expressions (8)
-		case NODE_BINARY_EXPR: VISIT(binary_expr);
-		case NODE_UNARY_EXPR: VISIT(unary_expr);
-		case NODE_FILE_EXPR: VISIT(file_expr);
-		case NODE_LIST_EXPR: VISIT(list_expr);
-		case NODE_LITERAL_EXPR: VISIT(literal_expr);
-		case NODE_IDENTIFIER_EXPR: VISIT(identifier_expr);
-		case NODE_KEYWORD_EXPR: VISIT(keyword_expr);
-		case NODE_POSTFIX_EXPR: VISIT(postfix_expr);
+        // expressions (8)
+        case NODE_BINARY_EXPR: VISIT(binary_expr);
+        case NODE_UNARY_EXPR: VISIT(unary_expr);
+        case NODE_FILE_EXPR: VISIT(file_expr);
+        case NODE_LIST_EXPR: VISIT(list_expr);
+        case NODE_LITERAL_EXPR: VISIT(literal_expr);
+        case NODE_IDENTIFIER_EXPR: VISIT(identifier_expr);
+        case NODE_KEYWORD_EXPR: VISIT(keyword_expr);
+        case NODE_POSTFIX_EXPR: VISIT(postfix_expr);
 
 
-		// default assert
-		default: default_action(node);
-	}
+        // default assert
+        default: default_action(node);
+    }
 
 
     // post-visit
     // post-visit
     if (self->visit_post) self->visit_post(self, node);
     if (self->visit_post) self->visit_post(self, node);

+ 30 - 30
src/compiler/gravity_visitor.h

@@ -14,41 +14,41 @@
 #define visit(node) gvisit(self, node)
 #define visit(node) gvisit(self, node)
 
 
 typedef struct gvisitor {
 typedef struct gvisitor {
-	uint32_t	nerr;			// to store err counter state
-	void		*data;			// to store a ptr state
-	void		*delegate;		// delegate callback
+    uint32_t    nerr;            // to store err counter state
+    void        *data;            // to store a ptr state
+    void        *delegate;        // delegate callback
 
 
     // COMMON
     // COMMON
     void (* visit_pre)(struct gvisitor *self, gnode_t *node);
     void (* visit_pre)(struct gvisitor *self, gnode_t *node);
     void (* visit_post)(struct gvisitor *self, gnode_t *node);
     void (* visit_post)(struct gvisitor *self, gnode_t *node);
 
 
-	// count must be equal to enum gnode_n defined in gravity_ast.h less 3
-
-	// STATEMENTS: 7
-	void (* visit_list_stmt)(struct gvisitor *self, gnode_compound_stmt_t *node);
-	void (* visit_compound_stmt)(struct gvisitor *self, gnode_compound_stmt_t *node);
-	void (* visit_label_stmt)(struct gvisitor *self, gnode_label_stmt_t *node);
-	void (* visit_flow_stmt)(struct gvisitor *self, gnode_flow_stmt_t *node);
-	void (* visit_jump_stmt)(struct gvisitor *self, gnode_jump_stmt_t *node);
-	void (* visit_loop_stmt)(struct gvisitor *self, gnode_loop_stmt_t *node);
-	void (* visit_empty_stmt)(struct gvisitor *self, gnode_empty_stmt_t *node);
-
-	// DECLARATIONS: 5+1 (NODE_VARIABLE handled by NODE_VARIABLE_DECL case)
-	void (* visit_function_decl)(struct gvisitor *self, gnode_function_decl_t *node);
-	void (* visit_variable_decl)(struct gvisitor *self, gnode_variable_decl_t *node);
-	void (* visit_enum_decl)(struct gvisitor *self, gnode_enum_decl_t *node);
-	void (* visit_class_decl)(struct gvisitor *self, gnode_class_decl_t *node);
-	void (* visit_module_decl)(struct gvisitor *self, gnode_module_decl_t *node);
-
-	// EXPRESSIONS: 7+3 (CALL EXPRESSIONS handled by one callback)
-	void (* visit_binary_expr)(struct gvisitor *self, gnode_binary_expr_t *node);
-	void (* visit_unary_expr)(struct gvisitor *self, gnode_unary_expr_t *node);
-	void (* visit_file_expr)(struct gvisitor *self, gnode_file_expr_t *node);
-	void (* visit_literal_expr)(struct gvisitor *self, gnode_literal_expr_t *node);
-	void (* visit_identifier_expr)(struct gvisitor *self, gnode_identifier_expr_t *node);
-	void (* visit_keyword_expr)(struct gvisitor *self, gnode_keyword_expr_t *node);
-	void (* visit_list_expr)(struct gvisitor *self, gnode_list_expr_t *node);
-	void (* visit_postfix_expr)(struct gvisitor *self, gnode_postfix_expr_t *node);
+    // count must be equal to enum gnode_n defined in gravity_ast.h less 3
+
+    // STATEMENTS: 7
+    void (* visit_list_stmt)(struct gvisitor *self, gnode_compound_stmt_t *node);
+    void (* visit_compound_stmt)(struct gvisitor *self, gnode_compound_stmt_t *node);
+    void (* visit_label_stmt)(struct gvisitor *self, gnode_label_stmt_t *node);
+    void (* visit_flow_stmt)(struct gvisitor *self, gnode_flow_stmt_t *node);
+    void (* visit_jump_stmt)(struct gvisitor *self, gnode_jump_stmt_t *node);
+    void (* visit_loop_stmt)(struct gvisitor *self, gnode_loop_stmt_t *node);
+    void (* visit_empty_stmt)(struct gvisitor *self, gnode_empty_stmt_t *node);
+
+    // DECLARATIONS: 5+1 (NODE_VARIABLE handled by NODE_VARIABLE_DECL case)
+    void (* visit_function_decl)(struct gvisitor *self, gnode_function_decl_t *node);
+    void (* visit_variable_decl)(struct gvisitor *self, gnode_variable_decl_t *node);
+    void (* visit_enum_decl)(struct gvisitor *self, gnode_enum_decl_t *node);
+    void (* visit_class_decl)(struct gvisitor *self, gnode_class_decl_t *node);
+    void (* visit_module_decl)(struct gvisitor *self, gnode_module_decl_t *node);
+
+    // EXPRESSIONS: 7+3 (CALL EXPRESSIONS handled by one callback)
+    void (* visit_binary_expr)(struct gvisitor *self, gnode_binary_expr_t *node);
+    void (* visit_unary_expr)(struct gvisitor *self, gnode_unary_expr_t *node);
+    void (* visit_file_expr)(struct gvisitor *self, gnode_file_expr_t *node);
+    void (* visit_literal_expr)(struct gvisitor *self, gnode_literal_expr_t *node);
+    void (* visit_identifier_expr)(struct gvisitor *self, gnode_identifier_expr_t *node);
+    void (* visit_keyword_expr)(struct gvisitor *self, gnode_keyword_expr_t *node);
+    void (* visit_list_expr)(struct gvisitor *self, gnode_list_expr_t *node);
+    void (* visit_postfix_expr)(struct gvisitor *self, gnode_postfix_expr_t *node);
 } gvisitor_t;
 } gvisitor_t;
 
 
 void gvisit(gvisitor_t *self, gnode_t *node);
 void gvisit(gvisitor_t *self, gnode_t *node);

File diff suppressed because it is too large
+ 413 - 413
src/runtime/gravity_core.c


+ 1 - 1
src/runtime/gravity_core.h

@@ -30,7 +30,7 @@ gravity_value_t convert_value2string (gravity_vm *vm, gravity_value_t v);
 
 
 // internal functions
 // internal functions
 gravity_closure_t *computed_property_create (gravity_vm *vm, gravity_function_t *getter_func, gravity_function_t *setter_func);
 gravity_closure_t *computed_property_create (gravity_vm *vm, gravity_function_t *getter_func, gravity_function_t *setter_func);
-void              computed_property_free (gravity_class_t *c, const char *name, bool remove_flag);
+void computed_property_free (gravity_class_t *c, const char *name, bool remove_flag);
 
 
 #ifdef __cplusplus
 #ifdef __cplusplus
 }
 }

File diff suppressed because it is too large
+ 864 - 864
src/runtime/gravity_vm.c


+ 43 - 43
src/runtime/gravity_vm.h

@@ -28,56 +28,56 @@ typedef bool (*vm_filter_cb) (gravity_object_t *obj);
 typedef void (*vm_transfer_cb) (gravity_vm *vm, gravity_object_t *obj);
 typedef void (*vm_transfer_cb) (gravity_vm *vm, gravity_object_t *obj);
 typedef void (*vm_cleanup_cb) (gravity_vm *vm);
 typedef void (*vm_cleanup_cb) (gravity_vm *vm);
 
 
-GRAVITY_API gravity_vm			*gravity_vm_new (gravity_delegate_t *delegate);
-GRAVITY_API gravity_vm			*gravity_vm_newmini (void);
-GRAVITY_API void				gravity_vm_set_callbacks (gravity_vm *vm, vm_transfer_cb vm_transfer, vm_cleanup_cb vm_cleanup);
-GRAVITY_API void				gravity_vm_free (gravity_vm *vm);
-GRAVITY_API void				gravity_vm_reset (gravity_vm *vm);
-GRAVITY_API bool				gravity_vm_runclosure (gravity_vm *vm, gravity_closure_t *closure, gravity_value_t sender, gravity_value_t params[], uint16_t nparams);
-GRAVITY_API bool				gravity_vm_runmain (gravity_vm *vm, gravity_closure_t *closure);
-GRAVITY_API void				gravity_vm_loadclosure (gravity_vm *vm, gravity_closure_t *closure);
-GRAVITY_API void				gravity_vm_setvalue (gravity_vm *vm, const char *key, gravity_value_t value);
-GRAVITY_API gravity_value_t		gravity_vm_lookup (gravity_vm *vm, gravity_value_t key);
-GRAVITY_API gravity_value_t		gravity_vm_getvalue (gravity_vm *vm, const char *key, uint32_t keylen);
-GRAVITY_API double				gravity_vm_time (gravity_vm *vm);
-GRAVITY_API gravity_value_t		gravity_vm_result (gravity_vm *vm);
-GRAVITY_API gravity_delegate_t	*gravity_vm_delegate (gravity_vm *vm);
-GRAVITY_API gravity_fiber_t		*gravity_vm_fiber (gravity_vm *vm);
-GRAVITY_API void				gravity_vm_setfiber(gravity_vm* vm, gravity_fiber_t *fiber);
-GRAVITY_API void				gravity_vm_seterror (gravity_vm *vm, const char *format, ...);
-GRAVITY_API void				gravity_vm_seterror_string (gravity_vm* vm, const char *s);
-GRAVITY_API bool				gravity_vm_ismini (gravity_vm *vm);
-GRAVITY_API gravity_value_t		gravity_vm_keyindex (gravity_vm *vm, uint32_t index);
-GRAVITY_API bool				gravity_vm_isaborted (gravity_vm *vm);
-GRAVITY_API void				gravity_vm_setaborted (gravity_vm *vm);
+GRAVITY_API gravity_vm          *gravity_vm_new (gravity_delegate_t *delegate);
+GRAVITY_API gravity_vm          *gravity_vm_newmini (void);
+GRAVITY_API void                gravity_vm_set_callbacks (gravity_vm *vm, vm_transfer_cb vm_transfer, vm_cleanup_cb vm_cleanup);
+GRAVITY_API void                gravity_vm_free (gravity_vm *vm);
+GRAVITY_API void                gravity_vm_reset (gravity_vm *vm);
+GRAVITY_API bool                gravity_vm_runclosure (gravity_vm *vm, gravity_closure_t *closure, gravity_value_t sender, gravity_value_t params[], uint16_t nparams);
+GRAVITY_API bool                gravity_vm_runmain (gravity_vm *vm, gravity_closure_t *closure);
+GRAVITY_API void                gravity_vm_loadclosure (gravity_vm *vm, gravity_closure_t *closure);
+GRAVITY_API void                gravity_vm_setvalue (gravity_vm *vm, const char *key, gravity_value_t value);
+GRAVITY_API gravity_value_t     gravity_vm_lookup (gravity_vm *vm, gravity_value_t key);
+GRAVITY_API gravity_value_t     gravity_vm_getvalue (gravity_vm *vm, const char *key, uint32_t keylen);
+GRAVITY_API double              gravity_vm_time (gravity_vm *vm);
+GRAVITY_API gravity_value_t     gravity_vm_result (gravity_vm *vm);
+GRAVITY_API gravity_delegate_t  *gravity_vm_delegate (gravity_vm *vm);
+GRAVITY_API gravity_fiber_t     *gravity_vm_fiber (gravity_vm *vm);
+GRAVITY_API void                gravity_vm_setfiber(gravity_vm* vm, gravity_fiber_t *fiber);
+GRAVITY_API void                gravity_vm_seterror (gravity_vm *vm, const char *format, ...);
+GRAVITY_API void                gravity_vm_seterror_string (gravity_vm* vm, const char *s);
+GRAVITY_API bool                gravity_vm_ismini (gravity_vm *vm);
+GRAVITY_API gravity_value_t     gravity_vm_keyindex (gravity_vm *vm, uint32_t index);
+GRAVITY_API bool                gravity_vm_isaborted (gravity_vm *vm);
+GRAVITY_API void                gravity_vm_setaborted (gravity_vm *vm);
 GRAVITY_API gravity_closure_t   *gravity_vm_getclosure (gravity_vm *vm);
 GRAVITY_API gravity_closure_t   *gravity_vm_getclosure (gravity_vm *vm);
 
 
-GRAVITY_API void				gravity_gray_value (gravity_vm* vm, gravity_value_t v);
-GRAVITY_API void				gravity_gray_object (gravity_vm* vm, gravity_object_t *obj);
-GRAVITY_API void				gravity_gc_start (gravity_vm* vm);
-GRAVITY_API void				gravity_gc_setenabled (gravity_vm* vm, bool enabled);
-GRAVITY_API void				gravity_gc_push (gravity_vm *vm, gravity_object_t *obj);
-GRAVITY_API void				gravity_gc_pop (gravity_vm *vm);
+GRAVITY_API void                gravity_gray_value (gravity_vm* vm, gravity_value_t v);
+GRAVITY_API void                gravity_gray_object (gravity_vm* vm, gravity_object_t *obj);
+GRAVITY_API void                gravity_gc_start (gravity_vm* vm);
+GRAVITY_API void                gravity_gc_setenabled (gravity_vm* vm, bool enabled);
+GRAVITY_API void                gravity_gc_push (gravity_vm *vm, gravity_object_t *obj);
+GRAVITY_API void                gravity_gc_pop (gravity_vm *vm);
 
 
-GRAVITY_API void				gravity_vm_transfer (gravity_vm* vm, gravity_object_t *obj);
-GRAVITY_API void				gravity_vm_cleanup (gravity_vm* vm);
-GRAVITY_API void				gravity_vm_filter (gravity_vm* vm, vm_filter_cb cleanup_filter);
+GRAVITY_API void                gravity_vm_transfer (gravity_vm* vm, gravity_object_t *obj);
+GRAVITY_API void                gravity_vm_cleanup (gravity_vm* vm);
+GRAVITY_API void                gravity_vm_filter (gravity_vm* vm, vm_filter_cb cleanup_filter);
 
 
-GRAVITY_API gravity_closure_t	*gravity_vm_loadfile (gravity_vm *vm, const char *path);
-GRAVITY_API gravity_closure_t	*gravity_vm_loadbuffer (gravity_vm *vm, const char *buffer, size_t len);
-GRAVITY_API void				gravity_vm_initmodule (gravity_vm *vm, gravity_function_t *f);
+GRAVITY_API gravity_closure_t   *gravity_vm_loadfile (gravity_vm *vm, const char *path);
+GRAVITY_API gravity_closure_t   *gravity_vm_loadbuffer (gravity_vm *vm, const char *buffer, size_t len);
+GRAVITY_API void                gravity_vm_initmodule (gravity_vm *vm, gravity_function_t *f);
 
 
-GRAVITY_API gravity_closure_t	*gravity_vm_fastlookup (gravity_vm *vm, gravity_class_t *c, int index);
-GRAVITY_API void				gravity_vm_setslot (gravity_vm *vm, gravity_value_t value, uint32_t index);
-GRAVITY_API gravity_value_t		gravity_vm_getslot (gravity_vm *vm, uint32_t index);
-GRAVITY_API void				gravity_vm_setdata (gravity_vm *vm, void *data);
-GRAVITY_API void				*gravity_vm_getdata (gravity_vm *vm);
-GRAVITY_API void				gravity_vm_memupdate (gravity_vm *vm, gravity_int_t value);
+GRAVITY_API gravity_closure_t   *gravity_vm_fastlookup (gravity_vm *vm, gravity_class_t *c, int index);
+GRAVITY_API void                gravity_vm_setslot (gravity_vm *vm, gravity_value_t value, uint32_t index);
+GRAVITY_API gravity_value_t     gravity_vm_getslot (gravity_vm *vm, uint32_t index);
+GRAVITY_API void                gravity_vm_setdata (gravity_vm *vm, void *data);
+GRAVITY_API void                *gravity_vm_getdata (gravity_vm *vm);
+GRAVITY_API void                gravity_vm_memupdate (gravity_vm *vm, gravity_int_t value);
 GRAVITY_API gravity_int_t       gravity_vm_maxmemblock (gravity_vm *vm);
 GRAVITY_API gravity_int_t       gravity_vm_maxmemblock (gravity_vm *vm);
 
 
-GRAVITY_API gravity_value_t		gravity_vm_get (gravity_vm *vm, const char *key);
-GRAVITY_API bool				gravity_vm_set (gravity_vm *vm, const char *key, gravity_value_t value);
-GRAVITY_API char				*gravity_vm_anonymous (gravity_vm *vm);
+GRAVITY_API gravity_value_t     gravity_vm_get (gravity_vm *vm, const char *key);
+GRAVITY_API bool                gravity_vm_set (gravity_vm *vm, const char *key, gravity_value_t value);
+GRAVITY_API char                *gravity_vm_anonymous (gravity_vm *vm);
 
 
 GRAVITY_API bool                gravity_isopt_class (gravity_class_t *c);
 GRAVITY_API bool                gravity_isopt_class (gravity_class_t *c);
 GRAVITY_API void                gravity_opt_register (gravity_vm *vm);
 GRAVITY_API void                gravity_opt_register (gravity_vm *vm);

+ 188 - 188
src/runtime/gravity_vmmacros.h

@@ -12,7 +12,7 @@
 // MACROS used in VM
 // MACROS used in VM
 
 
 #if 0
 #if 0
-#define DEBUG_CALL(s, f)								printf("%s %s\n", s, f->identifier)
+#define DEBUG_CALL(s, f)                                printf("%s %s\n", s, f->identifier)
 #else
 #else
 #define DEBUG_CALL(s, f)
 #define DEBUG_CALL(s, f)
 #endif
 #endif
@@ -20,44 +20,44 @@
 // signed operation decoding (OPCODE_GET_ONE8bit_SIGN_ONE17bit) from my question on stackoverflow
 // signed operation decoding (OPCODE_GET_ONE8bit_SIGN_ONE17bit) from my question on stackoverflow
 // http://stackoverflow.com/questions/37054769/optimize-a-bit-decoding-operation-in-c?noredirect=1#comment61673505_37054769
 // http://stackoverflow.com/questions/37054769/optimize-a-bit-decoding-operation-in-c?noredirect=1#comment61673505_37054769
 
 
-#define OPCODE_GET_OPCODE(op)							((op >> 26) & 0x3F)
-#define OPCODE_GET_ONE8bit_FLAG_ONE17bit(op,r1,f,n)		r1 = (op >> 18) & 0xFF; f = (op >> 17) & 0x01; n = (int32_t)(op & 0x1FFFF)
-#define OPCODE_GET_ONE8bit_SIGN_ONE17bit(op,r1,n)		r1 = (op >> 18) & 0xFF; n = ((int32_t)(op & 0x1FFFF) - (int32_t)(op & 0x20000))
-#define OPCODE_GET_TWO8bit_ONE10bit(op,r1,r2,r3)		r1 = (op >> 18) & 0xFF; r2 = (op >> 10) & 0xFF; r3 = (op & 0x3FF)
-#define OPCODE_GET_ONE8bit(op,r1)						r1 = (op >> 18) & 0xFF;
-#define OPCODE_GET_SIGN_ONE25bit(op, n)					n = ((op >> 25) & 0x01) ? -(op & 0x1FFFFFF) : (op & 0x1FFFFFF)
-#define OPCODE_GET_ONE8bit_ONE18bit(op,r1,n)			r1 = (op >> 18) & 0xFF; n = (op & 0x3FFFF)
-#define OPCODE_GET_LAST18bit(op,n)						n = (op & 0x3FFFF)
-#define OPCODE_GET_ONE26bit(op, n)						n = (op & 0x3FFFFFF)
-#define OPCODE_GET_ONE8bit_ONE10bit(op,r1,r3)			r1 = (op >> 18) & 0xFF; r3 = (op & 0x3FF)
-#define OPCODE_GET_THREE8bit(op,r1,r2,r3)				OPCODE_GET_TWO8bit_ONE10bit(op,r1,r2,r3)
-#define OPCODE_GET_FOUR8bit(op,r1,r2,r3,r4)				r1 = (op >> 24) & 0xFF; r2 = (op >> 16) & 0xFF; r3 = (op >> 8) & 0xFF; r4 = (op & 0xFF)
-#define OPCODE_GET_THREE8bit_ONE2bit(op,r1,r2,r3,r4)	r1 = (op >> 18) & 0xFF; r2 = (op >> 10) & 0xFF; r3 = (op >> 2) & 0xFF; r4 = (op & 0x03)
-
-#define GRAVITY_VM_DEGUB								0
-#define GRAVITY_VM_STATS								0
-#define GRAVITY_GC_STATS								0
-#define GRAVITY_GC_STRESSTEST							0
-#define GRAVITY_GC_DEBUG								0
-#define GRAVITY_STACK_DEBUG								0
+#define OPCODE_GET_OPCODE(op)                           ((op >> 26) & 0x3F)
+#define OPCODE_GET_ONE8bit_FLAG_ONE17bit(op,r1,f,n)     r1 = (op >> 18) & 0xFF; f = (op >> 17) & 0x01; n = (int32_t)(op & 0x1FFFF)
+#define OPCODE_GET_ONE8bit_SIGN_ONE17bit(op,r1,n)       r1 = (op >> 18) & 0xFF; n = ((int32_t)(op & 0x1FFFF) - (int32_t)(op & 0x20000))
+#define OPCODE_GET_TWO8bit_ONE10bit(op,r1,r2,r3)        r1 = (op >> 18) & 0xFF; r2 = (op >> 10) & 0xFF; r3 = (op & 0x3FF)
+#define OPCODE_GET_ONE8bit(op,r1)                       r1 = (op >> 18) & 0xFF;
+#define OPCODE_GET_SIGN_ONE25bit(op, n)                 n = ((op >> 25) & 0x01) ? -(op & 0x1FFFFFF) : (op & 0x1FFFFFF)
+#define OPCODE_GET_ONE8bit_ONE18bit(op,r1,n)            r1 = (op >> 18) & 0xFF; n = (op & 0x3FFFF)
+#define OPCODE_GET_LAST18bit(op,n)                      n = (op & 0x3FFFF)
+#define OPCODE_GET_ONE26bit(op, n)                      n = (op & 0x3FFFFFF)
+#define OPCODE_GET_ONE8bit_ONE10bit(op,r1,r3)           r1 = (op >> 18) & 0xFF; r3 = (op & 0x3FF)
+#define OPCODE_GET_THREE8bit(op,r1,r2,r3)               OPCODE_GET_TWO8bit_ONE10bit(op,r1,r2,r3)
+#define OPCODE_GET_FOUR8bit(op,r1,r2,r3,r4)             r1 = (op >> 24) & 0xFF; r2 = (op >> 16) & 0xFF; r3 = (op >> 8) & 0xFF; r4 = (op & 0xFF)
+#define OPCODE_GET_THREE8bit_ONE2bit(op,r1,r2,r3,r4)    r1 = (op >> 18) & 0xFF; r2 = (op >> 10) & 0xFF; r3 = (op >> 2) & 0xFF; r4 = (op & 0x03)
+
+#define GRAVITY_VM_DEGUB                0
+#define GRAVITY_VM_STATS                0
+#define GRAVITY_GC_STATS                0
+#define GRAVITY_GC_STRESSTEST           0
+#define GRAVITY_GC_DEBUG                0
+#define GRAVITY_STACK_DEBUG             0
 
 
 #if GRAVITY_STACK_DEBUG
 #if GRAVITY_STACK_DEBUG
-#define DEBUG_STACK()									gravity_stack_dump(fiber)
+#define DEBUG_STACK()                   gravity_stack_dump(fiber)
 #else
 #else
 #define DEBUG_STACK()
 #define DEBUG_STACK()
 #endif
 #endif
 
 
 #if GRAVITY_GC_DEBUG
 #if GRAVITY_GC_DEBUG
-#define DEBUG_GC(...)									printf(__VA_ARGS__);printf("\n");fflush(stdout)
+#define DEBUG_GC(...)                   printf(__VA_ARGS__);printf("\n");fflush(stdout)
 #else
 #else
 #define DEBUG_GC(...)
 #define DEBUG_GC(...)
 #endif
 #endif
 
 
 #if GRAVITY_VM_DEGUB
 #if GRAVITY_VM_DEGUB
-#define DEBUG_VM(...)									DEBUG_STACK();printf("%06u\t",vm->pc); printf(__VA_ARGS__);printf("\n");fflush(stdout)
-#define DEBUG_VM_NOCR(...)								DEBUG_STACK();printf("%06u\t",vm->pc); printf(__VA_ARGS__);fflush(stdout)
-#define DEBUG_VM_RAW(...)								printf(__VA_ARGS__);fflush(stdout)
-#define INC_PC											++vm->pc;
+#define DEBUG_VM(...)                   DEBUG_STACK();printf("%06u\t",vm->pc); printf(__VA_ARGS__);printf("\n");fflush(stdout)
+#define DEBUG_VM_NOCR(...)              DEBUG_STACK();printf("%06u\t",vm->pc); printf(__VA_ARGS__);fflush(stdout)
+#define DEBUG_VM_RAW(...)               printf(__VA_ARGS__);fflush(stdout)
+#define INC_PC                          ++vm->pc;
 #else
 #else
 #define DEBUG_VM(...)
 #define DEBUG_VM(...)
 #define DEBUG_VM_NOCR(...)
 #define DEBUG_VM_NOCR(...)
@@ -66,12 +66,12 @@
 #endif
 #endif
 
 
 #if GRAVITY_VM_STATS
 #if GRAVITY_VM_STATS
-#define RESET_STATS(_vm)								bzero(_vm->nstat, sizeof(_vm->nstat)); bzero(_vm->tstat, sizeof(_vm->tstat))
-#define PRINT_STATS(_vm)								gravity_vm_stats(_vm)
-#define START_MICROBENCH(_vm)							_vm->t = nanotime()
-#define UPDATE_STATS(_vm,_op)							++_vm->nstat[_op]; _vm->tstat[_op] += millitime(_vm->t, nanotime())
-#define STAT_FRAMES_REALLOCATED(_vm)					++_vm->nfrealloc
-#define STAT_STACK_REALLOCATED(_vm)						++_vm->nsrealloc
+#define RESET_STATS(_vm)                bzero(_vm->nstat, sizeof(_vm->nstat)); bzero(_vm->tstat, sizeof(_vm->tstat))
+#define PRINT_STATS(_vm)                gravity_vm_stats(_vm)
+#define START_MICROBENCH(_vm)           _vm->t = nanotime()
+#define UPDATE_STATS(_vm,_op)           ++_vm->nstat[_op]; _vm->tstat[_op] += millitime(_vm->t, nanotime())
+#define STAT_FRAMES_REALLOCATED(_vm)    ++_vm->nfrealloc
+#define STAT_STACK_REALLOCATED(_vm)     ++_vm->nsrealloc
 #else
 #else
 #define RESET_STATS(_vm)
 #define RESET_STATS(_vm)
 #define PRINT_STATS(_vm)
 #define PRINT_STATS(_vm)
@@ -81,196 +81,196 @@
 #define STAT_STACK_REALLOCATED(_vm)
 #define STAT_STACK_REALLOCATED(_vm)
 #endif
 #endif
 
 
-#define RUNTIME_ERROR(...)								do {																\
-															report_runtime_error(vm, GRAVITY_ERROR_RUNTIME, __VA_ARGS__);	\
-															return false;													\
-														} while (0)
-
-#define RUNTIME_FIBER_ERROR(_err)						RUNTIME_ERROR("%s",_err)
-
-#define RUNTIME_WARNING(...)							do {																\
-															report_runtime_error(vm, GRAVITY_WARNING, __VA_ARGS__);			\
-														} while (0)
-
-#define SETVALUE_BOOL(idx, x)							stackstart[idx]=VALUE_FROM_BOOL(x)
-#define SETVALUE_INT(idx, x)							stackstart[idx]=VALUE_FROM_INT(x)
-#define SETVALUE_FLOAT(idx, x)							stackstart[idx]=VALUE_FROM_FLOAT(x)
-#define SETVALUE_NULL(idx)								stackstart[idx]=VALUE_FROM_NULL
-#define SETVALUE(idx, x)								stackstart[idx]=x
-#define GETVALUE_INT(v)									v.n
-#define GETVALUE_FLOAT(v)								v.f
-#define STACK_GET(idx)									stackstart[idx]
+#define RUNTIME_ERROR(...)              do {                                                                \
+                                            report_runtime_error(vm, GRAVITY_ERROR_RUNTIME, __VA_ARGS__);   \
+                                            return false;                                                   \
+                                        } while (0)
+
+#define RUNTIME_FIBER_ERROR(_err)       RUNTIME_ERROR("%s",_err)
+
+#define RUNTIME_WARNING(...)            do {                                                            \
+                                            report_runtime_error(vm, GRAVITY_WARNING, __VA_ARGS__);     \
+                                        } while (0)
+
+#define SETVALUE_BOOL(idx, x)           stackstart[idx]=VALUE_FROM_BOOL(x)
+#define SETVALUE_INT(idx, x)            stackstart[idx]=VALUE_FROM_INT(x)
+#define SETVALUE_FLOAT(idx, x)          stackstart[idx]=VALUE_FROM_FLOAT(x)
+#define SETVALUE_NULL(idx)              stackstart[idx]=VALUE_FROM_NULL
+#define SETVALUE(idx, x)                stackstart[idx]=x
+#define GETVALUE_INT(v)                 v.n
+#define GETVALUE_FLOAT(v)               v.f
+#define STACK_GET(idx)                  stackstart[idx]
 // macro the count number of registers needed by the _f function which is the sum of local variables, temp variables and formal parameters
 // macro the count number of registers needed by the _f function which is the sum of local variables, temp variables and formal parameters
-#define FN_COUNTREG(_f,_nargs)							(MAXNUM(_f->nparams,_nargs) + _f->nlocals + _f->ntemps)
+#define FN_COUNTREG(_f,_nargs)          (MAXNUM(_f->nparams,_nargs) + _f->nlocals + _f->ntemps)
 
 
 #if GRAVITY_COMPUTED_GOTO
 #if GRAVITY_COMPUTED_GOTO
-#define DECLARE_DISPATCH_TABLE		static void* dispatchTable[] = {								\
-									&&RET0,			&&HALT,			&&NOP,			&&RET,			\
-									&&CALL,			&&LOAD,			&&LOADS,		&&LOADAT,		\
-									&&LOADK,		&&LOADG,		&&LOADI,		&&LOADU,		\
-									&&MOVE,			&&STORE,		&&STOREAT,		&&STOREG,		\
-									&&STOREU,		&&JUMP,			&&JUMPF,		&&SWITCH,		\
-									&&ADD,			&&SUB,			&&DIV,			&&MUL,			\
-									&&REM,			&&AND,			&&OR,			&&LT,			\
-									&&GT,			&&EQ,			&&LEQ,			&&GEQ,			\
-									&&NEQ,			&&EQQ,			&&NEQQ,			&&ISA,			\
-									&&MATCH,		&&NEG,			&&NOT,			&&LSHIFT,		\
-									&&RSHIFT,		&&BAND,			&&BOR,			&&BXOR,			\
-									&&BNOT,			&&MAPNEW,		&&LISTNEW,		&&RANGENEW,		\
-									&&SETLIST,		&&CLOSURE,		&&CLOSE,		&&RESERVED1,	\
-									&&RESERVED2,	&&RESERVED3,	&&RESERVED4,	&&RESERVED5,	\
-									&&RESERVED6														};
-#define INTERPRET_LOOP				DISPATCH();
-#define CASE_CODE(name)				START_MICROBENCH(vm); name
+#define DECLARE_DISPATCH_TABLE      static void* dispatchTable[] = {                                \
+                                    &&RET0,         &&HALT,         &&NOP,          &&RET,          \
+                                    &&CALL,         &&LOAD,         &&LOADS,        &&LOADAT,       \
+                                    &&LOADK,        &&LOADG,        &&LOADI,        &&LOADU,        \
+                                    &&MOVE,         &&STORE,        &&STOREAT,      &&STOREG,       \
+                                    &&STOREU,       &&JUMP,         &&JUMPF,        &&SWITCH,       \
+                                    &&ADD,          &&SUB,          &&DIV,          &&MUL,          \
+                                    &&REM,          &&AND,          &&OR,           &&LT,           \
+                                    &&GT,           &&EQ,           &&LEQ,          &&GEQ,          \
+                                    &&NEQ,          &&EQQ,          &&NEQQ,         &&ISA,          \
+                                    &&MATCH,        &&NEG,          &&NOT,          &&LSHIFT,       \
+                                    &&RSHIFT,       &&BAND,         &&BOR,          &&BXOR,         \
+                                    &&BNOT,         &&MAPNEW,       &&LISTNEW,      &&RANGENEW,     \
+                                    &&SETLIST,      &&CLOSURE,      &&CLOSE,        &&RESERVED1,    \
+                                    &&RESERVED2,    &&RESERVED3,    &&RESERVED4,    &&RESERVED5,    \
+                                    &&RESERVED6                                                        };
+#define INTERPRET_LOOP              DISPATCH();
+#define CASE_CODE(name)             START_MICROBENCH(vm); name
 #if GRAVITY_VM_STATS
 #if GRAVITY_VM_STATS
-#define DISPATCH()					DEBUG_STACK();INC_PC;inst = *ip++;op = (opcode_t)OPCODE_GET_OPCODE(inst);UPDATE_STATS(vm,op);goto *dispatchTable[op];
+#define DISPATCH()                  DEBUG_STACK();INC_PC;inst = *ip++;op = (opcode_t)OPCODE_GET_OPCODE(inst);UPDATE_STATS(vm,op);goto *dispatchTable[op];
 #else
 #else
-#define DISPATCH()					DEBUG_STACK();INC_PC;inst = *ip++;goto *dispatchTable[op = (opcode_t)OPCODE_GET_OPCODE(inst)];
+#define DISPATCH()                  DEBUG_STACK();INC_PC;inst = *ip++;goto *dispatchTable[op = (opcode_t)OPCODE_GET_OPCODE(inst)];
 #endif
 #endif
 #else
 #else
 #define DECLARE_DISPATCH_TABLE
 #define DECLARE_DISPATCH_TABLE
-#define INTERPRET_LOOP				inst = *ip++;op = (opcode_t)OPCODE_GET_OPCODE(inst);UPDATE_STATS(op);switch (op)
-#define CASE_CODE(name)				case name
-#define DISPATCH()					break
+#define INTERPRET_LOOP              inst = *ip++;op = (opcode_t)OPCODE_GET_OPCODE(inst);UPDATE_STATS(op);switch (op)
+#define CASE_CODE(name)             case name
+#define DISPATCH()                  break
 #endif
 #endif
 
 
-#define INIT_PARAMS(n)				for (uint32_t i=n; i<func->nparams; ++i)															\
-									stackstart[i] = VALUE_FROM_UNDEFINED;
+#define INIT_PARAMS(n)              for (uint32_t i=n; i<func->nparams; ++i)            \
+                                    stackstart[i] = VALUE_FROM_UNDEFINED;
 
 
-#define STORE_FRAME()				frame->ip = ip
+#define STORE_FRAME()               frame->ip = ip
 
 
-#define LOAD_FRAME()				if (vm->aborted) return false;                                                                      \
-                                    frame = &fiber->frames[fiber->nframes - 1];															\
-									stackstart = frame->stackstart;																		\
-									ip = frame->ip;																						\
-									func = frame->closure->f;																			\
-									DEBUG_VM_RAW("******\tEXEC %s (%p) ******\n", func->identifier, func);
+#define LOAD_FRAME()                if (vm->aborted) return false;                                                  \
+                                    frame = &fiber->frames[fiber->nframes - 1];                                     \
+                                    stackstart = frame->stackstart;                                                 \
+                                    ip = frame->ip;                                                                 \
+                                    func = frame->closure->f;                                                       \
+                                    DEBUG_VM_RAW("******\tEXEC %s (%p) ******\n", func->identifier, func)
 
 
-#define USE_ARGS(_c)				(_c->f->tag == EXEC_TYPE_NATIVE && _c->f->useargs)
-#define PUSH_FRAME(_c,_s,_r,_n)		gravity_callframe_t *cframe = gravity_new_callframe(vm, fiber);										\
-                                    if (!cframe) return false;                                                                          \
-									cframe->closure = _c;																				\
-									cframe->stackstart = _s;																			\
-									cframe->ip = _c->f->bytecode;																		\
-									cframe->dest = _r;																					\
-									cframe->nargs = _n;																					\
-									cframe->outloop = false;																			\
-									cframe->args = (USE_ARGS(_c)) ? gravity_list_from_array(vm, _n-1, _s+1) : NULL;						\
+#define USE_ARGS(_c)                (_c->f->tag == EXEC_TYPE_NATIVE && _c->f->useargs)
+#define PUSH_FRAME(_c,_s,_r,_n)     gravity_callframe_t *cframe = gravity_new_callframe(vm, fiber);                 \
+                                    if (!cframe) return false;                                                      \
+                                    cframe->closure = _c;                                                           \
+                                    cframe->stackstart = _s;                                                        \
+                                    cframe->ip = _c->f->bytecode;                                                   \
+                                    cframe->dest = _r;                                                              \
+                                    cframe->nargs = _n;                                                             \
+                                    cframe->outloop = false;                                                        \
+                                    cframe->args = (USE_ARGS(_c)) ? gravity_list_from_array(vm, _n-1, _s+1) : NULL
 
 
-#define SYNC_STACKTOP(_fiber,_n)	if (_fiber) _fiber->stacktop -= _n
-#define SETFRAME_OUTLOOP(cframe)	(cframe)->outloop = true
+#define SYNC_STACKTOP(_fiber,_n)    if (_fiber) _fiber->stacktop -= _n
+#define SETFRAME_OUTLOOP(cframe)    (cframe)->outloop = true
 
 
-#define COMPUTE_JUMP(value)			(func->bytecode + (value))
+#define COMPUTE_JUMP(value)         (func->bytecode + (value))
 
 
 // FAST MATH MACROS
 // FAST MATH MACROS
-#define FMATH_BIN_INT(_r1,_v2,_v3,_OP)				do {SETVALUE(_r1, VALUE_FROM_INT(_v2 _OP _v3)); DISPATCH();} while(0)
-#define FMATH_BIN_FLOAT(_r1,_v2,_v3,_OP)			do {SETVALUE(_r1, VALUE_FROM_FLOAT(_v2 _OP _v3)); DISPATCH();} while(0)
-#define FMATH_BIN_BOOL(_r1,_v2,_v3,_OP)				do {SETVALUE(_r1, VALUE_FROM_BOOL(_v2 _OP _v3)); DISPATCH();} while(0)
+#define FMATH_BIN_INT(_r1,_v2,_v3,_OP)              do {SETVALUE(_r1, VALUE_FROM_INT(_v2 _OP _v3)); DISPATCH();} while(0)
+#define FMATH_BIN_FLOAT(_r1,_v2,_v3,_OP)            do {SETVALUE(_r1, VALUE_FROM_FLOAT(_v2 _OP _v3)); DISPATCH();} while(0)
+#define FMATH_BIN_BOOL(_r1,_v2,_v3,_OP)             do {SETVALUE(_r1, VALUE_FROM_BOOL(_v2 _OP _v3)); DISPATCH();} while(0)
 
 
-#define DEFINE_STACK_VARIABLE(_v,_r)				register gravity_value_t _v = STACK_GET(_r)
-#define DEFINE_INDEX_VARIABLE(_v,_r)				register gravity_value_t _v = (_r < MAX_REGISTERS) ? STACK_GET(_r) : VALUE_FROM_INT(_r-MAX_REGISTERS)
+#define DEFINE_STACK_VARIABLE(_v,_r)                register gravity_value_t _v = STACK_GET(_r)
+#define DEFINE_INDEX_VARIABLE(_v,_r)                register gravity_value_t _v = (_r < MAX_REGISTERS) ? STACK_GET(_r) : VALUE_FROM_INT(_r-MAX_REGISTERS)
 
 
 #define NO_CHECK
 #define NO_CHECK
-#define CHECK_ZERO(_v)								if ((VALUE_ISA_INT(_v) && (_v.n == 0)) || (VALUE_ISA_FLOAT(_v) && (_v.f == 0.0)) || (VALUE_ISA_NULL(_v))) \
-													RUNTIME_ERROR("Division by 0 error.")
+#define CHECK_ZERO(_v)                              if ((VALUE_ISA_INT(_v) && (_v.n == 0)) || (VALUE_ISA_FLOAT(_v) && (_v.f == 0.0)) || (VALUE_ISA_NULL(_v))) \
+                                                    RUNTIME_ERROR("Division by 0 error.")
 
 
-#define CHECK_FAST_BINARY_BOOL(r1,r2,r3,v2,v3,OP)	DEFINE_STACK_VARIABLE(v2,r2);																\
-													DEFINE_STACK_VARIABLE(v3,r3);																\
-													if (VALUE_ISA_BOOL(v2) && VALUE_ISA_BOOL(v3)) FMATH_BIN_BOOL(r1, v2.n, v3.n, OP)
+#define CHECK_FAST_BINARY_BOOL(r1,r2,r3,v2,v3,OP)   DEFINE_STACK_VARIABLE(v2,r2);                                                           \
+                                                    DEFINE_STACK_VARIABLE(v3,r3);                                                           \
+                                                    if (VALUE_ISA_BOOL(v2) && VALUE_ISA_BOOL(v3)) FMATH_BIN_BOOL(r1, v2.n, v3.n, OP)
 
 
-#define CHECK_FAST_UNARY_BOOL(r1,r2,v2,OP)			DEFINE_STACK_VARIABLE(v2,r2);																\
-													if (VALUE_ISA_BOOL(v2)) {SETVALUE(r1, VALUE_FROM_BOOL(OP v2.n)); DISPATCH();}
+#define CHECK_FAST_UNARY_BOOL(r1,r2,v2,OP)          DEFINE_STACK_VARIABLE(v2,r2);                                                           \
+                                                    if (VALUE_ISA_BOOL(v2)) {SETVALUE(r1, VALUE_FROM_BOOL(OP v2.n)); DISPATCH();}
 
 
 // fast math only for INT and FLOAT
 // fast math only for INT and FLOAT
-#define CHECK_FAST_BINARY_MATH(r1,r2,r3,v2,v3,OP,_CHECK)																						\
-													DEFINE_STACK_VARIABLE(v2,r2);																\
-													DEFINE_STACK_VARIABLE(v3,r3);																\
-													_CHECK;																						\
-													if (VALUE_ISA_INT(v2)) {																	\
-														if (VALUE_ISA_INT(v3)) FMATH_BIN_INT(r1, v2.n, v3.n, OP);								\
-														if (VALUE_ISA_FLOAT(v3)) FMATH_BIN_FLOAT(r1, v2.n, v3.f, OP);							\
-                                                        if (VALUE_ISA_NULL(v3)) FMATH_BIN_INT(r1, v2.n, 0, OP);                                 \
+#define CHECK_FAST_BINARY_MATH(r1,r2,r3,v2,v3,OP,_CHECK)                                                                                                        \
+                                                    DEFINE_STACK_VARIABLE(v2,r2);                                                                               \
+                                                    DEFINE_STACK_VARIABLE(v3,r3);                                                                               \
+                                                    _CHECK;                                                                                                     \
+                                                    if (VALUE_ISA_INT(v2)) {                                                                                    \
+                                                        if (VALUE_ISA_INT(v3)) FMATH_BIN_INT(r1, v2.n, v3.n, OP);                                               \
+                                                        if (VALUE_ISA_FLOAT(v3)) FMATH_BIN_FLOAT(r1, v2.n, v3.f, OP);                                           \
+                                                        if (VALUE_ISA_NULL(v3)) FMATH_BIN_INT(r1, v2.n, 0, OP);                                                 \
                                                         if (VALUE_ISA_STRING(v3)) RUNTIME_ERROR("Right operand must be a number (use the number() method).");   \
                                                         if (VALUE_ISA_STRING(v3)) RUNTIME_ERROR("Right operand must be a number (use the number() method).");   \
-													} else if (VALUE_ISA_FLOAT(v2)) {															\
-														if (VALUE_ISA_FLOAT(v3)) FMATH_BIN_FLOAT(r1, v2.f, v3.f, OP);							\
-														if (VALUE_ISA_INT(v3)) FMATH_BIN_FLOAT(r1, v2.f, v3.n, OP);								\
-                                                        if (VALUE_ISA_NULL(v3)) FMATH_BIN_FLOAT(r1, v2.f, 0, OP);                               \
+                                                    } else if (VALUE_ISA_FLOAT(v2)) {                                                                           \
+                                                        if (VALUE_ISA_FLOAT(v3)) FMATH_BIN_FLOAT(r1, v2.f, v3.f, OP);                                           \
+                                                        if (VALUE_ISA_INT(v3)) FMATH_BIN_FLOAT(r1, v2.f, v3.n, OP);                                             \
+                                                        if (VALUE_ISA_NULL(v3)) FMATH_BIN_FLOAT(r1, v2.f, 0, OP);                                               \
                                                         if (VALUE_ISA_STRING(v3)) RUNTIME_ERROR("Right operand must be a number (use the number() method).");   \
                                                         if (VALUE_ISA_STRING(v3)) RUNTIME_ERROR("Right operand must be a number (use the number() method).");   \
-													}
+                                                    }
 
 
-#define CHECK_FAST_UNARY_MATH(r1,r2,v2,OP)			DEFINE_STACK_VARIABLE(v2,r2);	\
-													if (VALUE_ISA_INT(v2)) {SETVALUE(r1, VALUE_FROM_INT(OP v2.n)); DISPATCH();}	\
-													if (VALUE_ISA_FLOAT(v2)) {SETVALUE(r1, VALUE_FROM_FLOAT(OP v2.f)); DISPATCH();}
+#define CHECK_FAST_UNARY_MATH(r1,r2,v2,OP)          DEFINE_STACK_VARIABLE(v2,r2);                                                   \
+                                                    if (VALUE_ISA_INT(v2)) {SETVALUE(r1, VALUE_FROM_INT(OP v2.n)); DISPATCH();}     \
+                                                    if (VALUE_ISA_FLOAT(v2)) {SETVALUE(r1, VALUE_FROM_FLOAT(OP v2.f)); DISPATCH();}
 
 
 
 
-#define CHECK_FAST_BINARY_REM(r1,r2,r3,v2,v3)		DEFINE_STACK_VARIABLE(v2,r2);																\
-													DEFINE_STACK_VARIABLE(v3,r3);																\
-													CHECK_ZERO(v3);																				\
-													if (VALUE_ISA_INT(v2) && VALUE_ISA_INT(v3)) FMATH_BIN_INT(r1, v2.n, v3.n, %)
+#define CHECK_FAST_BINARY_REM(r1,r2,r3,v2,v3)       DEFINE_STACK_VARIABLE(v2,r2);                                                               \
+                                                    DEFINE_STACK_VARIABLE(v3,r3);                                                               \
+                                                    CHECK_ZERO(v3);                                                                             \
+                                                    if (VALUE_ISA_INT(v2) && VALUE_ISA_INT(v3)) FMATH_BIN_INT(r1, v2.n, v3.n, %)
 
 
-#define CHECK_FAST_BINARY_BIT(r1,r2,r3,v2,v3,OP)	DEFINE_STACK_VARIABLE(v2,r2);																\
-													DEFINE_STACK_VARIABLE(v3,r3);																\
-													if (VALUE_ISA_INT(v2) && VALUE_ISA_INT(v3)) FMATH_BIN_INT(r1, v2.n, v3.n, OP)
+#define CHECK_FAST_BINARY_BIT(r1,r2,r3,v2,v3,OP)    DEFINE_STACK_VARIABLE(v2,r2);                                                               \
+                                                    DEFINE_STACK_VARIABLE(v3,r3);                                                               \
+                                                    if (VALUE_ISA_INT(v2) && VALUE_ISA_INT(v3)) FMATH_BIN_INT(r1, v2.n, v3.n, OP)
 
 
-#define CHECK_FAST_BINBOOL_BIT(r1,v2,v3,OP)			if (VALUE_ISA_BOOL(v2) && VALUE_ISA_BOOL(v3)) FMATH_BIN_BOOL(r1, v2.n, v3.n, OP)
+#define CHECK_FAST_BINBOOL_BIT(r1,v2,v3,OP)         if (VALUE_ISA_BOOL(v2) && VALUE_ISA_BOOL(v3)) FMATH_BIN_BOOL(r1, v2.n, v3.n, OP)
 
 
-#define DECODE_BINARY_OPERATION(r1,r2,r3)			OPCODE_GET_TWO8bit_ONE10bit(inst, const uint32_t r1, const uint32_t r2, const uint32_t r3);	\
-													DEBUG_VM("%s %d %d %d", opcode_name(op), r1, r2, r3)
+#define DECODE_BINARY_OPERATION(r1,r2,r3)           OPCODE_GET_TWO8bit_ONE10bit(inst, const uint32_t r1, const uint32_t r2, const uint32_t r3); \
+                                                    DEBUG_VM("%s %d %d %d", opcode_name(op), r1, r2, r3)
 
 
-#define PREPARE_FUNC_CALLN(_c,_i,_w,_N)				gravity_closure_t *_c = (gravity_closure_t *)gravity_class_lookup_closure(gravity_value_getclass(v2), cache[_i]); \
-													if (!_c || !_c->f) RUNTIME_ERROR("Unable to perform operator %s on object", opcode_name(op));	\
-													uint32_t _w = FN_COUNTREG(func, frame->nargs);													\
-													uint32_t _rneed = FN_COUNTREG(_c->f, _N);														\
-													if (!gravity_check_stack(vm, fiber, MAXNUM(_rneed,_w), &stackstart)) return false;                         \
+#define PREPARE_FUNC_CALLN(_c,_i,_w,_N)             gravity_closure_t *_c = (gravity_closure_t *)gravity_class_lookup_closure(gravity_value_getclass(v2), cache[_i]); \
+                                                    if (!_c || !_c->f) RUNTIME_ERROR("Unable to perform operator %s on object", opcode_name(op));   \
+                                                    uint32_t _w = FN_COUNTREG(func, frame->nargs);                                                  \
+                                                    uint32_t _rneed = FN_COUNTREG(_c->f, _N);                                                       \
+                                                    if (!gravity_check_stack(vm, fiber, MAXNUM(_rneed,_w), &stackstart)) return false;              \
                                                     if (vm->aborted) return false
                                                     if (vm->aborted) return false
 
 
-#define PREPARE_FUNC_CALL1(_c,_v1,_i,_w)			PREPARE_FUNC_CALLN(_c,_i,_w,1);															\
-													SETVALUE(_w, _v1)
-
-
-#define PREPARE_FUNC_CALL2(_c,_v1,_v2,_i,_w)		PREPARE_FUNC_CALLN(_c,_i,_w,2);															\
-													SETVALUE(_w, _v1);																		\
-													SETVALUE(_w+1, _v2)
-
-#define PREPARE_FUNC_CALL3(_c,_v1,_v2,_v3,_i,_w)	PREPARE_FUNC_CALLN(_c,_i,_w,3);															\
-													SETVALUE(_w, _v1);																		\
-													SETVALUE(_w+1, _v2);																	\
-													SETVALUE(_w+2, _v3)
-
-
-#define CALL_FUNC(_name,_c,r1,nargs,rwin)           gravity_fiber_t *current_fiber = fiber;                                                 \
-                                                    STORE_FRAME();																			\
-													execute_op_##_name:																		\
-													switch(_c->f->tag) {																	\
-													case EXEC_TYPE_NATIVE: {																\
-                                                        current_fiber = NULL;                                                               \
-														PUSH_FRAME(_c, &stackstart[rwin], r1, nargs);										\
-													} break;																				\
-													case EXEC_TYPE_INTERNAL: {																\
-														if (!_c->f->internal(vm, &stackstart[rwin], nargs, r1)) {							\
-                                                            if (vm->aborted) return false;                                                  \
-															if (VALUE_ISA_CLOSURE(STACK_GET(r1))) {											\
-																closure = VALUE_AS_CLOSURE(STACK_GET(r1));									\
-																SETVALUE(r1, VALUE_FROM_NULL);												\
-																goto execute_op_##_name;													\
-															}																				\
-															fiber = vm->fiber;																\
-															if (fiber == NULL) return true;													\
-															if (fiber->error) RUNTIME_FIBER_ERROR(fiber->error);							\
-														}																					\
-													} break;																				\
-													case EXEC_TYPE_BRIDGED:	{																\
-														DEBUG_ASSERT(delegate->bridge_execute, "bridge_execute delegate callback is mandatory");	\
-														if (!delegate->bridge_execute(vm, _c->f->xdata, STACK_GET(0), &stackstart[rwin], nargs, r1)) {	\
-															if (fiber->error) RUNTIME_FIBER_ERROR(fiber->error);							\
-														}																					\
-													} break;																				\
-													case EXEC_TYPE_SPECIAL:																	\
-														RUNTIME_ERROR("Unable to handle a special function in current context");			\
-														break;																				\
-													}																						\
-													LOAD_FRAME();																			\
-													SYNC_STACKTOP(current_fiber, MAXNUM(_rneed, rwin))
+#define PREPARE_FUNC_CALL1(_c,_v1,_i,_w)            PREPARE_FUNC_CALLN(_c,_i,_w,1);         \
+                                                    SETVALUE(_w, _v1)
+
+
+#define PREPARE_FUNC_CALL2(_c,_v1,_v2,_i,_w)        PREPARE_FUNC_CALLN(_c,_i,_w,2);         \
+                                                    SETVALUE(_w, _v1);                      \
+                                                    SETVALUE(_w+1, _v2)
+
+#define PREPARE_FUNC_CALL3(_c,_v1,_v2,_v3,_i,_w)    PREPARE_FUNC_CALLN(_c,_i,_w,3);         \
+                                                    SETVALUE(_w, _v1);                      \
+                                                    SETVALUE(_w+1, _v2);                    \
+                                                    SETVALUE(_w+2, _v3)
+
+
+#define CALL_FUNC(_name,_c,r1,nargs,rwin)           gravity_fiber_t *current_fiber = fiber;                             \
+                                                    STORE_FRAME();                                                      \
+                                                    execute_op_##_name:                                                 \
+                                                    switch(_c->f->tag) {                                                \
+                                                    case EXEC_TYPE_NATIVE: {                                            \
+                                                        current_fiber = NULL;                                           \
+                                                        PUSH_FRAME(_c, &stackstart[rwin], r1, nargs);                   \
+                                                    } break;                                                            \
+                                                    case EXEC_TYPE_INTERNAL: {                                          \
+                                                        if (!_c->f->internal(vm, &stackstart[rwin], nargs, r1)) {       \
+                                                            if (vm->aborted) return false;                              \
+                                                            if (VALUE_ISA_CLOSURE(STACK_GET(r1))) {                     \
+                                                                closure = VALUE_AS_CLOSURE(STACK_GET(r1));              \
+                                                                SETVALUE(r1, VALUE_FROM_NULL);                          \
+                                                                goto execute_op_##_name;                                \
+                                                            }                                                           \
+                                                            fiber = vm->fiber;                                          \
+                                                            if (fiber == NULL) return true;                             \
+                                                            if (fiber->error) RUNTIME_FIBER_ERROR(fiber->error);        \
+                                                        }                                                               \
+                                                    } break;                                                            \
+                                                    case EXEC_TYPE_BRIDGED:    {                                        \
+                                                        DEBUG_ASSERT(delegate->bridge_execute, "bridge_execute delegate callback is mandatory");        \
+                                                        if (!delegate->bridge_execute(vm, _c->f->xdata, STACK_GET(0), &stackstart[rwin], nargs, r1)) {  \
+                                                            if (fiber->error) RUNTIME_FIBER_ERROR(fiber->error);        \
+                                                        }                                                               \
+                                                    } break;                                                            \
+                                                    case EXEC_TYPE_SPECIAL:                                             \
+                                                        RUNTIME_ERROR("Unable to handle a special function in current context");    \
+                                                        break;                                                          \
+                                                    }                                                                   \
+                                                    LOAD_FRAME();                                                       \
+                                                    SYNC_STACKTOP(current_fiber, MAXNUM(_rneed, rwin))
 
 
 // MACROS used in core and optionals
 // MACROS used in core and optionals
 #define SETMETA_INITED(c)                           gravity_class_get_meta(c)->is_inited = true
 #define SETMETA_INITED(c)                           gravity_class_get_meta(c)->is_inited = true

+ 29 - 29
src/shared/gravity_array.h

@@ -1,6 +1,6 @@
 //
 //
 //  gravity_array.h
 //  gravity_array.h
-//	gravity
+//    gravity
 //
 //
 //  Created by Marco Bambini on 31/07/14.
 //  Created by Marco Bambini on 31/07/14.
 //  Copyright (c) 2014 CreoLabs. All rights reserved.
 //  Copyright (c) 2014 CreoLabs. All rights reserved.
@@ -13,35 +13,35 @@
 
 
 // Inspired by https://github.com/attractivechaos/klib/blob/master/kvec.h
 // Inspired by https://github.com/attractivechaos/klib/blob/master/kvec.h
 
 
-#define MARRAY_DEFAULT_SIZE			8
-#define marray_t(type)				struct {size_t n, m; type *p;}
-#define marray_init(v)				((v).n = (v).m = 0, (v).p = 0)
-#define marray_decl_init(_t,_v)		_t _v; marray_init(_v)
-#define marray_destroy(v)			if ((v).p) free((v).p)
-#define marray_get(v, i)			((v).p[(i)])
-#define marray_pop(v)				((v).p[--(v).n])
-#define marray_last(v)				((v).p[(v).n-1])
-#define marray_size(v)				((v).n)
-#define marray_max(v)				((v).m)
-#define marray_inc(v)				(++(v).n)
-#define marray_dec(v)				(--(v).n)
-#define marray_nset(v,N)			((v).n = N)
-#define marray_push(type, v, x)		{if ((v).n == (v).m) {										\
-									(v).m = (v).m? (v).m<<1 : MARRAY_DEFAULT_SIZE;				\
-									(v).p = (type*)realloc((v).p, sizeof(type) * (v).m);}		\
-									(v).p[(v).n++] = (x);}
-#define marray_resize(type, v, n)	(v).m += n; (v).p = (type*)realloc((v).p, sizeof(type) * (v).m)
-#define marray_resize0(type, v, n)	(v).p = (type*)realloc((v).p, sizeof(type) * ((v).m+n));	\
-									(v).m ? memset((v).p+(sizeof(type) * n), 0, (sizeof(type) * n)) : memset((v).p, 0, (sizeof(type) * n)); (v).m += n
-#define marray_npop(v,k)			((v).n -= k)
-#define marray_reset(v,k)			((v).n = k)
-#define marray_reset0(v)			marray_reset(v, 0)
-#define marray_set(v,i,x)			(v).p[i] = (x)
+#define MARRAY_DEFAULT_SIZE         8
+#define marray_t(type)              struct {size_t n, m; type *p;}
+#define marray_init(v)              ((v).n = (v).m = 0, (v).p = 0)
+#define marray_decl_init(_t,_v)     _t _v; marray_init(_v)
+#define marray_destroy(v)           if ((v).p) free((v).p)
+#define marray_get(v, i)            ((v).p[(i)])
+#define marray_pop(v)               ((v).p[--(v).n])
+#define marray_last(v)              ((v).p[(v).n-1])
+#define marray_size(v)              ((v).n)
+#define marray_max(v)               ((v).m)
+#define marray_inc(v)               (++(v).n)
+#define marray_dec(v)               (--(v).n)
+#define marray_nset(v,N)            ((v).n = N)
+#define marray_push(type, v, x)     {if ((v).n == (v).m) {                                        \
+                                    (v).m = (v).m? (v).m<<1 : MARRAY_DEFAULT_SIZE;                \
+                                    (v).p = (type*)realloc((v).p, sizeof(type) * (v).m);}        \
+                                    (v).p[(v).n++] = (x);}
+#define marray_resize(type, v, n)   (v).m += n; (v).p = (type*)realloc((v).p, sizeof(type) * (v).m)
+#define marray_resize0(type, v, n)  (v).p = (type*)realloc((v).p, sizeof(type) * ((v).m+n));    \
+                                    (v).m ? memset((v).p+(sizeof(type) * n), 0, (sizeof(type) * n)) : memset((v).p, 0, (sizeof(type) * n)); (v).m += n
+#define marray_npop(v,k)            ((v).n -= k)
+#define marray_reset(v,k)           ((v).n = k)
+#define marray_reset0(v)            marray_reset(v, 0)
+#define marray_set(v,i,x)           (v).p[i] = (x)
 
 
 // commonly used arrays
 // commonly used arrays
-typedef marray_t(uint16_t)			uint16_r;
-typedef marray_t(uint32_t)			uint32_r;
-typedef marray_t(void *)			void_r;
-typedef marray_t(const char *)		cstring_r;
+typedef marray_t(uint16_t)          uint16_r;
+typedef marray_t(uint32_t)          uint32_r;
+typedef marray_t(void *)            void_r;
+typedef marray_t(const char *)      cstring_r;
 
 
 #endif
 #endif

+ 45 - 45
src/shared/gravity_delegate.h

@@ -14,75 +14,75 @@
 
 
 // error type and code definitions
 // error type and code definitions
 typedef enum {
 typedef enum {
-	GRAVITY_ERROR_NONE = 0,
-	GRAVITY_ERROR_SYNTAX,
-	GRAVITY_ERROR_SEMANTIC,
-	GRAVITY_ERROR_RUNTIME,
-	GRAVITY_ERROR_IO,
-	GRAVITY_WARNING,
+    GRAVITY_ERROR_NONE = 0,
+    GRAVITY_ERROR_SYNTAX,
+    GRAVITY_ERROR_SEMANTIC,
+    GRAVITY_ERROR_RUNTIME,
+    GRAVITY_ERROR_IO,
+    GRAVITY_WARNING,
 } error_type_t;
 } error_type_t;
 
 
 typedef struct {
 typedef struct {
-	uint32_t		lineno;
-	uint32_t		colno;
-	uint32_t		fileid;
-	uint32_t		offset;
+    uint32_t        lineno;
+    uint32_t        colno;
+    uint32_t        fileid;
+    uint32_t        offset;
     void            *meta;
     void            *meta;
 } error_desc_t;
 } error_desc_t;
 
 
-#define ERROR_DESC_NONE		(error_desc_t){0,0,0,0,NULL}
+#define ERROR_DESC_NONE     (error_desc_t){0,0,0,0,NULL}
 
 
-typedef void				(*gravity_log_callback)	(gravity_vm *vm, const char *message, void *xdata);
+typedef void                (*gravity_log_callback)    (gravity_vm *vm, const char *message, void *xdata);
 typedef void                (*gravity_log_clear) (gravity_vm *vm, void *xdata);
 typedef void                (*gravity_log_clear) (gravity_vm *vm, void *xdata);
-typedef void				(*gravity_error_callback) (gravity_vm *vm, error_type_t error_type, const char *description, error_desc_t error_desc, void *xdata);
-typedef void				(*gravity_unittest_callback) (gravity_vm *vm, error_type_t error_type, const char *desc, const char *note, gravity_value_t value, int32_t row, int32_t col, void *xdata);
-typedef void				(*gravity_parser_callback) (void *token, void *xdata);
+typedef void                (*gravity_error_callback) (gravity_vm *vm, error_type_t error_type, const char *description, error_desc_t error_desc, void *xdata);
+typedef void                (*gravity_unittest_callback) (gravity_vm *vm, error_type_t error_type, const char *desc, const char *note, gravity_value_t value, int32_t row, int32_t col, void *xdata);
+typedef void                (*gravity_parser_callback) (void *token, void *xdata);
 typedef void                (*gravity_type_callback) (void *token, const char *type, void *xdata);
 typedef void                (*gravity_type_callback) (void *token, const char *type, void *xdata);
-typedef const char*			(*gravity_precode_callback) (void *xdata);
-typedef const char*			(*gravity_loadfile_callback) (const char *file, size_t *size, uint32_t *fileid, void *xdata);
-typedef const char*			(*gravity_filename_callback) (uint32_t fileid, void *xdata);
+typedef const char*         (*gravity_precode_callback) (void *xdata);
+typedef const char*         (*gravity_loadfile_callback) (const char *file, size_t *size, uint32_t *fileid, void *xdata);
+typedef const char*         (*gravity_filename_callback) (uint32_t fileid, void *xdata);
 typedef const char**        (*gravity_optclass_callback) (void);
 typedef const char**        (*gravity_optclass_callback) (void);
 
 
-typedef bool				(*gravity_bridge_initinstance) (gravity_vm *vm, void *xdata, gravity_value_t ctx, gravity_instance_t *instance, gravity_value_t args[], int16_t nargs);
-typedef bool				(*gravity_bridge_setvalue) (gravity_vm *vm, void *xdata, gravity_value_t target, const char *key, gravity_value_t value);
-typedef bool				(*gravity_bridge_getvalue) (gravity_vm *vm, void *xdata, gravity_value_t target, const char *key, uint32_t vindex);
-typedef bool				(*gravity_bridge_setundef) (gravity_vm *vm, void *xdata, gravity_value_t target, const char *key, gravity_value_t value);
-typedef bool				(*gravity_bridge_getundef) (gravity_vm *vm, void *xdata, gravity_value_t target, const char *key, uint32_t vindex);
-typedef bool				(*gravity_bridge_execute)  (gravity_vm *vm, void *xdata, gravity_value_t ctx, gravity_value_t args[], int16_t nargs, uint32_t vindex);
+typedef bool                (*gravity_bridge_initinstance) (gravity_vm *vm, void *xdata, gravity_value_t ctx, gravity_instance_t *instance, gravity_value_t args[], int16_t nargs);
+typedef bool                (*gravity_bridge_setvalue) (gravity_vm *vm, void *xdata, gravity_value_t target, const char *key, gravity_value_t value);
+typedef bool                (*gravity_bridge_getvalue) (gravity_vm *vm, void *xdata, gravity_value_t target, const char *key, uint32_t vindex);
+typedef bool                (*gravity_bridge_setundef) (gravity_vm *vm, void *xdata, gravity_value_t target, const char *key, gravity_value_t value);
+typedef bool                (*gravity_bridge_getundef) (gravity_vm *vm, void *xdata, gravity_value_t target, const char *key, uint32_t vindex);
+typedef bool                (*gravity_bridge_execute)  (gravity_vm *vm, void *xdata, gravity_value_t ctx, gravity_value_t args[], int16_t nargs, uint32_t vindex);
 typedef bool                (*gravity_bridge_equals) (gravity_vm *vm, void *obj1, void *obj2);
 typedef bool                (*gravity_bridge_equals) (gravity_vm *vm, void *obj1, void *obj2);
 typedef const char*         (*gravity_bridge_string) (gravity_vm *vm, void *xdata, uint32_t *len);
 typedef const char*         (*gravity_bridge_string) (gravity_vm *vm, void *xdata, uint32_t *len);
 typedef void*               (*gravity_bridge_clone)  (gravity_vm *vm, void *xdata);
 typedef void*               (*gravity_bridge_clone)  (gravity_vm *vm, void *xdata);
-typedef uint32_t			(*gravity_bridge_size) (gravity_vm *vm, gravity_object_t *obj);
-typedef void				(*gravity_bridge_free) (gravity_vm *vm, gravity_object_t *obj);
+typedef uint32_t            (*gravity_bridge_size) (gravity_vm *vm, gravity_object_t *obj);
+typedef void                (*gravity_bridge_free) (gravity_vm *vm, gravity_object_t *obj);
 
 
 typedef struct {
 typedef struct {
-	// user data
-	void						*xdata;					// optional user data transparently passed between callbacks
+    // user data
+    void                        *xdata;                 // optional user data transparently passed between callbacks
 
 
-	// callbacks
-	gravity_log_callback		log_callback;			// log reporting callback
+    // callbacks
+    gravity_log_callback        log_callback;           // log reporting callback
     gravity_log_clear           log_clear;              // log reset callback
     gravity_log_clear           log_clear;              // log reset callback
-	gravity_error_callback		error_callback;			// error reporting callback
-	gravity_unittest_callback	unittest_callback;		// special unit test callback
-	gravity_parser_callback		parser_callback;		// lexer callback used for syntax highlight
+    gravity_error_callback      error_callback;         // error reporting callback
+    gravity_unittest_callback   unittest_callback;      // special unit test callback
+    gravity_parser_callback     parser_callback;        // lexer callback used for syntax highlight
     gravity_type_callback       type_callback;          // callback used to bind a token with a declared type
     gravity_type_callback       type_callback;          // callback used to bind a token with a declared type
-	gravity_precode_callback	precode_callback;		// called at parse time in order to give the opportunity to add custom source code
-	gravity_loadfile_callback	loadfile_callback;		// callback to give the opportunity to load a file from an import statement
-	gravity_filename_callback	filename_callback;		// called while reporting an error in order to be able to convert a fileid to a real filename
+    gravity_precode_callback    precode_callback;       // called at parse time in order to give the opportunity to add custom source code
+    gravity_loadfile_callback   loadfile_callback;      // callback to give the opportunity to load a file from an import statement
+    gravity_filename_callback   filename_callback;      // called while reporting an error in order to be able to convert a fileid to a real filename
     gravity_optclass_callback   optional_classes;       // optional classes to be exposed to the semantic checher as extern (to be later registered)
     gravity_optclass_callback   optional_classes;       // optional classes to be exposed to the semantic checher as extern (to be later registered)
 
 
-	// bridge
-	gravity_bridge_initinstance	bridge_initinstance;	// init class
-	gravity_bridge_setvalue		bridge_setvalue;		// setter
-	gravity_bridge_getvalue		bridge_getvalue;		// getter
-	gravity_bridge_setundef		bridge_setundef;		// setter not found
-	gravity_bridge_getundef		bridge_getundef;		// getter not found
-	gravity_bridge_execute		bridge_execute;			// execute a method/function
+    // bridge
+    gravity_bridge_initinstance bridge_initinstance;    // init class
+    gravity_bridge_setvalue     bridge_setvalue;        // setter
+    gravity_bridge_getvalue     bridge_getvalue;        // getter
+    gravity_bridge_setundef     bridge_setundef;        // setter not found
+    gravity_bridge_getundef     bridge_getundef;        // getter not found
+    gravity_bridge_execute      bridge_execute;         // execute a method/function
     gravity_bridge_string       bridge_string;          // instance string conversion
     gravity_bridge_string       bridge_string;          // instance string conversion
     gravity_bridge_equals       bridge_equals;          // check if two objects are equals
     gravity_bridge_equals       bridge_equals;          // check if two objects are equals
     gravity_bridge_clone        bridge_clone;           // clone
     gravity_bridge_clone        bridge_clone;           // clone
-	gravity_bridge_size			bridge_size;			// size of obj
-	gravity_bridge_free			bridge_free;			// free obj
+    gravity_bridge_size         bridge_size;            // size of obj
+    gravity_bridge_free         bridge_free;            // free obj
 } gravity_delegate_t;
 } gravity_delegate_t;
 
 
 #endif
 #endif

+ 298 - 298
src/shared/gravity_hash.c

@@ -11,302 +11,302 @@
 #include "gravity_macros.h"
 #include "gravity_macros.h"
 
 
 #if GRAVITYHASH_ENABLE_STATS
 #if GRAVITYHASH_ENABLE_STATS
-#define INC_COLLISION(tbl)	++tbl->ncollision
-#define INC_RESIZE(tbl)		++tbl->nresize
+#define INC_COLLISION(tbl)      ++tbl->ncollision
+#define INC_RESIZE(tbl)         ++tbl->nresize
 #else
 #else
 #define INC_COLLISION(tbl)
 #define INC_COLLISION(tbl)
 #define INC_RESIZE(tbl)
 #define INC_RESIZE(tbl)
 #endif
 #endif
 
 
 typedef struct hash_node_s {
 typedef struct hash_node_s {
-	uint32_t				hash;
-	gravity_value_t			key;
-	gravity_value_t			value;
-	struct hash_node_s		*next;
+    uint32_t                hash;
+    gravity_value_t         key;
+    gravity_value_t         value;
+    struct hash_node_s      *next;
 } hash_node_t;
 } hash_node_t;
 
 
 struct gravity_hash_t {
 struct gravity_hash_t {
-	// internals
-	uint32_t				size;
-	uint32_t				count;
-	hash_node_t				**nodes;
-	gravity_hash_compute_fn	compute_fn;
-	gravity_hash_isequal_fn	isequal_fn;
-	gravity_hash_iterate_fn free_fn;
-	void					*data;
-
-	// stats
-	#if GRAVITYHASH_ENABLE_STATS
-	uint32_t				ncollision;
-	uint32_t				nresize;
-	#endif
+    // internals
+    uint32_t                size;
+    uint32_t                count;
+    hash_node_t             **nodes;
+    gravity_hash_compute_fn compute_fn;
+    gravity_hash_isequal_fn isequal_fn;
+    gravity_hash_iterate_fn free_fn;
+    void                    *data;
+
+    // stats
+    #if GRAVITYHASH_ENABLE_STATS
+    uint32_t                ncollision;
+    uint32_t                nresize;
+    #endif
 };
 };
 
 
 // http://programmers.stackexchange.com/questions/49550/which-hashing-algorithm-is-best-for-uniqueness-and-speed
 // http://programmers.stackexchange.com/questions/49550/which-hashing-algorithm-is-best-for-uniqueness-and-speed
 
 
 /*
 /*
-	Hash algorithm used in Gravity Hash Table is DJB2 which does a pretty good job with string keys and it is fast.
-	Original algorithm is: http://www.cse.yorku.ca/~oz/hash.html
-
-	DJBX33A (Daniel J. Bernstein, Times 33 with Addition)
-
-	This is Daniel J. Bernstein's popular `times 33' hash function as
-	posted by him years ago on comp.lang.c. It basically uses a function
-	like ``hash(i) = hash(i-1) 	33 + str[i]''. This is one of the best
-	known hash functions for strings. Because it is both computed very
-	fast and distributes very well.
-
-	Why 33? (<< 5 in the code)
-	The magic of number 33, i.e. why it works better than many other
-	constants, prime or not, has never been adequately explained by
-	anyone. So I try an explanation: if one experimentally tests all
-	multipliers between 1 and 256 (as RSE did now) one detects that even
-	numbers are not useable at all. The remaining 128 odd numbers
-	(except for the number 1) work more or less all equally well. They
-	all distribute in an acceptable way and this way fill a hash table
-	with an average percent of approx. 86%.
-
-	If one compares the Chi^2 values of the variants, the number 33 not
-	even has the best value. But the number 33 and a few other equally
-	good numbers like 17, 31, 63, 127 and 129 have nevertheless a great
-	advantage to the remaining numbers in the large set of possible
-	multipliers: their multiply operation can be replaced by a faster
-	operation based on just one shift plus either a single addition
-	or subtraction operation. And because a hash function has to both
-	distribute good _and_ has to be very fast to compute, those few
-	numbers should be preferred and seems to be the reason why Daniel J.
-	Bernstein also preferred it.
-
-	Why 5381?
-	1. odd number
-	2. prime number
-	3. deficient number (https://en.wikipedia.org/wiki/Deficient_number)
-	4. 001/010/100/000/101 b
-
-	Practically any good multiplier works. I think you're worrying about
-	the fact that 31c + d doesn't cover any reasonable range of hash values
-	if c and d are between 0 and 255. That's why, when I discovered the 33 hash
-	function and started using it in my compressors, I started with a hash value
-	of 5381. I think you'll find that this does just as well as a 261 multiplier.
-
-	Note that the starting value of the hash (5381) makes no difference for strings
-	of equal lengths, but will play a role in generating different hash values for
-	strings of different lengths.
+    Hash algorithm used in Gravity Hash Table is DJB2 which does a pretty good job with string keys and it is fast.
+    Original algorithm is: http://www.cse.yorku.ca/~oz/hash.html
+
+    DJBX33A (Daniel J. Bernstein, Times 33 with Addition)
+
+    This is Daniel J. Bernstein's popular `times 33' hash function as
+    posted by him years ago on comp.lang.c. It basically uses a function
+    like ``hash(i) = hash(i-1)     33 + str[i]''. This is one of the best
+    known hash functions for strings. Because it is both computed very
+    fast and distributes very well.
+
+    Why 33? (<< 5 in the code)
+    The magic of number 33, i.e. why it works better than many other
+    constants, prime or not, has never been adequately explained by
+    anyone. So I try an explanation: if one experimentally tests all
+    multipliers between 1 and 256 (as RSE did now) one detects that even
+    numbers are not useable at all. The remaining 128 odd numbers
+    (except for the number 1) work more or less all equally well. They
+    all distribute in an acceptable way and this way fill a hash table
+    with an average percent of approx. 86%.
+
+    If one compares the Chi^2 values of the variants, the number 33 not
+    even has the best value. But the number 33 and a few other equally
+    good numbers like 17, 31, 63, 127 and 129 have nevertheless a great
+    advantage to the remaining numbers in the large set of possible
+    multipliers: their multiply operation can be replaced by a faster
+    operation based on just one shift plus either a single addition
+    or subtraction operation. And because a hash function has to both
+    distribute good _and_ has to be very fast to compute, those few
+    numbers should be preferred and seems to be the reason why Daniel J.
+    Bernstein also preferred it.
+
+    Why 5381?
+    1. odd number
+    2. prime number
+    3. deficient number (https://en.wikipedia.org/wiki/Deficient_number)
+    4. 001/010/100/000/101 b
+
+    Practically any good multiplier works. I think you're worrying about
+    the fact that 31c + d doesn't cover any reasonable range of hash values
+    if c and d are between 0 and 255. That's why, when I discovered the 33 hash
+    function and started using it in my compressors, I started with a hash value
+    of 5381. I think you'll find that this does just as well as a 261 multiplier.
+
+    Note that the starting value of the hash (5381) makes no difference for strings
+    of equal lengths, but will play a role in generating different hash values for
+    strings of different lengths.
  */
  */
 
 
-#define HASH_SEED_VALUE						5381
-#define ROT32(x, y)							((x << y) | (x >> (32 - y)))
-#define COMPUTE_HASH(tbl,key,hash)			register uint32_t hash = murmur3_32(key, len, HASH_SEED_VALUE); hash = hash % tbl->size
-#define COMPUTE_HASH_NOMODULO(key,hash)		register uint32_t hash = murmur3_32(key, len, HASH_SEED_VALUE)
-#define RECOMPUTE_HASH(tbl,key,hash)		hash = murmur3_32(key, len, HASH_SEED_VALUE); hash = hash % tbl->size
+#define HASH_SEED_VALUE                     5381
+#define ROT32(x, y)                         ((x << y) | (x >> (32 - y)))
+#define COMPUTE_HASH(tbl,key,hash)          register uint32_t hash = murmur3_32(key, len, HASH_SEED_VALUE); hash = hash % tbl->size
+#define COMPUTE_HASH_NOMODULO(key,hash)     register uint32_t hash = murmur3_32(key, len, HASH_SEED_VALUE)
+#define RECOMPUTE_HASH(tbl,key,hash)        hash = murmur3_32(key, len, HASH_SEED_VALUE); hash = hash % tbl->size
 
 
 static inline uint32_t murmur3_32 (const char *key, uint32_t len, uint32_t seed) {
 static inline uint32_t murmur3_32 (const char *key, uint32_t len, uint32_t seed) {
-	static const uint32_t c1 = 0xcc9e2d51;
-	static const uint32_t c2 = 0x1b873593;
-	static const uint32_t r1 = 15;
-	static const uint32_t r2 = 13;
-	static const uint32_t m = 5;
-	static const uint32_t n = 0xe6546b64;
-
-	uint32_t hash = seed;
-
-	const int nblocks = len / 4;
-	const uint32_t *blocks = (const uint32_t *) key;
-	for (int i = 0; i < nblocks; i++) {
-		uint32_t k = blocks[i];
-		k *= c1;
-		k = ROT32(k, r1);
-		k *= c2;
-
-		hash ^= k;
-		hash = ROT32(hash, r2) * m + n;
-	}
-
-	const uint8_t *tail = (const uint8_t *) (key + nblocks * 4);
-	uint32_t k1 = 0;
-
-	switch (len & 3) {
-		case 3:
-			k1 ^= tail[2] << 16;
-		case 2:
-			k1 ^= tail[1] << 8;
-		case 1:
-			k1 ^= tail[0];
-
-			k1 *= c1;
-			k1 = ROT32(k1, r1);
-			k1 *= c2;
-			hash ^= k1;
-	}
-
-	hash ^= len;
-	hash ^= (hash >> 16);
-	hash *= 0x85ebca6b;
-	hash ^= (hash >> 13);
-	hash *= 0xc2b2ae35;
-	hash ^= (hash >> 16);
-
-	return hash;
+    static const uint32_t c1 = 0xcc9e2d51;
+    static const uint32_t c2 = 0x1b873593;
+    static const uint32_t r1 = 15;
+    static const uint32_t r2 = 13;
+    static const uint32_t m = 5;
+    static const uint32_t n = 0xe6546b64;
+
+    uint32_t hash = seed;
+
+    const int nblocks = len / 4;
+    const uint32_t *blocks = (const uint32_t *) key;
+    for (int i = 0; i < nblocks; i++) {
+        uint32_t k = blocks[i];
+        k *= c1;
+        k = ROT32(k, r1);
+        k *= c2;
+
+        hash ^= k;
+        hash = ROT32(hash, r2) * m + n;
+    }
+
+    const uint8_t *tail = (const uint8_t *) (key + nblocks * 4);
+    uint32_t k1 = 0;
+
+    switch (len & 3) {
+        case 3:
+            k1 ^= tail[2] << 16;
+        case 2:
+            k1 ^= tail[1] << 8;
+        case 1:
+            k1 ^= tail[0];
+
+            k1 *= c1;
+            k1 = ROT32(k1, r1);
+            k1 *= c2;
+            hash ^= k1;
+    }
+
+    hash ^= len;
+    hash ^= (hash >> 16);
+    hash *= 0x85ebca6b;
+    hash ^= (hash >> 13);
+    hash *= 0xc2b2ae35;
+    hash ^= (hash >> 16);
+
+    return hash;
 }
 }
 
 
 static void table_dump (gravity_hash_t *hashtable, gravity_value_t key, gravity_value_t value, void *data) {
 static void table_dump (gravity_hash_t *hashtable, gravity_value_t key, gravity_value_t value, void *data) {
-	#pragma unused (hashtable, data)
-	const char *k = ((gravity_string_t *)key.p)->s;
-	printf("%-20s=>\t",k);
-	gravity_value_dump(NULL, value, NULL, 0);
+    #pragma unused (hashtable, data)
+    const char *k = ((gravity_string_t *)key.p)->s;
+    printf("%-20s=>\t",k);
+    gravity_value_dump(NULL, value, NULL, 0);
 }
 }
 
 
 // MARK: -
 // MARK: -
 
 
 gravity_hash_t *gravity_hash_create (uint32_t size, gravity_hash_compute_fn compute, gravity_hash_isequal_fn isequal, gravity_hash_iterate_fn free_fn, void *data) {
 gravity_hash_t *gravity_hash_create (uint32_t size, gravity_hash_compute_fn compute, gravity_hash_isequal_fn isequal, gravity_hash_iterate_fn free_fn, void *data) {
-	if ((!compute) || (!isequal)) return NULL;
-	if (size == 0) size = GRAVITYHASH_DEFAULT_SIZE;
-
-	gravity_hash_t *hashtable = (gravity_hash_t *)mem_alloc(NULL, sizeof(gravity_hash_t));
-	if (!hashtable) return NULL;
-	if (!(hashtable->nodes = mem_calloc(NULL, size, sizeof(hash_node_t*)))) {mem_free(hashtable); return NULL;}
-
-	hashtable->compute_fn = compute;
-	hashtable->isequal_fn = isequal;
-	hashtable->free_fn = free_fn;
-	hashtable->data = data;
-	hashtable->size = size;
-	return hashtable;
+    if ((!compute) || (!isequal)) return NULL;
+    if (size == 0) size = GRAVITYHASH_DEFAULT_SIZE;
+
+    gravity_hash_t *hashtable = (gravity_hash_t *)mem_alloc(NULL, sizeof(gravity_hash_t));
+    if (!hashtable) return NULL;
+    if (!(hashtable->nodes = mem_calloc(NULL, size, sizeof(hash_node_t*)))) {mem_free(hashtable); return NULL;}
+
+    hashtable->compute_fn = compute;
+    hashtable->isequal_fn = isequal;
+    hashtable->free_fn = free_fn;
+    hashtable->data = data;
+    hashtable->size = size;
+    return hashtable;
 }
 }
 
 
 void gravity_hash_free (gravity_hash_t *hashtable) {
 void gravity_hash_free (gravity_hash_t *hashtable) {
-	if (!hashtable) return;
-	gravity_hash_iterate_fn free_fn = hashtable->free_fn;
+    if (!hashtable) return;
+    gravity_hash_iterate_fn free_fn = hashtable->free_fn;
 
 
-	for (uint32_t n = 0; n < hashtable->size; ++n) {
-		hash_node_t *node = hashtable->nodes[n];
+    for (uint32_t n = 0; n < hashtable->size; ++n) {
+        hash_node_t *node = hashtable->nodes[n];
         hashtable->nodes[n] = NULL;
         hashtable->nodes[n] = NULL;
-		while (node) {
-			if (free_fn) free_fn(hashtable, node->key, node->value, hashtable->data);
-			hash_node_t *old_node = node;
-			node = node->next;
-			mem_free(old_node);
-		}
-	}
-	mem_free(hashtable->nodes);
-	mem_free(hashtable);
+        while (node) {
+            if (free_fn) free_fn(hashtable, node->key, node->value, hashtable->data);
+            hash_node_t *old_node = node;
+            node = node->next;
+            mem_free(old_node);
+        }
+    }
+    mem_free(hashtable->nodes);
+    mem_free(hashtable);
     hashtable = NULL;
     hashtable = NULL;
 }
 }
 
 
 uint32_t gravity_hash_memsize (gravity_hash_t *hashtable) {
 uint32_t gravity_hash_memsize (gravity_hash_t *hashtable) {
-	uint32_t size = sizeof(gravity_hash_t);
-	size += hashtable->size * sizeof(hash_node_t);
-	return size;
+    uint32_t size = sizeof(gravity_hash_t);
+    size += hashtable->size * sizeof(hash_node_t);
+    return size;
 }
 }
 
 
 bool gravity_hash_isempty (gravity_hash_t *hashtable) {
 bool gravity_hash_isempty (gravity_hash_t *hashtable) {
-	return (hashtable->count == 0);
+    return (hashtable->count == 0);
 }
 }
 
 
 static inline int gravity_hash_resize (gravity_hash_t *hashtable) {
 static inline int gravity_hash_resize (gravity_hash_t *hashtable) {
-	uint32_t size = (hashtable->size * 2) + 1;
-	gravity_hash_t newtbl = {
-		.size = size,
-		.count = 0,
-		.isequal_fn = hashtable->isequal_fn,
-		.compute_fn = hashtable->compute_fn
-	};
-	if (!(newtbl.nodes = mem_calloc(NULL, size, sizeof(hash_node_t*)))) return -1;
-
-	hash_node_t *node, *next;
-	for (uint32_t n = 0; n < hashtable->size; ++n) {
-		for (node = hashtable->nodes[n]; node; node = next) {
-			next = node->next;
-			gravity_hash_insert(&newtbl, node->key, node->value);
-			// temporary disable free callback registered in hashtable
-			// because both key and values are reused in the new table
-			gravity_hash_iterate_fn free_fn = hashtable->free_fn;
-			hashtable->free_fn = NULL;
-			gravity_hash_remove(hashtable, node->key);
-			hashtable->free_fn = free_fn;
-		}
-	}
-
-	mem_free(hashtable->nodes);
-	hashtable->size = newtbl.size;
-	hashtable->count = newtbl.count;
-	hashtable->nodes = newtbl.nodes;
-	INC_RESIZE(hashtable);
-
-	return 0;
+    uint32_t size = (hashtable->size * 2) + 1;
+    gravity_hash_t newtbl = {
+        .size = size,
+        .count = 0,
+        .isequal_fn = hashtable->isequal_fn,
+        .compute_fn = hashtable->compute_fn
+    };
+    if (!(newtbl.nodes = mem_calloc(NULL, size, sizeof(hash_node_t*)))) return -1;
+
+    hash_node_t *node, *next;
+    for (uint32_t n = 0; n < hashtable->size; ++n) {
+        for (node = hashtable->nodes[n]; node; node = next) {
+            next = node->next;
+            gravity_hash_insert(&newtbl, node->key, node->value);
+            // temporary disable free callback registered in hashtable
+            // because both key and values are reused in the new table
+            gravity_hash_iterate_fn free_fn = hashtable->free_fn;
+            hashtable->free_fn = NULL;
+            gravity_hash_remove(hashtable, node->key);
+            hashtable->free_fn = free_fn;
+        }
+    }
+
+    mem_free(hashtable->nodes);
+    hashtable->size = newtbl.size;
+    hashtable->count = newtbl.count;
+    hashtable->nodes = newtbl.nodes;
+    INC_RESIZE(hashtable);
+
+    return 0;
 }
 }
 
 
 bool gravity_hash_remove (gravity_hash_t *hashtable, gravity_value_t key) {
 bool gravity_hash_remove (gravity_hash_t *hashtable, gravity_value_t key) {
-	register uint32_t hash = hashtable->compute_fn(key);
-	register uint32_t position = hash % hashtable->size;
-
-	gravity_hash_iterate_fn free_fn = hashtable->free_fn;
-	hash_node_t *node = hashtable->nodes[position];
-	hash_node_t *prevnode = NULL;
-	while (node) {
-		if ((node->hash == hash) && (hashtable->isequal_fn(key, node->key))) {
-			if (free_fn) free_fn(hashtable, node->key, node->value, hashtable->data);
-			if (prevnode) prevnode->next = node->next;
-			else hashtable->nodes[position] = node->next;
-			mem_free(node);
-			hashtable->count--;
-			return true;
-		}
-
-		prevnode = node;
-		node = node->next;
-	}
-
-	return false;
+    register uint32_t hash = hashtable->compute_fn(key);
+    register uint32_t position = hash % hashtable->size;
+
+    gravity_hash_iterate_fn free_fn = hashtable->free_fn;
+    hash_node_t *node = hashtable->nodes[position];
+    hash_node_t *prevnode = NULL;
+    while (node) {
+        if ((node->hash == hash) && (hashtable->isequal_fn(key, node->key))) {
+            if (free_fn) free_fn(hashtable, node->key, node->value, hashtable->data);
+            if (prevnode) prevnode->next = node->next;
+            else hashtable->nodes[position] = node->next;
+            mem_free(node);
+            hashtable->count--;
+            return true;
+        }
+
+        prevnode = node;
+        node = node->next;
+    }
+
+    return false;
 }
 }
 
 
 bool gravity_hash_insert (gravity_hash_t *hashtable, gravity_value_t key, gravity_value_t value) {
 bool gravity_hash_insert (gravity_hash_t *hashtable, gravity_value_t key, gravity_value_t value) {
-	register uint32_t hash = hashtable->compute_fn(key);
-	register uint32_t position = hash % hashtable->size;
-
-	hash_node_t *node = hashtable->nodes[position];
-	if (node) INC_COLLISION(hashtable);
-
-	// check if the key is already in the table
-	while (node) {
-		if ((node->hash == hash) && (hashtable->isequal_fn(key, node->key))) {
-			node->value = value;
-			return false;
-		}
-		node = node->next;
-	}
-
-	// resize table if the threshold is exceeded
-	// default threshold is: <table size> * <load factor GRAVITYHASH_THRESHOLD>
-	if (hashtable->count >= hashtable->size * GRAVITYHASH_THRESHOLD) {
-		if (gravity_hash_resize(hashtable) == -1) return -1;
-		// recompute position here because hashtable->size has changed!
-		position = hash % hashtable->size;
-	}
-
-	// allocate new entry and set new data
-	if (!(node = mem_alloc(NULL, sizeof(hash_node_t)))) return -1;
-	node->key = key;
-	node->hash = hash;
-	node->value = value;
-	node->next = hashtable->nodes[position];
-	hashtable->nodes[position] = node;
-	++hashtable->count;
-
-	return true;
+    register uint32_t hash = hashtable->compute_fn(key);
+    register uint32_t position = hash % hashtable->size;
+
+    hash_node_t *node = hashtable->nodes[position];
+    if (node) INC_COLLISION(hashtable);
+
+    // check if the key is already in the table
+    while (node) {
+        if ((node->hash == hash) && (hashtable->isequal_fn(key, node->key))) {
+            node->value = value;
+            return false;
+        }
+        node = node->next;
+    }
+
+    // resize table if the threshold is exceeded
+    // default threshold is: <table size> * <load factor GRAVITYHASH_THRESHOLD>
+    if (hashtable->count >= hashtable->size * GRAVITYHASH_THRESHOLD) {
+        if (gravity_hash_resize(hashtable) == -1) return -1;
+        // recompute position here because hashtable->size has changed!
+        position = hash % hashtable->size;
+    }
+
+    // allocate new entry and set new data
+    if (!(node = mem_alloc(NULL, sizeof(hash_node_t)))) return -1;
+    node->key = key;
+    node->hash = hash;
+    node->value = value;
+    node->next = hashtable->nodes[position];
+    hashtable->nodes[position] = node;
+    ++hashtable->count;
+
+    return true;
 }
 }
 
 
 gravity_value_t *gravity_hash_lookup (gravity_hash_t *hashtable, gravity_value_t key) {
 gravity_value_t *gravity_hash_lookup (gravity_hash_t *hashtable, gravity_value_t key) {
-	register uint32_t hash = hashtable->compute_fn(key);
-	register uint32_t position = hash % hashtable->size;
+    register uint32_t hash = hashtable->compute_fn(key);
+    register uint32_t position = hash % hashtable->size;
 
 
-	hash_node_t *node = hashtable->nodes[position];
-	while (node) {
-		if ((node->hash == hash) && (hashtable->isequal_fn(key, node->key))) return &node->value;
-		node = node->next;
-	}
+    hash_node_t *node = hashtable->nodes[position];
+    while (node) {
+        if ((node->hash == hash) && (hashtable->isequal_fn(key, node->key))) return &node->value;
+        node = node->next;
+    }
 
 
-	return NULL;
+    return NULL;
 }
 }
 
 
 gravity_value_t *gravity_hash_lookup_cstring (gravity_hash_t *hashtable, const char *ckey) {
 gravity_value_t *gravity_hash_lookup_cstring (gravity_hash_t *hashtable, const char *ckey) {
@@ -315,96 +315,96 @@ gravity_value_t *gravity_hash_lookup_cstring (gravity_hash_t *hashtable, const c
 }
 }
 
 
 uint32_t gravity_hash_count (gravity_hash_t *hashtable) {
 uint32_t gravity_hash_count (gravity_hash_t *hashtable) {
-	return hashtable->count;
+    return hashtable->count;
 }
 }
 
 
 uint32_t gravity_hash_compute_buffer (const char *key, uint32_t len) {
 uint32_t gravity_hash_compute_buffer (const char *key, uint32_t len) {
-	return murmur3_32(key, len, HASH_SEED_VALUE);
+    return murmur3_32(key, len, HASH_SEED_VALUE);
 }
 }
 
 
 uint32_t gravity_hash_compute_int (gravity_int_t n) {
 uint32_t gravity_hash_compute_int (gravity_int_t n) {
-	char buffer[24];
-	snprintf(buffer, sizeof(buffer), "%" PRId64, n);
-	return murmur3_32(buffer, (uint32_t)strlen(buffer), HASH_SEED_VALUE);
+    char buffer[24];
+    snprintf(buffer, sizeof(buffer), "%" PRId64, n);
+    return murmur3_32(buffer, (uint32_t)strlen(buffer), HASH_SEED_VALUE);
 }
 }
 
 
 uint32_t gravity_hash_compute_float (gravity_float_t f) {
 uint32_t gravity_hash_compute_float (gravity_float_t f) {
-	char buffer[24];
-	snprintf(buffer, sizeof(buffer), "%f", f);
-	return murmur3_32(buffer, (uint32_t)strlen(buffer), HASH_SEED_VALUE);
+    char buffer[24];
+    snprintf(buffer, sizeof(buffer), "%f", f);
+    return murmur3_32(buffer, (uint32_t)strlen(buffer), HASH_SEED_VALUE);
 }
 }
 
 
 void gravity_hash_stat (gravity_hash_t *hashtable) {
 void gravity_hash_stat (gravity_hash_t *hashtable) {
-	#if GRAVITYHASH_ENABLE_STATS
-	printf("==============\n");
-	printf("Collision: %d\n", hashtable->ncollision);
-	printf("Resize: %d\n", hashtable->nresize);
-	printf("Size: %d\n", hashtable->size);
-	printf("Count: %d\n", hashtable->count);
-	printf("==============\n");
-	#endif
+    #if GRAVITYHASH_ENABLE_STATS
+    printf("==============\n");
+    printf("Collision: %d\n", hashtable->ncollision);
+    printf("Resize: %d\n", hashtable->nresize);
+    printf("Size: %d\n", hashtable->size);
+    printf("Count: %d\n", hashtable->count);
+    printf("==============\n");
+    #endif
 }
 }
 
 
 void gravity_hash_transform (gravity_hash_t *hashtable, gravity_hash_transform_fn transform, void *data) {
 void gravity_hash_transform (gravity_hash_t *hashtable, gravity_hash_transform_fn transform, void *data) {
-	if ((!hashtable) || (!transform)) return;
+    if ((!hashtable) || (!transform)) return;
 
 
-	for (uint32_t i=0; i<hashtable->size; ++i) {
-		hash_node_t *node = hashtable->nodes[i];
-		if (!node) continue;
+    for (uint32_t i=0; i<hashtable->size; ++i) {
+        hash_node_t *node = hashtable->nodes[i];
+        if (!node) continue;
 
 
-		while (node) {
-			transform(hashtable, node->key, &node->value, data);
-			node = node->next;
-		}
-	}
+        while (node) {
+            transform(hashtable, node->key, &node->value, data);
+            node = node->next;
+        }
+    }
 }
 }
 
 
 void gravity_hash_iterate (gravity_hash_t *hashtable, gravity_hash_iterate_fn iterate, void *data) {
 void gravity_hash_iterate (gravity_hash_t *hashtable, gravity_hash_iterate_fn iterate, void *data) {
-	if ((!hashtable) || (!iterate)) return;
+    if ((!hashtable) || (!iterate)) return;
 
 
-	for (uint32_t i=0; i<hashtable->size; ++i) {
-		hash_node_t *node = hashtable->nodes[i];
-		if (!node) continue;
+    for (uint32_t i=0; i<hashtable->size; ++i) {
+        hash_node_t *node = hashtable->nodes[i];
+        if (!node) continue;
 
 
-		while (node) {
-			iterate(hashtable, node->key, node->value, data);
-			node = node->next;
-		}
-	}
+        while (node) {
+            iterate(hashtable, node->key, node->value, data);
+            node = node->next;
+        }
+    }
 }
 }
 
 
 void gravity_hash_iterate2 (gravity_hash_t *hashtable, gravity_hash_iterate2_fn iterate, void *data1, void *data2) {
 void gravity_hash_iterate2 (gravity_hash_t *hashtable, gravity_hash_iterate2_fn iterate, void *data1, void *data2) {
-	if ((!hashtable) || (!iterate)) return;
+    if ((!hashtable) || (!iterate)) return;
 
 
-	for (uint32_t i=0; i<hashtable->size; ++i) {
-		hash_node_t *node = hashtable->nodes[i];
-		if (!node) continue;
+    for (uint32_t i=0; i<hashtable->size; ++i) {
+        hash_node_t *node = hashtable->nodes[i];
+        if (!node) continue;
 
 
-		while (node) {
-			iterate(hashtable, node->key, node->value, data1, data2);
-			node = node->next;
-		}
-	}
+        while (node) {
+            iterate(hashtable, node->key, node->value, data1, data2);
+            node = node->next;
+        }
+    }
 }
 }
 
 
 void gravity_hash_dump (gravity_hash_t *hashtable) {
 void gravity_hash_dump (gravity_hash_t *hashtable) {
-	gravity_hash_iterate(hashtable, table_dump, NULL);
+    gravity_hash_iterate(hashtable, table_dump, NULL);
 }
 }
 
 
 void gravity_hash_append (gravity_hash_t *hashtable1, gravity_hash_t *hashtable2) {
 void gravity_hash_append (gravity_hash_t *hashtable1, gravity_hash_t *hashtable2) {
-	for (uint32_t i=0; i<hashtable2->size; ++i) {
-		hash_node_t *node = hashtable2->nodes[i];
-		if (!node) continue;
-
-		while (node) {
-			gravity_hash_insert(hashtable1, node->key, node->value);
-			node = node->next;
-		}
-	}
+    for (uint32_t i=0; i<hashtable2->size; ++i) {
+        hash_node_t *node = hashtable2->nodes[i];
+        if (!node) continue;
+
+        while (node) {
+            gravity_hash_insert(hashtable1, node->key, node->value);
+            node = node->next;
+        }
+    }
 }
 }
 
 
 void gravity_hash_resetfree (gravity_hash_t *hashtable) {
 void gravity_hash_resetfree (gravity_hash_t *hashtable) {
-	hashtable->free_fn = NULL;
+    hashtable->free_fn = NULL;
 }
 }
 
 
 bool gravity_hash_compare (gravity_hash_t *hashtable1, gravity_hash_t *hashtable2, gravity_hash_compare_fn compare, void *data) {
 bool gravity_hash_compare (gravity_hash_t *hashtable1, gravity_hash_t *hashtable2, gravity_hash_compare_fn compare, void *data) {

+ 29 - 29
src/shared/gravity_hash.h

@@ -15,13 +15,13 @@
 #include <stdbool.h>
 #include <stdbool.h>
 #include "gravity_value.h"
 #include "gravity_value.h"
 
 
-#define GRAVITYHASH_ENABLE_STATS	1						// if 0 then stats are not enabled
-#define GRAVITYHASH_DEFAULT_SIZE	32						// default hash table size (used if 0 is passed in gravity_hash_create)
-#define GRAVITYHASH_THRESHOLD		0.75					// threshold used to decide when re-hash the table
+#define GRAVITYHASH_ENABLE_STATS    1               // if 0 then stats are not enabled
+#define GRAVITYHASH_DEFAULT_SIZE    32              // default hash table size (used if 0 is passed in gravity_hash_create)
+#define GRAVITYHASH_THRESHOLD       0.75            // threshold used to decide when re-hash the table
 
 
 #ifndef GRAVITY_HASH_DEFINED
 #ifndef GRAVITY_HASH_DEFINED
 #define GRAVITY_HASH_DEFINED
 #define GRAVITY_HASH_DEFINED
-typedef struct 		gravity_hash_t	gravity_hash_t;			// opaque hash table struct
+typedef struct         gravity_hash_t    gravity_hash_t;    // opaque hash table struct
 #endif
 #endif
 
 
 #ifdef __cplusplus
 #ifdef __cplusplus
@@ -29,36 +29,36 @@ extern "C" {
 #endif
 #endif
 
 
 // CALLBACK functions
 // CALLBACK functions
-typedef uint32_t	(*gravity_hash_compute_fn) (gravity_value_t key);
-typedef bool		(*gravity_hash_isequal_fn) (gravity_value_t v1, gravity_value_t v2);
-typedef void  		(*gravity_hash_iterate_fn) (gravity_hash_t *hashtable, gravity_value_t key, gravity_value_t value, void *data);
-typedef void  		(*gravity_hash_iterate2_fn) (gravity_hash_t *hashtable, gravity_value_t key, gravity_value_t value, void *data1, void *data2);
-typedef void		(*gravity_hash_transform_fn) (gravity_hash_t *hashtable, gravity_value_t key, gravity_value_t *value, void *data);
+typedef uint32_t    (*gravity_hash_compute_fn) (gravity_value_t key);
+typedef bool        (*gravity_hash_isequal_fn) (gravity_value_t v1, gravity_value_t v2);
+typedef void        (*gravity_hash_iterate_fn) (gravity_hash_t *hashtable, gravity_value_t key, gravity_value_t value, void *data);
+typedef void        (*gravity_hash_iterate2_fn) (gravity_hash_t *hashtable, gravity_value_t key, gravity_value_t value, void *data1, void *data2);
+typedef void        (*gravity_hash_transform_fn) (gravity_hash_t *hashtable, gravity_value_t key, gravity_value_t *value, void *data);
 typedef bool        (*gravity_hash_compare_fn) (gravity_value_t value1, gravity_value_t value2, void *data);
 typedef bool        (*gravity_hash_compare_fn) (gravity_value_t value1, gravity_value_t value2, void *data);
 
 
 // PUBLIC functions
 // PUBLIC functions
-GRAVITY_API gravity_hash_t		*gravity_hash_create (uint32_t size, gravity_hash_compute_fn compute, gravity_hash_isequal_fn isequal, gravity_hash_iterate_fn free, void *data);
-GRAVITY_API void				gravity_hash_free (gravity_hash_t *hashtable);
-GRAVITY_API bool				gravity_hash_isempty (gravity_hash_t *hashtable);
-GRAVITY_API bool				gravity_hash_remove  (gravity_hash_t *hashtable, gravity_value_t key);
-GRAVITY_API bool				gravity_hash_insert (gravity_hash_t *hashtable, gravity_value_t key, gravity_value_t value);
-GRAVITY_API gravity_value_t		*gravity_hash_lookup (gravity_hash_t *hashtable, gravity_value_t key);
-GRAVITY_API gravity_value_t		*gravity_hash_lookup_cstring (gravity_hash_t *hashtable, const char *key);
+GRAVITY_API gravity_hash_t  *gravity_hash_create (uint32_t size, gravity_hash_compute_fn compute, gravity_hash_isequal_fn isequal, gravity_hash_iterate_fn free, void *data);
+GRAVITY_API void            gravity_hash_free (gravity_hash_t *hashtable);
+GRAVITY_API bool            gravity_hash_isempty (gravity_hash_t *hashtable);
+GRAVITY_API bool            gravity_hash_remove  (gravity_hash_t *hashtable, gravity_value_t key);
+GRAVITY_API bool            gravity_hash_insert (gravity_hash_t *hashtable, gravity_value_t key, gravity_value_t value);
+GRAVITY_API gravity_value_t *gravity_hash_lookup (gravity_hash_t *hashtable, gravity_value_t key);
+GRAVITY_API gravity_value_t *gravity_hash_lookup_cstring (gravity_hash_t *hashtable, const char *key);
 
 
-GRAVITY_API uint32_t			gravity_hash_memsize (gravity_hash_t *hashtable);
-GRAVITY_API uint32_t			gravity_hash_count (gravity_hash_t *hashtable);
-GRAVITY_API uint32_t			gravity_hash_compute_buffer (const char *key, uint32_t len);
-GRAVITY_API uint32_t			gravity_hash_compute_int (gravity_int_t n);
-GRAVITY_API uint32_t			gravity_hash_compute_float (gravity_float_t f);
-GRAVITY_API void				gravity_hash_stat (gravity_hash_t *hashtable);
-GRAVITY_API void				gravity_hash_iterate (gravity_hash_t *hashtable, gravity_hash_iterate_fn iterate, void *data);
-GRAVITY_API void				gravity_hash_iterate2 (gravity_hash_t *hashtable, gravity_hash_iterate2_fn iterate, void *data1, void *data2);
-GRAVITY_API void				gravity_hash_transform (gravity_hash_t *hashtable, gravity_hash_transform_fn iterate, void *data);
-GRAVITY_API void				gravity_hash_dump (gravity_hash_t *hashtable);
-GRAVITY_API void				gravity_hash_append (gravity_hash_t *hashtable1, gravity_hash_t *hashtable2);
-GRAVITY_API void				gravity_hash_resetfree (gravity_hash_t *hashtable);
+GRAVITY_API uint32_t        gravity_hash_memsize (gravity_hash_t *hashtable);
+GRAVITY_API uint32_t        gravity_hash_count (gravity_hash_t *hashtable);
+GRAVITY_API uint32_t        gravity_hash_compute_buffer (const char *key, uint32_t len);
+GRAVITY_API uint32_t        gravity_hash_compute_int (gravity_int_t n);
+GRAVITY_API uint32_t        gravity_hash_compute_float (gravity_float_t f);
+GRAVITY_API void            gravity_hash_stat (gravity_hash_t *hashtable);
+GRAVITY_API void            gravity_hash_iterate (gravity_hash_t *hashtable, gravity_hash_iterate_fn iterate, void *data);
+GRAVITY_API void            gravity_hash_iterate2 (gravity_hash_t *hashtable, gravity_hash_iterate2_fn iterate, void *data1, void *data2);
+GRAVITY_API void            gravity_hash_transform (gravity_hash_t *hashtable, gravity_hash_transform_fn iterate, void *data);
+GRAVITY_API void            gravity_hash_dump (gravity_hash_t *hashtable);
+GRAVITY_API void            gravity_hash_append (gravity_hash_t *hashtable1, gravity_hash_t *hashtable2);
+GRAVITY_API void            gravity_hash_resetfree (gravity_hash_t *hashtable);
 
 
-GRAVITY_API bool                gravity_hash_compare (gravity_hash_t *hashtable1, gravity_hash_t *hashtable2, gravity_hash_compare_fn compare, void *data);
+GRAVITY_API bool            gravity_hash_compare (gravity_hash_t *hashtable1, gravity_hash_t *hashtable2, gravity_hash_compare_fn compare, void *data);
 
 
 #ifdef __cplusplus
 #ifdef __cplusplus
 }
 }

+ 113 - 113
src/shared/gravity_macros.h

@@ -9,142 +9,142 @@
 #ifndef __GRAVITY_MACROS__
 #ifndef __GRAVITY_MACROS__
 #define __GRAVITY_MACROS__
 #define __GRAVITY_MACROS__
 
 
-#define AUTOLENGTH							UINT32_MAX
+#define AUTOLENGTH                            UINT32_MAX
 
 
 // MARK: -
 // MARK: -
 // pragma unused is not recognized by VC
 // pragma unused is not recognized by VC
-#define UNUSED_PARAM(_x)					(void)(_x)
-#define UNUSED_PARAM2(_x,_y)				UNUSED_PARAM(_x),UNUSED_PARAM(_y)
-#define UNUSED_PARAM3(_x,_y,_z)				UNUSED_PARAM(_x),UNUSED_PARAM(_y),UNUSED_PARAM(_z)
+#define UNUSED_PARAM(_x)                    (void)(_x)
+#define UNUSED_PARAM2(_x,_y)                UNUSED_PARAM(_x),UNUSED_PARAM(_y)
+#define UNUSED_PARAM3(_x,_y,_z)             UNUSED_PARAM(_x),UNUSED_PARAM(_y),UNUSED_PARAM(_z)
 
 
 // MARK: -
 // MARK: -
-#define VALUE_AS_OBJECT(x)					((x).p)
-#define VALUE_AS_STRING(x)					((gravity_string_t *)VALUE_AS_OBJECT(x))
-#define VALUE_AS_FIBER(x)					((gravity_fiber_t *)VALUE_AS_OBJECT(x))
-#define VALUE_AS_FUNCTION(x)				((gravity_function_t *)VALUE_AS_OBJECT(x))
-#define VALUE_AS_PROPERTY(x)				((gravity_property_t *)VALUE_AS_OBJECT(x))
-#define VALUE_AS_CLOSURE(x)					((gravity_closure_t *)VALUE_AS_OBJECT(x))
-#define VALUE_AS_CLASS(x)					((gravity_class_t *)VALUE_AS_OBJECT(x))
-#define VALUE_AS_INSTANCE(x)				((gravity_instance_t *)VALUE_AS_OBJECT(x))
-#define VALUE_AS_LIST(x)					((gravity_list_t *)VALUE_AS_OBJECT(x))
-#define VALUE_AS_MAP(x)						((gravity_map_t *)VALUE_AS_OBJECT(x))
-#define VALUE_AS_RANGE(x)					((gravity_range_t *)VALUE_AS_OBJECT(x))
-#define VALUE_AS_CSTRING(x)					(VALUE_AS_STRING(x)->s)
-#define VALUE_AS_ERROR(x)					((const char *)(x).p)
-#define VALUE_AS_FLOAT(x)					((x).f)
-#define VALUE_AS_INT(x)						((x).n)
-#define VALUE_AS_BOOL(x)					((x).n)
+#define VALUE_AS_OBJECT(x)                  ((x).p)
+#define VALUE_AS_STRING(x)                  ((gravity_string_t *)VALUE_AS_OBJECT(x))
+#define VALUE_AS_FIBER(x)                   ((gravity_fiber_t *)VALUE_AS_OBJECT(x))
+#define VALUE_AS_FUNCTION(x)                ((gravity_function_t *)VALUE_AS_OBJECT(x))
+#define VALUE_AS_PROPERTY(x)                ((gravity_property_t *)VALUE_AS_OBJECT(x))
+#define VALUE_AS_CLOSURE(x)                 ((gravity_closure_t *)VALUE_AS_OBJECT(x))
+#define VALUE_AS_CLASS(x)                   ((gravity_class_t *)VALUE_AS_OBJECT(x))
+#define VALUE_AS_INSTANCE(x)                ((gravity_instance_t *)VALUE_AS_OBJECT(x))
+#define VALUE_AS_LIST(x)                    ((gravity_list_t *)VALUE_AS_OBJECT(x))
+#define VALUE_AS_MAP(x)                     ((gravity_map_t *)VALUE_AS_OBJECT(x))
+#define VALUE_AS_RANGE(x)                   ((gravity_range_t *)VALUE_AS_OBJECT(x))
+#define VALUE_AS_CSTRING(x)                 (VALUE_AS_STRING(x)->s)
+#define VALUE_AS_ERROR(x)                   ((const char *)(x).p)
+#define VALUE_AS_FLOAT(x)                   ((x).f)
+#define VALUE_AS_INT(x)                     ((x).n)
+#define VALUE_AS_BOOL(x)                    ((x).n)
 
 
 // MARK: -
 // MARK: -
-#define VALUE_FROM_ERROR(msg)				((gravity_value_t){.isa = NULL, .p = ((gravity_object_t *)msg)})
-#define VALUE_NOT_VALID						VALUE_FROM_ERROR(NULL)
-#define VALUE_FROM_OBJECT(obj)				((gravity_value_t){.isa = ((gravity_object_t *)(obj)->isa), .p = (gravity_object_t *)(obj)})
-#define VALUE_FROM_STRING(_vm,_s,_len)		(gravity_string_to_value(_vm, _s, _len))
-#define VALUE_FROM_CSTRING(_vm,_s)			(gravity_string_to_value(_vm, _s, AUTOLENGTH))
-#define VALUE_FROM_INT(x)					((gravity_value_t){.isa = gravity_class_int, .n = (x)})
-#define VALUE_FROM_FLOAT(x)					((gravity_value_t){.isa = gravity_class_float, .f = (x)})
-#define VALUE_FROM_NULL						((gravity_value_t){.isa = gravity_class_null, .n = 0})
-#define VALUE_FROM_UNDEFINED				((gravity_value_t){.isa = gravity_class_null, .n = 1})
-#define VALUE_FROM_BOOL(x)					((gravity_value_t){.isa = gravity_class_bool, .n = (x)})
-#define VALUE_FROM_FALSE					VALUE_FROM_BOOL(0)
-#define VALUE_FROM_TRUE						VALUE_FROM_BOOL(1)
-#define STATICVALUE_FROM_STRING(_v,_s,_l)	gravity_string_t __temp = {.isa = gravity_class_string, .s = (char *)_s, .len = (uint32_t)_l, }; \
-											__temp.hash = gravity_hash_compute_buffer(__temp.s, __temp.len); \
-											gravity_value_t _v = {.isa = gravity_class_string, .p = (gravity_object_t *)&__temp };
+#define VALUE_FROM_ERROR(msg)               ((gravity_value_t){.isa = NULL, .p = ((gravity_object_t *)msg)})
+#define VALUE_NOT_VALID                     VALUE_FROM_ERROR(NULL)
+#define VALUE_FROM_OBJECT(obj)              ((gravity_value_t){.isa = ((gravity_object_t *)(obj)->isa), .p = (gravity_object_t *)(obj)})
+#define VALUE_FROM_STRING(_vm,_s,_len)      (gravity_string_to_value(_vm, _s, _len))
+#define VALUE_FROM_CSTRING(_vm,_s)          (gravity_string_to_value(_vm, _s, AUTOLENGTH))
+#define VALUE_FROM_INT(x)                   ((gravity_value_t){.isa = gravity_class_int, .n = (x)})
+#define VALUE_FROM_FLOAT(x)                 ((gravity_value_t){.isa = gravity_class_float, .f = (x)})
+#define VALUE_FROM_NULL                     ((gravity_value_t){.isa = gravity_class_null, .n = 0})
+#define VALUE_FROM_UNDEFINED                ((gravity_value_t){.isa = gravity_class_null, .n = 1})
+#define VALUE_FROM_BOOL(x)                  ((gravity_value_t){.isa = gravity_class_bool, .n = (x)})
+#define VALUE_FROM_FALSE                    VALUE_FROM_BOOL(0)
+#define VALUE_FROM_TRUE                     VALUE_FROM_BOOL(1)
+#define STATICVALUE_FROM_STRING(_v,_s,_l)   gravity_string_t __temp = {.isa = gravity_class_string, .s = (char *)_s, .len = (uint32_t)_l, }; \
+                                            __temp.hash = gravity_hash_compute_buffer(__temp.s, __temp.len); \
+                                            gravity_value_t _v = {.isa = gravity_class_string, .p = (gravity_object_t *)&__temp };
 // MARK: -
 // MARK: -
-#define VALUE_ISA_FUNCTION(v)				(v.isa == gravity_class_function)
-#define VALUE_ISA_INSTANCE(v)				(v.isa == gravity_class_instance)
-#define VALUE_ISA_CLOSURE(v)				(v.isa == gravity_class_closure)
-#define VALUE_ISA_FIBER(v)					(v.isa == gravity_class_fiber)
-#define VALUE_ISA_CLASS(v)					(v.isa == gravity_class_class)
-#define VALUE_ISA_STRING(v)					(v.isa == gravity_class_string)
-#define VALUE_ISA_INT(v)					(v.isa == gravity_class_int)
-#define VALUE_ISA_FLOAT(v)					(v.isa == gravity_class_float)
-#define VALUE_ISA_BOOL(v)					(v.isa == gravity_class_bool)
-#define VALUE_ISA_LIST(v)					(v.isa == gravity_class_list)
-#define VALUE_ISA_MAP(v)					(v.isa == gravity_class_map)
-#define VALUE_ISA_RANGE(v)					(v.isa == gravity_class_range)
-#define VALUE_ISA_BASIC_TYPE(v)				(VALUE_ISA_STRING(v) || VALUE_ISA_INT(v) || VALUE_ISA_FLOAT(v) || VALUE_ISA_BOOL(v))
-#define VALUE_ISA_NULLCLASS(v)				(v.isa == gravity_class_null)
-#define VALUE_ISA_NULL(v)					((v.isa == gravity_class_null) && (v.n == 0))
-#define VALUE_ISA_UNDEFINED(v)				((v.isa == gravity_class_null) && (v.n == 1))
-#define VALUE_ISA_CLASS(v)					(v.isa == gravity_class_class)
-#define VALUE_ISA_CALLABLE(v)				(VALUE_ISA_FUNCTION(v) || VALUE_ISA_CLASS(v) || VALUE_ISA_FIBER(v))
-#define VALUE_ISA_VALID(v)					(v.isa != NULL)
-#define VALUE_ISA_NOTVALID(v)				(v.isa == NULL)
-#define VALUE_ISA_ERROR(v)					VALUE_ISA_NOTVALID(v)
+#define VALUE_ISA_FUNCTION(v)               (v.isa == gravity_class_function)
+#define VALUE_ISA_INSTANCE(v)               (v.isa == gravity_class_instance)
+#define VALUE_ISA_CLOSURE(v)                (v.isa == gravity_class_closure)
+#define VALUE_ISA_FIBER(v)                  (v.isa == gravity_class_fiber)
+#define VALUE_ISA_CLASS(v)                  (v.isa == gravity_class_class)
+#define VALUE_ISA_STRING(v)                 (v.isa == gravity_class_string)
+#define VALUE_ISA_INT(v)                    (v.isa == gravity_class_int)
+#define VALUE_ISA_FLOAT(v)                  (v.isa == gravity_class_float)
+#define VALUE_ISA_BOOL(v)                   (v.isa == gravity_class_bool)
+#define VALUE_ISA_LIST(v)                   (v.isa == gravity_class_list)
+#define VALUE_ISA_MAP(v)                    (v.isa == gravity_class_map)
+#define VALUE_ISA_RANGE(v)                  (v.isa == gravity_class_range)
+#define VALUE_ISA_BASIC_TYPE(v)             (VALUE_ISA_STRING(v) || VALUE_ISA_INT(v) || VALUE_ISA_FLOAT(v) || VALUE_ISA_BOOL(v))
+#define VALUE_ISA_NULLCLASS(v)              (v.isa == gravity_class_null)
+#define VALUE_ISA_NULL(v)                   ((v.isa == gravity_class_null) && (v.n == 0))
+#define VALUE_ISA_UNDEFINED(v)              ((v.isa == gravity_class_null) && (v.n == 1))
+#define VALUE_ISA_CLASS(v)                  (v.isa == gravity_class_class)
+#define VALUE_ISA_CALLABLE(v)               (VALUE_ISA_FUNCTION(v) || VALUE_ISA_CLASS(v) || VALUE_ISA_FIBER(v))
+#define VALUE_ISA_VALID(v)                  (v.isa != NULL)
+#define VALUE_ISA_NOTVALID(v)               (v.isa == NULL)
+#define VALUE_ISA_ERROR(v)                  VALUE_ISA_NOTVALID(v)
 
 
 // MARK: -
 // MARK: -
-#define OBJECT_ISA_INT(obj)					(obj->isa == gravity_class_int)
-#define OBJECT_ISA_FLOAT(obj)				(obj->isa == gravity_class_float)
-#define OBJECT_ISA_BOOL(obj)				(obj->isa == gravity_class_bool)
-#define OBJECT_ISA_NULL(obj)				(obj->isa == gravity_class_null)
-#define OBJECT_ISA_CLASS(obj)				(obj->isa == gravity_class_class)
-#define OBJECT_ISA_FUNCTION(obj)			(obj->isa == gravity_class_function)
-#define OBJECT_ISA_CLOSURE(obj)				(obj->isa == gravity_class_closure)
-#define OBJECT_ISA_INSTANCE(obj)			(obj->isa == gravity_class_instance)
-#define OBJECT_ISA_LIST(obj)				(obj->isa == gravity_class_list)
-#define OBJECT_ISA_MAP(obj)					(obj->isa == gravity_class_map)
-#define OBJECT_ISA_STRING(obj)				(obj->isa == gravity_class_string)
-#define OBJECT_ISA_UPVALUE(obj)				(obj->isa == gravity_class_upvalue)
-#define OBJECT_ISA_FIBER(obj)				(obj->isa == gravity_class_fiber)
-#define OBJECT_ISA_RANGE(obj)				(obj->isa == gravity_class_range)
-#define OBJECT_ISA_MODULE(obj)				(obj->isa == gravity_class_module)
-#define OBJECT_IS_VALID(obj)				(obj->isa != NULL)
+#define OBJECT_ISA_INT(obj)                 (obj->isa == gravity_class_int)
+#define OBJECT_ISA_FLOAT(obj)               (obj->isa == gravity_class_float)
+#define OBJECT_ISA_BOOL(obj)                (obj->isa == gravity_class_bool)
+#define OBJECT_ISA_NULL(obj)                (obj->isa == gravity_class_null)
+#define OBJECT_ISA_CLASS(obj)               (obj->isa == gravity_class_class)
+#define OBJECT_ISA_FUNCTION(obj)            (obj->isa == gravity_class_function)
+#define OBJECT_ISA_CLOSURE(obj)             (obj->isa == gravity_class_closure)
+#define OBJECT_ISA_INSTANCE(obj)            (obj->isa == gravity_class_instance)
+#define OBJECT_ISA_LIST(obj)                (obj->isa == gravity_class_list)
+#define OBJECT_ISA_MAP(obj)                 (obj->isa == gravity_class_map)
+#define OBJECT_ISA_STRING(obj)              (obj->isa == gravity_class_string)
+#define OBJECT_ISA_UPVALUE(obj)             (obj->isa == gravity_class_upvalue)
+#define OBJECT_ISA_FIBER(obj)               (obj->isa == gravity_class_fiber)
+#define OBJECT_ISA_RANGE(obj)               (obj->isa == gravity_class_range)
+#define OBJECT_ISA_MODULE(obj)              (obj->isa == gravity_class_module)
+#define OBJECT_IS_VALID(obj)                (obj->isa != NULL)
 
 
 // MARK: -
 // MARK: -
-#define LIST_COUNT(v)						(marray_size(VALUE_AS_LIST(v)->array))
-#define LIST_VALUE_AT_INDEX(v, idx)			(marray_get(VALUE_AS_LIST(v)->array, idx))
+#define LIST_COUNT(v)                       (marray_size(VALUE_AS_LIST(v)->array))
+#define LIST_VALUE_AT_INDEX(v, idx)         (marray_get(VALUE_AS_LIST(v)->array, idx))
 
 
 // MARK: -
 // MARK: -
-#define GRAVITY_JSON_FUNCTION				"function"
-#define GRAVITY_JSON_CLASS					"class"
-#define GRAVITY_JSON_ENUM					"enum"
-#define GRAVITY_JSON_MAP					"map"
-#define GRAVITY_JSON_VAR					"var"
-#define GRAVITY_JSON_GETTER					"$get"
-#define GRAVITY_JSON_SETTER					"$set"
+#define GRAVITY_JSON_FUNCTION               "function"
+#define GRAVITY_JSON_CLASS                  "class"
+#define GRAVITY_JSON_ENUM                   "enum"
+#define GRAVITY_JSON_MAP                    "map"
+#define GRAVITY_JSON_VAR                    "var"
+#define GRAVITY_JSON_GETTER                 "$get"
+#define GRAVITY_JSON_SETTER                 "$set"
 
 
-#define GRAVITY_JSON_LABELTAG				"tag"
-#define GRAVITY_JSON_LABELNAME				"name"
-#define GRAVITY_JSON_LABELTYPE				"type"
+#define GRAVITY_JSON_LABELTAG               "tag"
+#define GRAVITY_JSON_LABELNAME              "name"
+#define GRAVITY_JSON_LABELTYPE              "type"
 #define GRAVITY_JSON_LABELVALUE             "value"
 #define GRAVITY_JSON_LABELVALUE             "value"
-#define GRAVITY_JSON_LABELIDENTIFIER		"identifier"
-#define GRAVITY_JSON_LABELPOOL				"pool"
+#define GRAVITY_JSON_LABELIDENTIFIER        "identifier"
+#define GRAVITY_JSON_LABELPOOL              "pool"
 #define GRAVITY_JSON_LABELPVALUES           "pvalues"
 #define GRAVITY_JSON_LABELPVALUES           "pvalues"
 #define GRAVITY_JSON_LABELPNAMES            "pnames"
 #define GRAVITY_JSON_LABELPNAMES            "pnames"
-#define GRAVITY_JSON_LABELMETA				"meta"
-#define GRAVITY_JSON_LABELBYTECODE			"bytecode"
-#define GRAVITY_JSON_LABELNPARAM			"nparam"
-#define GRAVITY_JSON_LABELNLOCAL			"nlocal"
-#define GRAVITY_JSON_LABELNTEMP				"ntemp"
-#define GRAVITY_JSON_LABELNUPV				"nup"
-#define GRAVITY_JSON_LABELARGS				"args"
-#define GRAVITY_JSON_LABELINDEX				"index"
-#define GRAVITY_JSON_LABELSUPER				"super"
-#define GRAVITY_JSON_LABELNIVAR				"nivar"
-#define GRAVITY_JSON_LABELSIVAR				"sivar"
-#define GRAVITY_JSON_LABELPURITY			"purity"
-#define GRAVITY_JSON_LABELREADONLY			"readonly"
-#define GRAVITY_JSON_LABELSTORE				"store"
-#define GRAVITY_JSON_LABELINIT				"init"
-#define GRAVITY_JSON_LABELSTATIC			"static"
-#define GRAVITY_JSON_LABELPARAMS			"params"
-#define GRAVITY_JSON_LABELSTRUCT			"struct"
+#define GRAVITY_JSON_LABELMETA              "meta"
+#define GRAVITY_JSON_LABELBYTECODE          "bytecode"
+#define GRAVITY_JSON_LABELNPARAM            "nparam"
+#define GRAVITY_JSON_LABELNLOCAL            "nlocal"
+#define GRAVITY_JSON_LABELNTEMP             "ntemp"
+#define GRAVITY_JSON_LABELNUPV              "nup"
+#define GRAVITY_JSON_LABELARGS              "args"
+#define GRAVITY_JSON_LABELINDEX             "index"
+#define GRAVITY_JSON_LABELSUPER             "super"
+#define GRAVITY_JSON_LABELNIVAR             "nivar"
+#define GRAVITY_JSON_LABELSIVAR             "sivar"
+#define GRAVITY_JSON_LABELPURITY            "purity"
+#define GRAVITY_JSON_LABELREADONLY          "readonly"
+#define GRAVITY_JSON_LABELSTORE             "store"
+#define GRAVITY_JSON_LABELINIT              "init"
+#define GRAVITY_JSON_LABELSTATIC            "static"
+#define GRAVITY_JSON_LABELPARAMS            "params"
+#define GRAVITY_JSON_LABELSTRUCT            "struct"
 
 
-#define GRAVITY_VM_ANONYMOUS_PREFIX			"$$"
+#define GRAVITY_VM_ANONYMOUS_PREFIX         "$$"
 
 
 // MARK: -
 // MARK: -
 
 
 #if 1
 #if 1
-#define DEBUG_ASSERT(condition, message)	do { \
-												if (!(condition)) { \
-													fprintf(stderr, "[%s:%d] Assert failed in %s(): %s\n", \
-													__FILE__, __LINE__, __func__, message); \
-													abort(); \
-												} \
-											} \
-											while(0)
+#define DEBUG_ASSERT(condition, message)    do { \
+                                                if (!(condition)) { \
+                                                    fprintf(stderr, "[%s:%d] Assert failed in %s(): %s\n", \
+                                                    __FILE__, __LINE__, __func__, message); \
+                                                    abort(); \
+                                                } \
+                                            } \
+                                            while(0)
 #else
 #else
 #define DEBUG_ASSERT(condition, message)
 #define DEBUG_ASSERT(condition, message)
 #endif
 #endif

+ 240 - 240
src/shared/gravity_memory.c

@@ -1,6 +1,6 @@
 //
 //
 //  gravity_memory.c
 //  gravity_memory.c
-//	gravity
+//    gravity
 //
 //
 //  Created by Marco Bambini on 20/03/16.
 //  Created by Marco Bambini on 20/03/16.
 //  Copyright © 2016 Creolabs. All rights reserved.
 //  Copyright © 2016 Creolabs. All rights reserved.
@@ -41,318 +41,318 @@ static uint32_t _ptr_lookup (void *ptr);
 static char **_ptr_stacktrace (size_t *nframes);
 static char **_ptr_stacktrace (size_t *nframes);
 static bool _is_internal(const char *s);
 static bool _is_internal(const char *s);
 
 
-#define STACK_DEPTH				128
-#define SLOT_MIN				128
-#define SLOT_NOTFOUND			UINT32_MAX
-#define BUILD_ERROR(...)		char current_error[1024]; snprintf(current_error, sizeof(current_error), __VA_ARGS__)
-#define BUILD_STACK(v1,v2)		size_t v1; char **v2 = _ptr_stacktrace(&v1)
-#define CHECK_FLAG()			if (!check_flag) return
+#define STACK_DEPTH                128
+#define SLOT_MIN                128
+#define SLOT_NOTFOUND            UINT32_MAX
+#define BUILD_ERROR(...)        char current_error[1024]; snprintf(current_error, sizeof(current_error), __VA_ARGS__)
+#define BUILD_STACK(v1,v2)        size_t v1; char **v2 = _ptr_stacktrace(&v1)
+#define CHECK_FLAG()            if (!check_flag) return
 
 
 typedef struct {
 typedef struct {
-	bool					deleted;
-	void					*ptr;
-	size_t					size;
-	size_t					nrealloc;
-
-	// record where it has been allocated/reallocated
-	size_t					nframe;
-	char					**frames;
-
-	// record where is has been freed
-	size_t					nframe2;
-	char					**frames2;
+    bool                    deleted;
+    void                    *ptr;
+    size_t                    size;
+    size_t                    nrealloc;
+
+    // record where it has been allocated/reallocated
+    size_t                    nframe;
+    char                    **frames;
+
+    // record where is has been freed
+    size_t                    nframe2;
+    char                    **frames2;
 } memslot;
 } memslot;
 
 
 typedef struct {
 typedef struct {
-	uint32_t				nalloc;
-	uint32_t				nrealloc;
-	uint32_t				nfree;
-	uint32_t				currmem;
-	uint32_t				maxmem;
-	uint32_t				nslot;		// number of slot filled with data
-	uint32_t				aslot;		// number of allocated slot
-	memslot					*slot;
+    uint32_t                nalloc;
+    uint32_t                nrealloc;
+    uint32_t                nfree;
+    uint32_t                currmem;
+    uint32_t                maxmem;
+    uint32_t                nslot;        // number of slot filled with data
+    uint32_t                aslot;        // number of allocated slot
+    memslot                    *slot;
 } _memdebug;
 } _memdebug;
 
 
 static _memdebug memdebug;
 static _memdebug memdebug;
 static bool check_flag = true;
 static bool check_flag = true;
 
 
 static void memdebug_report (char *str, char **stack, size_t nstack, memslot *slot) {
 static void memdebug_report (char *str, char **stack, size_t nstack, memslot *slot) {
-	printf("%s\n", str);
-	for (size_t i=0; i<nstack; ++i) {
-		if (_is_internal(stack[i])) continue;
-		printf("%s\n", stack[i]);
-	}
-
-	if (slot) {
-		printf("\nallocated:\n");
-		for (size_t i=0; i<slot->nframe; ++i) {
-			if (_is_internal(slot->frames[i])) continue;
-			printf("%s\n", slot->frames[i]);
-		}
-
-		printf("\nfreed:\n");
-		for (size_t i=0; i<slot->nframe2; ++i) {
-			if (_is_internal(slot->frames2[i])) continue;
-			printf("%s\n", slot->frames2[i]);
-		}
-	}
-
-	abort();
+    printf("%s\n", str);
+    for (size_t i=0; i<nstack; ++i) {
+        if (_is_internal(stack[i])) continue;
+        printf("%s\n", stack[i]);
+    }
+
+    if (slot) {
+        printf("\nallocated:\n");
+        for (size_t i=0; i<slot->nframe; ++i) {
+            if (_is_internal(slot->frames[i])) continue;
+            printf("%s\n", slot->frames[i]);
+        }
+
+        printf("\nfreed:\n");
+        for (size_t i=0; i<slot->nframe2; ++i) {
+            if (_is_internal(slot->frames2[i])) continue;
+            printf("%s\n", slot->frames2[i]);
+        }
+    }
+
+    abort();
 }
 }
 
 
 void memdebug_init (void) {
 void memdebug_init (void) {
-	if (memdebug.slot) free(memdebug.slot);
-	bzero(&memdebug, sizeof(_memdebug));
+    if (memdebug.slot) free(memdebug.slot);
+    bzero(&memdebug, sizeof(_memdebug));
 
 
-	memdebug.slot = (memslot *) malloc(sizeof(memslot) * SLOT_MIN);
-	memdebug.aslot = SLOT_MIN;
+    memdebug.slot = (memslot *) malloc(sizeof(memslot) * SLOT_MIN);
+    memdebug.aslot = SLOT_MIN;
 }
 }
 
 
 void *memdebug_malloc(gravity_vm *vm, size_t size) {
 void *memdebug_malloc(gravity_vm *vm, size_t size) {
     #pragma unused(vm)
     #pragma unused(vm)
-	void *ptr = malloc(size);
-	if (!ptr) {
-		BUILD_ERROR("Unable to allocated a block of %zu bytes", size);
-		BUILD_STACK(n, stack);
-		memdebug_report(current_error, stack, n, NULL);
-		return NULL;
-	}
-
-	_ptr_add(ptr, size);
-	return ptr;
+    void *ptr = malloc(size);
+    if (!ptr) {
+        BUILD_ERROR("Unable to allocated a block of %zu bytes", size);
+        BUILD_STACK(n, stack);
+        memdebug_report(current_error, stack, n, NULL);
+        return NULL;
+    }
+
+    _ptr_add(ptr, size);
+    return ptr;
 }
 }
 
 
 void *memdebug_malloc0(gravity_vm *vm, size_t size) {
 void *memdebug_malloc0(gravity_vm *vm, size_t size) {
     #pragma unused(vm)
     #pragma unused(vm)
-	return memdebug_calloc(vm, 1, size);
+    return memdebug_calloc(vm, 1, size);
 }
 }
 
 
 void *memdebug_calloc(gravity_vm *vm, size_t num, size_t size) {
 void *memdebug_calloc(gravity_vm *vm, size_t num, size_t size) {
     #pragma unused(vm)
     #pragma unused(vm)
-	void *ptr = calloc(num, size);
-	if (!ptr) {
-		BUILD_ERROR("Unable to allocated a block of %zu bytes", size);
-		BUILD_STACK(n, stack);
-		memdebug_report(current_error, stack, n, NULL);
-		return NULL;
-	}
-
-	_ptr_add(ptr, num*size);
-	return ptr;
+    void *ptr = calloc(num, size);
+    if (!ptr) {
+        BUILD_ERROR("Unable to allocated a block of %zu bytes", size);
+        BUILD_STACK(n, stack);
+        memdebug_report(current_error, stack, n, NULL);
+        return NULL;
+    }
+
+    _ptr_add(ptr, num*size);
+    return ptr;
 }
 }
 
 
 void *memdebug_realloc(gravity_vm *vm, void *ptr, size_t new_size) {
 void *memdebug_realloc(gravity_vm *vm, void *ptr, size_t new_size) {
     #pragma unused(vm)
     #pragma unused(vm)
-	// ensure ptr has been previously allocated by malloc, calloc or realloc and not yet freed with free
-	uint32_t index = _ptr_lookup(ptr);
-	if (index == SLOT_NOTFOUND) {
-		BUILD_ERROR("Pointer being reallocated was now previously allocated");
-		BUILD_STACK(n, stack);
-		memdebug_report(current_error, stack, n, NULL);
-		return NULL;
-	}
-
-	void *new_ptr = realloc(ptr, new_size);
-	if (!ptr) {
-		BUILD_ERROR("Unable to reallocate a block of %zu bytes", new_size);
-		BUILD_STACK(n, stack);
-		memdebug_report(current_error, stack, n, &memdebug.slot[index]);
-		return NULL;
-	}
-
-	_ptr_replace(ptr, new_ptr, new_size);
-	return new_ptr;
+    // ensure ptr has been previously allocated by malloc, calloc or realloc and not yet freed with free
+    uint32_t index = _ptr_lookup(ptr);
+    if (index == SLOT_NOTFOUND) {
+        BUILD_ERROR("Pointer being reallocated was now previously allocated");
+        BUILD_STACK(n, stack);
+        memdebug_report(current_error, stack, n, NULL);
+        return NULL;
+    }
+
+    void *new_ptr = realloc(ptr, new_size);
+    if (!ptr) {
+        BUILD_ERROR("Unable to reallocate a block of %zu bytes", new_size);
+        BUILD_STACK(n, stack);
+        memdebug_report(current_error, stack, n, &memdebug.slot[index]);
+        return NULL;
+    }
+
+    _ptr_replace(ptr, new_ptr, new_size);
+    return new_ptr;
 }
 }
 
 
 bool memdebug_remove(void *ptr) {
 bool memdebug_remove(void *ptr) {
-	// ensure ptr has been previously allocated by malloc, calloc or realloc and not yet freed with free
-	if (check_flag) {
-		uint32_t index = _ptr_lookup(ptr);
-		if (index == SLOT_NOTFOUND) {
-			BUILD_ERROR("Pointer being freed was not previously allocated");
-			BUILD_STACK(n, stack);
-			memdebug_report(current_error, stack, n, NULL);
-			return false;
-		}
-
-		memslot m = memdebug.slot[index];
-		if (m.deleted) {
-			BUILD_ERROR("Pointer already freed");
-			BUILD_STACK(n, stack);
-			memdebug_report(current_error, stack, n, &m);
-			return false;
-		}
-	}
-
-	_ptr_remove(ptr);
-	return true;
+    // ensure ptr has been previously allocated by malloc, calloc or realloc and not yet freed with free
+    if (check_flag) {
+        uint32_t index = _ptr_lookup(ptr);
+        if (index == SLOT_NOTFOUND) {
+            BUILD_ERROR("Pointer being freed was not previously allocated");
+            BUILD_STACK(n, stack);
+            memdebug_report(current_error, stack, n, NULL);
+            return false;
+        }
+
+        memslot m = memdebug.slot[index];
+        if (m.deleted) {
+            BUILD_ERROR("Pointer already freed");
+            BUILD_STACK(n, stack);
+            memdebug_report(current_error, stack, n, &m);
+            return false;
+        }
+    }
+
+    _ptr_remove(ptr);
+    return true;
 }
 }
 
 
 void memdebug_free(void *ptr) {
 void memdebug_free(void *ptr) {
-	if (!memdebug_remove(ptr)) return;
-	free(ptr);
+    if (!memdebug_remove(ptr)) return;
+    free(ptr);
 }
 }
 void memdebug_setcheck(bool flag) {
 void memdebug_setcheck(bool flag) {
-	check_flag = flag;
+    check_flag = flag;
 }
 }
 
 
 void memdebug_stat(void) {
 void memdebug_stat(void) {
-	printf("\n========== MEMORY STATS ==========\n");
-	printf("Allocations count: %d\n", memdebug.nalloc);
-	printf("Reallocations count: %d\n", memdebug.nrealloc);
-	printf("Free count: %d\n", memdebug.nfree);
-	printf("Leaked: %d (bytes)\n", memdebug.currmem);
-	printf("Max memory usage: %d (bytes)\n", memdebug.maxmem);
-	printf("==================================\n\n");
-
-	if (memdebug.currmem > 0) {
-		printf("\n");
-		for (uint32_t i=0; i<memdebug.nslot; ++i) {
-			memslot m = memdebug.slot[i];
-			if ((!m.ptr) || (m.deleted)) continue;
-
-			printf("Block %p size: %zu (reallocated %zu)\n", m.ptr, m.size, m.nrealloc);
-			printf("Call stack:\n");
-			printf("===========\n");
-			for (size_t j=0; j<m.nframe; ++j) {
-				if (_is_internal(m.frames[j])) continue;
-				printf("%s\n", m.frames[j]);
-			}
-			printf("===========\n\n");
-		}
-	}
+    printf("\n========== MEMORY STATS ==========\n");
+    printf("Allocations count: %d\n", memdebug.nalloc);
+    printf("Reallocations count: %d\n", memdebug.nrealloc);
+    printf("Free count: %d\n", memdebug.nfree);
+    printf("Leaked: %d (bytes)\n", memdebug.currmem);
+    printf("Max memory usage: %d (bytes)\n", memdebug.maxmem);
+    printf("==================================\n\n");
+
+    if (memdebug.currmem > 0) {
+        printf("\n");
+        for (uint32_t i=0; i<memdebug.nslot; ++i) {
+            memslot m = memdebug.slot[i];
+            if ((!m.ptr) || (m.deleted)) continue;
+
+            printf("Block %p size: %zu (reallocated %zu)\n", m.ptr, m.size, m.nrealloc);
+            printf("Call stack:\n");
+            printf("===========\n");
+            for (size_t j=0; j<m.nframe; ++j) {
+                if (_is_internal(m.frames[j])) continue;
+                printf("%s\n", m.frames[j]);
+            }
+            printf("===========\n\n");
+        }
+    }
 }
 }
 
 
 size_t memdebug_status (void) {
 size_t memdebug_status (void) {
-	return memdebug.maxmem;
+    return memdebug.maxmem;
 }
 }
 
 
 size_t memdebug_leaks (void) {
 size_t memdebug_leaks (void) {
-	return memdebug.currmem;
+    return memdebug.currmem;
 }
 }
 
 
 // Internals
 // Internals
 void _ptr_add (void *ptr, size_t size) {
 void _ptr_add (void *ptr, size_t size) {
-	CHECK_FLAG();
-
-	if (memdebug.nslot + 1 >= memdebug.aslot) {
-		size_t old_size = sizeof(memslot) * memdebug.nslot;
-		size_t new_size = sizeof(memslot) * SLOT_MIN;
-		memslot *new_slot = (memslot *) realloc(memdebug.slot, old_size+new_size);
-		if (!new_slot) {
-			BUILD_ERROR("Unable to reallocate internal slots");
-			memdebug_report(current_error, NULL, 0, NULL);
-			abort();
-		}
-		memdebug.slot = new_slot;
-		memdebug.aslot += SLOT_MIN;
-	}
-
-	memslot slot = {
-		.deleted = false,
-		.ptr = ptr,
-		.size = size,
-		.nrealloc = 0,
-		.nframe2 = 0,
-		.frames = NULL
-	};
-	slot.frames = _ptr_stacktrace(&slot.nframe);
-
-	memdebug.slot[memdebug.nslot] = slot;
-	++memdebug.nslot;
-
-	++memdebug.nalloc;
-	memdebug.currmem += size;
-	if (memdebug.currmem > memdebug.maxmem)
-		memdebug.maxmem = memdebug.currmem;
+    CHECK_FLAG();
+
+    if (memdebug.nslot + 1 >= memdebug.aslot) {
+        size_t old_size = sizeof(memslot) * memdebug.nslot;
+        size_t new_size = sizeof(memslot) * SLOT_MIN;
+        memslot *new_slot = (memslot *) realloc(memdebug.slot, old_size+new_size);
+        if (!new_slot) {
+            BUILD_ERROR("Unable to reallocate internal slots");
+            memdebug_report(current_error, NULL, 0, NULL);
+            abort();
+        }
+        memdebug.slot = new_slot;
+        memdebug.aslot += SLOT_MIN;
+    }
+
+    memslot slot = {
+        .deleted = false,
+        .ptr = ptr,
+        .size = size,
+        .nrealloc = 0,
+        .nframe2 = 0,
+        .frames = NULL
+    };
+    slot.frames = _ptr_stacktrace(&slot.nframe);
+
+    memdebug.slot[memdebug.nslot] = slot;
+    ++memdebug.nslot;
+
+    ++memdebug.nalloc;
+    memdebug.currmem += size;
+    if (memdebug.currmem > memdebug.maxmem)
+        memdebug.maxmem = memdebug.currmem;
 }
 }
 
 
 void _ptr_replace (void *old_ptr, void *new_ptr, size_t new_size) {
 void _ptr_replace (void *old_ptr, void *new_ptr, size_t new_size) {
-	CHECK_FLAG();
-
-	uint32_t index = _ptr_lookup(old_ptr);
-
-	if (index == SLOT_NOTFOUND) {
-		BUILD_ERROR("Unable to find old pointer to realloc");
-		memdebug_report(current_error, NULL, 0, NULL);
-	}
-
-	memslot slot = memdebug.slot[index];
-	if (slot.deleted) {
-		BUILD_ERROR("Pointer already freed");
-		BUILD_STACK(n, stack);
-		memdebug_report(current_error, stack, n, &slot);
-	}
-	size_t old_size = memdebug.slot[index].size;
-	slot.ptr = new_ptr;
-	slot.size = new_size;
-	if (slot.frames) free((void *)slot.frames);
-	slot.frames = _ptr_stacktrace(&slot.nframe);
-	++slot.nrealloc;
-
-	memdebug.slot[index] = slot;
-	++memdebug.nrealloc;
-	memdebug.currmem += (new_size - old_size);
-	if (memdebug.currmem > memdebug.maxmem)
-		memdebug.maxmem = memdebug.currmem;
+    CHECK_FLAG();
+
+    uint32_t index = _ptr_lookup(old_ptr);
+
+    if (index == SLOT_NOTFOUND) {
+        BUILD_ERROR("Unable to find old pointer to realloc");
+        memdebug_report(current_error, NULL, 0, NULL);
+    }
+
+    memslot slot = memdebug.slot[index];
+    if (slot.deleted) {
+        BUILD_ERROR("Pointer already freed");
+        BUILD_STACK(n, stack);
+        memdebug_report(current_error, stack, n, &slot);
+    }
+    size_t old_size = memdebug.slot[index].size;
+    slot.ptr = new_ptr;
+    slot.size = new_size;
+    if (slot.frames) free((void *)slot.frames);
+    slot.frames = _ptr_stacktrace(&slot.nframe);
+    ++slot.nrealloc;
+
+    memdebug.slot[index] = slot;
+    ++memdebug.nrealloc;
+    memdebug.currmem += (new_size - old_size);
+    if (memdebug.currmem > memdebug.maxmem)
+        memdebug.maxmem = memdebug.currmem;
 }
 }
 
 
 void _ptr_remove (void *ptr) {
 void _ptr_remove (void *ptr) {
-	CHECK_FLAG();
+    CHECK_FLAG();
 
 
-	uint32_t index = _ptr_lookup(ptr);
+    uint32_t index = _ptr_lookup(ptr);
 
 
-	if (index == SLOT_NOTFOUND) {
-		BUILD_ERROR("Unable to find old pointer to realloc");
-		memdebug_report(current_error, NULL, 0, NULL);
-	}
+    if (index == SLOT_NOTFOUND) {
+        BUILD_ERROR("Unable to find old pointer to realloc");
+        memdebug_report(current_error, NULL, 0, NULL);
+    }
 
 
-	memslot slot = memdebug.slot[index];
-	if (slot.deleted) {
-		BUILD_ERROR("Pointer already freed");
-		BUILD_STACK(n, stack);
-		memdebug_report(current_error, stack, n, &slot);
-	}
+    memslot slot = memdebug.slot[index];
+    if (slot.deleted) {
+        BUILD_ERROR("Pointer already freed");
+        BUILD_STACK(n, stack);
+        memdebug_report(current_error, stack, n, &slot);
+    }
 
 
-	size_t old_size = memdebug.slot[index].size;
-	memdebug.slot[index].deleted = true;
-	memdebug.slot[index].frames2 = _ptr_stacktrace(&memdebug.slot[index].nframe2);
+    size_t old_size = memdebug.slot[index].size;
+    memdebug.slot[index].deleted = true;
+    memdebug.slot[index].frames2 = _ptr_stacktrace(&memdebug.slot[index].nframe2);
 
 
-	++memdebug.nfree;
-	memdebug.currmem -= old_size;
+    ++memdebug.nfree;
+    memdebug.currmem -= old_size;
 }
 }
 
 
 uint32_t _ptr_lookup (void *ptr) {
 uint32_t _ptr_lookup (void *ptr) {
-	for (uint32_t i=0; i<memdebug.nslot; ++i) {
-		if (memdebug.slot[i].ptr == ptr) return i;
-	}
-	return SLOT_NOTFOUND;
+    for (uint32_t i=0; i<memdebug.nslot; ++i) {
+        if (memdebug.slot[i].ptr == ptr) return i;
+    }
+    return SLOT_NOTFOUND;
 }
 }
 
 
 char **_ptr_stacktrace (size_t *nframes) {
 char **_ptr_stacktrace (size_t *nframes) {
-	#if _WIN32
-	// http://www.codeproject.com/Articles/11132/Walking-the-callstack
-	// https://spin.atomicobject.com/2013/01/13/exceptions-stack-traces-c/
-	#else
-	void *callstack[STACK_DEPTH];
-	int n = backtrace(callstack, STACK_DEPTH);
-	char **strs = backtrace_symbols(callstack, n);
-	*nframes = (size_t)n;
-	return strs;
-	#endif
+    #if _WIN32
+    // http://www.codeproject.com/Articles/11132/Walking-the-callstack
+    // https://spin.atomicobject.com/2013/01/13/exceptions-stack-traces-c/
+    #else
+    void *callstack[STACK_DEPTH];
+    int n = backtrace(callstack, STACK_DEPTH);
+    char **strs = backtrace_symbols(callstack, n);
+    *nframes = (size_t)n;
+    return strs;
+    #endif
 }
 }
 
 
 // Default callback
 // Default callback
 bool _is_internal(const char *s) {
 bool _is_internal(const char *s) {
-	static const char *reserved[] = {"??? ", "libdyld.dylib ", "memdebug_", "_ptr_", NULL};
-
-	const char **r = reserved;
-	while (*r) {
-		if (strstr(s, *r)) return true;
-		++r;
-	}
-	return false;
+    static const char *reserved[] = {"??? ", "libdyld.dylib ", "memdebug_", "_ptr_", NULL};
+
+    const char **r = reserved;
+    while (*r) {
+        if (strstr(s, *r)) return true;
+        ++r;
+    }
+    return false;
 }
 }
 
 
 #undef STACK_DEPTH
 #undef STACK_DEPTH

+ 14 - 14
src/shared/gravity_memory.h

@@ -1,6 +1,6 @@
 //
 //
 //  gravity_memory.h
 //  gravity_memory.h
-//	gravity
+//    gravity
 //
 //
 //  Created by Marco Bambini on 20/03/16.
 //  Created by Marco Bambini on 20/03/16.
 //  Copyright © 2016 Creolabs. All rights reserved.
 //  Copyright © 2016 Creolabs. All rights reserved.
@@ -19,7 +19,7 @@
 
 
 #ifndef GRAVITY_VM_DEFINED
 #ifndef GRAVITY_VM_DEFINED
 #define GRAVITY_VM_DEFINED
 #define GRAVITY_VM_DEFINED
-typedef struct gravity_vm				gravity_vm;
+typedef struct gravity_vm                gravity_vm;
 #endif
 #endif
 
 
 #if GRAVITY_MEMORY_DEBUG
 #if GRAVITY_MEMORY_DEBUG
@@ -37,7 +37,7 @@ typedef struct gravity_vm				gravity_vm;
 #define mem_init()
 #define mem_init()
 #define mem_stat()
 #define mem_stat()
 #define mem_alloc(_vm,_size)            gravity_calloc(_vm, 1, _size)
 #define mem_alloc(_vm,_size)            gravity_calloc(_vm, 1, _size)
-#define mem_calloc(_vm,_count,_size)	gravity_calloc(_vm, _count, _size)
+#define mem_calloc(_vm,_count,_size)    gravity_calloc(_vm, _count, _size)
 #define mem_realloc(_vm,_ptr,_size)     gravity_realloc(_vm, _ptr, _size)
 #define mem_realloc(_vm,_ptr,_size)     gravity_realloc(_vm, _ptr, _size)
 #define mem_free(v)                     free((void *)v)
 #define mem_free(v)                     free((void *)v)
 #define mem_check(v)
 #define mem_check(v)
@@ -47,17 +47,17 @@ typedef struct gravity_vm				gravity_vm;
 #endif
 #endif
 
 
 #if GRAVITY_MEMORY_DEBUG
 #if GRAVITY_MEMORY_DEBUG
-void	memdebug_init (void);
-void	*memdebug_malloc (gravity_vm *vm, size_t size);
-void	*memdebug_malloc0 (gravity_vm *vm, size_t size);
-void	*memdebug_calloc (gravity_vm *vm, size_t num, size_t size);
-void	*memdebug_realloc (gravity_vm *vm, void *ptr, size_t new_size);
-void	memdebug_free (void *ptr);
-size_t	memdebug_leaks (void);
-size_t	memdebug_status (void);
-void	memdebug_setcheck (bool flag);
-void	memdebug_stat (void);
-bool	memdebug_remove (void *ptr);
+void    memdebug_init (void);
+void    *memdebug_malloc (gravity_vm *vm, size_t size);
+void    *memdebug_malloc0 (gravity_vm *vm, size_t size);
+void    *memdebug_calloc (gravity_vm *vm, size_t num, size_t size);
+void    *memdebug_realloc (gravity_vm *vm, void *ptr, size_t new_size);
+void    memdebug_free (void *ptr);
+size_t    memdebug_leaks (void);
+size_t    memdebug_status (void);
+void    memdebug_setcheck (bool flag);
+void    memdebug_stat (void);
+bool    memdebug_remove (void *ptr);
 #else
 #else
 void    *gravity_calloc (gravity_vm *vm, size_t count, size_t size);
 void    *gravity_calloc (gravity_vm *vm, size_t count, size_t size);
 void    *gravity_realloc (gravity_vm *vm, void *ptr, size_t new_size);
 void    *gravity_realloc (gravity_vm *vm, void *ptr, size_t new_size);

+ 198 - 198
src/shared/gravity_opcodes.h

@@ -10,217 +10,217 @@
 #define __GRAVITY_OPCODES__
 #define __GRAVITY_OPCODES__
 
 
 /*
 /*
-		Big-endian vs Little-endian machines
-
-		ARM architecture runs both little & big endianess, but the android, iOS, and windows phone platforms run little endian.
-		95% of modern desktop computers are little-endian.
-		All x86 desktops (which is nearly all desktops with the demise of the PowerPC-based Macs several years ago) are little-endian.
-		It's probably actually a lot more than 95% nowadays. PowerPC was the only non-x86 architecture that has been popular for desktop
-		computers in the last 20 years and Apple abandoned it in favor of x86.
-		Sparc, Alpha, and Itanium did exist, but they were all very rare in the desktop market.
+        Big-endian vs Little-endian machines
+
+        ARM architecture runs both little & big endianess, but the android, iOS, and windows phone platforms run little endian.
+        95% of modern desktop computers are little-endian.
+        All x86 desktops (which is nearly all desktops with the demise of the PowerPC-based Macs several years ago) are little-endian.
+        It's probably actually a lot more than 95% nowadays. PowerPC was the only non-x86 architecture that has been popular for desktop
+        computers in the last 20 years and Apple abandoned it in favor of x86.
+        Sparc, Alpha, and Itanium did exist, but they were all very rare in the desktop market.
  */
  */
 
 
 /*
 /*
-		Instructions are 32bit in lenght
-
-		// 2 registers and 1 register/constant
-		+------------------------------------+
-		|  OP  |   Ax   |   Bx   |    Cx/K   |
-		+------------------------------------+
-
-		// instructions with no parameters
-		+------------------------------------+
-		|  OP  |0                            |
-		+------------------------------------+
-
-		// unconditional JUMP
-		+------------------------------------+
-		|  OP  |             N1              |
-		+------------------------------------+
-
-		// LOADI and JUMPF
-		+------------------------------------+
-		|  OP  |   Ax   |S|       N2         |
-		+------------------------------------+
-
-		OP   =>  6 bits
-		Ax   =>  8 bits
- 		Bx   =>  8 bits
- 		Cx/K =>  8/10 bits
-		S    =>  1 bit
-		N1   => 26 bits
-		N2   => 17 bits
+        Instructions are 32bit in lenght
+
+        // 2 registers and 1 register/constant
+        +------------------------------------+
+        |  OP  |   Ax   |   Bx   |    Cx/K   |
+        +------------------------------------+
+
+        // instructions with no parameters
+        +------------------------------------+
+        |  OP  |0                            |
+        +------------------------------------+
+
+        // unconditional JUMP
+        +------------------------------------+
+        |  OP  |             N1              |
+        +------------------------------------+
+
+        // LOADI and JUMPF
+        +------------------------------------+
+        |  OP  |   Ax   |S|       N2         |
+        +------------------------------------+
+
+        OP   =>  6 bits
+        Ax   =>  8 bits
+        Bx   =>  8 bits
+        Cx/K =>  8/10 bits
+        S    =>  1 bit
+        N1   =>  26 bits
+        N2   =>  17 bits
  */
  */
 
 
 typedef enum {
 typedef enum {
 
 
-	//		****************************************************************************************************
-	//		56 OPCODE INSTRUCTIONS (for a register based virtual machine)
-	//		opcode is a 6 bit value so at maximum 2^6 = 64 opcodes can be declared
-	//		****************************************************************************************************
-	//
-	//		MNEMONIC		PARAMETERS		DESCRIPTION								OPERATION
-	//		--------		----------		------------------------------------	----------------------------
-	//
-											//	*** GENERAL COMMANDS (5) ***
-			RET0 = 0,		//	NONE		//	return nothing from a function		MUST BE THE FIRST OPCODE (because an implict 0 is added
-											//										as a safeguard at the end of any bytecode
-			HALT,			//	NONE		//	stop VM execution
-			NOP,			//	NONE		//	NOP									http://en.wikipedia.org/wiki/NOP
-			RET,			//  A			//	return from a function				R(-1) = R(A)
-			CALL,			//	A, B, C		//	call a function						R(A) = B(C0...Cn) B is callable object and C is num args
-
-											//	*** LOAD/STORE OPERATIONS (11) ***
-			LOAD,			//	A, B, C		//	load C from B and store in A		R(A) = R(B)[C]
-			LOADS,			//	A, B, C		//	load C from B and store in A		R(A) = R(B)[C] (super variant)
-			LOADAT,			//	A, B, C		//	load C from B and store in A		R(A) = R(B)[C]
-			LOADK,			//	A, B		//	load constant into register			R(A) = K(B)
-			LOADG,			//	A, B		//	load global into register			R(A) = G[K(B)]
-			LOADI,			//	A, B		//	load integer into register			R(A) = I
-			LOADU,			//	A, B		//	load upvalue into register			R(A) = U(B)
-			MOVE,			//	A, B		//	move registers						R(A) = R(B)
-			STORE,			//	A, B, C		//	store A into R(B)[C]				R(B)[C] = R(A)
-			STOREAT,		//	A, B, C		//	store A into R(B)[C]				R(B)[C] = R(A)
-			STOREG,			//	A, B		//	store global						G[K(B)] = R(A)
-			STOREU,			//	A, B		//	store upvalue						U(B) = R(A)
-
-											//	*** JUMP OPERATIONS (3) ***
-			JUMP,			//	A			//	unconditional jump					PC += A
-			JUMPF,			//	A, B		//	jump if R(A) is false				(R(A) == 0)	? PC += B : 0
-			SWITCH,			//				//	switch statement
-
-											//	*** MATH OPERATIONS (19) ***
-			ADD,			//	A, B, C		//	add operation						R(A) = R(B) + R(C)
-			SUB,			//	A, B, C		//	sub operation						R(A) = R(B) - R(C)
-			DIV,			//	A, B, C		//	div operation						R(A) = R(B) / R(C)
-			MUL,			//	A, B, C		//	mul operation						R(A) = R(B) * R(C)
-			REM,			//	A, B, C		//	rem operation						R(A) = R(B) % R(C)
-			AND,			//	A, B, C		//	and operation						R(A) = R(B) && R(C)
-			OR,				//	A, B, C		//	or operation						R(A) = R(B) || R(C)
-			LT,				//	A, B, C		//	< comparison						R(A) = R(B) < R(C)
-			GT,				//	A, B, C		//	> comparison						R(A) = R(B) > R(C)
-			EQ,				//	A, B, C		//	== comparison						R(A) = R(B) == R(C)
-			LEQ,			//	A, B, C		//	<= comparison						R(A) = R(B) <= R(C)
-			GEQ,			//	A, B, C		//	>= comparison						R(A) = R(B) >= R(C)
-			NEQ,			//	A, B, C		//	!= comparison						R(A) = R(B) != R(C)
-			EQQ,			//	A, B, C		//	=== comparison						R(A) = R(B) === R(C)
-			NEQQ,			//	A, B, C		//	!== comparison						R(A) = R(B) !== R(C)
-			ISA,			//	A, B, C		//	isa comparison						R(A) = R(A).class == R(B).class
-			MATCH,			//	A, B, C		//	=~ pattern match					R(A) = R(B) =~ R(C)
-			NEG,			//	A, B		//	neg operation						R(A) = -R(B)
-			NOT,			//	A, B		//	not operation						R(A) = !R(B)
-
-											// *** BIT OPERATIONS (6) ***
-			LSHIFT,			//	A, B, C		// shift left							R(A) = R(B) << R(C)
-			RSHIFT,			//	A, B, C		// shift right							R(A) = R(B) >> R(C)
-			BAND,			//	A, B, C		// bit and								R(A) = R(B) & R(C)
-			BOR,			//	A, B, C		// bit or								R(A) = R(B) | R(C)
-			BXOR,			//	A, B, C		// bit xor								R(A) = R(B) ^ R(C)
-			BNOT,			//	A, B		// bit not								R(A) = ~R(B)
-
-											// *** ARRAY/MAP/RANGE OPERATIONS (4) ***
-			MAPNEW,			//	A, B		//	create a new map					R(A) = Alloc a MAP(B)
-			LISTNEW,		//	A, B		//	create a new array					R(A) = Alloc a LIST(B)
-			RANGENEW,		//	A, B, C, f	//	create a new range					R(A) = Alloc a RANGE(B,C) f flag tells if B inclusive or exclusive
-			SETLIST,		//	A, B, C		//	set list/map items
-
-											// *** CLOSURES (2) ***
-			CLOSURE,		//	A, B		//	create a new closure				R(A) = closure(K(B))
-			CLOSE,			//	A			//  close all upvalues from R(A)
-
-											// *** UNUSED (6) ***
-			RESERVED1,		//				// reserved for future use
-			RESERVED2,		//				// reserved for future use
-			RESERVED3,		//				// reserved for future use
-			RESERVED4,		//				// reserved for future use
-			RESERVED5,		//				// reserved for future use
-			RESERVED6		//				// reserved for future use
+    //      ***********************************************************************************************************
+    //      56 OPCODE INSTRUCTIONS (for a register based virtual machine)
+    //      opcode is a 6 bit value so at maximum 2^6 = 64 opcodes can be declared
+    //      ************************************************************************************************************
+    //
+    //      MNEMONIC        PARAMETERS          DESCRIPTION                                 OPERATION
+    //      --------        ----------          ------------------------------------        ----------------------------
+    //
+                                                //  *** GENERAL COMMANDS (5) ***
+            RET0 = 0,       //  NONE            //  return nothing from a function          MUST BE THE FIRST OPCODE (because an implict 0 is added
+                                                //                                          as a safeguard at the end of any bytecode
+            HALT,           //  NONE            //  stop VM execution
+            NOP,            //  NONE            //  NOP                                     http://en.wikipedia.org/wiki/NOP
+            RET,            //  A               //  return from a function                  R(-1) = R(A)
+            CALL,           //  A, B, C         //  call a function                         R(A) = B(C0...Cn) B is callable object and C is num args
+
+                                                //  *** LOAD/STORE OPERATIONS (11) ***
+            LOAD,           //  A, B, C         //  load C from B and store in A            R(A) = R(B)[C]
+            LOADS,          //  A, B, C         //  load C from B and store in A            R(A) = R(B)[C] (super variant)
+            LOADAT,         //  A, B, C         //  load C from B and store in A            R(A) = R(B)[C]
+            LOADK,          //  A, B            //  load constant into register             R(A) = K(B)
+            LOADG,          //  A, B            //  load global into register               R(A) = G[K(B)]
+            LOADI,          //  A, B            //  load integer into register              R(A) = I
+            LOADU,          //  A, B            //  load upvalue into register              R(A) = U(B)
+            MOVE,           //  A, B            //  move registers                          R(A) = R(B)
+            STORE,          //  A, B, C         //  store A into R(B)[C]                    R(B)[C] = R(A)
+            STOREAT,        //  A, B, C         //  store A into R(B)[C]                    R(B)[C] = R(A)
+            STOREG,         //  A, B            //  store global                            G[K(B)] = R(A)
+            STOREU,         //  A, B            //  store upvalue                           U(B) = R(A)
+
+                                                //  *** JUMP OPERATIONS (3) ***
+            JUMP,           //  A               //  unconditional jump                      PC += A
+            JUMPF,          //  A, B            //  jump if R(A) is false                   (R(A) == 0)    ? PC += B : 0
+            SWITCH,         //                  //  switch statement
+
+                                                //  *** MATH OPERATIONS (19) ***
+            ADD,            //  A, B, C         //  add operation                           R(A) = R(B) + R(C)
+            SUB,            //  A, B, C         //  sub operation                           R(A) = R(B) - R(C)
+            DIV,            //  A, B, C         //  div operation                           R(A) = R(B) / R(C)
+            MUL,            //  A, B, C         //  mul operation                           R(A) = R(B) * R(C)
+            REM,            //  A, B, C         //  rem operation                           R(A) = R(B) % R(C)
+            AND,            //  A, B, C         //  and operation                           R(A) = R(B) && R(C)
+            OR,             //  A, B, C         //  or operation                            R(A) = R(B) || R(C)
+            LT,             //  A, B, C         //  < comparison                            R(A) = R(B) < R(C)
+            GT,             //  A, B, C         //  > comparison                            R(A) = R(B) > R(C)
+            EQ,             //  A, B, C         //  == comparison                           R(A) = R(B) == R(C)
+            LEQ,            //  A, B, C         //  <= comparison                           R(A) = R(B) <= R(C)
+            GEQ,            //  A, B, C         //  >= comparison                           R(A) = R(B) >= R(C)
+            NEQ,            //  A, B, C         //  != comparison                           R(A) = R(B) != R(C)
+            EQQ,            //  A, B, C         //  === comparison                          R(A) = R(B) === R(C)
+            NEQQ,           //  A, B, C         //  !== comparison                          R(A) = R(B) !== R(C)
+            ISA,            //  A, B, C         //  isa comparison                          R(A) = R(A).class == R(B).class
+            MATCH,          //  A, B, C         //  =~ pattern match                        R(A) = R(B) =~ R(C)
+            NEG,            //  A, B            //  neg operation                           R(A) = -R(B)
+            NOT,            //  A, B            //  not operation                           R(A) = !R(B)
+
+                                                //  *** BIT OPERATIONS (6) ***
+            LSHIFT,         //  A, B, C         //  shift left                              R(A) = R(B) << R(C)
+            RSHIFT,         //  A, B, C         //  shift right                             R(A) = R(B) >> R(C)
+            BAND,           //  A, B, C         //  bit and                                 R(A) = R(B) & R(C)
+            BOR,            //  A, B, C         //  bit or                                  R(A) = R(B) | R(C)
+            BXOR,           //  A, B, C         //  bit xor                                 R(A) = R(B) ^ R(C)
+            BNOT,           //  A, B            //  bit not                                 R(A) = ~R(B)
+
+                                                //  *** ARRAY/MAP/RANGE OPERATIONS (4) ***
+            MAPNEW,         //  A, B            //  create a new map                        R(A) = Alloc a MAP(B)
+            LISTNEW,        //  A, B            //  create a new array                      R(A) = Alloc a LIST(B)
+            RANGENEW,       //  A, B, C, f      //  create a new range                      R(A) = Alloc a RANGE(B,C) f flag tells if B inclusive or exclusive
+            SETLIST,        //  A, B, C         //  set list/map items
+
+                                                //  *** CLOSURES (2) ***
+            CLOSURE,        //  A, B            //  create a new closure                    R(A) = closure(K(B))
+            CLOSE,          //  A               //  close all upvalues from R(A)
+
+                                                //  *** UNUSED (6) ***
+            RESERVED1,      //                  //  reserved for future use
+            RESERVED2,      //                  //  reserved for future use
+            RESERVED3,      //                  //  reserved for future use
+            RESERVED4,      //                  //  reserved for future use
+            RESERVED5,      //                  //  reserved for future use
+            RESERVED6       //                  //  reserved for future use
 } opcode_t;
 } opcode_t;
 
 
-#define GRAVITY_LATEST_OPCODE			RESERVED6	// used in some debug code so it is very useful to define the latest opcode here
+#define GRAVITY_LATEST_OPCODE           RESERVED6    // used in some debug code so it is very useful to define the latest opcode here
 
 
 typedef enum {
 typedef enum {
-	GRAVITY_NOTFOUND_INDEX				= 0,
-	GRAVITY_ADD_INDEX,
-	GRAVITY_SUB_INDEX,
-	GRAVITY_DIV_INDEX,
-	GRAVITY_MUL_INDEX,
-	GRAVITY_REM_INDEX,
-	GRAVITY_AND_INDEX,
-	GRAVITY_OR_INDEX,
-	GRAVITY_CMP_INDEX,
-	GRAVITY_EQQ_INDEX,
-	GRAVITY_ISA_INDEX,
-	GRAVITY_MATCH_INDEX,
-	GRAVITY_NEG_INDEX,
-	GRAVITY_NOT_INDEX,
-	GRAVITY_LSHIFT_INDEX,
-	GRAVITY_RSHIFT_INDEX,
-	GRAVITY_BAND_INDEX,
-	GRAVITY_BOR_INDEX,
-	GRAVITY_BXOR_INDEX,
-	GRAVITY_BNOT_INDEX,
-	GRAVITY_LOAD_INDEX,
-	GRAVITY_LOADS_INDEX,
-	GRAVITY_LOADAT_INDEX,
-	GRAVITY_STORE_INDEX,
-	GRAVITY_STOREAT_INDEX,
-	GRAVITY_INT_INDEX,
-	GRAVITY_FLOAT_INDEX,
-	GRAVITY_BOOL_INDEX,
-	GRAVITY_STRING_INDEX,
-	GRAVITY_EXEC_INDEX,
-	GRAVITY_VTABLE_SIZE					// MUST BE LAST ENTRY IN THIS ENUM
+    GRAVITY_NOTFOUND_INDEX              = 0,
+    GRAVITY_ADD_INDEX,
+    GRAVITY_SUB_INDEX,
+    GRAVITY_DIV_INDEX,
+    GRAVITY_MUL_INDEX,
+    GRAVITY_REM_INDEX,
+    GRAVITY_AND_INDEX,
+    GRAVITY_OR_INDEX,
+    GRAVITY_CMP_INDEX,
+    GRAVITY_EQQ_INDEX,
+    GRAVITY_ISA_INDEX,
+    GRAVITY_MATCH_INDEX,
+    GRAVITY_NEG_INDEX,
+    GRAVITY_NOT_INDEX,
+    GRAVITY_LSHIFT_INDEX,
+    GRAVITY_RSHIFT_INDEX,
+    GRAVITY_BAND_INDEX,
+    GRAVITY_BOR_INDEX,
+    GRAVITY_BXOR_INDEX,
+    GRAVITY_BNOT_INDEX,
+    GRAVITY_LOAD_INDEX,
+    GRAVITY_LOADS_INDEX,
+    GRAVITY_LOADAT_INDEX,
+    GRAVITY_STORE_INDEX,
+    GRAVITY_STOREAT_INDEX,
+    GRAVITY_INT_INDEX,
+    GRAVITY_FLOAT_INDEX,
+    GRAVITY_BOOL_INDEX,
+    GRAVITY_STRING_INDEX,
+    GRAVITY_EXEC_INDEX,
+    GRAVITY_VTABLE_SIZE                 // MUST BE LAST ENTRY IN THIS ENUM
 } GRAVITY_VTABLE_INDEX;
 } GRAVITY_VTABLE_INDEX;
 
 
-#define GRAVITY_OPERATOR_ADD_NAME		"+"
-#define GRAVITY_OPERATOR_SUB_NAME		"-"
-#define GRAVITY_OPERATOR_DIV_NAME		"/"
-#define GRAVITY_OPERATOR_MUL_NAME		"*"
-#define GRAVITY_OPERATOR_REM_NAME		"%"
-#define GRAVITY_OPERATOR_AND_NAME		"&&"
-#define GRAVITY_OPERATOR_OR_NAME		"||"
-#define GRAVITY_OPERATOR_CMP_NAME		"=="
-#define GRAVITY_OPERATOR_EQQ_NAME		"==="
+#define GRAVITY_OPERATOR_ADD_NAME       "+"
+#define GRAVITY_OPERATOR_SUB_NAME       "-"
+#define GRAVITY_OPERATOR_DIV_NAME       "/"
+#define GRAVITY_OPERATOR_MUL_NAME       "*"
+#define GRAVITY_OPERATOR_REM_NAME       "%"
+#define GRAVITY_OPERATOR_AND_NAME       "&&"
+#define GRAVITY_OPERATOR_OR_NAME        "||"
+#define GRAVITY_OPERATOR_CMP_NAME       "=="
+#define GRAVITY_OPERATOR_EQQ_NAME       "==="
 #define GRAVITY_OPERATOR_NEQQ_NAME      "!=="
 #define GRAVITY_OPERATOR_NEQQ_NAME      "!=="
-#define GRAVITY_OPERATOR_ISA_NAME		"is"
-#define GRAVITY_OPERATOR_MATCH_NAME		"=~"
-#define GRAVITY_OPERATOR_NEG_NAME		"neg"
-#define GRAVITY_OPERATOR_NOT_NAME		"!"
-#define GRAVITY_OPERATOR_LSHIFT_NAME	"<<"
-#define GRAVITY_OPERATOR_RSHIFT_NAME	">>"
-#define GRAVITY_OPERATOR_BAND_NAME		"&"
-#define GRAVITY_OPERATOR_BOR_NAME		"|"
-#define GRAVITY_OPERATOR_BXOR_NAME		"^"
-#define GRAVITY_OPERATOR_BNOT_NAME		"~"
-#define GRAVITY_INTERNAL_LOAD_NAME		"load"
-#define GRAVITY_INTERNAL_LOADS_NAME		"loads"
-#define GRAVITY_INTERNAL_STORE_NAME		"store"
-#define GRAVITY_INTERNAL_LOADAT_NAME	"loadat"
-#define GRAVITY_INTERNAL_STOREAT_NAME	"storeat"
-#define GRAVITY_INTERNAL_NOTFOUND_NAME	"notfound"
-#define GRAVITY_INTERNAL_EXEC_NAME		"exec"
-#define GRAVITY_INTERNAL_LOOP_NAME		"loop"
-
-#define GRAVITY_CLASS_INT_NAME			"Int"
-#define GRAVITY_CLASS_FLOAT_NAME		"Float"
-#define GRAVITY_CLASS_BOOL_NAME			"Bool"
-#define GRAVITY_CLASS_STRING_NAME		"String"
-#define GRAVITY_CLASS_OBJECT_NAME		"Object"
-#define GRAVITY_CLASS_CLASS_NAME		"Class"
-#define GRAVITY_CLASS_NULL_NAME			"Null"
-#define GRAVITY_CLASS_FUNCTION_NAME		"Function"
-#define GRAVITY_CLASS_FIBER_NAME		"Fiber"
-#define GRAVITY_CLASS_INSTANCE_NAME		"Instance"
-#define GRAVITY_CLASS_CLOSURE_NAME		"Closure"
-#define GRAVITY_CLASS_LIST_NAME			"List"
-#define GRAVITY_CLASS_MAP_NAME			"Map"
-#define GRAVITY_CLASS_RANGE_NAME		"Range"
-#define GRAVITY_CLASS_UPVALUE_NAME		"Upvalue"
-
-#define GRAVITY_CLASS_SYSTEM_NAME		"System"
-#define GRAVITY_SYSTEM_PRINT_NAME		"print"
-#define GRAVITY_SYSTEM_PUT_NAME			"put"
-#define GRAVITY_SYSTEM_NANOTIME_NAME	"nanotime"
+#define GRAVITY_OPERATOR_ISA_NAME       "is"
+#define GRAVITY_OPERATOR_MATCH_NAME     "=~"
+#define GRAVITY_OPERATOR_NEG_NAME       "neg"
+#define GRAVITY_OPERATOR_NOT_NAME        "!"
+#define GRAVITY_OPERATOR_LSHIFT_NAME    "<<"
+#define GRAVITY_OPERATOR_RSHIFT_NAME    ">>"
+#define GRAVITY_OPERATOR_BAND_NAME      "&"
+#define GRAVITY_OPERATOR_BOR_NAME       "|"
+#define GRAVITY_OPERATOR_BXOR_NAME      "^"
+#define GRAVITY_OPERATOR_BNOT_NAME      "~"
+#define GRAVITY_INTERNAL_LOAD_NAME      "load"
+#define GRAVITY_INTERNAL_LOADS_NAME     "loads"
+#define GRAVITY_INTERNAL_STORE_NAME     "store"
+#define GRAVITY_INTERNAL_LOADAT_NAME    "loadat"
+#define GRAVITY_INTERNAL_STOREAT_NAME   "storeat"
+#define GRAVITY_INTERNAL_NOTFOUND_NAME  "notfound"
+#define GRAVITY_INTERNAL_EXEC_NAME      "exec"
+#define GRAVITY_INTERNAL_LOOP_NAME      "loop"
+
+#define GRAVITY_CLASS_INT_NAME          "Int"
+#define GRAVITY_CLASS_FLOAT_NAME        "Float"
+#define GRAVITY_CLASS_BOOL_NAME         "Bool"
+#define GRAVITY_CLASS_STRING_NAME       "String"
+#define GRAVITY_CLASS_OBJECT_NAME       "Object"
+#define GRAVITY_CLASS_CLASS_NAME        "Class"
+#define GRAVITY_CLASS_NULL_NAME         "Null"
+#define GRAVITY_CLASS_FUNCTION_NAME     "Function"
+#define GRAVITY_CLASS_FIBER_NAME        "Fiber"
+#define GRAVITY_CLASS_INSTANCE_NAME     "Instance"
+#define GRAVITY_CLASS_CLOSURE_NAME      "Closure"
+#define GRAVITY_CLASS_LIST_NAME         "List"
+#define GRAVITY_CLASS_MAP_NAME          "Map"
+#define GRAVITY_CLASS_RANGE_NAME        "Range"
+#define GRAVITY_CLASS_UPVALUE_NAME      "Upvalue"
+
+#define GRAVITY_CLASS_SYSTEM_NAME       "System"
+#define GRAVITY_SYSTEM_PRINT_NAME       "print"
+#define GRAVITY_SYSTEM_PUT_NAME         "put"
+#define GRAVITY_SYSTEM_NANOTIME_NAME    "nanotime"
 
 
 #endif
 #endif

File diff suppressed because it is too large
+ 427 - 427
src/shared/gravity_value.c


+ 322 - 322
src/shared/gravity_value.h

@@ -40,54 +40,54 @@
 // Default is to have both int and float as 64bit.
 // Default is to have both int and float as 64bit.
 
 
 // In a 64bit OS:
 // In a 64bit OS:
-// sizeof(float)	=> 4 bytes
-// sizeof(double)	=> 8 bytes
-// sizeof(void*)	=> 8 bytes
-// sizeof(int64_t)	=> 8 bytes
+// sizeof(float)        => 4 bytes
+// sizeof(double)       => 8 bytes
+// sizeof(void*)        => 8 bytes
+// sizeof(int64_t)      => 8 bytes
 //
 //
 // sizeof various structs in a 64bit OS:
 // sizeof various structs in a 64bit OS:
-// STRUCT					BYTES
-// ======					=====
-// gravity_function_t		104
-// gravity_value_t			16
-// gravity_upvalue_t		56
-// gravity_closure_t		40
-// gravity_list_t			48
-// gravity_map_t			32
-// gravity_callframe_t		48
-// gravity_fiber_t			112
-// gravity_class_t			88
-// gravity_module_t			40
-// gravity_instance_t		40
-// gravity_string_t			48
-// gravity_range_t			40
+// STRUCT                       BYTES
+// ======                       =====
+// gravity_function_t           104
+// gravity_value_t              16
+// gravity_upvalue_t            56
+// gravity_closure_t            40
+// gravity_list_t               48
+// gravity_map_t                32
+// gravity_callframe_t          48
+// gravity_fiber_t              112
+// gravity_class_t              88
+// gravity_module_t             40
+// gravity_instance_t           40
+// gravity_string_t             48
+// gravity_range_t              40
 
 
 #ifdef __cplusplus
 #ifdef __cplusplus
 extern "C" {
 extern "C" {
 #endif
 #endif
 
 
-#define GRAVITY_VERSION						"0.5.1"     // git tag 0.5.1
-#define GRAVITY_VERSION_NUMBER				0x000501    // git push --tags
-#define GRAVITY_BUILD_DATE					__DATE__
+#define GRAVITY_VERSION                     "0.5.1"     // git tag 0.5.1
+#define GRAVITY_VERSION_NUMBER              0x000501    // git push --tags
+#define GRAVITY_BUILD_DATE                  __DATE__
 
 
 #ifndef GRAVITY_ENABLE_DOUBLE
 #ifndef GRAVITY_ENABLE_DOUBLE
-#define GRAVITY_ENABLE_DOUBLE				1			// if 1 enable gravity_float_t to be a double (instead of a float)
+#define GRAVITY_ENABLE_DOUBLE               1           // if 1 enable gravity_float_t to be a double (instead of a float)
 #endif
 #endif
 
 
 #ifndef GRAVITY_ENABLE_INT64
 #ifndef GRAVITY_ENABLE_INT64
-#define GRAVITY_ENABLE_INT64				1			// if 1 enable gravity_int_t to be a 64bit int (intead of a 32bit int)
+#define GRAVITY_ENABLE_INT64                1           // if 1 enable gravity_int_t to be a 64bit int (intead of a 32bit int)
 #endif
 #endif
 
 
 #ifndef GRAVITY_COMPUTED_GOTO
 #ifndef GRAVITY_COMPUTED_GOTO
-#define GRAVITY_COMPUTED_GOTO				1			// if 1 enable faster computed goto (instead of switch) for compilers that support it
+#define GRAVITY_COMPUTED_GOTO               1           // if 1 enable faster computed goto (instead of switch) for compilers that support it
 #endif
 #endif
 
 
 #ifndef GRAVITY_NULL_SILENT
 #ifndef GRAVITY_NULL_SILENT
-#define GRAVITY_NULL_SILENT					1			// if 1 then messages sent to null does not produce any runtime error
+#define GRAVITY_NULL_SILENT                 1           // if 1 then messages sent to null does not produce any runtime error
 #endif
 #endif
 
 
 #ifndef GRAVITY_MAP_DOTSUGAR
 #ifndef GRAVITY_MAP_DOTSUGAR
-#define GRAVITY_MAP_DOTSUGAR				1			// if 1 then map objects can be accessed with both map[key] and map.key
+#define GRAVITY_MAP_DOTSUGAR                1           // if 1 then map objects can be accessed with both map[key] and map.key
 #endif
 #endif
 
 
 #ifdef _MSC_VER
 #ifdef _MSC_VER
@@ -95,103 +95,103 @@ extern "C" {
 #define GRAVITY_COMPUTED_GOTO               0           // MSVC does not support it
 #define GRAVITY_COMPUTED_GOTO               0           // MSVC does not support it
 #endif
 #endif
 
 
-#define MAIN_FUNCTION						"main"
-#define ITERATOR_INIT_FUNCTION				"iterate"
-#define ITERATOR_NEXT_FUNCTION				"next"
-#define INITMODULE_NAME						"$moduleinit"
-#define CLASS_INTERNAL_INIT_NAME			"$init"
-#define CLASS_CONSTRUCTOR_NAME				"init"
-#define CLASS_DESTRUCTOR_NAME				"deinit"
-#define SELF_PARAMETER_NAME					"self"
-#define OUTER_IVAR_NAME						"outer"
-#define GETTER_FUNCTION_NAME				"get"
-#define SETTER_FUNCTION_NAME				"set"
-#define SETTER_PARAMETER_NAME				"value"
-
-#define GLOBALS_DEFAULT_SLOT				4096
-#define	CPOOL_INDEX_MAX						4096		// 2^12
-#define CPOOL_VALUE_SUPER					CPOOL_INDEX_MAX+1
-#define CPOOL_VALUE_NULL					CPOOL_INDEX_MAX+2
-#define CPOOL_VALUE_UNDEFINED				CPOOL_INDEX_MAX+3
-#define CPOOL_VALUE_ARGUMENTS				CPOOL_INDEX_MAX+4
-#define CPOOL_VALUE_TRUE					CPOOL_INDEX_MAX+5
-#define CPOOL_VALUE_FALSE					CPOOL_INDEX_MAX+6
-#define CPOOL_VALUE_FUNC					CPOOL_INDEX_MAX+7
-
-#define MAX_INSTRUCTION_OPCODE				64			// 2^6
-#define MAX_REGISTERS						256			// 2^8
-#define MAX_LOCALS							200			// maximum number of local variables
-#define MAX_UPVALUES						200			// maximum number of upvalues
-#define MAX_INLINE_INT						131072		// 32 - 6 (OPCODE) - 8 (register) - 1 bit sign = 17
-#define MAX_FIELDSxFLUSH					64			// used in list/map serialization
-#define MAX_IVARS							768			// 2^10 - 2^8
-#define MAX_ALLOCATION                      4194304     // 1024 * 1024 * 4 (about 4 millions entry)
-#define MAX_CCALLS                          100         // default maximum number of nested C calls
-#define MAX_MEMORY_BLOCK                    157286400   // 150MB
-
-#define DEFAULT_CONTEXT_SIZE				256			// default VM context entries (can grow)
-#define DEFAULT_MINSTRING_SIZE				32			// minimum string allocation size
-#define DEFAULT_MINSTACK_SIZE				256			// sizeof(gravity_value_t) * 256	 = 16 * 256 => 4 KB
-#define DEFAULT_MINCFRAME_SIZE				32			// sizeof(gravity_callframe_t) * 48  = 32 * 48 => 1.5 KB
-#define DEFAULT_CG_THRESHOLD				5*1024*1024 // 5MB
-#define DEFAULT_CG_MINTHRESHOLD				1024*1024	// 1MB
-#define DEFAULT_CG_RATIO					0.5			// 50%
-
-#define MAXNUM(a,b)							((a) > (b) ? a : b)
-#define MINNUM(a,b)							((a) < (b) ? a : b)
-#define EPSILON								0.000001
-#define MIN_LIST_RESIZE                     12          // value used when a List is resized
-
-#define GRAVITY_DATA_REGISTER				UINT32_MAX
-#define GRAVITY_FIBER_REGISTER				UINT32_MAX-1
-#define GRAVITY_MSG_REGISTER				UINT32_MAX-2
-
-#define GRAVITY_BRIDGE_INDEX				UINT16_MAX
-#define GRAVITY_COMPUTED_INDEX				UINT16_MAX-1
+#define MAIN_FUNCTION                       "main"
+#define ITERATOR_INIT_FUNCTION              "iterate"
+#define ITERATOR_NEXT_FUNCTION              "next"
+#define INITMODULE_NAME                     "$moduleinit"
+#define CLASS_INTERNAL_INIT_NAME            "$init"
+#define CLASS_CONSTRUCTOR_NAME              "init"
+#define CLASS_DESTRUCTOR_NAME               "deinit"
+#define SELF_PARAMETER_NAME                 "self"
+#define OUTER_IVAR_NAME                     "outer"
+#define GETTER_FUNCTION_NAME                "get"
+#define SETTER_FUNCTION_NAME                "set"
+#define SETTER_PARAMETER_NAME               "value"
+
+#define GLOBALS_DEFAULT_SLOT                4096
+#define CPOOL_INDEX_MAX                     4096        // 2^12
+#define CPOOL_VALUE_SUPER                   CPOOL_INDEX_MAX+1
+#define CPOOL_VALUE_NULL                    CPOOL_INDEX_MAX+2
+#define CPOOL_VALUE_UNDEFINED               CPOOL_INDEX_MAX+3
+#define CPOOL_VALUE_ARGUMENTS               CPOOL_INDEX_MAX+4
+#define CPOOL_VALUE_TRUE                    CPOOL_INDEX_MAX+5
+#define CPOOL_VALUE_FALSE                   CPOOL_INDEX_MAX+6
+#define CPOOL_VALUE_FUNC                    CPOOL_INDEX_MAX+7
+
+#define MAX_INSTRUCTION_OPCODE              64              // 2^6
+#define MAX_REGISTERS                       256             // 2^8
+#define MAX_LOCALS                          200             // maximum number of local variables
+#define MAX_UPVALUES                        200             // maximum number of upvalues
+#define MAX_INLINE_INT                      131072          // 32 - 6 (OPCODE) - 8 (register) - 1 bit sign = 17
+#define MAX_FIELDSxFLUSH                    64              // used in list/map serialization
+#define MAX_IVARS                           768             // 2^10 - 2^8
+#define MAX_ALLOCATION                      4194304         // 1024 * 1024 * 4 (about 4 millions entry)
+#define MAX_CCALLS                          100             // default maximum number of nested C calls
+#define MAX_MEMORY_BLOCK                    157286400       // 150MB
+
+#define DEFAULT_CONTEXT_SIZE                256             // default VM context entries (can grow)
+#define DEFAULT_MINSTRING_SIZE              32              // minimum string allocation size
+#define DEFAULT_MINSTACK_SIZE               256             // sizeof(gravity_value_t) * 256     = 16 * 256 => 4 KB
+#define DEFAULT_MINCFRAME_SIZE              32              // sizeof(gravity_callframe_t) * 48  = 32 * 48 => 1.5 KB
+#define DEFAULT_CG_THRESHOLD                5*1024*1024     // 5MB
+#define DEFAULT_CG_MINTHRESHOLD             1024*1024       // 1MB
+#define DEFAULT_CG_RATIO                    0.5             // 50%
+
+#define MAXNUM(a,b)                         ((a) > (b) ? a : b)
+#define MINNUM(a,b)                         ((a) < (b) ? a : b)
+#define EPSILON                             0.000001
+#define MIN_LIST_RESIZE                     12              // value used when a List is resized
+
+#define GRAVITY_DATA_REGISTER               UINT32_MAX
+#define GRAVITY_FIBER_REGISTER              UINT32_MAX-1
+#define GRAVITY_MSG_REGISTER                UINT32_MAX-2
+
+#define GRAVITY_BRIDGE_INDEX                UINT16_MAX
+#define GRAVITY_COMPUTED_INDEX              UINT16_MAX-1
 
 
 //DLL export/import support for Windows.
 //DLL export/import support for Windows.
 #ifdef _WIN32
 #ifdef _WIN32
-	#ifdef BUILD_GRAVITY_API
-		#define GRAVITY_API __declspec(dllexport)
-	#else
-		#define GRAVITY_API __declspec(dllimport)
-	#endif
+    #ifdef BUILD_GRAVITY_API
+        #define GRAVITY_API __declspec(dllexport)
+    #else
+        #define GRAVITY_API __declspec(dllimport)
+    #endif
 #else
 #else
-	#define GRAVITY_API
+    #define GRAVITY_API
 #endif
 #endif
 
 
 // MARK: - STRUCT -
 // MARK: - STRUCT -
 
 
 #if GRAVITY_ENABLE_DOUBLE
 #if GRAVITY_ENABLE_DOUBLE
-typedef double								gravity_float_t;
+typedef double                              gravity_float_t;
 #define FLOAT_MAX                           DBL_MAX
 #define FLOAT_MAX                           DBL_MAX
 #define FLOAT_MIN                           DBL_MIN
 #define FLOAT_MIN                           DBL_MIN
 #define FLOAT_EPSILON                       0.00001
 #define FLOAT_EPSILON                       0.00001
 #else
 #else
-typedef float								gravity_float_t;
+typedef float                               gravity_float_t;
 #define FLOAT_MAX                           FLT_MAX
 #define FLOAT_MAX                           FLT_MAX
 #define FLOAT_MIN                           FLT_MIN
 #define FLOAT_MIN                           FLT_MIN
 #define FLOAT_EPSILON                       0.00001
 #define FLOAT_EPSILON                       0.00001
 #endif
 #endif
 
 
 #if GRAVITY_ENABLE_INT64
 #if GRAVITY_ENABLE_INT64
-typedef int64_t								gravity_int_t;
+typedef int64_t                             gravity_int_t;
 #else
 #else
-typedef int32_t								gravity_int_t;
+typedef int32_t                             gravity_int_t;
 #endif
 #endif
 
 
 // Forward references (an object ptr is just its isa pointer)
 // Forward references (an object ptr is just its isa pointer)
-typedef struct gravity_class_s				gravity_class_t;
-typedef struct gravity_class_s				gravity_object_t;
+typedef struct gravity_class_s              gravity_class_t;
+typedef struct gravity_class_s              gravity_object_t;
 
 
 // Everything inside Gravity VM is a gravity_value_t struct
 // Everything inside Gravity VM is a gravity_value_t struct
 typedef struct {
 typedef struct {
-	gravity_class_t			*isa;			// EVERY object must have an ISA pointer (8 bytes on a 64bit system)
-	union {									// union takes 8 bytes on a 64bit system
-		gravity_int_t		n;				// integer slot
-		gravity_float_t		f;				// float/double slot
-		gravity_object_t	*p;				// ptr to object slot
-	};
+    gravity_class_t         *isa;           // EVERY object must have an ISA pointer (8 bytes on a 64bit system)
+    union {                                 // union takes 8 bytes on a 64bit system
+        gravity_int_t       n;              // integer slot
+        gravity_float_t     f;              // float/double slot
+        gravity_object_t    *p;             // ptr to object slot
+    };
 } gravity_value_t;
 } gravity_value_t;
 
 
 // All VM shares the same foundation classes
 // All VM shares the same foundation classes
@@ -212,111 +212,111 @@ extern gravity_class_t *gravity_class_module;
 extern gravity_class_t *gravity_class_range;
 extern gravity_class_t *gravity_class_range;
 extern gravity_class_t *gravity_class_upvalue;
 extern gravity_class_t *gravity_class_upvalue;
 
 
-typedef marray_t(gravity_value_t)		gravity_value_r;		// array of values
+typedef marray_t(gravity_value_t)        gravity_value_r;   // array of values
 #ifndef GRAVITY_HASH_DEFINED
 #ifndef GRAVITY_HASH_DEFINED
 #define GRAVITY_HASH_DEFINED
 #define GRAVITY_HASH_DEFINED
-typedef struct gravity_hash_t			gravity_hash_t;			// forward declaration
+typedef struct gravity_hash_t            gravity_hash_t;    // forward declaration
 #endif
 #endif
 
 
 #ifndef GRAVITY_VM_DEFINED
 #ifndef GRAVITY_VM_DEFINED
 #define GRAVITY_VM_DEFINED
 #define GRAVITY_VM_DEFINED
-typedef struct gravity_vm				gravity_vm;				// vm is an opaque data type
+typedef struct gravity_vm                gravity_vm;        // vm is an opaque data type
 #endif
 #endif
 
 
 typedef bool (*gravity_c_internal)(gravity_vm *vm, gravity_value_t *args, uint16_t nargs, uint32_t rindex);
 typedef bool (*gravity_c_internal)(gravity_vm *vm, gravity_value_t *args, uint16_t nargs, uint32_t rindex);
 
 
 typedef enum {
 typedef enum {
-	EXEC_TYPE_SPECIAL_GETTER = 0,				// index inside special gravity_function_t union to represent getter func
-	EXEC_TYPE_SPECIAL_SETTER = 1,				// index inside special gravity_function_t union to represent setter func
+    EXEC_TYPE_SPECIAL_GETTER = 0,       // index inside special gravity_function_t union to represent getter func
+    EXEC_TYPE_SPECIAL_SETTER = 1,       // index inside special gravity_function_t union to represent setter func
 } gravity_special_index;
 } gravity_special_index;
 
 
 typedef enum {
 typedef enum {
-	EXEC_TYPE_NATIVE,							// native gravity code (can change stack)
-	EXEC_TYPE_INTERNAL,							// c internal code (can change stack)
-	EXEC_TYPE_BRIDGED,							// external code to be executed by delegate (can change stack)
-	EXEC_TYPE_SPECIAL							// special execution like getter and setter (can be NATIVE, INTERNAL)
+    EXEC_TYPE_NATIVE,           // native gravity code (can change stack)
+    EXEC_TYPE_INTERNAL,         // c internal code (can change stack)
+    EXEC_TYPE_BRIDGED,          // external code to be executed by delegate (can change stack)
+    EXEC_TYPE_SPECIAL           // special execution like getter and setter (can be NATIVE, INTERNAL)
 } gravity_exec_type;
 } gravity_exec_type;
 
 
 typedef struct {
 typedef struct {
-	bool					isdark;				// flag to check if object is reachable
-	gravity_object_t		*next;				// to track next object in the linked list
+    bool                    isdark;         // flag to check if object is reachable
+    gravity_object_t        *next;          // to track next object in the linked list
 } gravity_gc_t;
 } gravity_gc_t;
 
 
 typedef struct {
 typedef struct {
-	gravity_class_t			*isa;				// to be an object
-	gravity_gc_t			gc;					// to be collectable by the garbage collector
-
-	void					*xdata;				// extra bridged data
-	const char				*identifier;		// function name
-	uint16_t				nparams;			// number of formal parameters
-	uint16_t				nlocals;			// number of local variables
-	uint16_t				ntemps;				// number of temporary values used
-	uint16_t				nupvalues;			// number of up values (if any)
-	gravity_exec_type		tag;				// can be EXEC_TYPE_NATIVE (default), EXEC_TYPE_INTERNAL, EXEC_TYPE_BRIDGED or EXEC_TYPE_SPECIAL
-	union {
-		// tag == EXEC_TYPE_NATIVE
-		struct {
-			gravity_value_r	cpool;				// constant pool
-            gravity_value_r pvalue;             // default param value
-            gravity_value_r pname;              // param names
-			uint32_t		ninsts;				// number of instructions in the bytecode
-			uint32_t		*bytecode;			// bytecode as array of 32bit values
-			float			purity;				// experimental value
-			bool			useargs;			// flag set by the compiler to optimize the creation of the arguments array only if needed
-		};
-
-		// tag == EXEC_TYPE_INTERNAL
-		gravity_c_internal	internal;			// function callback
-
-		// tag == EXEC_TYPE_SPECIAL
-		struct {
-			uint16_t		index;				// property index to speed-up default getter and setter
-			void			*special[2];		// getter/setter functions
-		};
-	};
+    gravity_class_t         *isa;           // to be an object
+    gravity_gc_t            gc;             // to be collectable by the garbage collector
+
+    void                    *xdata;         // extra bridged data
+    const char              *identifier;    // function name
+    uint16_t                nparams;        // number of formal parameters
+    uint16_t                nlocals;        // number of local variables
+    uint16_t                ntemps;         // number of temporary values used
+    uint16_t                nupvalues;      // number of up values (if any)
+    gravity_exec_type       tag;            // can be EXEC_TYPE_NATIVE (default), EXEC_TYPE_INTERNAL, EXEC_TYPE_BRIDGED or EXEC_TYPE_SPECIAL
+    union {
+        // tag == EXEC_TYPE_NATIVE
+        struct {
+            gravity_value_r cpool;          // constant pool
+            gravity_value_r pvalue;         // default param value
+            gravity_value_r pname;          // param names
+            uint32_t        ninsts;         // number of instructions in the bytecode
+            uint32_t        *bytecode;      // bytecode as array of 32bit values
+            float           purity;         // experimental value
+            bool            useargs;        // flag set by the compiler to optimize the creation of the arguments array only if needed
+        };
+
+        // tag == EXEC_TYPE_INTERNAL
+        gravity_c_internal  internal;       // function callback
+
+        // tag == EXEC_TYPE_SPECIAL
+        struct {
+            uint16_t        index;          // property index to speed-up default getter and setter
+            void            *special[2];    // getter/setter functions
+        };
+    };
 } gravity_function_t;
 } gravity_function_t;
 
 
 typedef struct upvalue_s {
 typedef struct upvalue_s {
-	gravity_class_t			*isa;				// to be an object
-	gravity_gc_t			gc;					// to be collectable by the garbage collector
-
-	gravity_value_t			*value;				// ptr to open value on the stack or to closed value on this struct
-	gravity_value_t			closed;				// copy of the value once has been closed
-	struct upvalue_s		*next;				// ptr to the next open upvalue
+    gravity_class_t         *isa;           // to be an object
+    gravity_gc_t            gc;             // to be collectable by the garbage collector
+    
+    gravity_value_t         *value;         // ptr to open value on the stack or to closed value on this struct
+    gravity_value_t         closed;         // copy of the value once has been closed
+    struct upvalue_s        *next;          // ptr to the next open upvalue
 } gravity_upvalue_t;
 } gravity_upvalue_t;
 
 
 typedef struct {
 typedef struct {
-	gravity_class_t			*isa;				// to be an object
-	gravity_gc_t			gc;					// to be collectable by the garbage collector
+    gravity_class_t         *isa;           // to be an object
+    gravity_gc_t            gc;             // to be collectable by the garbage collector
 
 
-	gravity_function_t		*f;					// function prototype
-    gravity_object_t        *context;           // context where the closure has been created (or object bound by the user)
-	gravity_upvalue_t		**upvalue;			// upvalue array
+    gravity_function_t      *f;             // function prototype
+    gravity_object_t        *context;       // context where the closure has been created (or object bound by the user)
+    gravity_upvalue_t       **upvalue;      // upvalue array
 } gravity_closure_t;
 } gravity_closure_t;
 
 
 typedef struct {
 typedef struct {
-	gravity_class_t			*isa;				// to be an object
-	gravity_gc_t			gc;					// to be collectable by the garbage collector
+    gravity_class_t         *isa;           // to be an object
+    gravity_gc_t            gc;             // to be collectable by the garbage collector
 
 
-	gravity_value_r			array;				// dinamic array of values
+    gravity_value_r         array;          // dinamic array of values
 } gravity_list_t;
 } gravity_list_t;
 
 
 typedef struct {
 typedef struct {
-	gravity_class_t			*isa;				// to be an object
-	gravity_gc_t			gc;					// to be collectable by the garbage collector
+    gravity_class_t         *isa;           // to be an object
+    gravity_gc_t            gc;             // to be collectable by the garbage collector
 
 
-	gravity_hash_t			*hash;				// hash table
+    gravity_hash_t          *hash;          // hash table
 } gravity_map_t;
 } gravity_map_t;
 
 
 // Call frame used for function call
 // Call frame used for function call
 typedef struct {
 typedef struct {
-	uint32_t				*ip;				// instruction pointer
-	uint32_t				dest;				// destination register that will receive result
-	uint16_t				nargs;				// number of effective arguments passed to the function
-	gravity_list_t			*args;				// implicit special _args array
-	gravity_closure_t		*closure;			// closure being executed
-	gravity_value_t			*stackstart;		// first stack slot used by this call frame (receiver, plus parameters, locals and temporaries)
-	bool					outloop;			// special case for events or native code executed from C that must be executed separately
+    uint32_t                *ip;            // instruction pointer
+    uint32_t                dest;           // destination register that will receive result
+    uint16_t                nargs;          // number of effective arguments passed to the function
+    gravity_list_t          *args;          // implicit special _args array
+    gravity_closure_t       *closure;       // closure being executed
+    gravity_value_t         *stackstart;    // first stack slot used by this call frame (receiver, plus parameters, locals and temporaries)
+    bool                    outloop;        // special case for events or native code executed from C that must be executed separately
 } gravity_callframe_t;
 } gravity_callframe_t;
 
 
 typedef enum {
 typedef enum {
@@ -329,223 +329,223 @@ typedef enum {
     
     
 // Fiber is the core executable model
 // Fiber is the core executable model
 typedef struct fiber_s {
 typedef struct fiber_s {
-	gravity_class_t			*isa;				// to be an object
-	gravity_gc_t			gc;					// to be collectable by the garbage collector
+    gravity_class_t         *isa;           // to be an object
+    gravity_gc_t            gc;             // to be collectable by the garbage collector
 
 
-	gravity_value_t			*stack;				// stack buffer (grown as needed and it holds locals and temps)
-	gravity_value_t			*stacktop;			// current stack ptr
-	uint32_t				stackalloc;			// number of allocated values
+    gravity_value_t         *stack;         // stack buffer (grown as needed and it holds locals and temps)
+    gravity_value_t         *stacktop;      // current stack ptr
+    uint32_t                stackalloc;     // number of allocated values
 
 
-	gravity_callframe_t		*frames;			// callframes buffer (grown as needed but never shrinks)
-	uint32_t				nframes;			// number of frames currently in use
-	uint32_t				framesalloc;		// number of allocated frames
+    gravity_callframe_t     *frames;        // callframes buffer (grown as needed but never shrinks)
+    uint32_t                nframes;        // number of frames currently in use
+    uint32_t                framesalloc;    // number of allocated frames
 
 
-	gravity_upvalue_t		*upvalues;			// linked list used to keep track of open upvalues
+    gravity_upvalue_t       *upvalues;      // linked list used to keep track of open upvalues
 
 
-	char					*error;				// runtime error message
-	bool					trying;				// set when the try flag is set by the user
-	struct fiber_s			*caller;			// optional caller fiber
-	gravity_value_t			result;				// end result of the fiber
+    char                    *error;         // runtime error message
+    bool                    trying;         // set when the try flag is set by the user
+    struct fiber_s          *caller;        // optional caller fiber
+    gravity_value_t         result;         // end result of the fiber
     
     
-    gravity_fiber_status    status;             // Fiber status (see enum)
-    nanotime_t              lasttime;           // last time Fiber has been called
-    gravity_float_t         timewait;           // used in yieldTime
-    gravity_float_t         elapsedtime;        // time passed since last execution
+    gravity_fiber_status    status;         // Fiber status (see enum)
+    nanotime_t              lasttime;       // last time Fiber has been called
+    gravity_float_t         timewait;       // used in yieldTime
+    gravity_float_t         elapsedtime;    // time passed since last execution
 } gravity_fiber_t;
 } gravity_fiber_t;
 
 
 typedef struct gravity_class_s {
 typedef struct gravity_class_s {
-	gravity_class_t			*isa;				// to be an object
-	gravity_gc_t			gc;					// to be collectable by the garbage collector
-
-	gravity_class_t			*objclass;			// meta class
-	const char				*identifier;		// class name
-	bool					has_outer;			// flag used to automatically set ivar 0 to outer class (if any)
-	bool					is_struct;			// flag to mark class as a struct
-	bool					is_inited;			// flag used to mark already init meta-classes (to be improved)
-	bool					unused;				// unused padding byte
-	void					*xdata;				// extra bridged data
-	struct gravity_class_s	*superclass;		// reference to the super class
-	gravity_hash_t			*htable;			// hash table
-	uint32_t				nivars;				// number of instance variables
-	//cstring_r				debug;				// ivar index to name debug info
-	gravity_value_t			*ivars;				// static variables
+    gravity_class_t         *isa;           // to be an object
+    gravity_gc_t            gc;             // to be collectable by the garbage collector
+
+    gravity_class_t         *objclass;      // meta class
+    const char              *identifier;    // class name
+    bool                    has_outer;      // flag used to automatically set ivar 0 to outer class (if any)
+    bool                    is_struct;      // flag to mark class as a struct
+    bool                    is_inited;      // flag used to mark already init meta-classes (to be improved)
+    bool                    unused;         // unused padding byte
+    void                    *xdata;         // extra bridged data
+    struct gravity_class_s  *superclass;    // reference to the super class
+    gravity_hash_t          *htable;        // hash table
+    uint32_t                nivars;         // number of instance variables
+    //cstring_r             debug;          // ivar index to name debug info
+    gravity_value_t         *ivars;         // static variables
 } gravity_class_s;
 } gravity_class_s;
 
 
 typedef struct {
 typedef struct {
-	gravity_class_t			*isa;				// to be an object
-	gravity_gc_t			gc;					// to be collectable by the garbage collector
+    gravity_class_t         *isa;           // to be an object
+    gravity_gc_t            gc;             // to be collectable by the garbage collector
 
 
-	const char				*identifier;		// module name
-	gravity_hash_t			*htable;			// hash table
+    const char              *identifier;    // module name
+    gravity_hash_t          *htable;        // hash table
 } gravity_module_t;
 } gravity_module_t;
 
 
 typedef struct {
 typedef struct {
-	gravity_class_t			*isa;				// to be an object
-	gravity_gc_t			gc;					// to be collectable by the garbage collector
+    gravity_class_t         *isa;           // to be an object
+    gravity_gc_t            gc;             // to be collectable by the garbage collector
 
 
-	gravity_class_t			*objclass;			// real instance class
-	void					*xdata;				// extra bridged data
-	gravity_value_t			*ivars;			    // instance variables
+    gravity_class_t         *objclass;      // real instance class
+    void                    *xdata;         // extra bridged data
+    gravity_value_t         *ivars;         // instance variables
 } gravity_instance_t;
 } gravity_instance_t;
 
 
 typedef struct {
 typedef struct {
-	gravity_class_t			*isa;				// to be an object
-	gravity_gc_t			gc;					// to be collectable by the garbage collector
+    gravity_class_t         *isa;           // to be an object
+    gravity_gc_t            gc;             // to be collectable by the garbage collector
 
 
-	char					*s;					// pointer to NULL terminated string
-	uint32_t				hash;				// string hash (type to be keeped in sync with gravity_hash_size_t)
-	uint32_t				len;				// actual string length
-	uint32_t				alloc;				// bytes allocated for string
+    char                    *s;             // pointer to NULL terminated string
+    uint32_t                hash;           // string hash (type to be keeped in sync with gravity_hash_size_t)
+    uint32_t                len;            // actual string length
+    uint32_t                alloc;          // bytes allocated for string
 } gravity_string_t;
 } gravity_string_t;
 
 
 typedef struct {
 typedef struct {
-	gravity_class_t			*isa;				// to be an object
-	gravity_gc_t			gc;					// to be collectable by the garbage collector
+    gravity_class_t         *isa;           // to be an object
+    gravity_gc_t            gc;             // to be collectable by the garbage collector
 
 
-	gravity_int_t			from;				// range start
-	gravity_int_t			to;					// range end
+    gravity_int_t           from;           // range start
+    gravity_int_t           to;             // range end
 } gravity_range_t;
 } gravity_range_t;
 
 
 typedef void (*code_dump_function) (void *code);
 typedef void (*code_dump_function) (void *code);
-typedef marray_t(gravity_function_t*)		gravity_function_r;		// array of functions
-typedef marray_t(gravity_class_t*)			gravity_class_r;		// array of classes
-typedef marray_t(gravity_object_t*)			gravity_object_r;		// array of objects
+typedef marray_t(gravity_function_t*)   gravity_function_r;     // array of functions
+typedef marray_t(gravity_class_t*)      gravity_class_r;        // array of classes
+typedef marray_t(gravity_object_t*)     gravity_object_r;       // array of objects
 
 
 // MARK: - MODULE -
 // MARK: - MODULE -
-GRAVITY_API gravity_module_t	*gravity_module_new (gravity_vm *vm, const char *identifier);
-GRAVITY_API void				gravity_module_free (gravity_vm *vm, gravity_module_t *m);
-GRAVITY_API void				gravity_module_blacken (gravity_vm *vm, gravity_module_t *m);
-GRAVITY_API uint32_t			gravity_module_size (gravity_vm *vm, gravity_module_t *m);
+GRAVITY_API gravity_module_t    *gravity_module_new (gravity_vm *vm, const char *identifier);
+GRAVITY_API void                gravity_module_free (gravity_vm *vm, gravity_module_t *m);
+GRAVITY_API void                gravity_module_blacken (gravity_vm *vm, gravity_module_t *m);
+GRAVITY_API uint32_t            gravity_module_size (gravity_vm *vm, gravity_module_t *m);
 
 
 // MARK: - FUNCTION -
 // MARK: - FUNCTION -
-GRAVITY_API gravity_function_t	*gravity_function_new (gravity_vm *vm, const char *identifier, uint16_t nparams, uint16_t nlocals, uint16_t ntemps, void *code);
-GRAVITY_API gravity_function_t	*gravity_function_new_internal (gravity_vm *vm, const char *identifier, gravity_c_internal exec, uint16_t nparams);
-GRAVITY_API gravity_function_t	*gravity_function_new_special (gravity_vm *vm, const char *identifier, uint16_t index, void *getter, void *setter);
-GRAVITY_API gravity_function_t	*gravity_function_new_bridged (gravity_vm *vm, const char *identifier, void *xdata);
-GRAVITY_API uint16_t			gravity_function_cpool_add (gravity_vm *vm, gravity_function_t *f, gravity_value_t v);
-GRAVITY_API gravity_value_t		gravity_function_cpool_get (gravity_function_t *f, uint16_t i);
-GRAVITY_API void				gravity_function_dump (gravity_function_t *f, code_dump_function codef);
-GRAVITY_API void				gravity_function_setouter (gravity_function_t *f, gravity_object_t *outer);
-GRAVITY_API void				gravity_function_setxdata (gravity_function_t *f, void *xdata);
-GRAVITY_API void				gravity_function_serialize (gravity_function_t *f, json_t *json);
-GRAVITY_API uint32_t			*gravity_bytecode_deserialize (const char *buffer, size_t len, uint32_t *ninst);
-GRAVITY_API gravity_function_t	*gravity_function_deserialize (gravity_vm *vm, json_value *json);
-GRAVITY_API void				gravity_function_free (gravity_vm *vm, gravity_function_t *f);
-GRAVITY_API void				gravity_function_blacken (gravity_vm *vm, gravity_function_t *f);
-GRAVITY_API uint32_t			gravity_function_size (gravity_vm *vm, gravity_function_t *f);
+GRAVITY_API gravity_function_t  *gravity_function_new (gravity_vm *vm, const char *identifier, uint16_t nparams, uint16_t nlocals, uint16_t ntemps, void *code);
+GRAVITY_API gravity_function_t  *gravity_function_new_internal (gravity_vm *vm, const char *identifier, gravity_c_internal exec, uint16_t nparams);
+GRAVITY_API gravity_function_t  *gravity_function_new_special (gravity_vm *vm, const char *identifier, uint16_t index, void *getter, void *setter);
+GRAVITY_API gravity_function_t  *gravity_function_new_bridged (gravity_vm *vm, const char *identifier, void *xdata);
+GRAVITY_API uint16_t            gravity_function_cpool_add (gravity_vm *vm, gravity_function_t *f, gravity_value_t v);
+GRAVITY_API gravity_value_t     gravity_function_cpool_get (gravity_function_t *f, uint16_t i);
+GRAVITY_API void                gravity_function_dump (gravity_function_t *f, code_dump_function codef);
+GRAVITY_API void                gravity_function_setouter (gravity_function_t *f, gravity_object_t *outer);
+GRAVITY_API void                gravity_function_setxdata (gravity_function_t *f, void *xdata);
+GRAVITY_API void                gravity_function_serialize (gravity_function_t *f, json_t *json);
+GRAVITY_API uint32_t            *gravity_bytecode_deserialize (const char *buffer, size_t len, uint32_t *ninst);
+GRAVITY_API gravity_function_t  *gravity_function_deserialize (gravity_vm *vm, json_value *json);
+GRAVITY_API void                gravity_function_free (gravity_vm *vm, gravity_function_t *f);
+GRAVITY_API void                gravity_function_blacken (gravity_vm *vm, gravity_function_t *f);
+GRAVITY_API uint32_t            gravity_function_size (gravity_vm *vm, gravity_function_t *f);
 
 
 // MARK: - CLOSURE -
 // MARK: - CLOSURE -
-GRAVITY_API gravity_closure_t	*gravity_closure_new (gravity_vm *vm, gravity_function_t *f);
-GRAVITY_API void				gravity_closure_free (gravity_vm *vm, gravity_closure_t *closure);
-GRAVITY_API uint32_t			gravity_closure_size (gravity_vm *vm, gravity_closure_t *closure);
-GRAVITY_API void				gravity_closure_blacken (gravity_vm *vm, gravity_closure_t *closure);
+GRAVITY_API gravity_closure_t   *gravity_closure_new (gravity_vm *vm, gravity_function_t *f);
+GRAVITY_API void                gravity_closure_free (gravity_vm *vm, gravity_closure_t *closure);
+GRAVITY_API uint32_t            gravity_closure_size (gravity_vm *vm, gravity_closure_t *closure);
+GRAVITY_API void                gravity_closure_blacken (gravity_vm *vm, gravity_closure_t *closure);
 
 
 // MARK: - UPVALUE -
 // MARK: - UPVALUE -
-GRAVITY_API gravity_upvalue_t	*gravity_upvalue_new (gravity_vm *vm, gravity_value_t *value);
-GRAVITY_API uint32_t			gravity_upvalue_size (gravity_vm *vm, gravity_upvalue_t *upvalue);
-GRAVITY_API void				gravity_upvalue_blacken (gravity_vm *vm, gravity_upvalue_t *upvalue);
-GRAVITY_API void				gravity_upvalue_free(gravity_vm *vm, gravity_upvalue_t *upvalue);
+GRAVITY_API gravity_upvalue_t    *gravity_upvalue_new (gravity_vm *vm, gravity_value_t *value);
+GRAVITY_API uint32_t            gravity_upvalue_size (gravity_vm *vm, gravity_upvalue_t *upvalue);
+GRAVITY_API void                gravity_upvalue_blacken (gravity_vm *vm, gravity_upvalue_t *upvalue);
+GRAVITY_API void                gravity_upvalue_free(gravity_vm *vm, gravity_upvalue_t *upvalue);
 
 
 // MARK: - CLASS -
 // MARK: - CLASS -
-GRAVITY_API void				gravity_class_bind (gravity_class_t *c, const char *key, gravity_value_t value);
-GRAVITY_API gravity_class_t		*gravity_class_getsuper (gravity_class_t *c);
-GRAVITY_API bool				gravity_class_grow (gravity_class_t *c, uint32_t n);
-GRAVITY_API bool				gravity_class_setsuper (gravity_class_t *subclass, gravity_class_t *superclass);
-GRAVITY_API gravity_class_t		*gravity_class_new_single (gravity_vm *vm, const char *identifier, uint32_t nfields);
-GRAVITY_API gravity_class_t		*gravity_class_new_pair (gravity_vm *vm, const char *identifier, gravity_class_t *superclass, uint32_t nivar, uint32_t nsvar);
-GRAVITY_API gravity_class_t		*gravity_class_get_meta (gravity_class_t *c);
-GRAVITY_API bool				gravity_class_is_meta (gravity_class_t *c);
+GRAVITY_API void                gravity_class_bind (gravity_class_t *c, const char *key, gravity_value_t value);
+GRAVITY_API gravity_class_t     *gravity_class_getsuper (gravity_class_t *c);
+GRAVITY_API bool                gravity_class_grow (gravity_class_t *c, uint32_t n);
+GRAVITY_API bool                gravity_class_setsuper (gravity_class_t *subclass, gravity_class_t *superclass);
+GRAVITY_API gravity_class_t     *gravity_class_new_single (gravity_vm *vm, const char *identifier, uint32_t nfields);
+GRAVITY_API gravity_class_t     *gravity_class_new_pair (gravity_vm *vm, const char *identifier, gravity_class_t *superclass, uint32_t nivar, uint32_t nsvar);
+GRAVITY_API gravity_class_t     *gravity_class_get_meta (gravity_class_t *c);
+GRAVITY_API bool                gravity_class_is_meta (gravity_class_t *c);
 GRAVITY_API bool                gravity_class_is_anon (gravity_class_t *c);
 GRAVITY_API bool                gravity_class_is_anon (gravity_class_t *c);
-GRAVITY_API uint32_t			gravity_class_count_ivars (gravity_class_t *c);
-GRAVITY_API void				gravity_class_dump (gravity_class_t *c);
-GRAVITY_API void				gravity_class_setxdata (gravity_class_t *c, void *xdata);
-GRAVITY_API int16_t				gravity_class_add_ivar (gravity_class_t *c, const char *identifier);
-GRAVITY_API void				gravity_class_serialize (gravity_class_t *c, json_t *json);
-GRAVITY_API gravity_class_t		*gravity_class_deserialize (gravity_vm *vm, json_value *json);
-GRAVITY_API void				gravity_class_free (gravity_vm *vm, gravity_class_t *c);
-GRAVITY_API void				gravity_class_free_core (gravity_vm *vm, gravity_class_t *c);
-GRAVITY_API gravity_object_t	*gravity_class_lookup (gravity_class_t *c, gravity_value_t key);
-GRAVITY_API gravity_closure_t	*gravity_class_lookup_closure (gravity_class_t *c, gravity_value_t key);
-GRAVITY_API gravity_closure_t	*gravity_class_lookup_constructor (gravity_class_t *c, uint32_t nparams);
-GRAVITY_API void				gravity_class_blacken (gravity_vm *vm, gravity_class_t *c);
-GRAVITY_API uint32_t			gravity_class_size (gravity_vm *vm, gravity_class_t *c);
+GRAVITY_API uint32_t            gravity_class_count_ivars (gravity_class_t *c);
+GRAVITY_API void                gravity_class_dump (gravity_class_t *c);
+GRAVITY_API void                gravity_class_setxdata (gravity_class_t *c, void *xdata);
+GRAVITY_API int16_t             gravity_class_add_ivar (gravity_class_t *c, const char *identifier);
+GRAVITY_API void                gravity_class_serialize (gravity_class_t *c, json_t *json);
+GRAVITY_API gravity_class_t     *gravity_class_deserialize (gravity_vm *vm, json_value *json);
+GRAVITY_API void                gravity_class_free (gravity_vm *vm, gravity_class_t *c);
+GRAVITY_API void                gravity_class_free_core (gravity_vm *vm, gravity_class_t *c);
+GRAVITY_API gravity_object_t    *gravity_class_lookup (gravity_class_t *c, gravity_value_t key);
+GRAVITY_API gravity_closure_t   *gravity_class_lookup_closure (gravity_class_t *c, gravity_value_t key);
+GRAVITY_API gravity_closure_t   *gravity_class_lookup_constructor (gravity_class_t *c, uint32_t nparams);
+GRAVITY_API void                gravity_class_blacken (gravity_vm *vm, gravity_class_t *c);
+GRAVITY_API uint32_t            gravity_class_size (gravity_vm *vm, gravity_class_t *c);
 
 
 // MARK: - FIBER -
 // MARK: - FIBER -
-GRAVITY_API gravity_fiber_t		*gravity_fiber_new (gravity_vm *vm, gravity_closure_t *closure, uint32_t nstack, uint32_t nframes);
-GRAVITY_API void				gravity_fiber_reassign (gravity_fiber_t *fiber, gravity_closure_t *closure, uint16_t nargs);
-GRAVITY_API void				gravity_fiber_seterror (gravity_fiber_t *fiber, const char *error);
-GRAVITY_API void				gravity_fiber_free (gravity_vm *vm, gravity_fiber_t *fiber);
-GRAVITY_API void				gravity_fiber_blacken (gravity_vm *vm, gravity_fiber_t *fiber);
-GRAVITY_API uint32_t			gravity_fiber_size (gravity_vm *vm, gravity_fiber_t *fiber);
+GRAVITY_API gravity_fiber_t     *gravity_fiber_new (gravity_vm *vm, gravity_closure_t *closure, uint32_t nstack, uint32_t nframes);
+GRAVITY_API void                gravity_fiber_reassign (gravity_fiber_t *fiber, gravity_closure_t *closure, uint16_t nargs);
+GRAVITY_API void                gravity_fiber_seterror (gravity_fiber_t *fiber, const char *error);
+GRAVITY_API void                gravity_fiber_free (gravity_vm *vm, gravity_fiber_t *fiber);
+GRAVITY_API void                gravity_fiber_blacken (gravity_vm *vm, gravity_fiber_t *fiber);
+GRAVITY_API uint32_t            gravity_fiber_size (gravity_vm *vm, gravity_fiber_t *fiber);
 
 
 // MARK: - INSTANCE -
 // MARK: - INSTANCE -
-GRAVITY_API gravity_instance_t	*gravity_instance_new (gravity_vm *vm, gravity_class_t *c);
-GRAVITY_API gravity_instance_t	*gravity_instance_clone (gravity_vm *vm, gravity_instance_t *instance);
-GRAVITY_API void				gravity_instance_setivar (gravity_instance_t *instance, uint32_t idx, gravity_value_t value);
-GRAVITY_API void				gravity_instance_setxdata (gravity_instance_t *i, void *xdata);
-GRAVITY_API void				gravity_instance_free (gravity_vm *vm, gravity_instance_t *i);
-GRAVITY_API gravity_closure_t	*gravity_instance_lookup_event (gravity_instance_t *i, const char *name);
-GRAVITY_API void				gravity_instance_blacken (gravity_vm *vm, gravity_instance_t *i);
-GRAVITY_API uint32_t			gravity_instance_size (gravity_vm *vm, gravity_instance_t *i);
+GRAVITY_API gravity_instance_t  *gravity_instance_new (gravity_vm *vm, gravity_class_t *c);
+GRAVITY_API gravity_instance_t  *gravity_instance_clone (gravity_vm *vm, gravity_instance_t *instance);
+GRAVITY_API void                gravity_instance_setivar (gravity_instance_t *instance, uint32_t idx, gravity_value_t value);
+GRAVITY_API void                gravity_instance_setxdata (gravity_instance_t *i, void *xdata);
+GRAVITY_API void                gravity_instance_free (gravity_vm *vm, gravity_instance_t *i);
+GRAVITY_API gravity_closure_t   *gravity_instance_lookup_event (gravity_instance_t *i, const char *name);
+GRAVITY_API void                gravity_instance_blacken (gravity_vm *vm, gravity_instance_t *i);
+GRAVITY_API uint32_t            gravity_instance_size (gravity_vm *vm, gravity_instance_t *i);
 
 
 // MARK: - VALUE -
 // MARK: - VALUE -
-GRAVITY_API bool				gravity_value_equals (gravity_value_t v1, gravity_value_t v2);
+GRAVITY_API bool                gravity_value_equals (gravity_value_t v1, gravity_value_t v2);
 GRAVITY_API bool                gravity_value_vm_equals (gravity_vm *vm, gravity_value_t v1, gravity_value_t v2);
 GRAVITY_API bool                gravity_value_vm_equals (gravity_vm *vm, gravity_value_t v1, gravity_value_t v2);
-GRAVITY_API uint32_t			gravity_value_hash (gravity_value_t value);
-GRAVITY_API gravity_class_t		*gravity_value_getclass (gravity_value_t v);
-GRAVITY_API gravity_class_t		*gravity_value_getsuper (gravity_value_t v);
-GRAVITY_API void				gravity_value_free (gravity_vm *vm, gravity_value_t v);
-GRAVITY_API void				gravity_value_serialize (gravity_value_t v, json_t *json);
-GRAVITY_API void				gravity_value_dump (gravity_vm *vm, gravity_value_t v, char *buffer, uint16_t len);
-GRAVITY_API bool				gravity_value_isobject (gravity_value_t v);
-GRAVITY_API void				*gravity_value_xdata (gravity_value_t value);
+GRAVITY_API uint32_t            gravity_value_hash (gravity_value_t value);
+GRAVITY_API gravity_class_t     *gravity_value_getclass (gravity_value_t v);
+GRAVITY_API gravity_class_t     *gravity_value_getsuper (gravity_value_t v);
+GRAVITY_API void                gravity_value_free (gravity_vm *vm, gravity_value_t v);
+GRAVITY_API void                gravity_value_serialize (gravity_value_t v, json_t *json);
+GRAVITY_API void                gravity_value_dump (gravity_vm *vm, gravity_value_t v, char *buffer, uint16_t len);
+GRAVITY_API bool                gravity_value_isobject (gravity_value_t v);
+GRAVITY_API void                *gravity_value_xdata (gravity_value_t value);
 GRAVITY_API const char          *gravity_value_name (gravity_value_t value);
 GRAVITY_API const char          *gravity_value_name (gravity_value_t value);
-GRAVITY_API void				gravity_value_blacken (gravity_vm *vm, gravity_value_t v);
-GRAVITY_API uint32_t			gravity_value_size (gravity_vm *vm, gravity_value_t v);
+GRAVITY_API void                gravity_value_blacken (gravity_vm *vm, gravity_value_t v);
+GRAVITY_API uint32_t            gravity_value_size (gravity_vm *vm, gravity_value_t v);
 
 
 // MARK: - OBJECT -
 // MARK: - OBJECT -
-GRAVITY_API void				gravity_object_serialize (gravity_object_t *obj, json_t *json);
-GRAVITY_API gravity_object_t	*gravity_object_deserialize (gravity_vm *vm, json_value *entry);
-GRAVITY_API void				gravity_object_free (gravity_vm *vm, gravity_object_t *obj);
-GRAVITY_API void				gravity_object_blacken (gravity_vm *vm, gravity_object_t *obj);
-GRAVITY_API uint32_t			gravity_object_size (gravity_vm *vm, gravity_object_t *obj);
-GRAVITY_API const char			*gravity_object_debug (gravity_object_t *obj, bool is_free);
+GRAVITY_API void                gravity_object_serialize (gravity_object_t *obj, json_t *json);
+GRAVITY_API gravity_object_t    *gravity_object_deserialize (gravity_vm *vm, json_value *entry);
+GRAVITY_API void                gravity_object_free (gravity_vm *vm, gravity_object_t *obj);
+GRAVITY_API void                gravity_object_blacken (gravity_vm *vm, gravity_object_t *obj);
+GRAVITY_API uint32_t            gravity_object_size (gravity_vm *vm, gravity_object_t *obj);
+GRAVITY_API const char          *gravity_object_debug (gravity_object_t *obj, bool is_free);
 
 
 // MARK: - LIST -
 // MARK: - LIST -
-GRAVITY_API gravity_list_t		*gravity_list_new (gravity_vm *vm, uint32_t n);
-GRAVITY_API gravity_list_t		*gravity_list_from_array (gravity_vm *vm, uint32_t n, gravity_value_t *p);
-GRAVITY_API void				gravity_list_free (gravity_vm *vm, gravity_list_t *list);
-GRAVITY_API void				gravity_list_append_list (gravity_vm *vm, gravity_list_t *list1, gravity_list_t *list2);
-GRAVITY_API void				gravity_list_blacken (gravity_vm *vm, gravity_list_t *list);
-GRAVITY_API uint32_t			gravity_list_size (gravity_vm *vm, gravity_list_t *list);
+GRAVITY_API gravity_list_t      *gravity_list_new (gravity_vm *vm, uint32_t n);
+GRAVITY_API gravity_list_t      *gravity_list_from_array (gravity_vm *vm, uint32_t n, gravity_value_t *p);
+GRAVITY_API void                gravity_list_free (gravity_vm *vm, gravity_list_t *list);
+GRAVITY_API void                gravity_list_append_list (gravity_vm *vm, gravity_list_t *list1, gravity_list_t *list2);
+GRAVITY_API void                gravity_list_blacken (gravity_vm *vm, gravity_list_t *list);
+GRAVITY_API uint32_t            gravity_list_size (gravity_vm *vm, gravity_list_t *list);
 
 
 // MARK: - MAP -
 // MARK: - MAP -
-GRAVITY_API gravity_map_t		*gravity_map_new (gravity_vm *vm, uint32_t n);
-GRAVITY_API void				gravity_map_free (gravity_vm *vm, gravity_map_t *map);
-GRAVITY_API void				gravity_map_append_map (gravity_vm *vm, gravity_map_t *map1, gravity_map_t *map2);
-GRAVITY_API void				gravity_map_insert (gravity_vm *vm, gravity_map_t *map, gravity_value_t key, gravity_value_t value);
-GRAVITY_API void				gravity_map_blacken (gravity_vm *vm, gravity_map_t *map);
-GRAVITY_API uint32_t			gravity_map_size (gravity_vm *vm, gravity_map_t *map);
+GRAVITY_API gravity_map_t       *gravity_map_new (gravity_vm *vm, uint32_t n);
+GRAVITY_API void                gravity_map_free (gravity_vm *vm, gravity_map_t *map);
+GRAVITY_API void                gravity_map_append_map (gravity_vm *vm, gravity_map_t *map1, gravity_map_t *map2);
+GRAVITY_API void                gravity_map_insert (gravity_vm *vm, gravity_map_t *map, gravity_value_t key, gravity_value_t value);
+GRAVITY_API void                gravity_map_blacken (gravity_vm *vm, gravity_map_t *map);
+GRAVITY_API uint32_t            gravity_map_size (gravity_vm *vm, gravity_map_t *map);
 
 
 // MARK: - RANGE -
 // MARK: - RANGE -
-GRAVITY_API gravity_range_t		*gravity_range_new (gravity_vm *vm, gravity_int_t from, gravity_int_t to, bool inclusive);
-GRAVITY_API void				gravity_range_free (gravity_vm *vm, gravity_range_t *range);
-GRAVITY_API void				gravity_range_blacken (gravity_vm *vm, gravity_range_t *range);
-GRAVITY_API uint32_t			gravity_range_size (gravity_vm *vm, gravity_range_t *range);
+GRAVITY_API gravity_range_t     *gravity_range_new (gravity_vm *vm, gravity_int_t from, gravity_int_t to, bool inclusive);
+GRAVITY_API void                gravity_range_free (gravity_vm *vm, gravity_range_t *range);
+GRAVITY_API void                gravity_range_blacken (gravity_vm *vm, gravity_range_t *range);
+GRAVITY_API uint32_t            gravity_range_size (gravity_vm *vm, gravity_range_t *range);
 
 
 /// MARK: - STRING -
 /// MARK: - STRING -
-GRAVITY_API gravity_value_t		gravity_string_to_value (gravity_vm *vm, const char *s, uint32_t len);
-GRAVITY_API gravity_string_t	*gravity_string_new (gravity_vm *vm, char *s, uint32_t len, uint32_t alloc);
-            inline void			gravity_string_set (gravity_string_t *obj, char *s, uint32_t len);
-GRAVITY_API void				gravity_string_free (gravity_vm *vm, gravity_string_t *value);
-GRAVITY_API void				gravity_string_blacken (gravity_vm *vm, gravity_string_t *string);
-GRAVITY_API uint32_t			gravity_string_size (gravity_vm *vm, gravity_string_t *string);
+GRAVITY_API gravity_value_t     gravity_string_to_value (gravity_vm *vm, const char *s, uint32_t len);
+GRAVITY_API gravity_string_t    *gravity_string_new (gravity_vm *vm, char *s, uint32_t len, uint32_t alloc);
+            inline void         gravity_string_set (gravity_string_t *obj, char *s, uint32_t len);
+GRAVITY_API void                gravity_string_free (gravity_vm *vm, gravity_string_t *value);
+GRAVITY_API void                gravity_string_blacken (gravity_vm *vm, gravity_string_t *string);
+GRAVITY_API uint32_t            gravity_string_size (gravity_vm *vm, gravity_string_t *string);
 
 
 // MARK: - CALLBACKS -
 // MARK: - CALLBACKS -
 // HASH FREE CALLBACK FUNCTION
 // HASH FREE CALLBACK FUNCTION
-GRAVITY_API void				gravity_hash_keyvaluefree (gravity_hash_t *table, gravity_value_t key, gravity_value_t value, void *data);
-GRAVITY_API void				gravity_hash_keyfree (gravity_hash_t *table, gravity_value_t key, gravity_value_t value, void *data);
-GRAVITY_API void				gravity_hash_valuefree (gravity_hash_t *table, gravity_value_t key, gravity_value_t value, void *data);
+GRAVITY_API void                gravity_hash_keyvaluefree (gravity_hash_t *table, gravity_value_t key, gravity_value_t value, void *data);
+GRAVITY_API void                gravity_hash_keyfree (gravity_hash_t *table, gravity_value_t key, gravity_value_t value, void *data);
+GRAVITY_API void                gravity_hash_valuefree (gravity_hash_t *table, gravity_value_t key, gravity_value_t value, void *data);
 GRAVITY_API void                gravity_hash_finteralfree (gravity_hash_t *table, gravity_value_t key, gravity_value_t value, void *data);
 GRAVITY_API void                gravity_hash_finteralfree (gravity_hash_t *table, gravity_value_t key, gravity_value_t value, void *data);
 
 
 #ifdef __cplusplus
 #ifdef __cplusplus

+ 184 - 184
src/utils/gravity_debug.c

@@ -12,79 +12,79 @@
 #include "gravity_vmmacros.h"
 #include "gravity_vmmacros.h"
 
 
 const char *opcode_constname (int n) {
 const char *opcode_constname (int n) {
-	switch (n) {
-		case CPOOL_VALUE_SUPER: return "SUPER";
-		case CPOOL_VALUE_NULL: return "NULL";
-		case CPOOL_VALUE_UNDEFINED: return "UNDEFINED";
-		case CPOOL_VALUE_ARGUMENTS: return "ARGUMENTS";
-		case CPOOL_VALUE_TRUE: return "TRUE";
-		case CPOOL_VALUE_FALSE: return "FALSE";
-		case CPOOL_VALUE_FUNC: return "FUNC";
-	}
-	return "N/A";
+    switch (n) {
+        case CPOOL_VALUE_SUPER: return "SUPER";
+        case CPOOL_VALUE_NULL: return "NULL";
+        case CPOOL_VALUE_UNDEFINED: return "UNDEFINED";
+        case CPOOL_VALUE_ARGUMENTS: return "ARGUMENTS";
+        case CPOOL_VALUE_TRUE: return "TRUE";
+        case CPOOL_VALUE_FALSE: return "FALSE";
+        case CPOOL_VALUE_FUNC: return "FUNC";
+    }
+    return "N/A";
 }
 }
 
 
 const char *opcode_name (opcode_t op) {
 const char *opcode_name (opcode_t op) {
-	static const char *optable[] = {
-		"RET0", "HALT", "NOP", "RET", "CALL", "LOAD", "LOADS", "LOADAT",
-		"LOADK", "LOADG", "LOADI", "LOADU", "MOVE", "STORE", "STOREAT",
-		"STOREG", "STOREU", "JUMP", "JUMPF", "SWITCH", "ADD", "SUB", "DIV",
-		"MUL", "REM", "AND", "OR", "LT", "GT", "EQ", "LEQ", "GEQ", "NEQ",
-		"EQQ", "NEQQ", "IS", "MATCH", "NEG", "NOT", "LSHIFT", "RSHIFT", "BAND",
-		"BOR", "BXOR", "BNOT", "MAPNEW", "LISTNEW", "RANGENEW", "SETLIST",
-		"CLOSURE", "CLOSE", "RESERVED1", "RESERVED2", "RESERVED3", "RESERVED4",
-		"RESERVED5", "RESERVED6"};
-	return optable[op];
+    static const char *optable[] = {
+        "RET0", "HALT", "NOP", "RET", "CALL", "LOAD", "LOADS", "LOADAT",
+        "LOADK", "LOADG", "LOADI", "LOADU", "MOVE", "STORE", "STOREAT",
+        "STOREG", "STOREU", "JUMP", "JUMPF", "SWITCH", "ADD", "SUB", "DIV",
+        "MUL", "REM", "AND", "OR", "LT", "GT", "EQ", "LEQ", "GEQ", "NEQ",
+        "EQQ", "NEQQ", "IS", "MATCH", "NEG", "NOT", "LSHIFT", "RSHIFT", "BAND",
+        "BOR", "BXOR", "BNOT", "MAPNEW", "LISTNEW", "RANGENEW", "SETLIST",
+        "CLOSURE", "CLOSE", "RESERVED1", "RESERVED2", "RESERVED3", "RESERVED4",
+        "RESERVED5", "RESERVED6"};
+    return optable[op];
 }
 }
 
 
-#define DUMP_VM(buffer, bindex, ...)					bindex += snprintf(&buffer[bindex], balloc-bindex, "%06u\t", pc);	\
-														bindex += snprintf(&buffer[bindex], balloc-bindex, __VA_ARGS__);		\
-														bindex += snprintf(&buffer[bindex], balloc-bindex, "\n");
+#define DUMP_VM(buffer, bindex, ...)                    bindex += snprintf(&buffer[bindex], balloc-bindex, "%06u\t", pc);    \
+                                                        bindex += snprintf(&buffer[bindex], balloc-bindex, __VA_ARGS__);        \
+                                                        bindex += snprintf(&buffer[bindex], balloc-bindex, "\n");
 
 
-#define DUMP_VM_NOCR(buffer, bindex, ...)				bindex += snprintf(&buffer[bindex], balloc-bindex, "%06u\t", pc);	\
-														bindex += snprintf(&buffer[bindex], balloc-bindex, __VA_ARGS__);
+#define DUMP_VM_NOCR(buffer, bindex, ...)                bindex += snprintf(&buffer[bindex], balloc-bindex, "%06u\t", pc);    \
+                                                        bindex += snprintf(&buffer[bindex], balloc-bindex, __VA_ARGS__);
 
 
-#define DUMP_VM_RAW(buffer, bindex, ...)				bindex += snprintf(&buffer[bindex], balloc-bindex, __VA_ARGS__);
+#define DUMP_VM_RAW(buffer, bindex, ...)                bindex += snprintf(&buffer[bindex], balloc-bindex, __VA_ARGS__);
 
 
 const char *gravity_disassemble (gravity_vm *vm, gravity_function_t *f, const char *bcode, uint32_t blen, bool deserialize) {
 const char *gravity_disassemble (gravity_vm *vm, gravity_function_t *f, const char *bcode, uint32_t blen, bool deserialize) {
-	uint32_t	*ip = NULL;
-	uint32_t	pc = 0, inst = 0, ninsts = 0;
-	opcode_t	op;
-	
-	const int	rowlen = 256;
-	uint32_t	bindex = 0;
-	uint32_t	balloc = 0;
-	char		*buffer = NULL;
-	
-	if (deserialize) {
-		// decode textual buffer to real bytecode
-		ip = gravity_bytecode_deserialize(bcode, blen, &ninsts);
-		if ((ip == NULL) || (ninsts == 0)) goto abort_disassemble;
-	} else {
-		ip = (uint32_t *)bcode;
-		ninsts = blen;
-	}
-		
-	// allocate a buffer big enought to fit all disassembled bytecode
-	// I assume that each instruction (each row) will be 256 chars long
-	balloc = ninsts * rowlen;
-	buffer = mem_alloc(NULL, balloc);
-	if (!buffer) goto abort_disassemble;
-		
-	// conversion loop
-	while (pc < ninsts) {
-		inst = *ip++;
-		op = (opcode_t)OPCODE_GET_OPCODE(inst);
-		
+    uint32_t    *ip = NULL;
+    uint32_t    pc = 0, inst = 0, ninsts = 0;
+    opcode_t    op;
+    
+    const int    rowlen = 256;
+    uint32_t    bindex = 0;
+    uint32_t    balloc = 0;
+    char        *buffer = NULL;
+    
+    if (deserialize) {
+        // decode textual buffer to real bytecode
+        ip = gravity_bytecode_deserialize(bcode, blen, &ninsts);
+        if ((ip == NULL) || (ninsts == 0)) goto abort_disassemble;
+    } else {
+        ip = (uint32_t *)bcode;
+        ninsts = blen;
+    }
+        
+    // allocate a buffer big enought to fit all disassembled bytecode
+    // I assume that each instruction (each row) will be 256 chars long
+    balloc = ninsts * rowlen;
+    buffer = mem_alloc(NULL, balloc);
+    if (!buffer) goto abort_disassemble;
+        
+    // conversion loop
+    while (pc < ninsts) {
+        inst = *ip++;
+        op = (opcode_t)OPCODE_GET_OPCODE(inst);
+        
         // for fixed N spaces in opcode name
         // for fixed N spaces in opcode name
         // replace %s with %-Ns
         // replace %s with %-Ns
-		switch (op) {
-			case NOP: {
-				DUMP_VM(buffer, bindex, "%s", opcode_name(op));
-				break;
-			}
-				
-			case MOVE:
+        switch (op) {
+            case NOP: {
+                DUMP_VM(buffer, bindex, "%s", opcode_name(op));
+                break;
+            }
+                
+            case MOVE:
             case LOADG:
             case LOADG:
             case LOADU:
             case LOADU:
             case STOREG:
             case STOREG:
@@ -93,21 +93,21 @@ const char *gravity_disassemble (gravity_vm *vm, gravity_function_t *f, const ch
             case MAPNEW:
             case MAPNEW:
             case LISTNEW:
             case LISTNEW:
             case CLOSURE: {
             case CLOSURE: {
-				OPCODE_GET_ONE8bit_ONE18bit(inst, const uint32_t r1, const uint32_t r2);
-				DUMP_VM(buffer, bindex, "%s %d %d", opcode_name(op), r1, r2);
-				break;
-			}
-				
-			case LOADI: {
-				OPCODE_GET_ONE8bit_SIGN_ONE17bit(inst, const uint32_t r1, const int32_t value);
-				DUMP_VM(buffer, bindex, "%s %d %d", opcode_name(op), r1, value);
-				break;
-			}
+                OPCODE_GET_ONE8bit_ONE18bit(inst, const uint32_t r1, const uint32_t r2);
+                DUMP_VM(buffer, bindex, "%s %d %d", opcode_name(op), r1, r2);
+                break;
+            }
+                
+            case LOADI: {
+                OPCODE_GET_ONE8bit_SIGN_ONE17bit(inst, const uint32_t r1, const int32_t value);
+                DUMP_VM(buffer, bindex, "%s %d %d", opcode_name(op), r1, value);
+                break;
+            }
 
 
-			case LOADK: {
-				OPCODE_GET_ONE8bit_ONE18bit(inst, const uint32_t r1, const uint32_t index);
-				if (index < CPOOL_INDEX_MAX) {
-					DUMP_VM(buffer, bindex, "%s %d %d", opcode_name(op), r1, index);
+            case LOADK: {
+                OPCODE_GET_ONE8bit_ONE18bit(inst, const uint32_t r1, const uint32_t index);
+                if (index < CPOOL_INDEX_MAX) {
+                    DUMP_VM(buffer, bindex, "%s %d %d", opcode_name(op), r1, index);
                     if (f) {
                     if (f) {
                         char b[2018];
                         char b[2018];
                         gravity_value_t constant = gravity_function_cpool_get(f, index);
                         gravity_value_t constant = gravity_function_cpool_get(f, index);
@@ -115,26 +115,26 @@ const char *gravity_disassemble (gravity_vm *vm, gravity_function_t *f, const ch
                         --bindex; // to replace the \n character
                         --bindex; // to replace the \n character
                         DUMP_VM_RAW(buffer, bindex, "\t\t;%s\n", b);
                         DUMP_VM_RAW(buffer, bindex, "\t\t;%s\n", b);
                     }
                     }
-				} else {
-					const char *special;
-					switch (index) {
-						case CPOOL_VALUE_SUPER: special = "SUPER"; break;
-						case CPOOL_VALUE_NULL: special = "NULL"; break;
-						case CPOOL_VALUE_UNDEFINED: special = "UNDEFINED"; break;
-						case CPOOL_VALUE_ARGUMENTS: special = "ARGUMENTS"; break;
-						case CPOOL_VALUE_TRUE: special = "TRUE"; break;
-						case CPOOL_VALUE_FALSE: special = "FALSE"; break;
-						case CPOOL_VALUE_FUNC: special = "_FUNC"; break;
-						default: special = "Invalid index in LOADK opcode"; break;
-					}
-					DUMP_VM(buffer, bindex, "%s %d %s", opcode_name(op), r1, special);
-				}
-				break;
-			}
-			
-			case LOAD:
-			case LOADS:
-			case LOADAT:
+                } else {
+                    const char *special;
+                    switch (index) {
+                        case CPOOL_VALUE_SUPER: special = "SUPER"; break;
+                        case CPOOL_VALUE_NULL: special = "NULL"; break;
+                        case CPOOL_VALUE_UNDEFINED: special = "UNDEFINED"; break;
+                        case CPOOL_VALUE_ARGUMENTS: special = "ARGUMENTS"; break;
+                        case CPOOL_VALUE_TRUE: special = "TRUE"; break;
+                        case CPOOL_VALUE_FALSE: special = "FALSE"; break;
+                        case CPOOL_VALUE_FUNC: special = "_FUNC"; break;
+                        default: special = "Invalid index in LOADK opcode"; break;
+                    }
+                    DUMP_VM(buffer, bindex, "%s %d %s", opcode_name(op), r1, special);
+                }
+                break;
+            }
+            
+            case LOAD:
+            case LOADS:
+            case LOADAT:
             case STORE:
             case STORE:
             case STOREAT:
             case STOREAT:
             case EQQ:
             case EQQ:
@@ -159,93 +159,93 @@ const char *gravity_disassemble (gravity_vm *vm, gravity_function_t *f, const ch
             case REM:
             case REM:
             case AND:
             case AND:
             case OR: {
             case OR: {
-				OPCODE_GET_TWO8bit_ONE10bit(inst, const uint32_t r1, const uint32_t r2, const uint32_t r3);
-				DUMP_VM(buffer, bindex, "%s %d %d %d", opcode_name(op), r1, r2, r3);
-				break;
-			}
-				
-			// unary operators
-			case BNOT:
-			case NEG:
-			case NOT: {
-				OPCODE_GET_TWO8bit_ONE10bit(inst, const uint32_t r1, const uint32_t r2, const uint32_t r3);
-				#pragma unused(r3)
-				DUMP_VM(buffer, bindex, "%s %d %d", opcode_name(op), r1, r2);
-				break;
-			}
-			
-			case RANGENEW: {
-				OPCODE_GET_TWO8bit_ONE10bit(inst, const uint32_t r1, const uint32_t r2, const uint32_t r3);
-				DUMP_VM(buffer, bindex, "%s %d %d %d", opcode_name(op), r1, r2, r3);
-				break;
-			}
-				
-			case JUMP: {
-				OPCODE_GET_ONE26bit(inst, const uint32_t value);
-				DUMP_VM(buffer, bindex, "%s %d", opcode_name(op), value);
-				break;
-			}
-				
-			case CALL: {
-				// CALL A B C => R(A) = B(C0... CN)
-				OPCODE_GET_THREE8bit(inst, const uint32_t r1, const uint32_t r2, uint32_t r3);
-				DUMP_VM(buffer, bindex, "%s %d %d %d", opcode_name(op), r1, r2, r3);
-				break;
-			}
-				
-			case RET0:
-			case RET: {
-				if (op == RET0) {
-					DUMP_VM(buffer, bindex, "%s", opcode_name(op));
-				} else {
-					OPCODE_GET_ONE8bit(inst, const uint32_t r1);
-					DUMP_VM(buffer, bindex, "%s %d", opcode_name(op), r1);
-				}
-				break;
-			}
-				
-			case HALT: {
-				DUMP_VM(buffer, bindex, "%s", opcode_name(op));
-				break;
-			}
-				
-			case SWITCH: {
-				DUMP_VM(buffer, bindex, "SWITCH instruction not yet implemented");
-				break;
-			}
-				
-			case SETLIST: {
-				OPCODE_GET_TWO8bit_ONE10bit(inst, const uint32_t r1, uint32_t r2, const uint32_t r3);
-				#pragma unused(r3)
-				DUMP_VM(buffer, bindex, "%s %d %d", opcode_name(op), r1, r2);
-				break;
-			}
-				
-			case CLOSE: {
-				OPCODE_GET_ONE8bit_ONE18bit(inst, const uint32_t r1, const uint32_t r2);
-				#pragma unused(r2)
-				DUMP_VM(buffer, bindex, "%s %d", opcode_name(op), r1);
-				break;
-			}
-				
-			case RESERVED1:
-			case RESERVED2:
-			case RESERVED3:
-			case RESERVED4:
-			case RESERVED5:
-			case RESERVED6: {
-				DUMP_VM(buffer, bindex, "RESERVED");
-				break;
-			}
-		}
-		
-		++pc;
-	}
-	
-	return buffer;
-	
+                OPCODE_GET_TWO8bit_ONE10bit(inst, const uint32_t r1, const uint32_t r2, const uint32_t r3);
+                DUMP_VM(buffer, bindex, "%s %d %d %d", opcode_name(op), r1, r2, r3);
+                break;
+            }
+                
+            // unary operators
+            case BNOT:
+            case NEG:
+            case NOT: {
+                OPCODE_GET_TWO8bit_ONE10bit(inst, const uint32_t r1, const uint32_t r2, const uint32_t r3);
+                #pragma unused(r3)
+                DUMP_VM(buffer, bindex, "%s %d %d", opcode_name(op), r1, r2);
+                break;
+            }
+            
+            case RANGENEW: {
+                OPCODE_GET_TWO8bit_ONE10bit(inst, const uint32_t r1, const uint32_t r2, const uint32_t r3);
+                DUMP_VM(buffer, bindex, "%s %d %d %d", opcode_name(op), r1, r2, r3);
+                break;
+            }
+                
+            case JUMP: {
+                OPCODE_GET_ONE26bit(inst, const uint32_t value);
+                DUMP_VM(buffer, bindex, "%s %d", opcode_name(op), value);
+                break;
+            }
+                
+            case CALL: {
+                // CALL A B C => R(A) = B(C0... CN)
+                OPCODE_GET_THREE8bit(inst, const uint32_t r1, const uint32_t r2, uint32_t r3);
+                DUMP_VM(buffer, bindex, "%s %d %d %d", opcode_name(op), r1, r2, r3);
+                break;
+            }
+                
+            case RET0:
+            case RET: {
+                if (op == RET0) {
+                    DUMP_VM(buffer, bindex, "%s", opcode_name(op));
+                } else {
+                    OPCODE_GET_ONE8bit(inst, const uint32_t r1);
+                    DUMP_VM(buffer, bindex, "%s %d", opcode_name(op), r1);
+                }
+                break;
+            }
+                
+            case HALT: {
+                DUMP_VM(buffer, bindex, "%s", opcode_name(op));
+                break;
+            }
+                
+            case SWITCH: {
+                DUMP_VM(buffer, bindex, "SWITCH instruction not yet implemented");
+                break;
+            }
+                
+            case SETLIST: {
+                OPCODE_GET_TWO8bit_ONE10bit(inst, const uint32_t r1, uint32_t r2, const uint32_t r3);
+                #pragma unused(r3)
+                DUMP_VM(buffer, bindex, "%s %d %d", opcode_name(op), r1, r2);
+                break;
+            }
+                
+            case CLOSE: {
+                OPCODE_GET_ONE8bit_ONE18bit(inst, const uint32_t r1, const uint32_t r2);
+                #pragma unused(r2)
+                DUMP_VM(buffer, bindex, "%s %d", opcode_name(op), r1);
+                break;
+            }
+                
+            case RESERVED1:
+            case RESERVED2:
+            case RESERVED3:
+            case RESERVED4:
+            case RESERVED5:
+            case RESERVED6: {
+                DUMP_VM(buffer, bindex, "RESERVED");
+                break;
+            }
+        }
+        
+        ++pc;
+    }
+    
+    return buffer;
+    
 abort_disassemble:
 abort_disassemble:
-	if (ip && deserialize) mem_free(ip);
-	if (buffer) mem_free(buffer);
-	return NULL;
+    if (ip && deserialize) mem_free(ip);
+    if (buffer) mem_free(buffer);
+    return NULL;
 }
 }

+ 206 - 206
src/utils/gravity_json.c

@@ -48,276 +48,276 @@
 // MARK: - JSON Serializer -
 // MARK: - JSON Serializer -
 // Written by Marco Bambini
 // Written by Marco Bambini
 
 
-#define JSON_MINSIZE		4096
-#define JSON_NEWLINE		"\n"
-#define JSON_NEWLINE_CHAR	'\n'
-#define JSON_PRETTYLINE		"    "
-#define JSON_PRETTYSIZE		4
-#define JSON_WRITE_SEP		json_write_raw(json, " : ", 3, false, false)
-#define JSON_TERM_FIELD		json_write_raw(json, ",", 1, false, false); json_write_raw(json, JSON_NEWLINE, 1, false, false)
-#define JSON_MAX_NESTED		1024
-#define JSON_POP_CTX(j)		--j->ctxidx
-#define JSON_PUSH_CTX(j,x)	if(j->ctxidx<JSON_MAX_NESTED-1) j->ctx[j->ctxidx++] = x
-#define JSON_CURR_XTX(j)	j->ctx[j->ctxidx-1]
-#define JSON_ESCAPE(c)		do {		\
-								new_buffer[j] = '\\';		\
-								new_buffer[j+1] = (c);		\
-								j+=2;						\
-							} while(0);						\
+#define JSON_MINSIZE        4096
+#define JSON_NEWLINE        "\n"
+#define JSON_NEWLINE_CHAR    '\n'
+#define JSON_PRETTYLINE        "    "
+#define JSON_PRETTYSIZE        4
+#define JSON_WRITE_SEP        json_write_raw(json, " : ", 3, false, false)
+#define JSON_TERM_FIELD        json_write_raw(json, ",", 1, false, false); json_write_raw(json, JSON_NEWLINE, 1, false, false)
+#define JSON_MAX_NESTED        1024
+#define JSON_POP_CTX(j)        --j->ctxidx
+#define JSON_PUSH_CTX(j,x)    if(j->ctxidx<JSON_MAX_NESTED-1) j->ctx[j->ctxidx++] = x
+#define JSON_CURR_XTX(j)    j->ctx[j->ctxidx-1]
+#define JSON_ESCAPE(c)        do {        \
+                                new_buffer[j] = '\\';        \
+                                new_buffer[j+1] = (c);        \
+                                j+=2;                        \
+                            } while(0);                        \
 
 
 
 
 typedef enum {
 typedef enum {
-	json_ctx_object,
-	json_ctx_array
+    json_ctx_object,
+    json_ctx_array
 } json_ctx_t;
 } json_ctx_t;
 
 
 struct json_t {
 struct json_t {
-	char		*buffer;
-	size_t		blen;
-	size_t		bused;
-	uint32_t	ident;
+    char        *buffer;
+    size_t        blen;
+    size_t        bused;
+    uint32_t    ident;
 
 
-	json_ctx_t	ctx[JSON_MAX_NESTED];
-	size_t		ctxidx;
+    json_ctx_t    ctx[JSON_MAX_NESTED];
+    size_t        ctxidx;
 };
 };
 
 
 json_t *json_new (void) {
 json_t *json_new (void) {
-	json_t *json = mem_alloc(NULL, sizeof(json_t));
-	assert(json);
+    json_t *json = mem_alloc(NULL, sizeof(json_t));
+    assert(json);
 
 
-	json->buffer = mem_alloc(NULL, JSON_MINSIZE);
-	assert(json->buffer);
+    json->buffer = mem_alloc(NULL, JSON_MINSIZE);
+    assert(json->buffer);
 
 
-	json->blen = JSON_MINSIZE;
-	json->bused = 0;
-	json->ident = 0;
-	json->ctxidx = 0;
+    json->blen = JSON_MINSIZE;
+    json->bused = 0;
+    json->ident = 0;
+    json->ctxidx = 0;
 
 
-	return json;
+    return json;
 }
 }
 
 
 static void json_write_raw (json_t *json, const char *buffer, size_t len, bool escape, bool is_pretty) {
 static void json_write_raw (json_t *json, const char *buffer, size_t len, bool escape, bool is_pretty) {
-	size_t	prettylen = (is_pretty) ? (json->ident * JSON_PRETTYSIZE)+1 : 0;
-	size_t	escapelen = (escape) ? 2 : 0;
-
-	// check buffer reallocation
-	size_t reqlen = json->bused + len + prettylen + escapelen + JSON_MINSIZE;
-	if (reqlen >= json->blen) {
-		json->buffer = mem_realloc(NULL, json->buffer, json->blen + reqlen);
-		assert(json->buffer);
-		json->blen += reqlen;
-	}
-
-	if (is_pretty) {
-		for (uint32_t i=0; i<json->ident; ++i) {
-			memcpy(json->buffer+json->bused, JSON_PRETTYLINE, JSON_PRETTYSIZE);
-			json->bused += JSON_PRETTYSIZE;
-		}
-	}
-
-	if (escape) {
-		memcpy(json->buffer+json->bused, "\"", 1);
-		json->bused += 1;
-	}
-
-	memcpy(json->buffer+json->bused, buffer, len);
-	json->bused += len;
-
-	if (escape) {
-		memcpy(json->buffer+json->bused, "\"", 1);
-		json->bused += 1;
-	}
+    size_t    prettylen = (is_pretty) ? (json->ident * JSON_PRETTYSIZE)+1 : 0;
+    size_t    escapelen = (escape) ? 2 : 0;
+
+    // check buffer reallocation
+    size_t reqlen = json->bused + len + prettylen + escapelen + JSON_MINSIZE;
+    if (reqlen >= json->blen) {
+        json->buffer = mem_realloc(NULL, json->buffer, json->blen + reqlen);
+        assert(json->buffer);
+        json->blen += reqlen;
+    }
+
+    if (is_pretty) {
+        for (uint32_t i=0; i<json->ident; ++i) {
+            memcpy(json->buffer+json->bused, JSON_PRETTYLINE, JSON_PRETTYSIZE);
+            json->bused += JSON_PRETTYSIZE;
+        }
+    }
+
+    if (escape) {
+        memcpy(json->buffer+json->bused, "\"", 1);
+        json->bused += 1;
+    }
+
+    memcpy(json->buffer+json->bused, buffer, len);
+    json->bused += len;
+
+    if (escape) {
+        memcpy(json->buffer+json->bused, "\"", 1);
+        json->bused += 1;
+    }
 }
 }
 
 
 static void json_write_escaped (json_t *json, const char *buffer, size_t len, bool escape, bool is_pretty) {
 static void json_write_escaped (json_t *json, const char *buffer, size_t len, bool escape, bool is_pretty) {
-	if (!len) {
-		json_write_raw(json, "", 0, escape, is_pretty);
-		return;
-	}
-
-	char	*new_buffer = mem_alloc(NULL, len*2);
-	size_t	j = 0;
-	assert(new_buffer);
-
-	for (size_t i=0; i<len; ++i) {
-		char c = buffer[i];
-		switch (c) {
-			case '"' : JSON_ESCAPE ('\"');	continue;
-			case '\\': JSON_ESCAPE ('\\');  continue;
-			case '\b': JSON_ESCAPE ('b');   continue;
-			case '\f': JSON_ESCAPE ('f');   continue;
-			case '\n': JSON_ESCAPE ('n');   continue;
-			case '\r': JSON_ESCAPE ('r');   continue;
-			case '\t': JSON_ESCAPE ('t');   continue;
-
-			default: new_buffer[j] = c; ++j;break;
-		};
-	}
-
-	json_write_raw(json, new_buffer, j, escape, is_pretty);
-	mem_free(new_buffer);
+    if (!len) {
+        json_write_raw(json, "", 0, escape, is_pretty);
+        return;
+    }
+
+    char    *new_buffer = mem_alloc(NULL, len*2);
+    size_t    j = 0;
+    assert(new_buffer);
+
+    for (size_t i=0; i<len; ++i) {
+        char c = buffer[i];
+        switch (c) {
+            case '"' : JSON_ESCAPE ('\"');    continue;
+            case '\\': JSON_ESCAPE ('\\');  continue;
+            case '\b': JSON_ESCAPE ('b');   continue;
+            case '\f': JSON_ESCAPE ('f');   continue;
+            case '\n': JSON_ESCAPE ('n');   continue;
+            case '\r': JSON_ESCAPE ('r');   continue;
+            case '\t': JSON_ESCAPE ('t');   continue;
+
+            default: new_buffer[j] = c; ++j;break;
+        };
+    }
+
+    json_write_raw(json, new_buffer, j, escape, is_pretty);
+    mem_free(new_buffer);
 }
 }
 
 
 
 
 void json_begin_object (json_t *json, const char *key) {
 void json_begin_object (json_t *json, const char *key) {
-	// ignore given key if not inside an object
-	if (JSON_CURR_XTX(json) != json_ctx_object) {
-		key = NULL;
-	}
+    // ignore given key if not inside an object
+    if (JSON_CURR_XTX(json) != json_ctx_object) {
+        key = NULL;
+    }
 
 
-	if (key) {
-		json_write_raw (json, key, strlen(key), true, true);
-		JSON_WRITE_SEP;
-	}
+    if (key) {
+        json_write_raw (json, key, strlen(key), true, true);
+        JSON_WRITE_SEP;
+    }
 
 
-	JSON_PUSH_CTX(json, json_ctx_object);
-	json_write_raw(json, "{", 1, false, (key == NULL));
-	json_write_raw(json, JSON_NEWLINE, 1, false, false);
+    JSON_PUSH_CTX(json, json_ctx_object);
+    json_write_raw(json, "{", 1, false, (key == NULL));
+    json_write_raw(json, JSON_NEWLINE, 1, false, false);
 
 
-	++json->ident;
+    ++json->ident;
 }
 }
 
 
 void json_end_object (json_t *json) {
 void json_end_object (json_t *json) {
-	--json->ident;
-	JSON_POP_CTX(json);
-
-	// check latest 2 characters
-	if ((json->buffer[json->bused-1] == JSON_NEWLINE_CHAR) && (json->buffer[json->bused-2] == ',')) {
-		json->buffer[json->bused-2] = JSON_NEWLINE_CHAR;
-		json->buffer[json->bused-1] = 0;
-		--json->bused;
-	}
-
-	json_write_raw(json, "}", 1, false, true);
-	if (json->ident) {JSON_TERM_FIELD;}
-	else json_write_raw(json, JSON_NEWLINE, 1, false, false);
+    --json->ident;
+    JSON_POP_CTX(json);
+
+    // check latest 2 characters
+    if ((json->buffer[json->bused-1] == JSON_NEWLINE_CHAR) && (json->buffer[json->bused-2] == ',')) {
+        json->buffer[json->bused-2] = JSON_NEWLINE_CHAR;
+        json->buffer[json->bused-1] = 0;
+        --json->bused;
+    }
+
+    json_write_raw(json, "}", 1, false, true);
+    if (json->ident) {JSON_TERM_FIELD;}
+    else json_write_raw(json, JSON_NEWLINE, 1, false, false);
 }
 }
 
 
 void json_begin_array (json_t *json, const char *key) {
 void json_begin_array (json_t *json, const char *key) {
-	// ignore given key if not inside an object
-	if (JSON_CURR_XTX(json) != json_ctx_object) {
-		key = NULL;
-	}
+    // ignore given key if not inside an object
+    if (JSON_CURR_XTX(json) != json_ctx_object) {
+        key = NULL;
+    }
 
 
-	if (key) {
-		json_write_raw (json, key, strlen(key), true, true);
-		JSON_WRITE_SEP;
-	}
+    if (key) {
+        json_write_raw (json, key, strlen(key), true, true);
+        JSON_WRITE_SEP;
+    }
 
 
-	JSON_PUSH_CTX(json, json_ctx_array);
-	json_write_raw(json, "[", 1, false, (key == NULL));
-	json_write_raw(json, JSON_NEWLINE, 1, false, false);
+    JSON_PUSH_CTX(json, json_ctx_array);
+    json_write_raw(json, "[", 1, false, (key == NULL));
+    json_write_raw(json, JSON_NEWLINE, 1, false, false);
 
 
-	++json->ident;
+    ++json->ident;
 }
 }
 
 
 void json_end_array (json_t *json) {
 void json_end_array (json_t *json) {
-	--json->ident;
-	JSON_POP_CTX(json);
-
-	// check latest 2 characters
-	if ((json->buffer[json->bused-1] == JSON_NEWLINE_CHAR) && (json->buffer[json->bused-2] == ',')) {
-		json->buffer[json->bused-2] = JSON_NEWLINE_CHAR;
-		json->buffer[json->bused-1] = 0;
-		--json->bused;
-	}
-
-	json_write_raw(json, "]", 1, false, true);
-	JSON_TERM_FIELD;
+    --json->ident;
+    JSON_POP_CTX(json);
+
+    // check latest 2 characters
+    if ((json->buffer[json->bused-1] == JSON_NEWLINE_CHAR) && (json->buffer[json->bused-2] == ',')) {
+        json->buffer[json->bused-2] = JSON_NEWLINE_CHAR;
+        json->buffer[json->bused-1] = 0;
+        --json->bused;
+    }
+
+    json_write_raw(json, "]", 1, false, true);
+    JSON_TERM_FIELD;
 }
 }
 
 
 void json_add_string (json_t *json, const char *key, const char *value, size_t len) {
 void json_add_string (json_t *json, const char *key, const char *value, size_t len) {
-	if (!value) {
-		json_add_null(json, key);
-		return;
-	}
-
-	if (key) {
-		json_write_raw (json, key, strlen(key), true, true);
-		JSON_WRITE_SEP;
-	}
-
-	// check if string value needs to be escaped
-	bool write_escaped = false;
-	for (size_t i=0; i<len; ++i) {
-		if (value[i] == '"') {write_escaped = true; break;}
-	}
-	if (len == 0)
-		write_escaped = true;
-
-	if (write_escaped)
-		json_write_escaped(json, value, len, true, (key == NULL));
-	else
-		json_write_raw(json, value, len, true, (key == NULL));
-	JSON_TERM_FIELD;
+    if (!value) {
+        json_add_null(json, key);
+        return;
+    }
+
+    if (key) {
+        json_write_raw (json, key, strlen(key), true, true);
+        JSON_WRITE_SEP;
+    }
+
+    // check if string value needs to be escaped
+    bool write_escaped = false;
+    for (size_t i=0; i<len; ++i) {
+        if (value[i] == '"') {write_escaped = true; break;}
+    }
+    if (len == 0)
+        write_escaped = true;
+
+    if (write_escaped)
+        json_write_escaped(json, value, len, true, (key == NULL));
+    else
+        json_write_raw(json, value, len, true, (key == NULL));
+    JSON_TERM_FIELD;
 }
 }
 
 
 void json_add_cstring (json_t *json, const char *key, const char *value) {
 void json_add_cstring (json_t *json, const char *key, const char *value) {
-	json_add_string(json, key, value, (value) ? strlen(value) : 0);
+    json_add_string(json, key, value, (value) ? strlen(value) : 0);
 }
 }
 
 
 void json_add_int (json_t *json, const char *key, int64_t value) {
 void json_add_int (json_t *json, const char *key, int64_t value) {
-	char buffer[512];
-	size_t len = snprintf(buffer, sizeof(buffer), "%" PRId64, value);
+    char buffer[512];
+    size_t len = snprintf(buffer, sizeof(buffer), "%" PRId64, value);
 
 
-	if (key) {
-		json_write_raw (json, key, strlen(key), true, true);
-		JSON_WRITE_SEP;
-	}
-	json_write_raw(json, buffer, len, false, (key == NULL));
-	JSON_TERM_FIELD;
+    if (key) {
+        json_write_raw (json, key, strlen(key), true, true);
+        JSON_WRITE_SEP;
+    }
+    json_write_raw(json, buffer, len, false, (key == NULL));
+    JSON_TERM_FIELD;
 
 
 }
 }
 
 
 void json_add_double (json_t *json, const char *key, double value) {
 void json_add_double (json_t *json, const char *key, double value) {
-	char buffer[512];
-	size_t len = snprintf(buffer, sizeof(buffer), "%f", value);
-
-	if (key) {
-		json_write_raw (json, key, strlen(key), true, true);
-		JSON_WRITE_SEP;
-	}
-	json_write_raw(json, buffer, len, false, (key == NULL));
-	JSON_TERM_FIELD;
+    char buffer[512];
+    size_t len = snprintf(buffer, sizeof(buffer), "%f", value);
+
+    if (key) {
+        json_write_raw (json, key, strlen(key), true, true);
+        JSON_WRITE_SEP;
+    }
+    json_write_raw(json, buffer, len, false, (key == NULL));
+    JSON_TERM_FIELD;
 }
 }
 
 
 void json_add_bool (json_t *json, const char *key, bool bvalue) {
 void json_add_bool (json_t *json, const char *key, bool bvalue) {
-	const char *value = (bvalue) ? "true" : "false";
-
-	if (key) {
-		json_write_raw (json, key, strlen(key), true, true);
-		JSON_WRITE_SEP;
-	}
-	json_write_raw(json, value, strlen(value), false, (key == NULL));
-	JSON_TERM_FIELD;
+    const char *value = (bvalue) ? "true" : "false";
+
+    if (key) {
+        json_write_raw (json, key, strlen(key), true, true);
+        JSON_WRITE_SEP;
+    }
+    json_write_raw(json, value, strlen(value), false, (key == NULL));
+    JSON_TERM_FIELD;
 }
 }
 
 
 void json_add_null (json_t *json, const char *key) {
 void json_add_null (json_t *json, const char *key) {
-	if (key) {
-		json_write_raw (json, key, strlen(key), true, true);
-		JSON_WRITE_SEP;
-	}
-	json_write_raw(json, "null", 4, false, (key == NULL));
-	JSON_TERM_FIELD;
+    if (key) {
+        json_write_raw (json, key, strlen(key), true, true);
+        JSON_WRITE_SEP;
+    }
+    json_write_raw(json, "null", 4, false, (key == NULL));
+    JSON_TERM_FIELD;
 }
 }
 
 
 void json_free (json_t *json) {
 void json_free (json_t *json) {
-	mem_free(json->buffer);
-	mem_free(json);
+    mem_free(json->buffer);
+    mem_free(json);
 }
 }
 
 
 const char *json_buffer (json_t *json, size_t *len) {
 const char *json_buffer (json_t *json, size_t *len) {
-	assert(json->buffer);
-	if (len) *len = json->bused;
-	return json->buffer;
+    assert(json->buffer);
+    if (len) *len = json->bused;
+    return json->buffer;
 }
 }
 
 
 bool json_write_file (json_t *json, const char *path) {
 bool json_write_file (json_t *json, const char *path) {
-	return file_write(path, json->buffer, json->bused);
+    return file_write(path, json->buffer, json->bused);
 }
 }
 
 
 void json_pop (json_t *json, uint32_t n) {
 void json_pop (json_t *json, uint32_t n) {
-	json->bused -= n;
+    json->bused -= n;
 }
 }
 
 
 #undef JSON_MINSIZE
 #undef JSON_MINSIZE
@@ -367,16 +367,16 @@ typedef struct
 
 
 static void * default_alloc (size_t size, int zero, void * user_data)
 static void * default_alloc (size_t size, int zero, void * user_data)
 {
 {
-	#pragma unused(zero, user_data)
-	return mem_alloc(NULL, size);
-	//return zero ? calloc (1, size) : malloc (size);
+    #pragma unused(zero, user_data)
+    return mem_alloc(NULL, size);
+    //return zero ? calloc (1, size) : malloc (size);
 }
 }
 
 
 static void default_free (void * ptr, void * user_data)
 static void default_free (void * ptr, void * user_data)
 {
 {
-	#pragma unused(user_data)
-	mem_free(ptr);
-	//free (ptr);
+    #pragma unused(user_data)
+    mem_free(ptr);
+    //free (ptr);
 }
 }
 
 
 static void * json_alloc (json_state * state, unsigned long size, int zero)
 static void * json_alloc (json_state * state, unsigned long size, int zero)

+ 18 - 18
src/utils/gravity_json.h

@@ -7,22 +7,22 @@
 
 
 // MARK: JSON serializer -
 // MARK: JSON serializer -
 
 
-typedef struct json_t	json_t;
-json_t		*json_new (void);
-void		json_begin_object (json_t *json, const char *key);
-void		json_end_object (json_t *json);
-void		json_begin_array (json_t *json, const char *key);
-void		json_end_array (json_t *json);
-void		json_add_cstring (json_t *json, const char *key, const char *value);
-void		json_add_string (json_t *json, const char *key, const char *value, size_t len);
-void		json_add_int (json_t *json, const char *key, int64_t value);
-void		json_add_double (json_t *json, const char *key, double value);
-void		json_add_bool (json_t *json, const char *key, bool value);
-void		json_add_null (json_t *json, const char *key);
-void		json_free (json_t *json);
-const char	*json_buffer (json_t *json, size_t *len);
-bool		json_write_file (json_t *json, const char *path);
-void		json_pop (json_t *json, uint32_t n);
+typedef struct json_t    json_t;
+json_t      *json_new (void);
+void        json_begin_object (json_t *json, const char *key);
+void        json_end_object (json_t *json);
+void        json_begin_array (json_t *json, const char *key);
+void        json_end_array (json_t *json);
+void        json_add_cstring (json_t *json, const char *key, const char *value);
+void        json_add_string (json_t *json, const char *key, const char *value, size_t len);
+void        json_add_int (json_t *json, const char *key, int64_t value);
+void        json_add_double (json_t *json, const char *key, double value);
+void        json_add_bool (json_t *json, const char *key, bool value);
+void        json_add_null (json_t *json, const char *key);
+void        json_free (json_t *json);
+const char  *json_buffer (json_t *json, size_t *len);
+bool        json_write_file (json_t *json, const char *path);
+void        json_pop (json_t *json, uint32_t n);
 
 
 #endif
 #endif
 
 
@@ -283,8 +283,8 @@ typedef struct _json_value
 
 
 } json_value;
 } json_value;
 
 
-#define EMPTY_SETTINGS_STRUCT	{0,0,0,0,0,0}
-#define EMPTY_STATE_STRUCT		{0,0,0,EMPTY_SETTINGS_STRUCT,0,0,0,0}
+#define EMPTY_SETTINGS_STRUCT    {0,0,0,0,0,0}
+#define EMPTY_STATE_STRUCT        {0,0,0,EMPTY_SETTINGS_STRUCT,0,0,0,0}
 
 
 json_value * json_parse (const json_char * json,
 json_value * json_parse (const json_char * json,
                          size_t length);
                          size_t length);

+ 364 - 364
src/utils/gravity_utils.c

@@ -34,56 +34,56 @@
 // MARK: Timer -
 // MARK: Timer -
 
 
 nanotime_t nanotime (void) {
 nanotime_t nanotime (void) {
-	nanotime_t value;
-	
-	#if defined(_WIN32)
-	static LARGE_INTEGER	win_frequency;
-	QueryPerformanceFrequency(&win_frequency);
-	LARGE_INTEGER			t;
-	
-	if (!QueryPerformanceCounter(&t)) return 0;
-	value = (t.QuadPart / win_frequency.QuadPart) * 1000000000;
-	value += (t.QuadPart % win_frequency.QuadPart) * 1000000000 / win_frequency.QuadPart;
-	
-	#elif defined(__MACH__)
-	mach_timebase_info_data_t	info;
-	kern_return_t				r;
-	nanotime_t					t;
-	
-	t = mach_absolute_time();
-	r = mach_timebase_info(&info);
-	if (r != 0) return 0;
-	value = (t / info.denom) * info.numer;
-	value += (t % info.denom) * info.numer / info.denom;
-	
-	#elif defined(__linux)
-	struct timespec ts;
-	int				r;
-	
-	r = clock_gettime(CLOCK_MONOTONIC, &ts);
-	if (r != 0) return 0;
-	value = ts.tv_sec * (nanotime_t)1000000000 + ts.tv_nsec;
-	
-	#else
-	struct timeval	tv;
-	int				r;
-	
-	r = gettimeofday(&tv, 0);
-	if (r != 0) return 0;
-	value = tv.tv_sec * (nanotime_t)1000000000 + tv.tv_usec * 1000;
-	#endif
-	
-	return value;
+    nanotime_t value;
+    
+    #if defined(_WIN32)
+    static LARGE_INTEGER    win_frequency;
+    QueryPerformanceFrequency(&win_frequency);
+    LARGE_INTEGER            t;
+    
+    if (!QueryPerformanceCounter(&t)) return 0;
+    value = (t.QuadPart / win_frequency.QuadPart) * 1000000000;
+    value += (t.QuadPart % win_frequency.QuadPart) * 1000000000 / win_frequency.QuadPart;
+    
+    #elif defined(__MACH__)
+    mach_timebase_info_data_t    info;
+    kern_return_t                r;
+    nanotime_t                    t;
+    
+    t = mach_absolute_time();
+    r = mach_timebase_info(&info);
+    if (r != 0) return 0;
+    value = (t / info.denom) * info.numer;
+    value += (t % info.denom) * info.numer / info.denom;
+    
+    #elif defined(__linux)
+    struct timespec ts;
+    int                r;
+    
+    r = clock_gettime(CLOCK_MONOTONIC, &ts);
+    if (r != 0) return 0;
+    value = ts.tv_sec * (nanotime_t)1000000000 + ts.tv_nsec;
+    
+    #else
+    struct timeval    tv;
+    int                r;
+    
+    r = gettimeofday(&tv, 0);
+    if (r != 0) return 0;
+    value = tv.tv_sec * (nanotime_t)1000000000 + tv.tv_usec * 1000;
+    #endif
+    
+    return value;
 }
 }
 
 
 double microtime (nanotime_t tstart, nanotime_t tend) {
 double microtime (nanotime_t tstart, nanotime_t tend) {
-	nanotime_t t = tend - tstart;
-	return ((double)t / 1000.0f);
+    nanotime_t t = tend - tstart;
+    return ((double)t / 1000.0f);
 }
 }
 
 
 double millitime (nanotime_t tstart, nanotime_t tend) {
 double millitime (nanotime_t tstart, nanotime_t tend) {
-	nanotime_t t = tend - tstart;
-	return ((double)t / 1000000.0f);
+    nanotime_t t = tend - tstart;
+    return ((double)t / 1000000.0f);
 }
 }
 
 
 // MARK: - Console Functions -
 // MARK: - Console Functions -
@@ -91,261 +91,261 @@ double millitime (nanotime_t tstart, nanotime_t tend) {
 #ifdef WIN32
 #ifdef WIN32
 // getline is a POSIX function not available in C on Windows (only C++)
 // getline is a POSIX function not available in C on Windows (only C++)
 static ssize_t getline (char **lineptr, size_t *n, FILE *stream) {
 static ssize_t getline (char **lineptr, size_t *n, FILE *stream) {
-	// to be implemented on Windows
-	// Never use gets: it offers no protections against a buffer overflow vulnerability.
-	// see http://stackoverflow.com/questions/3302255/c-scanf-vs-gets-vs-fgets
-	// we should implement something like ggets here
-	// http://web.archive.org/web/20080525133110/http://cbfalconer.home.att.net/download/
-	
-	return -1;
+    // to be implemented on Windows
+    // Never use gets: it offers no protections against a buffer overflow vulnerability.
+    // see http://stackoverflow.com/questions/3302255/c-scanf-vs-gets-vs-fgets
+    // we should implement something like ggets here
+    // http://web.archive.org/web/20080525133110/http://cbfalconer.home.att.net/download/
+    
+    return -1;
 }
 }
 #endif
 #endif
 
 
 char *readline (char *prompt, int *length) {
 char *readline (char *prompt, int *length) {
-	char	*line = NULL;
-	size_t	size = 0;
-	
-	printf("%s", prompt);
-	fflush(stdout);
-	
-	ssize_t nread = getline(&line, &size, stdin);
-	if (nread == -1 || feof(stdin)) return NULL;
-	
-	*length = (int)nread;
-	return line;
+    char    *line = NULL;
+    size_t    size = 0;
+    
+    printf("%s", prompt);
+    fflush(stdout);
+    
+    ssize_t nread = getline(&line, &size, stdin);
+    if (nread == -1 || feof(stdin)) return NULL;
+    
+    *length = (int)nread;
+    return line;
 }
 }
 
 
 // MARK: - I/O Functions -
 // MARK: - I/O Functions -
 
 
 uint64_t file_size (const char *path) {
 uint64_t file_size (const char *path) {
-	#ifdef WIN32
-	WIN32_FILE_ATTRIBUTE_DATA   fileInfo;
-	if (GetFileAttributesExA(path, GetFileExInfoStandard, (void*)&fileInfo) == 0) return -1;
-	return (uint64_t)(((__int64)fileInfo.nFileSizeHigh) << 32 ) + fileInfo.nFileSizeLow;
-	#else
-	struct stat sb;
-	if (stat(path, &sb) > 0) return -1;
-	return (uint64_t)sb.st_size;
-	#endif
+    #ifdef WIN32
+    WIN32_FILE_ATTRIBUTE_DATA   fileInfo;
+    if (GetFileAttributesExA(path, GetFileExInfoStandard, (void*)&fileInfo) == 0) return -1;
+    return (uint64_t)(((__int64)fileInfo.nFileSizeHigh) << 32 ) + fileInfo.nFileSizeLow;
+    #else
+    struct stat sb;
+    if (stat(path, &sb) > 0) return -1;
+    return (uint64_t)sb.st_size;
+    #endif
 }
 }
 
 
 const char *file_read(const char *path, size_t *len) {
 const char *file_read(const char *path, size_t *len) {
-	int		fd = 0;
-	off_t	fsize = 0;
-	size_t	fsize2 = 0;
-	char	*buffer = NULL;
-	
-	fsize = (size_t) file_size(path);
-	if (fsize < 0) goto abort_read;
-	
-	fd = open(path, O_RDONLY);
-	if (fd < 0) goto abort_read;
-	
-	buffer = (char *)mem_alloc(NULL, (size_t)fsize + 1);
-	if (buffer == NULL) goto abort_read;
-	buffer[fsize] = 0;
-	
-	fsize2 = read(fd, buffer, (size_t)fsize);
-	if (fsize2 == -1) goto abort_read;
-	
-	if (len) *len = fsize2;
-	close(fd);
-	return (const char *)buffer;
-	
+    int        fd = 0;
+    off_t    fsize = 0;
+    size_t    fsize2 = 0;
+    char    *buffer = NULL;
+    
+    fsize = (size_t) file_size(path);
+    if (fsize < 0) goto abort_read;
+    
+    fd = open(path, O_RDONLY);
+    if (fd < 0) goto abort_read;
+    
+    buffer = (char *)mem_alloc(NULL, (size_t)fsize + 1);
+    if (buffer == NULL) goto abort_read;
+    buffer[fsize] = 0;
+    
+    fsize2 = read(fd, buffer, (size_t)fsize);
+    if (fsize2 == -1) goto abort_read;
+    
+    if (len) *len = fsize2;
+    close(fd);
+    return (const char *)buffer;
+    
 abort_read:
 abort_read:
-	if (buffer) mem_free((void *)buffer);
-	if (fd >= 0) close(fd);
-	return NULL;
+    if (buffer) mem_free((void *)buffer);
+    if (fd >= 0) close(fd);
+    return NULL;
 }
 }
 
 
 bool file_exists (const char *path) {
 bool file_exists (const char *path) {
-	#ifdef WIN32
-	BOOL isDirectory;
-	DWORD attributes = GetFileAttributesA(path);
-	
-	// special directory case to drive the network path check
-	if (attributes == INVALID_FILE_ATTRIBUTES)
-		isDirectory = (GetLastError() == ERROR_BAD_NETPATH);
-	else
-		isDirectory = (FILE_ATTRIBUTE_DIRECTORY & attributes);
-	
-	if (isDirectory) {
-		if (PathIsNetworkPathA(path)) return true;
-		if (PathIsUNCA(path)) return true;
-	}
-	
-	if (PathFileExistsA(path) == 1) return true;
-	#else
-	if (access(path, F_OK)==0) return true;
-	#endif
-	
-	return false;
+    #ifdef WIN32
+    BOOL isDirectory;
+    DWORD attributes = GetFileAttributesA(path);
+    
+    // special directory case to drive the network path check
+    if (attributes == INVALID_FILE_ATTRIBUTES)
+        isDirectory = (GetLastError() == ERROR_BAD_NETPATH);
+    else
+        isDirectory = (FILE_ATTRIBUTE_DIRECTORY & attributes);
+    
+    if (isDirectory) {
+        if (PathIsNetworkPathA(path)) return true;
+        if (PathIsUNCA(path)) return true;
+    }
+    
+    if (PathFileExistsA(path) == 1) return true;
+    #else
+    if (access(path, F_OK)==0) return true;
+    #endif
+    
+    return false;
 }
 }
 
 
 const char *file_buildpath (const char *filename, const char *dirpath) {
 const char *file_buildpath (const char *filename, const char *dirpath) {
-//	#ifdef WIN32
-//	PathCombineA(result, filename, dirpath);
-//	#else
-	size_t len1 = strlen(filename);
-	size_t len2 = strlen(dirpath);
-	size_t len = len1+len2+2;
-	
-	char *full_path = (char *)mem_alloc(NULL, len);
-	if (!full_path) return NULL;
-	
-	if ((len2) && (dirpath[len2-1] != '/'))
-		snprintf(full_path, len, "%s/%s", dirpath, filename);
-	else
-		snprintf(full_path, len, "%s%s", dirpath, filename);
-//	#endif
-	
-	return (const char *)full_path;
+//    #ifdef WIN32
+//    PathCombineA(result, filename, dirpath);
+//    #else
+    size_t len1 = strlen(filename);
+    size_t len2 = strlen(dirpath);
+    size_t len = len1+len2+2;
+    
+    char *full_path = (char *)mem_alloc(NULL, len);
+    if (!full_path) return NULL;
+    
+    if ((len2) && (dirpath[len2-1] != '/'))
+        snprintf(full_path, len, "%s/%s", dirpath, filename);
+    else
+        snprintf(full_path, len, "%s%s", dirpath, filename);
+//    #endif
+    
+    return (const char *)full_path;
 }
 }
 
 
 bool file_write (const char *path, const char *buffer, size_t len) {
 bool file_write (const char *path, const char *buffer, size_t len) {
-	// RW for owner, R for group, R for others
-	#ifdef _WIN32
-	mode_t mode = _S_IWRITE;
-	#else
-	mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
-	#endif
-	
-	int fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, mode);
-	if (fd < 0) return false;
-	
-	ssize_t nwrite = write(fd, buffer, len);
-	close(fd);
-	
-	return (nwrite == len);
+    // RW for owner, R for group, R for others
+    #ifdef _WIN32
+    mode_t mode = _S_IWRITE;
+    #else
+    mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
+    #endif
+    
+    int fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, mode);
+    if (fd < 0) return false;
+    
+    ssize_t nwrite = write(fd, buffer, len);
+    close(fd);
+    
+    return (nwrite == len);
 }
 }
 
 
 // MARK: - Directory Functions -
 // MARK: - Directory Functions -
 
 
 bool is_directory (const char *path) {
 bool is_directory (const char *path) {
-	#ifdef WIN32
-	DWORD dwAttrs;
-	
-	dwAttrs = GetFileAttributesA(path);
-	if (dwAttrs == INVALID_FILE_ATTRIBUTES) return false;
-	if (dwAttrs & FILE_ATTRIBUTE_DIRECTORY) return true;
-	#else
-	struct stat buf;
-	
-	if (lstat(path, &buf) < 0) return false;
-	if (S_ISDIR(buf.st_mode)) return true;
-	#endif
-	
-	return false;
+    #ifdef WIN32
+    DWORD dwAttrs;
+    
+    dwAttrs = GetFileAttributesA(path);
+    if (dwAttrs == INVALID_FILE_ATTRIBUTES) return false;
+    if (dwAttrs & FILE_ATTRIBUTE_DIRECTORY) return true;
+    #else
+    struct stat buf;
+    
+    if (lstat(path, &buf) < 0) return false;
+    if (S_ISDIR(buf.st_mode)) return true;
+    #endif
+    
+    return false;
 }
 }
 
 
 DIRREF directory_init (const char *dirpath) {
 DIRREF directory_init (const char *dirpath) {
-	#ifdef WIN32
-	WIN32_FIND_DATA findData;
-	WCHAR			path[MAX_PATH];
-	WCHAR			dirpathW[MAX_PATH];
-	HANDLE			hFind;
-	(void)hFind;
-	
-	// convert dirpath to dirpathW
-	MultiByteToWideChar(CP_UTF8, 0, dirpath, -1, dirpathW, MAX_PATH);
-	
-	// in this way I can be sure that the first file returned (and lost) is .
-	PathCombineW(path, dirpathW, _T("*"));
-	
-	// if the path points to a symbolic link, the WIN32_FIND_DATA buffer contains
-	// information about the symbolic link, not the target
-	return FindFirstFileW(path, &findData);
-	#else
-	return opendir(dirpath);
-	#endif
+    #ifdef WIN32
+    WIN32_FIND_DATA findData;
+    WCHAR            path[MAX_PATH];
+    WCHAR            dirpathW[MAX_PATH];
+    HANDLE            hFind;
+    (void)hFind;
+    
+    // convert dirpath to dirpathW
+    MultiByteToWideChar(CP_UTF8, 0, dirpath, -1, dirpathW, MAX_PATH);
+    
+    // in this way I can be sure that the first file returned (and lost) is .
+    PathCombineW(path, dirpathW, _T("*"));
+    
+    // if the path points to a symbolic link, the WIN32_FIND_DATA buffer contains
+    // information about the symbolic link, not the target
+    return FindFirstFileW(path, &findData);
+    #else
+    return opendir(dirpath);
+    #endif
 }
 }
 
 
 const char *directory_read (DIRREF ref) {
 const char *directory_read (DIRREF ref) {
-	if (ref == NULL) return NULL;
-	
-	while (1) {
-		#ifdef WIN32
-		WIN32_FIND_DATA findData;
-		char 			*file_name;
-		
-		if (FindNextFile(ref, &findData) == 0) {
-			FindClose(ref);
-			return NULL;
-		}
-		if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) continue;
-		if (findData.cFileName == NULL) continue;
-		if (findData.cFileName[0] == '.') continue;
-		return (const char*)findData.cFileName;
-		#else
-		struct dirent *d;
-		if ((d = readdir(ref)) == NULL) {
-			closedir(ref);
-			return NULL;
-		}
-		if (d->d_name[0] == 0) continue;
-		if (d->d_name[0] == '.') continue;
-		return (const char *)d->d_name;
-		#endif
-	}
-	return NULL;
+    if (ref == NULL) return NULL;
+    
+    while (1) {
+        #ifdef WIN32
+        WIN32_FIND_DATA findData;
+        char             *file_name;
+        
+        if (FindNextFile(ref, &findData) == 0) {
+            FindClose(ref);
+            return NULL;
+        }
+        if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) continue;
+        if (findData.cFileName == NULL) continue;
+        if (findData.cFileName[0] == '.') continue;
+        return (const char*)findData.cFileName;
+        #else
+        struct dirent *d;
+        if ((d = readdir(ref)) == NULL) {
+            closedir(ref);
+            return NULL;
+        }
+        if (d->d_name[0] == 0) continue;
+        if (d->d_name[0] == '.') continue;
+        return (const char *)d->d_name;
+        #endif
+    }
+    return NULL;
 }
 }
 
 
 // MARK: - String Functions -
 // MARK: - String Functions -
 
 
 int string_nocasencmp(const char *s1, const char *s2, size_t n) {
 int string_nocasencmp(const char *s1, const char *s2, size_t n) {
-	while(n > 0 && tolower((unsigned char)*s1) == tolower((unsigned char)*s2)) {
-		if(*s1 == '\0') return 0;
-		s1++;
-		s2++;
-		n--;
-	}
-	
-	if(n == 0) return 0;
-	return tolower((unsigned char)*s1) - tolower((unsigned char)*s2);
+    while(n > 0 && tolower((unsigned char)*s1) == tolower((unsigned char)*s2)) {
+        if(*s1 == '\0') return 0;
+        s1++;
+        s2++;
+        n--;
+    }
+    
+    if(n == 0) return 0;
+    return tolower((unsigned char)*s1) - tolower((unsigned char)*s2);
 }
 }
 
 
 int string_casencmp(const char *s1, const char *s2, size_t n) {
 int string_casencmp(const char *s1, const char *s2, size_t n) {
-	while(n > 0 && ((unsigned char)*s1) == ((unsigned char)*s2)) {
-		if(*s1 == '\0') return 0;
-		s1++;
-		s2++;
-		n--;
-	}
-	
-	if(n == 0) return 0;
-	return ((unsigned char)*s1) - ((unsigned char)*s2);
+    while(n > 0 && ((unsigned char)*s1) == ((unsigned char)*s2)) {
+        if(*s1 == '\0') return 0;
+        s1++;
+        s2++;
+        n--;
+    }
+    
+    if(n == 0) return 0;
+    return ((unsigned char)*s1) - ((unsigned char)*s2);
 }
 }
 
 
 int string_cmp (const char *s1, const char *s2) {
 int string_cmp (const char *s1, const char *s2) {
-	if (!s1) return 1;
-	return strcmp(s1, s2);
+    if (!s1) return 1;
+    return strcmp(s1, s2);
 }
 }
 
 
 const char *string_dup (const char *s1) {
 const char *string_dup (const char *s1) {
-	size_t	len = (size_t)strlen(s1);
-	char	*s = (char *)mem_alloc(NULL, len + 1);
-	if (!s) return NULL;
-	memcpy(s, s1, len);
-	return s;
+    size_t    len = (size_t)strlen(s1);
+    char    *s = (char *)mem_alloc(NULL, len + 1);
+    if (!s) return NULL;
+    memcpy(s, s1, len);
+    return s;
 }
 }
 
 
 const char *string_ndup (const char *s1, size_t n) {
 const char *string_ndup (const char *s1, size_t n) {
-	char *s = (char *)mem_alloc(NULL, n + 1);
+    char *s = (char *)mem_alloc(NULL, n + 1);
     if (!s) return NULL;
     if (!s) return NULL;
-	memcpy(s, s1, n);
-	return s;
+    memcpy(s, s1, n);
+    return s;
 }
 }
 
 
 // From: http://stackoverflow.com/questions/198199/how-do-you-reverse-a-string-in-place-in-c-or-c
 // From: http://stackoverflow.com/questions/198199/how-do-you-reverse-a-string-in-place-in-c-or-c
 void string_reverse (char *p) {
 void string_reverse (char *p) {
-	char *q = p;
-	while(q && *q) ++q; /* find eos */
-	for(--q; p < q; ++p, --q) SWP(*p, *q);
+    char *q = p;
+    while(q && *q) ++q; /* find eos */
+    for(--q; p < q; ++p, --q) SWP(*p, *q);
 }
 }
 
 
 uint32_t string_size (const char *p) {
 uint32_t string_size (const char *p) {
-	if (!p) return 0;
-	return (uint32_t)strlen(p);
+    if (!p) return 0;
+    return (uint32_t)strlen(p);
 }
 }
 
 
 // From: https://opensource.apple.com/source/Libc/Libc-339/string/FreeBSD/strnstr.c
 // From: https://opensource.apple.com/source/Libc/Libc-339/string/FreeBSD/strnstr.c
@@ -371,130 +371,130 @@ char *string_strnstr(const char *s, const char *find, size_t slen) {
 // MARK: - UTF-8 Functions -
 // MARK: - UTF-8 Functions -
 
 
 /*
 /*
-	Based on: https://github.com/Stepets/utf8.lua/blob/master/utf8.lua
-	ABNF from RFC 3629
-
-	UTF8-octets = *( UTF8-char )
-	UTF8-char   = UTF8-1 / UTF8-2 / UTF8-3 / UTF8-4
-	UTF8-1      = %x00-7F
-	UTF8-2      = %xC2-DF UTF8-tail
-	UTF8-3      = %xE0 %xA0-BF UTF8-tail / %xE1-EC 2( UTF8-tail ) /
-				  %xED %x80-9F UTF8-tail / %xEE-EF 2( UTF8-tail )
-	UTF8-4      = %xF0 %x90-BF 2( UTF8-tail ) / %xF1-F3 3( UTF8-tail ) /
-				  %xF4 %x80-8F 2( UTF8-tail )
-	UTF8-tail   = %x80-BF
+    Based on: https://github.com/Stepets/utf8.lua/blob/master/utf8.lua
+    ABNF from RFC 3629
+
+    UTF8-octets = *( UTF8-char )
+    UTF8-char   = UTF8-1 / UTF8-2 / UTF8-3 / UTF8-4
+    UTF8-1      = %x00-7F
+    UTF8-2      = %xC2-DF UTF8-tail
+    UTF8-3      = %xE0 %xA0-BF UTF8-tail / %xE1-EC 2( UTF8-tail ) /
+                  %xED %x80-9F UTF8-tail / %xEE-EF 2( UTF8-tail )
+    UTF8-4      = %xF0 %x90-BF 2( UTF8-tail ) / %xF1-F3 3( UTF8-tail ) /
+                  %xF4 %x80-8F 2( UTF8-tail )
+    UTF8-tail   = %x80-BF
  
  
  */
  */
 
 
 inline uint32_t utf8_charbytes (const char *s, uint32_t i) {
 inline uint32_t utf8_charbytes (const char *s, uint32_t i) {
-	unsigned char c = s[i];
-	
-	// determine bytes needed for character, based on RFC 3629
-	if ((c > 0) && (c <= 127)) return 1;
-	if ((c >= 194) && (c <= 223)) return 2;
-	if ((c >= 224) && (c <= 239)) return 3;
-	if ((c >= 240) && (c <= 244)) return 4;
-	
-	// means error
-	return 0;
+    unsigned char c = s[i];
+    
+    // determine bytes needed for character, based on RFC 3629
+    if ((c > 0) && (c <= 127)) return 1;
+    if ((c >= 194) && (c <= 223)) return 2;
+    if ((c >= 224) && (c <= 239)) return 3;
+    if ((c >= 240) && (c <= 244)) return 4;
+    
+    // means error
+    return 0;
 }
 }
 
 
 uint32_t utf8_nbytes (uint32_t n) {
 uint32_t utf8_nbytes (uint32_t n) {
-	if (n <= 0x7f) return 1;		// 127
-	if (n <= 0x7ff) return 2;		// 2047
-	if (n <= 0xffff) return 3;		// 65535
-	if (n <= 0x10ffff) return 4;	// 1114111
+    if (n <= 0x7f) return 1;        // 127
+    if (n <= 0x7ff) return 2;        // 2047
+    if (n <= 0xffff) return 3;        // 65535
+    if (n <= 0x10ffff) return 4;    // 1114111
 
 
-	return 0;
+    return 0;
 }
 }
 
 
 // from: https://github.com/munificent/wren/blob/master/src/vm/wren_utils.c
 // from: https://github.com/munificent/wren/blob/master/src/vm/wren_utils.c
 uint32_t utf8_encode(char *buffer, uint32_t value) {
 uint32_t utf8_encode(char *buffer, uint32_t value) {
-	char *bytes = buffer;
-	
-	if (value <= 0x7f) {
-		// single byte (i.e. fits in ASCII).
-		*bytes = value & 0x7f;
-		return 1;
-	}
-	
-	if (value <= 0x7ff) {
-		// two byte sequence: 110xxxxx 10xxxxxx.
-		*bytes = 0xc0 | ((value & 0x7c0) >> 6);
-		++bytes;
-		*bytes = 0x80 | (value & 0x3f);
-		return 2;
-	}
-	
-	if (value <= 0xffff) {
-		// three byte sequence: 1110xxxx 10xxxxxx 10xxxxxx.
-		*bytes = 0xe0 | ((value & 0xf000) >> 12);
-		++bytes;
-		*bytes = 0x80 | ((value & 0xfc0) >> 6);
-		++bytes;
-		*bytes = 0x80 | (value & 0x3f);
-		return 3;
-	}
-	
-	if (value <= 0x10ffff) {
-		// four byte sequence: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx.
-		*bytes = 0xf0 | ((value & 0x1c0000) >> 18);
-		++bytes;
-		*bytes = 0x80 | ((value & 0x3f000) >> 12);
-		++bytes;
-		*bytes = 0x80 | ((value & 0xfc0) >> 6);
-		++bytes;
-		*bytes = 0x80 | (value & 0x3f);
-		return 4;
-	}
-	
-	return 0;
+    char *bytes = buffer;
+    
+    if (value <= 0x7f) {
+        // single byte (i.e. fits in ASCII).
+        *bytes = value & 0x7f;
+        return 1;
+    }
+    
+    if (value <= 0x7ff) {
+        // two byte sequence: 110xxxxx 10xxxxxx.
+        *bytes = 0xc0 | ((value & 0x7c0) >> 6);
+        ++bytes;
+        *bytes = 0x80 | (value & 0x3f);
+        return 2;
+    }
+    
+    if (value <= 0xffff) {
+        // three byte sequence: 1110xxxx 10xxxxxx 10xxxxxx.
+        *bytes = 0xe0 | ((value & 0xf000) >> 12);
+        ++bytes;
+        *bytes = 0x80 | ((value & 0xfc0) >> 6);
+        ++bytes;
+        *bytes = 0x80 | (value & 0x3f);
+        return 3;
+    }
+    
+    if (value <= 0x10ffff) {
+        // four byte sequence: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx.
+        *bytes = 0xf0 | ((value & 0x1c0000) >> 18);
+        ++bytes;
+        *bytes = 0x80 | ((value & 0x3f000) >> 12);
+        ++bytes;
+        *bytes = 0x80 | ((value & 0xfc0) >> 6);
+        ++bytes;
+        *bytes = 0x80 | (value & 0x3f);
+        return 4;
+    }
+    
+    return 0;
 }
 }
 
 
 uint32_t utf8_len (const char *s, uint32_t nbytes) {
 uint32_t utf8_len (const char *s, uint32_t nbytes) {
-	if (nbytes == 0) nbytes = (uint32_t)strlen(s);
-	
-	uint32_t pos = 1;
-	uint32_t len = 0;
-	
-	while (pos <= nbytes) {
-		++len;
-		uint32_t n = utf8_charbytes(s, pos);
-		if (n == 0) return 0; // means error
-		pos += n;
-	}
-	
-	return len;
+    if (nbytes == 0) nbytes = (uint32_t)strlen(s);
+    
+    uint32_t pos = 1;
+    uint32_t len = 0;
+    
+    while (pos <= nbytes) {
+        ++len;
+        uint32_t n = utf8_charbytes(s, pos);
+        if (n == 0) return 0; // means error
+        pos += n;
+    }
+    
+    return len;
 }
 }
 
 
 // From: http://stackoverflow.com/questions/198199/how-do-you-reverse-a-string-in-place-in-c-or-c
 // From: http://stackoverflow.com/questions/198199/how-do-you-reverse-a-string-in-place-in-c-or-c
 bool utf8_reverse (char *p) {
 bool utf8_reverse (char *p) {
-	char *q = p;
-	string_reverse(p);
-	
-	// now fix bass-ackwards UTF chars.
-	while(q && *q) ++q; // find eos
-	while(p < --q)
-		switch( (*q & 0xF0) >> 4 ) {
-			case 0xF: /* U+010000-U+10FFFF: four bytes. */
-				if (q-p < 4) return false;
-				SWP(*(q-0), *(q-3));
-				SWP(*(q-1), *(q-2));
-				q -= 3;
-				break;
-			case 0xE: /* U+000800-U+00FFFF: three bytes. */
-				if (q-p < 3) return false;
-				SWP(*(q-0), *(q-2));
-				q -= 2;
-				break;
-			case 0xC: /* fall-through */
-			case 0xD: /* U+000080-U+0007FF: two bytes. */
-				if (q-p < 1) return false;
-				SWP(*(q-0), *(q-1));
-				q--;
-				break;
-		}
-	return true;
+    char *q = p;
+    string_reverse(p);
+    
+    // now fix bass-ackwards UTF chars.
+    while(q && *q) ++q; // find eos
+    while(p < --q)
+        switch( (*q & 0xF0) >> 4 ) {
+            case 0xF: /* U+010000-U+10FFFF: four bytes. */
+                if (q-p < 4) return false;
+                SWP(*(q-0), *(q-3));
+                SWP(*(q-1), *(q-2));
+                q -= 3;
+                break;
+            case 0xE: /* U+000800-U+00FFFF: three bytes. */
+                if (q-p < 3) return false;
+                SWP(*(q-0), *(q-2));
+                q -= 2;
+                break;
+            case 0xC: /* fall-through */
+            case 0xD: /* U+000080-U+0007FF: two bytes. */
+                if (q-p < 1) return false;
+                SWP(*(q-0), *(q-1));
+                q--;
+                break;
+        }
+    return true;
 }
 }
 
 
 // MARK: - Math -
 // MARK: - Math -
@@ -502,15 +502,15 @@ bool utf8_reverse (char *p) {
 // From: http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2Float
 // From: http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2Float
 // WARNING: this function returns 0 if n is greater than 2^31
 // WARNING: this function returns 0 if n is greater than 2^31
 uint32_t power_of2_ceil (uint32_t n) {
 uint32_t power_of2_ceil (uint32_t n) {
-	n--;
-	n |= n >> 1;
-	n |= n >> 2;
-	n |= n >> 4;
-	n |= n >> 8;
-	n |= n >> 16;
-	n++;
-	
-	return n;
+    n--;
+    n |= n >> 1;
+    n |= n >> 2;
+    n |= n >> 4;
+    n |= n >> 8;
+    n |= n >> 16;
+    n++;
+    
+    return n;
 }
 }
 
 
 int64_t number_from_hex (const char *s, uint32_t len) {
 int64_t number_from_hex (const char *s, uint32_t len) {
@@ -518,9 +518,9 @@ int64_t number_from_hex (const char *s, uint32_t len) {
     // LLONG_MAX  = +9223372036854775807
     // LLONG_MAX  = +9223372036854775807
     // HEX(9223372036854775808) = 346DC5D638865
     // HEX(9223372036854775808) = 346DC5D638865
     
     
-	// sanity check on len in order to workaround an address sanityzer error
+    // sanity check on len in order to workaround an address sanityzer error
     if (len > 24) return 0;
     if (len > 24) return 0;
-	return (int64_t) strtoll(s, NULL, 16);
+    return (int64_t) strtoll(s, NULL, 16);
 }
 }
 
 
 int64_t number_from_oct (const char *s, uint32_t len) {
 int64_t number_from_oct (const char *s, uint32_t len) {
@@ -530,7 +530,7 @@ int64_t number_from_oct (const char *s, uint32_t len) {
     
     
     // sanity check on len in order to workaround an address sanityzer error
     // sanity check on len in order to workaround an address sanityzer error
     if (len > 24) return 0;
     if (len > 24) return 0;
-	return (int64_t) strtoll(s, NULL, 8);
+    return (int64_t) strtoll(s, NULL, 8);
 }
 }
 
 
 int64_t number_from_bin (const char *s, uint32_t len) {
 int64_t number_from_bin (const char *s, uint32_t len) {
@@ -540,11 +540,11 @@ int64_t number_from_bin (const char *s, uint32_t len) {
     
     
     // sanity check on len
     // sanity check on len
     if (len > 64) return 0;
     if (len > 64) return 0;
-	int64_t value = 0;
-	for (uint32_t i=0; i<len; ++i) {
-		int c = s[i];
-		value = (value << 1) + (c - '0');
-	}
-	return value;
+    int64_t value = 0;
+    for (uint32_t i=0; i<len; ++i) {
+        int c = s[i];
+        value = (value << 1) + (c - '0');
+    }
+    return value;
 }
 }
 
 

+ 32 - 32
src/utils/gravity_utils.h

@@ -14,55 +14,55 @@
 
 
 #if defined(_WIN32)
 #if defined(_WIN32)
 #include <windows.h>
 #include <windows.h>
-typedef unsigned __int64 nanotime_t;
-#define DIRREF			HANDLE
+typedef unsigned __int64    nanotime_t;
+#define DIRREF              HANDLE
 #else
 #else
 #include <dirent.h>
 #include <dirent.h>
-typedef uint64_t		nanotime_t;
-#define DIRREF			DIR*
+typedef uint64_t            nanotime_t;
+#define DIRREF              DIR*
 #endif
 #endif
 
 
 // TIMER
 // TIMER
-nanotime_t	nanotime (void);
-double		microtime (nanotime_t tstart, nanotime_t tend);
-double		millitime (nanotime_t tstart, nanotime_t tend);
+nanotime_t  nanotime (void);
+double      microtime (nanotime_t tstart, nanotime_t tend);
+double      millitime (nanotime_t tstart, nanotime_t tend);
 
 
 // CONSOLE
 // CONSOLE
-char		*readline (char *prompt, int *length);
+char        *readline (char *prompt, int *length);
 
 
 // FILE
 // FILE
-uint64_t	file_size (const char *path);
-const char	*file_read (const char *path, size_t *len);
-bool		file_exists (const char *path);
-const char	*file_buildpath (const char *filename, const char *dirpath);
-bool		file_write (const char *path, const char *buffer, size_t len);
+uint64_t    file_size (const char *path);
+const char  *file_read (const char *path, size_t *len);
+bool        file_exists (const char *path);
+const char  *file_buildpath (const char *filename, const char *dirpath);
+bool        file_write (const char *path, const char *buffer, size_t len);
 
 
 // DIRECTORY
 // DIRECTORY
-bool		is_directory (const char *path);
-DIRREF		directory_init (const char *path);
-const char	*directory_read (DIRREF ref);
+bool        is_directory (const char *path);
+DIRREF      directory_init (const char *path);
+const char  *directory_read (DIRREF ref);
 
 
 // STRING
 // STRING
-int			string_nocasencmp (const char *s1, const char *s2, size_t n);
-int			string_casencmp (const char *s1, const char *s2, size_t n);
-int			string_cmp (const char *s1, const char *s2);
-const char	*string_dup (const char *s1);
-const char	*string_ndup (const char *s1, size_t n);
-void		string_reverse (char *p);
-uint32_t	string_size (const char *p);
+int         string_nocasencmp (const char *s1, const char *s2, size_t n);
+int         string_casencmp (const char *s1, const char *s2, size_t n);
+int         string_cmp (const char *s1, const char *s2);
+const char  *string_dup (const char *s1);
+const char  *string_ndup (const char *s1, size_t n);
+void        string_reverse (char *p);
+uint32_t    string_size (const char *p);
 char        *string_strnstr(const char *s, const char *find, size_t slen);
 char        *string_strnstr(const char *s, const char *find, size_t slen);
 
 
 // UTF-8
 // UTF-8
-uint32_t	utf8_charbytes (const char *s, uint32_t i);
-uint32_t	utf8_nbytes (uint32_t n);
-uint32_t	utf8_encode(char *buffer, uint32_t value);
-uint32_t	utf8_len (const char *s, uint32_t nbytes);
-bool		utf8_reverse (char *p);
+uint32_t    utf8_charbytes (const char *s, uint32_t i);
+uint32_t    utf8_nbytes (uint32_t n);
+uint32_t    utf8_encode(char *buffer, uint32_t value);
+uint32_t    utf8_len (const char *s, uint32_t nbytes);
+bool        utf8_reverse (char *p);
 
 
 // MATH and NUMBERS
 // MATH and NUMBERS
-uint32_t	power_of2_ceil (uint32_t n);
-int64_t		number_from_hex (const char *s, uint32_t len);
-int64_t		number_from_oct (const char *s, uint32_t len);
-int64_t		number_from_bin (const char *s, uint32_t len);
+uint32_t    power_of2_ceil (uint32_t n);
+int64_t     number_from_hex (const char *s, uint32_t len);
+int64_t     number_from_oct (const char *s, uint32_t len);
+int64_t     number_from_bin (const char *s, uint32_t len);
 
 
 #endif
 #endif

+ 17 - 0
test/unittest/list_split_2.gravity

@@ -0,0 +1,17 @@
+#unittest {
+    name: "List split test 2";
+    result: "the cat sat on the mat";
+};
+
+func main() {
+    var testString = "the %animal% sat on the mat";
+    var bestEffort = testString.split(" ");
+    
+    var result = [];
+    for (var s in bestEffort) {
+        if (s == "%animal%") s = "cat";
+        result.push(s);
+    }
+    
+    return result.join(" ");
+}

+ 1 - 1
test/unittest/string/no-split.gravity

@@ -5,7 +5,7 @@
 };
 };
 
 
 func main () {
 func main () {
-	var s = "1 2 3 4 5 6 7 8 9 10"
+  var s = "1 2 3 4 5 6 7 8 9 10"
   var list = s.split("=")
   var list = s.split("=")
 
 
   return list[0] == s and list.count == 1
   return list[0] == s and list.count == 1

+ 1 - 1
test/unittest/string/split.gravity

@@ -6,7 +6,7 @@
 
 
 func main () {
 func main () {
 	var s = "1 2 3 4 5 6 7 8 9 10"
 	var s = "1 2 3 4 5 6 7 8 9 10"
-  var list = s.split(" ")
+	var list = s.split(" ")
 
 
 	var ret = true;
 	var ret = true;
 
 

+ 14 - 0
test/unittest/string_contains.gravity

@@ -0,0 +1,14 @@
+#unittest {
+    name: "String contains";
+    result: 1;
+};
+
+func main() {
+    var n = 0;
+    var s = "Bob and Alice";
+    
+    if (s.contains("Alice")) n += 1;
+    if (s.contains("Anna")) n += 1;
+    
+    return n;
+}

Some files were not shown because too many files changed in this diff