示例#1
0
        protected void EliminateVariable(JSNode context, JSVariable variable, JSExpression replaceWith, QualifiedMemberIdentifier method)
        {
            {
                var replacer = new VariableEliminator(
                    variable,
                    JSChangeTypeExpression.New(replaceWith, variable.GetActualType(TypeSystem), TypeSystem)
                    );
                replacer.Visit(context);
            }

            {
                var replacer    = new VariableEliminator(variable, replaceWith);
                var assignments = (from a in FirstPass.Assignments where
                                   variable.Equals(a.NewValue) ||
                                   a.NewValue.SelfAndChildrenRecursive.Any(variable.Equals)
                                   select a).ToArray();

                foreach (var a in assignments)
                {
                    if (!variable.Equals(a.NewValue))
                    {
                        replacer.Visit(a.NewValue);
                    }
                }
            }

            Variables.Remove(variable.Identifier);
            FunctionSource.InvalidateFirstPass(method);
        }
示例#2
0
        public void VisitNode(JSFunctionExpression fn)
        {
            Function  = fn;
            FirstPass = GetFirstPass(Function.Method.QualifiedIdentifier);

            VisitChildren(fn);

            if (EnumeratorsToKill.Count > 0)
            {
                // Rerun the static analyzer since we made major changes
                FunctionSource.InvalidateFirstPass(Function.Method.QualifiedIdentifier);
                FirstPass = GetFirstPass(Function.Method.QualifiedIdentifier);

                // Scan to see if any of the enumerators we eliminated uses of are now
                //  unreferenced. If they are, eliminate them entirely.
                foreach (var variable in EnumeratorsToKill)
                {
                    var variableName = variable.Name;
                    var accesses     = (
                        from a in FirstPass.Accesses
                        where a.Source.Name == variableName
                        select a
                        );

                    if (!accesses.Any())
                    {
                        var eliminator = new VariableEliminator(
                            variable, new JSNullExpression()
                            );
                        eliminator.Visit(fn);
                    }
                }
            }
        }
示例#3
0
        private bool SimplifyControlFlow()
        {
            if (Configuration.CodeGenerator.EliminateRedundantControlFlow.GetValueOrDefault(true))
            {
                bool shouldInvalidate = false;
                bool shouldCollapse   = false;
                bool shouldRun        = true;

                while (shouldRun)
                {
                    var cfs = new ControlFlowSimplifier();
                    cfs.Visit(Function);
                    shouldRun         = cfs.MadeChanges;
                    shouldCollapse   |= cfs.MadeChanges;
                    shouldInvalidate |= cfs.MadeChanges;
                }

                // HACK: Control flow simplification probably generated lots of nulls, so let's collapse them.
                // This makes it possible for loop simplification to work right later on.
                if (shouldCollapse)
                {
                    CollapseNulls();
                }

                if (shouldInvalidate)
                {
                    FunctionSource.InvalidateFirstPass(Identifier);
                }
            }

            return(true);
        }
示例#4
0
            protected internal override Node VisitFunctionSource([NotNull] FunctionSource node)
            {
                this.Visit(node.Function);

                this.Builder.Append($" {node.Alias}");

                return(node);
            }
            protected internal override Node VisitFunctionSource(FunctionSource node)
            {
                node = (FunctionSource)base.VisitFunctionSource(node);

                var function = this.data.ConvertToLinqExpression(node.Function);

                this.data.SetFactoryExpression(node, Evaluator.CreateDataSource(function, node.Alias));

                return(node);
            }
示例#6
0
        private static FunctionSource FunctionSourceFromDictionary(Dictionary <string, ExternalFunction> functions)
        {
            functions = functions ?? new Dictionary <string, ExternalFunction>();
            var functionSource = new FunctionSource();

            foreach (var kvp in functions)
            {
                functionSource.TryAddValue(kvp.Key, new Function(kvp.Value));
            }
            return(functionSource);
        }
        bool DoesValueEscapeFromInvocation(JSInvocationExpression invocation, JSExpression argumentExpression, bool includeReturn)
        {
            if (
                (invocation != null) &&
                (invocation.JSMethod != null) &&
                (invocation.JSMethod.Reference != null)
                )
            {
                var methodDef  = invocation.JSMethod.Reference.Resolve();
                var secondPass = FunctionSource.GetSecondPass(invocation.JSMethod, Function.Method.QualifiedIdentifier);
                if ((secondPass != null) && (methodDef != null))
                {
                    // HACK
                    var argumentIndex = invocation.Arguments.Select(
                        (a, i) => new { argument = a, index = i })
                                        .FirstOrDefault((_) => _.argument.SelfAndChildrenRecursive.Contains(argumentExpression));

                    if (argumentIndex != null)
                    {
                        var argumentName = methodDef.Parameters[argumentIndex.index].Name;

                        return(secondPass.DoesVariableEscape(argumentName, includeReturn));
                    }
                }
                else if (secondPass != null)
                {
                    // HACK for methods that do not have resolvable references. In this case, if NONE of their arguments escape, we're probably still okay.
                    if (secondPass.GetNumberOfEscapingVariables(includeReturn) == 0)
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }
示例#8
0
        protected internal override Node VisitFunctionSource([NotNull] FunctionSource node)
        {
            if (node.Alias != null)
            {
                if (this.Scope.GetSource(node.Alias) != null)
                {
                    this.AddError(node, $"There is already a source with alias {node.Alias}.");
                }
                else
                {
                    this.Scope.AddSource(node.Alias, node);
                }
            }

            var result   = this.ValidateChildren(node);
            var function = this.Data.GetFunction(result.Function);

            if (!function?.ReturnType.Interfaces.Contains(typeof(IDataSource)) ?? false)
            {
                this.AddError(node, $"Function {node.Function.Name.ToUpperInvariant()} is not a data source.");
            }

            return(result);
        }
示例#9
0
        public override EvaluationResult Evaluate(NumericPrecision numericPrecision, ValueSource values, FunctionSource functions)
        {
            EvaluationResult   left  = Constituents[0].Evaluate(numericPrecision, values, functions);
            OperatorExpression op    = Constituents[1] as OperatorExpression;
            EvaluationResult   right = Constituents[2].Evaluate(numericPrecision, values, functions);

            return(Evaluate(left, op, right, numericPrecision));
        }
示例#10
0
        public override EvaluationResult Evaluate(NumericPrecision numericPrecision, ValueSource values, FunctionSource functions)
        {
            var symbol = Constituents[0] as SymbolExpression;

            if (symbol == null)
            {
                throw new EvaluationException(this);
            }
            var matchingFunction = functions.TryGetValue(symbol.ToString());

            if (matchingFunction == null)
            {
                throw new UnmatchedSymbolException(symbol.ToString());
            }
            var parameters = Constituents[1].Evaluate(numericPrecision, values, functions);
            var result     = matchingFunction.Invoke(parameters) ?? new EvaluationResult(EvaluationType.Null, null);

            if (result.Type != EvaluationType.Expression)
            {
                return(result);
            }
            return(Interpreter.Interpreter.Evaluate(result.AsString(), numericPrecision, values, functions));
        }
示例#11
0
 public override EvaluationResult Evaluate(NumericPrecision numericPrecision, ValueSource values, FunctionSource functions)
 => new EvaluationResult(EvaluationType.Null, null);
示例#12
0
 public override EvaluationResult Evaluate(NumericPrecision numericPrecision, ValueSource values, FunctionSource functions)
 => Constituents.Any() ? Constituents[0].Evaluate(numericPrecision, values, functions) : new EvaluationResult(EvaluationType.Null, null);
        /// <summary>
        /// Visits a <see cref="FunctionSource"/>.
        /// </summary>
        /// <param name="node">
        /// The node.
        /// </param>
        /// <returns>
        /// The node, or a new version of the node.
        /// </returns>
        protected internal override Node VisitFunctionSource([NotNull] FunctionSource node)
        {
            this.aliases.Add(node.Alias);

            return(base.VisitFunctionSource(node));
        }
示例#14
0
        public static RecognisedType Resolve(string expression, ValueSource values, FunctionSource functions)
        {
            var nameAndValue = expression.Split(new[] { '=' }, 2);

            if (nameAndValue.Length != 2)
            {
                return(new RecognisedType());
            }
            var name  = nameAndValue[0]?.Trim();
            var value = nameAndValue[1]?.Trim();

            if (string.IsNullOrWhiteSpace(name) || string.IsNullOrWhiteSpace(value))
            {
                return(new RecognisedType());
            }
            int parsedInt;

            if (int.TryParse(value, out parsedInt))
            {
                return(new RecognisedType(name, parsedInt));
            }
            decimal parsedDecimal;

            if (decimal.TryParse(value, out parsedDecimal))
            {
                return(new RecognisedType(name, parsedDecimal));
            }
            float parsedFloat;

            if (float.TryParse(value, out parsedFloat))
            {
                return(new RecognisedType(name, parsedFloat));
            }
            DateTime parsedDateTime;

            if (DateTime.TryParse(value, out parsedDateTime))
            {
                return(new RecognisedType(name, parsedDateTime));
            }
            bool parsedBool;

            if (bool.TryParse(value, out parsedBool))
            {
                return(new RecognisedType(name, parsedBool));
            }
            var str = AsString(value);

            if (str != null)
            {
                return(new RecognisedType(name, str));
            }
            var list = AsList(value, values, functions);

            if (list != null)
            {
                return(new RecognisedType(name, list));
            }
            var expressionString = AsExpression(value);

            if (expressionString != null)
            {
                return(new RecognisedType(name, new EvaluationResult(EvaluationType.Expression, expressionString)));
            }
            return(new RecognisedType());
        }
示例#15
0
 public override EvaluationResult Evaluate(NumericPrecision numericPrecision, ValueSource values, FunctionSource functions)
 => numericPrecision == NumericPrecision.Float ?
 new EvaluationResult(EvaluationType.Float, float.Parse(ToString())) :
 new EvaluationResult(EvaluationType.Float, decimal.Parse(ToString()));
示例#16
0
 public override EvaluationResult Evaluate(NumericPrecision numericPrecision, ValueSource values, FunctionSource functions)
 => ToString();
示例#17
0
        /// <summary>
        /// Visits a <see cref="FunctionSource"/>.
        /// </summary>
        /// <param name="node">
        /// The node.
        /// </param>
        /// <returns>
        /// The node, or a new version of the node.
        /// </returns>
        protected internal override Node VisitFunctionSource([NotNull] FunctionSource node)
        {
            this.data.SetAlias(node.Function, node.Alias);

            return(base.VisitFunctionSource(node));
        }
示例#18
0
 public override EvaluationResult Evaluate(NumericPrecision numericPrecision, ValueSource values, FunctionSource functions)
 {
     throw new EvaluationException(this);
 }
示例#19
0
 public override EvaluationResult Evaluate(NumericPrecision numericPrecision, ValueSource values,
                                           FunctionSource functions)
 => WithoutQuotes();
示例#20
0
 /// <summary>
 /// Visits a <see cref="FunctionSource"/>.
 /// </summary>
 /// <param name="node">
 /// The node.
 /// </param>
 /// <returns>
 /// The node, or a new version of the node.
 /// </returns>
 protected internal virtual Node VisitFunctionSource([NotNull] FunctionSource node)
 {
     return(node.VisitChildren(this));
 }
示例#21
0
        /// <summary>
        /// Evaluates the parameter Expressive expression, with the parameter NumericPrecision, ValueSource and FunctionSource.
        /// </summary>
        public static EvaluationResult Evaluate(string expression, NumericPrecision precision, ValueSource values, FunctionSource functions)
        {
            values    = values ?? new ValueSource();
            functions = functions ?? new FunctionSource();
            var tokens = Lexer.Lex(expression);
            var parsed = Parser.Parse(tokens);

            if (parsed is ErrorExpression)
            {
                throw new ParserException(((ErrorExpression)parsed).ErroneousTokens);
            }
            return(parsed.Evaluate(precision, values, functions));
        }
示例#22
0
 public override EvaluationResult Evaluate(NumericPrecision numericPrecision, ValueSource values, FunctionSource functions)
 => Constituents.Select(c => c.Evaluate(numericPrecision, values, functions)).ToList();
示例#23
0
 public abstract EvaluationResult Evaluate(NumericPrecision numericPrecision, ValueSource values, FunctionSource functions);
示例#24
0
 public Interpreter(NumericPrecision numericPrecision, ValueSource values, FunctionSource functions)
 {
     NumericPrecision = numericPrecision;
     Values           = values;
     Functions        = functions;
 }
示例#25
0
 /// <summary>
 /// Visits a <see cref="FunctionSource"/>.
 /// </summary>
 /// <param name="node">
 /// The node.
 /// </param>
 /// <returns>
 /// The node, or a new version of the node.
 /// </returns>
 protected internal override Node VisitFunctionSource(FunctionSource node)
 {
     return(this.VisitImplementation(node) ?? base.VisitFunctionSource(node));
 }
 public EvaluationResult EvaluateOperation(string expression, NumericPrecision precision, ValueSource values,
                                           FunctionSource functions)
 {
     return(Interpreter.Evaluate(expression, precision, values, functions));
 }
示例#27
0
        //hacky approach to parse out a list from a string, will fail if the list contains undeclared variables
        private static List <EvaluationResult> AsList(string value, ValueSource values, FunctionSource functions)
        {
            var tokens = Lexer.Lex(value);

            //can't be a list if it doesn't start and end with scope
            if (tokens.First().TokenClass != TokenClass.StartScope || tokens.Last().TokenClass != TokenClass.EndScope)
            {
                return(null);
            }
            var separated = new SeparatedExpression().Parse(tokens);

            //can't be a list if it wasn't recognised by the list parser
            if (separated.Expression == null)
            {
                return(null);
            }
            return(Interpreter.Evaluate(value, NumericPrecision.Float, values, functions).AsList());
        }