diff options
-rw-r--r-- | examples/generated.csx | 16 | ||||
-rw-r--r-- | src/csx.c | 30 |
2 files changed, 27 insertions, 19 deletions
diff --git a/examples/generated.csx b/examples/generated.csx index 4c405c4..f6eac72 100644 --- a/examples/generated.csx +++ b/examples/generated.csx @@ -9,26 +9,18 @@ ] ] ]]] -[set map [fn [f l] [if [no l] [] - [pair [f [head l]] [map f [tail l]]] -]]] +[set map [fn [f l] [if l [pair [f [head l]] [map f [tail l]]]]]] [set id [fn args args]] -[set outstr [fn [str] [if str - [do [out [head str]] [outstr [tail str]]] - [] -]]] +[set outstr [fn [str] [if str [do [out [head str]] [outstr [tail str]]]]]] [set newline [fn [] [out 10]]] [set instr [fn [] [set c [in]] - [if [same c 10] - [] - [pair c [instr]] - ] + [if [no [same c 10]] [pair c [instr]]] ]] [outstr "-= loaded =-"] [newline] -[outstr "Hello, I am Conrad S. Xylander. What is your name?"] +[outstr "Hello, I am Casey Shawn Exton. What is your name?"] [newline] [outstr "> "] [set name [instr]] @@ -15,7 +15,8 @@ typedef enum csx_type { type_name, type_base, type_int, - type_fn + type_fn, + type_sx } csx_type; static csx_type type(void *p) @@ -222,6 +223,7 @@ static void *base_type(void *arg) case type_base: return csx_name("base"); case type_int: return csx_name("int"); case type_fn: return csx_name("fn"); + case type_sx: return csx_name("sx"); } return 0; } @@ -246,12 +248,20 @@ static void *base_fn(void *arg) return res; } +static void *base_sx(void *arg) +{ + fn_data *res = new(type_sx, sizeof(fn_data)); + res->params = head(arg); + res->body = tail(arg); + res->context = context; + return res; +} + static void *base_if(void *arg) { - void *saved = context; - void *res = csx_run(head(arg)); - context = saved; - return type(res) != type_null ? + if (type(arg) != type_pair) return null; + if (type(tail(arg)) != type_pair) return csx_run(head(arg)); + return type(csx_run(head(arg))) != type_null ? csx_run(head(tail(arg))) : csx_run(head(tail(tail(arg)))); } @@ -387,14 +397,19 @@ tailcall: return (*base)(ops); } } else if (type(fn) == type_fn) { - void *saved; void *res; + void *saved = context; ops = run_each(ops); - saved = context; context = new_pair(zip(fn->params, ops), fn->context); res = base_do(fn->body); context = saved; return res; + } else if (type(fn) == type_sx) { + void *saved = context; + context = new_pair(zip(fn->params, ops), fn->context); + arg = base_do(fn->body); + context = saved; + goto tailcall; } else if (type(fn) == type_pair) { pair_data *res = (void *)fn; int pos = *(int *)head(ops); @@ -425,6 +440,7 @@ static void new_context() base_set(csx_list(csx_name("type"), csx_base(base_type), 0)); base_set(csx_list(csx_name("do"), csx_base(base_do), 0)); base_set(csx_list(csx_name("fn"), csx_base(base_fn), 0)); + base_set(csx_list(csx_name("sx"), csx_base(base_sx), 0)); base_set(csx_list(csx_name("if"), csx_base(base_if), 0)); base_set(csx_list(csx_name("+"), csx_base(base_sum), 0)); base_set(csx_list(csx_name("*"), csx_base(base_prod), 0)); |