// --------------------------------------------------------------------------- // - Binding.cpp - // - afnix engine - builtin binding functions implementation - // --------------------------------------------------------------------------- // - This program is free software; you can redistribute it and/or modify - // - it provided that this copyright notice is kept intact. - // - - // - This program is distributed in the hope that it will be useful, but - // - without any warranty; without even the implied warranty of - // - merchantability or fitness for a particular purpose. In no event shall - // - the copyright holder be liable for any direct, indirect, incidental or - // - special damages arising in any way out of the use of this software. - // --------------------------------------------------------------------------- // - copyright (c) 1999-2007 amaury darsch - // --------------------------------------------------------------------------- #include "Cons.hpp" #include "Builtin.hpp" #include "Promise.hpp" #include "Globalset.hpp" #include "Exception.hpp" namespace afnix { // const reserved function implementation Object* builtin_const (Runnable* robj, Nameset* nset, Cons* args) { long len = (args == nilp) ? 0 : args->length (); if (len == 0) return nilp; if (len == 2) { Object* car = args->getcar (); Object* cdr = args->getcadr (); Object* obj = (cdr == nilp) ? nilp : cdr->eval (robj, nset); return (car == nilp) ? nilp : car->cdef (robj, nset, obj); } if ((len == 3) || (len == 4)) { Object* car = args->getcar (); Object* obj = builtin_gamma (robj, nset, args->getcdr ()); return (car == nilp) ? nilp : car->cdef (robj, nset, obj); } // invalid number of arguments throw Exception ("argument-error", "invalid number of arguments with const"); } // trans reserved function implementation Object* builtin_trans (Runnable* robj, Nameset* nset, Cons* args) { long len = (args == nilp) ? 0 : args->length (); if (len == 0) return nilp; if (len == 2) { Object* car = args->getcar (); Object* cdr = args->getcadr (); Object* obj = (cdr == nilp) ? nilp : cdr->eval (robj, nset); return (car == nilp) ? nilp : car->vdef (robj, nset, obj); } if ((len == 3) || (len == 4)) { Object* car = args->getcar (); Object* obj = builtin_lambda (robj, nset, args->getcdr ()); return (car == nilp) ? nilp : car->vdef (robj, nset, obj); } // invalid number of arguments throw Exception ("argument-error", "invalid number of arguments with trans"); } // nameset reserved function implementation Object* builtin_nameset (Runnable* robj, Nameset* nset, Cons* args) { long len = (args == nilp) ? 0 : args->length (); if (len == 0) return new Globalset; if (len == 1) { Object* car = args->getcar (); Object* obj = (car == nilp) ? nilp : car->eval (robj, nset); Nameset* nset = dynamic_cast (obj); if (nset == nilp) throw Exception ("type-error", "invalid object with nameset", Object::repr (obj)); return new Globalset (nset); } throw Exception ("argument-error", "too many arguments with nameset"); } // delay builtin function implementation Object* builtin_delay (Runnable* robj, Nameset* nset, Cons* args) { long len = (args == nilp) ? 0 : args->length (); if (len != 1) throw Exception ("argument-error", "invalid number of arguments with delay"); return new Promise (args->getcar ()); } // force the evaluation of a promise Object* builtin_force (Runnable* robj, Nameset* nset, Cons* args) { long len = (args == nilp) ? 0 : args->length (); if (len != 1) throw Exception ("argument-error", "invalid number of arguments with force"); // get the car and evaluate it to an object Object* car = args->getcar (); Object* obj = (car == nilp) ? nilp : car->eval (robj, nset); // try to map a promise Promise* prm = dynamic_cast (obj); if (prm == nilp) return obj; return prm->force (robj, nset); } }