Diff
Not logged in

Differences From Artifact [10baa46251b8a0b6]:

To Artifact [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 }