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      5    * Runtime data structures for Polemy programming language.
     6      6    */
     7      7   module polemy.value;
     8      8   import polemy._common;
     9      9   import polemy.failure;
    10     10   import polemy.ast;
    11     11   import polemy.layer;
    12         -import std.string;
    13     12   
    14     13   /// Runtime values of Polemy
    15     14   
    16     15   abstract class Value
    17     16   {
    18     17    override bool opEquals(Object rhs) { return 0==opCmp(rhs); }
    19     18   }
    20     19   
    21     20   ///
    22     21   class IntValue : Value
    23     22   {
    24     23    BigInt data;
    25     24   
           25  + this(bool n) { this.data = n?1:0; }
    26     26    this(int n) { this.data = n; }
    27     27    this(long n) { this.data = n; }
    28     28    this(BigInt n) { this.data = n; }
    29     29    this(string n) { this.data = BigInt(n); }
    30     30    override string toString() const { return toDecimalString(cast(BigInt)data); }
    31     31    override int opCmp(Object rhs) {
    32     32     if(auto r = cast(IntValue)rhs) return data.opCmp(r.data);
................................................................................
   216    216    assert_eq( c013.get("z", ValueLayer), new IntValue(BigInt(0)) );
   217    217    assert_eq( c012.get("z", ValueLayer), new IntValue(BigInt(555)) );
   218    218    assert_eq( c01.get("z", ValueLayer), new IntValue(BigInt(0)) );
   219    219    assert_eq( c0.get("z", ValueLayer), new IntValue(BigInt(0)) );
   220    220   
   221    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.data.toInt,cast(int)cl.data.toInt);
   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, "Invalid AST (non-table in cons-list)");
   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 (not a table)");
   268         -
   269         - auto nodeType = t.access!StrValue(theLayer, "is");
   270         - if( nodeType is null )
   271         -  throw genex!RuntimeException(cast(LexPosition)null, "Invalid AST {is:(not string)}");
   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 {is:"int", data:(not int)}`);
   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 {is:"str", data:(not string)}`);
   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 {is:"var", name:(not string)}`);
   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,e));
   291         -   else
   292         -    throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST {is:"lay", expr:(not table)}`);
   293         -  throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST {is:"lay", layer:(not string)}`);
   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 {is:"let", name:"???", init:"???", expr:"???"}`);
   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), tableToASTList(theLayer,a));
   312         -  throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST {is:"app", fun:???, args:???}`);
   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, ll))
   326         -      if(auto l = cast(StrValue)lll)
   327         -       ls ~= l.data;
   328         -      else
   329         -       throw genex!RuntimeException(cast(LexPosition)null, sprintf!`Invalid AST {bad fun params %s}`(lll));
   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)null, sprintf!`Invalid AST {bad fun params %s}`(v));
   340         -   }
   341         -   auto bb = tableToAST(theLayer, b);
   342         -   return new Fun(pos,ps,bb);
   343         -  }
   344         -  throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST {is:"fun", param:???, body:???}`);
   345         - default:
   346         -  throw genex!RuntimeException(cast(LexPosition)null, sprintf!`Invalid AST {is: "%s"} unknown`(nodeType.data));
   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(".")[$-1].tolower()));
   402         -  foreach(i,m; e.tupleof)
   403         -   static if(is(typeof(m) : AST))
   404         -    t.set(e.tupleof[i].stringof[2..$], ValueLayer, rec(m));
   405         -   else
   406         -    t.set(e.tupleof[i].stringof[2..$], ValueLayer, ast2table(m,rec));
   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, rec(m));
   416         -   else
   417         -    t.set(e.tupleof[i].stringof[2..$], ValueLayer, ast2table(m,rec));
   418         -  return t;
   419         - }
   420         - else
   421         -  static assert(false, "unknown type <"~T.stringof~"> during AST encoding");
   422         -}