8 #include "script/expr.h"
10 static char *string_duplicate(const char *str,
13 if (str_end != NULL && str > str_end) {
17 const size_t n = str_end == NULL ? strlen(str) : (size_t) (str_end - str);
18 char *dup_str = malloc(sizeof(char) * (n + 1));
19 if (dup_str == NULL) {
23 memcpy(dup_str, str, n);
29 struct Expr atom_as_expr(struct Atom *atom)
39 struct Expr cons_as_expr(struct Cons *cons)
49 static struct Atom *clone_atom(struct Atom *atom)
55 return create_number_atom(atom->num);
58 return create_string_atom(atom->str, NULL);
61 return create_symbol_atom(atom->sym, NULL);
67 struct Expr clone_expr(struct Expr expr)
71 return atom_as_expr(clone_atom(expr.atom));
76 clone_expr(expr.cons->car),
77 clone_expr(expr.cons->cdr)));
85 struct Expr void_expr(void)
94 void print_atom_as_sexpr(struct Atom *atom)
100 printf("%s", atom->sym);
104 printf("%f", atom->num);
108 printf("\"%s\"", atom->str);
113 void print_cons_as_sexpr(struct Cons *head)
117 struct Cons *cons = head;
120 print_expr_as_sexpr(cons->car);
122 while (cons->cdr.type == EXPR_CONS) {
123 cons = cons->cdr.cons;
125 print_expr_as_sexpr(cons->car);
128 if (cons->cdr.atom->type != ATOM_SYMBOL ||
129 strcmp("nil", cons->cdr.atom->sym) != 0) {
131 print_expr_as_sexpr(cons->cdr);
137 void print_expr_as_sexpr(struct Expr expr)
139 /* TODO(#296): print_expr_as_sexpr doesn't support lists */
142 print_atom_as_sexpr(expr.atom);
146 print_cons_as_sexpr(expr.cons);
156 void destroy_expr(struct Expr expr)
160 destroy_atom(expr.atom);
164 destroy_cons(expr.cons);
172 struct Cons *create_cons(struct Expr car, struct Expr cdr)
174 struct Cons *cons = malloc(sizeof(struct Cons));
185 void destroy_cons(struct Cons *cons)
187 destroy_expr(cons->car);
188 destroy_expr(cons->cdr);
192 struct Atom *create_number_atom(float num)
194 struct Atom *atom = malloc(sizeof(struct Atom));
198 atom->type = ATOM_NUMBER;
203 struct Atom *create_string_atom(const char *str, const char *str_end)
205 struct Atom *atom = malloc(sizeof(struct Atom));
209 atom->type = ATOM_STRING;
210 atom->str = string_duplicate(str, str_end);
211 if (atom->str == NULL) {
219 struct Atom *create_symbol_atom(const char *sym, const char *sym_end)
221 struct Atom *atom = malloc(sizeof(struct Atom));
225 atom->type = ATOM_SYMBOL;
226 atom->sym = string_duplicate(sym, sym_end);
227 if (atom->sym == NULL) {
235 void destroy_atom(struct Atom *atom)
237 switch (atom->type) {