Diff
Not logged in

Differences From Artifact [b6c76b48bfdecce6]:

To Artifact [6d85ee04f34c61b7]:


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