diff --git a/hscript/CustomClass.hx b/hscript/CustomClass.hx new file mode 100644 index 0000000..dd31206 --- /dev/null +++ b/hscript/CustomClass.hx @@ -0,0 +1,52 @@ +package hscript; + +using Lambda; + +// TODO +/** + * The Custom Class core. + * + * Provides handlers for custom classes. + * + * @author Jamextreme140 + */ +@:access(hscript.CustomClassHandler) +class CustomClass /*implements IHScriptCustomClassBehaviour*/{ + + public var className(get, never):String; + private function get_className():String + return __class.name; + + var interp:Interp; + var __class:CustomClassHandler; + var fields:Array; + + public function new(__class:CustomClassHandler) { + this.__class = __class; + + interp = new Interp(); + interp.errorHandler = __class.staticInterp.errorHandler; + interp.scriptObject = this; + + fields = []; + /* + for(e in __class.fields) { + switch (Tools.expr(e)) { + case EVar(n, _, e, _, isStatic, _, isFinal, _, get, set, isVar): + if(!isStatic) + fields.push(e); + case EFunction(args, e, name, ret, _, isStatic, _, _, isFinal, _): + if(!isStatic) + fields.push(e); + default: + } + } + */ + for(f in fields) + @:privateAccess interp.exprReturn(f); + + } + + public function toString():String + return className; +} \ No newline at end of file diff --git a/hscript/CustomClassHandler.hx b/hscript/CustomClassHandler.hx index ee2e593..b42cfda 100644 --- a/hscript/CustomClassHandler.hx +++ b/hscript/CustomClassHandler.hx @@ -5,6 +5,9 @@ import hscript.utils.UnsafeReflect; using StringTools; // BIG TODO: revamp this +/** + * Provides handlers for static custom class fields and instantiation. + */ class CustomClassHandler implements IHScriptCustomConstructor { public static var staticHandler = new StaticHandler(); @@ -16,6 +19,8 @@ class CustomClassHandler implements IHScriptCustomConstructor { public var cl:Class; + private var staticInterp:Interp; + public function new(ogInterp:Interp, name:String, fields:Array, ?extend:String, ?interfaces:Array) { this.ogInterp = ogInterp; this.name = name; @@ -26,6 +31,9 @@ class CustomClassHandler implements IHScriptCustomConstructor { this.cl = extend == null ? CustomTemplateClass : Type.resolveClass('${extend}_HSX'); if(cl == null) ogInterp.error(EInvalidClass(extend)); + + staticInterp = new Interp(); + staticInterp.errorHandler = ogInterp.errorHandler; } public function hnew(args:Array):Dynamic { diff --git a/hscript/Interp.hx b/hscript/Interp.hx index db72627..822652e 100644 --- a/hscript/Interp.hx +++ b/hscript/Interp.hx @@ -67,9 +67,15 @@ class RedeclaredVar { @:analyzer(optimize, local_dce, fusion, user_var_fusion) class Interp { - public var scriptObject(default, set):Dynamic; - private var _hasScriptObject(default, null):Bool = false; + private var hasScriptObject(get, never):Bool; + private function get_hasScriptObject():Bool + return scriptObject != null; + private var _scriptObjectType(default, null):ScriptObjectType = SNull; + + var __instanceFields:Array = []; + + public var scriptObject(default, set):Dynamic; public function set_scriptObject(v:Dynamic) { switch(Type.typeof(v)) { case TClass(c): // Class Access @@ -101,13 +107,17 @@ class Interp { __instanceFields = []; _scriptObjectType = SNull; } - _hasScriptObject = v != null; return scriptObject = v; } + + var inCustomClass(get, never):Bool; + private function get_inCustomClass():Bool + return hasScriptObject && _scriptObjectType == SCustomClass; + public var errorHandler:Error->Void; public var importFailedCallback:Array->Bool; - public var customClasses:Map; + public var customClasses:Map; // make this static ??? public var variables:Map; public var publicVariables:Map; public var staticVariables:Map; @@ -128,11 +138,11 @@ class Interp { public var allowStaticVariables:Bool = false; public var allowPublicVariables:Bool = false; + // TODO: move this to an external class public var importBlocklist:Array = [ // "flixel.FlxG" ]; - var __instanceFields:Array = []; #if hscriptPos var curExpr:Expr; #end @@ -149,6 +159,7 @@ class Interp { variables = new Map(); publicVariables = new Map(); staticVariables = new Map(); + variables.set("null", null); variables.set("true", true); variables.set("false", false); @@ -246,7 +257,7 @@ class Interp { case EIdent(id): var l = locals.get(id); if (l == null) { - if (_hasScriptObject && !varExists(id)) { + if (hasScriptObject && !varExists(id)) { var instanceHasField = __instanceFields.contains(id); if (_scriptObjectType == SObject && instanceHasField) { @@ -329,7 +340,7 @@ class Interp { var l = locals.get(id); v = fop(expr(e1), expr(e2)); if (l == null) { - if(_hasScriptObject && !varExists(id)) { + if(hasScriptObject && !varExists(id)) { var instanceHasField = __instanceFields.contains(id); if (_scriptObjectType == SObject && instanceHasField) { @@ -610,7 +621,7 @@ class Interp { if(customClasses.exists(id)) return customClasses.get(id); - if (_hasScriptObject) { + if (hasScriptObject) { // search in object if (id == "this") { return scriptObject; @@ -1316,7 +1327,7 @@ class Interp { } function fcall(o:Dynamic, f:String, args:Array):Dynamic { - if(_hasScriptObject && o == CustomClassHandler.staticHandler) { + if(hasScriptObject && o == CustomClassHandler.staticHandler) { return UnsafeReflect.callMethodUnsafe(scriptObject, UnsafeReflect.field(scriptObject, "_HX_SUPER__" + f), args); } return call(o, get(o, f), args); @@ -1333,11 +1344,10 @@ class Interp { var c:Dynamic = resolve(cl); if (c == null) c = Type.resolveClass(cl); - if(c is IHScriptCustomConstructor) { + if (c is IHScriptCustomConstructor) { var c:IHScriptCustomConstructor = cast c; return c.hnew(args); - } else { + } else return Type.createInstance(c, args); - } } }