Check-in [633e700889]
Not logged in
Overview
SHA1 Hash:633e70088935e81aeee7ee98474a883946575074
Date: 2010-11-08 01:31:52
User: kinaba
Comment:If-expression implemented. Factorial now works.
Timelines: family | ancestors | descendants | both | trunk
Downloads: Tarball | ZIP archive
Other Links: files | file ages | manifest
Tags And Properties
Changes

Modified polemy/eval.d from [f2bd29fa05629861] to [70846dfa5638c8e7].

50 })); 50 })); 51 ctx.add("print", new FunValue(delegate Value(immutable LexPosition pos, 51 ctx.add("print", new FunValue(delegate Value(immutable LexPosition pos, 52 foreach(a; args) 52 foreach(a; args) 53 write(a); 53 write(a); 54 writeln(""); 54 writeln(""); 55 return new UndefinedValue; 55 return new UndefinedValue; 56 })); 56 })); > 57 ctx.add("if", new FunValue(delegate Value(immutable LexPosition pos, Val > 58 if( args.length != 3 ) > 59 throw new PolemyRuntimeException("if takes three argumen > 60 if( auto x = cast(IntValue)args[0] ) > 61 if( auto ft = cast(FunValue)args[1] ) > 62 if( auto fe = cast(FunValue)args[2] ) > 63 return (x.data == 0 ? fe : ft).call(pos,[]); > 64 throw new PolemyRuntimeException("type mismatch in if ["~to!stri > 65 })); 57 return ctx; 66 return ctx; 58 } 67 } 59 68 60 Tuple!(Value,"val",Context,"ctx") evalString(T...)(T params) 69 Tuple!(Value,"val",Context,"ctx") evalString(T...)(T params) 61 { 70 { 62 return eval( parserFromString(params).parseProgram() ); 71 return eval( parserFromString(params).parseProgram() ); 63 } 72 } ................................................................................................................................................................................ 179 assert( r.val == new IntValue(BigInt(4)) ); 188 assert( r.val == new IntValue(BigInt(4)) ); 180 } 189 } 181 unittest 190 unittest 182 { 191 { 183 evalString(`print("Hello, world!");`); 192 evalString(`print("Hello, world!");`); 184 evalString(`print(fun(){});`); 193 evalString(`print(fun(){});`); 185 } 194 } > 195 unittest > 196 { > 197 evalString(`var fac = fun(x){ > 198 1; > 199 }; > 200 print(fac(3));`); > 201 evalString(`var fac = fun(x){ > 202 if(x) > 203 { x*fac(x-1); } > 204 else > 205 { 1; }; > 206 }; > 207 print(fac(10));`); > 208 }

Modified polemy/parse.d from [fe0b0bcfc1d8a230] to [31eeea68e341add3].

51 this(Lexer lex) 51 this(Lexer lex) 52 { 52 { 53 this.lex = lex; 53 this.lex = lex; 54 } 54 } 55 55 56 Program parseProgram() 56 Program parseProgram() 57 { 57 { > 58 Program p = parseStatements(); > 59 if( !lex.empty ) { > 60 auto e = ParserException.create(lex, "cannot reach eof") > 61 throw e; > 62 } > 63 return p; > 64 } > 65 > 66 Program parseStatements() > 67 { 58 Program p; 68 Program p; 59 while( !lex.empty ) | 69 while( !lex.empty && (lex.front.kind!=Token.Kind.identifier || l 60 p ~= parseStatement(); 70 p ~= parseStatement(); 61 return p; 71 return p; 62 } 72 } 63 73 64 Statement parseStatement() 74 Statement parseStatement() 65 { 75 { 66 auto saved = lex.save; 76 auto saved = lex.save; ................................................................................................................................................................................ 183 } 193 } 184 if( tryEat("(") ) 194 if( tryEat("(") ) 185 { 195 { 186 auto e = parseE(); 196 auto e = parseE(); 187 eat(")", "after parenthesized expression"); 197 eat(")", "after parenthesized expression"); 188 return e; 198 return e; 189 } 199 } > 200 if( tryEat("if") ) > 201 { > 202 eat("(", "after if"); > 203 auto cond = parseE(); > 204 eat(")", "after if condition"); > 205 auto thenPos = lex.front.pos; > 206 eat("{", "after if condition"); > 207 Statement[] th = parseStatements(); > 208 eat("}", "after if-then body"); > 209 Statement[] el; > 210 auto elsePos = lex.front.pos; > 211 if( tryEat("else") ) { > 212 eat("{", "after else"); > 213 el = parseStatements(); > 214 eat("}", "after else body"); > 215 } > 216 return new FuncallExpression(pos, > 217 new VarExpression(pos, "if"), > 218 cond, > 219 new FunLiteralExpression(thenPos, [], th), > 220 new FunLiteralExpression(elsePos, [], el) > 221 ); > 222 } 190 223 191 if( tryEat("fun") ) 224 if( tryEat("fun") ) 192 { 225 { 193 eat("(", "after fun"); 226 eat("(", "after fun"); 194 string[] params; 227 string[] params; 195 while(!tryEat(")")) 228 while(!tryEat(")")) 196 { 229 { ................................................................................................................................................................................ 311 )))); 344 )))); 312 } 345 } 313 unittest 346 unittest 314 { 347 { 315 auto p = parserFromString(`var x = 1; var f = fun(){x=x+1;}; f(); f(); x 348 auto p = parserFromString(`var x = 1; var f = fun(){x=x+1;}; f(); f(); x 316 Program prog = p.parseProgram(); 349 Program prog = p.parseProgram(); 317 } 350 } > 351 > 352 unittest > 353 { > 354 auto p = parserFromString(`if(x<2){1;}else{x;};`); > 355 Program prog = p.parseProgram(); > 356 assert( prog[0] == new ExprStatement(null, new FuncallExpression(null, > 357 new VarExpression(null, "if"), > 358 new FuncallExpression(null, new VarExpression(null,"<"), new Var > 359 new IntLiteralExpression(null, BigInt(2))), > 360 new FunLiteralExpression(null, [], [new ExprStatement(null, new > 361 new FunLiteralExpression(null, [], [new ExprStatement(null, new > 362 ))); > 363 }

Modified polemy/runtime.d from [2eb228662dba6e2d] to [0d0a3e76147a101b].

27 27 28 class IntValue : Value 28 class IntValue : Value 29 { 29 { 30 BigInt data; 30 BigInt data; 31 mixin SimpleConstructor; 31 mixin SimpleConstructor; 32 mixin SimpleCompare; 32 mixin SimpleCompare; 33 override string toString() const { 33 override string toString() const { 34 const(char)[] cs; data.toString((const(char)[] s){cs=s;}, null); | 34 return std.bigint.toDecimalString(cast(BigInt)data); 35 return to!string(cs); < 36 } 35 } 37 } 36 } 38 37 39 class StrValue : Value 38 class StrValue : Value 40 { 39 { 41 string data; 40 string data; 42 mixin SimpleConstructor; 41 mixin SimpleConstructor;