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