8 #include "script/expr.h"
11 static char *string_duplicate(const char *str,
14 if (str_end != NULL && str > str_end) {
18 const size_t n = str_end == NULL ? strlen(str) : (size_t) (str_end - str);
19 char *dup_str = malloc(sizeof(char) * (n + 1));
20 if (dup_str == NULL) {
24 memcpy(dup_str, str, n);
30 struct Expr atom_as_expr(struct Atom *atom)
40 struct Expr cons_as_expr(struct Cons *cons)
50 static struct Atom *clone_atom(Gc *gc, struct Atom *atom)
56 return create_number_atom(gc, atom->num);
59 return create_string_atom(gc, atom->str, NULL);
62 return create_symbol_atom(gc, atom->sym, NULL);
68 struct Expr clone_expr(Gc *gc, struct Expr expr)
72 return atom_as_expr(clone_atom(gc, expr.atom));
77 clone_expr(gc, expr.cons->car),
78 clone_expr(gc, expr.cons->cdr)));
86 struct Expr void_expr(void)
95 void print_atom_as_sexpr(struct Atom *atom)
101 printf("%s", atom->sym);
105 printf("%f", atom->num);
109 printf("\"%s\"", atom->str);
114 void print_cons_as_sexpr(struct Cons *head)
118 struct Cons *cons = head;
121 print_expr_as_sexpr(cons->car);
123 while (cons->cdr.type == EXPR_CONS) {
124 cons = cons->cdr.cons;
126 print_expr_as_sexpr(cons->car);
129 if (cons->cdr.atom->type != ATOM_SYMBOL ||
130 strcmp("nil", cons->cdr.atom->sym) != 0) {
132 print_expr_as_sexpr(cons->cdr);
138 void print_expr_as_sexpr(struct Expr expr)
140 /* TODO(#296): print_expr_as_sexpr doesn't support lists */
143 print_atom_as_sexpr(expr.atom);
147 print_cons_as_sexpr(expr.cons);
157 void destroy_expr_rec(struct Expr expr)
161 destroy_atom(expr.atom);
165 destroy_cons_rec(expr.cons);
173 void destroy_expr(struct Expr expr)
177 destroy_atom(expr.atom);
181 destroy_cons(expr.cons);
189 struct Cons *create_cons(Gc *gc, struct Expr car, struct Expr cdr)
191 struct Cons *cons = malloc(sizeof(struct Cons));
199 if (gc_add_expr(gc, cons_as_expr(cons)) < 0) {
207 void destroy_cons_rec(struct Cons *cons)
209 destroy_expr_rec(cons->car);
210 destroy_expr_rec(cons->cdr);
214 void destroy_cons(struct Cons *cons)
219 struct Atom *create_number_atom(Gc *gc, float num)
221 struct Atom *atom = malloc(sizeof(struct Atom));
225 atom->type = ATOM_NUMBER;
228 if (gc_add_expr(gc, atom_as_expr(atom)) < 0) {
236 struct Atom *create_string_atom(Gc *gc, const char *str, const char *str_end)
238 struct Atom *atom = malloc(sizeof(struct Atom));
244 atom->type = ATOM_STRING;
245 atom->str = string_duplicate(str, str_end);
247 if (atom->str == NULL) {
251 if (gc_add_expr(gc, atom_as_expr(atom)) < 0) {
259 if (atom->str != NULL) {
268 struct Atom *create_symbol_atom(Gc *gc, const char *sym, const char *sym_end)
270 struct Atom *atom = malloc(sizeof(struct Atom));
276 atom->type = ATOM_SYMBOL;
277 atom->sym = string_duplicate(sym, sym_end);
279 if (atom->sym == NULL) {
283 if (gc_add_expr(gc, atom_as_expr(atom)) < 0) {
291 if (atom->sym != NULL) {
300 void destroy_atom(struct Atom *atom)
302 switch (atom->type) {