Esempio n. 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);
 }
Esempio n. 2
0
        public void SetIfFalse(BracketFragment ifFalse)
        {
            IfFalse = ifFalse;

            // Add as child such that code tree iterators can visit them:
            AddChild(IfFalse);
        }
		public SwitchOperation(CompiledMethod method,BracketFragment switching,BracketFragment body):base(method){
			Body=body;
			
			if(switching.ChildCount()!=1){
				
				switching.Error("Too many entries inside this switches brackets. Should be e.g. switch(name){ .. }");
				
			}
			
			// Compile the switching frag:
			CompiledFragment variableFrag=switching.FirstChild.Compile(method);
			
			// Get the active value - this should be a variable object:
			object activeValue=variableFrag.ActiveValue();
			
			// Try and apply it:
			Switching=activeValue as Variable;
			
			if(Switching==null){
				
				switching.Error("Can only switch variables.");
				
			}
			
		}
Esempio n. 4
0
        public ObjectFragment(BracketFragment contents)
        {
            Contents = contents;

            // Add them as children such that code tree iterators can visit them:
            AddChild(Contents);
        }
Esempio n. 5
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);
        }
Esempio n. 6
0
        /// <summary>Finds any other entries in the given code fragment.</summary>
        /// <param name="fragment">The fragment to search.</param>
        public void FindOperations(CodeFragment fragment)
        {
            CodeFragment child = fragment.FirstChild;
            CodeFragment next  = null;

            BracketFragment ovrs = null;

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

                if (child.IsParent)
                {
                    // Got one!
                    // Just gotta transfer it into the method body of OnScriptReady:

                    if (ovrs == null)
                    {
                        ovrs = GetStartMethod().CodeBlock;
                    }

                    // Remove it as a child:
                    child.Remove();

                    // Remove the word 'var' to ensure its properties are globally scoped.
                    GloballyScope(child);

                    // Add it to start method:
                    ovrs.AddChild(child);
                }

                child = next;
            }
        }
		/// <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);
			
		}
		/// <summary>Creates a new method call.</summary>
		/// <param name="brackets">The brackets containing the arguments for the method.</param>
		/// <param name="methodName">The name of the method being called.</param>
		public MethodFragment(BracketFragment brackets,CodeFragment methodName){
			Brackets=brackets;
			MethodName=methodName;
			
			// Add them as children such that code tree iterators can visit them:
			AddChild(Brackets);
			
		}
Esempio n. 9
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);
        }
		public void SetIfFalse(BracketFragment ifFalse){
			
			IfFalse=ifFalse;
			
			// Add as child such that code tree iterators can visit them:
			AddChild(IfFalse);
			
		}
		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 method call.</summary>
        /// <param name="brackets">The brackets containing the arguments for the method.</param>
        /// <param name="methodName">The name of the method being called.</param>
        public MethodFragment(BracketFragment brackets, CodeFragment methodName)
        {
            Brackets   = brackets;
            MethodName = methodName;

            // Add them as children such that code tree iterators can visit them:
            AddChild(Brackets);
        }
Esempio n. 13
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);
        }
        /// <summary>Creates and reads a new for/while loop fragment.</summary>
        /// <param name="sr">The lexer to read the loop content from.</param>
        /// <param name="name">This class represents while too. This is the name of the loop; either 'for' or 'while'.</param>
        public ForFragment(CodeLexer sr, string name)
        {
            Value      = name;
            Parameters = new BracketFragment(sr);
            Body       = new BracketFragment(sr);

            // Add them as children such that code tree iterators can visit them:
            AddChild(Parameters);
            AddChild(Body);
        }
		/// <summary>Creates and reads a new if(){} fragment. Note that the else section is not read.</summary>
		/// <param name="sr">The lexer to read the if condition and its true bracket block from.</param>
		public IfFragment(CodeLexer sr){
			ApplyElseTo=this;
			Condition=new BracketFragment(sr);
			IfTrue=new BracketFragment(sr);
			
			// Add them as children such that code tree iterators can visit them:
			AddChild(Condition);
			AddChild(IfTrue);
			
		}
Esempio n. 16
0
        /// <summary>Creates and reads a new if(){} fragment. Note that the else section is not read.</summary>
        /// <param name="sr">The lexer to read the if condition and its true bracket block from.</param>
        public IfFragment(CodeLexer sr)
        {
            ApplyElseTo = this;
            Condition   = new BracketFragment(sr);
            IfTrue      = new BracketFragment(sr);

            // Add them as children such that code tree iterators can visit them:
            AddChild(Condition);
            AddChild(IfTrue);
        }
		/// <summary>Creates and reads a new for/while loop fragment.</summary>
		/// <param name="sr">The lexer to read the loop content from.</param>
		/// <param name="name">This class represents while too. This is the name of the loop; either 'for' or 'while'.</param>
		public ForFragment(CodeLexer sr,string name){
			Value=name;
			Parameters=new BracketFragment(sr);
			Body=new BracketFragment(sr);
			
			// Add them as children such that code tree iterators can visit them:
			AddChild(Parameters);
			AddChild(Body);
			
		}
		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);
			}
		}
		public IfOperation(CompiledMethod method,BracketFragment condition,BracketFragment ifTrue,BracketFragment ifFalse):base(method){
			IfTrue=ifTrue;
			IfFalse=ifFalse;
			
			Conditions=CompilationServices.CompileParameters(condition,method);
			
			if(Conditions==null||Conditions.Length==0){
				Error("An if was defined but with nothing to check (e.g. if(this is empty!){..} )");
			}
			
		}
        /// <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());
            }
        }
Esempio n. 21
0
        public IfOperation(CompiledMethod method, BracketFragment condition, BracketFragment ifTrue, BracketFragment ifFalse) : base(method)
        {
            IfTrue  = ifTrue;
            IfFalse = ifFalse;

            Conditions = CompilationServices.CompileParameters(condition, method);

            if (Conditions == null || Conditions.Length == 0)
            {
                Error("An if was defined but with nothing to check (e.g. if(this is empty!){..} )");
            }
        }
		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();
		}
Esempio n. 23
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();
 }
Esempio n. 24
0
 /// <summary>Creates a new type fragment by reading it from the given lexer.</summary>
 /// <param name="sr">The lexer to read it from.</param>
 /// <param name="hasColon">True if a colon (:) should be read from the lexer.</param>
 public TypeFragment(CodeLexer sr, bool hasColon)
 {
     HasColon = hasColon;
     if (HasColon)
     {
         // Read off the colon:
         sr.Read();
     }
     // Read until some other block can take over:
     while (true)
     {
         char peek = sr.Peek();
         if (peek == '<')
         {
             List <TypeFragment> generics = new List <TypeFragment>();
             while (true)
             {
                 // Read off the < or the comma:
                 sr.Read();
                 generics.Add(new TypeFragment(sr, false));
                 if (sr.Peek() == '>')
                 {
                     sr.Read();
                     GenericSet = generics.ToArray();
                     break;
                 }
             }
             if (sr.Peek() == '[')
             {
                 SetArray(sr);
             }
             break;
         }
         else if (peek == '[')
         {
             SetArray(sr);
             break;
         }
         else if (peek == ',' || peek == ';' || peek == StringReader.NULL || BracketFragment.AnyBracket(peek) || Operator.IsOperator(peek))
         {
             // Pass control back to the operation:
             break;
         }
         Value += char.ToLower(sr.Read());
     }
 }
        public SwitchOperation(CompiledMethod method, BracketFragment switching, BracketFragment body) : base(method)
        {
            Body = body;

            if (switching.ChildCount() != 1)
            {
                switching.Error("Too many entries inside this switches brackets. Should be e.g. switch(name){ .. }");
            }

            // Compile the switching frag:
            CompiledFragment variableFrag = switching.FirstChild.Compile(method);

            // Get the active value - this should be a variable object:
            object activeValue = variableFrag.ActiveValue();

            // Try and apply it:
            Switching = activeValue as Variable;

            if (Switching == null)
            {
                switching.Error("Can only switch variables.");
            }
        }
        public override AddResult AddTo(CodeFragment to, CodeLexer sr)
        {
            if (Value == "")
            {
                return(AddResult.Ok);
            }
            else if (Value == "var")
            {
                // We're reading a local:
                return(AddResult.Local);
            }
            else if (Value == "for" || Value == "while")
            {
                return(new ForFragment(sr, Value).AddTo(to, sr));
            }
            else if (Value == "switch")
            {
                return(new SwitchFragment(sr).AddTo(to, sr));
            }
            else if (Value == "if")
            {
                return(new IfFragment(sr).AddTo(to, sr));
            }
            else if (Value == "else")
            {
                CodeFragment previous = to.ParentFragment;

                // Parent->prev operation->last object. Should be an IF.

                if (previous == null || ((previous = previous.LastChild) == null) || ((previous = previous.LastChild) == null) || previous.GetType() != typeof(IfFragment))
                {
                    Error("Else can only be applied to an if. E.g. if(){}else{}.");
                }

                IfFragment ifFrag = (IfFragment)previous;

                ifFrag.ApplyElseTo.SetIfFalse(new BracketFragment(sr));

                return(AddResult.Stop);
            }
            else if (Value == "elseif")
            {
                CodeFragment previous = to.ParentFragment;
                // Parent->prev operation->last object. Should be an IF.

                if (previous == null || ((previous = previous.LastChild) == null) || ((previous = previous.LastChild) == null) || previous.GetType() != typeof(IfFragment))
                {
                    Error("Else if can only be applied to an if. E.g. if(){}else if{}..");
                }

                IfFragment ifFrag  = (IfFragment)previous;
                IfFragment newfrag = new IfFragment(sr);

                BracketFragment   bf = new BracketFragment();
                OperationFragment op = new OperationFragment();
                op.AddChild(newfrag);
                bf.AddChild(op);

                ifFrag.ApplyElseTo.SetIfFalse(bf);
                ifFrag.ApplyElseTo = newfrag;

                return(AddResult.Stop);
            }
            else
            {
                return(base.AddTo(to, sr));
            }
        }
		public override AddResult AddTo(CodeFragment to,CodeLexer sr){
			
			if(Value==""){
				return AddResult.Ok;
			}else if(Value=="var"){
				
				// We're reading a local:
				return AddResult.Local;
				
			}else if(Value=="for" || Value=="while"){
				return new ForFragment(sr,Value).AddTo(to,sr);
			}else if(Value=="switch"){
				return new SwitchFragment(sr).AddTo(to,sr);
			}else if(Value=="if"){
				return new IfFragment(sr).AddTo(to,sr);
			}else if(Value=="else"){
				CodeFragment previous=to.ParentFragment;
				
				// Parent->prev operation->last object. Should be an IF.
				
				if(previous==null||((previous=previous.LastChild)==null)||((previous=previous.LastChild)==null)||previous.GetType()!=typeof(IfFragment)){
					Error("Else can only be applied to an if. E.g. if(){}else{}.");
				}
				
				IfFragment ifFrag=(IfFragment)previous;
				
				ifFrag.ApplyElseTo.SetIfFalse(new BracketFragment(sr));
				
				return AddResult.Stop;
			}else if(Value=="elseif"){
				CodeFragment previous=to.ParentFragment;
				// Parent->prev operation->last object. Should be an IF.
				
				if(previous==null||((previous=previous.LastChild)==null)||((previous=previous.LastChild)==null)||previous.GetType()!=typeof(IfFragment)){
					Error("Else if can only be applied to an if. E.g. if(){}else if{}..");
				}
				
				IfFragment ifFrag=(IfFragment)previous;
				IfFragment newfrag=new IfFragment(sr);
				
				 BracketFragment bf=new BracketFragment();
				  OperationFragment op=new OperationFragment();
				  op.AddChild(newfrag);
				 bf.AddChild(op);
				
				ifFrag.ApplyElseTo.SetIfFalse(bf);
				ifFrag.ApplyElseTo=newfrag;
				
				return AddResult.Stop;
				
			}else{
				return base.AddTo(to,sr);
			}
			
		}
Esempio n. 28
0
 public ForOperation(CompiledMethod method, BracketFragment rules, BracketFragment body) : base(method)
 {
     Body       = body;
     Parameters = CompilationServices.CompileParameters(rules, method);
 }
		/// <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);
            }
        }
Esempio n. 31
0
 /// <summary>Creates and reads a new switch fragment.</summary>
 /// <param name="sr">The lexer to read the switch content from.</param>
 public SwitchFragment(CodeLexer sr)
 {
     Parameters = new BracketFragment(sr);
     Body       = new BracketFragment(sr);
 }
		public ForOperation(CompiledMethod method,BracketFragment rules,BracketFragment body):base(method){
			Body=body;
			Parameters=CompilationServices.CompileParameters(rules,method);
		}
		/// <summary>Creates and reads a new switch fragment.</summary>
		/// <param name="sr">The lexer to read the switch content from.</param>
		public SwitchFragment(CodeLexer sr){
			Parameters=new BracketFragment(sr);
			Body=new BracketFragment(sr);
		}
 /// <summary>Creates a property fragment by reading it from the given lexer.</summary>
 /// <param name="sr">The lexer to read the fragment from.</param>
 public PropertyFragment(CodeLexer sr)
 {
     // Skip the dot:
     sr.Read();
     // Read a 'variable':
     Value += char.ToLower(sr.Read());
     while (true)
     {
         char peek = sr.Peek();
         if (peek == ';' || peek == ',' || peek == '.' || peek == StringReader.NULL || BracketFragment.AnyBracket(peek))
         {
             // Pass control back to the operation:
             break;
         }
         Handler handle = Handlers.Find(peek);
         if (handle != Handler.Stop && handle != Handler.Variable && handle != Handler.Number && handle != Handler.Property)
         {
             break;
         }
         Value += char.ToLower(sr.Read());
     }
 }
Esempio n. 35
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;
            }
        }