Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
09923651d8 | ||
|
|
7ca5b85051 | ||
|
|
a34faf8a26 | ||
|
|
7708159e92 | ||
|
|
7851d48e82 | ||
|
|
f320b4fa9b | ||
|
|
b3ea81f4e8 | ||
|
|
ace61e589d | ||
|
|
51506e0400 | ||
|
|
4a1432b01d | ||
|
|
aa16393c1b | ||
|
|
55ed2c0d5c | ||
|
|
6c588733d9 | ||
|
|
d72411632d | ||
|
|
a1af1ec29e | ||
|
|
bdd55483f9 |
+15
-17
@@ -4,8 +4,12 @@ os:
|
||||
- linux
|
||||
- osx
|
||||
|
||||
sudo: false
|
||||
dist: trusty
|
||||
|
||||
haxe:
|
||||
- "3.2.1"
|
||||
- "3.4.2"
|
||||
- development
|
||||
|
||||
addons:
|
||||
@@ -22,14 +26,8 @@ addons:
|
||||
- mono-devel
|
||||
- mono-mcs
|
||||
# Flash
|
||||
- libcurl3:i386
|
||||
- libglib2.0-0:i386
|
||||
- libx11-6:i386
|
||||
- libxext6:i386
|
||||
- libxt6:i386
|
||||
- libxcursor1:i386
|
||||
- libnss3:i386
|
||||
- libgtk2.0-0:i386
|
||||
- libglib2.0
|
||||
- libfreetype6
|
||||
|
||||
install:
|
||||
# os-specific config
|
||||
@@ -62,12 +60,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
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import haxe.ds.EnumValueMap;
|
||||
import haxe.ds.Option;
|
||||
import hscript.Macro;
|
||||
import haxe.unit.*;
|
||||
|
||||
@@ -73,6 +75,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);
|
||||
@@ -95,6 +98,56 @@ class Test extends TestCase {
|
||||
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();
|
||||
runner.add(new Test());
|
||||
|
||||
+12
-10
@@ -6,13 +6,15 @@ environment:
|
||||
|
||||
install:
|
||||
# Install the haxe chocolatey package (https://chocolatey.org/packages/haxe)
|
||||
- cinst haxe -version 3.2.1 -y
|
||||
- cinst haxe -version 3.4.2 -y
|
||||
- RefreshEnv
|
||||
# Setup haxelib
|
||||
- mkdir "%HAXELIB_ROOT%"
|
||||
- haxelib setup "%HAXELIB_ROOT%"
|
||||
# Install test dependencies
|
||||
- ps: Set-Service wuauserv -StartupType Manual
|
||||
- cinst php -y
|
||||
- RefreshEnv
|
||||
# Download and setup a standalone flash player debugger
|
||||
- haxe flash/install.hxml
|
||||
# Install project dependencies
|
||||
@@ -28,12 +30,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 && php bin\index.php
|
||||
- haxe bin/build-python.hxml && C:\Python34-x64\python.exe bin\Test.py
|
||||
@@ -0,0 +1,2 @@
|
||||
bin/build-each.hxml
|
||||
-cpp bin
|
||||
@@ -0,0 +1,2 @@
|
||||
bin/build-each.hxml
|
||||
-cs bin
|
||||
@@ -1,4 +1,4 @@
|
||||
build-each.hxml
|
||||
bin/build-each.hxml
|
||||
-swf bin/Test.swf
|
||||
-swf-header 800:600:30:FFFFFF
|
||||
--flash-strict
|
||||
@@ -0,0 +1,2 @@
|
||||
bin/build-each.hxml
|
||||
--interp
|
||||
@@ -0,0 +1,2 @@
|
||||
bin/build-each.hxml
|
||||
-java bin
|
||||
@@ -0,0 +1,2 @@
|
||||
bin/build-each.hxml
|
||||
-js bin/Test.js
|
||||
@@ -0,0 +1,2 @@
|
||||
bin/build-each.hxml
|
||||
-neko bin/Test.n
|
||||
@@ -0,0 +1,2 @@
|
||||
bin/build-each.hxml
|
||||
-php bin
|
||||
@@ -0,0 +1,2 @@
|
||||
bin/build-each.hxml
|
||||
-python bin/Test.py
|
||||
@@ -1,2 +0,0 @@
|
||||
build-each.hxml
|
||||
-cpp bin
|
||||
@@ -1,2 +0,0 @@
|
||||
build-each.hxml
|
||||
-cs bin
|
||||
@@ -1,2 +0,0 @@
|
||||
build-each.hxml
|
||||
--interp
|
||||
@@ -1,2 +0,0 @@
|
||||
build-each.hxml
|
||||
-java bin
|
||||
@@ -1,2 +0,0 @@
|
||||
build-each.hxml
|
||||
-js bin/Test.js
|
||||
@@ -1,2 +0,0 @@
|
||||
build-each.hxml
|
||||
-neko bin/Test.n
|
||||
@@ -1,2 +0,0 @@
|
||||
build-each.hxml
|
||||
-php bin
|
||||
@@ -1,2 +0,0 @@
|
||||
build-each.hxml
|
||||
-python bin/Test.py
|
||||
+24
-7
@@ -1,5 +1,4 @@
|
||||
import Sys.*;
|
||||
import sys.FileSystem.*;
|
||||
import sys.io.File.*;
|
||||
import haxe.*;
|
||||
import haxe.io.*;
|
||||
@@ -8,11 +7,11 @@ class Install {
|
||||
// https://www.adobe.com/support/flashplayer/downloads.html
|
||||
static var fpDownload(default, never) = switch (systemName()) {
|
||||
case "Linux":
|
||||
"https://fpdownload.macromedia.com/pub/flashplayer/updaters/11/flashplayer_11_sa_debug.i386.tar.gz";
|
||||
"http://fpdownload.macromedia.com/pub/flashplayer/updaters/25/flash_player_sa_linux_debug.x86_64.tar.gz";
|
||||
case "Mac":
|
||||
"https://fpdownload.macromedia.com/pub/flashplayer/updaters/19/flashplayer_19_sa_debug.dmg";
|
||||
"http://fpdownload.macromedia.com/pub/flashplayer/updaters/25/flashplayer_25_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/25/flashplayer_25_sa_debug.exe";
|
||||
case _:
|
||||
throw "unsupported system";
|
||||
}
|
||||
@@ -47,9 +46,12 @@ 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)
|
||||
// https://github.com/caskroom/homebrew-cask/pull/15381
|
||||
if (command("brew", ["uninstall", "--force", "brew-cask"]) != 0)
|
||||
throw "failed to brew uninstall --force brew-cask";
|
||||
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 +76,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 _:
|
||||
throw 'cannot create $dir: $e';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+16
-4
@@ -21,22 +21,34 @@ class Run {
|
||||
var exitCode = switch (systemName()) {
|
||||
case "Linux":
|
||||
// The flash player has some issues with unexplained crashes,
|
||||
// but if it runs about 8 times, it should succeed one of those...
|
||||
// but if it runs about 16 times, it should succeed one of those...
|
||||
var c = -1;
|
||||
for (i in 0...8) {
|
||||
if ((c = command("xvfb-run", ["flash/flashplayerdebugger", swf])) == 0)
|
||||
for (i in 0...16) {
|
||||
if ((c = command("xvfb-run", ["-a", "flash/flashplayerdebugger", swf])) == 0)
|
||||
break;
|
||||
println('retry... (${i+1})');
|
||||
sleep(1.5);
|
||||
}
|
||||
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";
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -3,7 +3,7 @@
|
||||
"url": "https://github.com/HaxeFoundation/hscript",
|
||||
"license": "MIT",
|
||||
"description": "Haxe Script is a scripting engine for a subset of the Haxe language",
|
||||
"version": "2.0.7",
|
||||
"releasenote": "fixes for haxe 3.3, use property access by default",
|
||||
"version": "2.1.0",
|
||||
"releasenote": "added metadata support",
|
||||
"contributors": ["ncannasse"]
|
||||
}
|
||||
+1
-1
@@ -1 +1 @@
|
||||
build-flash.hxml
|
||||
bin/build-flash.hxml
|
||||
+26
-7
@@ -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:
|
||||
|
||||
+46
-2
@@ -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,14 +69,18 @@ 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);
|
||||
EMeta( name : String, args : Array<Expr>, e : Expr );
|
||||
}
|
||||
|
||||
typedef Argument = { name : String, ?t : CType, ?opt : Bool };
|
||||
|
||||
typedef Metadata = Array<{ name : String, params : Array<Expr> }>;
|
||||
|
||||
enum CType {
|
||||
CTPath( path : Array<String>, ?params : Array<CType> );
|
||||
CTFun( args : Array<CType>, ret : CType );
|
||||
CTAnon( fields : Array<{ name : String, t : CType }> );
|
||||
CTAnon( fields : Array<{ name : String, t : CType, ?meta : Metadata }> );
|
||||
CTParent( t : CType );
|
||||
}
|
||||
|
||||
@@ -83,10 +89,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: '"+String.fromCharCode(c)+"' ("+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 {
|
||||
|
||||
+134
-18
@@ -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);
|
||||
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,9 +204,21 @@ class Interp {
|
||||
} else
|
||||
set(obj,f,v + delta);
|
||||
return v;
|
||||
case EArray(e,index):
|
||||
var arr = expr(e);
|
||||
var index = expr(index);
|
||||
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;
|
||||
@@ -191,6 +226,7 @@ class Interp {
|
||||
} 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):
|
||||
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 )
|
||||
for ( e in arr ) {
|
||||
a.push(expr(e));
|
||||
}
|
||||
return a;
|
||||
case EArray(e,index):
|
||||
return expr(e)[expr(index)];
|
||||
}
|
||||
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 )
|
||||
@@ -477,10 +560,29 @@ class Interp {
|
||||
if( !match )
|
||||
val = def == null ? null : expr(def);
|
||||
return val;
|
||||
case EMeta(_, _, e):
|
||||
return expr(e);
|
||||
}
|
||||
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 +600,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,19 +628,33 @@ 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 ( o == null ) error(EInvalidAccess(f));
|
||||
return {
|
||||
#if php
|
||||
// https://github.com/HaxeFoundation/haxe/issues/4915
|
||||
return try {
|
||||
try {
|
||||
Reflect.getProperty(o, f);
|
||||
} catch (e:Dynamic) {
|
||||
Reflect.field(o, f);
|
||||
}
|
||||
#else
|
||||
return Reflect.getProperty(o, f);
|
||||
Reflect.getProperty(o, f);
|
||||
#end
|
||||
}
|
||||
}
|
||||
|
||||
function set( o : Dynamic, f : String, v : Dynamic ) : Dynamic {
|
||||
if( o == null ) error(EInvalidAccess(f));
|
||||
|
||||
@@ -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;
|
||||
@@ -229,6 +231,9 @@ class Macro {
|
||||
ETernary(convert(cond), convert(e1), convert(e2));
|
||||
case ESwitch(e, cases, edef):
|
||||
ESwitch(convert(e), [for( c in cases ) { values : [for( v in c.values ) convert(v)], expr : convert(c.expr) } ], edef == null ? null : convert(edef));
|
||||
case EMeta(m, params, esub):
|
||||
var mpos = #if hscriptPos { file : p.file, min : e.pmin, max : e.pmax } #else p #end;
|
||||
EMeta({ name : m, params : params == null ? [] : [for( p in params ) convert(p)], pos : mpos }, convert(esub));
|
||||
}, pos : #if hscriptPos { file : p.file, min : e.pmin, max : e.pmax } #else p #end }
|
||||
}
|
||||
|
||||
|
||||
+104
-51
@@ -41,6 +41,7 @@ enum Token {
|
||||
TBkClose;
|
||||
TQuestion;
|
||||
TDoubleDot;
|
||||
TMeta( s : String );
|
||||
}
|
||||
|
||||
class Parser {
|
||||
@@ -69,6 +70,11 @@ class Parser {
|
||||
**/
|
||||
public var allowTypes : Bool;
|
||||
|
||||
/**
|
||||
allow haxe metadata declarations
|
||||
**/
|
||||
public var allowMetadata : Bool;
|
||||
|
||||
// implementation
|
||||
var input : haxe.io.Input;
|
||||
var char : Int;
|
||||
@@ -77,6 +83,7 @@ class Parser {
|
||||
var uid : Int = 0;
|
||||
|
||||
#if hscriptPos
|
||||
var origin : String;
|
||||
var readPos : Int;
|
||||
var tokenMin : Int;
|
||||
var tokenMax : Int;
|
||||
@@ -111,7 +118,7 @@ class Parser {
|
||||
["..."],
|
||||
["&&"],
|
||||
["||"],
|
||||
["=","+=","-=","*=","/=","%=","<<=",">>=",">>>=","|=","&=","^="],
|
||||
["=","+=","-=","*=","/=","%=","<<=",">>=",">>>=","|=","&=","^=","=>"],
|
||||
];
|
||||
#if haxe3
|
||||
opPriority = new Map();
|
||||
@@ -133,7 +140,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 +150,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;
|
||||
@@ -198,6 +206,16 @@ class Parser {
|
||||
if( t != tk ) unexpected(t);
|
||||
}
|
||||
|
||||
function getIdent() {
|
||||
var tk = token();
|
||||
switch( tk ) {
|
||||
case TId(id): return id;
|
||||
default:
|
||||
unexpected(tk);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
inline function expr(e:Expr) {
|
||||
#if hscriptPos
|
||||
return e.e;
|
||||
@@ -224,9 +242,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 +260,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 +390,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),
|
||||
@@ -380,18 +400,47 @@ class Parser {
|
||||
return parseExprNext(e);
|
||||
default:
|
||||
}
|
||||
return parseExprNext(mk(EArrayDecl(a),p1));
|
||||
return parseExprNext(mk(EArrayDecl(a), p1));
|
||||
case TMeta(id) if( allowMetadata ):
|
||||
var args = parseMetaArgs();
|
||||
return mk(EMeta(id, args, parseExpr()),p1);
|
||||
default:
|
||||
return unexpected(tk);
|
||||
}
|
||||
}
|
||||
|
||||
function parseMetaArgs() {
|
||||
var tk = token();
|
||||
if( tk != TPOpen ) {
|
||||
push(tk);
|
||||
return null;
|
||||
}
|
||||
var args = [];
|
||||
tk = token();
|
||||
if( tk != TPClose ) {
|
||||
push(tk);
|
||||
while( true ) {
|
||||
args.push(parseExpr());
|
||||
switch( token() ) {
|
||||
case TComma:
|
||||
case TPClose:
|
||||
break;
|
||||
case tk:
|
||||
unexpected(tk);
|
||||
}
|
||||
}
|
||||
}
|
||||
return args;
|
||||
}
|
||||
|
||||
function mapCompr( tmp : String, e : Expr ) {
|
||||
var edef = switch( expr(e) ) {
|
||||
case EFor(v, it, e2):
|
||||
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]):
|
||||
@@ -454,13 +503,8 @@ class Parser {
|
||||
}
|
||||
mk(EIf(cond,e1,e2),p1,(e2 == null) ? tokenMax : pmax(e2));
|
||||
case "var":
|
||||
var ident = getIdent();
|
||||
var tk = token();
|
||||
var ident = null;
|
||||
switch(tk) {
|
||||
case TId(id): ident = id;
|
||||
default: unexpected(tk);
|
||||
}
|
||||
tk = token();
|
||||
var t = null;
|
||||
if( tk == TDoubleDot && allowTypes ) {
|
||||
t = parseType();
|
||||
@@ -476,15 +520,20 @@ class Parser {
|
||||
var econd = parseExpr();
|
||||
var e = parseExpr();
|
||||
mk(EWhile(econd,e),p1,pmax(e));
|
||||
case "for":
|
||||
ensure(TPOpen);
|
||||
case "do":
|
||||
var e = parseExpr();
|
||||
var tk = token();
|
||||
var vname = null;
|
||||
switch( tk ) {
|
||||
case TId(id): vname = id;
|
||||
switch(tk)
|
||||
{
|
||||
case TId("while"): // Valid
|
||||
default: unexpected(tk);
|
||||
}
|
||||
tk = token();
|
||||
var econd = parseExpr();
|
||||
mk(EDoWhile(econd,e),p1,pmax(econd));
|
||||
case "for":
|
||||
ensure(TPOpen);
|
||||
var vname = getIdent();
|
||||
var tk = token();
|
||||
if( !Type.enumEq(tk,TId("in")) ) unexpected(tk);
|
||||
var eiter = parseExpr();
|
||||
ensure(TPClose);
|
||||
@@ -552,21 +601,13 @@ class Parser {
|
||||
mk(EReturn(e),p1,if( e == null ) tokenMax else pmax(e));
|
||||
case "new":
|
||||
var a = new Array();
|
||||
var tk = token();
|
||||
switch( tk ) {
|
||||
case TId(id): a.push(id);
|
||||
default: unexpected(tk);
|
||||
}
|
||||
a.push(getIdent());
|
||||
var next = true;
|
||||
while( next ) {
|
||||
tk = token();
|
||||
var tk = token();
|
||||
switch( tk ) {
|
||||
case TDot:
|
||||
tk = token();
|
||||
switch(tk) {
|
||||
case TId(id): a.push(id);
|
||||
default: unexpected(tk);
|
||||
}
|
||||
a.push(getIdent());
|
||||
case TPOpen:
|
||||
next = false;
|
||||
default:
|
||||
@@ -583,11 +624,7 @@ class Parser {
|
||||
var tk = token();
|
||||
if( !Type.enumEq(tk, TId("catch")) ) unexpected(tk);
|
||||
ensure(TPOpen);
|
||||
tk = token();
|
||||
var vname = switch( tk ) {
|
||||
case TId(id): id;
|
||||
default: unexpected(tk);
|
||||
}
|
||||
var vname = getIdent();
|
||||
ensure(TDoubleDot);
|
||||
var t = null;
|
||||
if( allowTypes )
|
||||
@@ -684,12 +721,7 @@ class Parser {
|
||||
}
|
||||
return makeBinop(op,e1,parseExpr());
|
||||
case TDot:
|
||||
tk = token();
|
||||
var field = null;
|
||||
switch(tk) {
|
||||
case TId(id): field = id;
|
||||
default: unexpected(tk);
|
||||
}
|
||||
var field = getIdent();
|
||||
return parseExprNext(mk(EField(e1,field),pmin(e1)));
|
||||
case TPOpen:
|
||||
return parseExprNext(mk(ECall(e1,parseExprList(TPClose)),pmin(e1)));
|
||||
@@ -717,13 +749,7 @@ class Parser {
|
||||
t = token();
|
||||
if( t != TDot )
|
||||
break;
|
||||
t = token();
|
||||
switch( t ) {
|
||||
case TId(v):
|
||||
path.push(v);
|
||||
default:
|
||||
unexpected(t);
|
||||
}
|
||||
path.push(getIdent());
|
||||
}
|
||||
var params = null;
|
||||
switch( t ) {
|
||||
@@ -761,19 +787,29 @@ class Parser {
|
||||
return parseTypeNext(CTParent(t));
|
||||
case TBrOpen:
|
||||
var fields = [];
|
||||
var meta = null;
|
||||
while( true ) {
|
||||
t = token();
|
||||
switch( t ) {
|
||||
case TBrClose: break;
|
||||
case TId("var"):
|
||||
var name = getIdent();
|
||||
ensure(TDoubleDot);
|
||||
fields.push( { name : name, t : parseType(), meta : meta } );
|
||||
meta = null;
|
||||
ensure(TSemicolon);
|
||||
case TId(name):
|
||||
ensure(TDoubleDot);
|
||||
fields.push( { name : name, t : parseType() } );
|
||||
fields.push( { name : name, t : parseType(), meta : meta } );
|
||||
t = token();
|
||||
switch( t ) {
|
||||
case TComma:
|
||||
case TBrClose: break;
|
||||
default: unexpected(t);
|
||||
}
|
||||
case TMeta(name):
|
||||
if( meta == null ) meta = [];
|
||||
meta.push({ name : name, params : parseMetaArgs() });
|
||||
default:
|
||||
unexpected(t);
|
||||
}
|
||||
@@ -1062,8 +1098,24 @@ class Parser {
|
||||
char = readChar();
|
||||
if( char == '='.code )
|
||||
return TOp("==");
|
||||
else if ( char == '>'.code )
|
||||
return TOp("=>");
|
||||
this.char = char;
|
||||
return TOp("=");
|
||||
case '@'.code:
|
||||
char = readChar();
|
||||
if( idents[char] || char == ':'.code ) {
|
||||
var id = String.fromCharCode(char);
|
||||
while( true ) {
|
||||
char = readChar();
|
||||
if( !idents[char] ) {
|
||||
this.char = char;
|
||||
return TMeta(id);
|
||||
}
|
||||
id += String.fromCharCode(char);
|
||||
}
|
||||
}
|
||||
invalidChar(char);
|
||||
default:
|
||||
if( ops[char] ) {
|
||||
var op = String.fromCharCode(char);
|
||||
@@ -1168,6 +1220,7 @@ class Parser {
|
||||
case TBkClose: "]";
|
||||
case TQuestion: "?";
|
||||
case TDoubleDot: ":";
|
||||
case TMeta(id): "@" + id;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user