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 51 ctx.add("print", new FunValue(delegate Value(immutable LexPosition pos, Value[] args){ 52 52 foreach(a; args) 53 53 write(a); 54 54 writeln(""); 55 55 return new UndefinedValue; 56 56 })); 57 + ctx.add("if", new FunValue(delegate Value(immutable LexPosition pos, Value[] args){ 58 + if( args.length != 3 ) 59 + throw new PolemyRuntimeException("if takes three arguments!! ["~to!string(pos)~"]"); 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!string(pos)~"]"); 65 + })); 57 66 return ctx; 58 67 } 59 68 60 69 Tuple!(Value,"val",Context,"ctx") evalString(T...)(T params) 61 70 { 62 71 return eval( parserFromString(params).parseProgram() ); 63 72 } ................................................................................ 179 188 assert( r.val == new IntValue(BigInt(4)) ); 180 189 } 181 190 unittest 182 191 { 183 192 evalString(`print("Hello, world!");`); 184 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 51 this(Lexer lex) 52 52 { 53 53 this.lex = lex; 54 54 } 55 55 56 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 68 Program p; 59 - while( !lex.empty ) 69 + while( !lex.empty && (lex.front.kind!=Token.Kind.identifier || lex.front.str!="}") ) 60 70 p ~= parseStatement(); 61 71 return p; 62 72 } 63 73 64 74 Statement parseStatement() 65 75 { 66 76 auto saved = lex.save; ................................................................................ 183 193 } 184 194 if( tryEat("(") ) 185 195 { 186 196 auto e = parseE(); 187 197 eat(")", "after parenthesized expression"); 188 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 224 if( tryEat("fun") ) 192 225 { 193 226 eat("(", "after fun"); 194 227 string[] params; 195 228 while(!tryEat(")")) 196 229 { ................................................................................ 311 344 )))); 312 345 } 313 346 unittest 314 347 { 315 348 auto p = parserFromString(`var x = 1; var f = fun(){x=x+1;}; f(); f(); x;`); 316 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 VarExpression(null,"x"), 359 + new IntLiteralExpression(null, BigInt(2))), 360 + new FunLiteralExpression(null, [], [new ExprStatement(null, new IntLiteralExpression(null, BigInt(1)))]), 361 + new FunLiteralExpression(null, [], [new ExprStatement(null, new VarExpression(null, "x"))]) 362 + ))); 363 +}

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

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