#include "eval.h"
#include "builtin.h"
#include "exc.h"
#include "consts.h"
#include "gc.h"
#include <cstdio>
extern Pair *empty_list;
EvalObj *eval_stack[EVAL_STACK_SIZE];
void Evaluator::add_builtin_routines() {
#define ADD_ENTRY(name, rout) \
do { \
SymObj *tmp = new SymObj(name); \
envt->add_binding(tmp, rout); \
delete tmp; \
} while (0)
#define ADD_BUILTIN_PROC(name, rout) \
ADD_ENTRY(name, new BuiltinProcObj(rout, name))
ADD_ENTRY("if", new SpecialOptIf());
ADD_ENTRY("lambda", new SpecialOptLambda());
ADD_ENTRY("define", new SpecialOptDefine());
ADD_ENTRY("set!", new SpecialOptSet());
ADD_ENTRY("quote", new SpecialOptQuote());
ADD_ENTRY("eval", new SpecialOptEval());
ADD_ENTRY("and", new SpecialOptAnd());
ADD_ENTRY("or", new SpecialOptOr());
ADD_ENTRY("apply", new SpecialOptApply());
ADD_ENTRY("delay", new SpecialOptDelay());
ADD_ENTRY("force", new SpecialOptForce());
ADD_BUILTIN_PROC("+", num_add);
ADD_BUILTIN_PROC("-", num_sub);
ADD_BUILTIN_PROC("*", num_mul);
ADD_BUILTIN_PROC("/", num_div);
ADD_BUILTIN_PROC("<", num_lt);
ADD_BUILTIN_PROC("<=", num_le);
ADD_BUILTIN_PROC(">", num_gt);
ADD_BUILTIN_PROC(">=", num_ge);
ADD_BUILTIN_PROC("=", num_eq);
ADD_BUILTIN_PROC("exact?", num_is_exact);
ADD_BUILTIN_PROC("inexact?", num_is_inexact);
ADD_BUILTIN_PROC("number?", is_number);
ADD_BUILTIN_PROC("complex?", is_complex);
ADD_BUILTIN_PROC("real?", is_real);
ADD_BUILTIN_PROC("rational?", is_rational);
ADD_BUILTIN_PROC("integer?", is_integer);
ADD_BUILTIN_PROC("abs", num_abs);
ADD_BUILTIN_PROC("modulo", num_mod);
ADD_BUILTIN_PROC("remainder", num_rem);
ADD_BUILTIN_PROC("quotient", num_quo);
ADD_BUILTIN_PROC("gcd", num_gcd);
ADD_BUILTIN_PROC("lcm", num_lcm);
ADD_BUILTIN_PROC("not", bool_not);
ADD_BUILTIN_PROC("boolean?", is_boolean);
ADD_BUILTIN_PROC("pair?", is_pair);
ADD_BUILTIN_PROC("cons", make_pair);
ADD_BUILTIN_PROC("car", pair_car);
ADD_BUILTIN_PROC("cdr", pair_cdr);
ADD_BUILTIN_PROC("set-car!", pair_set_car);