/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ /* $Rev$ $Date$ */ #ifndef tuscany_scheme_primitive_hpp #define tuscany_scheme_primitive_hpp /** * Script evaluator primitive functions. */ #include #include "stream.hpp" #include "function.hpp" #include "list.hpp" #include "tree.hpp" #include "value.hpp" #include "parallel.hpp" namespace tuscany { namespace scheme { const value primitiveSymbol("primitive"); const value quoteSymbol("'"); const value lambdaSymbol("lambda"); #ifdef WANT_THREADS const perthread_ptr displayOutStream; #else ostream* displayOutStream = NULL; #endif #ifdef WANT_THREADS perthread_ptr logOutStream; #else ostream* logOutStream = NULL; #endif inline const bool setupDisplay(ostream& out) { displayOutStream = &out; return true; } inline ostream& displayStream() { if (displayOutStream == NULL) return cout; return *displayOutStream; } inline const bool setupLog(ostream& out) { logOutStream = &out; return true; } inline ostream& logStream() { if (logOutStream == NULL) return cerr; return *logOutStream; } inline const value carProc(const list& args) { return car((list )car(args)); } inline const value cdrProc(const list& args) { return cdr((list )car(args)); } inline const value consProc(const list& args) { return cons(car(args), (list )cadr(args)); } inline const value listProc(const list& args) { return args; } inline const value assocProc(const list& args) { return assoc(car(args), (list)cadr(args)); } inline const value delAssocProc(const list& args) { return delAssoc(car(args), (list)cadr(args)); } inline const value substAssocProc(const list& args) { return substAssoc(car(args), (list)cadr(args), (list)caddr(args)); } inline const value treeDelAssocProc(const list& args) { return treeDelAssoc((list)car(args), (list)cadr(args)); } inline const value treeSubstAssocProc(const list& args) { return treeSubstAssoc((list)car(args), (list)cadr(args), (list)caddr(args)); } inline const value treeSelectAssocProc(const list& args) { return treeSelectAssoc((list)car(args), (list)cadr(args)); } inline const value nullProc(const list& args) { const value v(car(args)); if (isNil(v)) return true; if (isList(v)) return isNil(list(v)); return false; } inline const value equalProc(const list& args) { return (bool)(car(args) == cadr(args)); } inline const value greaterProc(const list& args) { return (bool)(car(args) > cadr(args)); } inline const value lesserProc(const list& args) { return (bool)(car(args) < cadr(args)); } inline const value addProc(const list& args) { if (isNil(cdr(args))) return (double)car(args); return (double)car(args) + (double)cadr(args); } inline const value subProc(const list& args) { if (isNil(cdr(args))) return (double)0 - (double)car(args); return (double)car(args) - (double)cadr(args); } inline const value mulProc(const list& args) { return (double)car(args) * (double)cadr(args); } inline const value divProc(const list& args) { return (double)car(args) / (double)cadr(args); } inline const value sqrtProc(const list& args) { return (double)sqrt((double)car(args)); } inline const value displayProc(const list& args) { if (isNil(args)) { displayStream() << endl; return true; } displayStream() << car(args); return displayProc(cdr(args)); } inline const value logProc(const list& args) { if (isNil(args)) { logStream() << endl; return true; } logStream() << car(args); return logProc(cdr(args)); } inline const value uuidProc(unused const list& args) { return mkuuid(); } inline const value cadrProc(const list& args) { return cadr((list )car(args)); } inline const value caddrProc(const list& args) { return caddr((list )car(args)); } inline const value cadddrProc(const list& args) { return cadddr((list )car(args)); } inline const value cddrProc(const list& args) { return cddr((list )car(args)); } inline const value cdddrProc(const list& args) { return cdddr((list )car(args)); } inline const value appendProc(const list& args) { return append((list )car(args), (list)cadr(args)); } inline const value startProc(unused const list& args) { return lvvlambda(); } inline const value stopProc(unused const list& args) { return lvvlambda(); } inline const value applyPrimitiveProcedure(const value& proc, list& args) { const lvvlambda func(cadr((list)proc)); return func(args); } inline const bool isPrimitiveProcedure(const value& proc) { return isTaggedList(proc, primitiveSymbol); } inline const bool isSelfEvaluating(const value& exp) { if(isNil(exp)) return true; if(isNumber(exp)) return true; if(isString(exp)) return true; if(isBool(exp)) return true; if(isLambda(exp)) return true; return false; } inline const value primitiveImplementation(const list& proc) { return car(cdr(proc)); } template inline const value primitiveProcedure(const F& f) { return mklist(primitiveSymbol, (lvvlambda)f); } inline const list primitiveProcedureNames() { return mklist("car") + "cdr" + "cons" + "list" + "null?" + "=" + "equal?" + "<" + ">" + "+" + "-" + "*" + "/" + "sqrt" + "assoc" + "del-assoc" + "subst-assoc" + "tree-select-assoc" + "tree-del-assoc" + "tree-subst-assoc" + "cadr" + "caddr" + "cadddr" + "cddr" + "cdddr" + "append" + "display" + "log" + "uuid" + "start" + "stop"; } inline const list primitiveProcedureObjects() { return mklist(primitiveProcedure(carProc)) + primitiveProcedure(cdrProc) + primitiveProcedure(consProc) + primitiveProcedure(listProc) + primitiveProcedure(nullProc) + primitiveProcedure(equalProc) + primitiveProcedure(equalProc) + primitiveProcedure(lesserProc) + primitiveProcedure(greaterProc) + primitiveProcedure(addProc) + primitiveProcedure(subProc) + primitiveProcedure(mulProc) + primitiveProcedure(divProc) + primitiveProcedure(sqrtProc) + primitiveProcedure(assocProc) + primitiveProcedure(delAssocProc) + primitiveProcedure(substAssocProc) + primitiveProcedure(treeSelectAssocProc) + primitiveProcedure(treeDelAssocProc) + primitiveProcedure(treeSubstAssocProc) + primitiveProcedure(cadrProc) + primitiveProcedure(caddrProc) + primitiveProcedure(cadddrProc) + primitiveProcedure(cddrProc) + primitiveProcedure(cdddrProc) + primitiveProcedure(appendProc) + primitiveProcedure(displayProc) + primitiveProcedure(logProc) + primitiveProcedure(uuidProc) + primitiveProcedure(startProc) + primitiveProcedure(stopProc); } inline const bool isFalse(const value& exp) { return (bool)exp == false; } inline const bool isTrue(const value& exp) { return (bool)exp == true; } inline const bool isQuoted(const value& exp) { return isTaggedList(exp, quoteSymbol); } inline const value textOfQuotation(const value& exp) { return car(cdr((list )exp)); } inline const value makeLambda(const list& parameters, const list& body) { return cons(lambdaSymbol, cons(parameters, body)); } } } #endif /* tuscany_scheme_primitive_hpp */