Overview
SHA1 Hash: | aa770610d34f6f4d77cad5d3fb52a6193055993f |
---|---|
Date: | 2010-11-09 01:40:55 |
User: | kinaba |
Comment: | added layered-let |
Timelines: | family | ancestors | descendants | both | trunk |
Downloads: | Tarball | ZIP archive |
Other Links: | files | file ages | manifest |
Tags And Properties
- branch=trunk inherited from [f65680e1d2]
- sym-trunk inherited from [f65680e1d2]
Changes
Modified .poseidon from [1c3854b81b30b626] to [2bab91be5bee6d2e].
32 <name>d2stacktrace\stacktrace.d</name> 32 <name>d2stacktrace\stacktrace.d</name> 33 <name>main.d</name> 33 <name>main.d</name> 34 <name>polemy\_common.d</name> 34 <name>polemy\_common.d</name> 35 <name>polemy\ast.d</name> 35 <name>polemy\ast.d</name> 36 <name>polemy\lex.d</name> 36 <name>polemy\lex.d</name> 37 <name>polemy\parse.d</name> 37 <name>polemy\parse.d</name> 38 <name>polemy\tricks.d</name> 38 <name>polemy\tricks.d</name> > 39 <name>polemy\value.d</name> 39 </source> 40 </source> 40 <interface /> 41 <interface /> 41 <resource /> 42 <resource /> 42 <othersDMD /> 43 <othersDMD /> 43 <others> 44 <others> 44 <name>build.bat</name> 45 <name>build.bat</name> 45 <name>build.sh</name> 46 <name>build.sh</name>
Modified main.d from [e7185e89f4df4ae3] to [404b54e69646e17a].
5 * Entry point for Polemy interpreter. 5 * Entry point for Polemy interpreter. 6 */ 6 */ 7 7 8 import std.stdio; 8 import std.stdio; 9 9 10 version(unittest) static ~this() 10 version(unittest) static ~this() 11 { 11 { 12 writeln( "***********************" ); < 13 writeln( "* All Tests Passed <3 *" ); < 14 writeln( "*********************** (Press Enter to finish)" ); | 12 writeln( "(Press Enter to finish)" ); 15 readln(); 13 readln(); 16 } 14 } 17 15 18 void main( string[] args ) 16 void main( string[] args ) 19 { 17 { 20 } 18 }
Modified polemy/ast.d from [4e37845b6ce5021a] to [35d37c6aa0a6531e].
34 string var; 34 string var; 35 mixin SimpleClass; 35 mixin SimpleClass; 36 } 36 } 37 37 38 class LetExpression : AST 38 class LetExpression : AST 39 { 39 { 40 string var; 40 string var; > 41 string layer; 41 AST init; 42 AST init; 42 AST expr; 43 AST expr; 43 mixin SimpleClass; 44 mixin SimpleClass; 44 } 45 } 45 46 46 class FuncallExpression : AST 47 class FuncallExpression : AST 47 { 48 { ................................................................................................................................................................................ 65 template EasyAST() 66 template EasyAST() 66 { 67 { 67 template genEast(T) 68 template genEast(T) 68 { T genEast(P...)(P ps) { return new T(LexPosition.dummy, ps); } 69 { T genEast(P...)(P ps) { return new T(LexPosition.dummy, ps); } 69 70 70 alias genEast!StrLiteral strl; 71 alias genEast!StrLiteral strl; 71 alias genEast!IntLiteral intl; 72 alias genEast!IntLiteral intl; 72 auto fun(string[] xs, AST ps) { return genEast!FunLiteral(xs,ps); } | 73 auto fun(string[] xs, AST ps) { return genEast!FunLiteral(xs,ps); } // t 73 alias genEast!VarExpression var; 74 alias genEast!VarExpression var; 74 alias genEast!LetExpression let; 75 alias genEast!LetExpression let; 75 alias genEast!FuncallExpression call; 76 alias genEast!FuncallExpression call; 76 } 77 }
Modified polemy/lex.d from [50586221a28fd499] to [cc80329bc2ab2034].
153 this.current = (current is null ? readNext() : current); 153 this.current = (current is null ? readNext() : current); 154 } 154 } 155 155 156 public static { 156 public static { 157 bool isSpace (dchar c) { return std.ctype.isspace(c)!=0; } 157 bool isSpace (dchar c) { return std.ctype.isspace(c)!=0; } 158 bool isSymbol (dchar c) { return 0x21<=c && c<=0x7f && !std.cty 158 bool isSymbol (dchar c) { return 0x21<=c && c<=0x7f && !std.cty 159 bool isSSymbol (dchar c) { return !find("()[]{};", c).empty; } 159 bool isSSymbol (dchar c) { return !find("()[]{};", c).empty; } 160 bool isMSymbol (dchar c) { return isSymbol(c) && !isSSymbol(c); | 160 bool isMSymbol (dchar c) { return isSymbol(c) && !isSSymbol(c) & 161 bool isLetter (dchar c) { return !isSpace(c) && !isSymbol(c); } 161 bool isLetter (dchar c) { return !isSpace(c) && !isSymbol(c); } 162 } 162 } 163 163 164 string readQuoted(const LexPosition pos){char[] buf; return readQuoted(p 164 string readQuoted(const LexPosition pos){char[] buf; return readQuoted(p 165 string readQuoted(const LexPosition pos, ref char[] buf) 165 string readQuoted(const LexPosition pos, ref char[] buf) 166 { 166 { 167 if( reader.empty ) 167 if( reader.empty ) ................................................................................................................................................................................ 349 assert_eq( lex2.front.str, "5" ); 349 assert_eq( lex2.front.str, "5" ); 350 lex2.popFront; 350 lex2.popFront; 351 lex3.popFront; 351 lex3.popFront; 352 assert( lex2.empty ); 352 assert( lex2.empty ); 353 assert( !lex3.empty ); 353 assert( !lex3.empty ); 354 assert_eq( lex3.front.str, "5" ); 354 assert_eq( lex3.front.str, "5" ); 355 } 355 } > 356 > 357 unittest > 358 { > 359 auto lex = lexerFromString(`=""`); > 360 assert_eq(lex.front.str, "="); lex.popFront; > 361 assert_eq(lex.front.str, ""); lex.popFront; > 362 assert( lex.empty ); > 363 } 356 364 357 /// Forward range for reader character by character, 365 /// Forward range for reader character by character, 358 /// keeping track of position information and caring \r\n -> \n conversion. 366 /// keeping track of position information and caring \r\n -> \n conversion. 359 367 360 private 368 private 361 struct PositionedReader(CharSeq) 369 struct PositionedReader(CharSeq) 362 if( isForwardRange!(CharSeq) && is(ElementType!(CharSeq) == dchar) ) 370 if( isForwardRange!(CharSeq) && is(ElementType!(CharSeq) == dchar) )
Modified polemy/parse.d from [10baa46251b8a0b6] to [d47e2b014f260d66].
56 56 57 AST Body() 57 AST Body() 58 { 58 { 59 if( lex.empty || !lex.front.quoted && lex.front.str=="}" ) 59 if( lex.empty || !lex.front.quoted && lex.front.str=="}" ) 60 return doNothingExpression(); 60 return doNothingExpression(); 61 61 62 auto pos = lex.front.pos; 62 auto pos = lex.front.pos; > 63 string kwd = lex.front.str; 63 if( tryEat("var") ) | 64 if( tryEat("let") || tryEat("var") || tryEat("def") || tryEat("@ 64 { 65 { > 66 if( kwd == "@" ) > 67 kwd ~= eatId("after @"); 65 immutable LexPosition varpos = (lex.empty ? null : lex.f 68 immutable LexPosition varpos = (lex.empty ? null : lex.f 66 string var = eatId("after var"); | 69 string var = eatId("after "~kwd); 67 eat("=", "after var"); | 70 eat("=", "after "~kwd); > 71 kwd = (kwd[0]=='@' ? kwd : "@val"); 68 auto e = E(0); 72 auto e = E(0); 69 if( tryEat(";") && !lex.empty && (lex.front.quoted || (l 73 if( tryEat(";") && !lex.empty && (lex.front.quoted || (l 70 return new LetExpression(pos, var, e, Body()); | 74 return new LetExpression(pos, var, kwd, e, Body( 71 else 75 else 72 return new LetExpression(pos, var, e, new VarExp | 76 return new LetExpression(pos, var, kwd, e, new V 73 } 77 } 74 else 78 else 75 { 79 { 76 auto e = E(0); 80 auto e = E(0); 77 if( tryEat(";") && !lex.empty && (lex.front.quoted || (l 81 if( tryEat(";") && !lex.empty && (lex.front.quoted || (l 78 return new LetExpression(pos, "_", e, Body()); | 82 return new LetExpression(pos, "_", "@val", e, Bo 79 else 83 else 80 return e; 84 return e; 81 } 85 } 82 } 86 } 83 87 84 // [TODO] make customizable from program 88 // [TODO] make customizable from program 85 static immutable string[][] operator_perferences = [ 89 static immutable string[][] operator_perferences = [ ................................................................................................................................................................................ 183 return new FuncallExpression(pos, 187 return new FuncallExpression(pos, 184 new VarExpression(pos, "if"), 188 new VarExpression(pos, "if"), 185 cond, 189 cond, 186 new FunLiteral(thenPos, [], th), 190 new FunLiteral(thenPos, [], th), 187 new FunLiteral(elsePos, [], el) 191 new FunLiteral(elsePos, [], el) 188 ); 192 ); 189 } 193 } 190 if( tryEat("fun") ) | 194 if( tryEat("fun") || tryEat("λ") ) 191 { 195 { 192 eat("(", "after fun"); 196 eat("(", "after fun"); 193 string[] params; 197 string[] params; 194 while( !tryEat(")") ) 198 while( !tryEat(")") ) 195 { 199 { 196 params ~= eatId("for function parameter"); 200 params ~= eatId("for function parameter"); 197 if( !tryEat(",") ) { 201 if( !tryEat(",") ) { ................................................................................................................................................................................ 251 { 255 { 252 mixin EasyAST; 256 mixin EasyAST; 253 257 254 assert_eq(parseString(`123`), intl(123)); 258 assert_eq(parseString(`123`), intl(123)); 255 assert_eq(parseString(`"foo"`), strl("foo")); 259 assert_eq(parseString(`"foo"`), strl("foo")); 256 assert_eq(parseString(`fun(){1}`), fun([],intl(1))); 260 assert_eq(parseString(`fun(){1}`), fun([],intl(1))); 257 assert_eq(parseString(`fun(x){1}`), fun(["x"],intl(1))); 261 assert_eq(parseString(`fun(x){1}`), fun(["x"],intl(1))); > 262 assert_eq(parseString(`λ(){1}`), fun([],intl(1))); > 263 assert_eq(parseString(`λ(x){1}`), fun(["x"],intl(1))); 258 assert_eq(parseString(`1;2`), let("_",intl(1),intl(2))); | 264 assert_eq(parseString(`1;2`), let("_","@val",intl(1),intl(2))); 259 assert_eq(parseString(`1;2;`), let("_",intl(1),intl(2))); | 265 assert_eq(parseString(`1;2;`), let("_","@val",intl(1),intl(2))); 260 assert_eq(parseString(`var x=1;2`), let("x",intl(1),intl(2))); | 266 assert_eq(parseString(`let x=1;2`), let("x","@val",intl(1),intl(2))); 261 assert_eq(parseString(`var x=1;2;`), let("x",intl(1),intl(2))); | 267 assert_eq(parseString(`var x=1;2;`), let("x","@val",intl(1),intl(2))); 262 assert_eq(parseString(`var x=1`), let("x",intl(1),var("x"))); | 268 assert_eq(parseString(`def x=1`), let("x","@val",intl(1),var("x"))); 263 assert_eq(parseString(`var x=1;`), let("x",intl(1),var("x"))); | 269 assert_eq(parseString(`@val x=1;`), let("x","@val",intl(1),var("x"))); > 270 assert_eq(parseString(`@typ x="#int";`), let("x","@typ",strl("#int"),var 264 assert_eq(parseString(`f(1,2)`), call(var("f"),intl(1),intl(2))); 271 assert_eq(parseString(`f(1,2)`), call(var("f"),intl(1),intl(2))); 265 assert_eq(parseString(`if(1){2}`), call(var("if"),intl(1),fun([],intl(2) 272 assert_eq(parseString(`if(1){2}`), call(var("if"),intl(1),fun([],intl(2) 266 assert_eq(parseString(`if(1){2}else{3}`), call(var("if"),intl(1),fun([], 273 assert_eq(parseString(`if(1){2}else{3}`), call(var("if"),intl(1),fun([], 267 assert_eq(parseString(`if(1){}else{3}()()`), 274 assert_eq(parseString(`if(1){}else{3}()()`), 268 call(call(call(var("if"),intl(1),fun([],intl(178)),fun([],intl(3 275 call(call(call(var("if"),intl(1),fun([],intl(178)),fun([],intl(3 269 assert_eq(parseString(`1+2*3`), call(var("+"),intl(1),call(var("*"),intl 276 assert_eq(parseString(`1+2*3`), call(var("+"),intl(1),call(var("*"),intl 270 assert_eq(parseString(`(1+2)*3`), call(var("*"),call(var("+"),intl(1),in 277 assert_eq(parseString(`(1+2)*3`), call(var("*"),call(var("+"),intl(1),in 271 assert_eq(parseString(`1*(2+3)`), call(var("*"),intl(1),call(var("+"),in 278 assert_eq(parseString(`1*(2+3)`), call(var("*"),intl(1),call(var("+"),in 272 assert_eq(parseString(`1*2+3`), call(var("+"),call(var("*"),intl(1),intl 279 assert_eq(parseString(`1*2+3`), call(var("+"),call(var("*"),intl(1),intl 273 280 274 assert_eq(parseString(` 281 assert_eq(parseString(` 275 var x = 100; #comment | 282 let x = 100; #comment 276 var y = 200; #comment!!!!! | 283 let y = 200; #comment!!!!! 277 x+y 284 x+y 278 `), 285 `), 279 let("x", intl(100), let("y", intl(200), call(var("+"), var("x"), | 286 let("x", "@val", intl(100), let("y", "@val", intl(200), call(var 280 ); 287 ); 281 288 282 assert_eq(parseString(` 289 assert_eq(parseString(` 283 var fac = fun(x){ if(x <= 1) {1} else {x*fac(x-1)} }; 290 var fac = fun(x){ if(x <= 1) {1} else {x*fac(x-1)} }; 284 fac(10) 291 fac(10) 285 `), 292 `), 286 let("fac", fun(["x"], | 293 let("fac", "@val", fun(["x"], 287 call(var("if"), 294 call(var("if"), 288 call(var("<="), var("x"), intl(1)), 295 call(var("<="), var("x"), intl(1)), 289 fun([], intl(1)), 296 fun([], intl(1)), 290 fun([], call(var("*"), var("x"), call(var("fac") 297 fun([], call(var("*"), var("x"), call(var("fac") 291 )), 298 )), 292 call(var("fac"),intl(10)) 299 call(var("fac"),intl(10)) 293 ) 300 ) ................................................................................................................................................................................ 294 ); 301 ); 295 } 302 } 296 303 297 unittest 304 unittest 298 { 305 { 299 assert_throw!ParseException(parseString(`1+`)); 306 assert_throw!ParseException(parseString(`1+`)); 300 assert_throw!ParseException(parseString(`1+2}`)); 307 assert_throw!ParseException(parseString(`1+2}`)); 301 assert_throw!ParseException(parseString(`var "x"`)); | 308 assert_throw!ParseException(parseString(`let "x"`)); 302 assert_throw!ParseException(parseString(`var`)); 309 assert_throw!ParseException(parseString(`var`)); 303 assert_throw!ParseException(parseString(`var x ==`)); | 310 assert_throw!ParseException(parseString(`@val x ==`)); 304 assert_throw!ParseException(parseString(`if(){1}`)); 311 assert_throw!ParseException(parseString(`if(){1}`)); 305 assert_throw!ParseException(parseString(`f(`)); 312 assert_throw!ParseException(parseString(`f(`)); 306 } 313 }
Modified polemy/value.d from [ac6802f569d2081c] to [b8f99f303d4d3a98].
2 * Authors: k.inaba 2 * Authors: k.inaba 3 * License: NYSL 0.9982 http://www.kmonos.net/nysl/ 3 * License: NYSL 0.9982 http://www.kmonos.net/nysl/ 4 * 4 * 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.lex : LexPosition; | 9 import polemy.lex; 10 import std.stdio; < 11 10 > 11 /// Raised when something went wrong in runtime > 12 12 class PolemyRuntimeException : Exception | 13 class RuntimeException : Exception 13 { 14 { > 15 const LexPosition pos; > 16 > 17 this( const LexPosition pos, string msg ) > 18 { super(sprintf!"%s [%s]"(msg, pos)); this.pos = pos; } 14 this(string msg) { super(msg); } | 19 this( string msg ) { super(msg); this.pos = null; } 15 } 20 } > 21 > 22 /// Runtime values of Polemy 16 23 17 abstract class Value 24 abstract class Value 18 { 25 { 19 } 26 } 20 27 21 class UndefinedValue : Value < 22 { < 23 mixin SimpleConstructor; < 24 mixin SimpleCompare; < 25 override string toString() const { return "(undefined)"; } < 26 } < 27 < 28 class IntValue : Value 28 class IntValue : Value 29 { 29 { 30 BigInt data; 30 BigInt data; > 31 31 mixin SimpleConstructor; 32 mixin SimpleConstructor; 32 mixin SimpleCompare; 33 mixin SimpleCompare; 33 override string toString() const { < 34 return std.bigint.toDecimalString(cast(BigInt)data); | 34 override string toString() const { return std.bigint.toDecimalString(cas 35 } < 36 } 35 } 37 36 38 class StrValue : Value 37 class StrValue : Value 39 { 38 { 40 string data; 39 string data; > 40 41 mixin SimpleConstructor; 41 mixin SimpleConstructor; 42 mixin SimpleCompare; 42 mixin SimpleCompare; 43 override string toString() const { return data; } 43 override string toString() const { return data; } 44 } 44 } 45 45 46 class FunValue : Value 46 class FunValue : Value 47 { 47 { 48 Value delegate(immutable LexPosition pos, Value[]) data; 48 Value delegate(immutable LexPosition pos, Value[]) data; > 49 49 mixin SimpleConstructor; 50 mixin SimpleConstructor; 50 Value call(immutable LexPosition pos, Value[] args) { return data(pos,ar | 51 alias data call; 51 override string toString() const { return sprintf!"(function:%s:%s)"(dat 52 override string toString() const { return sprintf!"(function:%s:%s)"(dat 52 } 53 } 53 import std.stdio; < > 54 > 55 /// Layer ID > 56 > 57 alias string Layer; > 58 > 59 /// Context (variable environment) > 60 /// Simlar to prototype chain of ECMAScript etc. > 61 /// But extended with the notion of "Layer" > 62 54 class Context | 63 class Table : Value 55 { 64 { 56 Context parent; | 65 enum Kind {PropagateSet, NotPropagateSet}; 57 Value[string] table; < > 66 58 this(Context parent = null) { this.parent = parent; } | 67 this( Table proto=null, Kind k = Kind.PropagateSet ) > 68 { this.prototype = proto; this.kind = k; } 59 69 60 void add(string i, Value v) | 70 void set(string i, Layer lay, Value v) 61 { 71 { > 72 if( !setIfExist(i, lay, v) ) 62 table[i] = v; | 73 data[i][lay] = v; 63 } 74 } 64 75 65 Value opIndex(string i) | 76 Value get(string i, Layer lay) 66 { 77 { 67 if( i in table ) | 78 if( i in data ) 68 return table[i]; | 79 return data[i][lay]; 69 if( parent is null ) | 80 if( prototype is null ) 70 throw new PolemyRuntimeException(sprintf!"variable %s no | 81 throw new RuntimeException(sprintf!"variable %s not foun 71 return parent[i]; | 82 return prototype.get(i, lay); 72 } 83 } 73 84 74 void opIndexAssign(Value v, string i) | 85 private: > 86 Table prototype; > 87 Kind kind; > 88 Value[Layer][string] data; > 89 > 90 bool setIfExist(string i, Layer lay, Value v) 75 { 91 { 76 if( i in table ) | 92 if( i in data ) > 93 { > 94 data[i][lay] = v; 77 return table[i] = v; | 95 return true; 78 if( parent is null ) < 79 throw new PolemyRuntimeException(sprintf!"variable %s no < > 96 } > 97 if( kind==Kind.PropagateSet && prototype !is null ) > 98 return prototype.setIfExist(i, lay, v); 80 return parent[i] = v; | 99 return false; 81 } 100 } 82 } 101 } > 102 > 103 unittest > 104 { > 105 Table c0 = new Table; > 106 Table c01 = new Table(c0, Table.Kind.NotPropagateSet); > 107 Table c012 = new Table(c01, Table.Kind.PropagateSet); > 108 Table c013 = new Table(c01, Table.Kind.PropagateSet); > 109 > 110 assert_nothrow( c012.set("x", "@val", new IntValue(BigInt(12))) ); > 111 assert_throw!RuntimeException( c013.get("x", "@val") ); > 112 assert_nothrow( c013.set("x", "@val", new IntValue(BigInt(13))) ); > 113 assert_eq( c013.get("x", "@val"), new IntValue(BigInt(13)) ); > 114 assert_eq( c012.get("x", "@val"), new IntValue(BigInt(12)) ); > 115 assert_throw!RuntimeException( c01.get("x", "@val") ); > 116 > 117 assert_nothrow( c01.set("y", "@val", new IntValue(BigInt(1))) ); > 118 assert_eq( c013.get("y", "@val"), new IntValue(BigInt(1)) ); > 119 assert_eq( c012.get("y", "@val"), new IntValue(BigInt(1)) ); > 120 assert_eq( c01.get("y", "@val"), new IntValue(BigInt(1)) ); > 121 > 122 assert_nothrow( c0.set("z", "@val", new IntValue(BigInt(0))) ); > 123 assert_eq( c013.get("z", "@val"), new IntValue(BigInt(0)) ); > 124 assert_eq( c012.get("z", "@val"), new IntValue(BigInt(0)) ); > 125 assert_eq( c01.get("z", "@val"), new IntValue(BigInt(0)) ); > 126 assert_eq( c0.get("z", "@val"), new IntValue(BigInt(0)) ); > 127 > 128 assert_nothrow( c012.set("y", "@val", new IntValue(BigInt(444))) ); > 129 assert_eq( c013.get("y", "@val"), new IntValue(BigInt(444)) ); > 130 assert_eq( c012.get("y", "@val"), new IntValue(BigInt(444)) ); > 131 assert_eq( c01.get("y", "@val"), new IntValue(BigInt(444)) ); > 132 > 133 assert_nothrow( c012.set("z", "@val", new IntValue(BigInt(555))) ); > 134 assert_eq( c013.get("z", "@val"), new IntValue(BigInt(0)) ); > 135 assert_eq( c012.get("z", "@val"), new IntValue(BigInt(555)) ); > 136 assert_eq( c01.get("z", "@val"), new IntValue(BigInt(0)) ); > 137 assert_eq( c0.get("z", "@val"), new IntValue(BigInt(0)) ); > 138 > 139 // [TODO] define the semantics and test @layers > 140 }