8 #include "script/expr.h"
12 struct Expr atom_as_expr(struct Atom *atom)
22 struct Expr cons_as_expr(struct Cons *cons)
32 struct Expr void_expr(void)
41 void print_atom_as_sexpr(struct Atom *atom)
47 printf("%s", atom->sym);
51 printf("%ld", atom->num);
55 printf("\"%s\"", atom->str);
64 void print_cons_as_sexpr(struct Cons *head)
68 struct Cons *cons = head;
71 print_expr_as_sexpr(cons->car);
73 while (cons->cdr.type == EXPR_CONS) {
74 cons = cons->cdr.cons;
76 print_expr_as_sexpr(cons->car);
79 if (cons->cdr.atom->type != ATOM_SYMBOL ||
80 strcmp("nil", cons->cdr.atom->sym) != 0) {
82 print_expr_as_sexpr(cons->cdr);
88 void print_expr_as_sexpr(struct Expr expr)
92 print_atom_as_sexpr(expr.atom);
96 print_cons_as_sexpr(expr.cons);
104 void destroy_expr(struct Expr expr)
108 destroy_atom(expr.atom);
112 destroy_cons(expr.cons);
120 struct Cons *create_cons(Gc *gc, struct Expr car, struct Expr cdr)
122 struct Cons *cons = malloc(sizeof(struct Cons));
130 if (gc_add_expr(gc, cons_as_expr(cons)) < 0) {
138 void destroy_cons(struct Cons *cons)
143 struct Atom *create_number_atom(Gc *gc, long int num)
145 struct Atom *atom = malloc(sizeof(struct Atom));
149 atom->type = ATOM_NUMBER;
152 if (gc_add_expr(gc, atom_as_expr(atom)) < 0) {
160 struct Atom *create_string_atom(Gc *gc, const char *str, const char *str_end)
162 struct Atom *atom = malloc(sizeof(struct Atom));
168 atom->type = ATOM_STRING;
169 atom->str = string_duplicate(str, str_end);
171 if (atom->str == NULL) {
175 if (gc_add_expr(gc, atom_as_expr(atom)) < 0) {
183 if (atom->str != NULL) {
192 struct Atom *create_symbol_atom(Gc *gc, const char *sym, const char *sym_end)
194 struct Atom *atom = malloc(sizeof(struct Atom));
200 atom->type = ATOM_SYMBOL;
201 atom->sym = string_duplicate(sym, sym_end);
203 if (atom->sym == NULL) {
207 if (gc_add_expr(gc, atom_as_expr(atom)) < 0) {
215 if (atom->sym != NULL) {
224 struct Atom *create_native_atom(Gc *gc, NativeFunction fun, void *param)
226 struct Atom *atom = malloc(sizeof(struct Atom));
232 atom->type = ATOM_NATIVE;
233 atom->native.fun = fun;
234 atom->native.param = param;
236 if (gc_add_expr(gc, atom_as_expr(atom)) < 0) {
250 void destroy_atom(struct Atom *atom)
252 switch (atom->type) {
267 static int atom_as_sexpr(struct Atom *atom, char *output, size_t n)
272 switch (atom->type) {
274 return snprintf(output, n, "%s", atom->sym);
277 return snprintf(output, n, "%ld", atom->num);
280 return snprintf(output, n, "\"%s\"", atom->str);
283 return snprintf(output, n, "<native>");
289 static int cons_as_sexpr(struct Cons *head, char *output, size_t n)
294 /* TODO(#378): cons_as_sexpr does not handle encoding errors of snprintf */
296 struct Cons *cons = head;
300 int c = snprintf(output, n, "(");
305 c += expr_as_sexpr(cons->car, output + c, (size_t) (m - c));
310 while (cons->cdr.type == EXPR_CONS) {
311 cons = cons->cdr.cons;
313 c += snprintf(output + c, (size_t) (m - c), " ");
318 c += expr_as_sexpr(cons->car, output + c, (size_t) (m - c));
324 if (cons->cdr.atom->type != ATOM_SYMBOL ||
325 strcmp("nil", cons->cdr.atom->sym) != 0) {
327 c += snprintf(output + c, (size_t) (m - c), " . ");
332 c += expr_as_sexpr(cons->cdr, output + c, (size_t) (m - c));
338 c += snprintf(output + c, (size_t) (m - c), ")");
346 int expr_as_sexpr(struct Expr expr, char *output, size_t n)
350 return atom_as_sexpr(expr.atom, output, n);
353 return cons_as_sexpr(expr.cons, output, n);