From 6ba54b0e77af86d6868003c932b157e1db9e84e5 Mon Sep 17 00:00:00 2001 From: Yoshman29 <81191621+YoshiCrafter29@users.noreply.github.com> Date: Fri, 4 Nov 2022 19:33:04 +0100 Subject: [PATCH] static and public --- hscript/Expr.hx | 4 ++-- hscript/Interp.hx | 34 +++++++++++++++++++++++-------- hscript/Parser.hx | 52 +++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 75 insertions(+), 15 deletions(-) diff --git a/hscript/Expr.hx b/hscript/Expr.hx index 62862ee..b3309ce 100644 --- a/hscript/Expr.hx +++ b/hscript/Expr.hx @@ -45,7 +45,7 @@ enum Expr { #end EConst( c : Const ); EIdent( v : String ); - EVar( n : String, ?t : CType, ?e : Expr ); + EVar( n : String, ?t : CType, ?e : Expr, ?isPublic : Bool, ?isStatic : Bool); EParent( e : Expr ); EBlock( e : Array ); EField( e : Expr, f : String ); @@ -57,7 +57,7 @@ enum Expr { EFor( v : String, it : Expr, e : Expr ); EBreak; EContinue; - EFunction( args : Array, e : Expr, ?name : String, ?ret : CType ); + EFunction( args : Array, e : Expr, ?name : String, ?ret : CType, ?isPublic : Bool, ?isStatic : Bool); EReturn( ?e : Expr ); EArray( e : Expr, index : Expr ); EArrayDecl( e : Array ); diff --git a/hscript/Interp.hx b/hscript/Interp.hx index 6f7a397..decef39 100644 --- a/hscript/Interp.hx +++ b/hscript/Interp.hx @@ -26,6 +26,7 @@ */ package hscript; +import haxe.iterators.StringKeyValueIteratorUnicode; import haxe.EnumTools; import haxe.display.Protocol.InitializeResult; import haxe.PosInfos; @@ -43,23 +44,27 @@ private enum Stop { class Interp { public var scriptObject(default, set):Dynamic; public function set_scriptObject(v:Dynamic) { - __instanceFields = Type.getInstanceFields(Type.getClass(v)); + __instanceFields = (v == null) ? [] : Type.getInstanceFields(Type.getClass(v)); return scriptObject = v; } public var errorHandler:Error->Void; #if haxe3 public var variables:Map; + public var publicVariables:Map; + public var staticVariables:Map; var locals:Map; var binops:MapExpr->Dynamic>; #else public var variables:Hash; + public var publicVariables:Hash; + public var staticVariables:Hash; var locals:Hash<{r:Dynamic, depth:Int}>; var binops:HashExpr->Dynamic>; #end - var depth:Int; + var depth:Int = 0; var inTry:Bool; var declared:Array<{n:String, old:{r:Dynamic, depth:Int}, depth:Int}>; var returnValue:Dynamic; @@ -88,8 +93,12 @@ class Interp { private function resetVariables() { #if haxe3 variables = new Map(); + publicVariables = new Map(); + staticVariables = new Map(); #else variables = new Hash(); + publicVariables = new Hash(); + staticVariables = new Hash(); #end variables.set("null", null); @@ -168,7 +177,7 @@ class Interp { case EIdent(id): var l = locals.get(id); if (l == null) { - if (!variables.exists(id) && scriptObject != null) { + if (!variables.exists(id) && !staticVariables.exists(id) && !publicVariables.exists(id) && scriptObject != null) { if (Type.typeof(scriptObject) == TObject) { Reflect.setField(scriptObject, id, v); } else { @@ -378,9 +387,16 @@ class Interp { var l = locals.get(id); if (l != null) return l.r; - var v = variables.get(id); - if (v == null && !variables.exists(id)) { + var v = variables.get(id); + // !publicVariables.exists(id) + if (staticVariables.exists(id)) { + return staticVariables.get(id); + } else if (publicVariables.exists(id)) { + return publicVariables.get(id); + } else if (variables.exists(id)) { + return variables.get(id); + } else { if (scriptObject != null) { // search in object if (id == "this") { @@ -448,10 +464,10 @@ class Interp { } case EIdent(id): return resolve(id); - case EVar(n, _, e): + 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) 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); @@ -520,7 +536,7 @@ class Interp { case EReturn(e): returnValue = e == null ? null : expr(e); throw SReturn; - case EFunction(params, fexpr, name, _): + case EFunction(params, fexpr, name, _, isPublic, isStatic): var __capturedLocals = duplicate(locals); var capturedLocals:Map = []; for(k=>e in __capturedLocals) @@ -587,7 +603,7 @@ class Interp { if (name != null) { if (depth == 0) { // global function - variables.set(name, f); + (isStatic == true ? staticVariables : (isPublic ? publicVariables : variables)).set(name, f); } else { // function-in-function is a local function declared.push({n: name, old: locals.get(name), depth: depth}); diff --git a/hscript/Parser.hx b/hscript/Parser.hx index 2f1e646..4300c43 100644 --- a/hscript/Parser.hx +++ b/hscript/Parser.hx @@ -276,8 +276,8 @@ class Parser { 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 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); @@ -581,6 +581,8 @@ class Parser { } } + var nextIsStatic:Bool = false; + var nextIsPublic:Bool = false; function parseStructure(id, ?oldPos:Int) { #if hscriptPos var p1 = tokenMin; @@ -605,6 +607,48 @@ class Parser { if( semic ) push(TSemicolon); } mk(EIf(cond,e1,e2),p1,(e2 == null) ? tokenMax : pmax(e2)); + case "static": + nextIsStatic = true; + var nextToken = token(); + switch(nextToken) { + case TId("public"): + var str = parseStructure("public"); // public attribute + nextIsStatic = false; + str; + case TId("function"): + var str = parseStructure("function"); // static function + nextIsStatic = false; + str; + case TId("var"): + var str = parseStructure("var"); // static var + nextIsStatic = false; + str; + default: + unexpected(TId("static")); + nextIsStatic = false; + null; + } + case "public": + nextIsPublic = true; + var nextToken = token(); + switch(nextToken) { + case TId("static"): + var str = parseStructure("static"); // static attribute + nextIsPublic = false; + str; + case TId("function"): + var str = parseStructure("function"); // public function + nextIsPublic = false; + str; + case TId("var"): + var str = parseStructure("var"); // public var + nextIsPublic = false; + str; + default: + unexpected(TId("static")); + nextIsPublic = false; + null; + } case "var": var ident = getIdent(); var tk = token(); @@ -618,7 +662,7 @@ class Parser { e = parseExpr(); else push(tk); - mk(EVar(ident,t,e),p1,(e == null) ? tokenMax : pmax(e)); + mk(EVar(ident,t,e,nextIsPublic,nextIsStatic),p1,(e == null) ? tokenMax : pmax(e)); case "while": var econd = parseExpr(); var e = parseExpr(); @@ -655,7 +699,7 @@ class Parser { default: push(tk); } var inf = parseFunctionDecl(); - mk(EFunction(inf.args, inf.body, name, inf.ret),p1,pmax(inf.body)); + mk(EFunction(inf.args, inf.body, name, inf.ret,nextIsPublic,nextIsStatic),p1,pmax(inf.body)); case "import": var oldReadPos = readPos; var tk = token();