@@ -59,24 +59,28 @@ if( lex.empty || !lex.front.quoted && lex.front.str=="}" ) return doNothingExpression(); auto pos = lex.front.pos; - if( tryEat("var") ) + string kwd = lex.front.str; + if( tryEat("let") || tryEat("var") || tryEat("def") || tryEat("@") ) { + if( kwd == "@" ) + kwd ~= eatId("after @"); immutable LexPosition varpos = (lex.empty ? null : lex.front.pos); - string var = eatId("after var"); - eat("=", "after var"); + string var = eatId("after "~kwd); + eat("=", "after "~kwd); + kwd = (kwd[0]=='@' ? kwd : "@val"); auto e = E(0); if( tryEat(";") && !lex.empty && (lex.front.quoted || (lex.front.str!="}" && lex.front.str!=")")) ) - return new LetExpression(pos, var, e, Body()); + return new LetExpression(pos, var, kwd, e, Body()); else - return new LetExpression(pos, var, e, new VarExpression(varpos, var)); + return new LetExpression(pos, var, kwd, e, new VarExpression(varpos, var)); } else { auto e = E(0); if( tryEat(";") && !lex.empty && (lex.front.quoted || (lex.front.str!="}" && lex.front.str!=")")) ) - return new LetExpression(pos, "_", e, Body()); + return new LetExpression(pos, "_", "@val", e, Body()); else return e; } } @@ -186,9 +190,9 @@ new FunLiteral(thenPos, [], th), new FunLiteral(elsePos, [], el) ); } - if( tryEat("fun") ) + if( tryEat("fun") || tryEat("λ") ) { eat("(", "after fun"); string[] params; while( !tryEat(")") ) @@ -254,14 +258,17 @@ assert_eq(parseString(`123`), intl(123)); assert_eq(parseString(`"foo"`), strl("foo")); assert_eq(parseString(`fun(){1}`), fun([],intl(1))); assert_eq(parseString(`fun(x){1}`), fun(["x"],intl(1))); - assert_eq(parseString(`1;2`), let("_",intl(1),intl(2))); - assert_eq(parseString(`1;2;`), let("_",intl(1),intl(2))); - assert_eq(parseString(`var x=1;2`), let("x",intl(1),intl(2))); - assert_eq(parseString(`var x=1;2;`), let("x",intl(1),intl(2))); - assert_eq(parseString(`var x=1`), let("x",intl(1),var("x"))); - assert_eq(parseString(`var x=1;`), let("x",intl(1),var("x"))); + assert_eq(parseString(`λ(){1}`), fun([],intl(1))); + assert_eq(parseString(`λ(x){1}`), fun(["x"],intl(1))); + assert_eq(parseString(`1;2`), let("_","@val",intl(1),intl(2))); + assert_eq(parseString(`1;2;`), let("_","@val",intl(1),intl(2))); + assert_eq(parseString(`let x=1;2`), let("x","@val",intl(1),intl(2))); + assert_eq(parseString(`var x=1;2;`), let("x","@val",intl(1),intl(2))); + assert_eq(parseString(`def x=1`), let("x","@val",intl(1),var("x"))); + assert_eq(parseString(`@val x=1;`), let("x","@val",intl(1),var("x"))); + assert_eq(parseString(`@typ x="#int";`), let("x","@typ",strl("#int"),var("x"))); assert_eq(parseString(`f(1,2)`), call(var("f"),intl(1),intl(2))); assert_eq(parseString(`if(1){2}`), call(var("if"),intl(1),fun([],intl(2)),fun([],intl(178)))); assert_eq(parseString(`if(1){2}else{3}`), call(var("if"),intl(1),fun([],intl(2)),fun([],intl(3)))); assert_eq(parseString(`if(1){}else{3}()()`), @@ -271,20 +278,20 @@ assert_eq(parseString(`1*(2+3)`), call(var("*"),intl(1),call(var("+"),intl(2),intl(3)))); assert_eq(parseString(`1*2+3`), call(var("+"),call(var("*"),intl(1),intl(2)),intl(3))); assert_eq(parseString(` - var x = 100; #comment - var y = 200; #comment!!!!! + let x = 100; #comment + let y = 200; #comment!!!!! x+y `), - let("x", intl(100), let("y", intl(200), call(var("+"), var("x"), var("y")))) + let("x", "@val", intl(100), let("y", "@val", intl(200), call(var("+"), var("x"), var("y")))) ); assert_eq(parseString(` var fac = fun(x){ if(x <= 1) {1} else {x*fac(x-1)} }; fac(10) `), - let("fac", fun(["x"], + let("fac", "@val", fun(["x"], call(var("if"), call(var("<="), var("x"), intl(1)), fun([], intl(1)), fun([], call(var("*"), var("x"), call(var("fac"),call(var("-"),var("x"),intl(1))))) @@ -297,10 +304,10 @@ unittest { assert_throw!ParseException(parseString(`1+`)); assert_throw!ParseException(parseString(`1+2}`)); - assert_throw!ParseException(parseString(`var "x"`)); + assert_throw!ParseException(parseString(`let "x"`)); assert_throw!ParseException(parseString(`var`)); - assert_throw!ParseException(parseString(`var x ==`)); + assert_throw!ParseException(parseString(`@val x ==`)); assert_throw!ParseException(parseString(`if(){1}`)); assert_throw!ParseException(parseString(`f(`)); }