123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451 |
- #include "pch.h"
- #include "ast.h"
- //////////////////////////////////////////////////////////////////////////////
- //
- // Closure
- //
- //////////////////////////////////////////////////////////////////////////////
- class Closure : public Value {
- public:
- virtual TRef<Delay> Evaluate(Delay* pdelay) = 0;
- static TRef<Type> StaticGetType()
- {
- return
- new FunctionType(
- new PolymorphicType(),
- new PolymorphicType()
- );
- }
- };
- //////////////////////////////////////////////////////////////////////////////
- //
- // Closure
- //
- //////////////////////////////////////////////////////////////////////////////
- class ExpressionClosure : public Closure {
- private:
- ZString m_str;
- TRef<Environment> m_penv;
- TRef<Expression> m_pexpr;
- public:
- ExpressionClosure(Environment* penv, const ZString& str, Expression* pexpr) :
- m_str(str),
- m_penv(penv),
- m_pexpr(pexpr)
- {
- }
- TRef<Delay> Evaluate(Delay* pdelay)
- {
- return
- CreateDelay(
- new Environment(m_penv, m_str, pdelay),
- m_pexpr
- );
- }
- ZString GetString()
- {
- return "(function arg -> expr)";
- }
- };
- //////////////////////////////////////////////////////////////////////////////
- //
- // Expression
- //
- //////////////////////////////////////////////////////////////////////////////
- bool Expression::IsValue()
- {
- return false;
- }
- Value* Expression::GetValue()
- {
- return NULL;
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // ValueExpression
- //
- //////////////////////////////////////////////////////////////////////////////
- class ValueExpression : public Expression {
- private:
- TRef<Value> m_pvalue;
- public:
- ValueExpression(Value* pvalue) :
- m_pvalue(pvalue)
- {
- }
- bool IsValue()
- {
- return true;
- }
- Value* GetValue()
- {
- return m_pvalue;
- }
- TRef<Type> GetType(Environment* penv)
- {
- return m_pvalue->GetType();
- }
- TRef<Delay> Evaluate(Environment* penv)
- {
- return CreateDelay(NULL, this);
- }
- };
- TRef<Expression> CreateValueExpression(Value* pvalue)
- {
- return new ValueExpression(pvalue);
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // SymbolExpression
- //
- //////////////////////////////////////////////////////////////////////////////
- class SymbolExpression : public Expression {
- private:
- ZString m_str;
- public:
- SymbolExpression(const ZString& str) :
- m_str(str)
- {
- }
- TRef<Type> GetType(Environment* penv)
- {
- TRef<Delay> pdelay = penv->Find(m_str);
- if (pdelay == NULL) {
- ZError("Undefined symbol: " + m_str);
- }
- return pdelay->GetType();
- }
- TRef<Delay> Evaluate(Environment* penv)
- {
- return penv->Find(m_str);
- }
- };
- TRef<Expression> CreateSymbolExpression(const ZString& str)
- {
- return new SymbolExpression(str);
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // ApplyExpression
- //
- //////////////////////////////////////////////////////////////////////////////
- class ApplyExpression : public Expression {
- private:
- TRef<Expression> m_pexprFunc;
- TRef<Expression> m_pexprArg;
- public:
- ApplyExpression(Expression* pexprFunc, Expression* pexprArg) :
- m_pexprFunc(pexprFunc),
- m_pexprArg(pexprArg)
- {
- }
- TRef<Type> GetType(Environment* penv)
- {
- TRef<Type> ptypeFunc = m_pexprFunc->GetType(penv);
- ZVerify(ptypeFunc->IsMatch(Closure::StaticGetType()));
- TRef<FunctionType> pfuncType = ptypeFunc->GetFunctionType();
- TRef<Type> ptypeFuncArg = pfuncType->GetArgType();
- TRef<Type> ptypeArg = m_pexprArg->GetType(penv);
- if (ptypeFuncArg->IsMatch(ptypeArg)) {
- return pfuncType->GetResultType();
- } else {
- int id = 'a';
- ZError(
- "Type mismatch: "
- + ptypeFuncArg->GetString(id)
- + " != "
- + ptypeArg->GetString(id)
- );
- return NULL;
- }
- }
- TRef<Delay> Evaluate(Environment* penv)
- {
- TRef<Delay> pdelayFunc = m_pexprFunc->Evaluate(penv);
- TRef<Value> pvalue = pdelayFunc->Evaluate();
- TRef<Closure> pclosure; CastTo(pclosure, pvalue);
- TRef<Delay> pdelayArg = m_pexprArg->Evaluate(penv);
- return pclosure->Evaluate(pdelayArg);
- }
- };
- TRef<Expression> CreateApplyExpression(Expression* pexprFunc, Expression* pexprArg)
- {
- return new ApplyExpression(pexprFunc, pexprArg);
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // FunctionExpression
- //
- //////////////////////////////////////////////////////////////////////////////
- class FunctionExpression : public Expression {
- private:
- ZString m_str;
- TRef<Expression> m_pexpr;
- public:
- FunctionExpression(const ZString& str, Expression* pexpr) :
- m_str(str),
- m_pexpr(pexpr)
- {
- }
- TRef<Type> GetType(Environment* penv)
- {
- TRef<Type> ptypeArg = new PolymorphicType();
- penv =
- new Environment(
- penv,
- m_str,
- CreateTypeDelay(ptypeArg)
- );
- TRef<Type> ptypeResult = m_pexpr->GetType(penv);
- return new FunctionType(ptypeArg, ptypeResult);
- }
- TRef<Delay> Evaluate(Environment* penv)
- {
- TRef<Value> pvalue = new ExpressionClosure(penv, m_str, m_pexpr);
- TRef<Expression> pexpr = new ValueExpression(pvalue);
- return CreateDelay(NULL, pexpr);
- }
- };
- TRef<Expression> CreateFunctionExpression(const ZString& str, Expression* pexpr)
- {
- return new FunctionExpression(str, pexpr);
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // LetExpression
- //
- //////////////////////////////////////////////////////////////////////////////
- class LetExpression : public Expression {
- private:
- TRef<Environment> m_penv;
- TRef<Expression> m_pexprIn;
- public:
- LetExpression(Environment* penv, Expression* pexprIn) :
- m_penv(penv),
- m_pexprIn(pexprIn)
- {
- }
- TRef<Type> GetType(Environment* penv)
- {
- ZUnimplemented();
- return NULL;
- }
- TRef<Delay> Evaluate(Environment* penv)
- {
- Environment* penvLet = m_penv;
- TRef<Environment> penvTop = new Environment(NULL, "let", NULL);
- while (penvLet != NULL) {
- TRef<Delay> pdelay = penvLet->GetDelay();
- TRef<Expression> pexpr;
- if (pdelay != NULL) {
- pexpr = pdelay->GetExpression();
- }
- penv =
- new Environment(
- penv,
- penvLet->GetString(),
- CreateDelay(
- penvTop,
- pexpr
- )
- );
- penvLet = penvLet->GetNext();
- }
- penvTop->SetNext(penv);
- return CreateDelay(penvTop, m_pexprIn);
- }
- };
- TRef<Expression> CreateLetExpression(Environment* penv, Expression* pexprIn)
- {
- return new LetExpression(penv, pexprIn);
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // TypeDelay
- //
- //////////////////////////////////////////////////////////////////////////////
- class TypeDelay : public Delay {
- private:
- TRef<Type> m_ptype;
- public:
- TypeDelay(Type* ptype) :
- m_ptype(ptype)
- {
- }
- Expression* GetExpression()
- {
- return NULL;
- }
- TRef<Value> Evaluate()
- {
- return NULL;
- }
- TRef<Type> GetType()
- {
- return m_ptype;
- }
- };
- TRef<Delay> CreateTypeDelay(Type* ptype)
- {
- return new TypeDelay(ptype);
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // Delay
- //
- //////////////////////////////////////////////////////////////////////////////
- class DelayImpl : public Delay {
- private:
- TRef<Environment> m_penv;
- TRef<Expression> m_pexpr;
- TRef<Type> m_ptype;
- TRef<Value> m_pvalue;
- public:
- DelayImpl(Environment* penv, Expression* pexpr) :
- m_penv(penv),
- m_pexpr(pexpr)
- {
- }
- Expression* GetExpression()
- {
- return m_pexpr;
- }
- TRef<Value> Evaluate()
- {
- if (m_pvalue == NULL) {
- if (m_pexpr->IsValue()) {
- m_pvalue = m_pexpr->GetValue();
- } else {
- m_pvalue = m_pexpr->Evaluate(m_penv)->Evaluate();
- }
- }
- return m_pvalue;
- }
- TRef<Type> GetType()
- {
- if (m_ptype) {
- return m_ptype;
- } else {
- m_ptype = new PolymorphicType();
- TRef<Type> ptype = m_pexpr->GetType(m_penv);
- ZVerify(m_ptype->IsMatch(ptype));
- m_ptype = NULL;
- return ptype;
- }
- }
- };
- TRef<Delay> CreateDelay(Environment* penv, Expression* pexpr)
- {
- return new DelayImpl(penv, pexpr);
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // Environment
- //
- //////////////////////////////////////////////////////////////////////////////
- Environment::Environment(Environment* penv, const ZString& str, Delay* pdelay) :
- m_penv(penv),
- m_str(str),
- m_pdelay(pdelay)
- {
- }
- Delay* Environment::Find(const ZString& str)
- {
- if (m_str == str) {
- return m_pdelay;
- } else if (m_penv != NULL) {
- return m_penv->Find(str);
- }
- return NULL;
- }
- Delay* Environment::GetArgument(int index)
- {
- if (index == 1) {
- return m_pdelay;
- } else {
- return m_penv->GetArgument(index - 1);
- }
- }
|