public override bool Reduce(IVariableMap<Expression> Map, ref Expression Reduced) { // Is the source tuple an actual tuple? TupleExpression te = this.SourceTuple as TupleExpression; if (te != null) { // Now we got this :D Reduced = this.InnerExpression.Substitute(new SimpleMap<Expression>(this.BreakIndex, te.Parts)); return true; } // Wouldn't it be hilarious if the inner expression never even used the tuple's data? Expression cire = this.InnerExpression.Compress(this.BreakIndex, this.TupleSize); if (cire != null) { Reduced = cire; return true; } // Nope, guess i'll have to do it the normal way :( Expression tre = this.SourceTuple; Expression ire = this.InnerExpression; if (tre.Reduce(Map, ref tre) | ire.Reduce(this._CreateInner(Map), ref ire)) { Reduced = new TupleBreakExpression(this.BreakIndex, this.TupleSize, tre, ire); return true; } return false; }
public override void TypeCheck( IVariableStack<Expression> TypeStack, IVariableStack<Expression> Stack, out Expression TypeSafeExpression, out Expression Type) { Expression stuple; Expression tupletype; this.SourceTuple.TypeCheck(TypeStack, Stack, out stuple, out tupletype); TupleExpression te; while ((te = tupletype as TupleExpression) == null && tupletype.Reduce(Stack, ref tupletype)) ; if (te == null) { throw new NotImplementedException(); } TupleExpression se; while ((se = stuple as TupleExpression) == null && stuple.Reduce(Stack, ref stuple)) ; Expression[] stackappend; if (se != null) { stackappend = se.Parts ?? new Expression[0]; if (stackappend.Length != this.TupleSize) { throw new NotImplementedException(); } } else { if (te.Parts.Length != this.TupleSize) { throw new NotImplementedException(); } stackappend = new Expression[te.Parts.Length]; int ni = Stack.NextFreeIndex; for (int t = 0; t < te.Parts.Length; t++) { stackappend[t] = Expression.Variable(t + ni); } } Expression si; Expression itype; this.InnerExpression.TypeCheck( TypeStack.Cut(this.BreakIndex).Append(te.Parts ?? new Expression[0]), Stack.Cut(this.BreakIndex).Append(stackappend), out si, out itype); TypeSafeExpression = new TupleBreakExpression(this.BreakIndex, this.TupleSize, stuple, si); Type = itype; }