예제 #1
0
        public static ModifierCollection CreateStaticModifier(Token aToken)
        {
            ModifierCollection modifiers = new ModifierCollection(new Token[0]);

            modifiers.FirstToken = aToken;
            modifiers.tokens[(int)ModifierType.STATIC] = aToken;
            return(modifiers);
        }
예제 #2
0
 protected virtual FunctionDefinition MaybeParseFunctionDefinition(
     TokenStream tokens,
     Node owner,
     FileScope fileScope,
     AnnotationCollection annotations,
     ModifierCollection modifiers)
 {
     return(null);
 }
예제 #3
0
        protected virtual ConstructorDefinition ParseConstructor(
            TokenStream tokens,
            ClassDefinition owner,
            ModifierCollection modifiers,
            AnnotationCollection annotations)
        {
            Token constructorToken     = tokens.PopExpected(this.parser.Keywords.CONSTRUCTOR);
            ConstructorDefinition ctor = new ConstructorDefinition(constructorToken, modifiers, annotations, owner);

            tokens.PopExpected("(");

            List <AType>      argTypes  = new List <AType>();
            List <Token>      argNames  = new List <Token>();
            List <Expression> argValues = new List <Expression>();

            this.ParseArgumentListDeclaration(tokens, ctor, argTypes, argNames, argValues);

            List <Expression> baseArgs  = new List <Expression>();
            Token             baseToken = null;

            if (tokens.PopIfPresent(":"))
            {
                baseToken = tokens.PopExpected(this.parser.Keywords.BASE);
                tokens.PopExpected("(");
                while (!tokens.PopIfPresent(")"))
                {
                    if (baseArgs.Count > 0)
                    {
                        tokens.PopExpected(",");
                    }

                    baseArgs.Add(this.parser.ExpressionParser.Parse(tokens, ctor));
                }
            }

            IList <Executable> code = this.parser.ExecutableParser.ParseBlock(tokens, true, ctor);

            ctor.SetArgs(argNames, argValues, argTypes);
            ctor.SetBaseArgs(baseArgs);
            ctor.SetCode(code);
            ctor.BaseToken = baseToken;
            return(ctor);
        }
예제 #4
0
        protected virtual EnumDefinition ParseEnumDefinition(
            TokenStream tokens,
            Node owner,
            FileScope fileScope,
            ModifierCollection modifiers,
            AnnotationCollection annotations)
        {
            Token enumToken = tokens.PopExpected(this.parser.Keywords.ENUM);
            Token nameToken = tokens.Pop();

            this.parser.VerifyIdentifier(nameToken);
            string         name = nameToken.Value;
            EnumDefinition ed   = new EnumDefinition(enumToken, nameToken, owner, fileScope, modifiers, annotations);

            tokens.PopExpected("{");
            bool              nextForbidden = false;
            List <Token>      items         = new List <Token>();
            List <Expression> values        = new List <Expression>();

            while (!tokens.PopIfPresent("}"))
            {
                if (nextForbidden)
                {
                    tokens.PopExpected("}");                // crash
                }
                Token enumItem = tokens.Pop();
                this.parser.VerifyIdentifier(enumItem);
                if (tokens.PopIfPresent("="))
                {
                    values.Add(this.parser.ExpressionParser.Parse(tokens, ed));
                }
                else
                {
                    values.Add(null);
                }
                nextForbidden = !tokens.PopIfPresent(",");
                items.Add(enumItem);
            }

            ed.SetItems(items, values);
            return(ed);
        }
예제 #5
0
        internal virtual TopLevelEntity Parse(
            TokenStream tokens,
            TopLevelEntity owner,
            FileScope fileScope)
        {
            AnnotationCollection annotations = this.parser.AnnotationParser.ParseAnnotations(tokens);

            ModifierCollection modifiers = ModifierCollection.Parse(tokens);

            string value = tokens.PeekValue();

            if (value == this.parser.Keywords.IMPORT)
            {
                throw this.parser.GenerateParseError(
                          ErrorMessages.ALL_IMPORTS_MUST_OCCUR_AT_BEGINNING_OF_FILE,
                          tokens.Pop());
            }

            // TODO: check for annotations that aren't used.
            // https://github.com/blakeohare/crayon/issues/305

            if (value == this.parser.Keywords.NAMESPACE)
            {
                return(this.ParseNamespace(tokens, owner, fileScope, annotations));
            }
            if (value == this.parser.Keywords.CONST)
            {
                return(this.ParseConst(tokens, owner, fileScope, modifiers, annotations));
            }
            if (value == this.parser.Keywords.FUNCTION)
            {
                return(this.ParseFunction(tokens, owner, fileScope, modifiers, annotations));
            }
            if (value == this.parser.Keywords.CLASS)
            {
                return(this.ParseClassDefinition(tokens, owner, fileScope, modifiers, annotations));
            }
            if (value == this.parser.Keywords.ENUM)
            {
                return(this.ParseEnumDefinition(tokens, owner, fileScope, modifiers, annotations));
            }
            if (value == this.parser.Keywords.CONSTRUCTOR && owner is ClassDefinition)
            {
                return(this.ParseConstructor(tokens, (ClassDefinition)owner, modifiers, annotations));
            }

            FunctionDefinition nullableFunctionDef = this.MaybeParseFunctionDefinition(tokens, owner, fileScope, annotations, modifiers);

            if (nullableFunctionDef != null)
            {
                return(nullableFunctionDef);
            }

            tokens.EnsureNotEof();

            Token token = tokens.Peek();

            throw ParserException.ThrowException(
                      this.parser.CurrentLocale,
                      ErrorMessages.UNEXPECTED_TOKEN_NO_SPECIFIC_EXPECTATIONS,
                      token,
                      token.Value);
        }
예제 #6
0
 protected abstract FunctionDefinition ParseFunction(
     TokenStream tokens,
     TopLevelEntity nullableOwner,
     FileScope fileScope,
     ModifierCollection modifiers,
     AnnotationCollection annotations);
예제 #7
0
 protected abstract FieldDefinition ParseField(
     TokenStream tokens,
     ClassDefinition owner,
     ModifierCollection modifiers,
     AnnotationCollection annotations);
예제 #8
0
        protected virtual ClassDefinition ParseClassDefinition(
            TokenStream tokens,
            Node owner,
            FileScope fileScope,
            ModifierCollection modifiers,
            AnnotationCollection classAnnotations)
        {
            Token classToken     = tokens.PopExpected(this.parser.Keywords.CLASS);
            Token classNameToken = tokens.Pop();

            if (classNameToken.Type != TokenType.WORD)
            {
                throw new ParserException(classNameToken, "This is not a valid class name.");
            }
            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,
                owner,
                fileScope,
                modifiers,
                classAnnotations,
                this.parser);

            tokens.PopExpected("{");
            List <FunctionDefinition> methods    = new List <FunctionDefinition>();
            List <FieldDefinition>    fields     = new List <FieldDefinition>();
            List <PropertyDefinition> properties = new List <PropertyDefinition>();

            while (!tokens.PopIfPresent("}"))
            {
                this.ParseClassMember(tokens, fileScope, cd, methods, fields, properties);
            }

            cd.Methods = methods.ToArray();
            cd.Fields  = fields.ToArray();

            if (cd.Constructor == null)
            {
                // This should be empty if there is no base class, or just pass along the base class' args if there is.
                cd.Constructor = new ConstructorDefinition(
                    cd,
                    ModifierCollection.EMPTY,
                    new AnnotationCollection(parser));
                if (cd.BaseClassTokens.Length > 0)
                {
                    cd.Constructor.BaseToken = cd.FirstToken;
                    cd.Constructor.SetBaseArgs(new Expression[0]);
                }
            }

            return(cd);
        }
예제 #9
0
 protected abstract ConstDefinition ParseConst(
     TokenStream tokens,
     Node owner,
     FileScope fileScope,
     ModifierCollection modifiers,
     AnnotationCollection annotations);