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:
+    }
+  }
 }