/// <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; }
/// <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)); }
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); }
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; }
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; }
/// <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); }