Exemple #1
0
        public override AddResult AddTo(CodeFragment to, CodeLexer sr)
        {
            if (Bracket == '[')
            {
                if (to.LastChild == null)
                {
                    Error("Unexpected indexing. must be something[index].");
                }
                else
                {
                    CodeFragment var = to.LastChild;
                    var.Remove();

                    return(new IndexFragment(this, var).AddTo(to, sr));
                }
            }
            else if (Bracket == '{' && to.LastChild != null)
            {
                // new TYPE[]{default,default..};

                if (to.LastChild.GetType() == typeof(VariableFragment) && ((VariableFragment)(to.LastChild)).Value == "new")
                {
                    VariableFragment var = (VariableFragment)(to.LastChild);

                    if (var.GivenType == null)
                    {
                        Error("new must always be followed by a type name.");
                    }
                    else if (!var.GivenType.IsArray)
                    {
                        Error("new Type{} only works when Type is an array and curley brackets define it's default values e.g. new int[]{1,2}");
                    }
                    else
                    {
                        var.Remove();
                        return(new ArrayFragment(var.GivenType, this).AddTo(to, sr));
                    }
                }
            }
            else if (Bracket == '(' && to.LastChild != null)
            {
                Type type = to.LastChild.GetType();

                if (type == typeof(IndexFragment) || type == typeof(PropertyFragment) || (type == typeof(VariableFragment) && !((VariableFragment)(to.LastChild)).IsKeyword()))
                {
                    // Method call!
                    CodeFragment meth = to.LastChild;
                    meth.Remove();

                    return(new MethodFragment(this, meth).AddTo(to, sr));
                }
            }

            return(base.AddTo(to, sr));
        }
 public override AddResult AddTo(CodeFragment to, CodeLexer sr)
 {
     if (MethodName.GetType() == typeof(VariableFragment))
     {
         VariableFragment vfrag = (VariableFragment)MethodName;
         if (vfrag.Value == "new")
         {
             CodeFragment p = to.LastChild;
             if (p == null || p.GetType() != typeof(VariableFragment) || ((VariableFragment)p).Value != "function")
             {
                 // Constructor call.
                 vfrag.Remove();
                 return(new ConstructorFragment(vfrag.GivenType, Brackets).AddTo(to, sr));
             }
         }
     }
     return(base.AddTo(to, sr));
 }
Exemple #3
0
        /// <summary>Finds all classes within the given code fragment, identified with 'class'.</summary>
        /// <param name="frag">The fragment to search.</param>
        private void FindClasses(CodeFragment frag)
        {
            CodeFragment child = frag.FirstChild;

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

                if (child.IsParent)
                {
                    FindClasses(child);
                }
                else if (child.GetType() == typeof(VariableFragment))
                {
                    VariableFragment vfrag = (VariableFragment)child;

                    if (vfrag.Value == "class")
                    {
                        bool isPublic;
                        Modifiers.Handle(vfrag, out isPublic);

                        Type         baseType  = null;
                        CodeFragment nameBlock = vfrag.NextChild;

                        if (nameBlock == null || nameBlock.GetType() != typeof(VariableFragment))
                        {
                            vfrag.Error("Class keyword used but no class name given.");
                        }

                        vfrag.Remove();
                        vfrag = (VariableFragment)nameBlock;

                        if (vfrag.IsKeyword())
                        {
                            vfrag.Error("Can't use keywords for class names.");
                        }

                        string name = vfrag.Value;

                        if (Types.ContainsKey(name))
                        {
                            vfrag.Error("Cannot redefine class " + name + " - it already exists in this scope.");
                        }

                        if (vfrag.GivenType != null)
                        {
                            baseType = vfrag.GivenType.FindType(this);
                        }

                        if (baseType == null)
                        {
                            baseType = typeof(object);
                        }

                        CodeFragment cblock = vfrag.NextChild;

                        if (cblock == null || cblock.GetType() != typeof(BracketFragment))
                        {
                            vfrag.Error("Class " + name + " is missing it's code body. Correct syntax: class " + name + "{ .. }.");
                        }

                        next = cblock.NextChild;
                        vfrag.Remove();
                        cblock.Remove();
                        Types.Add(name, new CompiledClass(cblock, this, name, baseType, isPublic));
                    }
                }

                child = next;
            }
        }
		/// <summary>Compiles a known keyword fragment into the given method.</summary>
		/// <param name="kwd">The known keyword fragment. return, using, break or continue.</param>
		/// <param name="method">The method to compile the fragment into.</param>
		/// <returns>A compiled instruction of the given keyword.</returns>
		public static CompiledFragment Compile(VariableFragment kwd,CompiledMethod method){
			OperationFragment parent=(OperationFragment)kwd.ParentFragment;
			switch(kwd.Value){
				case "return":
				if(kwd.PreviousChild!=null){
					kwd.Error("Return cannot follow other operations. You might have a missing ;.");
				}
				kwd.Remove();
				ReturnOperation returnOperation=new ReturnOperation(method);
				
				if(parent.FirstChild!=null){
					if((returnOperation.Input0=parent.Compile(method))==null){
						return null;
					}
				}
				
				parent.FirstChild=returnOperation;
				return returnOperation;
				
				case "typeof":
				if(kwd.PreviousChild!=null){
					kwd.Error("Typeof cannot follow other operations. You might have a missing ;.");
				}
				kwd.Remove();
				TypeofOperation tOperation=new TypeofOperation(method);
				
				if(parent.FirstChild==null){
					kwd.Error("typeof command is missing the thing to find the type of.");
				}
				
				if((tOperation.Input0=parent.Compile(method))==null){
					return null;
				}
				
				parent.FirstChild=tOperation;
				return tOperation;
				
				case "using":
				if(kwd.PreviousChild!=null){
					kwd.Error("Using cannot follow other operations. You might be missing a ;.");
				}
				
				kwd.Remove();
				
				if(parent.FirstChild!=null){
					method.Script.AddReference(parent.FirstChild);
				}
				
				return null;
				
				case "break":
				kwd.Remove();
				BreakOperation breakOperation=new BreakOperation(method,1);
				
				if(parent.FirstChild!=null){
					CompiledFragment cf=parent.Compile(method);
					
					if(cf.Value!=null&&cf.Value.GetType()==typeof(int)){
						breakOperation.Depth=(int)cf.Value;
						
						if(breakOperation.Depth<=0){
							parent.Error("Break operations must be greater than 0 loops.");
						}
						
					}else{
						parent.Error("Break statements can only be followed by a fixed integer constant, e.g. break 2; or just break;");
					}
					
				}
				
				parent.FirstChild=breakOperation;
				return breakOperation;
				
				case "continue":
				kwd.Remove();
				ContinueOperation cOperation=new ContinueOperation(method,1);
				
				if(parent.FirstChild!=null){
					CompiledFragment cf=parent.Compile(method);
					
					if(cf.Value!=null&&cf.Value.GetType()==typeof(int)){
						cOperation.Depth=(int)cf.Value;
						if(cOperation.Depth<=0){
							parent.Error("Continue operations must be greater than 0 loops.");
						}
					}else{
						parent.Error("Continue statements can only be followed by a fixed integer constant, e.g. continue 2; or just continue;");
					}
					
				}
				
				parent.FirstChild=cOperation;
				return cOperation;
				
				default:
				parent.Error("Unrecognised keyword: "+kwd.Value);
				return null;
			}
		}
Exemple #5
0
        /// <summary>Compiles a known keyword fragment into the given method.</summary>
        /// <param name="kwd">The known keyword fragment. return, using, break or continue.</param>
        /// <param name="method">The method to compile the fragment into.</param>
        /// <returns>A compiled instruction of the given keyword.</returns>
        public static CompiledFragment Compile(VariableFragment kwd, CompiledMethod method)
        {
            OperationFragment parent = (OperationFragment)kwd.ParentFragment;

            switch (kwd.Value)
            {
            case "return":
                if (kwd.PreviousChild != null)
                {
                    kwd.Error("Return cannot follow other operations. You might have a missing ;.");
                }
                kwd.Remove();
                ReturnOperation returnOperation = new ReturnOperation(method);

                if (parent.FirstChild != null)
                {
                    if ((returnOperation.Input0 = parent.Compile(method)) == null)
                    {
                        return(null);
                    }
                }

                parent.FirstChild = returnOperation;
                return(returnOperation);

            case "typeof":
                if (kwd.PreviousChild != null)
                {
                    kwd.Error("Typeof cannot follow other operations. You might have a missing ;.");
                }
                kwd.Remove();
                TypeofOperation tOperation = new TypeofOperation(method);

                if (parent.FirstChild == null)
                {
                    kwd.Error("typeof command is missing the thing to find the type of.");
                }

                if ((tOperation.Input0 = parent.Compile(method)) == null)
                {
                    return(null);
                }

                parent.FirstChild = tOperation;
                return(tOperation);

            case "using":
                if (kwd.PreviousChild != null)
                {
                    kwd.Error("Using cannot follow other operations. You might be missing a ;.");
                }

                kwd.Remove();

                if (parent.FirstChild != null)
                {
                    method.Script.AddReference(parent.FirstChild);
                }

                return(null);

            case "break":
                kwd.Remove();
                BreakOperation breakOperation = new BreakOperation(method, 1);

                if (parent.FirstChild != null)
                {
                    CompiledFragment cf = parent.Compile(method);

                    if (cf.Value != null && cf.Value.GetType() == typeof(int))
                    {
                        breakOperation.Depth = (int)cf.Value;

                        if (breakOperation.Depth <= 0)
                        {
                            parent.Error("Break operations must be greater than 0 loops.");
                        }
                    }
                    else
                    {
                        parent.Error("Break statements can only be followed by a fixed integer constant, e.g. break 2; or just break;");
                    }
                }

                parent.FirstChild = breakOperation;
                return(breakOperation);

            case "continue":
                kwd.Remove();
                ContinueOperation cOperation = new ContinueOperation(method, 1);

                if (parent.FirstChild != null)
                {
                    CompiledFragment cf = parent.Compile(method);

                    if (cf.Value != null && cf.Value.GetType() == typeof(int))
                    {
                        cOperation.Depth = (int)cf.Value;
                        if (cOperation.Depth <= 0)
                        {
                            parent.Error("Continue operations must be greater than 0 loops.");
                        }
                    }
                    else
                    {
                        parent.Error("Continue statements can only be followed by a fixed integer constant, e.g. continue 2; or just continue;");
                    }
                }

                parent.FirstChild = cOperation;
                return(cOperation);

            default:
                parent.Error("Unrecognised keyword: " + kwd.Value);
                return(null);
            }
        }