Ejemplo n.º 1
0
        private static PainContext InvokeMethodGetContext(
            String Method,
            IList <Object> MethodParameters,
            IDictionary <String, Object> Values,
            IDictionary <String, Object> StaticValues)
        {
            PainContext newContext = CreateContext(
                new PainCodeLines(),
                Values,
                StaticValues,
                false, true);
            PainObject globalObject = newContext.GlobalObject;

            ExpressionGroup expressionGroup = new ExpressionGroup(false);

            expressionGroup.MainExpression = new Expression();
            expressionGroup.MainExpression.IsOnpExecution = false;
            expressionGroup.MainExpression.Tokens         = new ExpressionTokens();

            expressionGroup.MainExpression.Tokens.Add(
                new ExpressionToken(Method, TokenType.VARIABLE));

            expressionGroup.MainExpression.Tokens.Add(
                new ExpressionToken('@', TokenType.OPERATOR));

            expressionGroup.MainExpression.Tokens.Add(
                new ExpressionToken('(', TokenType.BRACKET_BEGIN));

            if (MethodParameters != null)
            {
                Int32 i = -1;
                foreach (Object parameter in MethodParameters)
                {
                    i++;
                    if (i > 0)
                    {
                        expressionGroup.MainExpression.Tokens.Add(
                            new ExpressionToken(',', TokenType.SEPARATOR));
                    }

                    String parameterName = IdGenerator.Generate();
                    globalObject.DynamicValues[parameterName] = parameter; // much faster
                    //newContext[parameterName] = parameter;

                    expressionGroup.MainExpression.Tokens.Add(
                        new ExpressionToken(parameterName, TokenType.VARIABLE));
                }
            }

            expressionGroup.MainExpression.Tokens.Add(
                new ExpressionToken(')', TokenType.BRACKET_END));

            PainCodeLine lineOfCode = new PainCodeLine()
            {
                ExpressionGroup = expressionGroup,
                Depth           = 0,
                IsLineEmpty     = false,
                OperatorType    = EOperatorType.RETURN
            };

            newContext.GlobalState.Program.Lines.Add(lineOfCode);

            return(newContext);
        }
Ejemplo n.º 2
0
        public PainCodeLine SetCodeLine(PainCodeLine compiledLine, CodeLine line)
        {
            IList <Char> lineTrimmed = line.
                                       TrimStart().
                                       ToArray();

            IList <Char>  lineBody     = line;
            EOperatorType operatorType = EOperatorType.NONE;

            // IF: wykrycie definicji IF'a
            if (lineTrimmed.Count > str_if.Length &&
                StringHelper.StrEquals(lineTrimmed.TrimStart().ToArray(), str_if, true) &&
                Char.IsWhiteSpace(lineTrimmed[str_if.Length]))
            {
                Int32 depth = GetDepth(line);
                operatorType = EOperatorType.IF;

                lineBody = lineTrimmed.
                           Substring2(str_if.Length).
                           TrimStart().
                           ToList();

                for (int i = 0; i < depth; i++)
                {
                    lineBody.Insert(0, ' ');
                }
                lineBody.TrimEnd(':');
            }
            // WHILE: wykrycie definicji WHILE'a
            else if (lineTrimmed.Count > str_while.Length &&
                     StringHelper.StrEquals(lineTrimmed.TrimStart().ToArray(), str_while, true) &&
                     Char.IsWhiteSpace(lineTrimmed[str_while.Length]))
            {
                Int32 depth = GetDepth(line);
                operatorType = EOperatorType.WHILE;

                lineBody = lineTrimmed.
                           Substring2(str_while.Length).
                           TrimStart().
                           ToList();

                for (int i = 0; i < depth; i++)
                {
                    lineBody.Insert(0, ' ');
                }
                lineBody.TrimEnd(':');
            }
            // ELSE: wykrycie definicji ELSE'a
            else if (lineTrimmed.Count >= str_else.Length &&
                     StringHelper.StrEquals(lineTrimmed.TrimStart().ToArray(), str_else, true))
            {
                Int32 depth = GetDepth(line);
                operatorType = EOperatorType.ELSE;

                lineBody = lineTrimmed.
                           Substring2(str_else.Length).
                           TrimStart().
                           ToList();

                for (int i = 0; i < depth; i++)
                {
                    lineBody.Insert(0, ' ');
                }
                lineBody.TrimEnd(':');
            }
            // ELIF: wykrycie definicji ELIF'a
            else if (lineTrimmed.Count > str_elif.Length &&
                     StringHelper.StrEquals(lineTrimmed.TrimStart().ToArray(), str_elif, true) &&
                     Char.IsWhiteSpace(lineTrimmed[str_elif.Length]))
            {
                Int32 depth = GetDepth(line);
                operatorType = EOperatorType.ELIF;

                lineBody = lineTrimmed.
                           Substring2(str_elif.Length).
                           TrimStart().
                           ToList();

                for (int i = 0; i < depth; i++)
                {
                    lineBody.Insert(0, ' ');
                }
                lineBody.TrimEnd(':');
            }
            // RETURN: wykrycie definicji RETURN'a
            else if (lineTrimmed.Count > str_return.Length &&
                     StringHelper.StrEquals(lineTrimmed.TrimStart().ToArray(), str_return, true) &&
                     Char.IsWhiteSpace(lineTrimmed[str_return.Length]))
            {
                Int32 depth = GetDepth(line);
                operatorType = EOperatorType.RETURN;

                lineBody = lineTrimmed.
                           Substring2(str_return.Length).
                           TrimStart().
                           ToList();

                for (int i = 0; i < depth; i++)
                {
                    lineBody.Insert(0, ' ');
                }
                lineBody.TrimEnd(':');
            }
            // TRY: wykrycie definicji TRY'a
            else if (lineTrimmed.Count > str_try.Length &&
                     StringHelper.StrEquals(lineTrimmed.TrimStart().ToArray(), str_try, true) /*&&
                                                                                               * Char.IsWhiteSpace(lineTrimmed[str_try.Length])*/)
            {
                Int32 depth = GetDepth(line);
                operatorType = EOperatorType.TRY;

                lineBody = lineTrimmed.
                           Substring2(str_try.Length).
                           TrimStart().
                           ToList();

                for (int i = 0; i < depth; i++)
                {
                    lineBody.Insert(0, ' ');
                }
                lineBody.TrimEnd(':');
            }
            // CATCH: wykrycie definicji CATCH'a
            else if (lineTrimmed.Count > str_catch.Length &&
                     StringHelper.StrEquals(lineTrimmed.TrimStart().ToArray(), str_catch, true) /*&&
                                                                                                 * Char.IsWhiteSpace(lineTrimmed[str_catch.Length])*/)
            {
                Int32 depth = GetDepth(line);
                operatorType = EOperatorType.CATCH;

                lineBody = lineTrimmed.
                           Substring2(str_catch.Length).
                           TrimStart().
                           ToList();

                for (int i = 0; i < depth; i++)
                {
                    lineBody.Insert(0, ' ');
                }
                lineBody.TrimEnd(':');
            }
            // FINALLY: wykrycie definicji FINALLY'a
            else if (lineTrimmed.Count > str_finally.Length &&
                     StringHelper.StrEquals(lineTrimmed.TrimStart().ToArray(), str_finally, true) /*&&
                                                                                                   * Char.IsWhiteSpace(lineTrimmed[str_finally.Length])*/)
            {
                Int32 depth = GetDepth(line);
                operatorType = EOperatorType.FINALLY;

                lineBody = lineTrimmed.
                           Substring2(str_finally.Length).
                           TrimStart().
                           ToList();

                for (int i = 0; i < depth; i++)
                {
                    lineBody.Insert(0, ' ');
                }
                lineBody.TrimEnd(':');
            }
            // THROW: wykrycie definicji THROW'a
            else if (lineTrimmed.Count > str_throw.Length &&
                     StringHelper.StrEquals(lineTrimmed.TrimStart().ToArray(), str_throw, true) /*&&
                                                                                                 * Char.IsWhiteSpace(lineTrimmed[str_THROW.Length])*/)
            {
                Int32 depth = GetDepth(line);
                operatorType = EOperatorType.THROW;

                lineBody = lineTrimmed.
                           Substring2(str_throw.Length).
                           TrimStart().
                           ToList();

                for (int i = 0; i < depth; i++)
                {
                    lineBody.Insert(0, ' ');
                }
                lineBody.TrimEnd(':');
            }

            ExpressionGroup expressionGroup = TokenizerInvariant.I.
                                              Compile(lineBody);

            if (compiledLine == null)
            {
                compiledLine = new PainCodeLine();
            }

            compiledLine.Code            = line.ToString2();
            compiledLine.ExpressionGroup = expressionGroup;
            compiledLine.OperatorType    = operatorType;
            compiledLine.IsLineEmpty     = lineTrimmed.Count == 0;
            compiledLine.Depth          += GetDepth(lineBody);

            return(compiledLine);
        }
Ejemplo n.º 3
0
        private static LinqExpression[] CompileGroup(ExpressionGroup group, CompilationData data)
        {
            switch (group)
            {
            case Persist p:
                foreach (var s in p.State)
                {
                    if (!(s.InitialValue is Constant))
                    {
                        throw new Exception("Persist initial value is not constant");
                    }

                    data.StateValues.Add(((Constant)s.InitialValue).Value);
                }

                var assigns = new List <LinqExpression>();
                // TODO: Resolve parent scopes
                data.ResolveState = s => LinqExpression.ArrayAccess(data.StateArray, LinqExpression.Constant(s.Id));
                for (var i = 0; i < p.NewValue.Count; i++)
                {
                    var newValueExpr = Compile(p.NewValue[i], data);
                    assigns.Add(LinqExpression.Assign(
                                    LinqExpression.ArrayAccess(data.StateArray, LinqExpression.Constant(i)), newValueExpr));
                }

                data.Statements.AddRange(assigns);
                return(Enumerable.Range(0, p.Size)
                       .Select(i => LinqExpression.ArrayAccess(data.StateArray, LinqExpression.Constant(i)))
                       .ToArray());

            case Loop l:
                var stateList = new List <ParameterExpression>();
                foreach (var s in l.State)
                {
                    var initial  = Compile(s.InitialValue, data);
                    var variable = LinqExpression.Variable(initial.Type);
                    data.Statements.Add(LinqExpression.Assign(variable, initial));
                    data.Variables.Add(variable);
                    stateList.Add(variable);
                }

                // TODO: Resolve parent scopes
                data.ResolveState = s => stateList[s.Id];
                var parentStatements = data.Statements;
                // Make a new cache that copies in the old one, but won't leak State expressions
                data.Cache = new Dictionary <CachedExpression, ParameterExpression>(data.Cache);

                // Create a new statements list to put in the loop body
                var s1        = data.Statements = new List <LinqExpression>();
                var condition = Compile(l.Condition, data);
                var s2        = data.Statements = new List <LinqExpression>();
                var newState  = l.Body.Select(e => Compile(e, data)).ToArray();

                // Ensure that the entire state is only set at the end of the loop
                for (var i = 0; i < newState.Length; i++)
                {
                    var s = newState[i];
                    if (!(s is ParameterExpression))
                    {
                        var tmpVar = LinqExpression.Variable(s.Type);
                        data.Variables.Add(tmpVar);
                        s2.Add(LinqExpression.Assign(tmpVar, s));
                        newState[i] = tmpVar;
                    }
                }

                var breakLabel = LinqExpression.Label();
                var body       = LinqExpression.Block(s1
                                                      .Concat(new[]
                {
                    LinqExpression.IfThen(
                        LinqExpression.LessThan(condition, LinqExpression.Constant(1f)),
                        LinqExpression.Break(breakLabel))
                })
                                                      .Concat(s2)
                                                      .Concat(newState.Select((e, i) =>
                                                                              LinqExpression.Assign(stateList[i], e))));
                parentStatements.Add(LinqExpression.Loop(body, breakLabel));
                return(stateList.ToArray());

            default:
                throw new NotSupportedException();
            }
        }