private static IIntermediateClassMethodMember AddPushMethod(IIntermediateClassType result, IIntermediateClassFieldMember charBufferSize, IIntermediateClassFieldMember charBuffer, IIntermediateClassMethodMember growBufferMethod, IIntermediateCliManager identityManager)
        {
            /* *
             * Full Method:
             * if (buffer == null)
             *     GrowBuffer(2);
             * else if (buffer.Length < actualSize + 1)
             *     GrowBuffer(actualSize + 1);
             * buffer[actualSize] = c;
             * actualSize++;
             * */
            IIntermediateClassMethodMember pushMethod = result.Methods.Add(new TypedName("Push", identityManager.ObtainTypeReference(RuntimeCoreType.VoidType)));

            pushMethod.AccessLevel = AccessLevelModifiers.Public;
            var cParameter = pushMethod.Parameters.Add(new TypedName("c", identityManager.ObtainTypeReference(RuntimeCoreType.Char)));
//          if (buffer == null)
            var nullCheck = pushMethod.If(charBuffer.EqualTo(IntermediateGateway.NullValue));

//              GrowBuffer(2);
            nullCheck.Call(growBufferMethod.GetReference().Invoke(2.ToPrimitive()));
//          else if (buffer.Length < actualSize + 1)
            nullCheck.CreateNext(charBuffer.GetReference().GetProperty("Length").LessThan(charBufferSize.GetReference().Add(1.ToPrimitive())));
            var rangeCheck = (IConditionBlockStatement)nullCheck.Next;

//              GrowBuffer(actualSize + 1);
            rangeCheck.Call(growBufferMethod.GetReference().Invoke(charBufferSize.GetReference().Add(1.ToPrimitive())));
//          buffer[actualSize++] = c;
            pushMethod.Assign(charBuffer.GetReference().GetIndexer(charBufferSize.Increment()), cParameter.GetReference());
            return(pushMethod);
        }
        private static IIntermediateClassMethodMember AddPushStringMethod(IIntermediateClassType result, IIntermediateClassFieldMember charBufferSize, IIntermediateClassFieldMember charBuffer, IIntermediateClassMethodMember growBufferMethod, IIntermediateCliManager identityManager)
        {
            /* *
             * Full Method:
             * if (buffer == null)
             *     GrowBuffer(s.Length);
             * else if (buffer.Length < actualSize + s.Length)
             *     GrowBuffer(actualSize + s.Length);
             * for (int i = 0; i < s.Length; i++)
             * {
             *     buffer[actualSize] = s[i];
             *     actualSize++;
             * }
             * */
            IIntermediateClassMethodMember pushStringMethod = result.Methods.Add(new TypedName("Push", identityManager.ObtainTypeReference(RuntimeCoreType.VoidType)));

            pushStringMethod.AccessLevel = AccessLevelModifiers.Public;
            var sParameter = pushStringMethod.Parameters.Add(new TypedName("s", identityManager.ObtainTypeReference(RuntimeCoreType.String)));
//          if (buffer == null)

            var nullCheck = pushStringMethod.If(charBuffer.GetReference().EqualTo(IntermediateGateway.NullValue));

//              GrowBuffer(s.Length);
            nullCheck.Call(growBufferMethod.GetReference().Invoke(sParameter.GetReference().GetProperty("Length")));
//          else if (buffer.Length < actualSize + s.Length)
            nullCheck.CreateNext(charBuffer.GetReference().GetProperty("Length").LessThan(charBufferSize.GetReference().Add(sParameter.GetReference().GetProperty("Length"))));
            var rangeCheck = (IConditionBlockStatement)nullCheck.Next;

//              GrowBuffer(actualSize + s.Length);
            rangeCheck.Call(growBufferMethod.GetReference().Invoke(charBufferSize.GetReference().Add(sParameter.GetReference().GetProperty("Length"))));

            //int i = 0;
            var iLocal = pushStringMethod.Locals.Add(new TypedName("i", identityManager.ObtainTypeReference(RuntimeCoreType.Int32)));

            //So it isn't declared in the main body.
            iLocal.InitializationExpression = IntermediateGateway.NumberZero;
            iLocal.AutoDeclare = false;
            //i++
//          for (int i = 0; i < s.Length; i++)
//          {
            var sToBufferIterate = pushStringMethod.Iterate(iLocal.GetDeclarationStatement(), iLocal.LessThan(sParameter.GetReference().GetProperty("Length")), new IStatementExpression[] { iLocal.Increment() });

            //var sToBufferIterate = pushStringMethod.Iterate(iLocal.GetDeclarationStatement(), IntermediateGateway.NumberZero, sParameter.GetReference().GetProperty("Length"));
//              buffer[actualSize++] = s[i];
            sToBufferIterate.Assign(charBuffer.GetReference().GetIndexer(charBufferSize.Increment()), sParameter.GetReference().GetIndexer(iLocal.GetReference()));
//          }
            return(pushStringMethod);
        }
Exemple #3
0
        private void BuildGetValidSyntax(ParserCompiler compiler, ParserBuilder parserBuilder, IIntermediateCliManager identityManager)
        {
            bool lexicallyAmbiguousModel = compiler._GrammarSymbols.AmbiguousSymbols.Count() > 0;
            var  advanceAdapters         =
                compiler
                .AdvanceMachines.Values
                .Select(k => k.All)
                .DefaultIfEmpty().Aggregate(
                    (a, b) =>
                    a.Concat(b));

            if (advanceAdapters == null)
            {
                advanceAdapters = new PredictionTreeDFAdapter[0];
            }
            var adapters              = compiler.FollowAdapters.Select(k => k.Value.AssociatedState).Concat(compiler.AllRuleAdapters.Select(k => k.Value.AssociatedState)).Concat(advanceAdapters.DefaultIfEmpty().Where(k => k != null).Select(k => k.AssociatedState)).Distinct().OrderBy(k => k.StateValue).ToArray();
            var distinctStateValues   = adapters.Select(k => k.StateValue).Distinct().ToArray();
            var stateSymbolStoreEntry =
                (from state in adapters
                 /* Since the other adapters are state-machines derived from the projection of a given state of a rule, normal adapters (derived from non-expanded lookahead) must be aggregated */
                 join normalAdapter in compiler.AllRuleAdapters on state equals normalAdapter.Value.AssociatedState into normalVariantSet
                 from normalAdapter in normalVariantSet.DefaultIfEmpty()
                 let fc = (normalAdapter.Value == null || normalAdapter.Value.OutgoingTransitions.Count == 0 || normalAdapter.Value.AssociatedContext.Leaf.LookAhead.Count == 0) ? state.OutTransitions.FullCheck : normalAdapter.Value.AssociatedContext.Leaf.LookAhead.Keys.Aggregate(GrammarVocabulary.UnionAggregateDelegate)
                          group new { State = state, Grammar = fc, GrammarStore = compiler.LexicalSymbolModel.GenerateSymbolstoreVariation(fc) } by new { Grammar = fc, IsEdge = state.IsEdge }).ToDictionary(k => k.Key, v => v.ToArray());
            var stateParam  = _getValidSyntaxMethodInternalImpl.Parameters["state"];
            var ruleContext = _getValidSyntaxMethodInternalImpl.Parameters["ruleContext"];
            var initialPass = _getValidSyntaxMethodInternalImpl.Parameters["initialPass"];

            if (!lexicallyAmbiguousModel)
            {
                _getValidSyntaxMethodInternalImpl.Parameters.Remove(initialPass);
                initialPass = null;
            }

            _getValidSyntaxMethodImpl.AccessLevel = AccessLevelModifiers.Public;

            var getSyntaxMethodImplInvocation = _getValidSyntaxMethodInternalImpl.GetReference().Invoke(parserBuilder._StateImpl.GetReference(), parserBuilder._CurrentContextImpl.GetReference());

            _getValidSyntaxMethodImpl.Return(getSyntaxMethodImplInvocation);
            if (lexicallyAmbiguousModel)
            {
                getSyntaxMethodImplInvocation.Arguments.Add(IntermediateGateway.TrueValue);
            }
            ITypedLocalMember pushAmbiguityContext = null;

            if (lexicallyAmbiguousModel)
            {
                pushAmbiguityContext = _getValidSyntaxMethodInternalImpl.Locals.Add(
                    new TypedName("pushAmbiguityContext", RuntimeCoreType.Boolean, identityManager),
                    IntermediateGateway.FalseValue);
            }

            ITypedLocalMember validResult = null;

            if (lexicallyAmbiguousModel)
            {
                validResult = _getValidSyntaxMethodInternalImpl.Locals.Add(
                    new TypedName("result", compiler.LexicalSymbolModel.ValidSymbols),
                    this._getValidSyntaxMethodInternalImpl.ReturnType.GetNewExpression());
            }

            var switchStatement = this._getValidSyntaxMethodInternalImpl.Switch(stateParam.GetReference());

            foreach (var uniqueGrammarSet in stateSymbolStoreEntry.Keys)
            {
                var           currentSet   = stateSymbolStoreEntry[uniqueGrammarSet];
                IExpression[] stateIndices = new IExpression[currentSet.Length];
                currentSet = currentSet.OrderBy(k => k.State.StateValue).ToArray();
                for (int stateIndex = 0; stateIndex < currentSet.Length; stateIndex++)
                {
                    stateIndices[stateIndex] = currentSet[stateIndex].State.StateValue.ToPrimitive();
                }

                var currentCase = switchStatement.Case(stateIndices);
                currentCase.Comment(currentSet[0].Grammar.ToString());
                if (uniqueGrammarSet.IsEdge)
                {
                    //Inject logic to look up in the stack.
                    if (lexicallyAmbiguousModel)
                    {
                        var nullCheck = currentCase.If(ruleContext.InequalTo(IntermediateGateway.NullValue));
                        nullCheck.Assign(validResult.GetReference(), currentSet[0].GrammarStore.GetReference().BitwiseOr(_getValidSyntaxMethodInternalImpl.GetReference().Invoke(compiler.RuleSymbolBuilder.FollowState.GetReference(ruleContext.GetReference()), compiler.RuleSymbolBuilder.Parent.GetReference(ruleContext.GetReference()), IntermediateGateway.FalseValue)));
                        nullCheck.If(initialPass.GetReference())
                        .Assign(pushAmbiguityContext.GetReference(), IntermediateGateway.TrueValue);
                        nullCheck.CreateNext();
                        nullCheck.Next.Assign(validResult.GetReference(), currentSet[0].GrammarStore.GetReference());
                    }
                    else
                    {
                        var nullCheck = currentCase.If(ruleContext.InequalTo(IntermediateGateway.NullValue));
                        nullCheck.Return(currentSet[0].GrammarStore.GetReference().BitwiseOr(_getValidSyntaxMethodInternalImpl.GetReference().Invoke(compiler.RuleSymbolBuilder.FollowState.GetReference(ruleContext.GetReference()), compiler.RuleSymbolBuilder.Parent.GetReference(ruleContext.GetReference()))));
                        nullCheck.CreateNext();
                        nullCheck.Next.Return(currentSet[0].GrammarStore.GetReference());
                    }
                }
                else if (lexicallyAmbiguousModel)
                {
                    currentCase.Assign(validResult.GetReference(), currentSet[0].GrammarStore.GetReference());
                }
                else
                {
                    currentCase.Return(currentSet[0].GrammarStore.GetReference());
                }
            }
            if (lexicallyAmbiguousModel)
            {
                this._getValidSyntaxMethodInternalImpl.If(pushAmbiguityContext.GetReference())
                .Assign(validResult.GetReference(), AssignmentOperation.BitwiseOrAssign,
                        _cullAmbiguities.GetReference().Invoke(validResult.GetReference()));
            }
            if (lexicallyAmbiguousModel)
            {
                this._getValidSyntaxMethodInternalImpl.Return(validResult.GetReference());
            }
            else
            {
                this._getValidSyntaxMethodInternalImpl.Return(this._getValidSyntaxMethodInternalImpl.ReturnType.GetNewExpression());
            }
            this._getValidSyntaxMethodInternalImpl.AccessLevel = AccessLevelModifiers.Private;
        }