示例#1
0
 public TupleBreakExpression(int BreakIndex, int TupleSize, Expression Tuple, Expression InnerExpression)
 {
     this.BreakIndex = BreakIndex;
     this.TupleSize = TupleSize;
     this.SourceTuple = Tuple;
     this.InnerExpression = InnerExpression;
 }
示例#2
0
        public override bool Reduce(IVariableMap<Expression> Map, ref Expression Reduced)
        {
            // Is the source tuple an actual tuple?
            TupleExpression te = this.SourceTuple as TupleExpression;
            if (te != null)
            {
                // Now we got this :D
                Reduced = this.InnerExpression.Substitute(new SimpleMap<Expression>(this.BreakIndex, te.Parts));
                return true;
            }

            // Wouldn't it be hilarious if the inner expression never even used the tuple's data?
            Expression cire = this.InnerExpression.Compress(this.BreakIndex, this.TupleSize);
            if (cire != null)
            {
                Reduced = cire;
                return true;
            }

            // Nope, guess i'll have to do it the normal way :(
            Expression tre = this.SourceTuple;
            Expression ire = this.InnerExpression;
            if (tre.Reduce(Map, ref tre) | ire.Reduce(this._CreateInner(Map), ref ire))
            {
                Reduced = new TupleBreakExpression(this.BreakIndex, this.TupleSize, tre, ire);
                return true;
            }

            return false;
        }
示例#3
0
 public override void TypeCheck(
     IVariableStack<Expression> TypeStack,
     IVariableStack<Expression> Stack,
     out Expression TypeSafeExpression, out Expression Type)
 {
     throw new NotImplementedException();
 }
示例#4
0
 /// <summary>
 /// Creates an expression that always evaluates to the same value.
 /// </summary>
 public static ValueExpression Constant(Expression Type, Value Value)
 {
     return new ValueExpression(Value, Type);
 }
示例#5
0
 public override bool Reduce(IVariableMap<Expression> Map, ref Expression Reduced)
 {
     // Only possible way to reduce a variable is to replace it with its value.
     Expression possible = null;
     if (Map.Lookup(this.Index, ref possible))
     {
         VariableExpression ve = possible as VariableExpression;
         if (ve != null)
         {
             if (ve.Index == this.Index)
             {
                 return false;
             }
         }
         Reduced = possible;
         return true;
     }
     return false;
 }
示例#6
0
 public override void TypeCheck(
     IVariableStack<Expression> TypeStack, 
     IVariableStack<Expression> Stack,
     out Expression TypeSafeExpression, out Expression Type)
 {
     TypeSafeExpression = this;
     Type = this.Datum.Type;
 }
示例#7
0
 public override void TypeCheck(
     IVariableStack<Expression> TypeStack,
     IVariableStack<Expression> Stack,
     out Expression TypeSafeExpression, out Expression Type)
 {
     Expression sifunc;
     Expression itype;
     this.Function.TypeCheck(
         TypeStack.Cut(this.ArgumentIndex).Append(new Expression[] { this.ArgumentType }),
         Stack.Cut(this.ArgumentIndex).Append(new Expression[] { Expression.Variable(Stack.NextFreeIndex) }),
         out sifunc, out itype);
     Type = Expression.FunctionType(this.ArgumentIndex, this.ArgumentType, itype);
     TypeSafeExpression = new FunctionDefineExpression(this.ArgumentIndex, this.ArgumentType, sifunc);
 }
示例#8
0
 public FunctionDefineExpression(int ArgumentIndex, Expression ArgumentType, Expression Function)
 {
     this.ArgumentIndex = ArgumentIndex;
     this.ArgumentType = ArgumentType;
     this.Function = Function;
 }
示例#9
0
        public override bool Reduce(IVariableMap<Expression> Map, ref Expression Reduced)
        {
            // Beta reduction (substituting an argument in a function definition)
            FunctionDefineExpression fde = this.Function as FunctionDefineExpression;
            if (fde != null)
            {
                Reduced = fde.SubstituteCall(this.Argument);
                return true;
            }

            // Recursive reduction
            Expression fre = this.Function;
            Expression are = this.Argument;
            if (fre.Reduce(Map, ref fre) | are.Reduce(Map, ref are))
            {
                Reduced = new FunctionCallExpression(fre, are);
                return true;
            }

            return false;
        }
示例#10
0
 public AccessorExpression(Expression Object, string Property)
 {
     this.Object = Object;
     this.Property = Property;
 }
示例#11
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();
        }
示例#12
0
 /// <summary>
 /// Creates an expression for a function type, given the argument type and the return type(which has access to the argument in its current scope).
 /// </summary>
 public static FunctionDefineExpression FunctionType(int NextFreeIndex, Expression ArgumentType, Expression ReturnType)
 {
     return new FunctionDefineExpression(NextFreeIndex, ArgumentType, ReturnType);
 }
示例#13
0
        /// <summary>
        /// Gets if the two specified expressions are equivalent. This function reduces and subsitutes 
        /// given expressions and the stack as needed to get an accurate result.
        /// </summary>
        public static FuzzyBool Equivalent(ref Expression A, ref Expression B, IVariableStack<Expression> Stack)
        {
            if (A == B)
            {
                return FuzzyBool.True;
            }

            while (true)
            {
                // Variable equality
                VariableExpression va = A as VariableExpression;
                if (va != null)
                {
                    VariableExpression vb = B as VariableExpression;
                    if (vb != null)
                    {
                        if (va.Index == vb.Index)
                        {
                            return FuzzyBool.True;
                        }
                    }
                }

                // Tuple equality
                TupleExpression at = A as TupleExpression;
                if (at != null)
                {
                    TupleExpression bt = B as TupleExpression;
                    if (bt != null)
                    {
                        if (at.Parts.Length != bt.Parts.Length)
                        {
                            return FuzzyBool.False;
                        }
                        for (int t = 0; t < at.Parts.Length; t++)
                        {
                            FuzzyBool pe = Equivalent(ref at.Parts[t], ref bt.Parts[t], Stack);
                            if (pe == FuzzyBool.False)
                            {
                                return FuzzyBool.False;
                            }
                            if (pe == FuzzyBool.Undetermined)
                            {
                                return FuzzyBool.Undetermined;
                            }
                        }
                        return FuzzyBool.True;
                    }
                }

                // Tuple break
                TupleBreakExpression atb = A as TupleBreakExpression;
                if (atb != null)
                {
                    TupleBreakExpression btb = B as TupleBreakExpression;
                    if (btb != null)
                    {
                        return FuzzyBoolLogic.And(
                            Expression.Equivalent(ref atb.SourceTuple, ref btb.SourceTuple, Stack),
                            Expression.Equivalent(ref atb.InnerExpression, ref btb.InnerExpression, Stack));
                    }
                }

                // Function definition equality
                FunctionDefineExpression afd = A as FunctionDefineExpression;
                if (afd != null)
                {
                    FunctionDefineExpression bfd = B as FunctionDefineExpression;
                    if (bfd != null)
                    {
                        if (afd.ArgumentIndex == bfd.ArgumentIndex)
                        {
                            var nstack = Stack.Cut(afd.ArgumentIndex).Append(new Expression[] { Expression.Variable(afd.ArgumentIndex) });
                            return FuzzyBoolLogic.And(
                                Expression.Equivalent(ref afd.ArgumentType, ref bfd.ArgumentType, nstack),
                                Expression.Equivalent(ref afd.Function, ref bfd.Function, nstack));
                        }
                    }
                }

                // Nothing yet? try reducing
                if (A.Reduce(Stack, ref A) | B.Reduce(Stack, ref B))
                {
                    continue;
                }
                else
                {
                    break;
                }
            }

            return FuzzyBool.Undetermined;
        }
示例#14
0
 public Expression AddBinaryFunction(string Name, Expression TypeA, Expression TypeB, Expression ReturnType, BinaryFunction Handler)
 {
     return this.AddRootVariable(Name, Expression.FunctionType(this.NextFreeIndex, Expression.Tuple(TypeA, TypeB), ReturnType),
         new BinaryFunctionValue() { Function = Handler });
 }
示例#15
0
 public _Input()
 {
     this.TypeType = this.AddUniversalType("type", null);
     this.IntType = this.AddRootVariable("int", this.TypeType, null);
     this.AddBinaryFunction("+", this.IntType, this.IntType, this.IntType, (x, y) => MakeIntValue(GetIntValue(x) + GetIntValue(y)));
     this.AddBinaryFunction("-", this.IntType, this.IntType, this.IntType, (x, y) => MakeIntValue(GetIntValue(x) - GetIntValue(y)));
     this.AddBinaryFunction("*", this.IntType, this.IntType, this.IntType, (x, y) => MakeIntValue(GetIntValue(x) * GetIntValue(y)));
 }
示例#16
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));
        }
示例#17
0
 public FunctionCallExpression(Expression Function, Expression Argument)
 {
     this.Function = Function;
     this.Argument = Argument;
 }
示例#18
0
 /// <summary>
 /// Creates an expression that produces a tuple with one item.
 /// </summary>
 public static TupleExpression Tuple(Expression A)
 {
     return new TupleExpression(new Expression[] { A });
 }
示例#19
0
        public override void TypeCheck(
            IVariableStack<Expression> TypeStack,
            IVariableStack<Expression> Stack,
            out Expression TypeSafeExpression, out Expression Type)
        {
            int li = TypeStack.NextFreeIndex;

            Expression sfunc;
            Expression functype;
            this.Function.TypeCheck(TypeStack, Stack, out sfunc, out functype);

            FunctionDefineExpression fte;
            while ((fte = functype as FunctionDefineExpression) == null && functype.Reduce(Stack, ref functype)) ;
            if (fte == null)
            {
                throw new NotCallableException(this);
            }

            Expression sarg;
            Expression argtype;
            this.Argument.TypeCheck(TypeStack, Stack, out sarg, out argtype);

            FuzzyBool typeokay = Expression.Equivalent(ref argtype, ref fte.ArgumentType, Stack);
            if (typeokay != FuzzyBool.True)
            {
                throw new TypeCheckException(this);
            }

            TypeSafeExpression = new FunctionCallExpression(sfunc, sarg);
            Type = fte.Function.SubstituteOne(Stack.NextFreeIndex, sarg);
        }
示例#20
0
 /// <summary>
 /// Creates an expression that produces a tuple with three items.
 /// </summary>
 public static TupleExpression Tuple(Expression A, Expression B, Expression C)
 {
     return new TupleExpression(new Expression[] { A, B, C });
 }
示例#21
0
 /// <summary>
 /// Creates an expression that represents the return value of the function when supplied with an argument.
 /// </summary>
 public Expression SubstituteCall(Expression Argument)
 {
     return this.Function.SubstituteOne(this.ArgumentIndex, Argument).Compress(this.ArgumentIndex, 1);
 }
示例#22
0
 /// <summary>
 /// Creates an expression with a varying amount of items.
 /// </summary>
 public static TupleExpression Tuple(Expression[] Items)
 {
     return new TupleExpression(Items);
 }
示例#23
0
 public ValueExpression(Value Value, Expression Type)
 {
     this.Datum = new Datum(Value, Type);
 }
示例#24
0
 /// <summary>
 /// Tries to gradually simplifies the expression. Can possibly access the map to dereference a variable.
 /// </summary>
 public virtual bool Reduce(IVariableMap<Expression> Map, ref Expression Reduced)
 {
     return false;
 }
示例#25
0
 /// <summary>
 /// Creates an expression that causes the parts in tuple to be used in the stack of the inner expression.
 /// </summary>
 public static TupleBreakExpression BreakTuple(int NextFreeIndex, int Size, Expression Tuple, Expression Inner)
 {
     return new TupleBreakExpression(NextFreeIndex, Size, Tuple, Inner);
 }
示例#26
0
 /// <summary>
 /// Substitutes a single variable in the expression.
 /// </summary>
 public Expression SubstituteOne(int Index, Expression Value)
 {
     return this.Substitute(new SingleVariableMap<Expression>(Index, Value));
 }
示例#27
0
 public override void TypeCheck(
     IVariableStack<Expression> TypeStack,
     IVariableStack<Expression> Stack,
     out Expression TypeSafeExpression, out Expression Type)
 {
     TypeSafeExpression = this;
     Type = null;
     TypeStack.Lookup(this.Index, ref Type);
 }
示例#28
0
 /// <summary>
 /// Creates a type-safe version of the expression by using conversions where necessary. An exception will
 /// be thrown if this is not possible.
 /// </summary>
 public abstract void TypeCheck(
     IVariableStack<Expression> TypeStack, 
     IVariableStack<Expression> Stack,
     out Expression TypeSafeExpression, out Expression Type);
示例#29
0
 /// <summary>
 /// Creates an expression that acts as a function.
 /// </summary>
 public static FunctionDefineExpression DefineFunction(int NextFreeIndex, Expression ArgumentType, Expression FunctionExpression)
 {
     return new FunctionDefineExpression(NextFreeIndex, ArgumentType, FunctionExpression);
 }
示例#30
0
 public override void TypeCheck(
     IVariableStack<Expression> TypeStack,
     IVariableStack<Expression> Stack,
     out Expression TypeSafeExpression, out Expression Type)
 {
     if (this.Parts != null && this.Parts.Length != 0)
     {
         Expression[] sparts = new Expression[this.Parts.Length];
         Expression[] stypes = new Expression[this.Parts.Length];
         for (int t = 0; t < this.Parts.Length; t++)
         {
             this.Parts[t].TypeCheck(TypeStack, Stack, out sparts[t], out stypes[t]);
         }
         TypeSafeExpression = new TupleExpression(sparts);
         Type = new TupleExpression(stypes);
     }
     else
     {
         TypeSafeExpression = Empty;
         Type = Empty;
     }
 }