Ejemplo n.º 1
0
        private static void _PrepareLambda(
            List<KeyValuePair<Parser.Expression, string>> Arguments,
            Parser.Expression Inner, Scope Scope, ProgramInput Input,
            out Expression ArgumentType, out Expression PreparedInner)
        {
            // 0 arg function
            if (Arguments.Count == 0)
            {
                ArgumentType = TupleExpression.Empty;
                PreparedInner = Prepare(Inner, Scope, Input);
                return;
            }

            // 1 arg function
            Dictionary<string, int> vars;
            int argloc = Scope.NextFreeIndex;
            Scope nscope = new Scope()
            {
                NextFreeIndex = argloc + 1,
                Variables = vars = new Dictionary<string, int>(),
                Parent = Scope
            };
            if (Arguments.Count == 1)
            {
                var kvp = Arguments[0];
                if (kvp.Value != null)
                {
                    vars.Add(kvp.Value, argloc);
                }
                ArgumentType = Prepare(kvp.Key, Scope, Input);
                PreparedInner = Prepare(Inner, nscope, Input);
                return;
            }

            // 2+ arg function
            Expression[] types = new Expression[Arguments.Count];
            for (int t = 0; t < types.Length; t++)
            {
                types[t] = Prepare(Arguments[t].Key, Scope, Input);
            }

            nscope.NextFreeIndex += types.Length;
            for (int t = 0; t < Arguments.Count; t++)
            {
                string argname = Arguments[t].Value;
                if (argname != null)
                {
                    vars.Add(argname, t + argloc + 1);
                }
            }
            ArgumentType = Expression.Tuple(types);
            PreparedInner = Expression.BreakTuple(
                argloc + 1,
                Arguments.Count,
                Expression.Variable(argloc),
                Prepare(Inner, nscope, Input));
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Prepares a parsed expression for use.
        /// </summary>
        public static Expression Prepare(Parser.Expression Expression, Scope Scope, ProgramInput Input)
        {
            // Function call
            Parser.FunctionCallExpression fce = Expression as Parser.FunctionCallExpression;
            if (fce != null)
            {
                Expression func = Prepare(fce.Function, Scope, Input);
                if (fce.Arguments.Count == 0)
                {
                    return new FunctionCallExpression(func, TupleExpression.Empty);
                }
                if (fce.Arguments.Count == 1)
                {
                    return new FunctionCallExpression(func, Prepare(fce.Arguments[0], Scope, Input));
                }
                Expression[] args = new Expression[fce.Arguments.Count];
                for (int t = 0; t < args.Length; t++)
                {
                    args[t] = Prepare(fce.Arguments[t], Scope, Input);
                }
                return new FunctionCallExpression(func, new TupleExpression(args));
            }

            // Procedure
            Parser.ProcedureExpression pe = Expression as Parser.ProcedureExpression;
            if (pe != null)
            {
                return ProcedureExpression.Prepare(pe, Scope, Input);
            }

            // Variable
            Parser.VariableExpression ve = Expression as Parser.VariableExpression;
            if (ve != null)
            {
                return PrepareVariable(ve.Name, Scope);
            }

            // Integer liteal
            Parser.IntegerLiteralExpression ile = Expression as Parser.IntegerLiteralExpression;
            if (ile != null)
            {
                return new ValueExpression(Input.GetIntegerLiteral(ile.Value), Input.IntegerLiteralType);
            }

            // Accessor
            Parser.AccessorExpression ae = Expression as Parser.AccessorExpression;
            if (ae != null)
            {
                return new AccessorExpression(Prepare(ae.Object, Scope, Input), ae.Property);
            }

            // Function definition
            Parser.FunctionDefineExpression fde = Expression as Parser.FunctionDefineExpression;
            if (fde != null)
            {
                Expression argtype;
                Expression inner;
                _PrepareLambda(fde.Arguments, fde.Definition, Scope, Input, out argtype, out inner);
                return new FunctionDefineExpression(Scope.NextFreeIndex, argtype, inner);
            }

            // Function type
            Parser.FunctionTypeExpression fte = Expression as Parser.FunctionTypeExpression;
            if (fte != null)
            {
                // Notice that this is almost exactly the same as a function definition? weird type system, eh?
                Expression argtype;
                Expression inner;
                _PrepareLambda(fte.ArgumentTypes, fte.ReturnType, Scope, Input, out argtype, out inner);
                return new FunctionDefineExpression(Scope.NextFreeIndex, argtype, inner);
            }

            throw new NotImplementedException();
        }
Ejemplo n.º 3
0
 /// <summary>
 /// Prepares a variable expression based on its name and the scope it's used in. Returns null if the variable is not found.
 /// </summary>
 public static VariableExpression PrepareVariable(string Name, Scope Scope)
 {
     int index;
     if (Scope.LookupVariable(Name, out index))
     {
         return new VariableExpression(index);
     }
     else
     {
         return null;
     }
 }
Ejemplo n.º 4
0
 /// <summary>
 /// Creates stacks and information about the root scope of this input.
 /// </summary>
 public void PrepareRootScope(out Scope Scope, out IMutableVariableStack<Value> Stack, out IVariableStack<Expression> TypeStack)
 {
     Dictionary<string, int> varmap = new Dictionary<string, int>();
     Value[] vals = new Value[this._RootVariables.Count];
     Expression[] types = new Expression[vals.Length];
     for (int t = 0; t < vals.Length; t++)
     {
         vals[t] = this._RootVariables[t].Value;
         types[t] = this._RootVariables[t].Type;
         varmap.Add(this._RootVariables[t].Name, t);
     }
     Scope = new Scope() { Variables = varmap, NextFreeIndex = vals.Length };
     Stack = new SpaghettiStack<Value>(vals);
     TypeStack = new SpaghettiStack<Expression>(types);
 }