Compare commits

...
10 Commits
Author SHA1 Message Date
Nicolas Cannasse 8b9b244512 fix overflow on bigint platforms (close #42) 2017-05-06 11:17:58 +02:00
Nicolas Cannasse ace61e589d moved build scripts in /bin 2017-05-06 11:14:45 +02:00
Tom CoxonandNicolas Cannasse 51506e0400 Add filename / line number error reporting with -D hscriptPos (#57) 2017-01-02 17:48:48 +01:00
Andy Li 4a1432b01d [TravisCI] flash-player-debuger has been moved to caskroom/versions 2016-10-16 23:35:42 +08:00
Pavel AlexandrovandNicolas Cannasse aa16393c1b Add do ... while support. (#51)
Add `do ... while` support.
2016-10-03 12:24:53 +02:00
Andy Li 55ed2c0d5c Avoid using Array#sort in test.
There is some problem with the php target. Let's workaround it for now.
2016-10-01 15:14:58 +08:00
Andy Li 6c588733d9 [CI] updated flash player install 2016-10-01 12:14:25 +08:00
Andy LiandGitHub d72411632d [TravisCI] use OSX 10.10 2016-10-01 10:59:02 +08:00
romamikandNicolas Cannasse a1af1ec29e Added Map support (#49)
Map support
2016-09-28 13:04:18 +02:00
Andy Li bdd55483f9 add a line in release.bat to remind Nicolas to create a git tag 2016-08-21 22:33:13 +08:00
32 changed files with 386 additions and 110 deletions
+11 -9
View File
@@ -4,6 +4,8 @@ os:
- linux
- osx
osx_image: xcode6.4
haxe:
- "3.2.1"
- development
@@ -62,12 +64,12 @@ script:
- pushd script &&
haxe build.hxml &&
popd
- haxe build-interp.hxml
- haxe build-neko.hxml && neko bin/Test.n
- haxe build-js.hxml && node bin/Test.js
- haxe build-java.hxml && java -jar bin/Test.jar
- haxe build-cs.hxml && mono bin/bin/Test.exe
- haxe build-cpp.hxml && ./bin/Test
- haxe build-flash.hxml -D fdb && haxe flash/run.hxml bin/Test.swf
- haxe build-php.hxml && php bin/index.php
- haxe build-python.hxml && python3 bin/Test.py
- haxe bin/build-interp.hxml
- haxe bin/build-neko.hxml && neko bin/Test.n
- haxe bin/build-js.hxml && node bin/Test.js
- haxe bin/build-java.hxml && java -jar bin/Test.jar
- haxe bin/build-cs.hxml && mono bin/bin/Test.exe
- haxe bin/build-cpp.hxml && ./bin/Test
- haxe bin/build-flash.hxml -D fdb && haxe flash/run.hxml bin/Test.swf
- haxe bin/build-php.hxml && php bin/index.php
- haxe bin/build-python.hxml && python3 bin/Test.py
+55 -9
View File
@@ -1,3 +1,5 @@
import haxe.ds.EnumValueMap;
import haxe.ds.Option;
import hscript.Macro;
import haxe.unit.*;
@@ -19,15 +21,8 @@ class Test extends TestCase {
function test():Void {
assertScript("0",0);
assertScript("0xFF", 255);
#if !(php || python)
#if haxe3
assertScript("0xBFFFFFFF", 0xBFFFFFFF);
assertScript("0x7FFFFFFF", 0x7FFFFFFF);
#elseif !neko
assertScript("n(0xBFFFFFFF)", 0xBFFFFFFF, { n : haxe.Int32.toNativeInt });
assertScript("n(0x7FFFFFFF)", 0x7FFFFFFF, { n : haxe.Int32.toNativeInt } );
#end
#end
assertScript("0xBFFFFFFF", 0xBFFFFFFF);
assertScript("0x7FFFFFFF", 0x7FFFFFFF);
assertScript("-123",-123);
assertScript("- 123",-123);
assertScript("1.546",1.546);
@@ -73,6 +68,7 @@ class Test extends TestCase {
assertScript("(function(a,b) return a + b)(4,5)",9);
assertScript("var y = 0; var add = function(a) y += a; add(5); add(3); y", 8);
assertScript("var a = [1,[2,[3,[4,null]]]]; var t = 0; while( a != null ) { t += a[0]; a = a[1]; }; t",10);
assertScript("var a = false; do { a = true; } while (!a); a;",true);
assertScript("var t = 0; for( x in 1...10 ) t += x; t", 45);
#if haxe3
assertScript("var t = 0; for( x in new IntIterator(1,10) ) t +=x; t", 45);
@@ -94,6 +90,56 @@ class Test extends TestCase {
assertScript("/**/0", 0);
assertScript("x=1;x*=-2", -2);
}
function testMap():Void {
var objKey = { ok:true };
var vars = {
stringMap: ["foo" => "Foo", "bar" => "Bar"],
intMap:[100 => "one hundred"],
objKey: objKey,
objMap:[objKey => "ok"],
enumKey:Option.Some("some"),
enumMap:new EnumValueMap<Option<String>, String>(),
stringIntMap: ["foo" => 100]
}
vars.enumMap.set(vars.enumKey, "ok");
assertScript('stringMap["foo"]', "Foo", vars);
assertScript('intMap[100]', "one hundred", vars);
assertScript('objMap[objKey]', "ok", vars);
assertScript('enumMap[enumKey]', "ok", vars);
assertScript('stringMap["a"] = "A"; stringMap["a"]', "A", vars);
assertScript('intMap[200] = objMap[{foo:false}] = enumMap[enumKey] = "A"', "A", vars);
assertEquals('A', vars.intMap[200]);
assertEquals('A', vars.enumMap.get(vars.enumKey));
for (key in vars.objMap.keys()) {
if (key != objKey) {
assertEquals(false, (key:Dynamic).foo);
assertEquals('A', vars.objMap[key]);
}
}
assertScript('
var keys = [];
for (key in stringMap.keys()) keys.push(key);
keys.join("_");
', {
var keys = [];
for (key in vars.stringMap.keys()) keys.push(key);
keys.join("_");
}, vars);
assertScript('stringMap.remove("foo"); stringMap.exists("foo");', false, vars);
assertScript('stringMap["foo"] = "a"; stringMap["foo"] += "b"', 'ab', vars);
assertEquals('ab', vars.stringMap['foo']);
assertScript('stringIntMap["foo"]++', 100, vars);
assertEquals(101, vars.stringIntMap['foo']);
assertScript('++stringIntMap["foo"]', 102, vars);
assertScript('var newMap = ["foo"=>"foo"]; newMap["foo"];', 'foo', vars);
#if (!php || (haxe_ver >= 3.3))
assertScript('var newMap = [enumKey=>"foo"]; newMap[enumKey];', 'foo', vars);
#end
assertScript('var newMap = [{a:"a"}=>"foo", objKey=>"bar"]; newMap[objKey];', 'bar', vars);
}
static function main() {
var runner = new TestRunner();
+9 -9
View File
@@ -28,12 +28,12 @@ test_script:
- pushd script &&
haxe build.hxml &&
popd
- haxe build-interp.hxml
- haxe build-neko.hxml && neko bin\Test.n
- haxe build-js.hxml && node bin\Test.js
- haxe build-java.hxml && java -jar bin\Test.jar
- haxe build-cs.hxml && bin\bin\Test.exe
- haxe build-cpp.hxml && bin\Test.exe
- haxe build-flash.hxml -D fdb && haxe flash\run.hxml bin\Test.swf
- haxe build-php.hxml && C:\tools\php\php.exe bin\index.php
- haxe build-python.hxml && C:\Python34-x64\python.exe bin\Test.py
- haxe bin/build-interp.hxml
- haxe bin/build-neko.hxml && neko bin\Test.n
- haxe bin/build-js.hxml && node bin\Test.js
- haxe bin/build-java.hxml && java -jar bin\Test.jar
- haxe bin/build-cs.hxml && bin\bin\Test.exe
- haxe bin/build-cpp.hxml && bin\Test.exe
- haxe bin/build-flash.hxml -D fdb && haxe flash\run.hxml bin\Test.swf
- haxe bin/build-php.hxml && C:\tools\php\php.exe bin\index.php
- haxe bin/build-python.hxml && C:\Python34-x64\python.exe bin\Test.py
+2
View File
@@ -0,0 +1,2 @@
bin/build-each.hxml
-cpp bin
+2
View File
@@ -0,0 +1,2 @@
bin/build-each.hxml
-cs bin
+1 -1
View File
@@ -1,4 +1,4 @@
build-each.hxml
bin/build-each.hxml
-swf bin/Test.swf
-swf-header 800:600:30:FFFFFF
--flash-strict
+2
View File
@@ -0,0 +1,2 @@
bin/build-each.hxml
--interp
+2
View File
@@ -0,0 +1,2 @@
bin/build-each.hxml
-java bin
+2
View File
@@ -0,0 +1,2 @@
bin/build-each.hxml
-js bin/Test.js
+2
View File
@@ -0,0 +1,2 @@
bin/build-each.hxml
-neko bin/Test.n
+2
View File
@@ -0,0 +1,2 @@
bin/build-each.hxml
-php bin
+2
View File
@@ -0,0 +1,2 @@
bin/build-each.hxml
-python bin/Test.py
-2
View File
@@ -1,2 +0,0 @@
build-each.hxml
-cpp bin
-2
View File
@@ -1,2 +0,0 @@
build-each.hxml
-cs bin
-2
View File
@@ -1,2 +0,0 @@
build-each.hxml
--interp
-2
View File
@@ -1,2 +0,0 @@
build-each.hxml
-java bin
-2
View File
@@ -1,2 +0,0 @@
build-each.hxml
-js bin/Test.js
-2
View File
@@ -1,2 +0,0 @@
build-each.hxml
-neko bin/Test.n
-2
View File
@@ -1,2 +0,0 @@
build-each.hxml
-php bin
-2
View File
@@ -1,2 +0,0 @@
build-each.hxml
-python bin/Test.py
+20 -6
View File
@@ -1,5 +1,4 @@
import Sys.*;
import sys.FileSystem.*;
import sys.io.File.*;
import haxe.*;
import haxe.io.*;
@@ -10,9 +9,9 @@ class Install {
case "Linux":
"https://fpdownload.macromedia.com/pub/flashplayer/updaters/11/flashplayer_11_sa_debug.i386.tar.gz";
case "Mac":
"https://fpdownload.macromedia.com/pub/flashplayer/updaters/19/flashplayer_19_sa_debug.dmg";
"https://fpdownload.macromedia.com/pub/flashplayer/updaters/21/flashplayer_21_sa_debug.dmg";
case "Windows":
"http://fpdownload.macromedia.com/pub/flashplayer/updaters/19/flashplayer_19_sa_debug.exe";
"http://fpdownload.macromedia.com/pub/flashplayer/updaters/21/flashplayer_21_sa_debug.exe";
case _:
throw "unsupported system";
}
@@ -47,9 +46,9 @@ class Install {
if (command("tar", ["-xf", Path.withoutDirectory(fpDownload), "-C", "flash"]) != 0)
throw "failed to extract flash player";
case "Mac":
if (command("brew", ["install", "caskroom/cask/brew-cask"]) != 0)
throw "failed to brew install caskroom/cask/brew-cask";
if (command("brew", ["cask", "install", "flash-player-debugger", "--appdir=flash"]) != 0)
if (command("brew", ["tap", "caskroom/versions"]) != 0)
throw "failed to brew tap caskroom/versions";
if (command("brew", ["cask", "install", "flash-player-debugger"]) != 0)
throw "failed to install flash-player-debugger";
case "Windows":
// Download flash player
@@ -74,4 +73,19 @@ class Install {
};
http.customRequest(false, write(saveAs));
}
static function createDirectory(dir:String):Void {
try {
sys.FileSystem.createDirectory(dir);
} catch(e:Dynamic) {
switch (systemName()) {
case "Mac", "Linux":
if (command("sudo", ["mkdir", "-p", dir]) != 0)
throw 'cannot create $dir';
if (command("sudo", ["chmod", "a+rw", dir]) != 0)
throw 'cannot set permission of $dir';
case _:
neko.Lib.rethrow(e);
}
}
}
}
+13 -2
View File
@@ -30,13 +30,24 @@ class Run {
}
c;
case "Mac":
command("flash/Flash Player Debugger.app/Contents/MacOS/Flash Player Debugger", [fullPath(swf)]);
command("/Applications/Flash Player Debugger.app/Contents/MacOS/Flash Player Debugger", [fullPath(swf)]);
case "Windows":
command("flash\\flashplayer.exe", [fullPath(swf)]);
case _:
throw "unsupported platform";
}
println(getContent(flashlog));
if (exists(flashlog))
println(getContent(flashlog));
else {
println('does not exist: $flashlog');
var parts = Path.normalize(flashlog).split("/");
println(parts);
for (i in 0...parts.length-1) {
var path = parts.splice(0, i+1).join("/");
println('ls $path');
command("ls", [path]);
}
}
exit(exitCode);
}
}
+1 -1
View File
@@ -1 +1 @@
build-flash.hxml
bin/build-flash.hxml
+27 -8
View File
@@ -74,6 +74,13 @@ class Bytes {
return strings[id];
}
function doEncodeInt(v: Int) {
bout.addByte(v & 0xFF);
bout.addByte((v >> 8) & 0xFF);
bout.addByte((v >> 16) & 0xFF);
bout.addByte(v >>> 24);
}
function doEncodeConst( c : Const ) {
switch( c ) {
case CInt(v):
@@ -82,10 +89,7 @@ class Bytes {
bout.addByte(v);
} else {
bout.addByte(1);
bout.addByte(v & 0xFF);
bout.addByte((v >> 8) & 0xFF);
bout.addByte((v >> 16) & 0xFF);
bout.addByte(v >>> 24);
doEncodeInt(v);
}
#if !haxe3
case CInt32(v):
@@ -105,13 +109,18 @@ class Bytes {
}
}
function doDecodeInt() {
var i = bin.get(pin) | (bin.get(pin+1) << 8) | (bin.get(pin+2) << 16) | (bin.get(pin+3) << 24);
pin += 4;
return i;
}
function doDecodeConst() {
return switch( bin.get(pin++) ) {
case 0:
CInt(bin.get(pin++));
case 1:
var i = bin.get(pin) | (bin.get(pin+1) << 8) | (bin.get(pin+2) << 16) | (bin.get(pin+3) << 24);
pin += 4;
var i = doDecodeInt();
CInt(i);
case 2:
CFloat( Std.parseFloat(doDecodeString()) );
@@ -131,6 +140,8 @@ class Bytes {
function doEncode( e : Expr ) {
#if hscriptPos
doEncodeString(e.origin);
doEncodeInt(e.line);
var e = e.e;
#end
bout.addByte(Type.enumIndex(e));
@@ -177,6 +188,9 @@ class Bytes {
case EWhile(cond,e):
doEncode(cond);
doEncode(e);
case EDoWhile(cond,e):
doEncode(cond);
doEncode(e);
case EFor(v,it,e):
doEncodeString(v);
doEncode(it);
@@ -238,7 +252,9 @@ class Bytes {
function doDecode() : Expr {
#if hscriptPos
return { e : _doDecode(), pmin : 0, pmax : 0 };
var origin = doDecodeString();
var line = doDecodeInt();
return { e : _doDecode(), pmin : 0, pmax : 0, origin : origin, line : line };
}
function _doDecode() : ExprDef {
#end
@@ -347,6 +363,9 @@ class Bytes {
}
var def = doDecode();
ESwitch(e, cases, def);
case 24:
var cond = doDecode();
EDoWhile(cond,doDecode());
case 255:
null;
default:
@@ -365,4 +384,4 @@ class Bytes {
return b.doDecode();
}
}
}
+42 -1
View File
@@ -38,6 +38,8 @@ typedef Expr = {
var e : ExprDef;
var pmin : Int;
var pmax : Int;
var origin : String;
var line : Int;
}
enum ExprDef {
#else
@@ -67,6 +69,7 @@ enum Expr {
EObject( fl : Array<{ name : String, e : Expr }> );
ETernary( cond : Expr, e1 : Expr, e2 : Expr );
ESwitch( e : Expr, cases : Array<{ values : Array<Expr>, expr : Expr }>, ?defaultExpr : Expr);
EDoWhile( cond : Expr, e : Expr);
}
typedef Argument = { name : String, ?t : CType, ?opt : Bool };
@@ -83,10 +86,48 @@ class Error {
public var e : ErrorDef;
public var pmin : Int;
public var pmax : Int;
public function new(e, pmin, pmax) {
public var origin : String;
public var line : Int;
public function new(e, pmin, pmax, origin, line) {
this.e = e;
this.pmin = pmin;
this.pmax = pmax;
this.origin = origin;
this.line = line;
}
private function errorDefToString(): String {
switch (e) {
case EInvalidChar(c):
return "Invalid character: '"+c+"'";
case EUnexpected(s):
return "Unexpected token: \""+s+"\"";
case EUnterminatedString:
return "Unterminated string";
case EUnterminatedComment:
return "Unterminated comment";
case EUnknownVariable(v):
return "Unknown variable: "+v;
case EInvalidIterator(v):
return "Invalid iterator: "+v;
case EInvalidOp(op):
return "Invalid operator: "+op;
case EInvalidAccess(f):
return "Invalid access to field "+f;
}
}
public function toString(): String {
var message = errorDefToString();
message = origin + ":" + line + ": " + message;
return message;
}
}
enum ErrorDef {
+151 -37
View File
@@ -23,6 +23,7 @@
* DAMAGE.
*/
package hscript;
import haxe.PosInfos;
import hscript.Expr;
private enum Stop {
@@ -63,10 +64,18 @@ class Interp {
variables.set("null",null);
variables.set("true",true);
variables.set("false",false);
variables.set("trace",function(e) haxe.Log.trace(Std.string(e),cast { fileName : "hscript", lineNumber : 0 }));
variables.set("trace",function(e) haxe.Log.trace(Std.string(e), posInfos()));
initOps();
}
public function posInfos(): PosInfos {
#if hscriptPos
if (curExpr != null)
return cast { fileName : curExpr.origin, lineNumber : curExpr.line };
#end
return cast { fileName : "hscript", lineNumber : 0 };
}
function initOps() {
var me = this;
#if haxe3
@@ -119,8 +128,16 @@ class Interp {
l.r = v;
case EField(e,f):
v = set(expr(e),f,v);
case EArray(e,index):
expr(e)[expr(index)] = v;
case EArray(e, index):
var arr:Dynamic = expr(e);
var index:Dynamic = expr(index);
if (isMap(arr)) {
setMapValue(arr, index, v);
}
else {
arr[index] = v;
}
default:
error(EInvalidOp("="));
}
@@ -146,11 +163,17 @@ class Interp {
var obj = expr(e);
v = fop(get(obj,f),expr(e2));
v = set(obj,f,v);
case EArray(e,index):
var arr = expr(e);
var index = expr(index);
v = fop(arr[index],expr(e2));
arr[index] = v;
case EArray(e, index):
var arr:Dynamic = expr(e);
var index:Dynamic = expr(index);
if (isMap(arr)) {
v = fop(getMapValue(arr, index), expr(e2));
setMapValue(arr, index, v);
}
else {
v = fop(arr[index],expr(e2));
arr[index] = v;
}
default:
return error(EInvalidOp(op));
}
@@ -181,16 +204,29 @@ class Interp {
} else
set(obj,f,v + delta);
return v;
case EArray(e,index):
var arr = expr(e);
var index = expr(index);
var v = arr[index];
if( prefix ) {
v += delta;
arr[index] = v;
} else
arr[index] = v + delta;
return v;
case EArray(e, index):
var arr:Dynamic = expr(e);
var index:Dynamic = expr(index);
if (isMap(arr)) {
var v = getMapValue(arr, index);
if (prefix) {
v += delta;
setMapValue(arr, index, v);
}
else {
setMapValue(arr, index, v + delta);
}
return v;
}
else {
var v = arr[index];
if( prefix ) {
v += delta;
arr[index] = v;
} else
arr[index] = v + delta;
return v;
}
default:
return error(EInvalidOp((delta > 0)?"++":"--"));
}
@@ -248,7 +284,7 @@ class Interp {
inline function error(e : #if hscriptPos ErrorDef #else Error #end ) : Dynamic {
#if hscriptPos
throw new Error(e, curExpr.pmin, curExpr.pmax);
throw new Error(e, curExpr.pmin, curExpr.pmax, curExpr.origin, curExpr.line);
#else
throw e;
#end
@@ -338,6 +374,9 @@ class Interp {
case EWhile(econd,e):
whileLoop(econd,e);
return null;
case EDoWhile(econd,e):
doWhileLoop(econd,e);
return null;
case EFor(v,it,e):
forLoop(v,it,e);
return null;
@@ -417,12 +456,56 @@ class Interp {
}
return f;
case EArrayDecl(arr):
var a = new Array();
for( e in arr )
a.push(expr(e));
return a;
case EArray(e,index):
return expr(e)[expr(index)];
if (arr.length > 0 && edef(arr[0]).match(EBinop("=>", _))) {
var isAllString:Bool = true;
var isAllInt:Bool = true;
var isAllObject:Bool = true;
var isAllEnum:Bool = true;
var keys:Array<Dynamic> = [];
var values:Array<Dynamic> = [];
for (e in arr) {
switch(edef(e)) {
case EBinop("=>", eKey, eValue): {
var key:Dynamic = expr(eKey);
var value:Dynamic = expr(eValue);
isAllString = isAllString && Std.is(key, String);
isAllInt = isAllInt && Std.is(key, Int);
isAllObject = isAllObject && Reflect.isObject(key);
isAllEnum = isAllEnum && Reflect.isEnumValue(key);
keys.push(key);
values.push(value);
}
default: throw("=> expected");
}
}
var map:Dynamic = {
if (isAllInt) new haxe.ds.IntMap<Dynamic>();
else if (isAllString) new haxe.ds.StringMap<Dynamic>();
else if (isAllEnum) new haxe.ds.EnumValueMap<Dynamic, Dynamic>();
else if (isAllObject) new haxe.ds.ObjectMap<Dynamic, Dynamic>();
else throw 'Inconsistent key types';
}
for (n in 0...keys.length) {
setMapValue(map, keys[n], values[n]);
}
return map;
}
else {
var a = new Array();
for ( e in arr ) {
a.push(expr(e));
}
return a;
}
case EArray(e, index):
var arr:Dynamic = expr(e);
var index:Dynamic = expr(index);
if (isMap(arr)) {
return getMapValue(arr, index);
}
else {
return arr[index];
}
case ENew(cl,params):
var a = new Array();
for( e in params )
@@ -481,6 +564,23 @@ class Interp {
return null;
}
function doWhileLoop(econd,e) {
var old = declared.length;
do {
try {
expr(e);
} catch( err : Stop ) {
switch(err) {
case SContinue:
case SBreak: break;
case SReturn(_): throw err;
}
}
}
while( expr(econd) == true );
restore(old);
}
function whileLoop(econd,e) {
var old = declared.length;
while( expr(econd) == true ) {
@@ -498,8 +598,8 @@ class Interp {
}
function makeIterator( v : Dynamic ) : Iterator<Dynamic> {
#if (flash && !flash9)
if( v.iterator != null ) v = v.iterator();
#if ((flash && !flash9) || php)
if ( v.iterator != null ) v = v.iterator();
#else
try v = v.iterator() catch( e : Dynamic ) {};
#end
@@ -526,18 +626,32 @@ class Interp {
restore(old);
}
inline function isMap(o:Dynamic):Bool {
return Std.is(o, haxe.Constraints.IMap);
}
inline function getMapValue(map:Dynamic, key:Dynamic):Dynamic {
return cast(map, haxe.Constraints.IMap<Dynamic, Dynamic>).get(key);
}
inline function setMapValue(map:Dynamic, key:Dynamic, value:Dynamic):Void {
cast(map, haxe.Constraints.IMap<Dynamic, Dynamic>).set(key, value);
}
function get( o : Dynamic, f : String ) : Dynamic {
if( o == null ) error(EInvalidAccess(f));
#if php
// https://github.com/HaxeFoundation/haxe/issues/4915
return try {
if ( o == null ) error(EInvalidAccess(f));
return {
#if php
// https://github.com/HaxeFoundation/haxe/issues/4915
try {
Reflect.getProperty(o, f);
} catch (e:Dynamic) {
Reflect.field(o, f);
}
#else
Reflect.getProperty(o, f);
} catch (e:Dynamic) {
Reflect.field(o, f);
}
#else
return Reflect.getProperty(o, f);
#end
#end
}
}
function set( o : Dynamic, f : String, v : Dynamic ) : Dynamic {
+3 -1
View File
@@ -180,6 +180,8 @@ class Macro {
EIf(convert(c), convert(e1), e2 == null ? null : convert(e2));
case EWhile(c, e):
EWhile(convert(c), convert(e), true);
case EDoWhile(c, e):
EWhile(convert(c), convert(e), false);
#if (haxe_211 || haxe3)
case EFor(v, it, efor):
var p = #if hscriptPos { file : p.file, min : e.pmin, max : e.pmax } #else p #end;
@@ -232,4 +234,4 @@ class Macro {
}, pos : #if hscriptPos { file : p.file, min : e.pmin, max : e.pmax } #else p #end }
}
}
}
+28 -10
View File
@@ -77,6 +77,7 @@ class Parser {
var uid : Int = 0;
#if hscriptPos
var origin : String;
var readPos : Int;
var tokenMin : Int;
var tokenMax : Int;
@@ -111,7 +112,7 @@ class Parser {
["..."],
["&&"],
["||"],
["=","+=","-=","*=","/=","%=","<<=",">>=",">>>=","|=","&=","^="],
["=","+=","-=","*=","/=","%=","<<=",">>=",">>>=","|=","&=","^=","=>"],
];
#if haxe3
opPriority = new Map();
@@ -133,7 +134,7 @@ class Parser {
public inline function error( err, pmin, pmax ) {
#if hscriptPos
throw new Error(err, pmin, pmax);
throw new Error(err, pmin, pmax, origin, line);
#else
throw err;
#end
@@ -143,14 +144,15 @@ class Parser {
error(EInvalidChar(c), readPos, readPos);
}
public function parseString( s : String ) {
line = 1;
public function parseString( s : String, ?origin : String = "hscript" ) {
uid = 0;
return parse( new haxe.io.StringInput(s) );
return parse( new haxe.io.StringInput(s), origin );
}
public function parse( s : haxe.io.Input ) {
public function parse( s : haxe.io.Input, ?origin : String = "hscript" ) {
line = 1;
#if hscriptPos
this.origin = origin;
readPos = 0;
tokenMin = oldTokenMin = 0;
tokenMax = oldTokenMax = 0;
@@ -224,9 +226,10 @@ class Parser {
inline function mk(e,?pmin,?pmax) : Expr {
#if hscriptPos
if( e == null ) return null;
if( pmin == null ) pmin = tokenMin;
if( pmax == null ) pmax = tokenMax;
return { e : e, pmin : pmin, pmax : pmax };
return { e : e, pmin : pmin, pmax : pmax, origin : origin, line : line };
#else
return e;
#end
@@ -241,6 +244,7 @@ class Parser {
case EBinop(_,_,e): isBlock(e);
case EUnop(_,prefix,e): !prefix && isBlock(e);
case EWhile(_,e): isBlock(e);
case EDoWhile(_,e): isBlock(e);
case EFor(_,_,e): isBlock(e);
case EReturn(e): e != null && isBlock(e);
case ETry(_, _, _, e): isBlock(e);
@@ -370,7 +374,7 @@ class Parser {
}
if( a.length == 1 )
switch( expr(a[0]) ) {
case EFor(_), EWhile(_):
case EFor(_), EWhile(_), EDoWhile(_):
var tmp = "__a_" + (uid++);
var e = mk(EBlock([
mk(EVar(tmp, null, mk(EArrayDecl([]), p1)), p1),
@@ -392,6 +396,8 @@ class Parser {
EFor(v, it, mapCompr(tmp, e2));
case EWhile(cond, e2):
EWhile(cond, mapCompr(tmp, e2));
case EDoWhile(cond, e2):
EDoWhile(cond, mapCompr(tmp, e2));
case EIf(cond, e1, e2) if( e2 == null ):
EIf(cond, mapCompr(tmp, e1), null);
case EBlock([e]):
@@ -476,6 +482,16 @@ class Parser {
var econd = parseExpr();
var e = parseExpr();
mk(EWhile(econd,e),p1,pmax(e));
case "do":
var e = parseExpr();
var tk = token();
switch(tk)
{
case TId("while"): // Valid
default: unexpected(tk);
}
var econd = parseExpr();
mk(EDoWhile(econd,e),p1,pmax(econd));
case "for":
ensure(TPOpen);
var tk = token();
@@ -967,7 +983,7 @@ class Parser {
// in case of '...'
if( exp == 10 && readChar() == 46 ) {
push(TOp("..."));
var i = Std.int(n);
var i = Std.int(n) & 0xFFFFFFFF;
return TConst( (i == n) ? CInt(i) : CFloat(n) );
}
invalidChar(char);
@@ -990,7 +1006,7 @@ class Parser {
n = (n << 4) + (char - 87);
default:
this.char = char;
return TConst(CInt(n));
return TConst(CInt(n & 0xFFFFFFFF));
}
}
#else
@@ -1062,6 +1078,8 @@ class Parser {
char = readChar();
if( char == '='.code )
return TOp("==");
else if ( char == '>'.code )
return TOp("=>");
this.char = char;
return TOp("=");
default:
+6
View File
@@ -148,6 +148,12 @@ class Printer {
expr(cond);
add(" ) ");
expr(e);
case EDoWhile(cond,e):
add("do ");
expr(e);
add(" while ( ");
expr(cond);
add(" )");
case EFor(v, it, e):
add("for( "+v+" in ");
expr(it);
+2
View File
@@ -15,6 +15,7 @@ class Tools {
case ECall(e, args): f(e); for( a in args ) f(a);
case EIf(c, e1, e2): f(c); f(e1); if( e2 != null ) f(e2);
case EWhile(c, e): f(c); f(e);
case EDoWhile(c, e): f(c); f(e);
case EFor(_, it, e): f(it); f(e);
case EBreak,EContinue:
case EFunction(_, e, _, _): f(e);
@@ -48,6 +49,7 @@ class Tools {
case ECall(e, args): ECall(f(e),[for( a in args ) f(a)]);
case EIf(c, e1, e2): EIf(f(c),f(e1),if( e2 != null ) f(e2) else null);
case EWhile(c, e): EWhile(f(c),f(e));
case EDoWhile(c, e): EDoWhile(f(c),f(e));
case EFor(v, it, e): EFor(v, f(it), f(e));
case EBreak, EContinue: e;
case EFunction(args, e, name, t): EFunction(args, f(e), name, t);
+1
View File
@@ -15,4 +15,5 @@ haxe -xml release/haxedoc.xml hscript.Interp hscript.Parser hscript.Bytes hscrip
7z a -tzip release.zip release
rm -rf release
haxelib submit release.zip
echo Remember to "git tag vX.Y.Z && git push --tags"
pause