Mercurial > projects > dil
diff src/dil/semantic/Interpreter.d @ 821:09a64d96967a
Started the interpreter. Made a couple changes in other parts -- CharExpression now has an IntExpression of a character type as its value member and its type is set accordingly.
author | Jarrett Billingsley <jarrett.billingsley@gmail.com> |
---|---|
date | Fri, 14 Mar 2008 11:01:05 -0400 |
parents | bcb74c9b895c |
children | 451ede0105e0 |
line wrap: on
line diff
--- a/src/dil/semantic/Interpreter.d Thu Mar 13 18:59:54 2008 +0100 +++ b/src/dil/semantic/Interpreter.d Fri Mar 14 11:01:05 2008 -0400 @@ -43,6 +43,13 @@ { return (new Interpreter(/+scop,+/ infoMan)).eval(e); } + + /// Executes the function at compile-time with the given arguments. + /// Returns: NAR or a value. + static Expression interpret(FunctionDeclaration fd, Expression[] args, InfoManager infoMan/+, Scope scop+/) + { + return (new Interpreter(/+scop,+/ infoMan)).eval(fd, args); + } /// Constructs an Interpreter object. this(/+Scope scop, +/InfoManager infoMan) @@ -56,6 +63,181 @@ { return e; } + + /// Start evaluation of a function. + Expression eval(FunctionDeclaration fd, Expression[] args) + { + // We cache this result so that we don't blindly try to reevaluate functions + // that can't be evaluated at compile time + if(fd.cantInterpret) + return NAR; + + // TODO: check for nested/method + + // Check for invalid parameter types + if(fd.params.hasVariadic() || fd.params.hasLazy()) + { + fd.cantInterpret = true; + return NAR; + } + + // remove me plx + assert(false); + return NAR; + } + + alias Expression E; + +override +{ + E visit(CondExpression e) + { + auto res = visitE(e.condition); + + if(res !is NAR) + { + if(isBool(res, true)) + res = visitE(e.lhs); + else if(isBool(res, false)) + res = visitE(e.rhs); + else + res = NAR; + } + + return res; + } + + E visit(CommaExpression e) + { + auto res = visitE(e.lhs); + + if(res !is NAR) + res = visitE(e.rhs); + + return res; + } + + E visit(OrOrExpression e) + { + auto res = visitE(e.lhs); + + if(res !is NAR) + { + if(isBool(res, true)) + res = new IntExpression(1, Types.Bool); + else if(isBool(res, false)) + { + res = visitE(e.rhs); + + if(res !is NAR) + { + if(isBool(res, true)) + res = new IntExpression(1, Types.Bool); + else if(isBool(res, false)) + res = new IntExpression(0, Types.Bool); + else + res = NAR; + } + } + else + res = NAR; + } + + return res; + } + + E visit(AndAndExpression e) + { + auto res = visitE(e.lhs); + + if(res !is NAR) + { + if(isBool(res, false)) + res = new IntExpression(0, Types.Bool); + else if(isBool(res, true)) + { + res = visitE(e.rhs); + + if(res !is NAR) + { + if(isBool(res, true)) + res = new IntExpression(1, Types.Bool); + else if(isBool(res, false)) + res = new IntExpression(0, Types.Bool); + else + res = NAR; + } + } + else + res = NAR; + } + + return res; + } + + + +/* + "OrExpression", + "XorExpression", + "AndExpression", + "EqualExpression", + "IdentityExpression", + "RelExpression", + "InExpression", + "LShiftExpression", + "RShiftExpression", + "URShiftExpression", + "PlusExpression", + "MinusExpression", + "CatExpression", + "MulExpression", + "DivExpression", + "ModExpression", + "AddressExpression", + "DerefExpression", + "SignExpression", + "NotExpression", + "CompExpression", + "CallExpression", + "NewExpression", + "NewAnonClassExpression", + "DeleteExpression", + "CastExpression", + "IndexExpression", + "SliceExpression", + "ModuleScopeExpression", + "IdentifierExpression", + "SpecialTokenExpression", + "DotExpression", + "TemplateInstanceExpression", + "ThisExpression", + "SuperExpression", + "NullExpression", + "DollarExpression", + "BoolExpression", + "IntExpression", + "RealExpression", + "ComplexExpression", + "CharExpression", + "StringExpression", + "ArrayLiteralExpression", + "AArrayLiteralExpression", + "AssertExpression", + "MixinExpression", + "ImportExpression", + "TypeofExpression", + "TypeDotIdExpression", + "TypeidExpression", + "IsExpression", + "ParenExpression", + "FunctionLiteralExpression", + "TraitsExpression", // D2.0 + "VoidInitExpression", + "ArrayInitExpression", + "StructInitExpression", +*/ +} /// Returns true if e is immutable. bool isImmutable(Expression e) @@ -65,10 +247,47 @@ alias NodeKind NK; case NK.IntExpression, NK.RealExpression, NK.ComplexExpression, NK.CharExpression, - NK.BoolExpression, NK.StringExpression: + NK.BoolExpression, NK.StringExpression, + NK.NullExpression: return true; default: } return false; } + + static bool isBool(Expression e, bool value) + { + switch(e.kind) + { + alias NodeKind NK; + + case NK.IntExpression: + auto num = (cast(IntExpression)e).number; + return num ? value == true : value == false; + + case NK.RealExpression: + auto num = (cast(RealExpression)e).number; + return num ? value == true : value == false; + + case NK.ComplexExpression: + auto num = (cast(RealExpression)e).number; + return num ? value == true : value == false; + + case NK.CharExpression: + auto num = (cast(CharExpression)e).value.number; + return num ? value == true : value == false; + + case NK.BoolExpression: + auto num = (cast(BoolExpression)e).value.number; + return num ? value == true : value == false; + + case NK.StringExpression: + return value == true; + + case NK.NullExpression: + return value == false; + + default: + } + } }