Skip to content

Commit

Permalink
Allow display VInt as hex, bin, EnumFlags<T>
Browse files Browse the repository at this point in the history
Usage: "myvar:h", "myvar:b", "myvar:EnumFlags<(enumname)>"(created using
haxe.EnumFlags)
  • Loading branch information
yuxiaomao committed Apr 4, 2024
1 parent 97a221d commit 6d67852
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 2 deletions.
23 changes: 21 additions & 2 deletions hld/Eval.hx
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,16 @@ class Eval {
public function eval( expr : String ) {
if( expr == null || expr == "" )
return null;
var exprs = expr.split(":");
var hint = HNone;
if( exprs.length > 1 ) {
hint = Value.parseHint(exprs.pop()); // content after the last ":" is considered as a display hint
expr = exprs.join(":");
}
var expr = try parser.parseString(expr) catch( e : hscript.Expr.Error ) throw hscript.Printer.errorToString(e);
return evalExpr(expr);
var v = evalExpr(expr);
v.hint = hint;
return v;
}

public function setValue( expr : String, value : String ) {
Expand Down Expand Up @@ -760,7 +768,18 @@ class Eval {
var str = switch( v.v ) {
case VUndef: "undef"; // null read / outside bounds
case VNull: "null";
case VInt(i): "" + i;
case VInt(i):
switch( v.hint ) {
case HHex: Value.int2Str(i, 16);
case HBin: Value.int2Str(i, 2);
case HEnumFlags(t):
var eproto = module.resolveEnum(t);
if( eproto == null )
throw "Can't resolve enum " + t;
Value.int2EnumFlags(i, eproto);
default:
"" + i;
}
case VInt64(i): "" + i;
case VFloat(v): "" + v;
case VBool(b): b?"true":"false";
Expand Down
7 changes: 7 additions & 0 deletions hld/Module.hx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class Module {
var functionsByFile : Map<Int, Array<{ f : HLFunction, ifun : Int, lmin : Int, lmax : Int }>>;
var globalsOffsets : Array<Int>;
var globalTable : GlobalAccess;
var eprotoTable : Map<String,EnumPrototype>;
var protoCache : Map<String,ModuleProto>;
var eprotoCache : Map<String,ModuleEProto>;
var functionRegsCache : Array<Array<{ t : HLType, offset : Int }>>;
Expand Down Expand Up @@ -163,6 +164,7 @@ class Module {
}
t.gid = gid;
}
eprotoTable = [];
for( t in code.types )
switch( t ) {
case HObj(o) if( o.globalValue != null ):
Expand All @@ -184,6 +186,7 @@ class Module {
if( hasAlias ) addGlobal(apath, o.globalValue);
case HEnum(e) if( e.globalValue != null ):
addGlobal(e.name.split("."), e.globalValue);
eprotoTable.set(e.name, e);
default:
}
}
Expand Down Expand Up @@ -289,6 +292,10 @@ class Module {
return g == globalTable || g.gid == null ? null : { type : code.globals[g.gid], offset : globalsOffsets[g.gid] };
}

public function resolveEnum( path : String ) {
return eprotoTable.get(path);
}

public function getFileFunctions( file : String ) {
var ifile = fileIndexes.get(file);
if( ifile == null )
Expand Down
48 changes: 48 additions & 0 deletions hld/Value.hx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,55 @@ enum FunRepr {

typedef InlinedField = { name : String, addr : Eval.VarAddress }

enum Hint {
HNone;
HHex;
HBin;
HEnumFlags(t : String);
}

@:structInit class Value {
public var v : ValueRepr;
public var t : HLType;
@:optional public var hint : Hint = HNone;

public static function parseHint( s : String ) : Hint {
if( s == "h" )
return HHex;
if( s == "b" )
return HBin;
if( StringTools.startsWith(s,"EnumFlags<") && StringTools.endsWith(s,">") )
return HEnumFlags(s.substr(10, s.length - 11));
return HNone;
}

static final INTBASE = "0123456789ABCDEF";
public static function int2Str( value : Int, base : Int ) : String {
if( base < 2 || base > INTBASE.length )
throw "Unsupported int base";
var prefix = base == 2 ? "0b" : base == 16 ? "0x" : "";
if( base == 10 || value == 0 )
return prefix + value;
var s = "";
var abs = value >= 0 ? value : -value;
while( abs > 0 ) {
s = INTBASE.charAt(abs % base) + s;
abs = Std.int(abs / base);
}
return (value < 0 ? "-" : "") + prefix + s;
}

public static function int2EnumFlags( value : Int, eproto : format.hl.Data.EnumPrototype ) : String {
var f = "";
for( i in 0...eproto.constructs.length ) {
if( (value >> i) % 2 == 1 )
f += " | " + eproto.constructs[i].name;
}
if( f.length == 0 )
f = "(noflag)";
else
f = f.substr(3);
return f;
}

}

0 comments on commit 6d67852

Please sign in to comment.