Exemple #1
0
        /// <summary>
        /// Compiles a single expression (e.g. part of an expression list)
        /// </summary>
        private IFunction CompileExpression(IFunction?previous, Match exprAst, CompilerStackFrame compilerStackFrame, CompilationContext context)
        {
            switch (exprAst.Name)
            {
            case ElementAST.LiteralExpression:
                return(new Constant((float)exprAst.Value));

            case ElementAST.VariableExpression:
                context.PushTrace(MakeCallSite(exprAst));
                var variable = CompileFunction(exprAst.Text, compilerStackFrame, context);
                context.PopTrace();
                return(variable);

            case ElementAST.SubExpression:
                return(previous.Call(exprAst[ElementAST.SubExpressionName].Text, context, MakeCallSite(exprAst)));

            case ElementAST.CallExpression:
                // This is called a *lot*, so try to make it high performance:
                var args    = exprAst[ElementAST.CallArguments].Matches;
                var argList = new IFunction[args.Count];
                for (var i = 0; i < argList.Length; i++)
                {
                    argList[i] = CompileExpressionList(args[i], compilerStackFrame, context);
                }

                return(previous.Call(argList, context, MakeCallSite(exprAst)));

            default:
                return(context.LogError(9999, $"Unknown expression {exprAst}"));
            }
        }
Exemple #2
0
        /// <summary>
        /// Called when another value references this function to compile scoped functions.
        /// </summary>
        public IFunction CompileFunction(string name, CompilerStackFrame compilerStackFrame, CompilationContext context)
        {
            // First try to get a cached/inputted value...
            if (!compilerStackFrame.GetLocal(name, out var value))
            {
                // If that fails, look in the list of drivers:
                if (_drivers != null)
                {
                    if (_drivers.TryGetValue(name, out var statement))
                    {
                        if (statement[ElementAST.TypeStatement])                         // Check if this statement is a type declaration
                        {
                            var type = FindType(name, context);
                            value = new Constructor(type, context);
                        }
                        else
                        {
                            value = new CustomFunction(this, statement, compilerStackFrame, context, Source);
                        }

                        compilerStackFrame.Add(name, value);
                    }
                }
                // If there's no driver list (i.e. during an assignment), then the only output is 'return'
                // Since there's no other drivers we can assume
                else if (name == "return")
                {
                    value = CompileExpressionList(_astAssign, compilerStackFrame, context);
                    compilerStackFrame.Add(name, value);
                }
            }

            // Failing the above, try to find the value including parents in the stack
            // if we still cannot find a value, try using the captured compilation stack
            if (value == null && !compilerStackFrame.Get(name, out value) && _capturedCompilationStack != null)
            {
                value = Parent.CompileFunction(name, _capturedCompilationStack, context);
            }

            if (value == null)
            {
                return(context.LogError(7, name));
            }

            return(value.ResolveReturns(context, null));            // TODO: Keep variable information here?
        }
Exemple #3
0
 /// <summary>
 /// Compiles an expression 'list' (such as chained calls or member accesses)
 /// </summary>
 private IFunction CompileExpressionList(Match list, CompilerStackFrame compilerStackFrame, CompilationContext context) =>
 list.Matches.Count == 0
                         ? CompileExpression(null, list, compilerStackFrame, context)
                         : list.Matches.Aggregate(default(IFunction), (current, exprAst) => CompileExpression(current, exprAst, compilerStackFrame, context));