All: add keywords.
[jackhill/mal.git] / c / step9_try.c
index 395a7f0..ffba2f9 100644 (file)
@@ -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) {
@@ -215,8 +217,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 {
@@ -288,11 +291,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);
@@ -300,10 +305,9 @@ 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\")");
     RE(repl_env, "", "(def! not (fn* (a) (if a false true)))");
     RE(repl_env, "",
        "(def! load-file (fn* (f) (eval (read-string (str \"(do \" (slurp f) \")\")))))");
@@ -328,7 +332,6 @@ int main(int argc, char *argv[])
     }
 
     // repl loop
-    RE(repl_env, "", "(println (str \"Mal [\" *host-language* \"]\"))");
     for(;;) {
         exp = RE(repl_env, prompt, NULL);
         if (mal_error && strcmp("EOF", mal_error->val.string) == 0) {