Typedef support
Original Implementation by ne_eo for hscript-iris. For now only works for normal scripts and making import redirects. Soon for custom classes.
This commit is contained in:
@@ -124,10 +124,13 @@ class Bytes {
|
||||
#end
|
||||
bout.addByte(Type.enumIndex(e));
|
||||
switch( e ) {
|
||||
case EIgnore(_):
|
||||
case EImport(c):
|
||||
// TODO
|
||||
case EClass(_, _, _, _):
|
||||
// TODO
|
||||
case ERedirect(_, _):
|
||||
// TODO
|
||||
case EConst(c):
|
||||
doEncodeConst(c);
|
||||
case EIdent(v):
|
||||
|
||||
@@ -51,6 +51,7 @@ enum ExprDef {
|
||||
typedef ExprDef = Expr;
|
||||
enum Expr {
|
||||
#end
|
||||
EIgnore(skip:Bool);
|
||||
EConst( c : Const );
|
||||
EIdent( v : String );
|
||||
EVar( n : String, ?t : CType, ?e : Expr, ?isPublic : Bool, ?isStatic : Bool, ?isPrivate : Bool, ?isFinal : Bool, ?isInline : Bool );
|
||||
@@ -81,6 +82,7 @@ enum Expr {
|
||||
|
||||
EImport( c : String, ?asname:String );
|
||||
EClass( name:String, fields:Array<Expr>, ?extend:String, interfaces:Array<String>, ?isFinal:Bool, ?isPrivate:Bool );
|
||||
ERedirect( name:String, className:String, ?cl:Class<Dynamic> );
|
||||
}
|
||||
|
||||
@:structInit
|
||||
|
||||
+8
-3
@@ -772,6 +772,7 @@ class Interp {
|
||||
var e = e.e;
|
||||
#end
|
||||
switch (e) {
|
||||
case EIgnore(_):
|
||||
case EClass(name, fields, extend, interfaces): //Not sure if leave the old system or implement the new one.
|
||||
if (customClasses.exists(name))
|
||||
error(EAlreadyExistingClass(name));
|
||||
@@ -854,7 +855,11 @@ class Interp {
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
case ERedirect(n, cln, cl):
|
||||
if(cl != null) {
|
||||
setVar(n, cl);
|
||||
}
|
||||
localImportRedirects.set(n, cln);
|
||||
case EConst(c):
|
||||
switch (c) {
|
||||
case CInt(v): return v;
|
||||
@@ -1644,8 +1649,8 @@ class Interp {
|
||||
}
|
||||
customClassDecl.cacheFields();
|
||||
registerCustomClass(customClassDecl, as);
|
||||
case DTypedef(_):
|
||||
//TODO: maybe make this work :3
|
||||
case DTypedef(td):
|
||||
// TODO: put this work
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1033,7 +1033,39 @@ class Parser {
|
||||
var tk = token();
|
||||
push(tk);
|
||||
mk(EClass(name, fields, extend, interfaces, nextIsFinal, nextIsPrivate), p1);
|
||||
case "typedef":
|
||||
var name = getIdent();
|
||||
|
||||
ensureToken(TOp("="));
|
||||
|
||||
var t = parseType();
|
||||
|
||||
switch(t) {
|
||||
case CTAnon(_) | CTFun(_):
|
||||
mk(EIgnore(true));
|
||||
case CTPath(path, params):
|
||||
if (params != null && params.length > 1)
|
||||
error(ECustom("Typedefs can't have parameters"), tokenMin, tokenMax);
|
||||
|
||||
if (path.length == 0)
|
||||
error(ECustom("Typedefs can't be empty"), tokenMin, tokenMax);
|
||||
|
||||
var className = path.join(".");
|
||||
var cl = Tools.getClass(className);
|
||||
if(cl != null)
|
||||
return mk(ERedirect(name, className, cl));
|
||||
|
||||
var expr = mk(EIdent(path.shift()));
|
||||
while (path.length > 0) {
|
||||
expr = mk(EField(expr, path.shift(), false));
|
||||
}
|
||||
|
||||
// todo? add import to the beginning of the file?
|
||||
mk(EVar(name, null, expr));
|
||||
default:
|
||||
error(ECustom("Typedef, unknown type " + t), tokenMin, tokenMax);
|
||||
null;
|
||||
}
|
||||
case "return":
|
||||
var tk = token();
|
||||
push(tk);
|
||||
|
||||
+4
-1
@@ -113,7 +113,8 @@ class Printer {
|
||||
add("??NULL??");
|
||||
return;
|
||||
}
|
||||
switch( #if hscriptPos e.e #else e #end ) {
|
||||
switch( Tools.expr(e) ) {
|
||||
case EIgnore(_):
|
||||
case EImport(c, n):
|
||||
add("import " + c);
|
||||
if(n != null)
|
||||
@@ -133,6 +134,8 @@ class Printer {
|
||||
|
||||
tabs = tabs.substr(1);
|
||||
add("}");
|
||||
case ERedirect(n, cl):
|
||||
add('typedef $n = $cl');
|
||||
case EConst(c):
|
||||
switch( c ) {
|
||||
case CInt(i): add(i);
|
||||
|
||||
+34
-1
@@ -59,7 +59,7 @@ class Tools {
|
||||
if( def != null ) f(def);
|
||||
case EMeta(name, args, e): if( args != null ) for( a in args ) f(a); f(e);
|
||||
case ECheckType(e,_): f(e);
|
||||
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,6 +91,7 @@ class Tools {
|
||||
case ECheckType(e,t): ECheckType(f(e), t);
|
||||
case EImport(c): EImport(c);
|
||||
case EClass(name, el, extend, interfaces): EClass(name, [for( e in el ) f(e)], extend, interfaces);
|
||||
default: #if hscriptPos e.e #else e #end;
|
||||
}
|
||||
return mk(edef, e);
|
||||
}
|
||||
@@ -111,4 +112,36 @@ class Tools {
|
||||
#end
|
||||
}
|
||||
|
||||
public static function removeInnerClass(name: String): String {
|
||||
var ll = name.lastIndexOf(".");
|
||||
if (name.indexOf(".") != ll) { // checks if there are 2 or more dots
|
||||
// wtf did i make -neo
|
||||
// this is awesome -crow
|
||||
return name.substr(0, name.lastIndexOf(".", ll - 1)) + "." + name.substr(ll + 1);
|
||||
}
|
||||
// only one dot or no dots (will work since -1 + 1 = 0)
|
||||
return name.substr(ll + 1);
|
||||
}
|
||||
|
||||
public static function getClass(name: String): Dynamic {
|
||||
var c: Dynamic = Type.resolveClass(name);
|
||||
if (c == null) // try importing as enum
|
||||
try
|
||||
c = Type.resolveEnum(name);
|
||||
|
||||
if (c == null) {
|
||||
// lastly try removing any inner class from it
|
||||
// this allows you to import stuff like
|
||||
// flixel.text.FlxText.FlxTextBorderStyle
|
||||
// without the script crashing immediately
|
||||
var className = removeInnerClass(name);
|
||||
if (className != name) {
|
||||
c = Type.resolveClass(className);
|
||||
if (c == null)
|
||||
c = Type.resolveEnum(className);
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user