Beispiel #1
0
        public void EmitExtract(IBlockContext context, List <IBlockVariable> targetVariables)
        {
            IBlockVariable target = targetVariables[0];

            Type generatedType = optionType.GeneratedType(context.ModuleContext);

            context.IL.Emit(OpCodes.Dup);
            context.IL.Emit(OpCodes.Ldfld, generatedType.GetField("defined"));

            if (target == null)
            {
                context.IL.Emit(OpCodes.Pop);
            }
            else
            {
                LabelRef onUndefined = context.IL.DefineLabel(true);
                LabelRef end         = context.IL.DefineLabel(true);

                context.IL.Emit(OpCodes.Brfalse_S, onUndefined);
                context.IL.Emit(OpCodes.Ldfld, generatedType.GetField("value"));
                target.EmitStore(context);
                context.IL.Emit(OpCodes.Ldc_I4_1);
                context.IL.Emit(OpCodes.Br_S, end);

                context.IL.MarkLabel(onUndefined);
                context.IL.Emit(OpCodes.Pop);
                context.IL.Emit(OpCodes.Ldc_I4_0);

                context.IL.MarkLabel(end);
            }
        }
Beispiel #2
0
        public void EmitExtract(IBlockContext context, List <IBlockVariable> targetVariables)
        {
            IBlockVariable target = targetVariables[0];

            Type generatedType = resultType.GeneratedType(context.ModuleContext);

            context.IL.Emit(OpCodes.Dup);
            context.IL.Emit(OpCodes.Ldfld, generatedType.GetField("success"));
            if (target == null)
            {
                context.IL.Emit(OpCodes.Ldc_I4_0);
                context.IL.Emit(OpCodes.Ceq);
                context.IL.Emit(OpCodes.Pop);
            }
            else
            {
                LabelRef onOk = context.IL.DefineLabel(true);
                LabelRef end  = context.IL.DefineLabel(true);

                context.IL.Emit(OpCodes.Brtrue_S, onOk);
                context.IL.Emit(OpCodes.Ldfld, generatedType.GetField("error"));
                target.EmitStore(context);
                context.IL.Emit(OpCodes.Ldc_I4_1);
                context.IL.Emit(OpCodes.Br_S, end);

                context.IL.MarkLabel(onOk);
                context.IL.Emit(OpCodes.Pop);
                context.IL.Emit(OpCodes.Ldc_I4_0);

                context.IL.MarkLabel(end);
            }
        }
Beispiel #3
0
		/// <summary>
		/// Initializes a new instance of the <see cref="ReduceActionItem"/> class.
		/// </summary>
		public ReduceActionItem(LabelRef label, IReadOnlyList<IReadOnlySet<CodePoint>> followRestriction)
		{
			#region Contract
			Contract.Requires<ArgumentNullException>(followRestriction != null);
			#endregion
			this.Label = label;
			this.FollowRestriction = followRestriction.ToArray();
		}
Beispiel #4
0
 public void Emit(OpCode opCode, LabelRef labelRef)
 {
     ilSize += InstructionSize.Get(opCode);
     AdjustStack(opCode);
     commands.Add(new ILCommand {
         opCode = opCode, args = $"<label>{labelRef.label.GetHashCode()}"
     });
 }
Beispiel #5
0
		public bool HasValidLayout(LabelRef? label, IReadOnlyList<IParseNode> children)
		{
			if (label == null)
				return true;
			var layoutConstraint = parseTable.Labels[((LabelRef)label).Index].Attributes.LayoutConstraint;
			if (layoutConstraint == null)
				return true;

			return EvalConstraint(layoutConstraint, children, new Dictionary<string, object>());
		}
Beispiel #6
0
 public void EmitCheckDone(IBlockContext context, LabelRef loop)
 {
     currentIndex.EmitLoad(context);
     context.IL.Emit(OpCodes.Ldc_I4_1);
     context.IL.Emit(OpCodes.Conv_I8);
     context.IL.Emit(OpCodes.Add);
     context.IL.Emit(OpCodes.Dup);
     currentIndex.EmitStore(context);
     rangeRef.EmitLoad(context);
     context.IL.Emit(OpCodes.Ldfld, typeof(Range).GetField("to"));
     context.IL.Emit(loop.isShort ? OpCodes.Blt_S : OpCodes.Blt, loop);
 }
Beispiel #7
0
        private object OnLabelRef(LabelRef labelRef)
        {
            INiCommandBarControl control;

            ErrorUtil.ThrowOnFailure(_commandManager.FindCommandBarControl(
                                         labelRef.Guid,
                                         out control
                                         ));

            if (control == null)
            {
                throw new NetIdeException(String.Format(NeutralResources.CannotFindCommand, labelRef.Guid));
            }

            return(control);
        }
Beispiel #8
0
        private ILCount EstimateLoop(IBlockContext context, IForInSource source)
        {
            IBlockContext prepContext = context.CloneCountingContext();

            sourceExpression.EmitCode(prepContext, false);
            source.EmitInitialize(prepContext);

            IBlockContext countingContext = prepContext.CloneCountingContext()
                                            .CreateLoopContext(context.IL.DefineLabel(false), context.IL.DefineLabel(false));
            IBlockVariable loopVariable = countingContext.DeclaredVariable(variableName, true, source.ElementType);
            LabelRef       loop         = countingContext.IL.DefineLabel(false);

            source.EmitNext(countingContext);
            loopVariable.EmitStore(countingContext);
            loopExpression.EmitCode(countingContext, true);
            source.EmitCheckDone(countingContext, loop);

            return(new ILCount {
                opCodes = countingContext.IL.ILSize,
                stack = countingContext.IL.StackCount
            });
        }
Beispiel #9
0
        internal static AsyncClass Create(IBlockContext parent, string name, TO2Type declaredReturn,
                                          List <FunctionParameter> parameters, Expression expression)
        {
            Type returnType    = declaredReturn.GeneratedType(parent.ModuleContext);
            Type typeParameter = returnType == typeof(void) ? typeof(object) : returnType;

            ModuleContext asyncModuleContext = parent.ModuleContext.DefineSubContext($"AsyncFunction_{name}",
                                                                                     typeof(Future <>).MakeGenericType(typeParameter));

            List <ClonedFieldVariable> clonedParameters = new List <ClonedFieldVariable>();

            foreach (FunctionParameter parameter in parameters)
            {
                FieldBuilder field = asyncModuleContext.typeBuilder.DefineField(parameter.name,
                                                                                parameter.type.GeneratedType(parent.ModuleContext), FieldAttributes.Private);
                clonedParameters.Add(
                    new ClonedFieldVariable(parameter.type.UnderlyingType(parent.ModuleContext), field));
            }

            // ------------- PollValue -------------
            AsyncBlockContext asyncContext = new AsyncBlockContext(asyncModuleContext, FunctionModifier.Public,
                                                                   "PollValue", declaredReturn, typeof(FutureResult <>).MakeGenericType(typeParameter), clonedParameters);

            LabelRef applyState   = asyncContext.IL.DefineLabel(false);
            LabelRef initialState = asyncContext.IL.DefineLabel(false);

            asyncContext.IL.Emit(OpCodes.Br, applyState);
            asyncContext.IL.MarkLabel(initialState);

            expression.EmitCode(asyncContext, false);
            if (!asyncContext.HasErrors)
            {
                declaredReturn.AssignFrom(asyncContext.ModuleContext, expression.ResultType(asyncContext))
                .EmitConvert(asyncContext);
            }

            asyncContext.IL.EmitNew(OpCodes.Newobj,
                                    asyncContext.MethodBuilder.ReturnType.GetConstructor(new[] { typeParameter }));
            asyncContext.IL.EmitReturn(asyncContext.MethodBuilder.ReturnType);

            // Apply state
            asyncContext.IL.MarkLabel(applyState);
            asyncContext.IL.Emit(OpCodes.Ldarg_0);
            asyncContext.IL.Emit(OpCodes.Ldfld, asyncContext.stateField);
            asyncContext.IL.Emit(OpCodes.Switch,
                                 initialState.Yield().Concat(asyncContext.asyncResumes.Select(ar => ar.pollLabel)));
            asyncContext.IL.Emit(OpCodes.Ldarg_0);
            asyncContext.IL.Emit(OpCodes.Ldfld, asyncContext.stateField);
            asyncContext.IL.EmitNew(OpCodes.Newobj,
                                    typeof(InvalidAsyncStateException).GetConstructor(new[] { typeof(int) }), 1);
            asyncContext.IL.Emit(OpCodes.Throw);

            foreach (AsyncResume asyncResume in asyncContext.asyncResumes)
            {
                asyncResume.EmitPoll(asyncContext);
            }

            // Restore state
            asyncContext.IL.MarkLabel(asyncContext.resume);
            foreach (StateRef stateRef in asyncContext.stateRefs)
            {
                stateRef.EmitRestore(asyncContext);
            }
            asyncContext.IL.Emit(OpCodes.Ldarg_0);
            asyncContext.IL.Emit(OpCodes.Ldfld, asyncContext.stateField);
            asyncContext.IL.Emit(OpCodes.Switch,
                                 initialState.Yield().Concat(asyncContext.asyncResumes.Select(ar => ar.resumeLabel)));
            asyncContext.IL.Emit(OpCodes.Ldarg_0);
            asyncContext.IL.Emit(OpCodes.Ldfld, asyncContext.stateField);
            asyncContext.IL.EmitNew(OpCodes.Newobj,
                                    typeof(InvalidAsyncStateException).GetConstructor(new[] { typeof(int) }), 1);
            asyncContext.IL.Emit(OpCodes.Throw);

            // Store state
            asyncContext.IL.MarkLabel(asyncContext.storeState);
            foreach (StateRef stateRef in asyncContext.stateRefs)
            {
                stateRef.EmitStore(asyncContext);
            }

            asyncContext.IL.MarkLabel(asyncContext.notReady);
            using (ITempLocalRef notReady = asyncContext.IL.TempLocal(asyncContext.MethodBuilder.ReturnType)) {
                notReady.EmitLoadPtr(asyncContext);
                asyncContext.IL.Emit(OpCodes.Initobj, asyncContext.MethodBuilder.ReturnType, 1, 0);
                notReady.EmitLoad(asyncContext);
                asyncContext.IL.EmitReturn(asyncContext.MethodBuilder.ReturnType);
            }

            foreach (StructuralError error in asyncContext.AllErrors)
            {
                parent.AddError(error);
            }

            // ------------- Constructor -------------
            List <FieldInfo>   parameterFields    = clonedParameters.Select(c => c.valueField).ToList();
            ConstructorBuilder constructorBuilder = asyncModuleContext.typeBuilder.DefineConstructor(
                MethodAttributes.Public, CallingConventions.Standard,
                parameterFields.Select(f => f.FieldType).ToArray());
            IILEmitter constructorEmitter = new GeneratorILEmitter(constructorBuilder.GetILGenerator());

            int argIndex = 1;

            foreach (FieldInfo field in parameterFields)
            {
                constructorEmitter.Emit(OpCodes.Ldarg_0);
                MethodParameter.EmitLoadArg(constructorEmitter, argIndex++);
                constructorEmitter.Emit(OpCodes.Stfld, field);
            }

            constructorEmitter.Emit(OpCodes.Ldarg_0);
            constructorEmitter.Emit(OpCodes.Ldc_I4_0);
            constructorEmitter.Emit(OpCodes.Stfld, asyncContext.stateField);

            constructorEmitter.EmitReturn(typeof(void));

            return(new AsyncClass(asyncModuleContext.typeBuilder, constructorBuilder));
        }
Beispiel #10
0
        public override void EmitCode(IBlockContext context, bool dropResult)
        {
            RealizedType sourceType = sourceExpression.ResultType(context).UnderlyingType(context.ModuleContext);
            IForInSource source     = sourceType.ForInSource(context.ModuleContext, variableType);

            if (source == null)
            {
                context.AddError(
                    new StructuralError(
                        StructuralError.ErrorType.InvalidType,
                        $"{sourceType} cannot be use as for ... in source",
                        Start,
                        End
                        )
                    );
            }
            if (context.FindVariable(variableName) != null)
            {
                context.AddError(new StructuralError(
                                     StructuralError.ErrorType.DuplicateVariableName,
                                     $"Variable '{variableName}' already declared in this scope",
                                     Start,
                                     End
                                     ));
            }
            if (source != null && variableType != null &&
                !variableType.IsAssignableFrom(context.ModuleContext, source.ElementType))
            {
                context.AddError(
                    new StructuralError(
                        StructuralError.ErrorType.InvalidType,
                        $"{sourceType} has elements of type {source.ElementType}, expected {variableType}",
                        Start,
                        End
                        )
                    );
            }

            if (context.HasErrors)
            {
                return;
            }

            using ITempLocalRef loopCounter = context.IL.TempLocal(typeof(int));
            ILCount  loopSize = EstimateLoop(context, source);
            LabelRef start    = context.IL.DefineLabel(loopSize.opCodes < 110);
            LabelRef end      = context.IL.DefineLabel(loopSize.opCodes < 110);
            LabelRef loop     = context.IL.DefineLabel(loopSize.opCodes < 100);

            IBlockContext  loopContext  = context.CreateLoopContext(start, end);
            IBlockVariable loopVariable = loopContext.DeclaredVariable(variableName, true, source !.ElementType);

            sourceExpression.EmitCode(context, false);

            if (context.HasErrors)
            {
                return;
            }

            source.EmitInitialize(loopContext);
            loopContext.IL.Emit(start.isShort ? OpCodes.Br_S : OpCodes.Br, start);

            loopContext.IL.MarkLabel(loop);

            // Timeout check
            LabelRef skipCheck = context.IL.DefineLabel(true);

            loopCounter.EmitLoad(loopContext);
            loopContext.IL.Emit(OpCodes.Ldc_I4_1);
            loopContext.IL.Emit(OpCodes.Add);
            loopContext.IL.Emit(OpCodes.Dup);
            loopCounter.EmitStore(loopContext);
            loopContext.IL.Emit(OpCodes.Ldc_I4, 10000);
            loopContext.IL.Emit(OpCodes.Cgt);
            loopContext.IL.Emit(OpCodes.Brfalse, skipCheck);
            loopContext.IL.Emit(OpCodes.Ldc_I4_0);
            loopCounter.EmitStore(loopContext);
            context.IL.EmitCall(OpCodes.Call, typeof(Runtime.ContextHolder).GetMethod("CheckTimeout"), 0);
            loopContext.IL.MarkLabel(skipCheck);

            source.EmitNext(loopContext);
            loopVariable.EmitStore(loopContext);
            loopExpression.EmitCode(loopContext, true);
            loopContext.IL.MarkLabel(start);
            source.EmitCheckDone(loopContext, loop);
            loopContext.IL.MarkLabel(end);
            if (!dropResult)
            {
                context.IL.Emit(OpCodes.Ldnull);
            }
        }
	// Emit a switch statement.
	public virtual void Emit(OpCode opcode, Label[] labels)
			{
				// Determine where the switch statement ends.
				int switchEnd = offset + opcode.size + labels.Length * 4;

				// Emit the opcode and the table length.
				EmitOpcode(ref opcode);
				EmitToken(labels.Length);

				// Output the table of switch labels.
				int posn;
				Label label;
				LabelInfo info;
				LabelRef newRef;
				for(posn = 0; posn < labels.Length; ++posn)
				{
					// Skip the label if it is invalid (shouldn't happen).
					label = labels[posn];
					if(label.index < 0 || label.index >= numLabels)
					{
						continue;
					}

					// Fetch the label information block.
					info = this.labels[label.index];

					// If it is already defined, output the offset now.
					// Otherwise add a reference and output a placeholder.
					if(info.offset != 0)
					{
						EmitToken(info.offset - switchEnd);
					}
					else
					{
						newRef = new LabelRef();
						newRef.next = this.labels[label.index].refs;
						newRef.address = offset;
						newRef.switchEnd = switchEnd;
						this.labels[label.index].refs = newRef;
						EmitToken(0);
					}
				}
			}
	// Emit code for a branch instruction.  Note: unlike other implementations,
	// we always output the branch in such a way that an out of range error
	// can never occur.  This makes it easier to process forward references
	// in a single pass through the code.
	public virtual void Emit(OpCode opcode, Label label)
			{
				int index = label.index;
				int shortForm, longForm;
				if(index < 0 || index >= numLabels)
				{
					return;
				}
				if((OperandType)(opcode.operandType) ==
						OperandType.ShortInlineBrTarget)
				{
					// Convert a short opcode into its long form.
					shortForm = opcode.value;
					if(shortForm >= 0x2B && shortForm <= 0x37)
					{
						longForm = shortForm - 0x2B + 0x38;
					}
					else
					{
						longForm = 0xDD;
					}
				}
				else if((OperandType)(opcode.operandType) ==
							OperandType.InlineBrTarget)
				{
					// Convert a long opcode into its short form.
					longForm = opcode.value;
					if(longForm >= 0x38 && longForm <= 0x44)
					{
						shortForm = longForm + 0x2B - 0x38;
					}
					else
					{
						shortForm = 0xDE;
					}
				}
				else
				{
					// Ignore non-branch opcodes.
					return;
				}
				if(labels[index].offset != 0)
				{
					// The label is already defined.  Determine if the
					// branch is long or short.
					int dest = (labels[index].offset - 1) - (offset + 2);
					if(dest >= -128 && dest <= 127)
					{
						EmitByte(shortForm);
						EmitByte(dest);
					}
					else
					{
						dest = (labels[index].offset - 1) - (offset + 5);
						EmitByte(longForm);
						EmitByte(dest);
						EmitByte(dest >> 8);
						EmitByte(dest >> 16);
						EmitByte(dest >> 24);
					}
				}
				else
				{
					// Output the long form and add a reference to the label.
					EmitByte(longForm);
					EmitByte(0);
					EmitByte(0);
					EmitByte(0);
					EmitByte(0);
					LabelRef newRef = new LabelRef();
					newRef.next = labels[index].refs;
					newRef.address = offset - 4;
					newRef.switchEnd = -1;
					labels[index].refs = newRef;
				}
				switch((StackBehaviour)(opcode.stackPop))
				{
					case StackBehaviour.Popi:
						--height;
						break;

					case StackBehaviour.Pop1_pop1:
						height -= 2;
						break;

					default: break;
				}
			}
		/// <summary>
		/// Parses the priorities items from the parse table.
		/// </summary>
		/// <param name="listTerm">A list of priority terms.</param>
		/// <returns>The parsed priorities.</returns>
		/// <example>
		/// The term might look like this:
		/// <code>
		/// [arg-gtr-prio(286,2,286), gtr-prio(301,295)]
		/// </code>
		/// </example>
		private IReadOnlyList<Priority> ParsePriorities(IListTerm listTerm)
		{
			#region Contract
			Contract.Requires<ArgumentNullException>(listTerm != null);
			Contract.Ensures(Contract.Result<IReadOnlyList<Priority>>() != null);
			#endregion

			var result = new List<Priority>(listTerm.Count);
			foreach (var term in listTerm.SubTerms.Cast<IConsTerm>())
			{
				switch (term.Name)
				{
					case "left-prio":
					case "right-prio":
					case "non-assoc":
						// Not supported.
						break;
					case "gtr-prio":
						{
							var left = new LabelRef(term[0].ToInt32() - SpoofaxParseTableFormat.LabelBase);
							var right = new LabelRef(term[1].ToInt32() - SpoofaxParseTableFormat.LabelBase);
							if (left != right)
								result.Add(new Priority(left, right, PriorityType.Greater));
							break;
						}
					case "arg-gtr-prio":
						{
							var left = new LabelRef(term[0].ToInt32() - SpoofaxParseTableFormat.LabelBase);
							var arg = term[1].ToInt32();
							var right = new LabelRef(term[2].ToInt32() - SpoofaxParseTableFormat.LabelBase);
							if (left != right)
								result.Add(new Priority(left, right, arg, PriorityType.Greater));
							break;
						}
					default:
						throw new InvalidParseTableException("Unknown priority: " + term);
				}
			}
			return result;
		}
		/// <summary>
		/// Parses a reduce action item.
		/// </summary>
		/// <param name="term">The term.</param>
		/// <param name="labels">The labels in the parse table.</param>
		/// <returns>The parsed action item.</returns>
		/// <example>
		/// The term might look like this (without lookahead)
		/// <code>
		/// reduce(0,280,0)
		/// </code>
		/// or this (with lookahead)
		/// <code>
		/// reduce(0,280,0,[follow-restriction([char-class([42,47])])])
		/// </code>
		/// </example>
		private ActionItem ParseReduce(IConsTerm term, IReadOnlyList<Label> labels)
		{
			#region Contract
			Contract.Requires<ArgumentNullException>(term != null);
			Contract.Requires<ArgumentException>(term.IsCons("reduce", 3) || term.IsCons("reduce", 4));
			Contract.Requires<ArgumentNullException>(labels != null);
			Contract.Ensures(Contract.Result<ActionItem>() != null);
			#endregion

			int productionArity = term[0].ToInt32();
			var label = new LabelRef(term[1].ToInt32() - SpoofaxParseTableFormat.LabelBase);
			ProductionType status = (ProductionType)term[2].ToInt32();
			bool isRecover = labels[label.Index].Production.IsRecover;
			bool isCompletion = labels[label.Index].Production.IsCompletion;
			var followRestriction = term.SubTerms.Count == 4 ? ParseLookaheadCharRanges((IListTerm)term[3]) : ArrayExt.Empty<IReadOnlySet<CodePoint>>();

			// Redundant information. Let's check it while we're at it.
			var production = labels[label.Index].Production;
			Contract.Assert(production.Arity == productionArity);
			Contract.Assert(production.IsCompletion == isCompletion);
			Contract.Assert(production.IsRecover == isRecover);
			Contract.Assert(production.Type == status);

			return new ReduceActionItem(label, followRestriction);
		}
 public void MarkLabel(LabelRef labelRef) => generator.MarkLabel(labelRef.label);
Beispiel #16
0
		private void ReduceAllPaths(LabelRef label, IEnumerable<Path> paths)
		{
			foreach (Path path in paths)
			{
				var kids = path.GetAncestorParseNodes();
				var st0 = path.Frame;
				var nextState = this.parseTable.Go(st0.State, label);
				Reducer(st0, nextState, label, kids, path);
			}
		}
Beispiel #17
0
		// TODO: Rename to DoReductions?
		/// <summary>
		/// 
		/// </summary>
		/// <param name="stack"></param>
		/// <param name="label"></param>
		/// <param name="link">; or <see langword="null"/>.</param>
		public void DoLimitedReductions(Frame stack, LabelRef label, Link link)
		{
			#region Contract
			Contract.Requires<ArgumentNullException>(stack != null);
			Contract.Requires<ArgumentNullException>(label != null);
			#endregion

			var production = this.parseTable.Labels[label.Index].Production;

			if (!RecoverModeOk(stack, production))
				return;

			var paths = stack.FindPathsToRoot(production.Arity, link);
			ReduceAllPaths(label, paths);
		}
Beispiel #18
0
        public override void EmitCode(IBlockContext context, bool dropResult)
        {
            TO2Type leftType  = left.ResultType(context);
            TO2Type rightType = right.ResultType(context);

            if (leftType != BuiltinType.Bool)
            {
                context.AddError(new StructuralError(
                                     StructuralError.ErrorType.IncompatibleTypes,
                                     "Expected boolean",
                                     left.Start,
                                     left.End
                                     ));
            }
            if (rightType != BuiltinType.Bool)
            {
                context.AddError(new StructuralError(
                                     StructuralError.ErrorType.IncompatibleTypes,
                                     "Expected boolean",
                                     right.Start,
                                     right.End
                                     ));
            }

            if (context.HasErrors)
            {
                return;
            }

            left.EmitCode(context, false);
            if (!dropResult)
            {
                context.IL.Emit(OpCodes.Dup);
            }

            ILCount  rightCount = right.GetILCount(context, dropResult);
            LabelRef skipRight  = context.IL.DefineLabel(rightCount.opCodes < 124);

            if (context.HasErrors)
            {
                return;
            }

            switch (op)
            {
            case Operator.BoolAnd:
                context.IL.Emit(skipRight.isShort ? OpCodes.Brfalse_S : OpCodes.Brfalse, skipRight);
                break;

            case Operator.BoolOr:
                context.IL.Emit(skipRight.isShort ? OpCodes.Brtrue_S : OpCodes.Brtrue, skipRight);
                break;

            default:
                context.AddError(new StructuralError(
                                     StructuralError.ErrorType.InvalidOperator,
                                     $"Invalid boolean operator {op}",
                                     Start,
                                     End
                                     ));
                return;
            }

            if (!dropResult)
            {
                context.IL.Emit(OpCodes.Pop);
            }

            right.EmitCode(context, dropResult);
            context.IL.MarkLabel(skipRight);
        }
Beispiel #19
0
		/// <param name="st0"></param>
		/// <param name="nextState"></param>
		/// <param name="label"></param>
		/// <param name="kids">A list of trees.</param>
		/// <param name="path"></param>
		private void Reducer(Frame st0, StateRef nextState, LabelRef label, IReadOnlyList<IParseNode> kids, Path path)
		{
			var production = this.parseTable.Labels[label.Index].Production;

			Contract.Assert(!production.IsRecover);

			// t := application of a -> A to kids
			IParseNode t = ApplyProduction(production, kids, /* TODO */ 0, /* TODO */ 0, /* TODO */ false, /* TODO */ false);

			Frame st1 = GetActiveFrame(nextState);

			if (st1 != null)
			{
				// A stack with state nextState exists. Check for ambiguities.
				Link nl = st1.TryGetParentLink(st0);
				if (nl != null)
				{
					// There exists a direct link from st1 to st0.
					// TODO: Add `t` to the possiblities of the ambiguity node at `tree(nl)`
					if (production.IsReject)
						nl.Reject();

					// TODO: Can't modify a link.
					//nl.Label = t;
				}
				else
				{
					// There is no direct link from st1 to st0.
					nl = new Link(st0, t, path.Length);
					st1.Links.Add(nl);

					if (production.IsReject)
						nl.Reject();

					ActorOnActiveStacksOverNewLink(nl);
				}
			}
			else
			{
				// Found no existing stack frame with state nextState.
				st1 = new Frame(nextState);
				this.activeStacks.PushFront(st1);
				this.forActorDelayed.PushFront(st1);

				var nl = new Link(st0, t, path.Length);
				st1.Links.Add(nl);

				if (production.IsReject)
					nl.Reject();
			}
		}
 public void Emit(OpCode opCode, LabelRef labelRef)
 {
     generator.Emit(opCode, labelRef.label);
     AdjustStack(opCode);
 }
Beispiel #21
0
        public override void EmitCode(IBlockContext context, bool dropResult)
        {
            if (condition.ResultType(context) != BuiltinType.Bool)
            {
                context.AddError(
                    new StructuralError(
                        StructuralError.ErrorType.InvalidType,
                        "Condition of while is not a boolean",
                        Start,
                        End
                        )
                    );
            }

            IBlockContext tmpContext =
                context.CreateLoopContext(context.IL.DefineLabel(false), context.IL.DefineLabel(false));
            Dictionary <string, TO2Type> scopeVariables = condition.GetScopeVariables(tmpContext);

            if (scopeVariables != null)
            {
                foreach (var(name, type) in scopeVariables)
                {
                    tmpContext.DeclaredVariable(name, true, type.UnderlyingType(context.ModuleContext));
                }
            }

            ILCount conditionCount = condition.GetILCount(tmpContext, false);
            ILCount loopCount      = loopExpression.GetILCount(tmpContext, true);

            if (loopCount.stack > 0)
            {
                context.AddError(
                    new StructuralError(
                        StructuralError.ErrorType.CoreGeneration,
                        "Body of the while expression leaves values on stack. This must not happen",
                        Start,
                        End
                        )
                    );
                return;
            }

            if (context.HasErrors)
            {
                return;
            }

            using ITempLocalRef loopCounter = context.IL.TempLocal(typeof(int));
            LabelRef      whileStart  = context.IL.DefineLabel(conditionCount.opCodes + loopCount.opCodes < 110);
            LabelRef      whileEnd    = context.IL.DefineLabel(conditionCount.opCodes + loopCount.opCodes < 110);
            LabelRef      whileLoop   = context.IL.DefineLabel(conditionCount.opCodes + loopCount.opCodes < 100);
            IBlockContext loopContext = context.CreateLoopContext(whileStart, whileEnd);

            if (scopeVariables != null)
            {
                foreach (var(name, type) in scopeVariables)
                {
                    if (loopContext.FindVariable(name) != null)
                    {
                        loopContext.AddError(new StructuralError(
                                                 StructuralError.ErrorType.DuplicateVariableName,
                                                 $"Variable '{name}' already declared in this scope",
                                                 Start,
                                                 End
                                                 ));
                        return;
                    }

                    loopContext.DeclaredVariable(name, true, type.UnderlyingType(context.ModuleContext));
                }
            }

            loopContext.IL.Emit(whileStart.isShort ? OpCodes.Br_S : OpCodes.Br, whileStart);
            context.IL.MarkLabel(whileLoop);

            // Timeout check
            LabelRef skipCheck = context.IL.DefineLabel(true);

            loopCounter.EmitLoad(loopContext);
            loopContext.IL.Emit(OpCodes.Ldc_I4_1);
            loopContext.IL.Emit(OpCodes.Add);
            loopContext.IL.Emit(OpCodes.Dup);
            loopCounter.EmitStore(loopContext);
            loopContext.IL.Emit(OpCodes.Ldc_I4, 10000);
            loopContext.IL.Emit(OpCodes.Cgt);
            loopContext.IL.Emit(OpCodes.Brfalse, skipCheck);
            loopContext.IL.Emit(OpCodes.Ldc_I4_0);
            loopCounter.EmitStore(loopContext);
            context.IL.EmitCall(OpCodes.Call, typeof(Runtime.ContextHolder).GetMethod("CheckTimeout"), 0);
            loopContext.IL.MarkLabel(skipCheck);

            loopExpression.EmitCode(loopContext, true);
            loopContext.IL.MarkLabel(whileStart);
            condition.EmitCode(loopContext, false);

            loopContext.IL.Emit(whileLoop.isShort ? OpCodes.Brtrue_S : OpCodes.Brtrue, whileLoop);

            loopContext.IL.MarkLabel(whileEnd);
            if (!dropResult)
            {
                context.IL.Emit(OpCodes.Ldnull);
            }
        }
Beispiel #22
0
        public override void EmitCode(IBlockContext context, bool dropResult)
        {
            if (condition.ResultType(context) != BuiltinType.Bool)
            {
                context.AddError(
                    new StructuralError(
                        StructuralError.ErrorType.InvalidType,
                        "Condition of if is not a boolean",
                        Start,
                        End
                        )
                    );
                return;
            }

            IBlockContext thenContext = context.CreateChildContext();
            Dictionary <string, TO2Type> scopeVariables = condition.GetScopeVariables(thenContext);

            if (scopeVariables != null)
            {
                foreach (var(name, type) in scopeVariables)
                {
                    if (thenContext.FindVariable(name) != null)
                    {
                        thenContext.AddError(new StructuralError(
                                                 StructuralError.ErrorType.DuplicateVariableName,
                                                 $"Variable '{name}' already declared in this scope",
                                                 Start,
                                                 End
                                                 ));
                        return;
                    }

                    thenContext.DeclaredVariable(name, true, type.UnderlyingType(context.ModuleContext));
                }
            }

            ILCount thenCount = thenExpression.GetILCount(thenContext, true);

            if (!context.HasErrors && thenCount.stack > 0)
            {
                context.AddError(
                    new StructuralError(
                        StructuralError.ErrorType.CoreGeneration,
                        "Then expression leaves values on stack. This must not happen",
                        Start,
                        End
                        )
                    );
                return;
            }

            condition.EmitCode(thenContext, false);

            if (context.HasErrors)
            {
                return;
            }

            TO2Type thenResultType = thenExpression.ResultType(thenContext);

            if (dropResult)
            {
                LabelRef skipThen = context.IL.DefineLabel(thenCount.opCodes < 124);

                thenContext.IL.Emit(skipThen.isShort ? OpCodes.Brfalse_S : OpCodes.Brfalse, skipThen);
                thenExpression.EmitCode(thenContext, true);
                thenContext.IL.MarkLabel(skipThen);
            }
            else
            {
                OptionType optionType    = new OptionType(thenResultType);
                Type       generatedType = optionType.GeneratedType(thenContext.ModuleContext);
                using ITempLocalRef tempResult = thenContext.IL.TempLocal(generatedType);
                LabelRef skipThen = thenContext.IL.DefineLabel(thenCount.opCodes < 114);

                thenContext.IL.Emit(skipThen.isShort ? OpCodes.Brfalse_S : OpCodes.Brfalse, skipThen);
                thenExpression.Prepare(thenContext);
                tempResult.EmitLoadPtr(context);
                thenContext.IL.Emit(OpCodes.Dup);
                thenContext.IL.Emit(OpCodes.Initobj, generatedType, 1, 0);
                thenContext.IL.Emit(OpCodes.Dup);
                thenContext.IL.Emit(OpCodes.Ldc_I4_1);
                thenContext.IL.Emit(OpCodes.Stfld, generatedType.GetField("defined"));
                thenExpression.EmitCode(thenContext, false);
                thenContext.IL.Emit(OpCodes.Stfld, generatedType.GetField("value"));
                LabelRef ifEnd = context.IL.DefineLabel(true);
                thenContext.IL.Emit(OpCodes.Br_S, ifEnd);

                thenContext.IL.MarkLabel(skipThen);

                tempResult.EmitLoadPtr(context);
                thenContext.IL.Emit(OpCodes.Initobj, generatedType, 1, 0);

                thenContext.IL.MarkLabel(ifEnd);

                tempResult.EmitLoad(thenContext);
            }
        }
Beispiel #23
0
		/// <summary>
		/// Reduces the specified stack frame 
		/// </summary>
		/// <param name="stack"></param>
		/// <param name="label"></param>
		public void DoReductions(Frame stack, LabelRef label)
		{
			DoLimitedReductions(stack, label, null);
		}
Beispiel #24
0
		/// <summary>
		/// Gets the label that corresponds to the specified label reference.
		/// </summary>
		/// <param name="labelRef">The label reference.</param>
		/// <returns>The corresponding <see cref="Label"/>.</returns>
		private Label GetLabel(LabelRef labelRef)
		{
			#region Contract
			Contract.Ensures(Contract.Result<Label>() != null);
			#endregion

			return this.parseTable.Labels[labelRef.Index];
		}
Beispiel #25
0
 public void MarkLabel(LabelRef label)
 {
 }
Beispiel #26
0
        public override void EmitCode(IBlockContext context, bool dropResult)
        {
            if (condition.ResultType(context) != BuiltinType.Bool)
            {
                context.AddError(
                    new StructuralError(
                        StructuralError.ErrorType.InvalidType,
                        "Condition of if is not a boolean",
                        Start,
                        End
                        )
                    );
                return;
            }

            IBlockContext thenContext = context.CreateChildContext();
            IBlockContext elseContext = context.CreateChildContext();

            Dictionary <string, TO2Type> scopeVariables = condition.GetScopeVariables(thenContext);

            if (scopeVariables != null)
            {
                foreach (var(name, type) in scopeVariables)
                {
                    if (thenContext.FindVariable(name) != null)
                    {
                        thenContext.AddError(new StructuralError(
                                                 StructuralError.ErrorType.DuplicateVariableName,
                                                 $"Variable '{name}' already declared in this scope",
                                                 Start,
                                                 End
                                                 ));
                        return;
                    }

                    thenContext.DeclaredVariable(name, true, type.UnderlyingType(context.ModuleContext));
                }
            }

            ILCount thenCount = thenExpression.GetILCount(thenContext, dropResult);
            ILCount elseCount = elseExpression.GetILCount(elseContext, dropResult);

            if (!context.HasErrors && thenCount.stack > 1)
            {
                context.AddError(
                    new StructuralError(
                        StructuralError.ErrorType.CoreGeneration,
                        "Then expression leaves too many values on stack. This must not happen",
                        Start,
                        End
                        )
                    );
                return;
            }

            if (!context.HasErrors && elseCount.stack > 1)
            {
                context.AddError(
                    new StructuralError(
                        StructuralError.ErrorType.CoreGeneration,
                        "Else expression leaves too many values on stack. This must not happen",
                        Start,
                        End
                        )
                    );
                return;
            }

            condition.EmitCode(thenContext, false);

            if (context.HasErrors)
            {
                return;
            }

            TO2Type thenType = thenExpression.ResultType(thenContext);
            TO2Type elseType = elseExpression.ResultType(elseContext);

            if (!dropResult)
            {
                if (!thenType.IsAssignableFrom(context.ModuleContext, elseType))
                {
                    context.AddError(new StructuralError(
                                         StructuralError.ErrorType.IncompatibleTypes,
                                         $"If condition has incompatible result {thenType} != {elseType}",
                                         Start,
                                         End
                                         ));
                }
            }

            if (context.HasErrors)
            {
                return;
            }

            LabelRef thenEnd = context.IL.DefineLabel(thenCount.opCodes < 124);
            LabelRef elseEnd = context.IL.DefineLabel(elseCount.opCodes < 124);

            context.IL.Emit(thenEnd.isShort ? OpCodes.Brfalse_S : OpCodes.Brfalse, thenEnd);
            thenExpression.EmitCode(thenContext, dropResult);
            context.IL.Emit(elseEnd.isShort ? OpCodes.Br_S : OpCodes.Br, elseEnd);
            context.IL.MarkLabel(thenEnd);
            if (!dropResult)
            {
                context.IL.AdjustStack(-1);              // Then leave its result on the stack, so is else supposed to
            }
            elseExpression.EmitCode(elseContext, dropResult);
            if (!dropResult)
            {
                thenType.AssignFrom(context.ModuleContext, elseType).EmitConvert(context);
            }
            context.IL.MarkLabel(elseEnd);
        }
Beispiel #27
0
        private object OnLabelRef(LabelRef labelRef)
        {
            INiCommandBarControl control;
            ErrorUtil.ThrowOnFailure(_commandManager.FindCommandBarControl(
                labelRef.Guid,
                out control
            ));

            if (control == null)
                throw new NetIdeException(String.Format(NeutralResources.CannotFindCommand, labelRef.Guid));

            return control;
        }
Beispiel #28
0
		private ITerm GetProduction(LabelRef label)
		{
			return this.parseTable.Labels[label.Index].Production;
		}