Пример #1
0
		private static Executable ParseClassDefinition(Parser parser, TokenStream tokens, Executable owner)
		{
			Token classToken = tokens.PopExpected("class");
			Token classNameToken = tokens.Pop();
			Parser.VerifyIdentifier(classNameToken);
			List<Token> baseClassTokens = new List<Token>();
			List<string> baseClassStrings = new List<string>();
			if (tokens.PopIfPresent(":"))
			{
				if (baseClassTokens.Count > 0)
				{
					tokens.PopExpected(",");
				}

				Token baseClassToken = tokens.Pop();
				string baseClassName = baseClassToken.Value;

				Parser.VerifyIdentifier(baseClassToken);
				while (tokens.PopIfPresent("."))
				{
					Token baseClassTokenNext = tokens.Pop();
					Parser.VerifyIdentifier(baseClassTokenNext);
					baseClassName += "." + baseClassTokenNext.Value;
				}

				baseClassTokens.Add(baseClassToken);
				baseClassStrings.Add(baseClassName);
			}

			ClassDefinition cd = new ClassDefinition(
				classToken,
				classNameToken,
				baseClassTokens,
				baseClassStrings,
				parser.CurrentNamespace,
				owner);

			tokens.PopExpected("{");
			List<FunctionDefinition> methods = new List<FunctionDefinition>();
			List<FieldDeclaration> fields = new List<FieldDeclaration>();
			ConstructorDefinition constructorDef = null;
			ConstructorDefinition staticConstructorDef = null;

			while (!tokens.PopIfPresent("}"))
			{
				if (tokens.IsNext("function") || tokens.AreNext("static", "function"))
				{
					methods.Add((FunctionDefinition)ExecutableParser.ParseFunction(parser, tokens, cd));
				}
				else if (tokens.IsNext("constructor"))
				{
					if (constructorDef != null)
					{
						throw new ParserException(tokens.Pop(), "Multiple constructors are not allowed. Use optional arguments.");
					}

					constructorDef = (ConstructorDefinition)ExecutableParser.ParseConstructor(parser, tokens, cd);
				}
				else if (tokens.AreNext("static", "constructor"))
				{
					tokens.Pop(); // static token
					if (staticConstructorDef != null)
					{
						throw new ParserException(tokens.Pop(), "Multiple static constructors are not allowed.");
					}

					staticConstructorDef = (ConstructorDefinition)ExecutableParser.ParseConstructor(parser, tokens, cd);
				}
				else if (tokens.IsNext("field") || tokens.AreNext("static", "field"))
				{
					fields.Add(ExecutableParser.ParseField(tokens, cd));
				}
				else
				{
					tokens.PopExpected("}");
				}
			}

			cd.Methods = methods.ToArray();
			cd.Constructor = constructorDef;
			cd.StaticConstructor = staticConstructorDef;
			cd.Fields = fields.ToArray();

			return cd;
		}
Пример #2
0
        private ClassDefinition ParseClassDefinition(TokenStream tokens, TopLevelConstruct owner, Token staticToken, Token finalToken, FileScope fileScope)
        {
            Token classToken     = tokens.PopExpected(this.parser.Keywords.CLASS);
            Token classNameToken = tokens.Pop();

            this.parser.VerifyIdentifier(classNameToken);
            List <Token>  baseClassTokens  = new List <Token>();
            List <string> baseClassStrings = new List <string>();

            if (tokens.PopIfPresent(":"))
            {
                if (baseClassTokens.Count > 0)
                {
                    tokens.PopExpected(",");
                }

                Token  baseClassToken = tokens.Pop();
                string baseClassName  = baseClassToken.Value;

                this.parser.VerifyIdentifier(baseClassToken);
                while (tokens.PopIfPresent("."))
                {
                    Token baseClassTokenNext = tokens.Pop();
                    this.parser.VerifyIdentifier(baseClassTokenNext);
                    baseClassName += "." + baseClassTokenNext.Value;
                }

                baseClassTokens.Add(baseClassToken);
                baseClassStrings.Add(baseClassName);
            }

            ClassDefinition cd = new ClassDefinition(
                classToken,
                classNameToken,
                baseClassTokens,
                baseClassStrings,
                parser.CurrentNamespace,
                owner,
                parser.CurrentLibrary,
                staticToken,
                finalToken,
                fileScope);

            tokens.PopExpected("{");
            List <FunctionDefinition> methods              = new List <FunctionDefinition>();
            List <FieldDeclaration>   fields               = new List <FieldDeclaration>();
            ConstructorDefinition     constructorDef       = null;
            ConstructorDefinition     staticConstructorDef = null;

            while (!tokens.PopIfPresent("}"))
            {
                Dictionary <string, List <Annotation> > annotations = null;

                while (tokens.IsNext("@"))
                {
                    annotations = annotations ?? new Dictionary <string, List <Annotation> >();
                    Annotation annotation = this.parser.AnnotationParser.ParseAnnotation(tokens);
                    if (!annotations.ContainsKey(annotation.Type))
                    {
                        annotations[annotation.Type] = new List <Annotation>();
                    }

                    annotations[annotation.Type].Add(annotation);
                }

                if (tokens.IsNext(this.parser.Keywords.FUNCTION) ||
                    tokens.AreNext(this.parser.Keywords.STATIC, this.parser.Keywords.FUNCTION))
                {
                    methods.Add((FunctionDefinition)this.parser.ExecutableParser.ParseFunction(tokens, cd, fileScope));
                }
                else if (tokens.IsNext(this.parser.Keywords.CONSTRUCTOR))
                {
                    if (constructorDef != null)
                    {
                        throw new ParserException(tokens.Pop(), "Multiple constructors are not allowed. Use optional arguments.");
                    }

                    constructorDef = (ConstructorDefinition)this.parser.ExecutableParser.ParseConstructor(tokens, cd);

                    if (annotations != null && annotations.ContainsKey(this.parser.Keywords.PRIVATE))
                    {
                        constructorDef.PrivateAnnotation = annotations[this.parser.Keywords.PRIVATE][0];
                        annotations[this.parser.Keywords.PRIVATE].RemoveAt(0);
                    }
                }
                else if (tokens.AreNext(this.parser.Keywords.STATIC, this.parser.Keywords.CONSTRUCTOR))
                {
                    tokens.Pop(); // static token
                    if (staticConstructorDef != null)
                    {
                        throw new ParserException(tokens.Pop(), "Multiple static constructors are not allowed.");
                    }

                    staticConstructorDef = (ConstructorDefinition)this.parser.ExecutableParser.ParseConstructor(tokens, cd);
                }
                else if (tokens.IsNext(this.parser.Keywords.FIELD) ||
                         tokens.AreNext(this.parser.Keywords.STATIC, this.parser.Keywords.FIELD))
                {
                    fields.Add(this.parser.ExecutableParser.ParseField(tokens, cd));
                }
                else
                {
                    tokens.PopExpected("}");
                }

                if (annotations != null)
                {
                    foreach (List <Annotation> annotationsOfType in annotations.Values)
                    {
                        if (annotationsOfType.Count > 0)
                        {
                            throw new ParserException(annotationsOfType[0].FirstToken, "Unused or extra annotation.");
                        }
                    }
                }
            }

            cd.Methods           = methods.ToArray();
            cd.Constructor       = constructorDef;
            cd.StaticConstructor = staticConstructorDef;
            cd.Fields            = fields.ToArray();

            return(cd);
        }
Пример #3
0
        private static Executable ParseClassDefinition(Parser parser, TokenStream tokens, Executable owner, Token staticToken, Token finalToken)
        {
            Token classToken     = tokens.PopExpected("class");
            Token classNameToken = tokens.Pop();

            Parser.VerifyIdentifier(classNameToken);
            List <Token>  baseClassTokens  = new List <Token>();
            List <string> baseClassStrings = new List <string>();

            if (tokens.PopIfPresent(":"))
            {
                if (baseClassTokens.Count > 0)
                {
                    tokens.PopExpected(",");
                }

                Token  baseClassToken = tokens.Pop();
                string baseClassName  = baseClassToken.Value;

                Parser.VerifyIdentifier(baseClassToken);
                while (tokens.PopIfPresent("."))
                {
                    Token baseClassTokenNext = tokens.Pop();
                    Parser.VerifyIdentifier(baseClassTokenNext);
                    baseClassName += "." + baseClassTokenNext.Value;
                }

                baseClassTokens.Add(baseClassToken);
                baseClassStrings.Add(baseClassName);
            }

            ClassDefinition cd = new ClassDefinition(
                classToken,
                classNameToken,
                baseClassTokens,
                baseClassStrings,
                parser.CurrentNamespace,
                owner,
                staticToken,
                finalToken);

            tokens.PopExpected("{");
            List <FunctionDefinition> methods              = new List <FunctionDefinition>();
            List <FieldDeclaration>   fields               = new List <FieldDeclaration>();
            ConstructorDefinition     constructorDef       = null;
            ConstructorDefinition     staticConstructorDef = null;

            while (!tokens.PopIfPresent("}"))
            {
                Dictionary <string, List <Annotation> > annotations = null;

                while (tokens.IsNext("@"))
                {
                    annotations = annotations ?? new Dictionary <string, List <Annotation> >();
                    Annotation annotation = AnnotationParser.ParseAnnotation(tokens);
                    if (!annotations.ContainsKey(annotation.Type))
                    {
                        annotations[annotation.Type] = new List <Annotation>();
                    }

                    annotations[annotation.Type].Add(annotation);
                }

                if (tokens.IsNext("function") || tokens.AreNext("static", "function"))
                {
                    methods.Add((FunctionDefinition)ExecutableParser.ParseFunction(parser, tokens, cd));
                }
                else if (tokens.IsNext("constructor"))
                {
                    if (constructorDef != null)
                    {
                        throw new ParserException(tokens.Pop(), "Multiple constructors are not allowed. Use optional arguments.");
                    }

                    constructorDef = (ConstructorDefinition)ExecutableParser.ParseConstructor(parser, tokens, cd);

                    if (annotations != null && annotations.ContainsKey("private"))
                    {
                        constructorDef.PrivateAnnotation = annotations["private"][0];
                        annotations["private"].RemoveAt(0);
                    }
                }
                else if (tokens.AreNext("static", "constructor"))
                {
                    tokens.Pop(); // static token
                    if (staticConstructorDef != null)
                    {
                        throw new ParserException(tokens.Pop(), "Multiple static constructors are not allowed.");
                    }

                    staticConstructorDef = (ConstructorDefinition)ExecutableParser.ParseConstructor(parser, tokens, cd);
                }
                else if (tokens.IsNext("field") || tokens.AreNext("static", "field"))
                {
                    fields.Add(ExecutableParser.ParseField(tokens, cd));
                }
                else
                {
                    tokens.PopExpected("}");
                }

                if (annotations != null)
                {
                    foreach (List <Annotation> annotationsOfType in annotations.Values)
                    {
                        if (annotationsOfType.Count > 0)
                        {
                            throw new ParserException(annotationsOfType[0].FirstToken, "Unused or extra annotation.");
                        }
                    }
                }
            }

            cd.Methods           = methods.ToArray();
            cd.Constructor       = constructorDef;
            cd.StaticConstructor = staticConstructorDef;
            cd.Fields            = fields.ToArray();

            return(cd);
        }