aboutsummaryrefslogtreecommitdiff
path: root/c/stepA_interop.c
diff options
context:
space:
mode:
authorJoel Martin <github@martintribe.org>2014-12-18 20:33:49 -0600
committerJoel Martin <github@martintribe.org>2015-01-09 16:16:50 -0600
commitb8ee29b22fbaa7a01f2754b4d6dd9af52e02017c (patch)
treef4d977ed220e9a3f665cfbf4f68770a81e4c2095 /c/stepA_interop.c
parentaaba249304b184e12e2445ab22d66df1f39a51a5 (diff)
downloadmal-b8ee29b22fbaa7a01f2754b4d6dd9af52e02017c.tar.gz
mal-b8ee29b22fbaa7a01f2754b4d6dd9af52e02017c.zip
All: add keywords.
Also, fix nth and count to match cloure.
Diffstat (limited to 'c/stepA_interop.c')
-rw-r--r--c/stepA_interop.c29
1 files changed, 17 insertions, 12 deletions
diff --git a/c/stepA_interop.c b/c/stepA_interop.c
index b4b7431..05e9f65 100644
--- a/c/stepA_interop.c
+++ b/c/stepA_interop.c
@@ -62,15 +62,15 @@ int is_macro_call(MalVal *ast, Env *env) {
if (!ast || ast->type != MAL_LIST) { return 0; }
MalVal *a0 = _nth(ast, 0);
return (a0->type & MAL_SYMBOL) &&
- env_find(env, a0->val.string) &&
- env_get(env, a0->val.string)->ismacro;
+ env_find(env, a0) &&
+ env_get(env, a0)->ismacro;
}
MalVal *macroexpand(MalVal *ast, Env *env) {
if (!ast || mal_error) return NULL;
while (is_macro_call(ast, env)) {
MalVal *a0 = _nth(ast, 0);
- MalVal *mac = env_get(env, a0->val.string);
+ MalVal *mac = env_get(env, a0);
// TODO: this is weird and limits it to 20. FIXME
ast = _apply(mac, _rest(ast));
}
@@ -81,7 +81,7 @@ MalVal *eval_ast(MalVal *ast, Env *env) {
if (!ast || mal_error) return NULL;
if (ast->type == MAL_SYMBOL) {
//g_print("EVAL symbol: %s\n", ast->val.string);
- return env_get(env, ast->val.string);
+ return env_get(env, ast);
} else if ((ast->type == MAL_LIST) || (ast->type == MAL_VECTOR)) {
//g_print("EVAL sequential: %s\n", _pr_str(ast,1));
MalVal *el = _map2((MalVal *(*)(void*, void*))EVAL, ast, env);
@@ -134,7 +134,8 @@ MalVal *EVAL(MalVal *ast, Env *env) {
MalVal *a1 = _nth(ast, 1),
*a2 = _nth(ast, 2);
MalVal *res = EVAL(a2, env);
- env_set(env, a1->val.string, res);
+ if (mal_error) return NULL;
+ env_set(env, a1, res);
return res;
} else if ((a0->type & MAL_SYMBOL) &&
strcmp("let*", a0->val.string) == 0) {
@@ -151,7 +152,7 @@ MalVal *EVAL(MalVal *ast, Env *env) {
key = g_array_index(a1->val.array, MalVal*, i);
val = g_array_index(a1->val.array, MalVal*, i+1);
assert_type(key, MAL_SYMBOL, "let* bind to non-symbol");
- env_set(let_env, key->val.string, EVAL(val, let_env));
+ env_set(let_env, key, EVAL(val, let_env));
}
ast = a2;
env = let_env;
@@ -172,8 +173,9 @@ MalVal *EVAL(MalVal *ast, Env *env) {
MalVal *a1 = _nth(ast, 1),
*a2 = _nth(ast, 2);
MalVal *res = EVAL(a2, env);
+ if (mal_error) return NULL;
res->ismacro = TRUE;
- env_set(env, a1->val.string, res);
+ env_set(env, a1, res);
return res;
} else if ((a0->type & MAL_SYMBOL) &&
strcmp("macroexpand", a0->val.string) == 0) {
@@ -220,8 +222,9 @@ MalVal *EVAL(MalVal *ast, Env *env) {
if (!cond || mal_error) return NULL;
if (cond->type & (MAL_FALSE|MAL_NIL)) {
// eval false slot form
- ast = _nth(ast, 3);
- if (!ast) {
+ if (ast->val.array->len > 3) {
+ ast = _nth(ast, 3);
+ } else {
return &mal_nil;
}
} else {
@@ -293,11 +296,13 @@ void init_repl_env(int argc, char *argv[]) {
// core.c: defined using C
int i;
for(i=0; i < (sizeof(core_ns) / sizeof(core_ns[0])); i++) {
- env_set(repl_env, core_ns[i].name,
+ env_set(repl_env,
+ malval_new_symbol(core_ns[i].name),
malval_new_function(core_ns[i].func, core_ns[i].arg_cnt));
}
MalVal *do_eval(MalVal *ast) { return EVAL(ast, repl_env); }
- env_set(repl_env, "eval",
+ env_set(repl_env,
+ malval_new_symbol("eval"),
malval_new_function((void*(*)(void *))do_eval, 1));
MalVal *_argv = _listX(0);
@@ -305,7 +310,7 @@ void init_repl_env(int argc, char *argv[]) {
MalVal *arg = malval_new_string(argv[i]);
g_array_append_val(_argv->val.array, arg);
}
- env_set(repl_env, "*ARGV*", _argv);
+ env_set(repl_env, malval_new_symbol("*ARGV*"), _argv);
// core.mal: defined using the language itself
RE(repl_env, "", "(def! *host-language* \"c\")");