Differences From Artifact [b6c76b48bfdecce6]:
- File        
polemy/value.d
- 2010-11-23 09:36:27 - part of checkin [b97bd4f713] on branch trunk - automatic AST to table encoder (user: kinaba) [annotate]
 
 
To Artifact [6d85ee04f34c61b7]:
- File        
polemy/value.d
- 2010-11-23 10:09:03 - part of checkin [36c517dfc4] on branch trunk - refactored d-value and polemy-value conversion (user: kinaba) [annotate]
 
 
    5   * Runtime data structures for Polemy programming language.                            5   * Runtime data structures for Polemy programming language.
    6   */                                                                                    6   */
    7  module polemy.value;                                                                   7  module polemy.value;
    8  import polemy._common;                                                                 8  import polemy._common;
    9  import polemy.failure;                                                                 9  import polemy.failure;
   10  import polemy.ast;                                                                    10  import polemy.ast;
   11  import polemy.layer;                                                                  11  import polemy.layer;
   12  import std.string;                                                               <
   13                                                                                        12  
   14  /// Runtime values of Polemy                                                          13  /// Runtime values of Polemy
   15                                                                                        14  
   16  abstract class Value                                                                  15  abstract class Value
   17  {                                                                                     16  {
   18          override bool opEquals(Object rhs) { return 0==opCmp(rhs); }                  17          override bool opEquals(Object rhs) { return 0==opCmp(rhs); }
   19  }                                                                                     18  }
   20                                                                                        19  
   21  ///                                                                                   20  ///
   22  class IntValue : Value                                                                21  class IntValue : Value
   23  {                                                                                     22  {
   24          BigInt data;                                                                  23          BigInt data;
   25                                                                                        24  
                                                                                        >    25          this(bool n) { this.data = n?1:0; }
   26          this(int n) { this.data = n; }                                                26          this(int n) { this.data = n; }
   27          this(long n) { this.data = n; }                                               27          this(long n) { this.data = n; }
   28          this(BigInt n) { this.data = n; }                                             28          this(BigInt n) { this.data = n; }
   29          this(string n) { this.data = BigInt(n); }                                     29          this(string n) { this.data = BigInt(n); }
   30          override string toString() const { return toDecimalString(cast(BigInt)da      30          override string toString() const { return toDecimalString(cast(BigInt)da
   31          override int opCmp(Object rhs) {                                              31          override int opCmp(Object rhs) {
   32                  if(auto r = cast(IntValue)rhs) return data.opCmp(r.data);             32                  if(auto r = cast(IntValue)rhs) return data.opCmp(r.data);
................................................................................................................................................................................
  216          assert_eq( c013.get("z", ValueLayer), new IntValue(BigInt(0)) );             216          assert_eq( c013.get("z", ValueLayer), new IntValue(BigInt(0)) );
  217          assert_eq( c012.get("z", ValueLayer), new IntValue(BigInt(555)) );           217          assert_eq( c012.get("z", ValueLayer), new IntValue(BigInt(555)) );
  218          assert_eq( c01.get("z", ValueLayer), new IntValue(BigInt(0)) );              218          assert_eq( c01.get("z", ValueLayer), new IntValue(BigInt(0)) );
  219          assert_eq( c0.get("z", ValueLayer), new IntValue(BigInt(0)) );               219          assert_eq( c0.get("z", ValueLayer), new IntValue(BigInt(0)) );
  220                                                                                       220  
  221          // [TODO] define the semantics and test @layers                              221          // [TODO] define the semantics and test @layers
  222  }                                                                                    222  }
  223                                                                                   <
  224  immutable(LexPosition) extractPos( Table t )                                     <
  225  {                                                                                <
  226          Layer theLayer = ValueLayer;                                             <
  227          if(auto tt = t.access!Table(theLayer, "pos"))                            <
  228          {                                                                        <
  229                  auto fn = tt.access!StrValue(theLayer, "filename");              <
  230                  auto ln = tt.access!IntValue(theLayer, "lineno");                <
  231                  auto cl = tt.access!IntValue(theLayer, "column");                <
  232                  if(fn !is null && ln !is null && cl !is null)                    <
  233                          return new immutable(LexPosition)(fn.data,cast(int)ln.da <
  234          }                                                                        <
  235          return null;                                                             <
  236  }                                                                                <
  237                                                                                   <
  238  Value[] tableAsConsList( Layer theLayer, Table t )                               <
  239  {                                                                                <
  240          Value[] result;                                                          <
  241          while(t)                                                                 <
  242                  if(auto v  = t.access!Value(theLayer, "car"))                    <
  243                  {                                                                <
  244                          result ~= v;                                             <
  245                          t = t.access!Table(theLayer, "cdr");                     <
  246                  }                                                                <
  247                  else                                                             <
  248                          break;                                                   <
  249          return result;                                                           <
  250  }                                                                                <
  251                                                                                   <
  252  AST[] tableToASTList( Layer theLayer, Table t )                                  <
  253  {                                                                                <
  254          AST[] result;                                                            <
  255          foreach(v; tableAsConsList(theLayer, t))                                 <
  256                  if(auto t = cast(Table)v)                                        <
  257                          result ~= tableToAST(theLayer,t);                        <
  258                  else                                                             <
  259                          throw genex!RuntimeException(cast(LexPosition)null, "Inv <
  260          return result;                                                           <
  261  }                                                                                <
  262                                                                                   <
  263  AST tableToAST( Layer theLayer, Value vvvv )                                     <
  264  {                                                                                <
  265          Table t = cast(Table)vvvv;                                               <
  266          if( t is null )                                                          <
  267                  throw genex!RuntimeException(cast(LexPosition)null, "Invalid AST <
  268                                                                                   <
  269          auto nodeType = t.access!StrValue(theLayer, "is");                       <
  270          if( nodeType is null )                                                   <
  271                  throw genex!RuntimeException(cast(LexPosition)null, "Invalid AST <
  272          auto pos = extractPos(t);                                                <
  273          switch(nodeType.data)                                                    <
  274          {                                                                        <
  275          case "int":                                                              <
  276                  if(auto v = t.access!IntValue(theLayer, "data"))                 <
  277                          return new Int(pos, v.data);                             <
  278                  throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST <
  279          case "str":                                                              <
  280                  if(auto v = t.access!StrValue(theLayer, "data"))                 <
  281                          return new Str(pos, v.data);                             <
  282                  throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST <
  283          case "var":                                                              <
  284                  if(auto v = t.access!StrValue(theLayer, "name"))                 <
  285                          return new Var(pos, v.data);                             <
  286                  throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST <
  287          case "lay":                                                              <
  288                  if(auto v = t.access!StrValue(theLayer, "layer"))                <
  289                          if(auto e = t.access!Table(theLayer, "expr"))            <
  290                                  return new Lay(pos, v.data, tableToAST(theLayer, <
  291                          else                                                     <
  292                                  throw genex!RuntimeException(cast(LexPosition)nu <
  293                  throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST <
  294          case "let":                                                              <
  295                  if(auto n = t.access!StrValue(theLayer, "name"))                 <
  296                  if(auto e = t.access!Table(theLayer, "init"))                    <
  297                  if(auto b = t.access!Table(theLayer, "expr"))                    <
  298                  {                                                                <
  299                          string nn = n.data;                                      <
  300                          auto ee = tableToAST(theLayer, e);                       <
  301                          auto bb = tableToAST(theLayer, b);                       <
  302                          Layer lay="";                                            <
  303                          if(auto l = t.access!StrValue(theLayer, "layer"))        <
  304                                  lay = l.data;                                    <
  305                          return new Let(pos, nn, lay, ee, bb);                    <
  306                  }                                                                <
  307                  throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST <
  308          case "app":                                                              <
  309                  if(auto f = t.access!Table(theLayer, "fun"))                     <
  310                  if(auto a = t.access!Table(theLayer, "args"))                    <
  311                          return new App(pos, tableToAST(theLayer,f), tableToASTLi <
  312                  throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST <
  313          case "fun":                                                              <
  314                  if(auto p = t.access!Table(theLayer, "params"))                  <
  315                  if(auto b = t.access!Table(theLayer, "funbody"))                 <
  316                  {                                                                <
  317                          Parameter[] ps;                                          <
  318                          foreach(v; tableAsConsList(theLayer, p))                 <
  319                          {                                                        <
  320                                  if(auto tt = cast(Table)v)                       <
  321                                  if(auto ss = tt.access!StrValue(theLayer, "name" <
  322                                  if(auto ll = tt.access!Table(theLayer, "layers") <
  323                                  {                                                <
  324                                          Layer[] ls;                              <
  325                                          foreach(lll; tableAsConsList(theLayer, l <
  326                                                  if(auto l = cast(StrValue)lll)   <
  327                                                          ls ~= l.data;            <
  328                                                  else                             <
  329                                                          throw genex!RuntimeExcep <
  330                                          ps ~= new Parameter(ss.data, ls);        <
  331                                          continue;                                <
  332                                  }                                                <
  333                                  else                                             <
  334                                  {                                                <
  335                                          Layer[] emp;                             <
  336                                          ps ~= new Parameter(ss.data, emp);       <
  337                                          continue;                                <
  338                                  }                                                <
  339                                  throw genex!RuntimeException(cast(LexPosition)nu <
  340                          }                                                        <
  341                          auto bb = tableToAST(theLayer, b);                       <
  342                          return new Fun(pos,ps,bb);                               <
  343                  }                                                                <
  344                  throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST <
  345          default:                                                                 <
  346                  throw genex!RuntimeException(cast(LexPosition)null, sprintf!`Inv <
  347          }                                                                        <
  348  }                                                                                <
  349                                                                                   <
  350  Table makeCons(Value a, Value d)                                                 <
  351  {                                                                                <
  352          Table t = new Table;                                                     <
  353          t.set("car", ValueLayer, a);                                             <
  354          t.set("cdr", ValueLayer, d);                                             <
  355          return t;                                                                <
  356  }                                                                                <
  357                                                                                   <
  358  Table fromPos(LexPosition pos)                                                   <
  359  {                                                                                <
  360          Table t = new Table;                                                     <
  361          if( pos !is null ) {                                                     <
  362                  t.set("filename", ValueLayer, new StrValue(pos.filename));       <
  363                  t.set("lineno",   ValueLayer, new IntValue(pos.lineno));         <
  364                  t.set("column",   ValueLayer, new IntValue(pos.column));         <
  365          } else {                                                                 <
  366                  t.set("filename", ValueLayer, new StrValue("nullpos"));          <
  367                  t.set("lineno",   ValueLayer, new IntValue(0));                  <
  368                  t.set("column",   ValueLayer, new IntValue(0));                  <
  369          }                                                                        <
  370          return t;                                                                <
  371  }                                                                                <
  372                                                                                   <
  373  /// Convert AST to Table so that it can be used in Polemy                        <
  374  /// TODO: generalize to DValue2PolemyValue                                       <
  375                                                                                   <
  376  Value ast2table(T)(T e, Value delegate(AST) rec)                                 <
  377  {                                                                                <
  378          assert( typeid(e) == typeid(T) );                                        <
  379                                                                                   <
  380          static if(is(T==BigInt) || is(T==long) || is(T==int))                    <
  381                  return new IntValue(e);                                          <
  382          else                                                                     <
  383          static if(is(T==string))                                                 <
  384                  return new StrValue(e);                                          <
  385          else                                                                     <
  386          static if(is(T S : S[]))                                                 <
  387          {                                                                        <
  388                  Table lst = new Table;                                           <
  389                  foreach_reverse(a; e)                                            <
  390                          static if(is(S : AST))                                   <
  391                                  lst = makeCons(rec(a), lst);                     <
  392                          else                                                     <
  393                                  lst = makeCons(ast2table(a,rec), lst);           <
  394                  return lst;                                                      <
  395          }                                                                        <
  396          else                                                                     <
  397          static if(is(T : AST))                                                   <
  398          {                                                                        <
  399                  auto t = new Table;                                              <
  400                  t.set("pos", ValueLayer, fromPos(e.pos));                        <
  401                  t.set("is" , ValueLayer, new StrValue(typeid(e).name.split(".")[ <
  402                  foreach(i,m; e.tupleof)                                          <
  403                          static if(is(typeof(m) : AST))                           <
  404                                  t.set(e.tupleof[i].stringof[2..$], ValueLayer, r <
  405                          else                                                     <
  406                                  t.set(e.tupleof[i].stringof[2..$], ValueLayer, a <
  407                  return t;                                                        <
  408          }                                                                        <
  409          else                                                                     <
  410          static if(is(T == class))                                                <
  411          {                                                                        <
  412                  auto t = new Table;                                              <
  413                  foreach(i,m; e.tupleof)                                          <
  414                          static if(is(typeof(m) : AST))                           <
  415                                  t.set(e.tupleof[i].stringof[2..$], ValueLayer, r <
  416                          else                                                     <
  417                                  t.set(e.tupleof[i].stringof[2..$], ValueLayer, a <
  418                  return t;                                                        <
  419          }                                                                        <
  420          else                                                                     <
  421                  static assert(false, "unknown type <"~T.stringof~"> during AST e <
  422  }                                                                                <