|
@@ -107,6 +107,31 @@ class Flatten {
|
|
}
|
|
}
|
|
|
|
|
|
function mapExpr( e : TExpr ) : TExpr {
|
|
function mapExpr( e : TExpr ) : TExpr {
|
|
|
|
+ inline function getFieldPos(expr, name) {
|
|
|
|
+ var pos = -1;
|
|
|
|
+ switch( expr.t ) {
|
|
|
|
+ case TStruct(vl):
|
|
|
|
+ var cur = 0;
|
|
|
|
+ for( v in vl ) {
|
|
|
|
+ if( v.name == name ) {
|
|
|
|
+ pos = cur;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ cur += v.type.size();
|
|
|
|
+ }
|
|
|
|
+ default:
|
|
|
|
+ }
|
|
|
|
+ if( pos < 0 ) throw "assert";
|
|
|
|
+ return pos;
|
|
|
|
+ }
|
|
|
|
+ inline function readField(expr, pos, size) {
|
|
|
|
+ var idx = pos >> 2;
|
|
|
|
+ var arr : TExpr = optimize({ e : TArray(expr,{ e : TConst(CInt(idx)), p : e.p, t : TInt }), p : e.p, t : TVec(4,VFloat) });
|
|
|
|
+ if( size == 4 && pos & 3 == 0 )
|
|
|
|
+ return arr;
|
|
|
|
+ var sw = SWIZ.slice(pos&3,(pos&3) + size);
|
|
|
|
+ return { e : TSwiz(arr,sw), t : size == 1 ? TFloat : TVec(size,VFloat), p : e.p }
|
|
|
|
+ }
|
|
e = switch( e.e ) {
|
|
e = switch( e.e ) {
|
|
case TVar(v):
|
|
case TVar(v):
|
|
var a = varMap.get(v);
|
|
var a = varMap.get(v);
|
|
@@ -148,60 +173,58 @@ class Flatten {
|
|
varMap.set(v, a);
|
|
varMap.set(v, a);
|
|
{ e : TVarDecl(v2, init == null ? null : mapExpr(init)), t : TVoid, p : e.p }
|
|
{ e : TVarDecl(v2, init == null ? null : mapExpr(init)), t : TVoid, p : e.p }
|
|
case TField(expr, name):
|
|
case TField(expr, name):
|
|
- var pos = -1;
|
|
|
|
- switch( expr.t ) {
|
|
|
|
- case TStruct(vl):
|
|
|
|
- var cur = 0;
|
|
|
|
- for( v in vl ) {
|
|
|
|
- if( v.name == name ) {
|
|
|
|
- pos = cur;
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- cur += v.type.size();
|
|
|
|
- }
|
|
|
|
- default:
|
|
|
|
- }
|
|
|
|
- if( pos < 0 ) throw "assert";
|
|
|
|
|
|
+ var pos = getFieldPos(expr, name);
|
|
var expr = mapExpr(expr);
|
|
var expr = mapExpr(expr);
|
|
- function read(pos, size) {
|
|
|
|
- var idx = pos >> 2;
|
|
|
|
- var arr : TExpr = optimize({ e : TArray(expr,{ e : TConst(CInt(idx)), p : e.p, t : TInt }), p : e.p, t : TVec(4,VFloat) });
|
|
|
|
- if( size == 4 && pos & 3 == 0 )
|
|
|
|
- return arr;
|
|
|
|
- var sw = SWIZ.slice(pos&3,(pos&3) + size);
|
|
|
|
- return { e : TSwiz(arr,sw), t : size == 1 ? TFloat : TVec(size,VFloat), p : e.p }
|
|
|
|
- }
|
|
|
|
switch( e.t ) {
|
|
switch( e.t ) {
|
|
case TFloat:
|
|
case TFloat:
|
|
- read(pos, 1);
|
|
|
|
|
|
+ readField(expr, pos, 1);
|
|
case TVec(size,VFloat):
|
|
case TVec(size,VFloat):
|
|
var idx = pos >> 2;
|
|
var idx = pos >> 2;
|
|
var idx2 = ((pos + size - 1) >> 2);
|
|
var idx2 = ((pos + size - 1) >> 2);
|
|
if( idx == idx2 )
|
|
if( idx == idx2 )
|
|
- read(pos, size);
|
|
|
|
|
|
+ readField(expr, pos, size);
|
|
else {
|
|
else {
|
|
var k = 4 - (idx & 3);
|
|
var k = 4 - (idx & 3);
|
|
{ e : TCall({ e : TGlobal(Vec4), p : e.p, t : TVoid },[
|
|
{ e : TCall({ e : TGlobal(Vec4), p : e.p, t : TVoid },[
|
|
- read(pos, k),
|
|
|
|
- read(pos + k, size - k)
|
|
|
|
|
|
+ readField(expr, pos, k),
|
|
|
|
+ readField(expr, pos + k, size - k)
|
|
]), t : e.t, p : e.p }
|
|
]), t : e.t, p : e.p }
|
|
}
|
|
}
|
|
case TMat4:
|
|
case TMat4:
|
|
{ e : TCall({ e : TGlobal(Mat4), p : e.p, t : TVoid },[
|
|
{ e : TCall({ e : TGlobal(Mat4), p : e.p, t : TVoid },[
|
|
- read(pos, 4),
|
|
|
|
- read(pos + 4, 4),
|
|
|
|
- read(pos + 8, 4),
|
|
|
|
- read(pos + 12, 4),
|
|
|
|
|
|
+ readField(expr, pos, 4),
|
|
|
|
+ readField(expr, pos + 4, 4),
|
|
|
|
+ readField(expr, pos + 8, 4),
|
|
|
|
+ readField(expr, pos + 12, 4),
|
|
]), t : e.t, p : e.p }
|
|
]), t : e.t, p : e.p }
|
|
case TMat3x4:
|
|
case TMat3x4:
|
|
{ e : TCall({ e : TGlobal(Mat3x4), p : e.p, t : TVoid },[
|
|
{ e : TCall({ e : TGlobal(Mat3x4), p : e.p, t : TVoid },[
|
|
- read(pos, 4),
|
|
|
|
- read(pos + 4, 4),
|
|
|
|
- read(pos + 8, 4),
|
|
|
|
|
|
+ readField(expr, pos, 4),
|
|
|
|
+ readField(expr, pos + 4, 4),
|
|
|
|
+ readField(expr, pos + 8, 4),
|
|
]), t : e.t, p : e.p }
|
|
]), t : e.t, p : e.p }
|
|
default:
|
|
default:
|
|
throw "Unsupported type "+e.t.toString();
|
|
throw "Unsupported type "+e.t.toString();
|
|
}
|
|
}
|
|
|
|
+ case TBinop(OpAssign, e1, e2) if ( e.t.match(TMat4) && e1.e.match(TField(_,_))):
|
|
|
|
+ var v = null;
|
|
|
|
+ switch ( e2.e ) {
|
|
|
|
+ case TVar(v2):
|
|
|
|
+ v = v2;
|
|
|
|
+ default: throw "Not yet implemented";
|
|
|
|
+ }
|
|
|
|
+ switch ( e1 ) {
|
|
|
|
+ case {e : TField(expr, name), t : TMat4}:
|
|
|
|
+ var pos = getFieldPos(expr, name);
|
|
|
|
+ var expr = mapExpr(expr);
|
|
|
|
+ {e : TBlock([
|
|
|
|
+ {e : TBinop(OpAssign, readField(expr, pos, 4), {e : TArray(e2, {e : TConst(CInt(0)), t : TInt, p : null}), t : TVec(4, VFloat), p : null}), t : e.t, p : e.p},
|
|
|
|
+ {e : TBinop(OpAssign, readField(expr, pos + 4, 4), {e : TArray(e2, {e : TConst(CInt(1)), t : TInt, p : null}), t : TVec(4, VFloat), p : null}), t : e.t, p : e.p},
|
|
|
|
+ {e : TBinop(OpAssign, readField(expr, pos + 8, 4), {e : TArray(e2, {e : TConst(CInt(2)), t : TInt, p : null}), t : TVec(4, VFloat), p : null}), t : e.t, p : e.p},
|
|
|
|
+ {e : TBinop(OpAssign, readField(expr, pos + 12, 4), {e : TArray(e2, {e : TConst(CInt(3)), t : TInt, p : null}), t : TVec(4, VFloat), p : null}), t : e.t, p : e.p},
|
|
|
|
+ ]), t : e.t, p : e.p}
|
|
|
|
+ default : throw "assert";
|
|
|
|
+ }
|
|
default:
|
|
default:
|
|
e.map(mapExpr);
|
|
e.map(mapExpr);
|
|
};
|
|
};
|