|
@@ -7,7 +7,7 @@ class BitsBuilder {
|
|
|
public static function build() {
|
|
|
var fields = Context.getBuildFields();
|
|
|
var pos = Context.currentPos();
|
|
|
- var offsetMap = new Map<String, Int>();
|
|
|
+ var bitsMap = new Map<String, { field : String, current : Int, fields : Array<haxe.macro.Expr> }>();
|
|
|
for( f in fields.copy() ) {
|
|
|
var bits = 0;
|
|
|
var field : String = null;
|
|
@@ -16,7 +16,7 @@ class BitsBuilder {
|
|
|
if( m2.params.length < 1 )
|
|
|
Context.error("Please specify the bits field", f.pos);
|
|
|
|
|
|
- bits = -1;
|
|
|
+ bits = -1; // auto
|
|
|
field = switch( m2.params[0] ) {
|
|
|
case { expr : EConst(CIdent(v)) } : v;
|
|
|
default : null;
|
|
@@ -34,9 +34,13 @@ class BitsBuilder {
|
|
|
|
|
|
if( bits == 0 ) continue;
|
|
|
|
|
|
- var offset = offsetMap.get(field);
|
|
|
- if( offset == null ) offset = 0;
|
|
|
+ var inf = bitsMap.get(field);
|
|
|
+ if( inf == null ) {
|
|
|
+ inf = { field : field, current : 0, fields : [] };
|
|
|
+ bitsMap.set(field, inf);
|
|
|
+ }
|
|
|
|
|
|
+ var offset = inf.current;
|
|
|
switch( f.kind ) {
|
|
|
case FVar(vt = TPath( { pack : pack, name : name }), init):
|
|
|
f.kind = FProp("default", "set", vt, init);
|
|
@@ -44,15 +48,18 @@ class BitsBuilder {
|
|
|
var path = pack.copy();
|
|
|
path.push(name);
|
|
|
var t = try Context.getType(path.join(".")) catch( e : Dynamic ) continue;
|
|
|
+ var fget = null;
|
|
|
var expr = switch( t ) {
|
|
|
case TAbstract(a, _):
|
|
|
var t = Std.string(a);
|
|
|
switch( t ) {
|
|
|
case "Bool":
|
|
|
if( bits < 0 ) bits = 1;
|
|
|
+ fget = function(v) return macro ($v != 0);
|
|
|
macro (v ? 1 : 0);
|
|
|
case "Int":
|
|
|
if( bits < 0 ) Context.error("Please specify bit count", f.pos);
|
|
|
+ fget = function(v) return v;
|
|
|
macro (v & $v{ (1<<bits) - 1 });
|
|
|
default:
|
|
|
null;
|
|
@@ -62,6 +69,7 @@ class BitsBuilder {
|
|
|
var count = e.get().names.length;
|
|
|
while( count > 1 << bits ) bits++;
|
|
|
}
|
|
|
+ fget = function(v) return macro Type.createEnumIndex($p{path},$v);
|
|
|
macro Type.enumIndex(v);
|
|
|
default:
|
|
|
null;
|
|
@@ -81,6 +89,9 @@ class BitsBuilder {
|
|
|
pos : f.pos,
|
|
|
});
|
|
|
|
|
|
+ var v = fget(macro (this.$field >> $v{offset}) & $v{mask});
|
|
|
+ inf.fields.push(macro this.$name = $v);
|
|
|
+
|
|
|
fields.push({
|
|
|
name : "get" + f.name.charAt(0).toUpperCase() + f.name.substr(1),
|
|
|
access : [AStatic,APublic,AInline],
|
|
@@ -109,12 +120,26 @@ class BitsBuilder {
|
|
|
kind : FVar(null, macro $v{ mask << offset } ),
|
|
|
pos : pos,
|
|
|
});
|
|
|
- offset += bits;
|
|
|
default:
|
|
|
}
|
|
|
- if( offset > 32 )
|
|
|
- Context.error(offset + " bits were used while maximum was 32", pos);
|
|
|
- offsetMap.set(field, offset);
|
|
|
+
|
|
|
+ inf.current += bits;
|
|
|
+ if( inf.current > 32 )
|
|
|
+ Context.error(inf.current + " bits were used while maximum was 32", pos);
|
|
|
+ }
|
|
|
+
|
|
|
+ for( f in bitsMap ) {
|
|
|
+ var field = f.field;
|
|
|
+ fields.push({
|
|
|
+ name : "load" + f.field.charAt(0).toUpperCase() + f.field.substr(1),
|
|
|
+ access : [],
|
|
|
+ pos : pos,
|
|
|
+ kind : FFun({
|
|
|
+ args : [{ name : "bits", type : macro : Int }],
|
|
|
+ ret : null,
|
|
|
+ expr : macro { this.$field = bits; {$a{f.fields}} },
|
|
|
+ }),
|
|
|
+ });
|
|
|
}
|
|
|
|
|
|
return fields;
|