2023-05-05 18:26:07 +00:00
|
|
|
#include "syntax.h"
|
|
|
|
|
|
|
|
#include "eval.h"
|
|
|
|
#include "object.h"
|
|
|
|
|
|
|
|
#include <assert.h>
|
|
|
|
|
2023-05-07 13:28:45 +00:00
|
|
|
struct Object *syntax_begin(
|
|
|
|
struct Object *args,
|
|
|
|
struct Object *const environment
|
|
|
|
) {
|
2023-05-05 18:31:42 +00:00
|
|
|
assert(OBJECT_IS_LIST_HEAD(args));
|
|
|
|
struct Object *result = NULL;
|
|
|
|
while (!OBJECT_IS_NULL(args)) {
|
|
|
|
assert(Object_is_pair(args));
|
2023-05-07 13:28:45 +00:00
|
|
|
result = eval(args->pair.car, environment);
|
2023-05-05 20:49:04 +00:00
|
|
|
args = args->pair.cdr;
|
2023-05-05 18:31:42 +00:00
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2023-05-07 13:28:45 +00:00
|
|
|
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
|
|
|
|
) {
|
2023-05-05 18:26:07 +00:00
|
|
|
assert(Object_is_pair(args));
|
2023-05-05 20:49:04 +00:00
|
|
|
struct Object *const cond = args->pair.car;
|
|
|
|
struct Object *const then_else_list = args->pair.cdr;
|
2023-05-05 18:26:07 +00:00
|
|
|
assert(then_else_list);
|
|
|
|
assert(Object_is_pair(then_else_list));
|
2023-05-05 20:49:04 +00:00
|
|
|
struct Object *const then_branch = then_else_list->pair.car;
|
|
|
|
struct Object *const else_list = then_else_list->pair.cdr;
|
2023-05-05 18:26:07 +00:00
|
|
|
assert(else_list);
|
|
|
|
assert(Object_is_pair(else_list));
|
2023-05-05 20:49:04 +00:00
|
|
|
struct Object *const else_branch = else_list->pair.car;
|
|
|
|
assert(OBJECT_IS_NULL(else_list->pair.cdr));
|
2023-05-05 18:26:07 +00:00
|
|
|
|
|
|
|
if (Object_is_false(cond)) {
|
2023-05-07 13:28:45 +00:00
|
|
|
return eval(else_branch, environment);
|
2023-05-05 18:26:07 +00:00
|
|
|
} else {
|
2023-05-07 13:28:45 +00:00
|
|
|
return eval(then_branch, environment);
|
2023-05-05 18:26:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-05-07 13:28:45 +00:00
|
|
|
struct Object *syntax_quote(
|
|
|
|
struct Object *const args,
|
|
|
|
struct Object *const environment
|
|
|
|
) {
|
|
|
|
(void)environment; // unused
|
|
|
|
|
2023-05-05 18:26:07 +00:00
|
|
|
assert(Object_is_pair(args));
|
2023-05-05 20:49:04 +00:00
|
|
|
assert(OBJECT_IS_NULL(args->pair.cdr));
|
|
|
|
return args->pair.car;
|
2023-05-05 18:26:07 +00:00
|
|
|
}
|