changeset 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 438ed3a72c9d
children fd52beaaa94a
files src/dil/ast/Declarations.d src/dil/ast/Expressions.d src/dil/ast/Parameters.d src/dil/semantic/Interpreter.d src/dil/semantic/Pass2.d
diffstat 5 files changed, 250 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- 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)
   {
--- 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);
 }
--- 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); }
--- 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:
+    }
+  }
 }
--- 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;
   }