diff --git a/hscript/Expr.hx b/hscript/Expr.hx index b3309ce..13b01b7 100644 --- a/hscript/Expr.hx +++ b/hscript/Expr.hx @@ -60,7 +60,7 @@ enum Expr { EFunction( args : Array, e : Expr, ?name : String, ?ret : CType, ?isPublic : Bool, ?isStatic : Bool); EReturn( ?e : Expr ); EArray( e : Expr, index : Expr ); - EArrayDecl( e : Array ); + EArrayDecl( e : Array, ?wantedType: CType); ENew( cl : String, params : Array ); EThrow( e : Expr ); ETry( e : Expr, v : String, t : Null, ecatch : Expr ); diff --git a/hscript/Interp.hx b/hscript/Interp.hx index 5a27275..4a5d669 100644 --- a/hscript/Interp.hx +++ b/hscript/Interp.hx @@ -23,6 +23,8 @@ /* * YoshiCrafter Engine fixes: * - Added Error handler + * - Added Imports + * - Added @:bypassAccessor */ package hscript; @@ -69,6 +71,8 @@ class Interp { var declared:Array<{n:String, old:{r:Dynamic, depth:Int}, depth:Int}>; var returnValue:Dynamic; + var isBypassAccessor:Bool = false; + public var importEnabled:Bool = true; public var allowStaticVariables:Bool = false; @@ -355,7 +359,7 @@ class Interp { } catch(e:Error) { if (errorHandler != null) errorHandler(e); - else + else throw e; return null; } catch(e) { @@ -431,7 +435,6 @@ class Interp { } if (doException) error(EUnknownVariable(id)); - } return v; } @@ -449,7 +452,7 @@ class Interp { var realClassName = splitClassName.join("."); if (importBlocklist.contains(realClassName)) - return null; + return null; var cl = Type.resolveClass(realClassName); if (cl == null) cl = Type.resolveClass('${realClassName}_HSC'); @@ -464,7 +467,15 @@ class Interp { // ENUM!!!! var enumThingy = {}; for (c in en.getConstructors()) { - Reflect.setField(enumThingy, c, en.createByName(c)); + try { + Reflect.setField(enumThingy, c, en.createByName(c)); + } catch(e) { + try { + Reflect.setField(enumThingy, c, Reflect.field(en, c)); + } catch(ex) { + throw e; + } + } } variables.set(splitClassName[splitClassName.length - 1], enumThingy); } else { @@ -488,7 +499,8 @@ class Interp { case EVar(n, _, e, isPublic, isStatic): declared.push({n: n, old: locals.get(n), depth: depth}); locals.set(n, {r: (e == null) ? null : expr(e), depth: depth}); - if (depth == 0) (isStatic == true ? staticVariables : (isPublic ? publicVariables : variables)).set(n, locals[n].r); + if (depth == 0) + (isStatic == true ? staticVariables : (isPublic ? publicVariables : variables)).set(n, locals[n].r); return null; case EParent(e): return expr(e); @@ -634,8 +646,16 @@ class Interp { } } return f; - case EArrayDecl(arr): - if (arr.length > 0 && Tools.expr(arr[0]).match(EBinop("=>", _))) { + case EArrayDecl(arr, wantedType): + var isMap = false; + var isTypeMap = false; + if(!isMap && wantedType != null) { + isMap = wantedType.match(CTPath(["Map"], [_, _])); + isTypeMap = true; + } else { + isMap = arr.length > 0 && Tools.expr(arr[0]).match(EBinop("=>", _)); + } + if (isMap) { var isAllString:Bool = true; var isAllInt:Bool = true; var isAllObject:Bool = true; @@ -657,6 +677,22 @@ class Interp { default: throw("=> expected"); } } + + if(isTypeMap) { + if(wantedType != null) { + isAllString = wantedType.match(CTPath(["Map"], [CTPath(["String"], _), _])); + isAllInt = wantedType.match(CTPath(["Map"], [CTPath(["Int"], _), _])); + if(isAllString || isAllInt) { + isAllObject = false; + isAllEnum = false; + } else { + if(!isAllObject && !isAllEnum) { + throw("Unknown Type Key"); + } + } + } + } + var map:Dynamic = { if (isAllInt) new haxe.ds.IntMap(); @@ -742,8 +778,15 @@ class Interp { if (!match) val = def == null ? null : expr(def); return val; - case EMeta(_, _, e): - return expr(e); + case EMeta(a, b, e): + var oldAccessor = isBypassAccessor; + if(a == ":bypassAccessor") { + isBypassAccessor = true; + } + var val = expr(e); + + isBypassAccessor = oldAccessor; + return val; case ECheckType(e, _): return expr(e); } @@ -860,8 +903,15 @@ class Interp { return obj.hget(f); } else { var v = null; - if ((v = Reflect.getProperty(o, f)) == null) - v = Reflect.getProperty(Type.getClass(o), f); + if(isBypassAccessor) { + if ((v = Reflect.field(o, f)) == null) + v = Reflect.field(Type.getClass(o), f); + } + + if(v == null) { + if ((v = Reflect.getProperty(o, f)) == null) + v = Reflect.getProperty(Type.getClass(o), f); + } return v; } } @@ -889,9 +939,12 @@ class Interp { else if (o is IHScriptCustomBehaviour) { var obj = cast(o, IHScriptCustomBehaviour); return obj.hset(f, v); - } - - Reflect.setProperty(o, f, v); + } + if(isBypassAccessor) { + Reflect.setField(o, f, v); + } else { + Reflect.setProperty(o, f, v); + } return v; } diff --git a/hscript/Parser.hx b/hscript/Parser.hx index 4300c43..a2afa5a 100644 --- a/hscript/Parser.hx +++ b/hscript/Parser.hx @@ -275,19 +275,19 @@ class Parser { function isBlock(e) { if( e == null ) return false; return switch( expr(e) ) { - case EBlock(_), EObject(_), ESwitch(_): true; - case EFunction(_,e,_,_,_,_): isBlock(e); - case EVar(_, t, e, _,_): e != null ? isBlock(e) : t != null ? t.match(CTAnon(_)) : false; - case EIf(_,e1,e2): if( e2 != null ) isBlock(e2) else isBlock(e1); - 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); - case EMeta(_, _, e): isBlock(e); - default: false; + case EBlock(_), EObject(_), ESwitch(_): true; + case EFunction(_,e,_,_,_,_): isBlock(e); + case EVar(_, t, e, _,_): e != null ? isBlock(e) : t != null ? t.match(CTAnon(_)) : false; + case EIf(_,e1,e2): if( e2 != null ) isBlock(e2) else isBlock(e1); + 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); + case EMeta(_, _, e): isBlock(e); + default: false; } } @@ -318,29 +318,29 @@ class Parser { var tk = token(); var id = null; switch( tk ) { - case TId(i): id = i; - case TConst(c): - if( !allowJSON ) + case TId(i): id = i; + case TConst(c): + if( !allowJSON ) + unexpected(tk); + switch( c ) { + case CString(s): id = s; + default: unexpected(tk); + } + case TBrClose: + break; + default: unexpected(tk); - switch( c ) { - case CString(s): id = s; - default: unexpected(tk); - } - case TBrClose: - break; - default: - unexpected(tk); - break; + break; } ensure(TDoubleDot); fl.push({ name : id, e : parseExpr() }); tk = token(); switch( tk ) { - case TBrClose: - break; - case TComma: - default: - unexpected(tk); + case TBrClose: + break; + case TComma: + default: + unexpected(tk); } } return parseExprNext(mk(EObject(fl),p1)); @@ -372,27 +372,27 @@ class Parser { var e = parseExpr(); tk = token(); switch( tk ) { - case TPClose: - return parseExprNext(mk(EParent(e),p1,tokenMax)); - case TDoubleDot: - var t = parseType(); - tk = token(); - switch( tk ) { case TPClose: - return parseExprNext(mk(ECheckType(e,t),p1,tokenMax)); + return parseExprNext(mk(EParent(e),p1,tokenMax)); + case TDoubleDot: + var t = parseType(); + tk = token(); + switch( tk ) { + case TPClose: + return parseExprNext(mk(ECheckType(e,t),p1,tokenMax)); + case TComma: + switch( expr(e) ) { + case EIdent(v): return parseLambda([{ name : v, t : t }], pmin(e)); + default: + } + default: + } case TComma: switch( expr(e) ) { - case EIdent(v): return parseLambda([{ name : v, t : t }], pmin(e)); - default: + case EIdent(v): return parseLambda([{name:v}], pmin(e)); + default: } default: - } - case TComma: - switch( expr(e) ) { - case EIdent(v): return parseLambda([{name:v}], pmin(e)); - default: - } - default: } return unexpected(tk); case TBrOpen: @@ -417,9 +417,9 @@ class Parser { push(tk2); push(tk); switch( tk2 ) { - case TDoubleDot: - return parseExprNext(parseObject(p1)); - default: + case TDoubleDot: + return parseExprNext(parseObject(p1)); + default: } default: push(tk); @@ -445,12 +445,12 @@ class Parser { if( e == null ) return makeUnop(op,e); switch( expr(e) ) { - case EConst(CInt(i)): - return mk(EConst(CInt(-i)), start, pmax(e)); - case EConst(CFloat(f)): - return mk(EConst(CFloat(-f)), start, pmax(e)); - default: - return makeUnop(op,e); + case EConst(CInt(i)): + return mk(EConst(CInt(-i)), start, pmax(e)); + case EConst(CFloat(f)): + return mk(EConst(CFloat(-f)), start, pmax(e)); + default: + return makeUnop(op,e); } } if( opPriority.get(op) < 0 ) @@ -466,19 +466,19 @@ class Parser { if( tk == TComma ) tk = token(); } - if( a.length == 1 && a[0] != null ) + if( a.length == 1 && a[0] != null ) // What is this for??? switch( expr(a[0]) ) { - case EFor(_), EWhile(_), EDoWhile(_): - var tmp = "__a_" + (uid++); - var e = mk(EBlock([ - mk(EVar(tmp, null, mk(EArrayDecl([]), p1)), p1), - mapCompr(tmp, a[0]), - mk(EIdent(tmp),p1), - ]),p1); - return parseExprNext(e); - default: + case EFor(_), EWhile(_), EDoWhile(_): + var tmp = "__a_" + (uid++); + var e = mk(EBlock([ + mk(EVar(tmp, null, mk(EArrayDecl([]), p1)), p1), + mapCompr(tmp, a[0]), + mk(EIdent(tmp),p1), + ]),p1); + return parseExprNext(e); + default: } - return parseExprNext(mk(EArrayDecl(a), p1)); + return parseExprNext(mk(EArrayDecl(a, nextType), p1)); case TMeta(id) if( allowMetadata ): var args = parseMetaArgs(); return mk(EMeta(id, args, parseExpr()),p1); @@ -583,6 +583,7 @@ class Parser { var nextIsStatic:Bool = false; var nextIsPublic:Bool = false; + var nextType:CType = null; function parseStructure(id, ?oldPos:Int) { #if hscriptPos var p1 = tokenMin; @@ -653,15 +654,19 @@ class Parser { var ident = getIdent(); var tk = token(); var t = null; + nextType = null; if( tk == TDoubleDot && allowTypes ) { t = parseType(); tk = token(); + + nextType = t; } var e = null; if( Type.enumEq(tk,TOp("=")) ) e = parseExpr(); else push(tk); + nextType = null; mk(EVar(ident,t,e,nextIsPublic,nextIsStatic),p1,(e == null) ? tokenMax : pmax(e)); case "while": var econd = parseExpr(); diff --git a/hscript/Printer.hx b/hscript/Printer.hx index d9972d1..fe007d9 100644 --- a/hscript/Printer.hx +++ b/hscript/Printer.hx @@ -236,7 +236,7 @@ class Printer { add("["); expr(index); add("]"); - case EArrayDecl(el): + case EArrayDecl(el, _): add("["); var first = true; for( e in el ) { diff --git a/hscript/UsingHandler.hx b/hscript/UsingHandler.hx index dc2e08d..5d008a0 100644 --- a/hscript/UsingHandler.hx +++ b/hscript/UsingHandler.hx @@ -11,95 +11,95 @@ import haxe.macro.Compiler; using StringTools; class UsingHandler { - public var usedClass:Class; - public var className:String; + public var usedClass:Class; + public var className:String; - public function new(className:String, usedClass:Class) { - this.className = className; - this.usedClass = usedClass; - } + public function new(className:String, usedClass:Class) { + this.className = className; + this.usedClass = usedClass; + } - public static function init() { - Compiler.addGlobalMetadata('flixel', '@:build(hscript.UsingHandler.build())'); - Compiler.addGlobalMetadata('openfl.display.BlendMode', '@:build(hscript.UsingHandler.build())'); - } + public static function init() { + Compiler.addGlobalMetadata('flixel', '@:build(hscript.UsingHandler.build())'); + Compiler.addGlobalMetadata('openfl.display.BlendMode', '@:build(hscript.UsingHandler.build())'); + } - public static function build():Array { - var fields = Context.getBuildFields(); - var clRef = Context.getLocalClass(); - if (clRef == null) return fields; - var cl = clRef.get(); + public static function build():Array { + var fields = Context.getBuildFields(); + var clRef = Context.getLocalClass(); + if (clRef == null) return fields; + var cl = clRef.get(); - if (/* cl.name.startsWith("Flx") && */ cl.name.endsWith("_Impl_") && cl.params.length <= 0 && !cl.meta.has(":multiType")) { - var metas = cl.meta.get(); + if (/* cl.name.startsWith("Flx") && */ cl.name.endsWith("_Impl_") && cl.params.length <= 0 && !cl.meta.has(":multiType")) { + var metas = cl.meta.get(); - var shadowClass = macro class { - - }; - shadowClass.params = switch(cl.params.length) { - case 0: - null; - case 1: - [ - { - name: "T", - } - ]; - default: - [for(k=>e in cl.params) { - name: "T" + Std.int(k+1) - }]; - }; - shadowClass.name = '${cl.name.substr(0, cl.name.length - 6)}_HSC'; + var shadowClass = macro class { + + }; + shadowClass.params = switch(cl.params.length) { + case 0: + null; + case 1: + [ + { + name: "T", + } + ]; + default: + [for(k=>e in cl.params) { + name: "T" + Std.int(k+1) + }]; + }; + shadowClass.name = '${cl.name.substr(0, cl.name.length - 6)}_HSC'; - for(f in fields) - switch(f.kind) { - case FFun(fun): - if (f.access.contains(AStatic)) { - if (fun.expr != null) - shadowClass.fields.push(f); - } - case FProp(get, set, t, e): - if (get == "default" && (set == "never" || set == "null")) - shadowClass.fields.push(f); - case FVar(t, e): - if (f.access.contains(AStatic) || cl.meta.has(":enum") || f.name.toUpperCase() == f.name) { - var name:String = f.name; - var enumType:String = cl.name; - var pack = cl.module.split("."); - pack.pop(); - var complexType:ComplexType = t != null ? t : (name.contains("REGEX") ? TPath({ - name: "EReg", - pack: [] - }) : TPath({ - name: cl.name.substr(0, cl.name.length - 6), - pack: pack})); - var field:Field = { - pos: f.pos, - name: f.name, - meta: f.meta, - kind: FVar(complexType, { - pos: Context.currentPos(), - expr: ECast(e, complexType) - }), - doc: f.doc, - access: [APublic, AStatic] - } - - shadowClass.fields.push(field); - } - default: - } + for(f in fields) + switch(f.kind) { + case FFun(fun): + if (f.access.contains(AStatic)) { + if (fun.expr != null) + shadowClass.fields.push(f); + } + case FProp(get, set, t, e): + if (get == "default" && (set == "never" || set == "null")) + shadowClass.fields.push(f); + case FVar(t, e): + if (f.access.contains(AStatic) || cl.meta.has(":enum") || f.name.toUpperCase() == f.name) { + var name:String = f.name; + var enumType:String = cl.name; + var pack = cl.module.split("."); + pack.pop(); + var complexType:ComplexType = t != null ? t : (name.contains("REGEX") ? TPath({ + name: "EReg", + pack: [] + }) : TPath({ + name: cl.name.substr(0, cl.name.length - 6), + pack: pack})); + var field:Field = { + pos: f.pos, + name: f.name, + meta: f.meta, + kind: FVar(complexType, { + pos: Context.currentPos(), + expr: ECast(e, complexType) + }), + doc: f.doc, + access: [APublic, AStatic] + } + + shadowClass.fields.push(field); + } + default: + } - Context.defineModule(cl.module, [shadowClass], Context.getLocalImports()); - } + Context.defineModule(cl.module, [shadowClass], Context.getLocalImports()); + } - return fields; - } + return fields; + } } #else class UsingHandler { - public var usedClass:Class; - public var className:String; + public var usedClass:Class; + public var className:String; } #end \ No newline at end of file