1
0
Fork 0
lesson-lisp/src/syntax.c

99 lines
2.5 KiB
C

#include "syntax.h"
#include "eval.h"
#include "object.h"
#include <assert.h>
/*******************************************
* 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;
}