install_subr("car", "Fcar", 1); volatile function Fcar(x) { return car(x); } install_subr("cdr", "Fcdr", 1); volatile function Fcdr(x) { return cdr(x); } install_subr("cons", "Fcons", 2); volatile function Fcons(x, y) { return cons(x, y); } install_subr("atom", "Fatom", 1); volatile function Fatom(x) { if(typeof(x) != QH_List) return "t"; return "nil"; } install_subr("eq", "Feq", 2); volatile function Feq(x, y) { if(typeof(x) != typeof(y)) return "nil"; if(typeof(x) == QH_String) { if(!strcmp(x, y)) return "t"; return "nil"; } if(x == y) return "t"; return "nil"; } install_subr("quote", "Fquote", UNEVALLED); volatile function Fquote(x) { return car(x); } // (defun name (a1 a2 ... ) e1 e2 ... ) // => // x := (name (a1 a2 ... ) e1 e2 ... ) install_subr("defun", "Fdefun", UNEVALLED); volatile function Fdefun(x) { local name; local def; name = car(x); def = cdr(x); if(typeof(name) != QH_String) { error_message = "Illegal defun format."; return "nil"; } if(!equal(car(def), "nil") && typeof(car(def)) != QH_List) { writeln("Illegal defun format: ", car(x)); error_message = True; return "nil"; } if(equal(car(def), "nil")) def = cons(NIL, cdr(def)); install_new_function(name, def); return name; } install_subr("+", "Fadd", MANY); volatile function Fadd(x, narg) { local y = 0; local t; while(--narg >= 0) { t = x[narg]; if(typeof(t) != QH_Int) { write("+: Not a number: "); lisp::print(t); error_message = True; return 0; } y += t; } return y; } install_subr("-", "Fsub", MANY); volatile function Fsub(x, narg) { local y = 0; local t; if(narg == 0) return 0; if(narg == 1) { t = x[0]; if(typeof(t) != QH_Int) { write("-: Not a number: "); lisp::print(t); error_message = True; return 0; } return -t; } y = x[0]; while(--narg > 0) { t = x[narg]; if(typeof(t) != QH_Int) { write("-: Not a number: "); lisp::print(t); error_message = True; return 0; } y -= t; } return y; } install_subr("*", "Fmulti", MANY); volatile function Fmulti(x, narg) { local y = 1; local t; while(--narg >= 0) { t = x[narg]; if(typeof(t) != QH_Int) { write("*: Not a number: "); lisp::print(t); error_message = True; return 0; } y *= t; } return y; } install_subr("/", "Fdiv", MANY); volatile function Fdiv(x, narg) { local y; local t; local i; if(narg == 0) { error_message = "/: wrong number of arguments"; return 0; } y = x[0]; for(i = 1; i < narg; i++) { t = x[i]; if(typeof(t) != QH_Int) { write("/: Not a number: "); lisp::print(t); error_message = True; return 0; } y /= t; } return y; } // x := ((expr1 body1 ...) ...) install_subr("cond", "Fcond", UNEVALLED); volatile function Fcond(x) { local t; local body_list; while(typeof(x) == QH_List) { t = car(x); if(equal(eval(car(t)), "t")) { body_list = cdr(t); t = "nil"; while(typeof(body_list) == QH_List) { t = eval(car(body_list)); body_list = cdr(body_list); } return t; } x = cdr(x); } return "nil"; } install_subr("equal", "Fequal", 2); volatile function Fequal(x, y) { if(equal(x, y)) return "t"; return "nil"; } install_subr("<", "Flt", 2); volatile function Flt(x, y) { if(typeof(x) != QH_Int) { write("<: Not a number: "); lisp::print(x); error_message = True; return "nil"; } if(typeof(y) != QH_Int) { write("<: Not a number: "); lisp::print(y); error_message = True; return "nil"; } if(x < y) return "t"; return "nil"; } install_subr(">", "Fgt", 2); volatile function Fgt(x, y) { if(typeof(x) != QH_Int) { write(">: Not a number: "); lisp::print(x); error_message = True; return "nil"; } if(typeof(y) != QH_Int) { write(">: Not a number: "); lisp::print(y); error_message = True; return "nil"; } if(x > y) return "t"; return "nil"; } install_subr("<=", "Fle", 2); volatile function Fle(x, y) { if(typeof(x) != QH_Int) { write("<=: Not a number: "); lisp::print(x); error_message = True; return "nil"; } if(typeof(y) != QH_Int) { write("<=: Not a number: "); lisp::print(y); error_message = True; return "nil"; } if(x <= y) return "t"; return "nil"; } install_subr(">=", "Fge", 2); volatile function Fge(x, y) { if(typeof(x) != QH_Int) { write(">=: Not a number: "); lisp::print(x); error_message = True; return "nil"; } if(typeof(y) != QH_Int) { write(">=: Not a number: "); lisp::print(y); error_message = True; return "nil"; } if(x >= y) return "t"; return "nil"; } install_subr("print", "Fprint", 1); volatile function Fprint(x) { lisp::print(x); } install_subr("prin1", "Fprin1", 1); volatile function Fprin1(x) { lisp::prin1(x); } install_subr("eval", "Feval", 1); volatile function Feval(expr) { return eval(expr); } install_subr("load", "Fload", 1); volatile function Fload(fname) { if(typeof(fname) != QH_String) { write("load: Invalid argument: "); lisp::print(fname); error_message = True; return "nil"; } eval_file(fname); return fname; } install_subr("quit", "Fquit", 0); volatile function Fquit() { exit(0); }