Diff
Not logged in

Differences From Artifact [b6c76b48bfdecce6]:

To Artifact [6d85ee04f34c61b7]:


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