Check-in [8de5b49cdf]
Not logged in
Overview
SHA1 Hash:8de5b49cdf478ae4727df1eaddd3ad369c707e5e
Date: 2010-11-09 14:19:20
User: kinaba
Comment:split tricks module into a separate package.
Timelines: family | ancestors | descendants | both | trunk
Downloads: Tarball | ZIP archive
Other Links: files | file ages | manifest
Tags And Properties
Changes

Modified .poseidon from [2bab91be5bee6d2e] to [374d8a7e60e3002a].

29 <projectFiles> 29 <projectFiles> 30 <source> 30 <source> 31 <name>d2stacktrace\dbghelp.d</name> 31 <name>d2stacktrace\dbghelp.d</name> 32 <name>d2stacktrace\stacktrace.d</name> 32 <name>d2stacktrace\stacktrace.d</name> 33 <name>main.d</name> 33 <name>main.d</name> 34 <name>polemy\_common.d</name> 34 <name>polemy\_common.d</name> 35 <name>polemy\ast.d</name> 35 <name>polemy\ast.d</name> > 36 <name>polemy\eval.d</name> 36 <name>polemy\lex.d</name> 37 <name>polemy\lex.d</name> 37 <name>polemy\parse.d</name> 38 <name>polemy\parse.d</name> 38 <name>polemy\tricks.d</name> < 39 <name>polemy\value.d</name> 39 <name>polemy\value.d</name> > 40 <name>tricks\test.d</name> > 41 <name>tricks\tricks.d</name> 40 </source> 42 </source> 41 <interface /> 43 <interface /> 42 <resource /> 44 <resource /> 43 <othersDMD /> 45 <othersDMD /> 44 <others> 46 <others> 45 <name>build.bat</name> 47 <name>build.bat</name> 46 <name>build.sh</name> 48 <name>build.sh</name>

Modified build.bat from [a3b137d66c9ae5c5] to [4a978e9aa8f5388f].

1 @setlocal ENABLEDELAYEDEXPANSION 1 @setlocal ENABLEDELAYEDEXPANSION 2 @set ARGS= 2 @set ARGS= 3 @for %%I in (main.d polemy\*.d) do @set ARGS=!ARGS! %%I | 3 @for %%I in (main.d polemy\*.d tricks\*.d) do @set ARGS=!ARGS! %%I 4 @if not exist bin mkdir bin 4 @if not exist bin mkdir bin 5 @echo dmd -ofbin\polemy.exe -O -release -inline %ARGS% 5 @echo dmd -ofbin\polemy.exe -O -release -inline %ARGS% 6 @dmd -ofbin\polemy.exe -O -release -inline %ARGS% 6 @dmd -ofbin\polemy.exe -O -release -inline %ARGS%

Modified d2stacktrace/stacktrace.d from [059fc11fc8a1312c] to [1456272a3238466c].

Modified polemy/_common.d from [935cc3e03ebe462f] to [5141868f3bc27248].

7 module polemy._common; 7 module polemy._common; 8 public import std.array; 8 public import std.array; 9 public import std.range; 9 public import std.range; 10 public import std.algorithm; 10 public import std.algorithm; 11 public import std.conv : to; 11 public import std.conv : to; 12 public import std.bigint; 12 public import std.bigint; 13 public import std.exception; 13 public import std.exception; > 14 public import tricks.tricks; 14 public import polemy.tricks; | 15 public import tricks.test;

Modified polemy/ast.d from [35d37c6aa0a6531e] to [c08643c4271f8f35].

1 /** | 1 /** 2 * Authors: k.inaba 2 * Authors: k.inaba 3 * License: NYSL 0.9982 http://www.kmonos.net/nysl/ 3 * License: NYSL 0.9982 http://www.kmonos.net/nysl/ 4 * 4 * 5 * Syntax tree for Polemy programming language. 5 * Syntax tree for Polemy programming language. 6 */ 6 */ 7 module polemy.ast; 7 module polemy.ast; 8 import polemy._common; 8 import polemy._common;

Modified polemy/eval.d from [003971cb94b55966] to [1a40d715cf0caee4].

1 /** | 1 /** 2 * Authors: k.inaba 2 * Authors: k.inaba 3 * License: NYSL 0.9982 http://www.kmonos.net/nysl/ 3 * License: NYSL 0.9982 http://www.kmonos.net/nysl/ 4 * 4 * 5 * Evaluator for Polemy programming language. 5 * Evaluator for Polemy programming language. 6 */ 6 */ 7 module polemy.eval; 7 module polemy.eval; 8 import polemy._common; 8 import polemy._common; ................................................................................................................................................................................ 9 import polemy.lex : LexPosition; 9 import polemy.lex : LexPosition; 10 import polemy.ast; 10 import polemy.ast; 11 import polemy.parse; 11 import polemy.parse; 12 import polemy.value; 12 import polemy.value; 13 import std.typecons; 13 import std.typecons; 14 import std.stdio; 14 import std.stdio; 15 15 16 Context createGlobalContext() | 16 Table createGlobalContext() 17 { 17 { 18 auto ctx = new Context; | 18 auto ctx = new Table; > 19 // [TODO] autogenerate these typechecks 19 ctx.add("+", new FunValue(delegate Value(immutable LexPosition pos, Valu | 20 ctx.set("+", "@val", new FunValue(delegate Value(immutable LexPosition p 20 if( args.length != 2 ) 21 if( args.length != 2 ) 21 throw new PolemyRuntimeException("+ takes two arguments! | 22 throw new RuntimeException(pos, "+ takes two arguments!! 22 if( auto x = cast(IntValue)args[0] ) 23 if( auto x = cast(IntValue)args[0] ) 23 if( auto y = cast(IntValue)args[1] ) 24 if( auto y = cast(IntValue)args[1] ) 24 return new IntValue(x.data+y.data); 25 return new IntValue(x.data+y.data); 25 throw new PolemyRuntimeException("cannot add non-integers ["~to! | 26 throw new RuntimeException(pos, "cannot add non-integers"); 26 })); 27 })); 27 ctx.add("-", new FunValue(delegate Value(immutable LexPosition pos, Valu | 28 ctx.set("-", "@val", new FunValue(delegate Value(immutable LexPosition p 28 if( args.length != 2 ) 29 if( args.length != 2 ) 29 throw new PolemyRuntimeException("- takes two arguments! | 30 throw new RuntimeException(pos, "- takes two arguments!! 30 if( auto x = cast(IntValue)args[0] ) 31 if( auto x = cast(IntValue)args[0] ) 31 if( auto y = cast(IntValue)args[1] ) 32 if( auto y = cast(IntValue)args[1] ) 32 return new IntValue(x.data-y.data); 33 return new IntValue(x.data-y.data); 33 throw new PolemyRuntimeException("cannot add non-integers ["~to! | 34 throw new RuntimeException(pos, "cannot subtract non-integers"); 34 })); 35 })); 35 ctx.add("*", new FunValue(delegate Value(immutable LexPosition pos, Valu | 36 ctx.set("*", "@val", new FunValue(delegate Value(immutable LexPosition p 36 if( args.length != 2 ) 37 if( args.length != 2 ) 37 throw new PolemyRuntimeException("* takes two arguments! | 38 throw new RuntimeException(pos, "* takes two arguments!! 38 if( auto x = cast(IntValue)args[0] ) 39 if( auto x = cast(IntValue)args[0] ) 39 if( auto y = cast(IntValue)args[1] ) 40 if( auto y = cast(IntValue)args[1] ) 40 return new IntValue(x.data*y.data); 41 return new IntValue(x.data*y.data); 41 throw new PolemyRuntimeException("cannot add non-integers ["~to! | 42 throw new RuntimeException(pos, "cannot multiply non-integers"); 42 })); 43 })); 43 ctx.add("/", new FunValue(delegate Value(immutable LexPosition pos, Valu | 44 ctx.set("/", "@val", new FunValue(delegate Value(immutable LexPosition p 44 if( args.length != 2 ) 45 if( args.length != 2 ) 45 throw new PolemyRuntimeException("/ takes two arguments! | 46 throw new RuntimeException(pos, "/ takes two arguments!! 46 if( auto x = cast(IntValue)args[0] ) 47 if( auto x = cast(IntValue)args[0] ) 47 if( auto y = cast(IntValue)args[1] ) 48 if( auto y = cast(IntValue)args[1] ) 48 return new IntValue(x.data/y.data); 49 return new IntValue(x.data/y.data); 49 throw new PolemyRuntimeException("cannot add non-integers ["~to! | 50 throw new RuntimeException(pos, "cannot divide non-integers"); 50 })); 51 })); 51 ctx.add("<", new FunValue(delegate Value(immutable LexPosition pos, Valu | 52 ctx.set("<", "@val", new FunValue(delegate Value(immutable LexPosition p 52 if( args.length != 2 ) 53 if( args.length != 2 ) 53 throw new PolemyRuntimeException("< takes two arguments! | 54 throw new RuntimeException(pos, "< takes two arguments!! 54 if( auto x = cast(IntValue)args[0] ) 55 if( auto x = cast(IntValue)args[0] ) 55 if( auto y = cast(IntValue)args[1] ) 56 if( auto y = cast(IntValue)args[1] ) 56 return new IntValue(BigInt(to!int(x.data < y.dat 57 return new IntValue(BigInt(to!int(x.data < y.dat 57 throw new PolemyRuntimeException("cannot add non-integers ["~to! | 58 throw new RuntimeException(pos, "cannot compare non-integers"); 58 })); 59 })); 59 ctx.add(">", new FunValue(delegate Value(immutable LexPosition pos, Valu | 60 ctx.set(">", "@val", new FunValue(delegate Value(immutable LexPosition p 60 if( args.length != 2 ) 61 if( args.length != 2 ) 61 throw new PolemyRuntimeException("> takes two arguments! | 62 throw new RuntimeException(pos, "> takes two arguments!! 62 if( auto x = cast(IntValue)args[0] ) 63 if( auto x = cast(IntValue)args[0] ) 63 if( auto y = cast(IntValue)args[1] ) 64 if( auto y = cast(IntValue)args[1] ) 64 return new IntValue(BigInt(to!int(x.data>y.data) 65 return new IntValue(BigInt(to!int(x.data>y.data) 65 throw new PolemyRuntimeException("cannot add non-integers ["~to! | 66 throw new RuntimeException(pos, "cannot compare non-integers"); 66 })); 67 })); 67 ctx.add("print", new FunValue(delegate Value(immutable LexPosition pos, | 68 ctx.set("print", "@val", new FunValue(delegate Value(immutable LexPositi 68 foreach(a; args) 69 foreach(a; args) 69 write(a); 70 write(a); 70 writeln(""); 71 writeln(""); 71 return new UndefinedValue; | 72 return new IntValue(BigInt(178)); 72 })); 73 })); 73 ctx.add("if", new FunValue(delegate Value(immutable LexPosition pos, Val | 74 ctx.set("if", "@val", new FunValue(delegate Value(immutable LexPosition 74 if( args.length != 3 ) 75 if( args.length != 3 ) 75 throw new PolemyRuntimeException("if takes three argumen | 76 throw new RuntimeException(pos, "if takes three argument 76 if( auto x = cast(IntValue)args[0] ) 77 if( auto x = cast(IntValue)args[0] ) 77 if( auto ft = cast(FunValue)args[1] ) 78 if( auto ft = cast(FunValue)args[1] ) 78 if( auto fe = cast(FunValue)args[2] ) 79 if( auto fe = cast(FunValue)args[2] ) 79 return (x.data == 0 ? fe : ft).call(pos,[]); 80 return (x.data == 0 ? fe : ft).call(pos,[]); 80 throw new PolemyRuntimeException("type mismatch in if ["~to!stri | 81 throw new RuntimeException(pos, "type mismatch in if"); 81 })); 82 })); 82 return ctx; 83 return ctx; 83 } 84 } 84 85 85 Tuple!(Value,"val",Context,"ctx") evalString(T...)(T params) | 86 /// Entry point of this module > 87 > 88 Tuple!(Value,"val",Table,"ctx") evalString(S,T...)(S str, T fn_ln_cn) 86 { 89 { 87 return eval( parserFromString(params).parseProgram() ); | 90 return eval( polemy.parse.parseString(str, fn_ln_cn) ); 88 } 91 } 89 92 90 Tuple!(Value,"val",Context,"ctx") evalFile(T...)(T params) | 93 Tuple!(Value,"val",Table,"ctx") evalFile(S, T...)(S filenae, T ln_cn) 91 { 94 { 92 return eval( parserFromFile(params).parseProgram() ); | 95 return eval( polemy.parse.parseFile(filename, ln_cn) ); 93 } 96 } 94 97 95 Tuple!(Value,"val",Context,"ctx") eval(Program prog) | 98 Tuple!(Value,"val",Table,"ctx") eval(AST e) 96 { 99 { 97 Context ctx = createGlobalContext(); | 100 Table ctx = createGlobalContext(); 98 return typeof(return)(eval(prog, ctx), ctx); | 101 return typeof(return)(eval(e, ctx), ctx); 99 } 102 } 100 103 101 Value eval(Program prog, Context ctx) | 104 Value eval(AST _e, Table ctx, bool splitCtx = true) 102 { < 103 Value v = new UndefinedValue; < 104 foreach(s; prog) < 105 v = eval(s, ctx); < 106 return v; < 107 } < 108 < 109 Value eval(Statement _s, Context ctx) < 110 { 105 { 111 if( auto s = cast(DeclStatement)_s ) < 112 { < 113 auto v = eval(s.expr, ctx); < 114 ctx.add(s.var, v); < 115 return v; < 116 } < 117 else < 118 if( auto s = cast(ExprStatement)_s ) < 119 { < 120 return eval(s.expr, ctx); < 121 } < 122 throw new PolemyRuntimeException(sprintf!"Unknown Kind of Statement %s a < 123 } < 124 < 125 Value eval(Expression _e, Context ctx) < 126 { < 127 if( auto e = cast(StrLiteralExpression)_e ) | 106 if( auto e = cast(StrLiteral)_e ) 128 { 107 { 129 return new StrValue(e.data); 108 return new StrValue(e.data); 130 } 109 } 131 else 110 else 132 if( auto e = cast(IntLiteralExpression)_e ) | 111 if( auto e = cast(IntLiteral)_e ) 133 { 112 { 134 return new IntValue(e.data); 113 return new IntValue(e.data); 135 } 114 } 136 else 115 else 137 if( auto e = cast(VarExpression)_e ) 116 if( auto e = cast(VarExpression)_e ) 138 { 117 { 139 return ctx[e.var]; | 118 return ctx.get(e.var, "@val", e.pos); 140 } 119 } 141 else 120 else 142 if( auto e = cast(AssignExpression)_e ) | 121 if( auto e = cast(LetExpression)_e ) 143 { 122 { 144 if( auto ev = cast(VarExpression)e.lhs ) | 123 // for letrec, we need this, but should avoid overwriting???? 145 { < > 124 // ctx.set(e.var, "@val", new UndefinedValue, e.pos); 146 Value r = eval(e.rhs, ctx); | 125 Value v = eval(e.init, ctx, true); 147 ctx[ev.var] = r; | 126 ctx.set(e.var, "@val", v, e.pos); 148 return r; | 127 return eval(e.expr, ctx); 149 } < 150 throw new PolemyRuntimeException(sprintf!"Lhs of assignment must < 151 } 128 } 152 else 129 else 153 if( auto e = cast(FuncallExpression)_e ) 130 if( auto e = cast(FuncallExpression)_e ) 154 { 131 { 155 Value _f = eval(e.fun, ctx); 132 Value _f = eval(e.fun, ctx); 156 if( auto f = cast(FunValue)_f ) { 133 if( auto f = cast(FunValue)_f ) { 157 Value[] args; 134 Value[] args; 158 foreach(a; e.args) 135 foreach(a; e.args) 159 args ~= eval(a, ctx); 136 args ~= eval(a, ctx); 160 return f.call(e.pos, args); 137 return f.call(e.pos, args); 161 } else 138 } else 162 throw new PolemyRuntimeException(sprintf!"Non-funcion is | 139 throw new RuntimeException(e.pos, "Non-funcion is applie 163 } 140 } 164 else 141 else 165 if( auto e = cast(FunLiteralExpression)_e ) | 142 if( auto e = cast(FunLiteral)_e ) 166 { 143 { 167 return new FunValue(delegate Value(immutable LexPosition pos, Va 144 return new FunValue(delegate Value(immutable LexPosition pos, Va 168 if( e.params.length != args.length ) 145 if( e.params.length != args.length ) 169 throw new PolemyRuntimeException(sprintf!"Argume | 146 throw new RuntimeException(e.pos, sprintf!"Argum 170 (e.params.length, args.length, e.pos)); | 147 (e.params.length, args.length)); 171 Context ctxNeo = new Context(ctx); | 148 Table ctxNeo = new Table(ctx, Table.Kind.NotPropagateSet 172 foreach(i,p; e.params) 149 foreach(i,p; e.params) 173 ctxNeo.add(p, args[i]); | 150 ctxNeo.set(p, "@val", args[i]); 174 return eval(e.funbody, ctxNeo); 151 return eval(e.funbody, ctxNeo); 175 }); 152 }); 176 } 153 } 177 throw new PolemyRuntimeException(sprintf!"Unknown Kind of Expression %s | 154 throw new RuntimeException(_e.pos, sprintf!"Unknown Kind of Expression % 178 } 155 } 179 156 180 unittest 157 unittest 181 { 158 { 182 auto r = evalString(`var x = 21; x = x + x*x;`); | 159 auto r = assert_nothrow( evalString(`var x = 21; x + x*x;`) ); 183 assert( r.val == new IntValue(BigInt(21+21*21)) ); | 160 assert_eq( r.val, new IntValue(BigInt(21+21*21)) ); 184 assert( r.ctx["x"] == new IntValue(BigInt(21+21*21)) ); | 161 assert_eq( r.ctx.get("x","@val"), new IntValue(BigInt(21)) ); 185 assert( !collectException(r.ctx["x"]) ); | 162 assert_nothrow( r.ctx.get("x","@val") ); 186 assert( collectException(r.ctx["y"]) ); | 163 assert_throw!RuntimeException( r.ctx.get("y","@val") ); 187 } 164 } 188 unittest 165 unittest 189 { 166 { 190 assert( collectException(evalString(`var x = 21; x = x + x*y;`)) ); | 167 auto r = assert_nothrow( evalString(`var x = 21; var x = x + x*x;`) ); 191 assert( collectException(evalString(`x=1;`)) ); | 168 assert_eq( r.val, new IntValue(BigInt(21+21*21)) ); > 169 assert_eq( r.ctx.get("x","@val"), new IntValue(BigInt(21+21*21)) ); > 170 assert_nothrow( r.ctx.get("x","@val") ); > 171 assert_throw!RuntimeException( r.ctx.get("y","@val") ); 192 } 172 } 193 unittest 173 unittest 194 { 174 { 195 auto r = evalString(`var x = fun(a){1+a;}(2);`); | 175 assert_nothrow( evalString(`print("Hello, world!");`) ); 196 assert( r.ctx["x"] == new IntValue(BigInt(3)) ); | 176 assert_nothrow( evalString(`print(fun(){});`) ); 197 assert( r.val == new IntValue(BigInt(3)) ); < 198 } 177 } 199 unittest 178 unittest 200 { 179 { 201 auto r = evalString(`var x = 1; var f = fun(){x=x+1;}; f(); f(); f();`); < 202 assert( r.ctx["x"] == new IntValue(BigInt(4)) ); < 203 assert( r.val == new IntValue(BigInt(4)) ); < 204 } < 205 unittest < 206 { < 207 evalString(`print("Hello, world!");`); < 208 evalString(`print(fun(){});`); < 209 } < 210 unittest < 211 { < 212 evalString(`var fac = fun(x){ | 180 assert_nothrow( evalString(`var fac = fun(x){ 213 1; 181 1; 214 }; 182 }; 215 print(fac(3));`); | 183 print(fac(3));`)); 216 evalString(`var fac = fun(x){ | 184 assert_nothrow( evalString(`var fac = fun(x){ 217 if(x) 185 if(x) 218 { x*fac(x-1); } 186 { x*fac(x-1); } 219 else 187 else 220 { 1; }; 188 { 1; }; 221 }; 189 }; 222 print(fac(10));`); | 190 print(fac(10));`)); 223 evalString(`var fib = fun(x){ | 191 assert_nothrow( evalString(`var fib = fun(x){ 224 if(x<2) 192 if(x<2) 225 { 1; } 193 { 1; } 226 else 194 else 227 { fib(x-1) + fib(x-2); }; 195 { fib(x-1) + fib(x-2); }; 228 }; 196 }; 229 print(fib(10));`); | 197 print(fib(10));`)); 230 } 198 }

Modified polemy/lex.d from [cc80329bc2ab2034] to [df057f5d35e6bc8a].

11 11 12 /// Exception from this module 12 /// Exception from this module 13 13 14 class LexException : Exception 14 class LexException : Exception 15 { 15 { 16 const LexPosition pos; 16 const LexPosition pos; 17 17 18 private this( const LexPosition pos, string msg ) | 18 this( const LexPosition pos, string msg, string file="", int line=0 ) 19 { super(sprintf!"%s [%s]"(msg, pos)); this.pos = pos; } | 19 { super(sprintf!"[%s] %s"(pos, msg), file, line); this.pos = pos 20 }; 20 }; 21 21 22 /// Represents a position in a source code 22 /// Represents a position in a source code 23 23 24 class LexPosition 24 class LexPosition 25 { 25 { 26 immutable string filename; /// name of the source file 26 immutable string filename; /// name of the source file 27 immutable int lineno; /// 1-origin 27 immutable int lineno; /// 1-origin 28 immutable int column; /// 1-origin 28 immutable int column; /// 1-origin 29 29 > 30 mixin SimpleClass; 30 override string toString() const 31 override string toString() const 31 { return sprintf!"%s:%d:%d"(filename, lineno, column); } 32 { return sprintf!"%s:%d:%d"(filename, lineno, column); } 32 33 33 mixin SimpleConstructor; < 34 mixin SimpleCompare; < 35 < 36 static immutable LexPosition dummy; 34 static immutable LexPosition dummy; 37 static this(){ dummy = new immutable(LexPosition)("<unnamed>",0,0); } 35 static this(){ dummy = new immutable(LexPosition)("<unnamed>",0,0); } 38 } 36 } 39 37 40 unittest 38 unittest 41 { 39 { 42 auto p = new LexPosition("hello.cpp", 123, 45); 40 auto p = new LexPosition("hello.cpp", 123, 45); ................................................................................................................................................................................ 59 57 60 class Token 58 class Token 61 { 59 { 62 immutable LexPosition pos; /// Position where the token occurred in t 60 immutable LexPosition pos; /// Position where the token occurred in t 63 immutable string str; /// The token string itself 61 immutable string str; /// The token string itself 64 immutable bool quoted; /// Was it a "quoted" token or unquoted? 62 immutable bool quoted; /// Was it a "quoted" token or unquoted? 65 63 66 mixin SimpleConstructor; < 67 mixin SimpleCompare; | 64 mixin SimpleClass; 68 mixin SimpleToString; < 69 } 65 } 70 66 71 unittest 67 unittest 72 { 68 { 73 auto p = new immutable(LexPosition)("hello.cpp", 123, 45); 69 auto p = new immutable(LexPosition)("hello.cpp", 123, 45); 74 auto t = new Token(p, "class", false); 70 auto t = new Token(p, "class", false); 75 auto u = new Token(p, "class", true); 71 auto u = new Token(p, "class", true);

Modified polemy/parse.d from [d47e2b014f260d66] to [fe5c9fee07b98701].

18 private this( const LexPosition pos, string msg ) 18 private this( const LexPosition pos, string msg ) 19 { super(sprintf!"%s [%s]"(msg, pos)); this.pos = pos; } 19 { super(sprintf!"%s [%s]"(msg, pos)); this.pos = pos; } 20 } 20 } 21 21 22 private auto createException(Lexer)(Lexer lex, string msg) 22 private auto createException(Lexer)(Lexer lex, string msg) 23 { return new ParseException(lex.empty?null:lex.front.pos, msg); } 23 { return new ParseException(lex.empty?null:lex.front.pos, msg); } 24 24 25 /// Entry point of this module | 25 /// Entry points of this module 26 26 27 auto parseString(S, T...)(S str, T fn_ln_cn) 27 auto parseString(S, T...)(S str, T fn_ln_cn) 28 { return parserFromString(str, fn_ln_cn).parse(); } 28 { return parserFromString(str, fn_ln_cn).parse(); } 29 29 30 auto parseFile(S, T...)(S filename,T ln_cn) 30 auto parseFile(S, T...)(S filename,T ln_cn) 31 { return parserFromString(filename, ln_cn).parse(); } 31 { return parserFromString(filename, ln_cn).parse(); } 32 32

Deleted polemy/tricks.d version [73906cba073bce6c]

1 /** < 2 * Authors: k.inaba < 3 * License: NYSL 0.9982 http://www.kmonos.net/nysl/ < 4 * < 5 * Common tricks and utilities for programming in D. < 6 */ < 7 module polemy.tricks; < 8 import std.array : appender; < 9 import std.format : formattedWrite; < 10 import core.exception : onAssertErrorMsg, AssertError; < 11 < 12 /// Simple Wrapper for std.format.doFormat < 13 < 14 string sprintf(string fmt, T...)(T params) < 15 { < 16 auto writer = appender!string(); < 17 formattedWrite(writer, fmt, params); < 18 return writer.data; < 19 } < 20 < 21 unittest < 22 { < 23 assert( sprintf!"%s == %d"("1+2", 3) == "1+2 == 3" ); < 24 assert( sprintf!"%s == %04d"("1+2", 3) == "1+2 == 0003" ); < 25 } < 26 < 27 /// Unittest helper that asserts an expression must throw something < 28 < 29 void assert_throw(ExceptionType, T, string fn=__FILE__, int ln=__LINE__)(lazy T < 30 { < 31 try { < 32 t(); < 33 } catch(ExceptionType) { < 34 return; < 35 } catch(Throwable e) { < 36 onAssertErrorMsg(fn, ln, msg.length ? msg : sprintf!"exception [ < 37 } < 38 onAssertErrorMsg(fn, ln, msg.length ? msg : "no execption"); < 39 } < 40 < 41 /// Unittest helper that asserts an expression must not throw anything < 42 < 43 void assert_nothrow(T, string fn=__FILE__, int ln=__LINE__)(lazy T t, string msg < 44 { < 45 try { < 46 t(); < 47 } catch(Throwable e) { < 48 onAssertErrorMsg(fn, ln, msg.length ? msg : sprintf!"exception [ < 49 } < 50 } < 51 < 52 unittest < 53 { < 54 auto error = {throw new Error("hello");}; < 55 auto nothing = (){}; < 56 auto assertError = {assert(0);}; < 57 < 58 assert_nothrow ( assert_nothrow(nothing()) ); < 59 assert_throw!AssertError( assert_nothrow(error()) ); < 60 assert_throw!AssertError( assert_nothrow(assertError()) ); < 61 < 62 assert_nothrow ( assert_throw!Error(error()) ); < 63 assert_throw!AssertError( assert_throw!Error(nothing()) ); < 64 assert_nothrow ( assert_throw!Error(assertError()) ); < 65 assert_throw!AssertError( assert_throw!AssertError(error()) ); < 66 } < 67 < 68 /// Unittest helpers asserting two values are in some relation ==, !=, <, <=, >, < 69 < 70 template assertOp(string op) < 71 { < 72 void assertOp(A, B, string fn=__FILE__, int ln=__LINE__)(A a, B b, strin < 73 { < 74 try { < 75 if( mixin("a"~op~"b") ) return; < 76 } catch(Throwable e) { < 77 onAssertErrorMsg(fn, ln, msg.length ? msg : sprintf!"exc < 78 } < 79 onAssertErrorMsg(fn, ln, msg.length ? msg : sprintf!"%s !%s %s"( < 80 } < 81 } < 82 < 83 alias assertOp!(`==`) assert_eq; < 84 alias assertOp!(`!=`) assert_ne; < 85 alias assertOp!(`<`) assert_lt; < 86 alias assertOp!(`<=`) assert_le; < 87 alias assertOp!(`>`) assert_gt; < 88 alias assertOp!(`>=`) assert_ge; < 89 < 90 unittest < 91 { < 92 assert_nothrow( assert_eq(1, 1) ); < 93 assert_nothrow( assert_ne(1, 0) ); < 94 assert_nothrow( assert_lt(0, 1) ); < 95 assert_nothrow( assert_le(0, 1) ); < 96 assert_nothrow( assert_le(0, 0) ); < 97 assert_nothrow( assert_gt(1, 0) ); < 98 assert_nothrow( assert_ge(1, 0) ); < 99 assert_nothrow( assert_ge(0, 0) ); < 100 < 101 assert_throw!AssertError( assert_eq(1, 0) ); < 102 assert_throw!AssertError( assert_ne(1, 1) ); < 103 assert_throw!AssertError( assert_lt(1, 1) ); < 104 assert_throw!AssertError( assert_lt(1, 0) ); < 105 assert_throw!AssertError( assert_le(1, 0) ); < 106 assert_throw!AssertError( assert_gt(0, 0) ); < 107 assert_throw!AssertError( assert_gt(0, 1) ); < 108 assert_throw!AssertError( assert_ge(0, 1) ); < 109 < 110 class Temp { bool opEquals(int x){return x/x==x;} } < 111 assert_throw!AssertError( assert_eq(new Temp, 0) ); < 112 assert_nothrow ( assert_eq(new Temp, 1) ); < 113 assert_throw!AssertError( assert_eq(new Temp, 2) ); < 114 } < 115 < 116 /* [Todo] is there any way to clearnly implement "assert_compiles" and "assert_n < 117 < 118 /// Mixing-in the bean constructor for a class < 119 < 120 /*mixin*/ < 121 template SimpleConstructor() < 122 { < 123 static if( is(typeof(super) == Object) || super.tupleof.length==0 ) < 124 this( typeof(this.tupleof) params ) < 125 { < 126 static if(this.tupleof.length>0) < 127 this.tupleof = params; < 128 } < 129 else < 130 this( typeof(super.tupleof) ps, typeof(this.tupleof) params ) < 131 { < 132 // including (only) the direct super class members < 133 // may not always be a desirable choice, but should work < 134 super(ps); < 135 static if(this.tupleof.length>0) < 136 this.tupleof = params; < 137 } < 138 } < 139 < 140 unittest < 141 { < 142 class Temp < 143 { < 144 int x; < 145 string y; < 146 mixin SimpleConstructor; < 147 } < 148 assert_eq( (new Temp(1,"foo")).x, 1 ); < 149 assert_eq( (new Temp(1,"foo")).y, "foo" ); < 150 assert( !__traits(compiles, new Temp) ); < 151 assert( !__traits(compiles, new Temp(1)) ); < 152 assert( !__traits(compiles, new Temp("foo",1)) ); < 153 < 154 class Tomp : Temp < 155 { < 156 real z; < 157 mixin SimpleConstructor; < 158 } < 159 assert_eq( (new Tomp(1,"foo",2.5)).x, 1 ); < 160 assert_eq( (new Tomp(1,"foo",2.5)).y, "foo" ); < 161 assert_eq( (new Tomp(1,"foo",2.5)).z, 2.5 ); < 162 assert( !__traits(compiles, new Tomp(3.14)) ); < 163 < 164 // shiyo- desu. Don't use in this way. < 165 // Tamp tries to call new Tomp(real) (because it only sees Tomp's memb < 166 // but it fails because Tomp takes (int,string,real). < 167 assert( !__traits(compiles, { < 168 class Tamp : Tomp < 169 { < 170 mixin SimpleConstructor; < 171 } < 172 }) ); < 173 } < 174 < 175 /// Mixing-in the MOST-DERIVED-member-wise comparator for a class < 176 < 177 /*mixin*/ < 178 template SimpleCompare() < 179 { < 180 override bool opEquals(Object rhs_) const < 181 { < 182 if( auto rhs = cast(typeof(this))rhs_ ) < 183 { < 184 foreach(i,_; this.tupleof) < 185 if( this.tupleof[i] != rhs.tupleof[i] ) < 186 return false; < 187 return true; < 188 } < 189 assert(false, sprintf!"Cannot compare %s with %s"(typeid(this), < 190 } < 191 < 192 override hash_t toHash() const < 193 { < 194 hash_t h = 0; < 195 foreach(mem; this.tupleof) < 196 h += typeid(mem).getHash(&mem); < 197 return h; < 198 } < 199 < 200 override int opCmp(Object rhs_) const < 201 { < 202 if( auto rhs = cast(typeof(this))rhs_ ) < 203 { < 204 foreach(i,_; this.tupleof) < 205 if(auto c = typeid(_).compare(&this.tupleof[i],& < 206 return c; < 207 return 0; < 208 } < 209 assert(false, sprintf!"Cannot compare %s with %s"(typeid(this), < 210 } < 211 } < 212 < 213 unittest < 214 { < 215 class Temp < 216 { < 217 int x; < 218 string y; < 219 mixin SimpleConstructor; < 220 mixin SimpleCompare; < 221 } < 222 assert_eq( new Temp(1,"foo"), new Temp(1,"foo") ); < 223 assert_eq( (new Temp(1,"foo")).toHash, (new Temp(1,"foo")).toHash ); < 224 assert_ne( new Temp(1,"foo"), new Temp(2,"foo") ); < 225 assert_ne( new Temp(1,"foo"), new Temp(1,"bar") ); < 226 assert_gt( new Temp(1,"foo"), new Temp(1,"bar") ); < 227 assert_lt( new Temp(1,"foo"), new Temp(2,"bar") ); < 228 assert_ge( new Temp(1,"foo"), new Temp(1,"foo") ); < 229 < 230 class TempDummy < 231 { < 232 int x; < 233 string y; < 234 mixin SimpleConstructor; < 235 mixin SimpleCompare; < 236 } < 237 assert_throw!AssertError( new Temp(1,"foo") == new TempDummy(1,"foo") ); < 238 assert_throw!AssertError( new Temp(1,"foo") <= new TempDummy(1,"foo") ); < 239 } < 240 < 241 /// Mixing-in a simple toString method < 242 < 243 /*mixin*/ < 244 template SimpleToString() < 245 { < 246 override string toString() < 247 { < 248 string str = sprintf!"%s("(typeof(this).stringof); < 249 foreach(i,mem; this.tupleof) < 250 { < 251 if(i) str ~= ","; < 252 static if( is(typeof(mem) == std.bigint.BigInt) ) < 253 str ~= std.bigint.toDecimalString(mem); < 254 else < 255 str ~= sprintf!"%s"(mem); < 256 } < 257 return str ~ ")"; < 258 } < 259 } < 260 < 261 version(unittest) import std.bigint; < 262 unittest < 263 { < 264 class Temp < 265 { < 266 int x; < 267 string y; < 268 BigInt z; < 269 mixin SimpleConstructor; < 270 mixin SimpleToString; < 271 } < 272 assert_eq( (new Temp(1,"foo",BigInt(42))).toString(), "Temp(1,foo,42)" ) < 273 } < 274 < 275 /// Everything is in < 276 < 277 /*mixin*/ < 278 template SimpleClass() < 279 { < 280 mixin SimpleConstructor; < 281 mixin SimpleCompare; < 282 mixin SimpleToString; < 283 } <

Modified polemy/value.d from [b8f99f303d4d3a98] to [38155bcc400d812f].

1 /** | 1 /** 2 * Authors: k.inaba 2 * Authors: k.inaba 3 * License: NYSL 0.9982 http://www.kmonos.net/nysl/ 3 * License: NYSL 0.9982 http://www.kmonos.net/nysl/ 4 * 4 * 5 * Runtime data structures for Polemy programming language. 5 * Runtime data structures for Polemy programming language. 6 */ 6 */ 7 module polemy.value; 7 module polemy.value; 8 import polemy._common; 8 import polemy._common; ................................................................................................................................................................................ 11 /// Raised when something went wrong in runtime 11 /// Raised when something went wrong in runtime 12 12 13 class RuntimeException : Exception 13 class RuntimeException : Exception 14 { 14 { 15 const LexPosition pos; 15 const LexPosition pos; 16 16 17 this( const LexPosition pos, string msg ) 17 this( const LexPosition pos, string msg ) 18 { super(sprintf!"%s [%s]"(msg, pos)); this.pos = pos; } | 18 { super(sprintf!"%s at [%s]"(msg, pos)); this.pos = pos; } 19 this( string msg ) { super(msg); this.pos = null; } < 20 } 19 } 21 20 22 /// Runtime values of Polemy 21 /// Runtime values of Polemy 23 22 24 abstract class Value 23 abstract class Value 25 { 24 { 26 } 25 } ................................................................................................................................................................................ 63 class Table : Value 62 class Table : Value 64 { 63 { 65 enum Kind {PropagateSet, NotPropagateSet}; 64 enum Kind {PropagateSet, NotPropagateSet}; 66 65 67 this( Table proto=null, Kind k = Kind.PropagateSet ) 66 this( Table proto=null, Kind k = Kind.PropagateSet ) 68 { this.prototype = proto; this.kind = k; } 67 { this.prototype = proto; this.kind = k; } 69 68 70 void set(string i, Layer lay, Value v) | 69 void set(string i, Layer lay, Value v, in LexPosition pos=null) 71 { 70 { 72 if( !setIfExist(i, lay, v) ) | 71 if( setIfExist(i, lay, v) ) > 72 return; 73 data[i][lay] = v; | 73 data[i][lay] = v; 74 } 74 } 75 75 76 Value get(string i, Layer lay) | 76 Value get(string i, Layer lay, in LexPosition pos=null) 77 { 77 { 78 if( i in data ) 78 if( i in data ) 79 return data[i][lay]; 79 return data[i][lay]; 80 if( prototype is null ) 80 if( prototype is null ) 81 throw new RuntimeException(sprintf!"variable %s not foun | 81 throw new RuntimeException(pos, sprintf!"variable %s not 82 return prototype.get(i, lay); 82 return prototype.get(i, lay); 83 } 83 } 84 84 85 private: 85 private: 86 Table prototype; 86 Table prototype; 87 Kind kind; 87 Kind kind; 88 Value[Layer][string] data; 88 Value[Layer][string] data;

Added tricks/test.d version [bb5afea9b7b1423d]

> 1 /** > 2 * Authors: k.inaba > 3 * License: NYSL 0.9982 http://www.kmonos.net/nysl/ > 4 * > 5 * Unittest helpers. > 6 */ > 7 module tricks.test; > 8 import std.conv : to; > 9 import core.exception; > 10 > 11 /// Unittest helper that asserts an expression must throw something > 12 > 13 void assert_throw(ExceptionType, T, string fn=__FILE__, int ln=__LINE__)(lazy T > 14 { > 15 try > 16 { t(); } > 17 catch(ExceptionType) > 18 { return; } > 19 catch(Throwable e) > 20 { onAssertErrorMsg(fn, ln, msg.length ? msg : "exception ["~e.to > 21 onAssertErrorMsg(fn, ln, msg.length ? msg : "no execption"); > 22 } > 23 > 24 /// Unittest helper that asserts an expression must not throw anything > 25 > 26 auto assert_nothrow(T, string fn=__FILE__, int ln=__LINE__)(lazy T t, string msg > 27 { > 28 try > 29 { return t(); } > 30 catch(Throwable e) > 31 { onAssertErrorMsg(fn, ln, msg.length ? msg : "exception ["~e.to > 32 assert(false); > 33 } > 34 > 35 unittest > 36 { > 37 auto error = {throw new Error("hello");}; > 38 auto nothing = (){}; > 39 auto assertError = {assert(0);}; > 40 > 41 assert_nothrow ( assert_nothrow(nothing()) ); > 42 assert_throw!AssertError( assert_nothrow(error()) ); > 43 assert_throw!AssertError( assert_nothrow(assertError()) ); > 44 > 45 assert_nothrow ( assert_throw!Error(error()) ); > 46 assert_throw!AssertError( assert_throw!Error(nothing()) ); > 47 assert_nothrow ( assert_throw!Error(assertError()) ); > 48 assert_throw!AssertError( assert_throw!AssertError(error()) ); > 49 } > 50 > 51 /// Unittest helpers asserting two values are in some relation ==, !=, <, <=, >, > 52 > 53 template assertOp(string op) > 54 { > 55 void assertOp(A, B, string fn=__FILE__, int ln=__LINE__)(A a, B b, strin > 56 { > 57 try > 58 { if( mixin("a"~op~"b") ) return; } > 59 catch(Throwable e) > 60 { onAssertErrorMsg(fn, ln, msg.length ? msg : "exception > 61 onAssertErrorMsg(fn, ln, msg.length ? msg : to!string(a)~" !"~op > 62 } > 63 } > 64 > 65 alias assertOp!(`==`) assert_eq; > 66 alias assertOp!(`!=`) assert_ne; > 67 alias assertOp!(`<`) assert_lt; > 68 alias assertOp!(`<=`) assert_le; > 69 alias assertOp!(`>`) assert_gt; > 70 alias assertOp!(`>=`) assert_ge; > 71 > 72 unittest > 73 { > 74 assert_nothrow( assert_eq(1, 1) ); > 75 assert_nothrow( assert_ne(1, 0) ); > 76 assert_nothrow( assert_lt(0, 1) ); > 77 assert_nothrow( assert_le(0, 1) ); > 78 assert_nothrow( assert_le(0, 0) ); > 79 assert_nothrow( assert_gt(1, 0) ); > 80 assert_nothrow( assert_ge(1, 0) ); > 81 assert_nothrow( assert_ge(0, 0) ); > 82 > 83 assert_throw!AssertError( assert_eq(1, 0) ); > 84 assert_throw!AssertError( assert_ne(1, 1) ); > 85 assert_throw!AssertError( assert_lt(1, 1) ); > 86 assert_throw!AssertError( assert_lt(1, 0) ); > 87 assert_throw!AssertError( assert_le(1, 0) ); > 88 assert_throw!AssertError( assert_gt(0, 0) ); > 89 assert_throw!AssertError( assert_gt(0, 1) ); > 90 assert_throw!AssertError( assert_ge(0, 1) ); > 91 > 92 class Temp { bool opEquals(int x){return x/x==x;} } > 93 assert_throw!AssertError( assert_eq(new Temp, 0) ); > 94 assert_nothrow ( assert_eq(new Temp, 1) ); > 95 assert_throw!AssertError( assert_eq(new Temp, 2) ); > 96 } > 97 > 98 /* [Todo] is there any way to clearnly implement "assert_compiles" and "assert_n

Modified tricks/tricks.d from [73906cba073bce6c] to [3f689d3451f8c1cc].

1 /** | 1 /** 2 * Authors: k.inaba 2 * Authors: k.inaba 3 * License: NYSL 0.9982 http://www.kmonos.net/nysl/ 3 * License: NYSL 0.9982 http://www.kmonos.net/nysl/ 4 * 4 * 5 * Common tricks and utilities for programming in D. 5 * Common tricks and utilities for programming in D. 6 */ 6 */ 7 module polemy.tricks; | 7 module tricks.tricks; > 8 import tricks.test; 8 import std.array : appender; 9 import std.array : appender; 9 import std.format : formattedWrite; 10 import std.format : formattedWrite; 10 import core.exception : onAssertErrorMsg, AssertError; | 11 import core.exception : AssertError; 11 12 12 /// Simple Wrapper for std.format.doFormat 13 /// Simple Wrapper for std.format.doFormat 13 14 14 string sprintf(string fmt, T...)(T params) 15 string sprintf(string fmt, T...)(T params) 15 { 16 { 16 auto writer = appender!string(); 17 auto writer = appender!string(); 17 formattedWrite(writer, fmt, params); 18 formattedWrite(writer, fmt, params); ................................................................................................................................................................................ 20 21 21 unittest 22 unittest 22 { 23 { 23 assert( sprintf!"%s == %d"("1+2", 3) == "1+2 == 3" ); 24 assert( sprintf!"%s == %d"("1+2", 3) == "1+2 == 3" ); 24 assert( sprintf!"%s == %04d"("1+2", 3) == "1+2 == 0003" ); 25 assert( sprintf!"%s == %04d"("1+2", 3) == "1+2 == 0003" ); 25 } 26 } 26 27 27 /// Unittest helper that asserts an expression must throw something | 28 /// Create an exception with automatically completed filename and lineno informa 28 29 29 void assert_throw(ExceptionType, T, string fn=__FILE__, int ln=__LINE__)(lazy T | 30 auto genex(ExceptionType, string fn=__FILE__, int ln=__LINE__, T...)(T params) 30 { 31 { 31 try { | 32 static if( T.length > 0 && is(T[$-1] : Throwable) ) 32 t(); | 33 return new ExceptionType(params[0..$-1], fn, ln, params[$-1]); > 34 else 33 } catch(ExceptionType) { | 35 return new ExceptionType(params, fn, ln); 34 return; < 35 } catch(Throwable e) { < 36 onAssertErrorMsg(fn, ln, msg.length ? msg : sprintf!"exception [ < 37 } < 38 onAssertErrorMsg(fn, ln, msg.length ? msg : "no execption"); < 39 } < 40 < 41 /// Unittest helper that asserts an expression must not throw anything < 42 < 43 void assert_nothrow(T, string fn=__FILE__, int ln=__LINE__)(lazy T t, string msg < 44 { < 45 try { < 46 t(); < 47 } catch(Throwable e) { < 48 onAssertErrorMsg(fn, ln, msg.length ? msg : sprintf!"exception [ < 49 } < 50 } 36 } 51 37 52 unittest 38 unittest 53 { 39 { 54 auto error = {throw new Error("hello");}; | 40 assert_ne( genex!Exception("msg").file, "" ); 55 auto nothing = (){}; | 41 assert_ne( genex!Exception("msg").line, 0 ); 56 auto assertError = {assert(0);}; | 42 assert_ne( genex!Exception("msg",new Exception("bar")).next, Exception.i 57 < 58 assert_nothrow ( assert_nothrow(nothing()) ); < 59 assert_throw!AssertError( assert_nothrow(error()) ); < 60 assert_throw!AssertError( assert_nothrow(assertError()) ); < 61 < 62 assert_nothrow ( assert_throw!Error(error()) ); < 63 assert_throw!AssertError( assert_throw!Error(nothing()) ); < 64 assert_nothrow ( assert_throw!Error(assertError()) ); < 65 assert_throw!AssertError( assert_throw!AssertError(error()) ); < 66 } 43 } 67 44 68 /// Unittest helpers asserting two values are in some relation ==, !=, <, <=, >, < 69 < 70 template assertOp(string op) < 71 { < 72 void assertOp(A, B, string fn=__FILE__, int ln=__LINE__)(A a, B b, strin < 73 { < 74 try { < 75 if( mixin("a"~op~"b") ) return; < 76 } catch(Throwable e) { < 77 onAssertErrorMsg(fn, ln, msg.length ? msg : sprintf!"exc < 78 } < 79 onAssertErrorMsg(fn, ln, msg.length ? msg : sprintf!"%s !%s %s"( < 80 } < 81 } < 82 < 83 alias assertOp!(`==`) assert_eq; < 84 alias assertOp!(`!=`) assert_ne; < 85 alias assertOp!(`<`) assert_lt; < 86 alias assertOp!(`<=`) assert_le; < 87 alias assertOp!(`>`) assert_gt; < 88 alias assertOp!(`>=`) assert_ge; < 89 < 90 unittest < 91 { < 92 assert_nothrow( assert_eq(1, 1) ); < 93 assert_nothrow( assert_ne(1, 0) ); < 94 assert_nothrow( assert_lt(0, 1) ); < 95 assert_nothrow( assert_le(0, 1) ); < 96 assert_nothrow( assert_le(0, 0) ); < 97 assert_nothrow( assert_gt(1, 0) ); < 98 assert_nothrow( assert_ge(1, 0) ); < 99 assert_nothrow( assert_ge(0, 0) ); < 100 < 101 assert_throw!AssertError( assert_eq(1, 0) ); < 102 assert_throw!AssertError( assert_ne(1, 1) ); < 103 assert_throw!AssertError( assert_lt(1, 1) ); < 104 assert_throw!AssertError( assert_lt(1, 0) ); < 105 assert_throw!AssertError( assert_le(1, 0) ); < 106 assert_throw!AssertError( assert_gt(0, 0) ); < 107 assert_throw!AssertError( assert_gt(0, 1) ); < 108 assert_throw!AssertError( assert_ge(0, 1) ); < 109 < 110 class Temp { bool opEquals(int x){return x/x==x;} } < 111 assert_throw!AssertError( assert_eq(new Temp, 0) ); < 112 assert_nothrow ( assert_eq(new Temp, 1) ); < 113 assert_throw!AssertError( assert_eq(new Temp, 2) ); < 114 } < 115 < 116 /* [Todo] is there any way to clearnly implement "assert_compiles" and "assert_n < 117 < 118 /// Mixing-in the bean constructor for a class 45 /// Mixing-in the bean constructor for a class 119 46 120 /*mixin*/ 47 /*mixin*/ 121 template SimpleConstructor() 48 template SimpleConstructor() 122 { 49 { 123 static if( is(typeof(super) == Object) || super.tupleof.length==0 ) 50 static if( is(typeof(super) == Object) || super.tupleof.length==0 ) 124 this( typeof(this.tupleof) params ) 51 this( typeof(this.tupleof) params )