Exemplo n.º 1
0
        private static void SubstituteRuleMask(MethodInfo method, List <CilSymbolRef> parts, CilSymbolRef[] ruleMask)
        {
            int maskLength = ruleMask.Length;
            int paramCount = method.GetParameters().Length;

            for (int i = 0, paramIndex = 0; i != maskLength || paramIndex != paramCount;)
            {
                if (paramIndex == paramCount)
                {
                    // Mask has keywords after parameters
                    if (ruleMask[i] == null)
                    {
                        throw new InvalidOperationException("Insufficient parameters to substitute literal-mask slot #" + i);
                    }

                    parts.Add(ruleMask[i]);
                }
                else if (i == maskLength || ruleMask[i] == null)
                {
                    // Mask slot or there are parameters after mask
                    var p = method.GetParameters()[paramIndex++];
                    parts.Add(CilSymbolRef.Create(p.ParameterType));
                }
                else
                {
                    // Add keyword from the rule mask
                    parts.Add(ruleMask[i]);
                }

                if (i != maskLength)
                {
                    ++i;
                }
            }
        }
Exemplo n.º 2
0
        public void Test()
        {
            var tokens = new []
            {
                CilSymbolRef.Create("foo"),
                CilSymbolRef.Create("bar"),
                CilSymbolRef.Create("other"),
                CilSymbolRef.Create(typeof(string)),
                CilSymbolRef.Create(typeof(string), "foo"),   // links foo and string
                CilSymbolRef.Create(typeof(string), "bar"),   // links bar and string
                CilSymbolRef.Create(typeof(string), "other"), // links other and string
            };

            foreach (var token in tokens)
            {
                target.Link(token);
            }

            Assert.AreEqual(1, target.Definitions.Count());

            var SYM1 = new Symbol("123");

            target.Resolve(tokens[0]).Symbol = SYM1;
            for (int i = 1; i != tokens.Length; ++i)
            {
                var context = "#" + i;
                Assert.AreSame(SYM1, target.GetSymbol(tokens[i]), context);
            }
        }
        private void LdTid(EmitSyntax emit, CilSymbolRef tid)
        {
            if (tid.Type != null)
            {
                emit
                .Ldtoken(emit.Types.Import(tid.Type))
                .Call((RuntimeTypeHandle h) => Type.GetTypeFromHandle(h))
                ;
            }
            else
            {
                emit.Ldnull();
            }

            if (tid.Literal == null)
            {
                emit.Ldnull();
            }
            else
            {
                emit.Ldstr(new QStr(tid.Literal));
            }

            emit
            .Newobj(() => new CilSymbolRef(default(Type), default(string)));
        }
Exemplo n.º 4
0
        protected bool DetectThisAsToken(List <CilSymbolRef> parts)
        {
            if (HasThisAsSymbol)
            {
                parts.Add(CilSymbolRef.Create(Member.DeclaringType));
                return(true);
            }

            return(false);
        }
 public IEnumerable <CilProduction> GetProductions(IEnumerable <CilSymbolRef> leftSides)
 {
     foreach (var leftSide in leftSides.ToArray())
     {
         yield return(new CilProduction(
                          outcome: CilSymbolRef.Create(typeof(void)),
                          pattern: new[] { CilSymbolRef.Create(typeof(int)) },
                          context: CilContextRef.None,
                          actionBuilder: code => code.Emit(il => il.Ldnull().Ret())));
     }
 }
        public void LanguageDescriptorCollectDataFromTypeMetadata()
        {
            ILogging logging = new MemoryLogging();
            var      target  = new CilGrammar(new CilGrammarSource(typeof(IMetadtaTest0)), logging);

            Assert.AreEqual(CilSymbolRef.Create(typeof(void)), target.Start);
            Assert.AreEqual(2, target.SymbolResolver.Definitions.Count());
            Assert.AreEqual(
                new [] { typeof(void), typeof(int) },
                target.SymbolResolver.Definitions.Select(def => def.Type).ToArray());
        }
Exemplo n.º 7
0
        protected override CilSymbolRef[] DoGetRuleMask(MethodInfo methodInfo)
        {
            var resultList = new List <CilSymbolRef>();

            resultList.AddRange(
                Enumerable.Repeat(default(CilSymbolRef),
                                  methodInfo.GetParameters().Length));

            resultList.Add(CilSymbolRef.Create(StemScanner.RParen));

            return(resultList.ToArray());;
        }
Exemplo n.º 8
0
        protected CilSymbolRef GetThisSymbol()
        {
            if (HasThisAsSymbol)
            {
                if (Parent != null && Parent.Member is Type)
                {
                    return(CilSymbolRef.Create((Type)Parent.Member));
                }

                return(CilSymbolRef.Create(Member.DeclaringType));
            }

            return(null);
        }
Exemplo n.º 9
0
        protected override CilSymbolRef[] DoGetRuleMask(MethodInfo methodInfo)
        {
            int placeholderCount             = KeywordMask.Count(item => item == null);
            int nonPlaceholderParameterCount = methodInfo.GetParameters().Length - placeholderCount;

            if (nonPlaceholderParameterCount < 0)
            {
                throw new InvalidOperationException("Insufficient rule-method arguments in " + this);
            }

            return(KeywordMask
                   .Select(item => item == null ? null : CilSymbolRef.Create(item))
                   .ToArray());
        }
Exemplo n.º 10
0
        public override IEnumerable <CilSymbolFeature <CilContextProvider> > GetLocalContextProviders()
        {
            if (Parent == null)
            {
                var type = (Type)Member;
                return(new[]
                {
                    new CilSymbolFeature <CilContextProvider>(
                        CilSymbolRef.Create(type),
                        new CilContextProvider(type))
                });
            }

            return(new CilSymbolFeature <CilContextProvider> [0]);
        }
Exemplo n.º 11
0
        public override IEnumerable <CilSymbolRef> GetSymbolsInCategory(SymbolCategory requestedCategories)
        {
            if ((requestedCategories & this.categories) == 0)
            {
                return(Enumerable.Empty <CilSymbolRef>());
            }

            if (Text == null)
            {
                return(new[] { CilSymbolRef.Create(TokenType) });
            }
            else
            {
                return(new[] { CilSymbolRef.Create(Text) });
            }
        }
Exemplo n.º 12
0
        public override IEnumerable <CilSymbolRef> GetSymbolsInCategory(SymbolCategory category)
        {
            if ((category & SymbolCategory.ExplicitlyUsed) != SymbolCategory.ExplicitlyUsed)
            {
                return(Enumerable.Empty <CilSymbolRef>());
            }

            if (Text == null)
            {
                return(new[] { CilSymbolRef.Create(TokenType) });
            }
            else
            {
                return(new[] { CilSymbolRef.Create(Text) });
            }
        }
Exemplo n.º 13
0
        private CilSymbolRef[] GetProducedTokens()
        {
            List <CilSymbolRef> resultList = new List <CilSymbolRef>();

            if (LiteralText != null)
            {
                resultList.Add(CilSymbolRef.Create(LiteralText));
            }

            if (TokenType != null)
            {
                resultList.Add(CilSymbolRef.Create(TokenType));
            }

            return(resultList.ToArray());
        }
        public CilSymbol Resolve(CilSymbolRef symbolRef)
        {
            if (symbolRef == null)
            {
                return null;
            }

            var literalDef   = ResolveLiteral(symbolRef.Literal);
            var tokenTypeDef = ResolveTokenType(symbolRef.Type);

            if (literalDef != null && tokenTypeDef != null && literalDef != tokenTypeDef)
            {
                throw new InvalidOperationException("Unable to resolve conflicting token reference: " + symbolRef);
            }

            return literalDef ?? tokenTypeDef;
        }
Exemplo n.º 15
0
        public override IEnumerable <CilSymbolFeature <Precedence> > GetSymbolPrecedence()
        {
            CilSymbolRef token;

            if (TermText == null)
            {
                token = CilSymbolRef.Create(TermType);
            }
            else
            {
                token = CilSymbolRef.Create(TermText);
            }

            yield return(new CilSymbolFeature <Precedence>(
                             token,
                             new Precedence(PrecedenceValue, Associativity)));
        }
Exemplo n.º 16
0
        public override IEnumerable <CilMerger> GetMergers(IEnumerable <CilSymbolRef> leftSides)
        {
            var returnToken = CilSymbolRef.Create(Method.ReturnType);

            if (!leftSides.Contains(returnToken))
            {
                return(new CilMerger[0]);
            }

            var type   = Method.ReturnType;
            var method = Method;

            return(new []
            {
                new CilMerger
                {
                    Symbol = returnToken,
                    Context = GetContext(),
                    ActionBuilder = code =>
                    {
                        code = code.LdMergerOldValue();
                        if (type.IsValueType)
                        {
                            code = code.Emit(il => il.Unbox_Any(il.Types.Import(type)));
                        }

                        code = code.LdMergerNewValue();
                        if (type.IsValueType)
                        {
                            code = code.Emit(il => il.Unbox_Any(il.Types.Import(type)));
                        }

                        code = code
                               .Emit(il => il.Call(il.Methods.Import(method)));

                        if (type.IsValueType)
                        {
                            code = code.Emit(il => il.Box(il.Types.Import(type)));
                        }

                        return code;
                    }
                }
            });
        }
Exemplo n.º 17
0
        protected override CilSymbolRef[] DoGetRuleMask(MethodInfo methodInfo)
        {
            var resultList = new List <CilSymbolRef>();

            int nonMaskParameterCount = methodInfo.GetParameters().Length - KeywordMask.Count(item => item == null);

            if (nonMaskParameterCount < 0)
            {
                throw new InvalidOperationException("Insufficient rule-method arguments.");
            }

            resultList.Add(CilSymbolRef.Create(StemScanner.LParen));

            resultList.AddRange(
                KeywordMask
                .Select(item => item == null ? null : CilSymbolRef.Create(item)));

            return(resultList.ToArray());
        }
Exemplo n.º 18
0
        private IEnumerable <CilProduction> GetExpansionRules(CilSymbolRef token)
        {
            if (token.HasLiteral)
            {
                return(Enumerable.Empty <CilProduction>());
            }

            var        method   = this.Method;
            var        pattern  = new TypePattern(method);
            MethodInfo producer = pattern.MakeProducer(token.Type);

            if (producer != null)
            {
                return(DoGetRules(producer, token));
            }
            else
            {
                return(Enumerable.Empty <CilProduction>());
            }
        }
        private CilSymbol Ensure(CilSymbolRef symbolRef)
        {
            CilSymbol literalDef = ResolveLiteral(symbolRef.Literal);
            CilSymbol typeDef    = ResolveTokenType(symbolRef.Type);
            CilSymbol def        = MergeDefs(literalDef, typeDef);

            if (def == null)
            {
                 def = new CilSymbol();
            }
            else if (symbolRef.Type != null && def.Type != null && def.Type != symbolRef.Type)
            {
                throw new InvalidOperationException("Incompatible symbol constraints.");
            }

            // Add token to a defintion
            if (symbolRef.Type != null)
            {
                def.Type = symbolRef.Type;
            }

            if (symbolRef.HasLiteral)
            {
                def.Literals.Add(symbolRef.Literal);
            }

            // Update index
            foreach (var literal in def.Literals)
            {
                ref2def[literal] = def;
            }

            if (def.Type != null)
            {
                ref2def[def.Type] = def;
            }

            return def;
        }
Exemplo n.º 20
0
        protected IEnumerable <CilProduction> DoGetRules(MethodInfo method, CilSymbolRef leftSide)
        {
            var outcome = CilSymbolRef.Create(method.ReturnType);

            if (!object.Equals(outcome, leftSide))
            {
                return(Enumerable.Empty <CilProduction>());
            }

            var pattern  = new List <CilSymbolRef>();
            int argShift = 0;

            CilSymbolRef thisSymbol = GetThisSymbol();

            if (thisSymbol != null)
            {
                ++argShift;
                pattern.Add(thisSymbol);
            }

            var ruleMask = DoGetRuleMask(method);

            SubstituteRuleMask(method, pattern, ruleMask);

            var rule = new CilProduction(
                outcome:    outcome,
                pattern:    pattern,
                precedence: GetPrecedence(),
                context:    GetContext(method, thisSymbol != null),
                actionBuilder:
                code =>
            {
                if (thisSymbol != null)
                {
                    code.LdActionArgument(0, method.DeclaringType);
                }

                // Pass rule-arguments to the rule-method
                for (int i = 0; i != method.GetParameters().Length; ++i)
                {
                    var param        = method.GetParameters()[i];
                    int ruleArgIndex = NthEmptySlotIndex(ruleMask, i);
                    if (thisSymbol != null)
                    {
                        ++ruleArgIndex;
                    }

                    code.LdActionArgument(ruleArgIndex, param.ParameterType);
                }

                code.Emit(
                    il =>
                {
                    il.Call(method);

                    if (method.ReturnType == typeof(void))
                    {
                        il.Ldnull();
                    }
                    else if (method.ReturnType.IsValueType)
                    {
                        il.Box(il.Types.Import(method.ReturnType));
                    }

                    return(il);
                });

                return(code);
            });

            return(new[] { rule });
        }
Exemplo n.º 21
0
 public CilSymbolFeature(CilSymbolRef symbolRef, T value)
 {
     this._symbolRef = symbolRef;
     this._value     = value;
 }
Exemplo n.º 22
0
        public override IEnumerable <CilMatcher> GetMatchers()
        {
            var tokenType         = Method.ReturnType;
            var nextConditionType = GetNextConditionType();

            var matcher = new CilMatcher();

            var contextType = GetContextType();

            //var context = CilContextRef.ByType(contextType);

            if (tokenType != typeof(void))
            {
                var outcome = CilSymbolRef.Create(tokenType, LiteralText);
                matcher.MainOutcome = outcome;
                matcher.AllOutcomes.Add(outcome);
            }

            matcher.DefiningMethod = Method;
            matcher.Disambiguation = Disambiguation;
            if (LiteralText == null)
            {
                matcher.Pattern = ScanPattern.CreateRegular(Pattern, RegexPattern);
            }
            else
            {
                matcher.Pattern = ScanPattern.CreateLiteral(LiteralText);
            }

            var parameters = Method.GetParameters().ToList();

            matcher.Context           = GetContext();
            matcher.NextConditionType = nextConditionType;
            matcher.ActionBuilder     =
                code =>
            {
                ParameterInfo nextModeParameter;
                if (parameters.Count != 0 && parameters.Last().IsOut)
                {
                    nextModeParameter = parameters.Last();
                    parameters.RemoveAt(parameters.Count - 1);
                }
                else
                {
                    nextModeParameter = null;
                }

                if (parameters.Count == 0)
                {
                }
                else if (parameters.Count == 1 &&
                         parameters[0].ParameterType == typeof(string))
                {
                    code.LdMatcherTokenString();
                }
                else if (parameters.Count == 3 &&
                         parameters[0].ParameterType == typeof(char[]) &&
                         parameters[1].ParameterType == typeof(int) &&
                         parameters[2].ParameterType == typeof(int))
                {
                    code
                    .LdMatcherBuffer()
                    .LdMatcherStartIndex()
                    .LdMatcherLength();
                }
                else
                {
                    throw new InvalidOperationException(
                              "Unsupported match-method signature: "
                              + string.Join(", ", parameters.Select(p => p.ParameterType.Name)));
                }

                Ref <Locals> nextModeVar = null;
                if (nextModeParameter != null)
                {
                    code
                    .Emit(il =>
                    {
                        nextModeVar = il.Locals.Generate().GetRef();
                        return(il
                               .Local(nextModeVar.Def, il.Types.Object)
                               .Ldloca(nextModeVar));
                    });
                }

                code.Emit(il => il.Call(Method));

                if (nextModeParameter != null)
                {
                    code
                    .Emit(il => il.Ldloc(nextModeVar))
                    .ChangeCondition(nextConditionType);
                }

                if (Method.ReturnType == typeof(void))
                {
                    code.SkipAction();
                }
                else
                {
                    if (Method.ReturnType.IsValueType)
                    {
                        code.Emit(il => il.Box(il.Types.Import(Method.ReturnType)));
                    }

                    code
                    .ReturnFromAction()
                    ;
                }

                return(code);
            };


            return(new[] { matcher });
        }
 public void Link(CilSymbolRef first)
 {
     Ensure(first);
 }
 public Symbol GetSymbol(CilSymbolRef tid)
 {
     CilSymbol def = Resolve(tid);
     return def == null ? null : def.Symbol;
 }
 public bool Contains(CilSymbolRef symbolRef)
 {
     return symbolRef != null
         && (ResolveLiteral(symbolRef.Literal) != null
             || ResolveTokenType(symbolRef.Type) != null);
 }
Exemplo n.º 26
0
        protected IEnumerable<CilProduction> DoGetRules(MethodInfo method, CilSymbolRef leftSide)
        {
            var outcome = CilSymbolRef.Create(method.ReturnType);

            if (!object.Equals(outcome, leftSide))
            {
                return Enumerable.Empty<CilProduction>();
            }

            var pattern = new List<CilSymbolRef>();
            int argShift = 0;

            CilSymbolRef thisSymbol = GetThisSymbol();
            if (thisSymbol != null)
            {
                ++argShift;
                pattern.Add(thisSymbol);
            }

            var ruleMask = DoGetRuleMask(method);

            SubstituteRuleMask(method, pattern, ruleMask);

            var rule = new CilProduction(
                outcome:    outcome,
                pattern:    pattern,
                precedence: GetPrecedence(),
                context:    GetContext(method, thisSymbol != null),
                actionBuilder:
                    code =>
                    {
                        if (thisSymbol != null)
                        {
                            code.LdActionArgument(0, method.DeclaringType);
                        }

                        // Pass rule-arguments to the rule-method
                        for (int i = 0; i != method.GetParameters().Length; ++i)
                        {
                            var param = method.GetParameters()[i];
                            int ruleArgIndex = NthEmptySlotIndex(ruleMask, i);
                            if (thisSymbol != null)
                            {
                                ++ruleArgIndex;
                            }

                            code.LdActionArgument(ruleArgIndex, param.ParameterType);
                        }

                        code.Emit(
                            il =>
                            {
                                il.Call(method);

                                if (method.ReturnType == typeof(void))
                                {
                                    il.Ldnull();
                                }
                                else if (method.ReturnType.IsValueType)
                                {
                                    il.Box(il.Types.Import(method.ReturnType));
                                }

                                return il;
                            });

                        return code;
                    });

            return new[] { rule };
        }
Exemplo n.º 27
0
        private IEnumerable<CilProduction> GetExpansionRules(CilSymbolRef token)
        {
            if (token.HasLiteral)
            {
                return Enumerable.Empty<CilProduction>();
            }

            var method = this.Method;
            var pattern = new TypePattern(method);
            MethodInfo producer = pattern.MakeProducer(token.Type);
            if (producer != null)
            {
                return DoGetRules(producer, token);
            }
            else
            {
                return Enumerable.Empty<CilProduction>();
            }
        }
Exemplo n.º 28
0
        private static void SubstituteRuleMask(MethodInfo method, List<CilSymbolRef> parts, CilSymbolRef[] ruleMask)
        {
            int maskLength = ruleMask.Length;
            int paramCount = method.GetParameters().Length;

            for (int i = 0, paramIndex = 0; i != maskLength || paramIndex != paramCount; )
            {
                if (paramIndex == paramCount)
                {
                    // Mask has keywords after parameters
                    if (ruleMask[i] == null)
                    {
                        throw new InvalidOperationException("Insufficient parameters to substitute literal-mask slot #" + i);
                    }

                    parts.Add(ruleMask[i]);
                }
                else if (i == maskLength || ruleMask[i] == null)
                {
                    // Mask slot or there are parameters after mask
                    var p = method.GetParameters()[paramIndex++];
                    parts.Add(CilSymbolRef.Create(p.ParameterType));
                }
                else
                {
                    // Add keyword from the rule mask
                    parts.Add(ruleMask[i]);
                }

                if (i != maskLength)
                {
                    ++i;
                }
            }
        }
Exemplo n.º 29
0
        private static int NthEmptySlotIndex(CilSymbolRef[] ruleMask, int n)
        {
            int i = 0;
            for (; i != ruleMask.Length; ++i)
            {
                if (ruleMask[i] == null)
                {
                    if (n == 0)
                    {
                        return i;
                    }

                    --n;
                }
            }

            return i + n;
        }
        private void LdTid(EmitSyntax emit, CilSymbolRef tid)
        {
            if (tid.Type != null)
            {
                emit
                    .Ldtoken(emit.Types.Import(tid.Type))
                    .Call((RuntimeTypeHandle h) => Type.GetTypeFromHandle(h))
                    ;
            }
            else
            {
                emit.Ldnull();
            }

            if (tid.Literal == null)
            {
                emit.Ldnull();
            }
            else
            {
                emit.Ldstr(new QStr(tid.Literal));
            }

            emit
                .Newobj(() => new CilSymbolRef(default(Type), default(string)));
        }
Exemplo n.º 31
0
        private static SymbolBase GetMatcherOutcomeSymbol(
            Grammar                   grammar,
            ICilSymbolResolver        symbolResolver,
            CilSymbolRef              mainOutcome,
            IEnumerable<CilSymbolRef> allOutcomes)
        {
            Symbol main = symbolResolver.GetSymbol(mainOutcome);
            Symbol[] all = (from outcome in allOutcomes
                             select symbolResolver.GetSymbol(outcome))
                             .ToArray();

            switch (all.Length)
            {
                case 0:  return null;
                case 1:  return main;
                default: return new AmbiguousSymbol(main, all);
            }
        }
Exemplo n.º 32
0
 public void TestLinkTwoTypes()
 {
     target.Link(CilSymbolRef.Create(typeof(string), "foo"));
     Assert.Throws <InvalidOperationException>(
         () => target.Link(CilSymbolRef.Create(typeof(int), "foo")));
 }