#include "syntax.h" #include "eval.h" #include "object.h" #include /******************************************* * Special syntax to use in the executable * *******************************************/ struct Object *syntax_repl( struct Object *args, struct Object *const environment ) { return eval(args, environment); } struct Object *syntax_script( struct Object *args, struct Object *const environment ) { return eval(args, environment); } /******************* * Syntax keywords * *******************/ struct Object *syntax_begin( struct Object *args, struct Object *const environment ) { assert(OBJECT_IS_LIST_HEAD(args)); struct Object *result = NULL; while (!OBJECT_IS_NULL(args)) { assert(Object_is_pair(args)); result = eval(args->pair.car, environment); args = args->pair.cdr; } return result; } struct Object *syntax_define( struct Object *const args, struct Object *const environment ) { assert(Object_is_pair(args)); struct Object *const name = args->pair.car; assert(Object_is_symbol(name)); assert(Object_is_pair(args->pair.cdr)); struct Object *const value_expr = args->pair.cdr->pair.car; assert(OBJECT_IS_NULL(args->pair.cdr->pair.cdr)); assert(Object_is_pair(environment)); assert(OBJECT_IS_NULL(environment->pair.cdr)); assert(OBJECT_IS_LIST_HEAD(environment->pair.car)); environment->pair.car = Object_new_pair( Object_new_pair(name, eval(value_expr, environment)), environment->pair.car ); return NULL; } struct Object *syntax_if( struct Object *const args, struct Object *const environment ) { assert(Object_is_pair(args)); struct Object *const cond = args->pair.car; struct Object *const then_else_list = args->pair.cdr; assert(then_else_list); assert(Object_is_pair(then_else_list)); struct Object *const then_branch = then_else_list->pair.car; struct Object *const else_list = then_else_list->pair.cdr; assert(else_list); assert(Object_is_pair(else_list)); struct Object *const else_branch = else_list->pair.car; assert(OBJECT_IS_NULL(else_list->pair.cdr)); if (Object_is_false(cond)) { return eval(else_branch, environment); } else { return eval(then_branch, environment); } } struct Object *syntax_quote( struct Object *const args, struct Object *const environment ) { (void)environment; // unused assert(Object_is_pair(args)); assert(OBJECT_IS_NULL(args->pair.cdr)); return args->pair.car; }