Ejemplo n.º 1
0
        /// <summary>
        /// Высокий приоритет
        /// </summary>
        /// <returns>результат выражения</returns>
        protected ExprResult Term()
        {
            ExprResult result = Factor();

            while (true)
            {
                switch (e.Current.Token)
                {
                case DelphiTokens.Multiply:
                case DelphiTokens.Division:
                case DelphiTokens.Div:
                case DelphiTokens.Mod:
                case DelphiTokens.And:
                case DelphiTokens.Shl:
                case DelphiTokens.Shr:
                    result.WasOperand = true;
                    e.Next();
                    result.Add(Factor());
                    break;

                default:
                    return(result);
                }
            }
        }
Ejemplo n.º 2
0
        private ExprResult Assignment()
        {
            /*
             * assignment → IDENTIFIER "=" assignment
             *              | logic_or ;
             */
            //https://craftinginterpreters.com/statements-and-state.html#assignment
            return
                (from expr in LogicOr()        //if left is a valid expression
                 from expr2 in LookAhead(expr) //look to see if it's an assignment
                 select expr2);                //if not, return expr we gave to the lookahead

            ExprResult LookAhead(Expr expr)
            {
                if (Match(TokenType.Equal))
                {
                    var eq = PreviousToken();
                    return
                        (from value in Assignment() //recurse to snag the right hand expr
                         from assignment in VariableAssignment(expr, value, eq)
                         select assignment);
                }
                return(ExprResult.Ok(expr)); //not a variable assignment, give the plain expr back
            }

            ExprResult VariableAssignment(Expr expr, Expr value, Token equals) =>
            (expr is VariableExpr variable)
                    ? ExprResult.Ok(new AssignExpr(variable.name, value))
                    : ExprResult.Err(new ParseError(equals, "Invalid assignment target."));
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Низший приоритет
        /// </summary>
        /// <returns>результат выражения</returns>
        protected ExprResult Expression()
        {
            ExprResult result = SimpleExpression();

            while (true)
            {
                switch (e.Current.Token)
                {
                case DelphiTokens.Equal:
                case DelphiTokens.Less:
                case DelphiTokens.Greater:
                case DelphiTokens.LessOrEqual:
                case DelphiTokens.GreaterOrEqual:
                case DelphiTokens.NotEqual:
                case DelphiTokens.In:
                case DelphiTokens.Is:
                case DelphiTokens.As:
                    result.WasOperand = true;
                    e.Next();
                    result.Add(SimpleExpression());
                    break;

                default:
                    return(result);
                }
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Наивысший приоритет
        /// </summary>
        /// <returns>результат выражения</returns>
        protected ExprResult Factor()
        {
            ExprResult result = new ExprResult();

            switch (e.Current.Token)
            {
            case DelphiTokens.Not:
            case DelphiTokens.AtSign:
            case DelphiTokens.Inherited:
                e.Next();
                result.Add(Factor());
                break;

            case DelphiTokens.String:
            case DelphiTokens.Char:
            case DelphiTokens.Addition:
            case DelphiTokens.Subtraction:
            case DelphiTokens.Digits:
            case DelphiTokens.HexConstant:
            case DelphiTokens.True:
            case DelphiTokens.False:
                result.Value = Const();
                break;

            default:
                Variable();
                result.IsConstant = false;
                break;
            }
            return(result);
        }
Ejemplo n.º 5
0
        private StmtResult VarDeclaration() =>

        /*
         * varDecl → "var" IDENTIFIER ( "=" expression )? ";" ;
         */
        from name in Consume(TokenType.Identifier, "Expected variable name.")
        from initializer in Match(TokenType.Equal) ? Expression() : ExprResult.Ok(null)
        from _ in Consume(TokenType.Semicolon, "Expected ';' after variable declaration.")
        select new VarStmt(name, initializer) as Stmt;
Ejemplo n.º 6
0
 /// <summary>
 /// Объединить результаты двух выражений
 /// </summary>
 /// <param name="parent"></param>
 public void Add(ExprResult parent)
 {
     this.isConstant &= parent.isConstant;
     this.wasOperand |= parent.wasOperand;
     this.wasValue   |= parent.wasValue;
     if (!this.wasValue)
     {
         this.value = parent.value;
     }
 }
Ejemplo n.º 7
0
        private StmtResult ReturnStatement()
        {
            // returnStmt → "return" expression? ";" ;
            var keyword = PreviousToken();

            return
                (from value in !Check(TokenType.Semicolon) ? Expression() : ExprResult.Ok(null)
                 from token in Consume(TokenType.Semicolon, "Expected ';' after return value.")
                 select new ReturnStmt(keyword, value) as Stmt);
        }
Ejemplo n.º 8
0
        private ExprResult ParseLogicalExpr(TokenType tokenType, Func <ExprResult> current, Func <ExprResult> next)
        {
            // current -> next ( "token" next )* ;
            ExprResult ParseRight(Expr left)
            {
                var @operator = PreviousToken();

                return
                    (from right in current()
                     select new LogicalExpr(left, @operator, right) as Expr);
            }

            return
                (from left in next()
                 from right in Match(tokenType) ? ParseRight(left) : ExprResult.Ok(left)
                 select right);
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Собственно анализ
        /// </summary>
        /// <param name="sender">инициатор события</param>
        /// <param name="e">список токенов</param>
        protected override void DoAnalyse(AnalyserParameters e)
        {
            e.First();
            this.e = e;
            ExprResult expr = Expression();

            if (expr.IsConstant && !expr.WasOperand)
            {
                if ((expr.Value.GetType() == typeof(Int32)) && !(settings as AnalyserSettings.CaseConditionSettings).StdNumbers.Contains(Convert.ToInt32(expr.Value)))
                {
                    AddError(e, 0);
                }
                else if ((settings as AnalyserSettings.CaseConditionSettings).LocateStd)
                {
                    AddError((settings as AnalyserSettings.CaseConditionSettings).Message, (settings as AnalyserSettings.CaseConditionSettings).StdLevel, e.File, e[0].Line, e[0].MetaTags);
                }
            }
        }
Ejemplo n.º 10
0
        private IEnumerable <ExprResult> Arguments()
        {
            //arguments → expression ( "," expression )* ;
            if (!Check(TokenType.RightParen))
            {
                var counter = 0;
                do
                {
                    // maximum args; for compat with bytecode version
                    if (counter >= 255)
                    {
                        yield return(ExprResult.Err(new ParseError(Peek(), "Can't have more than 255 arguments.")));

                        yield break;
                    }
                    counter++;
                    yield return(Expression());
                } while (Match(TokenType.Comma));
            }
        }
Ejemplo n.º 11
0
 private ExprResult ParseBinaryOperation(Func <ExprResult> next, params TokenType[] tokenTypes)
 {
     /*
      * current -> next ( ( tokenA | tokenB | etc. ) next )* ;
      */
     return
         (next()
          .Bind(expr => {
         var result = ExprResult.Ok(expr);
         while (Match(tokenTypes))
         {
             var @operator = PreviousToken();
             result =
                 next()
                 .Bind(right =>
                       ExprResult.Ok(new BinaryExpr(expr, @operator, right))
                       );
         }
         return result;
     }));
 }
Ejemplo n.º 12
0
        /// <summary>
        /// Низкий приоритет
        /// </summary>
        /// <returns>результат выражения</returns>
        protected ExprResult SimpleExpression()
        {
            ExprResult result = Term();

            while (true)
            {
                switch (e.Current.Token)
                {
                case DelphiTokens.Addition:
                case DelphiTokens.Subtraction:
                case DelphiTokens.Or:
                case DelphiTokens.Xor:
                    result.WasOperand = true;
                    e.Next();
                    result.Add(Term());
                    break;

                default:
                    return(result);
                }
            }
        }
Ejemplo n.º 13
0
        private ExprResult Primary()
        {
            /*
             * primary → NUMBER | STRING | "true" | "false" | "nil"
             *         | "(" expression ")"
             *         | IDENTIFIER ;
             */
            if (Match(TokenType.False))
            {
                return(ExprResult.Ok(new LiteralExpr(false)));
            }
            if (Match(TokenType.True))
            {
                return(ExprResult.Ok(new LiteralExpr(true)));
            }
            if (Match(TokenType.Nil))
            {
                return(ExprResult.Ok(new LiteralExpr(null)));
            }
            if (Match(TokenType.Number, TokenType.String))
            {
                return(ExprResult.Ok(new LiteralExpr(PreviousToken().Literal)));
            }
            if (Match(TokenType.Identifier))
            {
                return(ExprResult.Ok(new VariableExpr(PreviousToken())));
            }

            if (Match(TokenType.LeftParen))
            {
                return
                    (from expr in Expression()
                     from token in Consume(TokenType.RightParen, "Expected ')' after expression.")
                     select new GroupingExpr(expr) as Expr);
            }

            return(ExprResult.Err(new ParseError(Peek(), "Expected expression.")));
        }
Ejemplo n.º 14
0
 private ExprResult Call() =>
 // call → primary ( "(" arguments? ")" )* ;
 from expr in Primary()
 from call in Match(TokenType.LeftParen) ? FinishCall(expr) : ExprResult.Ok(expr)
 select call;
Ejemplo n.º 15
0
        private StmtResult ForStatement()
        {
            /*
             * forStmt → "for" "(" ( varDecl | exprStmt | ";" )
             *           expression? ";"
             *           expression? ")" statement ;
             */
            StmtResult ForInitializer()
            {
                if (Match(TokenType.Semicolon))
                {
                    return(StmtResult.Ok(null));
                }
                if (Match(TokenType.Var))
                {
                    return(VarDeclaration());
                }
                return(ExpressionStatement());
            }

            ExprResult ForCondition()
            {
                if (Check(TokenType.Semicolon))
                {
                    return(ExprResult.Ok(null));
                }
                return(Expression());
            }

            ExprResult ForIncrementer()
            {
                if (Check(TokenType.RightParen))
                {
                    return(ExprResult.Ok(null));
                }
                return(Expression());
            }

            Stmt BuildForAst(Stmt initializer, Expr condition, Expr incrementer, Stmt statement)
            {
                // express `for(var i = 0; i < 10; i++) { statement }` as a while loop;
                // var i = 0;
                // while(i<10) {
                //   { statement; }
                //   i++;
                // }
                var body = incrementer is null ? statement : new BlockStmt(new List <Stmt>()
                {
                    statement, new ExpressionStmt(incrementer)
                });
                var cond  = condition ?? new LiteralExpr(true);
                var loop  = new WhileStmt(cond, body);
                var block = initializer is null ? loop : new BlockStmt(new List <Stmt>()
                {
                    initializer, loop
                }) as Stmt;

                return(block);
            }

            return
                (from lParen in Consume(TokenType.LeftParen, "Expected '(' after 'for'.")
                 from initializer in ForInitializer() //first semi is parsed as part of initializer
                 from condition in ForCondition()
                 from semi2 in Consume(TokenType.Semicolon, "Expected ';' after condition.")
                 from incrementer in ForIncrementer()
                 from rParen in Consume(TokenType.RightParen, "Expected ')' after increment expression.")
                 from statement in Statement()
                 select BuildForAst(initializer, condition, incrementer, statement));
        }
            internal static AutoCrudMetadata Create(Type dtoType)
            {
                if (cache.TryGetValue(dtoType, out var to))
                {
                    return(to);
                }

                to = new AutoCrudMetadata {
                    DtoType   = dtoType,
                    ModelType = GetModelType(dtoType),
                    DtoProps  = TypeProperties.Get(dtoType),
                };
                if (to.ModelType != null)
                {
                    to.ModelDef = to.ModelType.GetModelMetadata();
                }

                to.RowVersionGetter = to.DtoProps.GetPublicGetter(Keywords.RowVersion);

                var dtoAttrs = dtoType.AllAttributes();

                foreach (var dtoAttr in dtoAttrs)
                {
                    if (dtoAttr is AutoPopulateAttribute populateAttr)
                    {
                        to.PopulateAttrs ??= new List <AutoPopulateAttribute>();
                        to.PopulateAttrs.Add(populateAttr);
                    }
                    else if (dtoAttr is AutoFilterAttribute filterAttr)
                    {
                        to.AutoFilters ??= new List <AutoFilterAttribute>();
                        to.AutoFiltersDbFields ??= new List <QueryDbFieldAttribute>();

                        to.AutoFilters.Add(filterAttr);
                        to.AutoFiltersDbFields.Add(ExprResult.ToDbFieldAttribute(filterAttr));
                    }
                }

                foreach (var pi in to.DtoProps.PublicPropertyInfos)
                {
                    var allAttrs = pi.AllAttributes();
                    var propName = pi.Name;

                    if (allAttrs.FirstOrDefault(x => x is AutoMapAttribute) is AutoMapAttribute mapAttr)
                    {
                        to.MapAttrs ??= new Dictionary <string, AutoMapAttribute>();
                        to.MapAttrs[propName] = mapAttr;
                        propName = mapAttr.To;
                    }

                    if (allAttrs.FirstOrDefault(x => x is AutoUpdateAttribute) is AutoUpdateAttribute updateAttr)
                    {
                        to.UpdateAttrs ??= new Dictionary <string, AutoUpdateAttribute>();
                        to.UpdateAttrs[propName] = updateAttr;
                    }

                    if (allAttrs.FirstOrDefault(x => x is AutoDefaultAttribute) is AutoDefaultAttribute defaultAttr)
                    {
                        to.DefaultAttrs ??= new Dictionary <string, AutoDefaultAttribute>();
                        to.DefaultAttrs[propName] = defaultAttr;
                    }

                    if (pi.PropertyType.IsNullableType())
                    {
                        to.NullableProps ??= new HashSet <string>();
                        to.NullableProps.Add(propName);
                    }
                }

                return(cache[dtoType] = to);
            }
        internal bool GetAutoFilterExpressions(IDbConnection db, object dto, Dictionary <string, object> dtoValues, IRequest req, out string expr, out List <object> exprParams)
        {
            var meta = AutoCrudMetadata.Create(dto.GetType());

            if (meta.AutoFilters != null)
            {
                var dialectProvider = db.GetDialectProvider();
                var sb             = StringBuilderCache.Allocate();
                var exprParamsList = new List <object>();

                //Update's require PK's, Delete's don't need to
                if (dtoValues.TryRemove(meta.ModelDef.PrimaryKey.Name, out var idValue))
                {
                    var idColumn = dialectProvider.GetQuotedColumnName(meta.ModelDef, meta.ModelDef.PrimaryKey);
                    sb.Append(idColumn + " = {0}");
                    exprParamsList.Add(idValue);
                }

                var appHost = HostContext.AppHost;
                for (var i = 0; i < meta.AutoFilters.Count; i++)
                {
                    var filter = meta.AutoFilters[i];
                    var dbAttr = meta.AutoFiltersDbFields[i];

                    var fieldDef = meta.ModelDef.GetFieldDefinition(filter.Field);
                    if (fieldDef == null)
                    {
                        throw new NotSupportedException($"{dto.GetType().Name} '{filter.Field}' AutoFilter was not found on '{meta.ModelType.Name}'");
                    }

                    var quotedColumn = dialectProvider.GetQuotedColumnName(meta.ModelDef, fieldDef);

                    var value = appHost.EvalScriptValue(filter, req);

                    var ret = ExprResult.CreateExpression("AND", quotedColumn, value, dbAttr);


                    if (ret != null)
                    {
                        if (sb.Length > 0)
                        {
                            sb.Append(" AND ");
                        }

                        var exprResult = ret.Value;
                        if (exprResult.Format.IndexOf("{1}", StringComparison.Ordinal) >= 0)
                        {
                            throw new NotSupportedException($"SQL Template '{exprResult.Format}' with multiple arguments is not supported");
                        }

                        if (exprResult.Values != null)
                        {
                            for (var index = 0; index < exprResult.Values.Length; index++)
                            {
                                sb.Append(exprResult.Format.Replace("{" + index + "}", "{" + exprParamsList.Count + "}"));
                                exprParamsList.Add(exprResult.Values[index]);
                            }
                        }
                    }

                    expr       = StringBuilderCache.ReturnAndFree(sb);
                    exprParams = exprParamsList;
                    return(true);
                }
            }

            expr       = null;
            exprParams = null;
            return(false);
        }