Diff
Not logged in

Differences From Artifact [a4c75e644b34fb64]:

To Artifact [10fa9090c50cdaf9]:


3 3 * License: NYSL 0.9982 http://www.kmonos.net/nysl/ 4 4 * 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.lex; 10 +import polemy.ast; 10 11 11 12 /// Raised when something went wrong in runtime 12 13 13 14 class RuntimeException : Exception 14 15 { 15 16 mixin ExceptionWithPosition; 16 17 } ................................................................................ 129 130 throw genex!RuntimeException(pos, sprintf!"variable %s is not set in layer %s"(i,lay)); 130 131 return data[i][lay]; 131 132 } 132 133 if( prototype is null ) 133 134 throw new RuntimeException(pos, sprintf!"variable %s not found"(i)); 134 135 return prototype.get(i, lay, pos); 135 136 } 137 + 138 + T access(T,S...)( Layer lay, string path, S rest ) 139 + { 140 + static if( rest.length == 0 ) 141 + { 142 + if( this.has(path, lay) ) 143 + return cast(T) this.get(path, lay); 144 + } 145 + else 146 + { 147 + if(auto next = this.access!Table(lay,path)) 148 + return next.access!T(lay,rest); 149 + } 150 + return null; 151 + } 136 152 137 153 private: 138 154 Table prototype; 139 155 Kind kind; 140 156 Value[Layer][string] data; 141 157 142 158 bool setIfExist(string i, Layer lay, Value v) ................................................................................ 186 202 assert_eq( c013.get("z", "@v"), new IntValue(BigInt(0)) ); 187 203 assert_eq( c012.get("z", "@v"), new IntValue(BigInt(555)) ); 188 204 assert_eq( c01.get("z", "@v"), new IntValue(BigInt(0)) ); 189 205 assert_eq( c0.get("z", "@v"), new IntValue(BigInt(0)) ); 190 206 191 207 // [TODO] define the semantics and test @layers 192 208 } 209 + 210 +immutable(LexPosition) extractPos( Table t ) 211 +{ 212 + Layer theLayer = "@v"; 213 + if(auto tt = t.access!Table(theLayer, "pos")) 214 + { 215 + auto fn = tt.access!StrValue(theLayer, "filename"); 216 + auto ln = tt.access!IntValue(theLayer, "lineno"); 217 + auto cl = tt.access!IntValue(theLayer, "column"); 218 + if(fn !is null && ln !is null && cl !is null) 219 + return new immutable(LexPosition)(fn.data,cast(int)ln.data.toInt,cast(int)cl.data.toInt); 220 + } 221 + return null; 222 +} 223 + 224 +Value[] tableAsConsList( Layer theLayer, Table t ) 225 +{ 226 + Value[] result; 227 + while(t) 228 + if(auto v = t.access!Value(theLayer, "car")) 229 + { 230 + result ~= v; 231 + t = t.access!Table(theLayer, "cdr"); 232 + } 233 + else 234 + break; 235 + return result; 236 +} 237 + 238 +AST[] tableToASTList( Layer theLayer, Table t ) 239 +{ 240 + AST[] result; 241 + foreach(v; tableAsConsList(theLayer, t)) 242 + if(auto t = cast(Table)v) 243 + result ~= tableToAST(theLayer,t); 244 + else 245 + throw genex!RuntimeException(cast(LexPosition)null, "Invalid AST (non-table in cons-list)"); 246 + return result; 247 +} 248 + 249 +AST tableToAST( Layer theLayer, Table t ) 250 +{ 251 + auto nodeType = t.access!StrValue(theLayer, "is"); 252 + if( nodeType is null ) 253 + throw genex!RuntimeException(cast(LexPosition)null, "Invalid AST {is:(not string)}"); 254 + auto pos = extractPos(t); 255 + switch(nodeType.data) 256 + { 257 + case "int": 258 + if(auto v = t.access!IntValue(theLayer, "data")) 259 + return new IntLiteral(pos, v.data); 260 + throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST {is:"int", data:(not int)}`); 261 + case "str": 262 + if(auto v = t.access!StrValue(theLayer, "data")) 263 + return new StrLiteral(pos, v.data); 264 + throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST {is:"str", data:(not string)}`); 265 + case "var": 266 + if(auto v = t.access!StrValue(theLayer, "name")) 267 + return new VarExpression(pos, v.data); 268 + throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST {is:"var", name:(not string)}`); 269 + case "lay": 270 + if(auto v = t.access!StrValue(theLayer, "layer")) 271 + if(auto e = t.access!Table(theLayer, "expr")) 272 + return new LayeredExpression(pos, v.data, tableToAST(theLayer,e)); 273 + else 274 + throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST {is:"lay", expr:(not table)}`); 275 + throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST {is:"lay", layer:(not string)}`); 276 + case "let": 277 + if(auto n = t.access!StrValue(theLayer, "name")) 278 + if(auto e = t.access!Table(theLayer, "init")) 279 + if(auto b = t.access!Table(theLayer, "expr")) 280 + { 281 + string nn = n.data; 282 + auto ee = tableToAST(theLayer, e); 283 + auto bb = tableToAST(theLayer, b); 284 + Layer lay=""; 285 + if(auto l = t.access!StrValue(theLayer, "layer")) 286 + lay = l.data; 287 + return new LetExpression(pos, nn, lay, ee, bb); 288 + } 289 + throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST {is:"let", name:"???", init:"???", expr:"???"}`); 290 + case "app": 291 + if(auto f = t.access!Table(theLayer, "fun")) 292 + if(auto a = t.access!Table(theLayer, "arg")) 293 + return new FuncallExpression(pos, tableToAST(theLayer,f), tableToASTList(theLayer,a)); 294 + throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST {is:"app", fun:???, arg:???}`); 295 + case "fun": 296 + if(auto p = t.access!Table(theLayer, "param")) 297 + if(auto b = t.access!Table(theLayer, "body")) 298 + { 299 + Parameter[] ps; 300 + foreach(v; tableAsConsList(theLayer, p)) 301 + { 302 + if(auto tt = cast(Table)v) 303 + if(auto ss = tt.access!StrValue(theLayer, "name")) 304 + if(auto ll = tt.access!Table(theLayer, "layer")) 305 + { 306 + Layer[] ls; 307 + foreach(lll; tableAsConsList(theLayer, ll)) 308 + if(auto l = cast(StrValue)lll) 309 + ls ~= l.data; 310 + else 311 + throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST {bad fun params}`); 312 + ps ~= new Parameter(ss.data, ls); 313 + continue; 314 + } 315 + else 316 + { 317 + Layer[] emp; 318 + ps ~= new Parameter(ss.data, emp); 319 + } 320 + throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST {bad fun params}`); 321 + } 322 + auto bb = tableToAST(theLayer, b); 323 + return new FunLiteral(pos,ps,bb); 324 + } 325 + throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST {is:"fun", param:???, body:???}`); 326 + default: 327 + throw genex!RuntimeException(cast(LexPosition)null, sprintf!`Invalid AST {is: "%s"} unknown`(nodeType.data)); 328 + } 329 +}