summary refs log tree commit diff stats
path: root/lith.c
diff options
context:
space:
mode:
Diffstat (limited to 'lith.c')
-rw-r--r--lith.c61
1 files changed, 34 insertions, 27 deletions
diff --git a/lith.c b/lith.c
index 7eefa37..670a05c 100644
--- a/lith.c
+++ b/lith.c
@@ -184,46 +184,46 @@ static lith_value *read_expr(lith_st *L, char *start, char **end);
 
 static lith_value *read_list_expr(lith_st *L, char *start, char **end)
 {
-    lith_value *p, *r, *v;
+    lith_value *p, *expr, *list;
     char *t;
     *end = start;
-    v = p = L->nil;
+    list = p = L->nil;
     for (;;) {
         lex(L, *end, &t, end);
         if (LITH_IS_ERR(L)) return NULL;
-        if (*t == ')') return v;
+        if (*t == ')') return list;
         if (*t == '.' && (*end - t == 1)) {
             if (LITH_IS_NIL(p)) {
                 lith_simple_error(L, LITH_ERR_SYNTAX,
                     "improper lists do not start with '.'");
-                lith_free_value(v);
+                lith_free_value(list);
                 return NULL;
             }
-            r = read_expr(L, *end, end);
+            expr = read_expr(L, *end, end);
             if (LITH_IS_ERR(L)) {
-                 lith_free_value(v);
+                 lith_free_value(list);
                  return NULL;
             }
-            LITH_CDR(p) = r;
+            LITH_CDR(p) = expr;
             lex(L, *end, &t, end);
             if (LITH_IS_ERR(L) || (*t != ')')) {
                 lith_simple_error(L, LITH_ERR_SYNTAX,
                     "expecting ')' at the end of this improper list");
-                lith_free_value(v);
+                lith_free_value(list);
                 return NULL;
             }
-            return v;
+            return list;
         }
-        r = read_expr(L, t, end);
+        expr = read_expr(L, t, end);
         if (LITH_IS_ERR(L)) {
-            lith_free_value(v);
+            lith_free_value(list);
             return NULL;
         }
         if (LITH_IS_NIL(p)) {
-            v = LITH_CONS(L, r, L->nil);
-            p = v;
+            list = LITH_CONS(L, expr, L->nil);
+            p = list;
         } else {
-            LITH_CDR(p) = LITH_CONS(L, r, L->nil);
+            LITH_CDR(p) = LITH_CONS(L, expr, L->nil);
             p = LITH_CDR(p);
         }
     }
@@ -241,15 +241,14 @@ static lith_value *read_expr(lith_st *L, char *start, char **end)
         lith_simple_error(L, LITH_ERR_SYNTAX, "unbalanced parenthesis, expected an expression");
         return NULL;
     } else if ((*t == '\'') || (*t == '@') || (*t == ',') || (*t == '`')) {
-        s = ((*t == '\'')
-          ? "quote"
-          : (((*t == '@') || (*t == '`'))
-            ? "quasiquote"
-            : ((*t == ',')
-              ? ((t[1] == '@')
+        if (*t == '\'')
+            s = "quote";
+        else if ((*t == '@') || (*t == '`'))
+            s = "quasiquote";
+        else if (*t == ',')
+            s = (t[1] == '@')
                 ? "unquote-splicing"
-                : "unquote")
-              : "???" )));
+                : "unquote";
         p = LITH_CONS(L, lith_get_symbol(L, s), L->nil);
         v = read_expr(L, *end, end);
         if (!v) { lith_free_value(p); return NULL; }
@@ -1110,6 +1109,12 @@ lith_value *lith_eval_expr(lith_st *L, lith_env *V, lith_value *expr)
             if (!lith_expect_nargs(L, "quote", 1, rest, 1))
                 return NULL;
             return lith_copy_value(L, LITH_CAR(rest));
+        } else if (LITH_SYM_EQ(f, "eval!")) {
+            if (!lith_expect_nargs(L, "eval!", 1, rest, 1))
+                return NULL;
+            val = lith_eval_expr(L, V, LITH_CAR(rest));
+            if (!val) return NULL;
+            return lith_eval_expr(L, V, val); 
         } else if (LITH_SYM_EQ(f, "if")) {
             if (!lith_expect_nargs(L, "if", 3, rest, 1)) return NULL;
             val = lith_eval_expr(L, V, LITH_CAR(rest));
@@ -1264,18 +1269,20 @@ lith_value *lith_apply(lith_st *L, lith_value *f, lith_value *args)
     return r;
 }
 
-void lith_run_string(lith_st *L, lith_env *V, char *input)
+void lith_run_string(lith_st *L, lith_env *V, char *input, int repl)
 {
     char *end;
     lith_value *expr, *res;
     end = input;
-    L->filename = "<<string>>";
+    L->filename = repl ? "<<stdin>>" : "<<string>>";
     
     while (!LITH_IS_ERR(L)) {
         if ((expr = lith_read_expr(L, end, &end))) {
-            printf(">> ");
-            lith_print_value(expr, stdout);
-            putchar('\n');
+            if (!repl) {
+                printf(">> ");
+                lith_print_value(expr, stdout);
+                putchar('\n');
+            }
             if ((res = lith_eval_expr(L, V, expr))) {
                 printf("-> ");
                 lith_print_value(res, stdout);