Exemple #1
0
 /// <summary>Finds which type of fragment will accept and handle the given character.</summary>
 /// <param name="peek">The character to find a handler for.</param>
 /// <returns>The handler which will deal with this character. May also be told to stop if no handler is available.</returns>
 public static Handler Find(char peek)
 {
     if (peek == StringReader.NULL || BracketFragment.IsEndBracket(peek) != -1)
     {
         return(Handler.Stop);
     }
     else if (BracketFragment.WillHandle(peek))
     {
         return(Handler.Brackets);
     }
     else if (StringFragment.WillHandle(peek))
     {
         return(Handler.String);
     }
     else if (TypeFragment.WillHandle(peek))
     {
         return(Handler.Type);
     }
     else if (OperatorFragment.WillHandle(peek))
     {
         return(Handler.Operator);
     }
     else if (PropertyFragment.WillHandle(peek))
     {
         return(Handler.Property);
     }
     else if (NumberFragment.WillHandle(peek))
     {
         return(Handler.Number);
     }
     return(Handler.Variable);
 }
Exemple #2
0
        /// <summary>Creates a new Constructor Fragment.</summary>
        /// <param name="type">The type of the object to construct.</param>
        /// <param name="brackets">The arguments for the constructor as a bracket fragment.</param>
        public ConstructorFragment(TypeFragment type, BracketFragment brackets)
        {
            NewType  = type;
            Brackets = brackets;

            // Add them as children such that code tree iterators can visit them:
            AddChild(Brackets);
        }
Exemple #3
0
        public ArrayFragment(TypeFragment arrayType, BracketFragment defaults)
        {
            ArrayType = arrayType;
            Defaults  = defaults;

            // Add them as children such that code tree iterators can visit them:
            AddChild(Defaults);
        }
		public ArrayFragment(TypeFragment arrayType,BracketFragment defaults){
			ArrayType=arrayType;
			Defaults=defaults;
			
			// Add them as children such that code tree iterators can visit them:
			AddChild(Defaults);
			
		}
		/// <summary>Creates a new Constructor Fragment.</summary>
		/// <param name="type">The type of the object to construct.</param>
		/// <param name="brackets">The arguments for the constructor as a bracket fragment.</param>
		public ConstructorFragment(TypeFragment type,BracketFragment brackets){
			NewType=type;
			Brackets=brackets;
			
			// Add them as children such that code tree iterators can visit them:
			AddChild(Brackets);
			
		}
		public CompiledMethod(CompiledClass parent,string name,BracketFragment parameterBlock,BracketFragment codeBlock,TypeFragment retType,bool isPublic){
			Name=name;
			Parent=parent;
			CodeBlock=codeBlock;
			Script=Parent.Script;
			ParameterBlock=parameterBlock;
			
			Type returnType=null;
			if(retType!=null){
				returnType=retType.FindType(Script);
				if(returnType==null){
					Error("Type '"+retType.Value+"' was not found.");
				}
			}
			string methodName=Name;
			MethodAttributes attrib=isPublic?MethodAttributes.Public:MethodAttributes.Private;
			if(methodName=="new"){
				methodName=".ctor";
				attrib|=MethodAttributes.HideBySig|MethodAttributes.SpecialName|MethodAttributes.RTSpecialName;
			}
			// Does the parent base type define this method?
			// If so, use it's name.
			Type baseType=Parent.Builder.BaseType;
			
			// Parse the parameter set right away:
			ParseParameters();
			
			MethodInfo mInfo=Types.GetOverload(baseType.GetMethods(),Name,ParameterTypes,true);
			
			if(mInfo!=null){
				methodName=mInfo.Name;
				attrib|=MethodAttributes.Virtual|MethodAttributes.HideBySig;//|MethodAttributes.NewSlot;
			}
			
			bool isVoid=Types.IsVoid(returnType);
			
			if(isVoid){
				returnType=typeof(void);
			}
			
			Builder=Parent.Builder.DefineMethod(
				methodName,
				attrib,
				returnType,
				null
			);
			
			ApplyParameters();
			
			ILStream=new NitroIL(Builder.GetILGenerator());
			EndOfMethod=ILStream.DefineLabel();
			if(!isVoid){
				ReturnBay=ILStream.DeclareLocal(returnType);
			}
		}
        /// <summary>Creates a new variable fragment by reading it from the given lexer.</summary>
        /// <param name="sr">The lexer to read the variable from.</param>
        public VariableFragment(CodeLexer sr)
        {
            Value += char.ToLower(sr.Read());

            // Read until some other block can take over:
            while (true)
            {
                char peek = sr.Peek();
                if (peek == ';' || peek == ',' || peek == StringReader.NULL || BracketFragment.AnyBracket(peek))
                {
                    // Pass control back to the operation:
                    break;
                }

                if (sr.PeekJunk())
                {
                    // Is Value anything special?
                    if (Value == "var")
                    {
                        break;
                    }
                    else if (Value == "private")
                    {
                        break;
                    }
                    else if (Value == "function")
                    {
                        break;
                    }
                    else if (Value == "class")
                    {
                        break;
                    }
                    else if (Value == "new")
                    {
                        GivenType = new TypeFragment(sr, false);
                        break;
                    }
                    else if (IsKeyword())
                    {
                        break;
                    }
                }

                Handler handle = Handlers.Find(peek);

                if (handle != Handler.Stop && handle != Handler.Variable && handle != Handler.Number)
                {
                    break;
                }

                Value += char.ToLower(sr.Read());
            }
        }
		public ConstructOperation(TypeFragment type,BracketFragment brackets,CompiledMethod method):base(method){
			if(type==null){
				Error("A constructor is missing the type to construct. E.g. new myClass();");
			}
			ObjectType=type.FindType(method.Script);
			if(ObjectType==null){
				Error("Couldn't find type '"+type+"'.");
			}
			// Compile the brackets - what types to they have?
			Parameters=CompilationServices.CompileParameters(brackets,method);
			SetConstructor();
		}
Exemple #9
0
 public ConstructOperation(TypeFragment type, BracketFragment brackets, CompiledMethod method) : base(method)
 {
     if (type == null)
     {
         Error("A constructor is missing the type to construct. E.g. new myClass();");
     }
     ObjectType = type.FindType(method.Script);
     if (ObjectType == null)
     {
         Error("Couldn't find type '" + type + "'.");
     }
     // Compile the brackets - what types to they have?
     Parameters = CompilationServices.CompileParameters(brackets, method);
     SetConstructor();
 }
		/// <summary>Creates a new variable fragment by reading it from the given lexer.</summary>
		/// <param name="sr">The lexer to read the variable from.</param>
		public VariableFragment(CodeLexer sr){
			Value+=char.ToLower(sr.Read());
			
			// Read until some other block can take over:
			while(true){
				char peek=sr.Peek();	
				if(peek==';'||peek==','||peek==StringReader.NULL||BracketFragment.AnyBracket(peek)){
					// Pass control back to the operation:
					break;
				}
				
				if(sr.PeekJunk()){
					// Is Value anything special?
					if(Value=="var"){
						break;
					}else if(Value=="private"){
						break;
					}else if(Value=="function"){
						break;
					}else if(Value=="class"){
						break;
					}else if(Value=="new"){
						GivenType=new TypeFragment(sr,false);
						break;
					}else if(IsKeyword()){
						break;
					}
				}
				
				Handler handle=Handlers.Find(peek);
				
				if(handle!=Handler.Stop&&handle!=Handler.Variable&&handle!=Handler.Number){
					break;
				}
				
				Value+=char.ToLower(sr.Read());
			}
			
		}
		/// <summary>Adds a method that was found into this classes set of methods to compile.</summary>
		/// <param name="fragment">The first fragment of the method, used for generating errors. This gives a valid line number.</param>
		/// <param name="body">The block of code for this method.</param>
		/// <param name="name">The name of the method. Null if anonymous is true.</param>
		/// <param name="anonymous">True if this method is an anonymous one and requires a name.</param>
		/// <param name="parameters">The set of parameters for this method.</param>
		/// <param name="returnType">The type that this method returns.</param>
		/// <param name="isPublic">True if this is a public method; false for private.</param>
		/// <returns>The first fragment following the method, if there is one.</returns>
		protected virtual CodeFragment AddFoundMethod(CodeFragment fragment,CodeFragment body,string name,bool anonymous,BracketFragment parameters,TypeFragment returnType,bool isPublic){
			
			if(body==null){
				fragment.Error("Invalid function definition ("+name+"). The content block {} is missing or isnt valid.");
			}
			
			if(anonymous){
				name="Compiler-Generated-$"+AnonymousCount;
				AnonymousCount++;
			}
			
			// The following is the explicit code block for this function:
			BracketFragment codeBlock=(BracketFragment)body;
			CompiledMethod cMethod=new CompiledMethod(this,name,parameters,codeBlock,returnType,isPublic);
			MethodOverloads set=MakeOrFind(name,cMethod.Builder.ReturnType);
			CodeFragment next=body.NextChild;
			
			if(anonymous){
				CodeFragment newChild=DynamicMethodCompiler.Compile(cMethod,name,set.ReturnType,new ThisOperation(cMethod));
				newChild.AddAfter(body);
			}
			
			body.Remove();
			set.AddMethod(cMethod);
			FindMethods(codeBlock);
			
			return next;
			
		}
        public CompiledMethod(CompiledClass parent, string name, BracketFragment parameterBlock, BracketFragment codeBlock, TypeFragment retType, bool isPublic)
        {
            Name           = name;
            Parent         = parent;
            CodeBlock      = codeBlock;
            Script         = Parent.Script;
            ParameterBlock = parameterBlock;

            Type returnType = null;

            if (retType != null)
            {
                returnType = retType.FindType(Script);
                if (returnType == null)
                {
                    Error("Type '" + retType.Value + "' was not found.");
                }
            }
            string           methodName = Name;
            MethodAttributes attrib     = isPublic?MethodAttributes.Public:MethodAttributes.Private;

            if (methodName == "new")
            {
                methodName = ".ctor";
                attrib    |= MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName;
            }
            // Does the parent base type define this method?
            // If so, use it's name.
            Type baseType = Parent.Builder.BaseType;

            // Parse the parameter set right away:
            ParseParameters();

            MethodInfo mInfo = Types.GetOverload(baseType.GetMethods(), Name, ParameterTypes, true);

            if (mInfo != null)
            {
                methodName = mInfo.Name;
                attrib    |= MethodAttributes.Virtual | MethodAttributes.HideBySig;         //|MethodAttributes.NewSlot;
            }

            bool isVoid = Types.IsVoid(returnType);

            if (isVoid)
            {
                returnType = typeof(void);
            }

            Builder = Parent.Builder.DefineMethod(
                methodName,
                attrib,
                returnType,
                null
                );

            ApplyParameters();

            ILStream    = new NitroIL(Builder.GetILGenerator());
            EndOfMethod = ILStream.DefineLabel();
            if (!isVoid)
            {
                ReturnBay = ILStream.DeclareLocal(returnType);
            }
        }
Exemple #13
0
        /// <summary>Adds a method that was found into this classes set of methods to compile.</summary>
        /// <param name="fragment">The first fragment of the method, used for generating errors. This gives a valid line number.</param>
        /// <param name="body">The block of code for this method.</param>
        /// <param name="name">The name of the method. Null if anonymous is true.</param>
        /// <param name="anonymous">True if this method is an anonymous one and requires a name.</param>
        /// <param name="parameters">The set of parameters for this method.</param>
        /// <param name="returnType">The type that this method returns.</param>
        /// <param name="isPublic">True if this is a public method; false for private.</param>
        /// <returns>The first fragment following the method, if there is one.</returns>
        protected virtual CodeFragment AddFoundMethod(CodeFragment fragment, CodeFragment body, string name, bool anonymous, BracketFragment parameters, TypeFragment returnType, bool isPublic)
        {
            if (body == null)
            {
                fragment.Error("Invalid function definition (" + name + "). The content block {} is missing or isnt valid.");
            }

            if (anonymous)
            {
                name = "Compiler-Generated-$" + AnonymousCount;
                AnonymousCount++;
            }

            // The following is the explicit code block for this function:
            BracketFragment codeBlock = (BracketFragment)body;
            CompiledMethod  cMethod   = new CompiledMethod(this, name, parameters, codeBlock, returnType, isPublic);
            MethodOverloads set       = MakeOrFind(name, cMethod.Builder.ReturnType);
            CodeFragment    next      = body.NextChild;

            if (anonymous)
            {
                CodeFragment newChild = DynamicMethodCompiler.Compile(cMethod, name, set.ReturnType, new ThisOperation(cMethod));
                newChild.AddAfter(body);
            }

            body.Remove();
            set.AddMethod(cMethod);
            FindMethods(codeBlock);

            return(next);
        }
Exemple #14
0
        /// <summary>Finds methods within the given fragment by looking for 'function'.</summary>
        /// <param name="fragment">The fragment to search.</param>
        public void FindMethods(CodeFragment fragment)
        {
            CodeFragment child = fragment.FirstChild;

            while (child != null)
            {
                CodeFragment next = child.NextChild;

                if (child.IsParent)
                {
                    FindMethods(child);
                }

                try{
                    if (child.GetType() == typeof(VariableFragment))
                    {
                        VariableFragment vfrag    = ((VariableFragment)child);
                        CodeFragment     toRemove = null;
                        string           Value    = vfrag.Value;

                        if (Value == "function")
                        {
                            // Found a function.
                            bool isPublic;
                            Modifiers.Handle(vfrag, out isPublic);

                            // The return type could be on the function word (function:String{return "hey!";})
                            TypeFragment returnType = child.GivenType;

                            toRemove = child;
                            child    = child.NextChild;

                            if (child == null)
                            {
                                fragment.Error("Keyword 'function' can't be used on its own.");
                            }

                            toRemove.Remove();
                            string          name       = "";
                            bool            anonymous  = false;
                            BracketFragment parameters = null;

                            if (child.GetType() == typeof(MethodFragment))
                            {
                                MethodFragment method = (MethodFragment)child;
                                name       = ((VariableFragment)(method.MethodName)).Value;
                                parameters = method.Brackets;
                                toRemove   = child;
                                child      = child.NextChild;
                                toRemove.Remove();
                                returnType = method.GivenType;
                            }
                            else if (child.GetType() == typeof(VariableFragment))
                            {
                                // Found the name
                                vfrag = (VariableFragment)child;

                                if (vfrag.IsKeyword())
                                {
                                    vfrag.Error("Keywords cannot be used as function names (" + vfrag.Value + ").");
                                }

                                name = vfrag.Value;

                                if (returnType == null)
                                {
                                    returnType = child.GivenType;
                                }

                                toRemove = child;
                                child    = child.NextChild;
                                toRemove.Remove();

                                if (child == null)
                                {
                                    fragment.Error("Invalid function definition (" + name + "). All brackets are missing or arent valid.");
                                }
                            }
                            else
                            {
                                anonymous = true;
                            }

                            next = AddFoundMethod(fragment, child, name, anonymous, parameters, returnType, isPublic);
                        }
                    }
                    else if (child.GetType() == typeof(MethodFragment))
                    {
                        // Looking for anonymous methods ( defined as function() )
                        MethodFragment method = (MethodFragment)child;

                        if (method.MethodName.GetType() == typeof(VariableFragment))
                        {
                            VariableFragment methodName = ((VariableFragment)(method.MethodName));
                            string           name       = methodName.Value;

                            if (name == "function")
                            {
                                // Found an anonymous function, function():RETURN_TYPE{}.
                                // Note that function{}; is also possible and is handled above.
                                CodeFragment toRemove = child;
                                child = child.NextChild;
                                toRemove.Remove();

                                next = AddFoundMethod(fragment, child, null, true, method.Brackets, method.GivenType, true);
                            }
                            else if (method.Brackets != null)
                            {
                                FindMethods(method.Brackets);
                            }
                        }
                        else if (method.Brackets != null)
                        {
                            FindMethods(method.Brackets);
                        }
                    }
                }catch (CompilationException e) {
                    if (e.LineNumber == -1 && child != null)
                    {
                        // Setup line number:
                        e.LineNumber = child.GetLineNumber();
                    }

                    // Rethrow:
                    throw e;
                }

                child = next;
            }
        }