]> git.lizzy.rs Git - nothing.git/blobdiff - src/ebisp/expr.c
Add TODO(#928)
[nothing.git] / src / ebisp / expr.c
index 16b4277df5bedae89185483cf97cc8fd13592f35..67e6abc95294a6b2f43a647f6d463eddbc6d25e3 100644 (file)
@@ -7,7 +7,7 @@
 
 #include "ebisp/expr.h"
 #include "ebisp/gc.h"
-#include "str.h"
+#include "system/str.h"
 
 struct Expr atom_as_expr(struct Atom *atom)
 {
@@ -55,12 +55,49 @@ void print_atom_as_sexpr(FILE *stream, struct Atom *atom)
         fprintf(stream, "\"%s\"", atom->str);
         break;
 
+    case ATOM_LAMBDA:
+        /* TODO(#649): Print LAMBDAs with arglists (and maybe bodies) in print_atom_as_sexpr and atom_as_sexpr */
+        fprintf(stream, "<lambda>");
+        break;
+
     case ATOM_NATIVE:
         fprintf(stream, "<native>");
         break;
     }
 }
 
+static void print_atom_as_c(FILE *stream, struct Atom *atom)
+{
+    trace_assert(stream);
+    trace_assert(atom);
+
+    switch(atom->type) {
+    case ATOM_SYMBOL:
+        fprintf(stream, "SYMBOL(gc, \"%s\")", atom->sym);
+        break;
+
+    case ATOM_NUMBER:
+        fprintf(stream, "NUMBER(gc, %ld)", atom->num);
+        break;
+
+    case ATOM_STRING:
+        fprintf(stream, "STRING(gc, \"%s\")", atom->str);
+        break;
+
+    case ATOM_LAMBDA:
+        fprintf(stream, "CONS(gc, SYMBOL(gc, \"lambda\"), CONS(gc, ");
+        print_expr_as_c(stream, atom->lambda.args_list);
+        fprintf(stream, ", CONS(gc, ");
+        print_expr_as_c(stream, atom->lambda.body);
+        fprintf(stream, ")))");
+        break;
+
+    case ATOM_NATIVE:
+        fprintf(stream, "NIL(gc)");
+        break;
+    }
+}
+
 void print_cons_as_sexpr(FILE *stream, struct Cons *head)
 {
     trace_assert(head);
@@ -85,6 +122,18 @@ void print_cons_as_sexpr(FILE *stream, struct Cons *head)
     fprintf(stream, ")");
 }
 
+static void print_cons_as_c(FILE *stream, struct Cons *cons)
+{
+    trace_assert(stream);
+    trace_assert(cons);
+
+    fprintf(stream, "CONS(gc, ");
+    print_expr_as_c(stream, cons->car);
+    fprintf(stream, ", ");
+    print_expr_as_c(stream, cons->cdr);
+    fprintf(stream, ")");
+}
+
 void print_expr_as_sexpr(FILE *stream, struct Expr expr)
 {
     switch (expr.type) {
@@ -101,6 +150,25 @@ void print_expr_as_sexpr(FILE *stream, struct Expr expr)
     }
 }
 
+void print_expr_as_c(FILE *stream, struct Expr expr)
+{
+    trace_assert(stream);
+    (void) expr;
+
+    switch (expr.type) {
+    case EXPR_ATOM:
+        print_atom_as_c(stream, expr.atom);
+        break;
+
+    case EXPR_CONS:
+        print_cons_as_c(stream, expr.cons);
+        break;
+
+    case EXPR_VOID:
+        break;
+    }
+}
+
 void destroy_expr(struct Expr expr)
 {
     switch (expr.type) {
@@ -221,6 +289,33 @@ error:
     return NULL;
 }
 
+struct Atom *create_lambda_atom(Gc *gc, struct Expr args_list, struct Expr body, struct Expr envir)
+{
+    struct Atom *atom = malloc(sizeof(struct Atom));
+
+    if (atom == NULL) {
+        goto error;
+    }
+
+    atom->type = ATOM_LAMBDA;
+    atom->lambda.args_list = args_list;
+    atom->lambda.body = body;
+    atom->lambda.envir = envir;
+
+    if (gc_add_expr(gc, atom_as_expr(atom)) < 0) {
+        goto error;
+    }
+
+    return atom;
+
+error:
+    if (atom != NULL) {
+        free(atom);
+    }
+
+    return NULL;
+}
+
 struct Atom *create_native_atom(Gc *gc, NativeFunction fun, void *param)
 {
     struct Atom *atom = malloc(sizeof(struct Atom));
@@ -255,6 +350,7 @@ void destroy_atom(struct Atom *atom)
         free(atom->str);
     } break;
 
+    case ATOM_LAMBDA:
     case ATOM_NATIVE:
     case ATOM_NUMBER: {
         /* Nothing */
@@ -279,6 +375,9 @@ static int atom_as_sexpr(struct Atom *atom, char *output, size_t n)
     case ATOM_STRING:
         return snprintf(output, n, "\"%s\"", atom->str);
 
+    case ATOM_LAMBDA:
+        return snprintf(output, n, "<lambda>");
+
     case ATOM_NATIVE:
         return snprintf(output, n, "<native>");
     }
@@ -376,6 +475,7 @@ const char *atom_type_as_string(enum AtomType atom_type)
     case ATOM_SYMBOL: return "ATOM_SYMBOL";
     case ATOM_NUMBER: return "ATOM_NUMBER";
     case ATOM_STRING: return "ATOM_STRING";
+    case ATOM_LAMBDA: return "ATOM_LAMBDA";
     case ATOM_NATIVE: return "ATOM_NATIVE";
     }