Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
09923651d8 | ||
|
|
7ca5b85051 | ||
|
|
a34faf8a26 | ||
|
|
7708159e92 | ||
|
|
7851d48e82 | ||
|
|
f320b4fa9b | ||
|
|
b3ea81f4e8 |
+5
-9
@@ -4,10 +4,12 @@ os:
|
||||
- linux
|
||||
- osx
|
||||
|
||||
osx_image: xcode6.4
|
||||
sudo: false
|
||||
dist: trusty
|
||||
|
||||
haxe:
|
||||
- "3.2.1"
|
||||
- "3.4.2"
|
||||
- development
|
||||
|
||||
addons:
|
||||
@@ -24,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
|
||||
|
||||
@@ -21,8 +21,15 @@ class Test extends TestCase {
|
||||
function test():Void {
|
||||
assertScript("0",0);
|
||||
assertScript("0xFF", 255);
|
||||
assertScript("0xBFFFFFFF", 0xBFFFFFFF);
|
||||
assertScript("0x7FFFFFFF", 0x7FFFFFFF);
|
||||
#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("-123",-123);
|
||||
assertScript("- 123",-123);
|
||||
assertScript("1.546",1.546);
|
||||
|
||||
+4
-2
@@ -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
|
||||
@@ -35,5 +37,5 @@ test_script:
|
||||
- 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-php.hxml && php bin\index.php
|
||||
- haxe bin/build-python.hxml && C:\Python34-x64\python.exe bin\Test.py
|
||||
+7
-4
@@ -7,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/21/flashplayer_21_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/21/flashplayer_21_sa_debug.exe";
|
||||
"http://fpdownload.macromedia.com/pub/flashplayer/updaters/25/flashplayer_25_sa_debug.exe";
|
||||
case _:
|
||||
throw "unsupported system";
|
||||
}
|
||||
@@ -46,6 +46,9 @@ class Install {
|
||||
if (command("tar", ["-xf", Path.withoutDirectory(fpDownload), "-C", "flash"]) != 0)
|
||||
throw "failed to extract flash player";
|
||||
case "Mac":
|
||||
// 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)
|
||||
@@ -84,7 +87,7 @@ class Install {
|
||||
if (command("sudo", ["chmod", "a+rw", dir]) != 0)
|
||||
throw 'cannot set permission of $dir';
|
||||
case _:
|
||||
neko.Lib.rethrow(e);
|
||||
throw 'cannot create $dir: $e';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+4
-3
@@ -21,12 +21,13 @@ 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":
|
||||
|
||||
+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"]
|
||||
}
|
||||
+5
-2
@@ -70,14 +70,17 @@ enum 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 );
|
||||
}
|
||||
|
||||
@@ -99,7 +102,7 @@ class Error {
|
||||
private function errorDefToString(): String {
|
||||
switch (e) {
|
||||
case EInvalidChar(c):
|
||||
return "Invalid character: '"+c+"'";
|
||||
return "Invalid character: '"+String.fromCharCode(c)+"' ("+c+")";
|
||||
|
||||
case EUnexpected(s):
|
||||
return "Unexpected token: \""+s+"\"";
|
||||
|
||||
+5
-3
@@ -137,7 +137,7 @@ class Interp {
|
||||
else {
|
||||
arr[index] = v;
|
||||
}
|
||||
|
||||
|
||||
default:
|
||||
error(EInvalidOp("="));
|
||||
}
|
||||
@@ -560,6 +560,8 @@ class Interp {
|
||||
if( !match )
|
||||
val = def == null ? null : expr(def);
|
||||
return val;
|
||||
case EMeta(_, _, e):
|
||||
return expr(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -629,7 +631,7 @@ class Interp {
|
||||
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);
|
||||
}
|
||||
@@ -637,7 +639,7 @@ class Interp {
|
||||
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));
|
||||
return {
|
||||
|
||||
@@ -231,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 }
|
||||
}
|
||||
|
||||
|
||||
+81
-46
@@ -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;
|
||||
@@ -200,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;
|
||||
@@ -384,12 +400,39 @@ 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):
|
||||
@@ -460,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();
|
||||
@@ -494,13 +532,8 @@ class Parser {
|
||||
mk(EDoWhile(econd,e),p1,pmax(econd));
|
||||
case "for":
|
||||
ensure(TPOpen);
|
||||
var vname = getIdent();
|
||||
var tk = token();
|
||||
var vname = null;
|
||||
switch( tk ) {
|
||||
case TId(id): vname = id;
|
||||
default: unexpected(tk);
|
||||
}
|
||||
tk = token();
|
||||
if( !Type.enumEq(tk,TId("in")) ) unexpected(tk);
|
||||
var eiter = parseExpr();
|
||||
ensure(TPClose);
|
||||
@@ -568,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:
|
||||
@@ -599,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 )
|
||||
@@ -700,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)));
|
||||
@@ -733,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 ) {
|
||||
@@ -758,7 +768,7 @@ class Parser {
|
||||
tokens.add({ t : TOp(op.substr(1)), min : tokenMax - op.length - 1, max : tokenMax });
|
||||
#else
|
||||
tokens.add(TOp(op.substr(1)));
|
||||
#end
|
||||
#end
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -777,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);
|
||||
}
|
||||
@@ -983,7 +1003,7 @@ class Parser {
|
||||
// in case of '...'
|
||||
if( exp == 10 && readChar() == 46 ) {
|
||||
push(TOp("..."));
|
||||
var i = Std.int(n) & 0xFFFFFFFF;
|
||||
var i = Std.int(n);
|
||||
return TConst( (i == n) ? CInt(i) : CFloat(n) );
|
||||
}
|
||||
invalidChar(char);
|
||||
@@ -1006,7 +1026,7 @@ class Parser {
|
||||
n = (n << 4) + (char - 87);
|
||||
default:
|
||||
this.char = char;
|
||||
return TConst(CInt(n & 0xFFFFFFFF));
|
||||
return TConst(CInt(n));
|
||||
}
|
||||
}
|
||||
#else
|
||||
@@ -1082,6 +1102,20 @@ class Parser {
|
||||
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);
|
||||
@@ -1186,6 +1220,7 @@ class Parser {
|
||||
case TBkClose: "]";
|
||||
case TQuestion: "?";
|
||||
case TDoubleDot: ":";
|
||||
case TMeta(id): "@" + id;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user