Beispiel #1
0
 public virtual void BuildAxisClosureSequence(Expression source, AxisBuildState state, SequenceAccessor sqa, Block block, BlockScope scope) {
   if (!this.IsLocal(source)) {
     Expression loc = this.NewClosureLocal(source.Type, scope);
     block.Statements.Add(new AssignmentStatement(loc, source));
     source = loc;
   }
   foreach( Accessor acc in sqa.Accessors ) {
     block.Statements.Add(this.BuildAxisClosureBlock(source, state, acc, scope));
   }
 }
Beispiel #2
0
 public virtual void BuildAxisClosureUnion(Expression source, AxisBuildState state, SwitchAccessor swa, bool yieldResult, Block block, BlockScope scope) {
   TypeUnion tu = source.Type as TypeUnion;
   Debug.Assert(tu != null, "Switch accessor must have type union");
   if (!this.IsLocal(source)) {
     Expression loc = this.NewClosureLocal(source.Type, scope);
     block.Statements.Add(new AssignmentStatement(loc, source));
     source = loc;
   }
   // determine type union tag and value
   Method mgetvalue = this.GetTypeView(tu).GetMethod(StandardIds.GetValue);
   MethodCall mcgetvalue = new MethodCall(new MemberBinding(source, mgetvalue), null); 
   mcgetvalue.Type = mgetvalue.ReturnType;
   Local locValue = new Local(SystemTypes.Object);
   block.Statements.Add(new AssignmentStatement(locValue, mcgetvalue));
   Method mgettag = this.GetTypeView(tu).GetMethod(StandardIds.GetTag);
   MethodCall mcgettag = new MethodCall(new MemberBinding(source, mgettag), null);
   mcgettag.Type = mgettag.ReturnType;
   Local locTag = new Local(SystemTypes.UInt32);
   block.Statements.Add(new AssignmentStatement(locTag, mcgettag));
   // switch on type union tag
   BlockList blocks = new BlockList(swa.Accessors.Count);
   Block endBlock = new Block(null);
   foreach( int id in swa.Accessors.Keys ) {
     Accessor acc = (Accessor) swa.Accessors[id];
     Block caseBlock = new Block(new StatementList(3));
     blocks.Add(caseBlock);
     block.Statements.Add(new Branch(new BinaryExpression(locTag, new Literal(id, SystemTypes.Int32), NodeType.Eq), caseBlock));
     Expression locvar = this.NewClosureLocal(swa.Type.Types[id], scope);
     caseBlock.Statements.Add(new AssignmentStatement(locvar, this.Unbox(locValue, locvar.Type)));
     this.BuildAxisClosureExpression(locvar, state, acc, yieldResult, caseBlock, scope);
     caseBlock.Statements.Add(new Branch(null, endBlock));
   }
   block.Statements.Add(new Branch(null, endBlock));
   for( int i = 0, n = blocks.Count; i < n; i++ ) {
     block.Statements.Add(blocks[i]);
   }
   block.Statements.Add(endBlock);
 }
Beispiel #3
0
 public virtual void BuildAxisClosureExpression(Expression source, AxisBuildState state, Accessor next, bool yieldResult, Block inner, BlockScope scope) {
   Cardinality tcard = this.typeSystem.GetCardinality(state.YieldType, this.TypeViewer);
   Cardinality scard = this.typeSystem.GetCardinality(source, this.TypeViewer);
   // lift over collections
   while (true) {
     if (this.typeSystem.IsStructural(source.Type))
       goto lift_done;
     if (yieldResult && scard == tcard) 
       goto lift_done;        
     switch (scard) {
       case Cardinality.ZeroOrOne:
         Block b = new Block(new StatementList(3));
         inner.Statements.Add(this.IfNotNull(source, b));
         inner = b;
         source = this.GetNonNull(source, inner, scope);
         break;
       case Cardinality.ZeroOrMore:
       case Cardinality.OneOrMore:
         TypeNode elementType = this.typeSystem.GetStreamElementType(source, this.TypeViewer);
         Expression target = null;
         Block newInner = null;
         inner.Statements.Add(this.BuildClosureForEach(source, ref target, out newInner, scope));
         inner = newInner;
         source = target;
         break;
       default:
         goto lift_done;
     }
     scard = this.typeSystem.GetCardinality(source, this.TypeViewer);
   }
   lift_done:
     if (yieldResult) {
       if (scard == Cardinality.None) {
         Block b = new Block(new StatementList(1));
         inner.Statements.Add(this.IfNotNull(source, b));
         inner = b;
         source = this.GetNonNull(source, inner, scope);
       }
       if (state.YieldTarget != null && state.YieldBlock != null) {
         inner.Statements.Add(new AssignmentStatement(state.YieldTarget, this.typeSystem.ExplicitCoercion(source, state.YieldType, this.TypeViewer)));
         inner.Statements.Add(new Branch(Literal.True, state.YieldBlock));
       }
       else {
         inner.Statements.Add(new Yield(this.typeSystem.ExplicitCoercion(source, state.YieldType, this.TypeViewer)));
       }
     }
   if (next != null) {
     inner.Statements.Add(this.BuildAxisClosure(source, state, next, scope));
   }
 }
Beispiel #4
0
 public virtual void BuildAxisClosureMember(Expression source, AxisBuildState state, MemberAccessor ma, Block block, BlockScope scope) {
   Block inner = block; 
   bool isStatic = (source is Literal) && (source.Type == SystemTypes.Type);
   if (!this.IsLocal(source)) {
     Expression loc = this.NewClosureLocal(source.Type, scope);
     inner.Statements.Add(new AssignmentStatement(loc, source));
     source = loc;
   }
   // sanity check for member/type mismatch caused by aliases
   if (!isStatic && source.Type != ma.Member.DeclaringType) {
     Expression loc = this.NewClosureLocal(ma.Member.DeclaringType, scope);
     inner.Statements.Add(new AssignmentStatement(loc, this.typeSystem.ExplicitCoercion(source, loc.Type, this.TypeViewer)));
     source = loc;
   }
   Cardinality tcard = this.typeSystem.GetCardinality(state.YieldType, this.TypeViewer);
   Cardinality scard = this.typeSystem.GetCardinality(source, this.TypeViewer);
   if (scard != Cardinality.One) {
     Block b = new Block(new StatementList(3));
     inner.Statements.Add(this.IfNotNull(source, b));
     inner = b;
     source = this.GetNonNull(source, inner, scope);
   }
   TypeNode memberType = this.typeSystem.GetMemberType(ma.Member);
   MemberBinding mb = null;
   if (isStatic) {
     mb = new MemberBinding(null, ma.Member);
   }
   else {
     mb = new MemberBinding(source, ma.Member);
   }
   mb.Type = memberType;
   this.BuildAxisClosureExpression(mb, state, ma.Next, ma.Yield, inner, scope);
 }
Beispiel #5
0
 public virtual Block BuildAxisClosureBlock(Expression source, AxisBuildState state, Accessor accessor, BlockScope scope) {
   if (accessor == null || source == null || state == null || state.YieldType == null || scope == null)
     return null;
   MemberAccessor ma = accessor as MemberAccessor;
   if (ma != null) {
     Block block = new Block(new StatementList(3));
     this.BuildAxisClosureMember(source, state, ma, block, scope);
     return block;
   }
   SequenceAccessor sqa = accessor as SequenceAccessor;
   if (sqa != null) {
     Block block = new Block(new StatementList(sqa.Accessors.Count + 1));
     this.BuildAxisClosureSequence(source, state, sqa, block, scope);
     return block;
   }
   SwitchAccessor swa = accessor as SwitchAccessor;
   if (swa != null) {
     Block block = new Block(new StatementList());
     this.BuildAxisClosureUnion(source, state, swa, false, block, scope);
     return block;
   }
   // todo: add error message here
   return null;
 }
Beispiel #6
0
 public virtual Block BuildAxisClosure(Expression source, AxisBuildState state, Accessor acc, BlockScope scope) {
   if (state.TypeClosures != null) {
     TypeNode tn = source.Type;
     CurrentClosure cc = (CurrentClosure) state.TypeClosures[tn.UniqueKey];
     if (cc == null) {
       cc = this.BeginCurrentClosure(state.YieldType, "axis");
       Parameter p = new Parameter(Identifier.For("source"), tn);
       cc.Method.Parameters = new ParameterList(1);
       cc.Method.Parameters.Add(p);
       state.TypeClosures[tn.UniqueKey] = cc;
       ParameterField pf = new ParameterField(cc.Method.Scope, null, FieldFlags.Public, p.Name, p.Type, null);
       pf.Parameter = p;
       cc.Method.Scope.Members.Add(pf);
       MemberBinding mb = new MemberBinding(new ImplicitThis(), pf);
       mb.Type = pf.Type;
       cc.Method.Body.Statements.Add(this.BuildAxisClosureBlock(mb, state, acc, cc.Method.Body.Scope));
       this.EndCurrentClosure(cc);
     }
     Block block = new Block(new StatementList(1));
     ImplicitThis it = new ImplicitThis();
     it.Type = cc.Method.DeclaringType;
     MethodCall mc = new MethodCall(new MemberBinding(it, cc.Method), new ExpressionList(source));
     mc.Type = cc.Method.ReturnType;
     if (cc.Method.IsVirtual) mc.NodeType = NodeType.Callvirt;
     Expression target = null;
     Block inner = null;
     block.Statements.Add(this.BuildClosureForEach(mc, ref target, out inner, scope));
     inner.Statements.Add(new Yield(target));
     return block;
   }
   return this.BuildAxisClosureBlock(source, state, acc, scope);
 }
Beispiel #7
0
 public override Node VisitQueryAxis(QueryAxis axis) {
   if (axis.Type == null) return null; // error handling.
   Cardinality tcard = this.typeSystem.GetCardinality(axis, this.TypeViewer);
   switch( tcard ) {
     case Cardinality.None:
     case Cardinality.One:
     case Cardinality.ZeroOrOne: {
       BlockScope scope = this.currentMethod.Body.Scope;
       Block block = new Block(new StatementList(4));
       AxisBuildState state = new AxisBuildState(axis.Type);
       state.YieldBlock = new Block();
       state.YieldTarget = this.NewClosureLocal(axis.Type, scope);
       if (tcard == Cardinality.ZeroOrOne) {
         block.Statements.Add(new AssignmentStatement(state.YieldTarget, this.typeSystem.ImplicitCoercion(Literal.Null, state.YieldType, this.TypeViewer)));
       }
       block.Statements.Add(this.BuildAxisClosure(axis.Source, state, axis.AccessPlan, scope));
       block.Statements.Add(state.YieldBlock);
       block.Statements.Add(new ExpressionStatement(state.YieldTarget));
       BlockExpression be = new BlockExpression(block, state.YieldType);
       return this.VisitBlockExpression(be);
     }
     default:
     case Cardinality.OneOrMore:
     case Cardinality.ZeroOrMore: {
       TypeNode targetType = this.typeSystem.GetStreamElementType(axis, this.TypeViewer);
       Block body = null;
       Node closure = this.StartQueryClosure(targetType, "axis", out body);
       BlockScope scope = body.Scope;
       AxisBuildState state = new AxisBuildState(targetType);
       if (axis.IsCyclic) state.TypeClosures = new Hashtable();
       Cardinality scard = this.typeSystem.GetCardinality(axis.Source, this.TypeViewer);
       switch( scard ) {
         case Cardinality.None:
         case Cardinality.One:
         case Cardinality.ZeroOrOne:
           body.Statements.Add(this.BuildAxisClosure(axis.Source, state, axis.AccessPlan, scope));
           break;
         case Cardinality.OneOrMore:
         case Cardinality.ZeroOrMore:
           Expression feTarget = null;
           Block inner = null;
           body.Statements.Add(this.BuildClosureForEach(axis.Source, ref feTarget, out inner, scope));
           inner.Statements.Add(this.BuildAxisClosure(feTarget, state, axis.AccessPlan, scope));
           break;
       }
       return this.EndQueryClosure(closure, axis.Type);
     }
   }
 }