Diff
Not logged in

Differences From Artifact [10baa46251b8a0b6]:

To Artifact [d47e2b014f260d66]:


56 56 57 57 AST Body() 58 58 { 59 59 if( lex.empty || !lex.front.quoted && lex.front.str=="}" ) 60 60 return doNothingExpression(); 61 61 62 62 auto pos = lex.front.pos; 63 - if( tryEat("var") ) 63 + string kwd = lex.front.str; 64 + if( tryEat("let") || tryEat("var") || tryEat("def") || tryEat("@") ) 64 65 { 66 + if( kwd == "@" ) 67 + kwd ~= eatId("after @"); 65 68 immutable LexPosition varpos = (lex.empty ? null : lex.front.pos); 66 - string var = eatId("after var"); 67 - eat("=", "after var"); 69 + string var = eatId("after "~kwd); 70 + eat("=", "after "~kwd); 71 + kwd = (kwd[0]=='@' ? kwd : "@val"); 68 72 auto e = E(0); 69 73 if( tryEat(";") && !lex.empty && (lex.front.quoted || (lex.front.str!="}" && lex.front.str!=")")) ) 70 - return new LetExpression(pos, var, e, Body()); 74 + return new LetExpression(pos, var, kwd, e, Body()); 71 75 else 72 - return new LetExpression(pos, var, e, new VarExpression(varpos, var)); 76 + return new LetExpression(pos, var, kwd, e, new VarExpression(varpos, var)); 73 77 } 74 78 else 75 79 { 76 80 auto e = E(0); 77 81 if( tryEat(";") && !lex.empty && (lex.front.quoted || (lex.front.str!="}" && lex.front.str!=")")) ) 78 - return new LetExpression(pos, "_", e, Body()); 82 + return new LetExpression(pos, "_", "@val", e, Body()); 79 83 else 80 84 return e; 81 85 } 82 86 } 83 87 84 88 // [TODO] make customizable from program 85 89 static immutable string[][] operator_perferences = [ ................................................................................ 183 187 return new FuncallExpression(pos, 184 188 new VarExpression(pos, "if"), 185 189 cond, 186 190 new FunLiteral(thenPos, [], th), 187 191 new FunLiteral(elsePos, [], el) 188 192 ); 189 193 } 190 - if( tryEat("fun") ) 194 + if( tryEat("fun") || tryEat("λ") ) 191 195 { 192 196 eat("(", "after fun"); 193 197 string[] params; 194 198 while( !tryEat(")") ) 195 199 { 196 200 params ~= eatId("for function parameter"); 197 201 if( !tryEat(",") ) { ................................................................................ 251 255 { 252 256 mixin EasyAST; 253 257 254 258 assert_eq(parseString(`123`), intl(123)); 255 259 assert_eq(parseString(`"foo"`), strl("foo")); 256 260 assert_eq(parseString(`fun(){1}`), fun([],intl(1))); 257 261 assert_eq(parseString(`fun(x){1}`), fun(["x"],intl(1))); 258 - assert_eq(parseString(`1;2`), let("_",intl(1),intl(2))); 259 - assert_eq(parseString(`1;2;`), let("_",intl(1),intl(2))); 260 - assert_eq(parseString(`var x=1;2`), let("x",intl(1),intl(2))); 261 - assert_eq(parseString(`var x=1;2;`), let("x",intl(1),intl(2))); 262 - assert_eq(parseString(`var x=1`), let("x",intl(1),var("x"))); 263 - assert_eq(parseString(`var x=1;`), let("x",intl(1),var("x"))); 262 + assert_eq(parseString(`λ(){1}`), fun([],intl(1))); 263 + assert_eq(parseString(`λ(x){1}`), fun(["x"],intl(1))); 264 + assert_eq(parseString(`1;2`), let("_","@val",intl(1),intl(2))); 265 + assert_eq(parseString(`1;2;`), let("_","@val",intl(1),intl(2))); 266 + assert_eq(parseString(`let x=1;2`), let("x","@val",intl(1),intl(2))); 267 + assert_eq(parseString(`var x=1;2;`), let("x","@val",intl(1),intl(2))); 268 + assert_eq(parseString(`def x=1`), let("x","@val",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("x"))); 264 271 assert_eq(parseString(`f(1,2)`), call(var("f"),intl(1),intl(2))); 265 272 assert_eq(parseString(`if(1){2}`), call(var("if"),intl(1),fun([],intl(2)),fun([],intl(178)))); 266 273 assert_eq(parseString(`if(1){2}else{3}`), call(var("if"),intl(1),fun([],intl(2)),fun([],intl(3)))); 267 274 assert_eq(parseString(`if(1){}else{3}()()`), 268 275 call(call(call(var("if"),intl(1),fun([],intl(178)),fun([],intl(3)))))); 269 276 assert_eq(parseString(`1+2*3`), call(var("+"),intl(1),call(var("*"),intl(2),intl(3)))); 270 277 assert_eq(parseString(`(1+2)*3`), call(var("*"),call(var("+"),intl(1),intl(2)),intl(3))); 271 278 assert_eq(parseString(`1*(2+3)`), call(var("*"),intl(1),call(var("+"),intl(2),intl(3)))); 272 279 assert_eq(parseString(`1*2+3`), call(var("+"),call(var("*"),intl(1),intl(2)),intl(3))); 273 280 274 281 assert_eq(parseString(` 275 - var x = 100; #comment 276 - var y = 200; #comment!!!!! 282 + let x = 100; #comment 283 + let y = 200; #comment!!!!! 277 284 x+y 278 285 `), 279 - let("x", intl(100), let("y", intl(200), call(var("+"), var("x"), var("y")))) 286 + let("x", "@val", intl(100), let("y", "@val", intl(200), call(var("+"), var("x"), var("y")))) 280 287 ); 281 288 282 289 assert_eq(parseString(` 283 290 var fac = fun(x){ if(x <= 1) {1} else {x*fac(x-1)} }; 284 291 fac(10) 285 292 `), 286 - let("fac", fun(["x"], 293 + let("fac", "@val", fun(["x"], 287 294 call(var("if"), 288 295 call(var("<="), var("x"), intl(1)), 289 296 fun([], intl(1)), 290 297 fun([], call(var("*"), var("x"), call(var("fac"),call(var("-"),var("x"),intl(1))))) 291 298 )), 292 299 call(var("fac"),intl(10)) 293 300 ) ................................................................................ 294 301 ); 295 302 } 296 303 297 304 unittest 298 305 { 299 306 assert_throw!ParseException(parseString(`1+`)); 300 307 assert_throw!ParseException(parseString(`1+2}`)); 301 - assert_throw!ParseException(parseString(`var "x"`)); 308 + assert_throw!ParseException(parseString(`let "x"`)); 302 309 assert_throw!ParseException(parseString(`var`)); 303 - assert_throw!ParseException(parseString(`var x ==`)); 310 + assert_throw!ParseException(parseString(`@val x ==`)); 304 311 assert_throw!ParseException(parseString(`if(){1}`)); 305 312 assert_throw!ParseException(parseString(`f(`)); 306 313 }