public ForeignAction(int offset, int argumentCount, ForeignContextRef context = null)
 {
     this.ContextRef    = context ?? ForeignContextRef.None;
     this.Offset        = offset;
     this.ArgumentCount = argumentCount;
     this.Joint         = new Joint();
 }
        private static ForeignContextRef CreateActionContextRef(CilContextRef cilContext)
        {
            ForeignContextRef result;

            if (cilContext == CilContextRef.None)
            {
                result = ForeignContextRef.None;
            }
            else
            {
                result = new ForeignContextRef(cilContext.UniqueName);
            }

            return(result);
        }
Beispiel #3
0
        private bool LdGlobalContext(string contextName)
        {
            var contextRef = new ForeignContextRef(contextName);
            var context    = this.contextProvider.Resolve(contextRef);

            if (context == null)
            {
                return(false);
            }

            var binding = context.Joint.The <CilContext>();

            binding.Ld(emit, ldGlobalContextProvider);
            return(true);
        }
 public ForeignAction(int argumentCount, ForeignContextRef context = null)
     : this(0, argumentCount, context)
 {
 }
        private static Grammar BuildGrammar(CilGrammar definition)
        {
            var result = new Grammar();

            InitContextProvider(
                result,
                definition.GlobalContextProvider,
                result.GlobalContextProvider);

            var symbolResolver = definition.SymbolResolver;

            // Define grammar tokens
            foreach (var cilSymbol in symbolResolver.Definitions)
            {
                Symbol symbol;
                if (cilSymbol.Type == typeof(Exception))
                {
                    cilSymbol.Symbol = symbol = (Symbol)result.Symbols[PredefinedTokens.Error];
                    symbol.Joint.Add(
                        new CilSymbol
                    {
                        Type       = typeof(Exception),
                        Symbol     = symbol,
                        Categories = SymbolCategory.DoNotDelete | SymbolCategory.DoNotInsert
                    });
                }
                else
                {
                    symbol = new Symbol(cilSymbol.Name)
                    {
                        Categories = cilSymbol.Categories,
                        Joint      = { cilSymbol }
                    };
                    result.Symbols.Add(symbol);
                    cilSymbol.Symbol = symbol;
                }
            }

            foreach (CilSymbolFeature <Precedence> feature in definition.Precedence)
            {
                var symbol = symbolResolver.GetSymbol(feature.SymbolRef);
                symbol.Precedence = feature.Value;
            }

            foreach (CilSymbolFeature <CilContextProvider> feature in definition.LocalContextProviders)
            {
                var symbol = symbolResolver.GetSymbol(feature.SymbolRef);
                if (symbol != null)
                {
                    InitContextProvider(result, feature.Value, symbol.LocalContextProvider);
                }
            }

            result.Start = symbolResolver.GetSymbol(definition.Start);

            // Define grammar rules
            foreach (var cilProduction in definition.Productions)
            {
                Symbol outcome = symbolResolver.GetSymbol(cilProduction.Outcome);
                var    pattern = Array.ConvertAll(cilProduction.Pattern, symbolResolver.GetSymbol);

                // Try to find existing rules whith same token-signature
                Production production;
                if (result.Productions.FindOrAdd(outcome, pattern, out production))
                {
                    ForeignContextRef contextRef = CreateActionContextRef(cilProduction.Context);
                    production.Actions.Add(new ForeignAction(pattern.Length, contextRef));
                }

                var action = production.Actions[0];
                action.Joint.Add(cilProduction);

                production.ExplicitPrecedence = cilProduction.Precedence;
            }

            // Create conditions to allow referencing them from matchers
            foreach (CilCondition cilCondition in definition.Conditions)
            {
                var cond = CreateCondtion(result, cilCondition);
                result.Conditions.Add(cond);
            }

            // Create matchers
            foreach (CilCondition cilCondition in definition.Conditions)
            {
                var condition = ConditionFromType(result, cilCondition.ConditionType);

                foreach (var cilMatcher in cilCondition.Matchers)
                {
                    SymbolBase outcome = GetMatcherOutcomeSymbol(result, symbolResolver, cilMatcher.MainOutcome, cilMatcher.AllOutcomes);

                    var matcher = new Matcher(
                        cilMatcher.Pattern,
                        outcome,
#if false
                        context: CreateActionContextRef(cilMatcher.Context),
#endif
                        nextCondition: ConditionFromType(result, cilMatcher.NextConditionType),
                        disambiguation: cilMatcher.Disambiguation);
                    matcher.Joint.Add(cilMatcher);

                    condition.Matchers.Add(matcher);
                }
            }

            foreach (var cilMerger in definition.Mergers)
            {
                var symbol = symbolResolver.GetSymbol(cilMerger.Symbol);
                var merger = new Merger(symbol)
                {
                    Joint = { cilMerger }
                };
                result.Mergers.Add(merger);
            }

            foreach (var report in definition.Reports)
            {
                result.Reports.Add(report);
            }

            return(result);
        }
        public void LdContext(string contextName)
        {
            var contextRef = new ForeignContextRef(contextName);

            if (localContexts != null && localContexts.Length != 0)
            {
                var locals = localContexts.Where(lc => lc.Consumer.Equals(contextRef)).ToArray();
                if (locals.Length != 0)
                {
                    var END = emit.Labels.Generate().GetRef();
                    var labels = new Ref<Labels>[locals.Length + 1];
                    for (int i = 0; i != labels.Length; ++i)
                    {
                        labels[i] = emit.Labels.Generate().GetRef();
                    }

                    var map =
                        (from i in Enumerable.Range(0, locals.Length)
                         let lc = locals[i]
                         select new IntArrow<int>(lc.StackState, i))
                        .ToArray();

                    var switchGenerator = SwitchGenerator.Sparse(
                                            map,
                                            labels.Length - 1,
                                            new IntInterval(0, short.MaxValue));
                    Expression<Action<IStackLookback<Msg>>> lookback = lb => lb.GetParentState();
                    switchGenerator.Build(
                        emit,
                        new Pipe<EmitSyntax>(il => il.Do(ldLookback).Call<IStackLookback<Msg>>(lookback)),
                        (il, value) =>
                        {
                            il.Label(labels[value].Def);

                            if (value == locals.Length)
                            {
                                if (LdGlobalContext(contextName))
                                {
                                    il.Br(END);
                                }
                                else
                                {
                                    il
                                        .Ldstr(new QStr("Internal error: missing global context : " + contextRef.UniqueName))
                                        .Newobj((string msg) => new Exception(msg))
                                        .Throw()
                                        ;
                                }
                            }
                            else
                            {
                                var lc = locals[value];
                                var provider = lc.Provider.Joint.The<CilContextProvider>();
                                var context = provider.GetContext(contextName);
                                context.Ld(
                                    il,
                                    il2 => il2
                                        // Lookback for getting parent instance
                                        .Do(ldLookback)
                                        .Ldc_I4(lc.StackLookback)
                                        .Call((IStackLookback<Msg> lb, int backOffset)
                                                => lb.GetValueAt(backOffset))
                                        .Ldfld((Msg msg) => msg.Value));
                                il.Br(END);
                            }
                        });

                    emit.Label(END.Def);
                    return;
                }
            }

            if (!LdGlobalContext(contextName))
            {
                throw new InvalidOperationException(
                    "Context '" + contextName + "' is not accessible.");
            }
        }
        private bool LdGlobalContext(string contextName)
        {
            var contextRef = new ForeignContextRef(contextName);
            var context = this.contextProvider.Resolve(contextRef);
            if (context == null)
            {
                return false;
            }

            var binding = context.Joint.The<CilContext>();
            binding.Ld(emit, ldGlobalContextProvider);
            return true;
        }
        private static ForeignContextRef CreateActionContextRef(CilContextRef cilContext)
        {
            ForeignContextRef result;

            if (cilContext == CilContextRef.None)
            {
                result = ForeignContextRef.None;
            }
            else
            {
                result = new ForeignContextRef(cilContext.UniqueName);
            }

            return result;
        }
Beispiel #9
0
        public void LdContext(string contextName)
        {
            var contextRef = new ForeignContextRef(contextName);

            if (localContexts != null && localContexts.Length != 0)
            {
                var locals = localContexts.Where(lc => lc.Consumer.Equals(contextRef)).ToArray();
                if (locals.Length != 0)
                {
                    var END    = emit.Labels.Generate().GetRef();
                    var labels = new Ref <Labels> [locals.Length + 1];
                    for (int i = 0; i != labels.Length; ++i)
                    {
                        labels[i] = emit.Labels.Generate().GetRef();
                    }

                    var map =
                        (from i in Enumerable.Range(0, locals.Length)
                         let lc = locals[i]
                                  select new IntArrow <int>(lc.StackState, i))
                        .ToArray();

                    var switchGenerator = SwitchGenerator.Sparse(
                        map,
                        labels.Length - 1,
                        new IntInterval(0, short.MaxValue));
                    Expression <Action <IStackLookback <Msg> > > lookback = lb => lb.GetParentState();
                    switchGenerator.Build(
                        emit,
                        new Pipe <EmitSyntax>(il => il.Do(ldLookback).Call <IStackLookback <Msg> >(lookback)),
                        (il, value) =>
                    {
                        il.Label(labels[value].Def);

                        if (value == locals.Length)
                        {
                            if (LdGlobalContext(contextName))
                            {
                                il.Br(END);
                            }
                            else
                            {
                                il
                                .Ldstr(new QStr("Internal error: missing global context : " + contextRef.UniqueName))
                                .Newobj((string msg) => new Exception(msg))
                                .Throw()
                                ;
                            }
                        }
                        else
                        {
                            var lc       = locals[value];
                            var provider = lc.Provider.Joint.The <CilContextProvider>();
                            var context  = provider.GetContext(contextName);
                            context.Ld(
                                il,
                                il2 => il2
                                // Lookback for getting parent instance
                                .Do(ldLookback)
                                .Ldc_I4(lc.StackLookback)
                                .Call((IStackLookback <Msg> lb, int backOffset)
                                      => lb.GetValueAt(backOffset))
                                .Ldfld((Msg msg) => msg.Value));
                            il.Br(END);
                        }
                    });

                    emit.Label(END.Def);
                    return;
                }
            }

            if (!LdGlobalContext(contextName))
            {
                throw new InvalidOperationException(
                          "Context '" + contextName + "' is not accessible.");
            }
        }