예제 #1
0
 public bool Parse(TokensReader expression, bool expression_end)
 {
     body   = null;
     haveIf = false;
     if (expression.tokens.Pop() == TokenType.ELSE)
     {
         TokensReader backup = new TokensReader();
         backup.Add(expression);
         try
         {
             if (ift.Parse(expression, expression_end))
             {
                 haveIf = true;
                 return(true);
             }
         }
         finally { }
         if (expression_end)
         {
             body = backup;
         }
         return(true);
     }
     else
     {
         return(false);
     }
 }
예제 #2
0
        public bool Parse(TokensReader expression, bool expression_end)
        {
            field     = null;
            local     = null;
            valuetype = null;
            if (expression.tokens.Pop() == TokenType.LITERAL && expression_end)
            {
                expression.tokens.Insert(0, TokenType.LITERAL);
                TokensReader backup = new TokensReader();
                backup.Add(expression);
                local = PartTemplate.ParseLocal(ref expression);
                if (local == null) // is field
                {
                    expression = backup;
                    field      = PartTemplate.ParseField(ref expression);
                }

                if (expression.tokens.Pop() == TokenType.OPERATOR && expression.operators.Pop() == OperatorType.ASSIGN)
                {
                    valuetype = PartTemplate.ParseValue(ref expression);
                    if (expression.tokens.Count == 0)
                    {
                        return(true);
                    }
                    else
                    {
                        return(false);
                    }
                }
                else
                {
                    return(false);
                }
            }
            else
            {
                return(false);
            }
        }
예제 #3
0
        /// <summary>
        /// Parse getted expression
        /// </summary>
        public void ParseExpression(TokensReader expr)
        {
            bool error  = false;
            int  trypos = -1;

            try
            {
                if (expr.tokens.IsEmpty())
                {
                    return;
                }
reparse:
                TokensTemplate template = strongTemplates[expr.tokens[0]];
                try
                {
                    if (template.Parse(expr, exprend))
                    {
                        List <TokensError> errs = template.Run();
                        if (!errs.IsEmpty())
                        {
                            errors.AddRange(errs);
                            error = true;
                        }
                    }
                    else
                    {
                        error = true;
                    }
                }
                catch
                {
                    error = true;
                }
                if (error)
                {
                    if (!tryTokens.IsEmpty())
                    {
                        LaterCalls.RemoveLast();
                        if (trypos < 0)
                        {
                            if (tryPositions.IsEmpty()) // TODO: need to change text of error
                            {
                                errors.Add(new InvalidTokensTemplateError(line, "tryPositions is empty"));
                                tryTokens.Clear(); // сделаем это для того, чтобы эта ошибка не повторялась
                                return;            // беспричинно и не было исключений (переведите на английский пж)
                            }
                            else
                            {
                                trypos = tryPositions.Pop();
                            }
                        }
                        expr.tokens.RemoveAt(trypos);
                        if (count == 0)
                        {
                            count = tryCounts.Pop();
                        }
                        if (count > 0)
                        {
                            count--;
                            expr.tokens.Insert(trypos, tryTokens.Pop());
                            goto reparse;
                        }
                    }
                    else
                    {
                        errors.Add(new InvalidTokensTemplateError(line, $"Invalid template of token {expression.tokens[0]}"));
                    }
                }
            }
            catch (KeyNotFoundException)
            {
reparse:
                foreach (TokensTemplate template in flexTemplates)
                {
                    TokensReader backup = new TokensReader();
                    backup.Add(expr);
                    try
                    {
                        if (template.Parse(expr, exprend))
                        {
                            errors.AddRange(template.Run());
                            return;
                        }
                        else
                        {
                            expr = backup;
                        }
                    }
                    catch { expr = backup; }
                }
                if (!tryTokens.IsEmpty())
                {
                    LaterCalls.RemoveLast();
                    if (trypos < 0)
                    {
                        if (tryPositions.IsEmpty()) // TODO: need to change text of error
                        {
                            errors.Add(new InvalidTokensTemplateError(line, "tryPositions is empty"));
                            tryTokens.Clear(); // сделаем это для того, чтобы эта ошибка не повторялась
                            return;            // беспричинно и не было исключений (переведите на английский пж)
                        }
                        else
                        {
                            trypos = tryPositions.Pop();
                        }
                    }
                    expr.tokens.RemoveAt(trypos);
                    if (count == 0)
                    {
                        count = tryCounts.Pop();
                    }
                    if (count > 0)
                    {
                        count--;
                        expr.tokens.Insert(trypos, tryTokens.Pop());
                        goto reparse;
                    }
                }
                else
                {
                    errors.Add(new InvalidTokensTemplateError(line, $"Unknown tokens template {string.Join(" ", expr.tokens)}"));
                }
            }
            finally
            {
                if (isFuncBody && needLaterCall)
                {
                    LaterCalls.Call();
                }
                needLaterCall = true;
                tryTokens.Clear();
            }
        }
예제 #4
0
        public static Type ParseValue(ref TokensReader expression)
        {
            Type      type  = null;
            TokenType token = expression.tokens.Pop();

            if (token == TokenType.VALUE)
            {
                byte valtype = expression.byte_values.Pop();
                if (valtype == 0)
                {
                    type = typeof(object);
                }
                else if (valtype == 1)
                {
                    type = typeof(int);
                }
                else if (valtype == 2)
                {
                    type = typeof(string);
                }
                else if (valtype == 3)
                {
                    type = typeof(sbyte);
                }
                else if (valtype == 4)
                {
                    type = typeof(bool);
                }
                else if (valtype == 5)
                {
                    type = typeof(char);
                }
                else if (valtype == 6)
                {
                    type = typeof(float);
                }
                else if (valtype == 7)
                {
                    type = typeof(short);
                }
                else if (valtype == 8)
                {
                    type = typeof(long);
                }
                else if (valtype == 9)
                {
                    type = typeof(double);
                }
                LaterCalls.LoadObject(expression.values.Pop());
            }
            else if (token == TokenType.LITERAL) // is method
            {
                expression.tokens.Insert(0, TokenType.LITERAL);
                TokensReader backup = new TokensReader();
                backup.Add(expression);
                MethodInfo method = ParseCallMethod(ref expression);
                if (method == null) // is local
                {
                    expression = backup;
                    LocalBuilder local = ParseLocal(ref expression);
                    if (local != null)
                    {
                        LaterCalls.LoadLocal(local);
                        type = local.LocalType;
                    }
                    else // is field
                    {
                        expression = backup;
                        FieldInfo value = ParseField(ref expression);
                        LaterCalls.LoadField(value);
                        type = value.FieldType;
                    }
                }
                else
                {
                    type = method.ReturnType;
                }
            }
            else if (token == TokenType.NEW)
            {
                type = ParseNewObject(ref expression);
            }
            else if (token == TokenType.STATEMENT)
            {
                if (expression.bool_values.Pop())
                {
                    type = ParseSmallStatement(ref expression);
                }
                else
                {
                    if (lvlStatement == 0)
                    {
                        errors.Add(new InvalidTokenError(line, $"There are wrong 'closing statement' token"));
                    }
                    else
                    {
                        lvlStatement--;
                    }
                }
            }
            else if (token == TokenType.OPERATOR)
            {
                OperatorType op = expression.operators.Pop();
            }
            if (!expression.tokens.IsEmpty() && expression.tokens[0] == TokenType.OPERATOR)
            {
                expression.tokens.RemoveAt(0);
                OperatorType op = expression.operators.Pop();
                if (type != null)
                {
                    if (type == ParseValue(ref expression))
                    {
                        LaterCalls.LoadOperator(type, op);
                    }
                    else
                    {
                        errors.Add(new InvalidTypeError(
                                       line, $"Type {type} before operator {op} not equals type of value after operator"));
                    }
                }
                switch (op)
                {
                case OperatorType.EQ:
                case OperatorType.NOTEQ:
                case OperatorType.NOT:
                case OperatorType.AND:
                case OperatorType.OR:
                case OperatorType.GT:
                case OperatorType.LT:
                case OperatorType.GORE:
                case OperatorType.LORE:
                case OperatorType.IN:
                    type = typeof(bool);
                    break;

                case OperatorType.RANGE:
                    break;

                case OperatorType.POW:
                    type = typeof(float);
                    break;
                }
            }
            return(type);
        }