#include "ebisp/expr.h"
#include "ebisp/gc.h"
-#include "str.h"
+#include "system/str.h"
struct Expr atom_as_expr(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);
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) {
}
}
+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) {
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));
free(atom->str);
} break;
+ case ATOM_LAMBDA:
case ATOM_NATIVE:
case ATOM_NUMBER: {
/* Nothing */
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>");
}
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";
}