コード例 #1
0
        void EmitTemplateMethod(IAst ast, TypeBuilder tb, NLiquidDependentPropertyEvalContext context)
        {
            var compilationUnit = (CompilationUnit)ast;
            var methodBuilder   = CreatreMethodBuilder(ast, tb);

            _variablesMap = new Dictionary <LocalVariableSymbol, Expression>();
            _context      = context;
            //_variablesMap           = new Dictionary<LocalVariableSymbol, Expression>(context.PredefinedTypes.DotNetTypesMap);
            // the first parameter of tempalte method is TextWriter
            var methodParameters = new BlockCollector();

            methodParameters.AddVariable(_textWriterParameter);

            var commentParameter = EmitCommentParameter(compilationUnit);

            if (commentParameter != null)
            {
                methodParameters.AddVariable(commentParameter);
            }

            var blockCollector = new BlockCollector();

            foreach (var statement in compilationUnit.Statements)
            {
                EmitStatement(statement, blockCollector);
            }

            var templateMethod = Expression.Lambda(blockCollector.ToBlockExpression(), methodParameters.Variables);

            templateMethod.CompileToMethod(methodBuilder);
        }
コード例 #2
0
        private void EmitIfStatement(Statement.If ifStmt, BlockCollector blockCollector)
        {
            var        ifStmtElseIfs = (IAstList <ElseIf>)ifStmt.ElseIfs;
            var        elseBody      = ifStmt.Else.HasValue ? EmitStatement(ifStmt.Else.Value.Body).ToBlockExpression() : null;
            Expression elseIfExpr    = null;

            // else if statements
            if (ifStmt.ElseIfs != null && ifStmtElseIfs.Count > 0)
            {
                var        lastElseIf     = ifStmtElseIfs[ifStmtElseIfs.Count - 1];
                Expression lastElseIfExpr = elseBody == null
          ? Expression.IfThen(EmitExpression(lastElseIf.Condition), EmitStatement(lastElseIf.Body).ToBlockExpression())
          : Expression.IfThenElse(EmitExpression(lastElseIf.Condition), EmitStatement(lastElseIf.Body).ToBlockExpression(), elseBody);

                for (int i = ifStmtElseIfs.Count - 2; i >= 0; i--)
                {
                    var currentElseIf = ifStmtElseIfs[i];
                    elseIfExpr = Expression.IfThenElse(
                        EmitExpression(currentElseIf.Condition), EmitStatement(currentElseIf.Body).ToBlockExpression(),
                        Expression.Block(lastElseIfExpr));
                    lastElseIfExpr = elseIfExpr;
                }

                elseBody = Expression.Block(elseIfExpr ?? lastElseIfExpr);
            }

            blockCollector.AddExpression(elseBody == null
        ? Expression.IfThen(EmitExpression(ifStmt.Condition), EmitStatement(ifStmt.Body).ToBlockExpression())
        : Expression.IfThenElse(EmitExpression(ifStmt.Condition), EmitStatement(ifStmt.Body).ToBlockExpression(), elseBody));
        }
コード例 #3
0
        private void EmitTextWriteStatement <T>(T value, BlockCollector blockCollector)
        {
            var valueType = typeof(T);

            if (!_writeTextWriteMethodInfoMap.TryGetValue(valueType, out var methodInfo))
            {
                methodInfo = _defaultTextWriteMethodInfo;
            }
            blockCollector.AddExpression(Expression.Call(_textWriterParameter, methodInfo, Expression.Constant(value, valueType)));
        }
コード例 #4
0
        private void EmitOutputStatement(Statement.Output outputStmt, BlockCollector blockCollector)
        {
            var valExpr = EmitExpression(outputStmt.Expr);


            var valueType = valExpr.Type;

            if (!_writeTextWriteMethodInfoMap.TryGetValue(valueType, out var methodInfo))
            {
                methodInfo = _defaultTextWriteMethodInfo;
            }
            blockCollector.AddExpression(Expression.Call(_textWriterParameter, methodInfo, valExpr));
        }
コード例 #5
0
        private BlockCollector EmitStatement(IEnumerable <Statement> statements, BlockCollector blockCollector = null)
        {
            if (blockCollector == null)
            {
                blockCollector = new BlockCollector();
            }
            foreach (var statement in statements)
            {
                EmitStatement(statement, blockCollector);
            }

            return(blockCollector);
        }
コード例 #6
0
        private void EmitStatement(Statement statement, BlockCollector blockCollector)
        {
            switch (statement)
            {
            case Statement.Plain plainStmt:
                EmitTextWriteStatement <string>(plainStmt.Value.Value, blockCollector);
                break;

            case Statement.Output outputStmt:
                EmitOutputStatement(outputStmt, blockCollector);
                break;

            case SimpleLocalVariable simpleLocalVariableStmt:
                EmitSimpleLocalVariableStatement(simpleLocalVariableStmt, blockCollector);
                break;

            case CaptureLocalVariable captureLocalVariableStmt:
                break;

            case Statement.Unless unlessStmt:
                break;

            case Statement.If ifStmt:
                EmitIfStatement(ifStmt, blockCollector);
                break;

            case For forStmt:
                EmitForStatement(forStmt, blockCollector);
                break;

            case Statement.Break breakStmt:
                //blockCollector.AddExpression(Expression.Return(Expression.la))
                break;

            case Statement.Continue continueStmt:
                break;

            default:
                blockCollector.AddExpression(Expression.Empty());
                break;
            }
        }
コード例 #7
0
        private void EmitForStatement(For forStmtFor, BlockCollector blockCollector)
        {
            var forBlockCollector = new BlockCollector();
            var collectionExpr    = EmitExpression(forStmtFor.ForSource);
            var elementType       = _context.PredefinedTypes.GetDotNetType(forStmtFor.Symbol.Type);
            var enumerableType    = typeof(IEnumerable <>).MakeGenericType(elementType);
            var enumeratorType    = typeof(IEnumerator <>).MakeGenericType(elementType);

            var enumeratorVar     = Expression.Variable(enumeratorType, "enumerator");
            var getEnumeratorCall = Expression.Call(collectionExpr, enumerableType.GetMethod("GetEnumerator", BindingFlags.Instance | BindingFlags.Public));
            var enumeratorAssign  = Expression.Assign(enumeratorVar, getEnumeratorCall);

            blockCollector.AddVariable(enumeratorVar);
            // The MoveNext method's actually on IEnumerator, not IEnumerator<T>
            var moveNextCall = Expression.Call(enumeratorVar, typeof(IEnumerator).GetMethod("MoveNext", BindingFlags.Instance | BindingFlags.Public));
            var breakLabel   = Expression.Label("LoopBreak");

            var loopVar = Expression.Variable(elementType, forStmtFor.Name.Text);

            forBlockCollector.AddVariable(loopVar);
            _variablesMap[forStmtFor.Symbol] = loopVar;
            forBlockCollector.AddExpression(Expression.Assign(loopVar, Expression.Property(enumeratorVar, "Current")));
            EmitStatement(forStmtFor.Body, forBlockCollector);

            var loop = Expression.Block(new[] { enumeratorVar },
                                        enumeratorAssign,
                                        Expression.Loop(
                                            Expression.IfThenElse(
                                                Expression.Equal(moveNextCall, Expression.Constant(true)),
                                                forBlockCollector.ToBlockExpression(),
                                                Expression.Break(breakLabel)
                                                ),
                                            breakLabel)
                                        );

            blockCollector.AddExpression(loop);
        }
コード例 #8
0
        private void EmitSimpleLocalVariableStatement(SimpleLocalVariable simpleLocalVariableStmt, BlockCollector blockCollector)
        {
            if (_context.PredefinedTypes.DotNetTypesMap.TryGetValue(simpleLocalVariableStmt.Symbol.Type, out var type))
            {
                var variable   = Expression.Variable(type, simpleLocalVariableStmt.Name.Text);
                var assingExpr = Expression.Assign(variable, EmitExpression(simpleLocalVariableStmt.Initializer));
                blockCollector.AddVariable(variable).AddExpression(assingExpr);

                _variablesMap[simpleLocalVariableStmt.Symbol] = variable;
            }
        }