# HG changeset patch # User Jarrett Billingsley # Date 1205506865 14400 # Node ID 09a64d96967a51420d50eadd598d40fbb1351569 # Parent 438ed3a72c9d749c4f3670ea0b495461e4814d82 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. diff -r 438ed3a72c9d -r 09a64d96967a src/dil/ast/Declarations.d --- a/src/dil/ast/Declarations.d Thu Mar 13 18:59:54 2008 +0100 +++ b/src/dil/ast/Declarations.d Fri Mar 14 11:01:05 2008 -0400 @@ -394,6 +394,7 @@ Parameters params; FuncBodyStatement funcBody; LinkageType linkageType; + bool cantInterpret = false; this(TypeNode returnType, Identifier* name,/+ TemplateParameters tparams,+/ Parameters params, FuncBodyStatement funcBody) { diff -r 438ed3a72c9d -r 09a64d96967a src/dil/ast/Expressions.d --- a/src/dil/ast/Expressions.d Thu Mar 13 18:59:54 2008 +0100 +++ b/src/dil/ast/Expressions.d Fri Mar 14 11:01:05 2008 -0400 @@ -662,6 +662,8 @@ class BoolExpression : Expression { + IntExpression value; /// IntExpression of type bool. + this() { mixin(set_kind); @@ -673,8 +675,6 @@ return begin.kind == TOK.True ? true : false; } - Expression value; /// IntExpression of type int. - mixin(copyMethod); } @@ -765,11 +765,22 @@ class CharExpression : Expression { - dchar character; + IntExpression value; // IntExpression of type Char/Wchar/Dchar. +// dchar character; this(dchar character) { mixin(set_kind); - this.character = character; +// this.character = character; + if(character <= 0xFF) + this.value = new IntExpression(character, Types.Char); + else if(character <= 0xFFFF) + this.value = new IntExpression(character, Types.Wchar); + else + this.value = new IntExpression(character, Types.Dchar); + + assert(this.value.type !is null); + + this.type = this.value.type; } mixin(copyMethod); } diff -r 438ed3a72c9d -r 09a64d96967a src/dil/ast/Parameters.d --- a/src/dil/ast/Parameters.d Thu Mar 13 18:59:54 2008 +0100 +++ b/src/dil/ast/Parameters.d Fri Mar 14 11:01:05 2008 -0400 @@ -53,6 +53,12 @@ { return !!(stc & StorageClass.Variadic); } + + /// Returns true if this parameter is lazy. + bool isLazy() + { + return !!(stc & StorageClass.Lazy); + } mixin(copyMethod); } @@ -72,6 +78,14 @@ return items[$-1].isVariadic(); return false; } + + bool hasLazy() + { + foreach(param; items) + if(param.isLazy()) + return true; + return false; + } void opCatAssign(Parameter param) { addChild(param); } diff -r 438ed3a72c9d -r 09a64d96967a src/dil/semantic/Interpreter.d --- 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: + } + } } diff -r 438ed3a72c9d -r 09a64d96967a src/dil/semantic/Pass2.d --- a/src/dil/semantic/Pass2.d Thu Mar 13 18:59:54 2008 +0100 +++ b/src/dil/semantic/Pass2.d Fri Mar 14 11:01:05 2008 -0400 @@ -377,14 +377,6 @@ E visit(CharExpression e) { - if (e.type) - return e; - if (e.character <= 0xFF) - e.type = Types.Char; - else if (e.character <= 0xFFFF) - e.type = Types.Wchar; - else - e.type = Types.Dchar; return e; }