diff options
Diffstat (limited to '')
-rw-r--r-- | cpp/sca/modules/eval/eval.hpp | 261 |
1 files changed, 70 insertions, 191 deletions
diff --git a/cpp/sca/modules/eval/eval.hpp b/cpp/sca/modules/eval/eval.hpp index 23e9554aa8..28e1d01ffc 100644 --- a/cpp/sca/modules/eval/eval.hpp +++ b/cpp/sca/modules/eval/eval.hpp @@ -23,10 +23,10 @@ #define tuscany_eval_eval_hpp /** - * Script evaluator core evaluation logic. + * Core script evaluation logic. */ -#include <string> +#include <string.h> #include "list.hpp" #include "value.hpp" #include "primitive.hpp" @@ -36,8 +36,11 @@ namespace tuscany { +const value eval(const value& exp, Env& env); + const value compoundProcedureSymbol("compound-procedure"); const value procedureSymbol("procedure"); +const value applySymbol("apply"); const value beginSymbol("begin"); const value condSymbol("cond"); const value elseSymbol("else"); @@ -67,6 +70,10 @@ const value makeProcedure(const list<value>& parameters, const value& body, cons return value(makeList(procedureSymbol, value(parameters), body, value(env))); } +const bool isApply(const value& exp) { + return isTaggedList(exp, applySymbol); +} + const bool isApplication(const value& exp) { return isList(exp); } @@ -79,6 +86,20 @@ const list<value> operands(const value& exp) { return cdr((list<value> )exp); } +const list<value> listOfValues(const list<value> exps, Env& env) { + if(exps == list<value> ()) + return list<value> (); + return cons(eval(car(exps), env), listOfValues(cdr(exps), env)); +} + +const value applyOperat(const value& exp) { + return cadr((list<value> )exp); +} + +const value applyOperand(const value& exp) { + return caddr((list<value> )exp); +} + const bool isCompoundProcedure(const value& procedure) { return isTaggedList(procedure, procedureSymbol); } @@ -103,10 +124,32 @@ const value firstExp(const list<value>& seq) { return car(seq); } +const list<value> restExp(const list<value>& seq) { + return cdr(seq); +} + const value makeBegin(const list<value> seq) { return value(cons(beginSymbol, seq)); } +const value evalSequence(const list<value>& exps, Env& env) { + if(isLastExp(exps)) + return eval(firstExp(exps), env); + eval(firstExp(exps), env); + return evalSequence(restExp(exps), env); +} + +const value applyProcedure(const value& procedure, list<value>& arguments) { + if(isPrimitiveProcedure(procedure)) + return applyPrimitiveProcedure(procedure, arguments); + if(isCompoundProcedure(procedure)) { + Env env = extendEnvironment(procedureParameters(procedure), arguments, procedureEnvironment(procedure)); + return evalSequence(procedureBody(procedure), env); + } + std::cout << "Unknown procedure type " << procedure << "\n"; + return value(); +} + const value sequenceToExp(const list<value> exps) { if(exps == list<value> ()) return value(list<value>()); @@ -175,208 +218,44 @@ value condToIf(const value& exp) { return expandClauses(condClauses(exp)); } -const lambda<value(Env&)> analyze(const value exp); - -struct evalUndefinedLambda { - evalUndefinedLambda() { - } - - const value operator()(Env& env) const { - return value(); - } -}; - -struct evalSelfEvaluatingLambda { - const value exp; - evalSelfEvaluatingLambda(const value& exp) : exp(exp) { - } - const value operator()(Env& env) const { - return exp; - } -}; - -const lambda<value(Env&)> analyzeSelfEvaluating(value exp) { - return lambda<value(Env&)>(evalSelfEvaluatingLambda(exp)); -} - -struct evalQuotedLambda { - const value qval; - evalQuotedLambda(const value& qval) : qval(qval) { - } - const value operator()(Env& env) const { - return qval; - } -}; - -const lambda<value(Env&)> analyzeQuoted(const value& exp) { - return lambda<value(Env&)>(evalQuotedLambda(textOfQuotation(exp))); -} - -struct evalVariableLambda { - const value var; - evalVariableLambda(const value& var) : var(var) { - } - const value operator()(Env& env) const { - return lookupVariableValue(var, env); - } -}; - -const lambda<value(Env&)> analyzeVariable(const value& exp) { - return lambda<value(Env&)>(evalVariableLambda(exp)); -} - -struct evalDefinitionLambda { - const value var; - const lambda<value(Env&)> vproc; - evalDefinitionLambda(const value& var, const lambda<value(Env&)>& vproc) : var(var), vproc(vproc) { - } - const value operator()(Env& env) const { - env = defineVariable(var, vproc(env), env); - return var; - } -}; - -const lambda<value(Env&)> analyzeDefinition(const value& exp) { - return lambda<value(Env&)>(evalDefinitionLambda(definitionVariable(exp), analyze(definitionValue(exp)))); +value evalIf(const value& exp, Env& env) { + if(isTrue(eval(ifPredicate(exp), env))) + return eval(ifConsequent(exp), env); + return eval(ifAlternative(exp), env); } -struct evalIfLambda { - const lambda<value(Env&)> pproc; - const lambda<value(Env&)> cproc; - const lambda<value(Env&)> aproc; - evalIfLambda(const lambda<value(Env&)> pproc, const lambda<value(Env&)>& cproc, const lambda<value(Env&)>& aproc) : - pproc(pproc), cproc(cproc), aproc(aproc) { - } - const value operator()(Env& env) const { - if(pproc(env)) - return cproc(env); - return aproc(env); - } -}; - -const lambda<value(Env&)> analyzeIf(const value& exp) { - const lambda<value(Env&)> pproc = analyze(ifPredicate(exp)); - const lambda<value(Env&)> cproc = analyze(ifConsequent(exp)); - const lambda<value(Env&)> aproc = analyze(ifAlternative(exp)); - return lambda<value(Env&)>(evalIfLambda(pproc, cproc, aproc)); -} - -struct evalSequenceLambda { - const lambda<value(Env&)> proc1; - const lambda<value(Env&)> proc2; - evalSequenceLambda(const lambda<value(Env&)>& proc1, const lambda<value(Env&)>& proc2) : - proc1(proc1), proc2(proc2) { - } - const value operator()(Env& env) const { - proc1(env); - return proc2(env); - } -}; - -const lambda<value(Env&)> analyzeSequenceSequentially(const lambda<value(Env&)>& proc1, const lambda<value(Env&)>& proc2) { - return lambda<value(Env&)>(evalSequenceLambda(proc1, proc2)); +const value evalDefinition(const value& exp, Env& env) { + env = defineVariable(definitionVariable(exp), eval(definitionValue(exp), env), env); + return definitionVariable(exp); } -const lambda<value(Env&)> analyzeSequenceLoop(const lambda<value(Env&)>& firstProc, const list<lambda<value(Env&)> >& restProcs) { - if(restProcs == list<lambda<value(Env&)> >()) - return firstProc; - return analyzeSequenceLoop(analyzeSequenceSequentially(firstProc, car(restProcs)), cdr(restProcs)); -} - -const lambda<value(Env&)> analyzeSequence(const list<value>& exps) { - lambda<lambda<value(Env&)>(value exp)> a(analyze); - const list<lambda<value(Env&)> > procs = map(a, exps); - if(procs == list<lambda<value(Env&)> >()) { - std::cout << "Empty sequence" << "\n"; - return lambda<value(Env&)>(evalUndefinedLambda()); - } - return analyzeSequenceLoop(car(procs), cdr(procs)); -} - -struct lambdaLambda { - const list<value> vars; - const lambda<value(Env&)> bproc; - lambdaLambda(const list<value> vars, const lambda<value(Env&)>& bproc) - : vars(vars), bproc(bproc) { - } - - const value operator()(Env& env) const { - return makeProcedure(vars, value(bproc), env); - } -}; - -const lambda<value(Env&)> analyzeLambda(const value& exp) { - const list<value> vars = lambdaParameters(exp); - const lambda<value(Env&)> bproc = analyzeSequence(lambdaBody(exp)); - return lambda<value(Env&)>(lambdaLambda(vars, bproc)); -} - -const value executeApplication(const value& proc, const list<value>& args) { - if(isPrimitiveProcedure(proc)) { - list<value> ncargs = args; - return applyPrimitiveProcedure(proc, ncargs); - } - if(isCompoundProcedure(proc)) { - lambda<value(Env&) > bproc(procedureBody(proc)); - Env env = extendEnvironment(procedureParameters(proc), args, procedureEnvironment(proc)); - return bproc(env); - } - std::cout << "Unknown procedure type " << proc << "\n"; - return value(); -} - -struct evalApplicationArgLambda { - Env& env; - evalApplicationArgLambda(Env& env) : env(env) { - } - const value operator()(const lambda<value(Env&)>& aproc) const { - return aproc(env); - } -}; - -struct evalApplicationLambda { - const lambda<value(Env&)> fproc; - const list<lambda<value(Env&)> > aprocs; - evalApplicationLambda(const lambda<value(Env&)>& fproc, const list<lambda<value(Env&)> >& aprocs) : - fproc(fproc), aprocs(aprocs) { - } - const value operator()(Env& env) const { - return executeApplication(fproc(env), map(lambda<value(lambda<value(Env&)>)>(evalApplicationArgLambda(env)), aprocs)); - } -}; - -const lambda<value(Env&)> analyzeApplication(const value& exp) { - const lambda<value(Env&)> fproc = analyze(operat(exp)); - lambda<lambda<value(Env&)>(value exp)> a(analyze); - const list<lambda<value(Env&)> > aprocs = map(a, operands(exp)); - return lambda<value(Env&)>(evalApplicationLambda(fproc, aprocs)); -} - -const lambda<value(Env&)> analyze(const value exp) { +const value eval(const value& exp, Env& env) { if(isSelfEvaluating(exp)) - return analyzeSelfEvaluating(exp); + return exp; if(isQuoted(exp)) - return analyzeQuoted(exp); + return textOfQuotation(exp); if(isDefinition(exp)) - return analyzeDefinition(exp); + return evalDefinition(exp, env); if(isIf(exp)) - return analyzeIf(exp); + return evalIf(exp, env); if(isBegin(exp)) - return analyzeSequence(beginActions(exp)); + return evalSequence(beginActions(exp), env); if(isCond(exp)) - return analyze(condToIf(exp)); + return eval(condToIf(exp), env); if(isLambda(exp)) - return analyzeLambda(exp); + return makeProcedure(lambdaParameters(exp), value(lambdaBody(exp)), env); if(isVariable(exp)) - return analyzeVariable(exp); - if(isApplication(exp)) - return analyzeApplication(exp); + return lookupVariableValue(exp, env); + if(isApply(exp)) { + list<value> applyOperandValues = eval(applyOperand(exp), env); + return applyProcedure(eval(applyOperat(exp), env), applyOperandValues); + } + if(isApplication(exp)) { + list<value> operandValues = listOfValues(operands(exp), env); + return applyProcedure(eval(operat(exp), env), operandValues); + } std::cout << "Unknown expression type " << exp << "\n"; - return lambda<value(Env&)>(evalUndefinedLambda()); -} - - const value eval(const value& exp, Env& env) { - return analyze(exp)(env); + return value(); } } |