public EmitSyntax Build(EmitSyntax emit)
        {
            var result = emit.Locals.Generate().GetRef();

            emit
                .Local(result.Def, emit.Types.Import(LanguageBase.Fields.tokenKeyToId.FieldType))
                .Newobj(() => new Dictionary<object,int>())
                .Stloc(result);

            foreach (var pair in EnumerateTokenKeyToId())
            {
                emit.Ldloc(result);

                if (pair.Item1 is string)
                {
                    emit.Ldstr(new QStr((string)pair.Item1));
                }
                else if (pair.Item1 is Type)
                {
                    emit
                        .Ldtoken(emit.Types.Import((Type)pair.Item1))
                        .Call((RuntimeTypeHandle h) => Type.GetTypeFromHandle(h));
                }
                else
                {
                    throw new InvalidOperationException("Internal error: Unsupported token key type");
                }

                emit
                    .Ldc_I4(pair.Item2)
                    .Call((Dictionary<object, int> self, object _key, int _id) => self.Add(_key, _id))
                    ;
            }

            return emit.Ldloc(result);
        }
        public EmitSyntax Build(EmitSyntax emit)
        {
            int rows = table.RowCount;
            int columns = table.ColumnCount;

            Ref<Labels> END = emit.Labels.Generate().GetRef();
            Ref<Labels>[] labels = new Ref<Labels>[rows];
            for (int i = 0; i != rows; ++i)
            {
                labels[i] = emit.Labels.Generate().GetRef();
            }

            emit
                .Do(LdRow)
                .Switch(labels)
                .Ldc_I4(-1)
                .Br(END)
                ;

            var columnRange = new IntInterval(0, columns - 1);
            var columnFrequency = new UniformIntFrequency(columnRange);
            for (int i = 0; i != rows; ++i)
            {
                var switchEmitter = SwitchGenerator.Sparse(table.GetRow(i), columnRange, columnFrequency);

                emit.Label(labels[i].Def);
                switchEmitter.Build(emit, LdCol, SwitchGenerator.LdValueAction(END));
            }

            return emit .Label(END.Def);
        }
        public EmitSyntax Build(EmitSyntax emit)
        {
            int rows    = table.RowCount;
            int columns = table.ColumnCount;

            Ref <Labels> END = emit.Labels.Generate().GetRef();

            Ref <Labels>[] labels = new Ref <Labels> [rows];
            for (int i = 0; i != rows; ++i)
            {
                labels[i] = emit.Labels.Generate().GetRef();
            }

            emit
            .Do(LdRow)
            .Switch(labels)
            .Ldc_I4(-1)
            .Br(END)
            ;

            var columnRange     = new IntInterval(0, columns - 1);
            var columnFrequency = new UniformIntFrequency(columnRange);

            for (int i = 0; i != rows; ++i)
            {
                var switchEmitter = SwitchGenerator.Sparse(table.GetRow(i), columnRange, columnFrequency);

                emit.Label(labels[i].Def);
                switchEmitter.Build(emit, LdCol, SwitchGenerator.LdValueAction(END));
            }

            return(emit.Label(END.Def));
        }
Example #4
0
        public static EmitSyntax LdMethodDelegate(
            this EmitSyntax emit,
            Ref <Types> declaringType,
            string methodName,
            Type delegateType)
        {
            var method = delegateType.GetMethod("Invoke");
            Pipe <WantArgsSigBase> argBuilder =
                args =>
            {
                foreach (var param in method.GetParameters())
                {
                    var argType = emit.Types.Import(param.ParameterType);
                    args = args.Argument(argType, param.Name);
                }

                return(args);
            };

            return(emit.LdMethodDelegate(
                       scope =>
            {
                return scope.StartSignature
                .Returning(emit.Types.Import(method.ReturnType))
                .DecaringType(declaringType)
                .Named(methodName)
                .BeginArgs()
                .Do(argBuilder)
                .EndArgs()
                ;
            },
                       delegateType));
        }
Example #5
0
        private IActionCode LdActionArgument(int index)
        {
            emit = emit
                   .Do(LdRuleArgs)
                   .Do(LdArgsStart);

            // Optmization for "+ 0".
            if (index != 0)
            {
                emit
                .Ldc_I4(index)
                .Add();
            }

            if (typeof(Msg).IsValueType)
            {
                emit = emit
                       .Ldelema(emit.Types.Import(typeof(Msg)));
            }
            else
            {
                emit = emit
                       .Ldelem_Ref();
            }

            emit = emit
                   .Ldfld((Msg msg) => msg.Value)
            ;

            return(this);
        }
 public EmitSyntax Clear(EmitSyntax emit)
 {
     return emit
         .Ldc_I4_0()
         .Stloc(index.GetRef())
         ;
 }
Example #7
0
        public EmitSyntax StackLoop(EmitSyntax emit, Action <EmitSyntax, Def <Locals> > emitLoopBody)
        {
            var labels = emit.Labels;
            var START  = labels.Generate();
            var END    = labels.Generate();

            var item = emit.Locals.Generate();

            emit
            .Local(item, itemType)
            .Label(START)
            .Ldloc(index.GetRef())
            .Ldc_I4(0)
            .Beq(END.GetRef())
            .Do(Pop)
            .Stloc(item.GetRef())
            ;

            emitLoopBody(emit, item);

            emit
            .Br(START.GetRef())
            .Label(END)
            .Nop();

            return(emit);
        }
        protected override void DoBuild(
            EmitSyntax emit,
            Pipe <EmitSyntax> ldvalue,
            SwitchGeneratorAction action)
        {
            this.action = action;

#if false
            var decisionTree = new BinaryDecisionTreeBuilder(intMap.DefaultValue, platformInfo);
            var node         = decisionTree.Build(intMap.Enumerate().ToArray());
#else
            this.builder = new DecisionTreeBuilder(platformInfo);
            var node = builder.Build(
                intMap,
                possibleBounds,
                frequency);
#endif
            this.emit    = emit;
            this.ldvalue = ldvalue;
            this.labels  = new List <Ref <Labels> >();

            strategy.PlanCode(node);
            strategy.GenerateCode();

            // Debug.Write(node);
        }
        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)));
        }
Example #10
0
 public EmitSyntax Clear(EmitSyntax emit)
 {
     return(emit
            .Ldc_I4_0()
            .Stloc(index.GetRef())
            );
 }
Example #11
0
 private static EmitSyntax LdMethodDelegate(
     this EmitSyntax emit,
     Pipe <IMethodNs, DoneMethodSig> methodSig,
     Type delegateType)
 {
     return(emit
            .Ldnull()
            .Ldftn(emit.Methods.Method(methodSig))
            .NewDelegate(delegateType));
 }
Example #12
0
        public static EmitSyntax NewDelegate(this EmitSyntax emit, Type delegateType)
        {
            if (!typeof(Delegate).IsAssignableFrom(delegateType))
            {
                throw new ArgumentException("Expected delegate type.", "delegateType");
            }

            var ctor = delegateType.GetConstructor(new[] { typeof(object), typeof(IntPtr) });

            return(emit.Newobj(ctor));
        }
Example #13
0
 public static EmitSyntax Swap(this EmitSyntax emit, Def <Locals> x, Def <Locals> y, Def <Locals> tmp)
 {
     return
         (emit
          .Ldloc(x.GetRef())
          .Stloc(tmp.GetRef())
          .Ldloc(y.GetRef())
          .Stloc(x.GetRef())
          .Ldloc(tmp.GetRef())
          .Stloc(y.GetRef()));
 }
Example #14
0
 public void BuildBody(EmitSyntax emit, LanguageData data, Ref <Args>[] args)
 {
     BuildBody(
         emit,
         data,
         ruleId:     args[0],
         ruleArgs:   args[1],
         argsStart:  args[2],
         ctx:        args[3],
         lookbackStart: args[4]);
 }
Example #15
0
        private EmitSyntax EmitFactoryCode(
            EmitSyntax emit,
            PlannedClass contextPlannedClass,
            Type type,
            bool nullAllowed)
        {
            if (type == typeof(void))
            {
            }
            else if (type == typeof(int))
            {
                emit = emit.Ldc_I4_0();
            }
            else if (type.IsValueType)
            {
                var resultType = emit.Types.Import(type);
                var resultLoc  = emit.Locals.Generate("result");

                emit = emit
                       .Local(resultLoc, resultType)
                       .Ldloca(resultLoc.GetRef())
                       .Initobj(resultType)
                       .Ldloc(resultLoc.GetRef())
                ;
            }
            else if (nullAllowed)
            {
                emit.Ldnull();
            }
            else if (!type.IsAbstract && !type.IsInterface)
            {
                emit = emit.Newobj(
                    emit.Types.Import(type));
            }
            else if (contextPlannedClass != null && contextPlannedClass.Implements(type))
            {
                emit = emit.Ldarg(0);
            }
            else if (plan.Exists(e => e.Implements(type)))
            {
                var otherEntry = plan.Find(e => e.Implements(type));
                emit = emit.Newobj(
                    emit.Types.Class_(
                        ClassName.Parse(
                            otherEntry.ClassName)));
            }
            else
            {
                throw new InvalidOperationException(
                          "Internal error: non-planned abstract result type");
            }

            return(emit);
        }
        public EmitSyntax EmitFactoryCode(
            EmitSyntax   emit,
            Type         type)
        {
            if (type.IsAbstract && !plan.Exists(e => e.Implements(type)))
            {
                PlanImplementationOf(type);
            }

            return EmitFactoryCode(emit, null, type, false);
        }
Example #17
0
 public void BuildBody(EmitSyntax emit, LanguageData data, Ref <Args>[] args)
 {
     BuildBody(
         emit,
         data,
         tokenId:    args[0],
         oldValue:   args[1],
         newValue:   args[2],
         ctx:        args[3],
         lookbackStart: args[4]);
 }
 public void BuildBody(EmitSyntax emit, LanguageData data, Ref<Args>[] args)
 {
     BuildBody(
         emit,
         data,
         ruleId:     args[0],
         ruleArgs:   args[1],
         argsStart:  args[2],
         ctx:        args[3],
         lookbackStart: args[4]);
 }
 public void BuildBody(EmitSyntax emit, LanguageData data, Ref<Args>[] args)
 {
     BuildBody(
         emit,
         data,
         tokenId:    args[0],
         oldValue:   args[1],
         newValue:   args[2],
         ctx:        args[3],
         lookbackStart: args[4]);
 }
Example #20
0
        public EmitSyntax EmitFactoryCode(
            EmitSyntax emit,
            Type type)
        {
            if (type.IsAbstract && !plan.Exists(e => e.Implements(type)))
            {
                PlanImplementationOf(type);
            }

            return(EmitFactoryCode(emit, null, type, false));
        }
Example #21
0
 /// <summary>
 /// Create new object using default constructor of the specified type
 /// </summary>
 /// <param name="emit"></param>
 /// <param name="typeRef"></param>
 /// <returns></returns>
 public static EmitSyntax Newobj(this EmitSyntax emit, Ref <Types> typeRef)
 {
     return(emit.Newobj(
                emit.Methods.Method(
                    _ => _.StartSignature
                    .Instance
                    .Returning(emit.Types.Void)
                    .DecaringType(typeRef)
                    .Named(".ctor")
                    .BeginArgs()
                    .EndArgs())));
 }
Example #22
0
 /// <summary>
 /// Pops item and puts on the CLR stack
 /// </summary>
 /// <param name="emit"></param>
 public EmitSyntax Pop(EmitSyntax emit)
 {
     return(emit
            .Ldloc(index.GetRef())
            .Ldc_I4_1()
            .Sub()
            .Stloc(index.GetRef())
            .Ldloc(stack.GetRef())
            .Ldloc(index.GetRef())
            .Ldelem(itemType)
            );
 }
Example #23
0
        public EmitSyntax Ld(EmitSyntax emit, Pipe <EmitSyntax> ldFrom)
        {
            // Load start value
            emit = ldFrom(emit);

            foreach (var getter in path)
            {
                emit = emit.Call(getter);
            }

            return(emit);
        }
Example #24
0
        public StackGenerator(EmitSyntax emit, Type itemType, bool nullContainer = false)
        {
            this.itemType      = emit.Types.Import(itemType);
            this.stackType     = emit.Types.Import(itemType.MakeArrayType());
            this.nullContainer = nullContainer;

            this.stack = emit.Locals.Generate();
            this.index = emit.Locals.Generate();
            emit
            .Local(stack, stackType)
            .Local(index, emit.Types.Int32)
            ;
        }
Example #25
0
        public static EmitSyntax Call(this EmitSyntax emit, SR.MethodInfo method)
        {
            var methodRef = emit.Methods.Import(method);

            if (method.IsStatic)
            {
                return(emit.Call(methodRef));
            }
            else
            {
                return(emit.Callvirt(methodRef));
            }
        }
        public StackGenerator(EmitSyntax emit, Type itemType, bool nullContainer = false)
        {
            this.itemType = emit.Types.Import(itemType);
            this.stackType = emit.Types.Import(itemType.MakeArrayType());
            this.nullContainer = nullContainer;

            this.stack = emit.Locals.Generate();
            this.index = emit.Locals.Generate();
            emit
                .Local(stack, stackType)
                .Local(index, emit.Types.Int32)
                ;
        }
Example #27
0
 public ProductionCode(
     EmitSyntax emit,
     IContextCode contextCode,
     Pipe <EmitSyntax> ldRuleArgs,
     Pipe <EmitSyntax> ldArgsStart,
     Def <Labels> returnLabel)
 {
     this.emit        = emit;
     this.contextCode = contextCode;
     this.LdRuleArgs  = ldRuleArgs;
     this.LdArgsStart = ldArgsStart;
     this.ReturnLabel = returnLabel;
 }
Example #28
0
 public void PushFrom(EmitSyntax emit, Def <Locals> local)
 {
     emit
     .Ldloc(stack.GetRef())
     .Ldloc(index.GetRef())
     .Ldloc(local.GetRef())
     .Stelem(itemType)
     .Ldloc(index.GetRef())
     .Ldc_I4_1()
     .Add()
     .Stloc(index.GetRef())
     ;
 }
 public ProductionCode(
     EmitSyntax       emit,
     IContextCode     contextCode,
     Pipe<EmitSyntax> ldRuleArgs,
     Pipe<EmitSyntax> ldArgsStart,
     Def<Labels>      returnLabel)
 {
     this.emit        = emit;
     this.contextCode = contextCode;
     this.LdRuleArgs  = ldRuleArgs;
     this.LdArgsStart = ldArgsStart;
     this.ReturnLabel = returnLabel;
 }
Example #30
0
 public ContextCode(
     EmitSyntax emit,
     Pipe <EmitSyntax> ldGlobalContextProvider,
     Pipe <EmitSyntax> ldLookback,
     LanguageData data,
     ForeignContextProvider contextProvider,
     LocalContextBinding[] localContexts = null)
 {
     this.emit = emit;
     this.ldGlobalContextProvider = ldGlobalContextProvider;
     this.ldLookback      = ldLookback;
     this.contextProvider = contextProvider;
     this.localContexts   = localContexts;
 }
Example #31
0
 public ContextCode(
     EmitSyntax       emit,
     Pipe<EmitSyntax> ldGlobalContextProvider,
     Pipe<EmitSyntax> ldLookback,
     LanguageData     data,
     ForeignContextProvider  contextProvider,
     LocalContextBinding[] localContexts = null)
 {
     this.emit = emit;
     this.ldGlobalContextProvider   = ldGlobalContextProvider;
     this.ldLookback      = ldLookback;
     this.contextProvider = contextProvider;
     this.localContexts   = localContexts;
 }
Example #32
0
 public MatcherCode(
     EmitSyntax emit,
     IContextCode contextCode,
     Pipe <EmitSyntax> ldCursor,
     Ref <Types> declaringType,
     ConditionCollection conditions,
     Ref <Labels> RETURN)
 {
     this.emit          = emit;
     this.ldCursor      = ldCursor;
     this.contextCode   = contextCode;
     this.declaringType = declaringType;
     this.conditions    = conditions;
     this.RETURN        = RETURN;
 }
Example #33
0
 public MatcherCode(
     EmitSyntax           emit, 
     IContextCode         contextCode,
     Pipe<EmitSyntax>     ldCursor,
     Ref<Types>           declaringType,
     ConditionCollection  conditions,
     Ref<Labels>          RETURN)
 {
     this.emit            = emit;
     this.ldCursor        = ldCursor;
     this.contextCode     = contextCode;
     this.declaringType   = declaringType;
     this.conditions      = conditions;
     this.RETURN          = RETURN;
 }
        public EmitSyntax EmitLoopPass(EmitSyntax emit, bool loop)
        {
            emit.Label(START);

            FetchNext(emit, END);
            body(emit);

            if (loop)
            {
                emit.Br(START.GetRef());
            }

            return(emit
                   .Label(END)
                   .Nop());
        }
Example #35
0
        private EmitSyntax BuildNodeInvocation(ref int startArgIndex, EmitSyntax emit, Ref <Args>[] args, SppfNode node)
        {
            if (node.IsTerminal)
            {
                return(emit.Ldarg(args[startArgIndex++]));
            }

            int count = node.Children.Length;

            for (int i = 0; i != count; ++i)
            {
                emit = BuildNodeInvocation(ref startArgIndex, emit, args, node.Children[i]);
            }

            return(emit);
        }
        public EmitSyntax EmitInitialization(EmitSyntax emit)
        {
            var types = emit.Types;

            var labels = emit.Labels;

            END   = labels.Generate();
            START = labels.Generate();

            var locals = emit.Locals;

            count = locals.Generate();
            if (Index == null)
            {
                Index = locals.Generate();
                emit.Local(Index, types.Int32);
            }

            if (Value == null)
            {
                Value = locals.Generate();
                emit
                .Local(Value, valueType)
                .Ldc_I4(int.MinValue)
                .Stloc(Value.GetRef());
            }

            emit
            // int count;
            .Local(count, types.Int32);

            // count = array.Length
            ldarray(emit);
            return(emit
                   .Ldlen()
                   .Stloc(count.GetRef())

                   // Index = 0
                   .Ldc_I4(-1)
                   .Stloc(Index.GetRef())
                   // Value = -1
                   .Ldc_I4(-1)
                   .Stloc(Value.GetRef()));

            ;
        }
 private void FetchNext(EmitSyntax emit, Def <Labels> END_OF_INPUT)
 {
     emit
     .Ldloc(Index.GetRef())
     .Ldc_I4_1()
     .Add()
     .Stloc(Index.GetRef())
     // ++Index
     // if (Index == count) goto END
     .Ldloc(Index.GetRef())
     .Ldloc(count.GetRef())
     .Beq(END_OF_INPUT.GetRef())
     .Do(ldarray)
     .Ldloc(Index.GetRef())
     .Ldelem(valueType)
     .Stloc(Value.GetRef())
     ;
 }
        public EmitSyntax Init(EmitSyntax emit)
        {
            emit = emit
                .Ldc_I4_0()
                .Stloc(index.GetRef())
                ;

            if (!nullContainer)
            {
                emit = emit
                    .Ldc_I4(this.stackSize)
                    .Newarr(itemType)
                    .Stloc(stack.GetRef())
                    ;
            }

            return emit;
        }
Example #39
0
        public EmitSyntax Init(EmitSyntax emit)
        {
            emit = emit
                   .Ldc_I4_0()
                   .Stloc(index.GetRef())
            ;

            if (!nullContainer)
            {
                emit = emit
                       .Ldc_I4(this.stackSize)
                       .Newarr(itemType)
                       .Stloc(stack.GetRef())
                ;
            }

            return(emit);
        }
        public EmitSyntax EmitInitialization(EmitSyntax emit)
        {
            var types = emit.Types;

            var labels = emit.Labels;
            END = labels.Generate();
            START = labels.Generate();

            var locals = emit.Locals;
            count = locals.Generate();
            if (Index == null)
            {
                Index = locals.Generate();
                emit.Local(Index, types.Int32);
            }

            if (Value == null)
            {
                Value = locals.Generate();
                emit
                    .Local(Value, valueType)
                    .Ldc_I4(int.MinValue)
                    .Stloc(Value.GetRef());
            }

            emit
                // int count;
                .Local(count, types.Int32);

            // count = array.Length
            ldarray(emit);
            return emit
                .Ldlen()
                .Stloc(count.GetRef())

                // Index = 0
                .Ldc_I4(-1)
                .Stloc(Index.GetRef())
                // Value = -1
                .Ldc_I4(-1)
                .Stloc(Value.GetRef());
                ;
        }
Example #41
0
        private static EmitSyntax EmitAst(EmitSyntax emit, AstNode ast, Ref <Args> input)
        {
            var settings = new ILCompilerSettings
            {
                LdInput = il => il.Ldarg(input),
                SUCCESS = emit.Labels.Generate(),
                FAILURE = emit.Labels.Generate(),
            };

            var _ = new ILNfaCompiler(ast, emit, settings);

            emit
            .Label(settings.SUCCESS)
            .Ldc_I4_1()
            .Ret()
            .Label(settings.FAILURE)
            .Ldc_I4_0()
            .Ret();

            return(emit);
        }
        protected override void DoBuild(EmitSyntax emit, Pipe<EmitSyntax> ldvalue, SwitchGeneratorAction action)
        {
            var labels = new Ref<Labels>[map.Length];
            for (int i = 0; i != labels.Length; ++i)
            {
                labels[i] = emit.Labels.Generate().GetRef();
            }

            emit
                .Do(ldvalue)
                .Switch(labels)
                ;

            action(emit, defaultValue);

            for (int i = 0; i != labels.Length; ++i)
            {
                emit.Label(labels[i].Def);
                action(emit, map[i]);
            }
        }
        protected override void DoBuild(EmitSyntax emit, Pipe <EmitSyntax> ldvalue, SwitchGeneratorAction action)
        {
            var labels = new Ref <Labels> [map.Length];

            for (int i = 0; i != labels.Length; ++i)
            {
                labels[i] = emit.Labels.Generate().GetRef();
            }

            emit
            .Do(ldvalue)
            .Switch(labels)
            ;

            action(emit, defaultValue);

            for (int i = 0; i != labels.Length; ++i)
            {
                emit.Label(labels[i].Def);
                action(emit, map[i]);
            }
        }
 private void FetchNext(EmitSyntax emit, Def<Labels> END_OF_INPUT)
 {
     emit
         .Ldloc(Index.GetRef())
         .Ldc_I4_1()
         .Add()
         .Stloc(Index.GetRef())
         // ++Index
         // if (Index == count) goto END
         .Ldloc(Index.GetRef())
         .Ldloc(count.GetRef())
         .Beq(END_OF_INPUT.GetRef())
         .Do(ldarray)
         .Ldloc(Index.GetRef())
         .Ldelem(valueType)
         .Stloc(Value.GetRef())
         ;
 }
 public void LdValue(EmitSyntax emit)
 {
     emit.Ldloc(Value.GetRef());
 }
        public EmitSyntax Build(EmitSyntax emit)
        {
            int rows = table.RowCount;
            int columns = table.ColumnCount;

            // Dispatch info index
            Ref<Labels> DISP_INFO = emit.Labels.Generate().GetRef();
            // Return no-data result
            Ref<Labels> RET_NONE = emit.Labels.Generate().GetRef();
            // Exit
            Ref<Labels> END = emit.Labels.Generate().GetRef();
            Ref<Labels>[] rowLabels = new Ref<Labels>[rows];
            for (int i = 0; i != rows; ++i)
            {
                rowLabels[i] = emit.Labels.Generate().GetRef();
            }

            emit
                .Do(LdRow)
                .Switch(rowLabels)
                .Br(RET_NONE)
                ;

            for (int i = 0; i != rows; ++i)
            {
                emit
                    .Label(rowLabels[i].Def)
                    .Ldc_I4(table.RowToOffset[i])
                    .Br(DISP_INFO);
            }

            int infoCount = table.Info.Count;
            var infoLabels = new Ref<Labels>[infoCount];
            for (int i = 0; i != infoCount; ++i)
            {
                infoLabels[i] = emit.Labels.Generate().GetRef();
            }

            emit
                .Label(DISP_INFO.Def)
                // Row offset should already be in stack
                .Do(LdCol)
                .Add()
                .Switch(infoLabels)
                .Br(RET_NONE);
            for (int i = 0; i != infoCount; ++i)
            {
                emit
                    .Label(infoLabels[i].Def)
                    .Do(LdRow)
                    .Ldc_I4(table.Check[i])
                    .Bne_Un(RET_NONE)
                    .Ldc_I4(table.Info[i])
                    .Br(END)
                    ;
            }

            emit
                .Label(RET_NONE.Def)
                .Ldc_I4(0)
                ;
            return emit.Label(END.Def);
        }
        public void BuildBody(
            EmitSyntax emit, 
            LanguageData data,
            Ref<Args> ruleId,
            Ref<Args> ruleArgs,
            Ref<Args> argsStart,
            Ref<Args> ctx,
            Ref<Args> lookbackStart)
        {
            Def<Labels> returnLabel = emit.Labels.Generate();

            var contextCode = new ContextCode(
                emit,
                il => il.Ldarg(ctx),
                il => il.Ldarg(lookbackStart),
                data,
                data.Grammar.GlobalContextProvider,
                data.LocalParseContexts);

            IActionCode code = new ProductionCode(
                emit,
                contextCode,
                ldRuleArgs:  il => il.Ldarg(ruleArgs),
                ldArgsStart: il => il.Ldarg(argsStart),
                returnLabel: returnLabel);

            var defaultLabel = emit.Labels.Generate();
            var endWithSingleResultLabel = emit.Labels.Generate();
            var jumpTable = new Ref<Labels>[data.Grammar.Productions.Count];
            for (int i = 0; i != jumpTable.Length; ++i)
            {
                jumpTable[i] = emit.Labels.Generate().GetRef();
            }

            emit
                .Do(il => il.Ldarg(ruleId))
                .Switch(jumpTable)
                .Br(defaultLabel.GetRef());

            foreach (var prod in data.Grammar.Productions)
            {
                emit.Label(jumpTable[prod.Index].Def);

                if (0 == prod.Actions.Count)
                {
                    // Augumented start rule has null action and should never be invoked.
                    // Also it is possible that for some platforms production may have default
                    // action.
                    emit.Ldnull();
                }
                else
                {
                    foreach (var action in prod.Actions)
                    {
                        code = GenerateActionCode(code, action);
                    }
                }

                emit.Br(endWithSingleResultLabel.GetRef());
            }

            emit
                .Label(defaultLabel)
                .Ldnull()
                .Label(endWithSingleResultLabel)
                .Label(returnLabel)
                .Ret();
        }
        protected override void DoBuild(
            EmitSyntax            emit,
            Pipe<EmitSyntax>      ldvalue,
            SwitchGeneratorAction action)
        {
            this.action = action;

            #if false
            var decisionTree = new BinaryDecisionTreeBuilder(intMap.DefaultValue, platformInfo);
            var node = decisionTree.Build(intMap.Enumerate().ToArray());
            #else
            this.builder = new DecisionTreeBuilder(platformInfo);
            var node = builder.Build(
                    intMap,
                    possibleBounds,
                    frequency);
            #endif
            this.emit = emit;
            this.ldvalue = ldvalue;
            this.labels = new List<Ref<Labels>>();

            strategy.PlanCode(node);
            strategy.GenerateCode();

            // Debug.Write(node);
        }
Example #49
0
        private static EmitSyntax EmitAst(EmitSyntax emit, AstNode ast, Ref<Args> input)
        {
            var settings = new ILCompilerSettings
            {
                LdInput = il => il.Ldarg(input),
                SUCCESS = emit.Labels.Generate(),
                FAILURE = emit.Labels.Generate(),
            };

            var _ = new ILNfaCompiler(ast, emit, settings);

            emit
                .Label(settings.SUCCESS)
                .Ldc_I4_1()
                .Ret()
                .Label(settings.FAILURE)
                .Ldc_I4_0()
                .Ret();

            return emit;
        }
 public void Build(EmitSyntax emit, Pipe<EmitSyntax> ldvalue, SwitchGeneratorAction action)
 {
     this.END = emit.Labels.Generate();
     DoBuild(emit, ldvalue, action);
 }
        public EmitSyntax EmitLoopPass(EmitSyntax emit, bool loop)
        {
            emit.Label(START);

            FetchNext(emit, END);
            body(emit);

            if (loop)
            {
                emit.Br(START.GetRef());
            }

            return emit
                .Label(END)
                .Nop();
        }
        public void Build(
            EmitSyntax          emit,
            Pipe<EmitSyntax>    ldCursor,
            Pipe<EmitSyntax>    ldTokenPtr)
        {
            var labels = emit.Labels;
            var locals = emit.Locals;

            var RETURN = labels.Generate();

            var valueTmp = locals.Generate();
            var tokenId  = locals.Generate();

            emit
                .Local(valueTmp, emit.Types.Object)
                .Ldnull()
                .Stloc(valueTmp.GetRef())

                .Local(tokenId, emit.Types.Int32)
                .Ldc_I4(-1)
                .Stloc(tokenId.GetRef())
                ;

            int ruleCount = data.Grammar.Conditions.Sum(cond => cond.Matchers.Count);

            var action = new Ref<Labels>[ruleCount];
            for (int i = 0; i != ruleCount; ++i)
            {
                action[i] = labels.Generate().GetRef();
            }

            emit
                .Do(ldCursor)
                .Ldfld((ScanCursor c) => c.CurrentActionId)
                .Switch(action)
                ;

            foreach (var cond in data.Grammar.Conditions)
            {
                var contextResolver = new ContextCode(
                                        emit,
                                        il => il
                                            .Do(ldCursor)
                                            .Ldfld((ScanCursor c) => c.RootContext),
                                        null,
                                        data,
                                        cond.ContextProvider);
                IActionCode code = new MatcherCode(
                                emit,
                                contextResolver,
                                ldCursor,
                                declaringType,
                                data.Grammar.Conditions,
                                RETURN.GetRef());

                foreach (var matcher in cond.Matchers)
                {
                    emit
                        .Label(action[matcher.Index].Def)
                        .Ldc_I4(matcher.Outcome == null ? -1 : matcher.Outcome.Index)
                        .Stloc(tokenId.GetRef())
                        ;

                    var productionBinding = matcher.Joint.The<CilMatcher>();
                    code = code
                        .Do(productionBinding.Context.Load)
                        .Do(productionBinding.ActionBuilder);
                }
            }

            // Load null value for incorrectly implemented actions
            emit.Ldnull();

            emit
                .Label(RETURN)

                .Stloc(valueTmp.GetRef())
                .Do(ldTokenPtr)
                .Ldloc(valueTmp.GetRef())
                .Stind_Ref()

                .Ldloc(tokenId.GetRef())
                .Ret()
                ;
        }
        private EmitSyntax EmitFactoryCode(
            EmitSyntax   emit,
            PlannedClass contextPlannedClass,
            Type         type,
            bool         nullAllowed)
        {
            if (type == typeof(void))
            {
            }
            else if (type == typeof(int))
            {
                emit = emit.Ldc_I4_0();
            }
            else if (type.IsValueType)
            {
                var resultType = emit.Types.Import(type);
                var resultLoc = emit.Locals.Generate("result");

                emit = emit
                    .Local(resultLoc, resultType)
                    .Ldloca(resultLoc.GetRef())
                    .Initobj(resultType)
                    .Ldloc(resultLoc.GetRef())
                    ;
            }
            else if (nullAllowed)
            {
                emit.Ldnull();
            }
            else if (!type.IsAbstract && !type.IsInterface)
            {
                emit = emit.Newobj(
                         emit.Types.Import(type));
            }
            else if (contextPlannedClass != null && contextPlannedClass.Implements(type))
            {
                emit = emit.Ldarg(0);
            }
            else if (plan.Exists(e => e.Implements(type)))
            {
                var otherEntry = plan.Find(e => e.Implements(type));
                emit = emit.Newobj(
                         emit.Types.Class_(
                            ClassName.Parse(
                                otherEntry.ClassName)));
            }
            else
            {
                throw new InvalidOperationException(
                    "Internal error: non-planned abstract result type");
            }

            return emit;
        }
        private IActionCode LdActionArgument(int index)
        {
            emit = emit
                .Do(LdRuleArgs)
                .Do(LdArgsStart);

            // Optmization for "+ 0".
            if (index != 0)
            {
                emit
                    .Ldc_I4(index)
                    .Add();
            }

            if (typeof(Msg).IsValueType)
            {
                emit = emit
                    .Ldelema(emit.Types.Import(typeof(Msg)));
            }
            else
            {
                emit = emit
                    .Ldelem_Ref();
            }

            emit = emit
                .Ldfld((Msg msg) => msg.Value)
                ;

            return this;
        }
 public void Build(EmitSyntax emit, Ref<Args>[] args, SwitchGeneratorAction action)
 {
     Build(emit, il => il.Ldarg(args[0]), action);
 }
 protected abstract void DoBuild(EmitSyntax emit, Pipe<EmitSyntax> ldvalue, SwitchGeneratorAction action);
        public void BuildBody(
            EmitSyntax emit, 
            LanguageData data,
            Ref<Args> tokenId,
            Ref<Args> oldValue,
            Ref<Args> newValue,
            Ref<Args> ctx,
            Ref<Args> lookbackStart)
        {
            var mergers = data.Grammar.Mergers;

            if (mergers.Count == 0)
            {
                emit
                    .Ldarg(oldValue)
                    .Ret();

                return;
            }

            var contextResolverCode = new ContextCode(
                                            emit,
                                            il => il.Ldarg(ctx),
                                            il => il.Ldarg(lookbackStart),
                                            data,
                                            data.Grammar.GlobalContextProvider,
                                            data.LocalParseContexts);

            IActionCode code = new MergeCode(emit, contextResolverCode)
            {
                LoadOldValue = il => il.Ldarg(oldValue),
                LoadNewValue = il => il.Ldarg(newValue),
            };

            var tokenToRuleIndex = new MutableIntMap<int>(
                                        mergers.Select(
                                            merger =>
                                                new IntArrow<int>(merger.Symbol.Index, merger.Index)));
            tokenToRuleIndex.DefaultValue = -1;

            var ids = mergers.Select(m => m.Symbol.Index);
            IntInterval possibleBounds = new IntInterval(ids.Min(), ids.Max());
            var switchGenerator = SwitchGenerator.Sparse(tokenToRuleIndex, possibleBounds);
            switchGenerator.Build(
                emit,
                il => il.Ldarg(tokenId),
                (il, value) =>
                {
                    if (value < 0)
                    {
                        emit
                            .Ldarg(newValue)
                            .Ret();
                    }
                    else
                    {
                        var merger = mergers[value];
                        var binding = merger.Joint.The<CilMerger>();
                        code = code
                            .Do(binding.Context.Load)
                            .Do(binding.ActionBuilder)
                            .Emit(il2 => il2.Ret())
                            ;
                    }
                });

            emit
                .Ret();
        }
 public IActionCode Emit(Pipe<EmitSyntax> pipe)
 {
     emit = pipe(emit);
     return this;
 }
Example #59
0
        public ILNfaCompiler(AstNode node, EmitSyntax emit, ILCompilerSettings settings)
        {
            this.Scanner = new StemScanner();

            this.emit = emit;
            this.settings = settings;

            var labels = emit.Labels;
            NEXT_THREAD     = labels.Generate();
            RESUME_ALL      = labels.Generate();
            NEXT_INPUT      = labels.Generate();
            THREAD_SUSPEND  = labels.Generate();
            THREAD_DISPATCH = labels.Generate();

            var LABEL0      = labels.Generate();
            var LABEL1      = labels.Generate();
            var POSTCOMPILEINIT = labels.Generate();
            var POSTCOMPILEINIT_BACK = labels.Generate();

            var locals = emit.Locals;
            slots        = locals.Generate();
            labelIndexToLocation = locals.Generate();
            intTmp       = locals.Generate();
            threadTmp    = locals.Generate();

            INfaVM code = this;

            this.inputPump = new ArrayLoopGenerator(
                       valueType: emit.Types.Int32,
                       ldarray:   settings.LdInput,
                       body:
                           il => il
                               .Do(matchedStack.Clear)
                               .Br(RESUME_ALL.GetRef())
                        );

            this.runningStack   = new StackGenerator(emit, typeof(Thread));
            this.suspendedStack = new StackGenerator(emit, typeof(Thread));
            this.matchedStack   = new StackGenerator(emit, typeof(Thread));
            this.tmpStack       = new StackGenerator(emit, typeof(Thread), nullContainer: true);

            emit
                .Local(intTmp, emit.Types.Int32)
                .Local(slots, emit.Types.Import(typeof(int[])))
                .Local(labelIndexToLocation, emit.Types.Import(typeof(int[])))
                .Br(POSTCOMPILEINIT.GetRef())
                .Label(POSTCOMPILEINIT_BACK)
                .Local(threadTmp, emit.Types.Import(typeof(Thread)))
                .Ldloca(threadTmp.GetRef())
                .Initobj(emit.Types.Import(typeof(Thread)))
                .Do(inputPump.EmitInitialization)
                ;

            new RegularNfaVMCompiler().Compile(node, code);

            int LabelCount = Math.Max(1, indexToLabel.Count);

            this.runningStack.SetSize(LabelCount);
            this.suspendedStack.SetSize(LabelCount);
            this.matchedStack.SetSize(LabelCount);
            this.tmpStack.SetSize(LabelCount);

            emit
                .Label(POSTCOMPILEINIT)
                .Do(runningStack.Init)
                .Do(suspendedStack.Init)
                .Do(matchedStack.Init)
                .Do(tmpStack.Init)
                .Ldc_I4(slotCount)
                .Newarr(emit.Types.Int32)
                .Stloc(slots.GetRef())

                .Ldc_I4(LabelCount)
                .Newarr(emit.Types.Int32)
                .Stloc(labelIndexToLocation.GetRef())
                // Fill labelIndexToLocation with -1 :
                .Ldc_I4(LabelCount).Stloc(intTmp.GetRef())

                .Label(LABEL1)
                .Ldloc(intTmp.GetRef())
                .Ldc_I4_0()
                .Beq(LABEL0.GetRef())
                .Ldloc(intTmp.GetRef())
                .Ldc_I4(1)
                .Sub()
                .Stloc(intTmp.GetRef())
                .Ldloc(labelIndexToLocation.GetRef())
                .Ldloc(intTmp.GetRef())
                .Ldc_I4(int.MinValue)
                .Stelem_I4()
                .Br(LABEL1.GetRef())
                .Label(LABEL0)
                .Br(POSTCOMPILEINIT_BACK.GetRef());

            // Save thread as suspended (stack should already contain label index to suspend)
            emit.Label(THREAD_SUSPEND);
            StThreadValueByRuntimeLabelIndex();
            emit
                // Don't add thread if same thread (same label index
                // with current input location) already exists in a list.
                .Ldloc(labelIndexToLocation.GetRef())
                .Ldloca(threadTmp.GetRef())
                .Ldfld(LabelIndexField)
                .Ldelem_I4()
                .Ldloc(inputPump.Index.GetRef())
                .Beq(NEXT_THREAD.GetRef())

                // Mark label index as visited
                .Ldloc(labelIndexToLocation.GetRef())
                .Ldloca(threadTmp.GetRef())
                .Ldfld(LabelIndexField)
                .Ldloc(inputPump.Index.GetRef())
                .Stelem_I4()
                ;

            suspendedStack.PushFrom(emit, threadTmp);

            emit
                .Br(NEXT_THREAD.GetRef())

                .Label(RESUME_ALL)
                .Swap(suspendedStack.Stack, runningStack.Stack, tmpStack.Stack)
                .Swap(suspendedStack.Index, runningStack.Index, tmpStack.Index)
                .Label(NEXT_THREAD)
                ;

            runningStack
                .StackLoop(
                    emit,
                    (emit2, thread) =>
                    {
                        emit2
                            .Ldloca(thread.GetRef())
                            .Ldfld(LabelIndexField)
                            .Label(THREAD_DISPATCH)
                            .Switch(indexToLabel.Select(def => def.GetRef()).ToArray())
                            .Br(settings.FAILURE.GetRef());
                    })
                    ;
            emit
                .Br(NEXT_INPUT.GetRef())
                ;

            emit
                .Label(NEXT_INPUT)
                ;

            inputPump.EmitLoopPass(emit, false);

            emit
                // Check if there are matched threads:
                .Do(matchedStack.LdCount)
                .Ldc_I4_0()
                .Beq(settings.FAILURE.GetRef())
                .Br(settings.SUCCESS.GetRef());
        }
        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)));
        }