Пример #1
0
        /// <summary>Defines a new field on this class.</summary>
        /// <param name="name">The name of the field.</param>
        /// <param name="type">The type of the value held by this field.</param>
        /// <returns>A new FieldBuilder.</returns>
        protected virtual void DefineField(string name, VariableFragment nameFragment, bool isPublic, CodeFragment defaultValue)
        {
            Type type = null;

            if (nameFragment.GivenType != null)
            {
                type = nameFragment.GivenType.FindType(Script);
                nameFragment.GivenType = null;

                if (type == null)
                {
                    nameFragment.Error(name + " has a type that was not recognised.");
                }
            }
            else if (defaultValue != null)
            {
                // Try and compile it:
                CompiledFragment frag = defaultValue.Compile(GetInit());

                // Get the output type:
                type = frag.OutputType(out frag);
            }

            if (type == null)
            {
                nameFragment.Error(name + "'s type isn't given. Should be e.g. " + name + ":String if it has no default value.");
            }

            FieldBuilder field = Builder.DefineField(name, type, isPublic?FieldAttributes.Public:FieldAttributes.Private);

            Fields[name] = field;
        }
Пример #2
0
        /// <summary>Compiles a set of parameters into an array of compiled fragments.</summary>
        /// <param name="brackets">The parent block which contains each parameter as a child.</param>
        /// <param name="parentBlock">The method the parameters are for.</param>
        /// <returns>A set of compiled fragments.</returns>
        public static CompiledFragment[] CompileParameters(CodeFragment brackets, CompiledMethod parentBlock)
        {
            if (!brackets.IsParent)
            {
                return(null);
            }

            int count = 0;

            brackets.Compile(parentBlock);
            CodeFragment child = brackets.FirstChild;

            CompiledFragment[] output = new CompiledFragment[brackets.ChildCount()];

            while (child != null)
            {
                CompiledFragment frag = (CompiledFragment)child;

                if (frag == null)
                {
                    return(null);
                }

                output[count] = frag;
                count++;
                child = child.NextChild;
            }

            return(output);
        }
        public override CompiledFragment Compile(CompiledMethod method)
        {
            CompiledFragment cfrag = MethodName.Compile(method);

            if (!Types.IsTypeOf(cfrag.ActiveValue(), typeof(ISettable)))
            {
                Error("Unable to compile a method call - didn't recognise an invokable object.");
            }
            CompiledFragment[] parameters = CompilationServices.CompileParameters(Brackets, method);
            return(new MethodOperation(method, cfrag, parameters));
        }
Пример #4
0
        public override CompiledFragment Compile(CompiledMethod method)
        {
            if (!IsParent)
            {
                return(null);
            }

            CodeFragment child = FirstChild;

            while (child != null)
            {
                CodeFragment     next  = child.NextChild;
                CompiledFragment cfrag = child.Compile(method);

                if (cfrag != null)
                {
                    cfrag.AddAfter(child);
                }

                child.Remove();
                child = next;
            }

            if (GivenType != null)
            {
                Type toType = GivenType.FindType(method.Script);

                if (toType == null)
                {
                    Error("Type not found: " + GivenType.ToString() + ".");
                }

                CompiledFragment compiledKid = (CompiledFragment)FirstChild;
                CompiledFragment result      = Types.TryCast(method, compiledKid, toType);

                if (result == null)
                {
                    Error("Cannot cast " + compiledKid.OutputType() + " to " + toType + ".");
                }

                return(result);
            }

            return((CompiledFragment)FirstChild);
        }
Пример #5
0
        public override CompiledFragment Compile(CompiledMethod method)
        {
            if (!IsParent)
            {
                return(null);
            }

            CodeFragment child = FirstChild;

            while (child != null)
            {
                CodeFragment     next  = child.NextChild;
                CompiledFragment cfrag = child.Compile(method);

                if (cfrag != null)
                {
                    cfrag.AddAfter(child);
                }

                child.Remove();
                child = next;
            }

            // Is this a cast?
            if (GivenType != null)
            {
                // Get the type being cast to:
                Type toType = GivenType.FindType(method.Script);

                if (toType == null)
                {
                    Error("Type to cast to was not found: " + GivenType.ToString() + ".");
                }

                // Get the object being cast:
                CompiledFragment compiledKid = (CompiledFragment)FirstChild;

                // Create a cast operation with it:
                return(new CastOperation(method, compiledKid, toType));
            }

            return((CompiledFragment)FirstChild);
        }
		/// <summary>Defines a new field on this class.</summary>
		/// <param name="name">The name of the field.</param>
		/// <param name="type">The type of the value held by this field.</param>
		/// <returns>A new FieldBuilder.</returns>
		protected virtual void DefineField(string name,VariableFragment nameFragment,bool isPublic,CodeFragment defaultValue){
			
			Type type=null;
			
			if(nameFragment.GivenType!=null){
				type=nameFragment.GivenType.FindType(Script);
				nameFragment.GivenType=null;
				
				if(type==null){
					nameFragment.Error(name+" has a type that was not recognised.");
				}
				
			}else if(defaultValue!=null){
				
				// Try and compile it:
				CompiledFragment frag=defaultValue.Compile(GetInit());
				
				// Get the output type:
				type=frag.OutputType(out frag);
				
			}
			
			if(type==null){
				nameFragment.Error(name+"'s type isn't given. Should be e.g. "+name+":String if it has no default value.");
			}
			
			FieldBuilder field=Builder.DefineField(name,type,isPublic?FieldAttributes.Public:FieldAttributes.Private);
			Fields[name]=field;
		}
Пример #7
0
 public override CompiledFragment Compile(CompiledMethod parentBlock)
 {
     return(new IndexOperation(parentBlock, Variable.Compile(parentBlock), CompilationServices.CompileParameters(Brackets, parentBlock)));
 }
        /// <summary>Loads the parameter block into a set of types.</summary>
        private void ParseParameters()
        {
            if (DefaultParameterValues != null)
            {
                DefaultParameterValues = null;
                Builder.SetParameters(null);
            }

            if (ParameterBlock == null || !ParameterBlock.IsParent)
            {
                // No inputs anyway, e.g. test(){..}
                ParametersOk();
                return;
            }

            // Each of blocks children is an operation segment.

            ParameterTypes         = new Type[ParameterBlock.ChildCount()];
            DefaultParameterValues = new CompiledFragment[ParameterTypes.Length];
            int index = 0;

            // For each parameter..
            CodeFragment current = ParameterBlock.FirstChild;

            while (current != null)
            {
                if (!current.IsParent)
                {
                    Error("Invalid function definition input variable found.");
                }

                // Default value of this variable (if any). E.g. var1=true,var2..
                CompiledFragment DefaultValue = null;

                CodeFragment inputName = current.FirstChild;

                if (inputName.GetType() != typeof(VariableFragment))
                {
                    Error("Invalid function definition inputs for " + Name + ". Must be (var1:type,var2:type[=a default value],var3:type..). [=..] is optional and can be used for any of the variables.");
                }

                string paramName = ((VariableFragment)inputName).Value;

                if (inputName.NextChild == null)
                {
                }
                else if (inputName.NextChild != null && !Types.IsTypeOf(inputName.NextChild, typeof(OperatorFragment)))
                {
                    // No type OR default, or the block straight after isn't : or =
                    Error("Invalid function parameters for " + Name + ". '" + paramName + "' is missing a type or default value.");
                }
                else
                {
                    OperatorFragment opFrag = (OperatorFragment)inputName.NextChild;
                    //it must be a set otherwise it's invalid.

                    if (opFrag.Value == null || opFrag.Value.GetType() != typeof(OperatorSet))
                    {
                        Error("Invalid default function parameter value provided for " + Name + ". '" + paramName + "'.");
                    }

                    current.FirstChild = inputName.NextChild.NextChild;

                    if (!current.IsParent)
                    {
                        Error("Invalid default function definition. Must be (name:type=expr,..)");
                    }

                    DefaultValue = current.Compile(this);
                }

                if (inputName.GivenType != null)
                {
                    ParameterTypes[index] = inputName.GivenType.FindType(Script);
                }
                else if (DefaultValue != null)
                {
                    ParameterTypes[index] = DefaultValue.OutputType(out DefaultValue);
                }
                else
                {
                    Error("Parameter " + paramName + "'s type isn't given. Should be e.g. (" + paramName + ":String,..).");
                }

                DefaultParameterValues[index] = DefaultValue;

                if (ParameterSet.ContainsKey(paramName))
                {
                    Error("Cant use the same parameter name twice. " + paramName + " in function " + Name + ".");
                }
                else if (ParameterTypes[index] == null)
                {
                    Error("Type not given or invalid for parameter " + paramName + " in function " + Name + ".");
                }
                else
                {
                    ParameterSet.Add(paramName, new ParameterVariable(paramName, ParameterTypes[index]));
                }

                current = current.NextChild;
                index++;
            }

            ApplyParameters();
        }
 public override CompiledFragment Compile(CompiledMethod method)
 {
     return(new PropertyOperation(method, of.Compile(method), Value));
 }
		/// <summary>Compiles a set of parameters into an array of compiled fragments.</summary>
		/// <param name="brackets">The parent block which contains each parameter as a child.</param>
		/// <param name="parentBlock">The method the parameters are for.</param>
		/// <returns>A set of compiled fragments.</returns>
		public static CompiledFragment[] CompileParameters(CodeFragment brackets,CompiledMethod parentBlock){
			if(!brackets.IsParent){
				return null;
			}
			
			int count=0;
			brackets.Compile(parentBlock);
			CodeFragment child=brackets.FirstChild;
			CompiledFragment[] output=new CompiledFragment[brackets.ChildCount()];
			
			while(child!=null){
				CompiledFragment frag=(CompiledFragment)child;
				
				if(frag==null){
					return null;
				}
				
				output[count]=frag;
				count++;
				child=child.NextChild;
			}
			
			return output;
		}
Пример #11
0
        /// <summary>Compiles an operation fragment into an executable operation. The fragment may contain multiple
        /// operators and some may even be the same so the furthest right takes priority; 1+2+3 becomes 1+(2+3).
        /// The compiled fragments are placed back into the same operation fragment. When it's complete, the operation
        /// will only contain one compiled fragment.</summary>
        /// <param name="fragment">The operation fragment to compile.</param>
        /// <param name="parentBlock">The method the operations are compiling into.</param>
        public static void CompileOperators(OperationFragment fragment, CompiledMethod parentBlock)
        {
            CodeFragment     child           = fragment.FirstChild;
            OperatorFragment highestPriority = null;

            while (child != null)
            {
                if (child.GetType() == typeof(OperatorFragment))
                {
                    OperatorFragment thisOperator = (OperatorFragment)child;

                    // <= below enforces furthest right:
                    if (highestPriority == null || highestPriority.Value.Priority <= thisOperator.Value.Priority)
                    {
                        highestPriority = thisOperator;
                    }
                }

                child = child.NextChild;
            }

            if (highestPriority == null)
            {
                return;
            }

            CodeFragment left      = highestPriority.PreviousChild;
            CodeFragment right     = highestPriority.NextChild;
            CodeFragment leftUsed  = left;
            CodeFragment rightUsed = right;

            if (left == null || left.GetType() == typeof(OperatorFragment))
            {
                leftUsed = null;
            }
            else if (!Types.IsCompiled(left))
            {
                leftUsed = left.Compile(parentBlock);
            }

            if (right == null || right.GetType() == typeof(OperatorFragment))
            {
                rightUsed = null;
            }
            else if (!Types.IsCompiled(right))
            {
                rightUsed = right.Compile(parentBlock);
            }

            Operation newFragment = highestPriority.Value.ToOperation((CompiledFragment)leftUsed, (CompiledFragment)rightUsed, parentBlock);

            if (newFragment == null)
            {
                highestPriority.Error("Error: An operator has been used but with nothing to use it on! (It was a '" + highestPriority.Value.Pattern + "')");
            }

            // Replace out Left, Right and the operator itself with the new fragment:
            highestPriority.Remove();

            if (left == null)
            {
                newFragment.AddBefore(right);
            }
            else
            {
                newFragment.AddAfter(left);
            }

            if (rightUsed != null)
            {
                right.Remove();
            }

            if (leftUsed != null)
            {
                left.Remove();
            }

            // And call again to collect the rest:
            CompileOperators(fragment, parentBlock);
        }