Example #1
0
        private static Executable ParseEnumDefinition(Parser parser, TokenStream tokens, Executable owner)
        {
            Token enumToken = tokens.PopExpected("enum");
            Token nameToken = tokens.Pop();

            Parser.VerifyIdentifier(nameToken);
            string name = nameToken.Value;

            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();
                Parser.VerifyIdentifier(enumItem);
                if (tokens.PopIfPresent("="))
                {
                    values.Add(ExpressionParser.Parse(tokens, owner));
                }
                else
                {
                    values.Add(null);
                }
                nextForbidden = !tokens.PopIfPresent(",");
                items.Add(enumItem);
            }

            return(new EnumDefinition(enumToken, nameToken, parser.CurrentNamespace, items, values, owner));
        }
Example #2
0
        private static Executable ParseStruct(TokenStream tokens, Executable owner)
        {
            Token structToken     = tokens.PopExpected("struct");
            Token structNameToken = tokens.Pop();

            Parser.VerifyIdentifier(structNameToken);

            tokens.PopExpected("{");

            List <Token>      fieldTokens     = new List <Token>();
            List <Annotation> typeAnnotations = new List <Annotation>();
            bool nextForbidden = false;

            while (!tokens.PopIfPresent("}"))
            {
                if (nextForbidden)
                {
                    tokens.PopExpected("}");                // crash
                }
                Annotation annotation = tokens.IsNext("@") ? AnnotationParser.ParseAnnotation(tokens) : null;

                Token fieldToken = tokens.Pop();
                Parser.VerifyIdentifier(fieldToken);
                nextForbidden = !tokens.PopIfPresent(",");
                fieldTokens.Add(fieldToken);
                typeAnnotations.Add(annotation);
            }

            return(new StructDefinition(structToken, structNameToken, fieldTokens, typeAnnotations, owner));
        }
Example #3
0
        private Namespace ParseNamespace(TokenStream tokens, TopLevelConstruct owner, FileScope fileScope)
        {
            Token namespaceToken = tokens.PopExpected(this.parser.Keywords.NAMESPACE);
            Token first          = tokens.Pop();

            this.parser.VerifyIdentifier(first);
            List <Token> namespacePieces = new List <Token>()
            {
                first
            };
            string namespaceBuilder = first.Value;

            parser.RegisterNamespace(namespaceBuilder);
            while (tokens.PopIfPresent("."))
            {
                Token nsToken = tokens.Pop();
                this.parser.VerifyIdentifier(nsToken);
                namespacePieces.Add(nsToken);
                namespaceBuilder += "." + nsToken.Value;
                parser.RegisterNamespace(namespaceBuilder);
            }

            string name = string.Join(".", namespacePieces.Select <Token, string>(t => t.Value));

            parser.PushNamespacePrefix(name);

            Namespace namespaceInstance = new Namespace(namespaceToken, name, owner, parser.CurrentLibrary, fileScope);

            tokens.PopExpected("{");
            List <TopLevelConstruct> namespaceMembers = new List <TopLevelConstruct>();

            while (!tokens.PopIfPresent("}"))
            {
                TopLevelConstruct executable = this.parser.ExecutableParser.ParseTopLevel(tokens, namespaceInstance, fileScope);
                if (executable is FunctionDefinition ||
                    executable is ClassDefinition ||
                    executable is EnumDefinition ||
                    executable is ConstStatement ||
                    executable is Namespace)
                {
                    namespaceMembers.Add(executable);
                }
                else
                {
                    throw new ParserException(executable.FirstToken, "Only function, class, and nested namespace declarations may exist as direct members of a namespace.");
                }
            }

            namespaceInstance.Code = namespaceMembers.ToArray();

            parser.PopNamespacePrefix();

            return(namespaceInstance);
        }
Example #4
0
        private static Executable ParseNamespace(Parser parser, TokenStream tokens, Executable owner)
        {
            Token namespaceToken = tokens.PopExpected("namespace");
            Token first          = tokens.Pop();

            Parser.VerifyIdentifier(first);
            List <Token> namespacePieces = new List <Token>()
            {
                first
            };

            while (tokens.PopIfPresent("."))
            {
                Token nsToken = tokens.Pop();
                Parser.VerifyIdentifier(nsToken);
                namespacePieces.Add(nsToken);
            }

            string name = string.Join(".", namespacePieces.Select <Token, string>(t => t.Value));

            parser.PushNamespacePrefix(name);

            Namespace namespaceInstance = new Namespace(namespaceToken, name, owner);

            tokens.PopExpected("{");
            List <Executable> namespaceMembers = new List <Executable>();

            while (!tokens.PopIfPresent("}"))
            {
                Executable executable = ExecutableParser.Parse(parser, tokens, false, false, true, namespaceInstance);
                if (executable is FunctionDefinition ||
                    executable is ClassDefinition ||
                    executable is EnumDefinition ||
                    executable is ConstStatement ||
                    executable is Namespace)
                {
                    namespaceMembers.Add(executable);
                }
                else
                {
                    throw new ParserException(executable.FirstToken, "Only function, class, and nested namespace declarations may exist as direct members of a namespace.");
                }
            }

            namespaceInstance.Code = namespaceMembers.ToArray();

            parser.PopNamespacePrefix();

            return(namespaceInstance);
        }
Example #5
0
        public Annotation ParseAnnotation(TokenStream tokens)
        {
            Token annotationToken = tokens.PopExpected("@");
            Token typeToken       = tokens.Pop();

            // TODO: refactor this. All built-in annotations should be exempt from the VerifyIdentifier check in an extensible way.
            if (typeToken.Value != this.parser.Keywords.PRIVATE)
            {
                parser.VerifyIdentifier(typeToken);
            }

            List <Expression> args = new List <Expression>();

            if (tokens.PopIfPresent("("))
            {
                while (!tokens.PopIfPresent(")"))
                {
                    if (args.Count > 0)
                    {
                        tokens.PopExpected(",");
                    }

                    args.Add(this.parser.ExpressionParser.Parse(tokens, null));
                }
            }
            return(new Annotation(annotationToken, typeToken, args));
        }
Example #6
0
        private Executable ParseFor(TokenStream tokens, TopLevelConstruct owner)
        {
            Token forToken = tokens.PopExpected(this.parser.Keywords.FOR);

            tokens.PopExpected("(");
            if (!tokens.HasMore)
            {
                tokens.ThrowEofException();
            }

            if (this.parser.IsValidIdentifier(tokens.PeekValue()) && tokens.PeekValue(1) == ":")
            {
                Token iteratorToken = tokens.Pop();
                if (this.parser.IsReservedKeyword(iteratorToken.Value))
                {
                    throw new ParserException(iteratorToken, "Cannot use this name for an iterator.");
                }
                tokens.PopExpected(":");
                Expression iterationExpression = this.parser.ExpressionParser.Parse(tokens, owner);
                tokens.PopExpected(")");
                IList <Executable> body = Parser.ParseBlock(parser, tokens, false, owner);

                return(new ForEachLoop(forToken, iteratorToken, iterationExpression, body, owner));
            }
            else
            {
                List <Executable> init = new List <Executable>();
                while (!tokens.PopIfPresent(";"))
                {
                    if (init.Count > 0)
                    {
                        tokens.PopExpected(",");
                    }
                    init.Add(this.Parse(tokens, true, false, owner));
                }
                Expression condition = null;
                if (!tokens.PopIfPresent(";"))
                {
                    condition = this.parser.ExpressionParser.Parse(tokens, owner);
                    tokens.PopExpected(";");
                }
                List <Executable> step = new List <Executable>();
                while (!tokens.PopIfPresent(")"))
                {
                    if (step.Count > 0)
                    {
                        tokens.PopExpected(",");
                    }
                    step.Add(this.Parse(tokens, true, false, owner));
                }

                IList <Executable> body = Parser.ParseBlock(parser, tokens, false, owner);

                return(new ForLoop(forToken, init, condition, step, body, owner));
            }
        }
Example #7
0
        private ConstructorDefinition ParseConstructor(TokenStream tokens, TopLevelConstruct owner)
        {
            Token constructorToken = tokens.PopExpected(this.parser.Keywords.CONSTRUCTOR);

            tokens.PopExpected("(");
            List <Token>      argNames  = new List <Token>();
            List <Expression> argValues = new List <Expression>();
            bool optionalArgFound       = false;

            while (!tokens.PopIfPresent(")"))
            {
                if (argNames.Count > 0)
                {
                    tokens.PopExpected(",");
                }

                Token argName = tokens.Pop();
                this.parser.VerifyIdentifier(argName);
                Expression defaultValue = null;
                if (tokens.PopIfPresent("="))
                {
                    defaultValue     = this.parser.ExpressionParser.Parse(tokens, owner);
                    optionalArgFound = true;
                }
                else if (optionalArgFound)
                {
                    throw new ParserException(argName, "All optional arguments must come at the end of the argument list.");
                }

                argNames.Add(argName);
                argValues.Add(defaultValue);
            }

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

            IList <Executable> code = Parser.ParseBlock(parser, tokens, true, owner);

            return(new ConstructorDefinition(constructorToken, argNames, argValues, baseArgs, code, baseToken, owner));
        }
Example #8
0
        private static Expression ParseIncrement(TokenStream tokens, Executable owner)
        {
            Expression root;

            if (tokens.IsNext("++") || tokens.IsNext("--"))
            {
                Token incrementToken = tokens.Pop();
                root = ParseEntity(tokens, owner);
                return(new Increment(incrementToken, incrementToken, incrementToken.Value == "++", true, root, owner));
            }

            root = ParseEntity(tokens, owner);
            if (tokens.IsNext("++") || tokens.IsNext("--"))
            {
                Token incrementToken = tokens.Pop();
                return(new Increment(root.FirstToken, incrementToken, incrementToken.Value == "++", false, root, owner));
            }

            return(root);
        }
Example #9
0
        private Expression ParseIncrement(TokenStream tokens, TopLevelConstruct owner)
        {
            Expression root;

            if (tokens.IsNext("++") || tokens.IsNext("--"))
            {
                Token incrementToken = tokens.Pop();
                root = this.ParseEntity(tokens, owner);
                return(new Increment(incrementToken, incrementToken, incrementToken.Value == "++", true, root, owner));
            }

            root = this.ParseEntity(tokens, owner);
            if (tokens.IsNext("++") || tokens.IsNext("--"))
            {
                Token incrementToken = tokens.Pop();
                return(new Increment(root.FirstToken, incrementToken, incrementToken.Value == "++", false, root, owner));
            }

            return(root);
        }
Example #10
0
		private static Expression ParseBitwiseOp(TokenStream tokens, Executable owner)
		{
			Expression expr = ParseEqualityComparison(tokens, owner);
			string next = tokens.PeekValue();
			if (next == "|" || next == "&" || next == "^")
			{
				Token bitwiseToken = tokens.Pop();
				Expression rightExpr = ParseBitwiseOp(tokens, owner);
				return new BinaryOpChain(expr, bitwiseToken, rightExpr, owner);
			}
			return expr;
		}
Example #11
0
        private static Executable ParseConst(Parser parser, TokenStream tokens, Executable owner)
        {
            Token constToken = tokens.PopExpected("const");
            Token nameToken  = tokens.Pop();

            Parser.VerifyIdentifier(nameToken);
            tokens.PopExpected("=");
            Expression expression = ExpressionParser.Parse(tokens, owner);

            tokens.PopExpected(";");

            return(new ConstStatement(constToken, nameToken, parser.CurrentNamespace, expression, owner));
        }
Example #12
0
        private Executable ParseConst(TokenStream tokens, Executable owner)
        {
            Token          constToken     = tokens.PopExpected(this.parser.Keywords.CONST);
            Token          nameToken      = tokens.Pop();
            ConstStatement constStatement = new ConstStatement(constToken, nameToken, parser.CurrentNamespace, owner);

            this.parser.VerifyIdentifier(nameToken);
            tokens.PopExpected("=");
            constStatement.Expression = this.parser.ExpressionParser.Parse(tokens, constStatement);
            tokens.PopExpected(";");

            return(constStatement);
        }
Example #13
0
        private ConstStatement ParseConst(TokenStream tokens, TopLevelConstruct owner, FileScope fileScope)
        {
            Token          constToken     = tokens.PopExpected(this.parser.Keywords.CONST);
            Token          nameToken      = tokens.Pop();
            ConstStatement constStatement = new ConstStatement(constToken, nameToken, parser.CurrentNamespace, owner, parser.CurrentLibrary, fileScope);

            this.parser.VerifyIdentifier(nameToken);
            tokens.PopExpected("=");
            constStatement.Expression = this.parser.ExpressionParser.Parse(tokens, constStatement);
            tokens.PopExpected(";");

            return(constStatement);
        }
Example #14
0
        private Expression ParseBitwiseOp(TokenStream tokens, Executable owner)
        {
            Expression expr = ParseEqualityComparison(tokens, owner);
            string     next = tokens.PeekValue();

            if (next == "|" || next == "&" || next == "^")
            {
                Token      bitwiseToken = tokens.Pop();
                Expression rightExpr    = ParseBitwiseOp(tokens, owner);
                return(new BinaryOpChain(expr, bitwiseToken, rightExpr, owner));
            }
            return(expr);
        }
Example #15
0
        private static Expression ParseBitShift(TokenStream tokens, Executable owner)
        {
            Expression expr = ParseAddition(tokens, owner);
            string     next = tokens.PeekValue();

            if (next == "<<" || next == ">>")
            {
                Token      opToken   = tokens.Pop();
                Expression rightExpr = ParseBitShift(tokens, owner);
                return(new BinaryOpChain(expr, opToken, rightExpr, owner));
            }
            return(expr);
        }
Example #16
0
        private static Expression ParseEqualityComparison(TokenStream tokens, Executable owner)
        {
            Expression expr = ParseInequalityComparison(tokens, owner);
            string     next = tokens.PeekValue();

            if (next == "==" || next == "!=")
            {
                Token      equalityToken = tokens.Pop();
                Expression rightExpr     = ParseEqualityComparison(tokens, owner);
                return(new BinaryOpChain(expr, equalityToken, rightExpr, owner));
            }
            return(expr);
        }
Example #17
0
        private static string PopClassName(TokenStream tokens, Token firstToken)
        {
            Parser.VerifyIdentifier(firstToken);
            string name = firstToken.Value;

            while (tokens.PopIfPresent("."))
            {
                Token nameNext = tokens.Pop();
                Parser.VerifyIdentifier(nameNext);
                name += "." + nameNext.Value;
            }
            return(name);
        }
Example #18
0
        private static Expression ParseExponents(TokenStream tokens, Executable owner)
        {
            Expression expr = ParseIncrement(tokens, owner);
            string     next = tokens.PeekValue();

            if (next == "**")
            {
                Token      op    = tokens.Pop();
                Expression right = ParseNegate(tokens, owner);
                expr = new BinaryOpChain(expr, op, right, owner);
            }
            return(expr);
        }
Example #19
0
        public string PopClassNameWithFirstTokenAlreadyPopped(TokenStream tokens, Token firstToken)
        {
            this.VerifyIdentifier(firstToken);
            string name = firstToken.Value;

            while (tokens.PopIfPresent("."))
            {
                Token nameNext = tokens.Pop();
                this.VerifyIdentifier(nameNext);
                name += "." + nameNext.Value;
            }
            return(name);
        }
Example #20
0
        private Expression ParseAddition(TokenStream tokens, TopLevelConstruct owner)
        {
            Expression expr = ParseMultiplication(tokens, owner);
            string     next = tokens.PeekValue();

            while (ADDITION_OPS.Contains(next))
            {
                Token      op    = tokens.Pop();
                Expression right = ParseMultiplication(tokens, owner);
                expr = new BinaryOpChain(expr, op, right, owner);
                next = tokens.PeekValue();
            }
            return(expr);
        }
Example #21
0
        private static Expression ParseMultiplication(TokenStream tokens, Executable owner)
        {
            Expression expr = ParseNegate(tokens, owner);
            string     next = tokens.PeekValue();

            while (MULTIPLICATION_OPS.Contains(next))
            {
                Token      op    = tokens.Pop();
                Expression right = ParseNegate(tokens, owner);
                expr = new BinaryOpChain(expr, op, right, owner);
                next = tokens.PeekValue();
            }
            return(expr);
        }
Example #22
0
        private static Expression ParseInequalityComparison(TokenStream tokens, Executable owner)
        {
            Expression expr = ParseBitShift(tokens, owner);
            string     next = tokens.PeekValue();

            if (next == "<" || next == ">" || next == "<=" || next == ">=")
            {
                // Don't allow chaining of inqeualities
                Token      opToken   = tokens.Pop();
                Expression rightExpr = ParseBitShift(tokens, owner);
                return(new BinaryOpChain(expr, opToken, rightExpr, owner));
            }
            return(expr);
        }
Example #23
0
        private EnumDefinition ParseEnumDefinition(TokenStream tokens, TopLevelConstruct owner, FileScope fileScope)
        {
            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, parser.CurrentNamespace, owner, parser.CurrentLibrary, fileScope);

            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);
        }
Example #24
0
        private static Executable ParseTry(Parser parser, TokenStream tokens, Executable owner)
        {
            Token tryToken = tokens.PopExpected("try");
            IList <Executable> tryBlock     = Parser.ParseBlock(parser, tokens, true, owner);
            Token catchToken                = null;
            IList <Executable> catchBlock   = null;
            Token exceptionToken            = null;
            Token finallyToken              = null;
            IList <Executable> finallyBlock = null;

            if (tokens.IsNext("catch"))
            {
                catchToken = tokens.Pop();
                if (tokens.PopIfPresent("("))
                {
                    exceptionToken = tokens.Pop();
                    char firstChar = exceptionToken.Value[0];
                    if (firstChar != '_' &&
                        !(firstChar >= 'a' && firstChar <= 'z') &&
                        !(firstChar >= 'A' && firstChar <= 'Z'))
                    {
                        throw new ParserException(exceptionToken, "Invalid name for variable.");
                    }
                    tokens.PopExpected(")");
                }

                catchBlock = Parser.ParseBlock(parser, tokens, true, owner);
            }

            if (tokens.IsNext("finally"))
            {
                finallyToken = tokens.Pop();
                finallyBlock = Parser.ParseBlock(parser, tokens, true, owner);
            }

            return(new TryStatement(tryToken, tryBlock, catchToken, exceptionToken, catchBlock, finallyToken, finallyBlock, owner));
        }
Example #25
0
        private static FieldDeclaration ParseField(TokenStream tokens, ClassDefinition owner)
        {
            bool  isStatic   = tokens.PopIfPresent("static");
            Token fieldToken = tokens.PopExpected("field");
            Token nameToken  = tokens.Pop();

            Parser.VerifyIdentifier(nameToken);
            FieldDeclaration fd = new FieldDeclaration(fieldToken, nameToken, owner, isStatic);

            if (tokens.PopIfPresent("="))
            {
                fd.DefaultValue = ExpressionParser.Parse(tokens, owner);
            }
            tokens.PopExpected(";");
            return(fd);
        }
Example #26
0
        private FieldDeclaration ParseField(TokenStream tokens, ClassDefinition owner)
        {
            bool  isStatic   = tokens.PopIfPresent(this.parser.Keywords.STATIC);
            Token fieldToken = tokens.PopExpected(this.parser.Keywords.FIELD);
            Token nameToken  = tokens.Pop();

            this.parser.VerifyIdentifier(nameToken);
            FieldDeclaration fd = new FieldDeclaration(fieldToken, nameToken, owner, isStatic);

            if (tokens.PopIfPresent("="))
            {
                fd.DefaultValue = this.parser.ExpressionParser.Parse(tokens, owner);
            }
            tokens.PopExpected(";");
            return(fd);
        }
Example #27
0
		private static Expression ParseBooleanCombination(TokenStream tokens, Executable owner)
		{
			Expression expr = ParseBitwiseOp(tokens, owner);
			string next = tokens.PeekValue();
			if (next == "||" || next == "&&")
			{
				List<Expression> expressions = new List<Expression>() { expr };
				List<Token> ops = new List<Token>();
				while (next == "||" || next == "&&")
				{
					ops.Add(tokens.Pop());
					expressions.Add(ParseBitwiseOp(tokens, owner));
					next = tokens.PeekValue();
				}
				return new BooleanCombination(expressions, ops, owner);
			}
			return expr;
		}
Example #28
0
        private void Initialize(Token annotationToken, TokenStream proxyTokenStream)
        {
            this.Token = annotationToken;

            Token token = proxyTokenStream.Pop();

            if (!Parser.IsValidIdentifier(token.Value))
            {
                throw new ParserException(annotationToken, "Invalid type");
            }

            this.Name = token.Value;

            while (proxyTokenStream.PopIfPresent("."))
            {
                this.Name += ".";
                this.Name += proxyTokenStream.PopValue();
            }

            List <AnnotatedType> generics = new List <AnnotatedType>();

            if (proxyTokenStream.PopIfPresent("<"))
            {
                while (proxyTokenStream.HasMore && !proxyTokenStream.IsNext(">"))
                {
                    if (generics.Count > 0 && !proxyTokenStream.PopIfPresent(","))
                    {
                        throw new ParserException(annotationToken, "Expected comma in generic list");
                    }

                    AnnotatedType genericItem = new AnnotatedType(annotationToken, proxyTokenStream);
                    generics.Add(genericItem);
                }

                if (!proxyTokenStream.PopIfPresent(">"))
                {
                    throw new ParserException(annotationToken, "Unclosed generic bracket.");
                }
            }

            this.Generics = generics.ToArray();
        }
Example #29
0
        private Expression ParseInstantiate(TokenStream tokens, Executable owner)
        {
            Token  newToken       = tokens.PopExpected(this.parser.Keywords.NEW);
            Token  classNameToken = tokens.Pop();
            string name           = this.parser.PopClassNameWithFirstTokenAlreadyPopped(tokens, classNameToken);

            List <Expression> args = new List <Expression>();

            tokens.PopExpected("(");
            while (!tokens.PopIfPresent(")"))
            {
                if (args.Count > 0)
                {
                    tokens.PopExpected(",");
                }
                args.Add(Parse(tokens, owner));
            }

            return(new Instantiate(newToken, classNameToken, name, args, owner));
        }
Example #30
0
        private static Expression ParseInstantiate(TokenStream tokens, Executable owner)
        {
            Token  newToken       = tokens.PopExpected("new");
            Token  classNameToken = tokens.Pop();
            string name           = PopClassName(tokens, classNameToken);

            List <Expression> args = new List <Expression>();

            tokens.PopExpected("(");
            while (!tokens.PopIfPresent(")"))
            {
                if (args.Count > 0)
                {
                    tokens.PopExpected(",");
                }
                args.Add(Parse(tokens, owner));
            }

            return(new Instantiate(newToken, classNameToken, name, args, owner));
        }
Example #31
0
		public static Annotation ParseAnnotation(TokenStream tokens)
		{
			Token annotationToken = tokens.PopExpected("@");
			Token typeToken = tokens.Pop();
			Parser.VerifyIdentifier(typeToken);
			List<Expression> args = new List<Expression>();
			if (tokens.PopIfPresent("("))
			{
				while (!tokens.PopIfPresent(")"))
				{
					if (args.Count > 0)
					{
						tokens.PopExpected(",");
					}

					args.Add(ExpressionParser.Parse(tokens, null));
				}
			}
			return new Annotation(annotationToken, typeToken, args);
		}
Example #32
0
        private static Expression ParseNegate(TokenStream tokens, Executable owner)
        {
            string next = tokens.PeekValue();

            if (NEGATE_OPS.Contains(next))
            {
                Token      negateOp = tokens.Pop();
                Expression root     = ParseNegate(tokens, owner);
                if (negateOp.Value == "!")
                {
                    return(new BooleanNot(negateOp, root, owner));
                }
                if (negateOp.Value == "-")
                {
                    return(new NegativeSign(negateOp, root, owner));
                }
                throw new Exception("This shouldn't happen.");
            }

            return(ParseExponents(tokens, owner));
        }
Example #33
0
        public static Annotation ParseAnnotation(TokenStream tokens)
        {
            Token annotationToken = tokens.PopExpected("@");
            Token typeToken       = tokens.Pop();

            Parser.VerifyIdentifier(typeToken);
            List <Expression> args = new List <Expression>();

            if (tokens.PopIfPresent("("))
            {
                while (!tokens.PopIfPresent(")"))
                {
                    if (args.Count > 0)
                    {
                        tokens.PopExpected(",");
                    }

                    args.Add(ExpressionParser.Parse(tokens, null));
                }
            }
            return(new Annotation(annotationToken, typeToken, args));
        }
Example #34
0
		private void Initialize(Token annotationToken, TokenStream proxyTokenStream)
		{
			this.Token = annotationToken;

			Token token = proxyTokenStream.Pop();
			if (!Parser.IsValidIdentifier(token.Value)) throw new ParserException(annotationToken, "Invalid type");

			this.Name = token.Value;

			while (proxyTokenStream.PopIfPresent("."))
			{
				this.Name += ".";
				this.Name += proxyTokenStream.PopValue();
			}

			List<AnnotatedType> generics = new List<AnnotatedType>();
			if (proxyTokenStream.PopIfPresent("<"))
			{
				while (proxyTokenStream.HasMore && !proxyTokenStream.IsNext(">"))
				{
					if (generics.Count > 0 && !proxyTokenStream.PopIfPresent(","))
					{
						throw new ParserException(annotationToken, "Expected comma in generic list");
					}

					AnnotatedType genericItem = new AnnotatedType(annotationToken, proxyTokenStream);
					generics.Add(genericItem);
				}

				if (!proxyTokenStream.PopIfPresent(">"))
				{
					throw new ParserException(annotationToken, "Unclosed generic bracket.");
				}
			}

			this.Generics = generics.ToArray();
		}
Example #35
0
		public static Executable Parse(Parser parser, TokenStream tokens, bool simpleOnly, bool semicolonPresent, bool isRoot, Executable owner)
		{
			string value = tokens.PeekValue();

			if (!simpleOnly)
			{
				if (parser.IsTranslateMode && value == "struct")
				{
					if (!isRoot)
					{
						throw new ParserException(tokens.Peek(), "structs cannot be nested into any other construct.");
					}

					// struct is special. If you are not compiling in JS mode, 
					if (Parser.IsValidIdentifier(tokens.PeekValue(1)) && tokens.PeekValue(2) == "{")
					{
						return ParseStruct(tokens, owner);
					}
				}

				if (!isRoot && (value == "function" || value == "class"))
				{
					throw new ParserException(tokens.Peek(), (value == "function" ? "Function" : "Class") + " definition cannot be nested in another construct.");
				}

				if (value == "import")
				{
					Token importToken = tokens.PopExpected("import");

					bool inline = parser.IsTranslateMode && tokens.PopIfPresent("inline");

					if (inline)
					{
						Token fileToken = tokens.Pop();
						char c = fileToken.Value[0];
						if (c != '\'' && c != '"') throw new ParserException(fileToken, "Inline imports are supposed to be strings.");
						tokens.PopExpected(";");
						string inlineImportFileName = fileToken.Value.Substring(1, fileToken.Value.Length - 2);
						string inlineImportFileContents = Util.ReadFileInternally(inlineImportFileName);
						// TODO: Anti-pattern alert. Clean this up.
						if (inlineImportFileContents.Contains("%%%"))
						{
							Dictionary<string, string> replacements = parser.NullablePlatform.InterpreterCompiler.BuildReplacementsDictionary();
							inlineImportFileContents = Constants.DoReplacements(inlineImportFileContents, replacements);
						}
						TokenStream inlineTokens = Tokenizer.Tokenize(inlineImportFileName, inlineImportFileContents, 0, true);

						// OMGHAX - insert the inline import into the current token stream.
						tokens.InsertTokens(inlineTokens);

						return ExecutableParser.Parse(parser, tokens, simpleOnly, semicolonPresent, isRoot, owner); // start exectuable parser anew.
					}

					if (!isRoot)
					{
						throw new ParserException(tokens.Peek(), "Imports can only be made from the root of a file and cannot be nested inside other constructs.");
					}

					List<string> importPathBuilder = new List<string>();
					while (!tokens.PopIfPresent(";"))
					{
						if (importPathBuilder.Count > 0)
						{
							tokens.PopExpected(".");
						}

						Token pathToken = tokens.Pop();
						Parser.VerifyIdentifier(pathToken);
						importPathBuilder.Add(pathToken.Value);
					}
					string importPath = string.Join(".", importPathBuilder);

					return new ImportStatement(importToken, importPath);
				}

				if (value == "enum")
				{
					if (!isRoot)
					{
						throw new ParserException(tokens.Peek(), "Enums can only be defined from the root of a file and cannot be nested inside functions/loops/etc.");
					}

					return ParseEnumDefinition(parser, tokens, owner);
				}

				if (value == "namespace")
				{
					if (!isRoot)
					{
						throw new ParserException(tokens.Peek(), "Namespace declarations cannot be nested in other constructs.");
					}
				}

				switch (value)
				{
					case "namespace": return ParseNamespace(parser, tokens, owner);
					case "function": return ParseFunction(parser, tokens, owner);
					case "class": return ParseClassDefinition(parser, tokens, owner);
					case "enum": return ParseEnumDefinition(parser, tokens, owner);
					case "for": return ParseFor(parser, tokens, owner);
					case "while": return ParseWhile(parser, tokens, owner);
					case "do": return ParseDoWhile(parser, tokens, owner);
					case "switch": return ParseSwitch(parser, tokens, owner);
					case "if": return ParseIf(parser, tokens, owner);
					case "try": return ParseTry(parser, tokens, owner);
					case "return": return ParseReturn(tokens, owner);
					case "break": return ParseBreak(tokens, owner);
					case "continue": return ParseContinue(tokens, owner);
					case "const": return ParseConst(parser, tokens, owner);
					case "constructor": return ParseConstructor(parser, tokens, owner);
					default: break;
				}
			}

			Expression expr = ExpressionParser.Parse(tokens, owner);
			value = tokens.PeekValue();
			if (ASSIGNMENT_OPS.Contains(value))
			{
				Token assignment = tokens.Pop();
				Expression assignmentValue = ExpressionParser.Parse(tokens, owner);
				if (semicolonPresent) tokens.PopExpected(";");
				return new Assignment(expr, assignment, assignment.Value, assignmentValue, owner);
			}

			if (semicolonPresent)
			{
				tokens.PopExpected(";");
			}

			return new ExpressionAsExecutable(expr, owner);
		}
Example #36
0
		private static Expression ParseExponents(TokenStream tokens, Executable owner)
		{
			Expression expr = ParseIncrement(tokens, owner);
			string next = tokens.PeekValue();
			if (next == "**")
			{
				Token op = tokens.Pop();
				Expression right = ParseNegate(tokens, owner);
				expr = new BinaryOpChain(expr, op, right, owner);
			}
			return expr;
		}
Example #37
0
		private static Expression ParseNegate(TokenStream tokens, Executable owner)
		{
			string next = tokens.PeekValue();
			if (NEGATE_OPS.Contains(next))
			{
				Token negateOp = tokens.Pop();
				Expression root = ParseNegate(tokens, owner);
				// TODO: just make a negation parse tree node
				if (negateOp.Value == "!") return new BooleanNot(negateOp, root, owner);
				if (negateOp.Value == "-") return new NegativeSign(negateOp, root, owner);
				throw new Exception("This shouldn't happen.");
			}

			return ParseExponents(tokens, owner);
		}
Example #38
0
		private static Expression ParseIncrement(TokenStream tokens, Executable owner)
		{
			Expression root;
			if (tokens.IsNext("++") || tokens.IsNext("--"))
			{
				Token incrementToken = tokens.Pop();
				root = ParseEntity(tokens, owner);
				return new Increment(incrementToken, incrementToken, incrementToken.Value == "++", true, root, owner);
			}

			root = ParseEntity(tokens, owner);
			if (tokens.IsNext("++") || tokens.IsNext("--"))
			{
				Token incrementToken = tokens.Pop();
				return new Increment(root.FirstToken, incrementToken, incrementToken.Value == "++", false, root, owner);
			}

			return root;
		}
Example #39
0
		private static FieldDeclaration ParseField(TokenStream tokens, ClassDefinition owner)
		{
			bool isStatic = tokens.PopIfPresent("static");
			Token fieldToken = tokens.PopExpected("field");
			Token nameToken = tokens.Pop();
			Parser.VerifyIdentifier(nameToken);
			FieldDeclaration fd = new FieldDeclaration(fieldToken, nameToken, owner, isStatic);
			if (tokens.PopIfPresent("="))
			{
				fd.DefaultValue = ExpressionParser.Parse(tokens, owner);
			}
			tokens.PopExpected(";");
			return fd;
		}
Example #40
0
		private static Expression ParseInstantiate(TokenStream tokens, Executable owner)
		{
			Token newToken = tokens.PopExpected("new");
			Token classNameToken = tokens.Pop();
			Parser.VerifyIdentifier(classNameToken);
			string name = classNameToken.Value;
			while (tokens.PopIfPresent("."))
			{
				Token nameNext = tokens.Pop();
				Parser.VerifyIdentifier(nameNext);
				name += "." + nameNext.Value;
			}

			List<Expression> args = new List<Expression>();
			tokens.PopExpected("(");
			while (!tokens.PopIfPresent(")"))
			{
				if (args.Count > 0)
				{
					tokens.PopExpected(",");
				}
				args.Add(Parse(tokens, owner));
			}

			return new Instantiate(newToken, classNameToken, name, args, owner);
		}
Example #41
0
		private static Executable ParseStruct(TokenStream tokens, Executable owner)
		{
			Token structToken = tokens.PopExpected("struct");
			Token structNameToken = tokens.Pop();
			Parser.VerifyIdentifier(structNameToken);

			tokens.PopExpected("{");

			List<Token> fieldTokens = new List<Token>();
			List<Annotation> typeAnnotations = new List<Annotation>();
			bool nextForbidden = false;
			while (!tokens.PopIfPresent("}"))
			{
				if (nextForbidden) tokens.PopExpected("}"); // crash

				Annotation annotation = tokens.IsNext("@") ? AnnotationParser.ParseAnnotation(tokens) : null;

				Token fieldToken = tokens.Pop();
				Parser.VerifyIdentifier(fieldToken);
				nextForbidden = !tokens.PopIfPresent(",");
				fieldTokens.Add(fieldToken);
				typeAnnotations.Add(annotation);
			}

			return new StructDefinition(structToken, structNameToken, fieldTokens, typeAnnotations, owner);
		}
Example #42
0
		private static Expression ParseEntityWithoutSuffixChain(TokenStream tokens, Executable owner)
		{
			string next = tokens.PeekValue();

			if (next == "null") return new NullConstant(tokens.Pop(), owner);
			if (next == "true") return new BooleanConstant(tokens.Pop(), true, owner);
			if (next == "false") return new BooleanConstant(tokens.Pop(), false, owner);

			Token peekToken = tokens.Peek();
			if (next.StartsWith("'")) return new StringConstant(tokens.Pop(), StringConstant.ParseOutRawValue(peekToken), owner);
			if (next.StartsWith("\"")) return new StringConstant(tokens.Pop(), StringConstant.ParseOutRawValue(peekToken), owner);
			if (next == "new") return ParseInstantiate(tokens, owner);

			char firstChar = next[0];
			if (VARIABLE_STARTER.Contains(firstChar))
			{
				Token varToken = tokens.Pop();
				return new Variable(varToken, varToken.Value, owner);
			}

			if (firstChar == '[')
			{
				Token bracketToken = tokens.PopExpected("[");
				List<Expression> elements = new List<Expression>();
				bool previousHasCommaOrFirst = true;
				while (!tokens.PopIfPresent("]"))
				{
					if (!previousHasCommaOrFirst) tokens.PopExpected("]"); // throws appropriate error
					elements.Add(Parse(tokens, owner));
					previousHasCommaOrFirst = tokens.PopIfPresent(",");
				}
				return new ListDefinition(bracketToken, elements, owner);
			}

			if (firstChar == '{')
			{
				Token braceToken = tokens.PopExpected("{");
				List<Expression> keys = new List<Expression>();
				List<Expression> values = new List<Expression>();
				bool previousHasCommaOrFirst = true;
				while (!tokens.PopIfPresent("}"))
				{
					if (!previousHasCommaOrFirst) tokens.PopExpected("}"); // throws appropriate error
					keys.Add(Parse(tokens, owner));
					tokens.PopExpected(":");
					values.Add(Parse(tokens, owner));
					previousHasCommaOrFirst = tokens.PopIfPresent(",");
				}
				return new DictionaryDefinition(braceToken, keys, values, owner);
			}

			if (next.Length > 2 && next.Substring(0, 2) == "0x")
			{
				Token intToken = tokens.Pop();
				int intValue = IntegerConstant.ParseIntConstant(intToken, intToken.Value);
				return new IntegerConstant(intToken, intValue, owner);
			}

			if (Parser.IsInteger(next))
			{
				Token numberToken = tokens.Pop();
				string numberValue = numberToken.Value;

				if (tokens.IsNext("."))
				{
					Token decimalToken = tokens.Pop();
					if (decimalToken.HasWhitespacePrefix)
					{
						throw new ParserException(decimalToken, "Decimals cannot have whitespace before them.");
					}

					Token afterDecimal = tokens.Pop();
					if (afterDecimal.HasWhitespacePrefix) throw new ParserException(afterDecimal, "Cannot have whitespace after the decimal.");
					if (!Parser.IsInteger(afterDecimal.Value)) throw new ParserException(afterDecimal, "Decimal must be followed by an integer.");

					numberValue += "." + afterDecimal.Value;

					double floatValue = FloatConstant.ParseValue(numberToken, numberValue);
					return new FloatConstant(numberToken, floatValue, owner);
				}

				int intValue = IntegerConstant.ParseIntConstant(numberToken, numberToken.Value);
				return new IntegerConstant(numberToken, intValue, owner);
			}

			if (tokens.IsNext("."))
			{
				Token dotToken = tokens.PopExpected(".");
				string numberValue = "0.";
				Token postDecimal = tokens.Pop();
				if (postDecimal.HasWhitespacePrefix || !Parser.IsInteger(postDecimal.Value))
				{
					throw new ParserException(dotToken, "Unexpected dot.");
				}

				numberValue += postDecimal.Value;

				double floatValue;
				if (double.TryParse(numberValue, out floatValue))
				{
					return new FloatConstant(dotToken, floatValue, owner);
				}

				throw new ParserException(dotToken, "Invalid float literal.");
			}

			throw new ParserException(tokens.Peek(), "Encountered unexpected token: '" + tokens.PeekValue() + "'");
		}
Example #43
0
		private static Expression ParseEntity(TokenStream tokens, Executable owner)
		{
			Expression root;
			if (tokens.PopIfPresent("("))
			{
				root = Parse(tokens, owner);
				tokens.PopExpected(")");
			}
			else
			{
				root = ParseEntityWithoutSuffixChain(tokens, owner);
			}
			bool anySuffixes = true;
			while (anySuffixes)
			{
				if (tokens.IsNext("."))
				{
					Token dotToken = tokens.Pop();
					Token stepToken = tokens.Pop();
					Parser.VerifyIdentifier(stepToken);
					root = new DotStep(root, dotToken, stepToken, owner);
				}
				else if (tokens.IsNext("["))
				{
					Token openBracket = tokens.Pop();
					List<Expression> sliceComponents = new List<Expression>();
					if (tokens.IsNext(":"))
					{
						sliceComponents.Add(null);
					}
					else
					{
						sliceComponents.Add(Parse(tokens, owner));
					}

					for (int i = 0; i < 2; ++i)
					{
						if (tokens.PopIfPresent(":"))
						{
							if (tokens.IsNext(":") || tokens.IsNext("]"))
							{
								sliceComponents.Add(null);
							}
							else
							{
								sliceComponents.Add(Parse(tokens, owner));
							}
						}
					}

					tokens.PopExpected("]");

					if (sliceComponents.Count == 1)
					{
						Expression index = sliceComponents[0];
						root = new BracketIndex(root, openBracket, index, owner);
					}
					else
					{
						root = new ListSlice(root, sliceComponents, openBracket, owner);
					}
				}
				else if (tokens.IsNext("("))
				{
					Token openParen = tokens.Pop();
					List<Expression> args = new List<Expression>();
					while (!tokens.PopIfPresent(")"))
					{
						if (args.Count > 0)
						{
							tokens.PopExpected(",");
						}

						args.Add(Parse(tokens, owner));
					}
					root = new FunctionCall(root, openParen, args, owner);
				}
				else
				{
					anySuffixes = false;
				}
			}
			return root;
		}
Example #44
0
		private static Executable ParseEnumDefinition(Parser parser, TokenStream tokens, Executable owner)
		{
			Token enumToken = tokens.PopExpected("enum");
			Token nameToken = tokens.Pop();
			Parser.VerifyIdentifier(nameToken);
			string name = nameToken.Value;
			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();
				Parser.VerifyIdentifier(enumItem);
				if (tokens.PopIfPresent("="))
				{
					values.Add(ExpressionParser.Parse(tokens, owner));
				}
				else
				{
					values.Add(null);
				}
				nextForbidden = !tokens.PopIfPresent(",");
				items.Add(enumItem);
			}

			return new EnumDefinition(enumToken, nameToken, parser.CurrentNamespace, items, values, owner);
		}
Example #45
0
		private static Executable ParseNamespace(Parser parser, TokenStream tokens, Executable owner)
		{
			Token namespaceToken = tokens.PopExpected("namespace");
			Token first = tokens.Pop();
			Parser.VerifyIdentifier(first);
			List<Token> namespacePieces = new List<Token>() { first };
			while (tokens.PopIfPresent("."))
			{
				Token nsToken = tokens.Pop();
				Parser.VerifyIdentifier(nsToken);
				namespacePieces.Add(nsToken);
			}

			string name = string.Join(".", namespacePieces.Select<Token, string>(t => t.Value));
			parser.PushNamespacePrefix(name);

			Namespace namespaceInstance = new Namespace(namespaceToken, name, owner);

			tokens.PopExpected("{");
			List<Executable> namespaceMembers = new List<Executable>();
			while (!tokens.PopIfPresent("}"))
			{
				Executable executable = ExecutableParser.Parse(parser, tokens, false, false, true, namespaceInstance);
				if (executable is FunctionDefinition ||
					executable is ClassDefinition ||
					executable is Namespace)
				{
					namespaceMembers.Add(executable);
				}
				else
				{
					throw new ParserException(executable.FirstToken, "Only function, class, and nested namespace declarations may exist as direct members of a namespace.");
				}
			}

			namespaceInstance.Code = namespaceMembers.ToArray();

			parser.PopNamespacePrefix();

			return namespaceInstance;
		}
Example #46
0
		private static Expression ParseBitShift(TokenStream tokens, Executable owner)
		{
			Expression expr = ParseAddition(tokens, owner);
			string next = tokens.PeekValue();
			if (next == "<<" || next == ">>")
			{
				Token opToken = tokens.Pop();
				Expression rightExpr = ParseBitShift(tokens, owner);
				return new BinaryOpChain(expr, opToken, rightExpr, owner);
			}
			return expr;
		}
Example #47
0
		private static Executable ParseFunction(Parser parser, TokenStream tokens, Executable nullableOwner)
		{
			bool isStatic = 
				nullableOwner != null && 
				nullableOwner is ClassDefinition && 
				tokens.PopIfPresent("static");

			Token functionToken = tokens.PopExpected("function");

			List<Annotation> functionAnnotations = new List<Annotation>();

			while (tokens.IsNext("@"))
			{
				functionAnnotations.Add(AnnotationParser.ParseAnnotation(tokens));
			}

			Token functionNameToken = tokens.Pop();
			Parser.VerifyIdentifier(functionNameToken);

			FunctionDefinition fd = new FunctionDefinition(functionToken, nullableOwner, isStatic, functionNameToken, functionAnnotations, parser.CurrentNamespace);

			tokens.PopExpected("(");
			List<Token> argNames = new List<Token>();
			List<Expression> defaultValues = new List<Expression>();
			List<Annotation> argAnnotations = new List<Annotation>();
			bool optionalArgFound = false;
			while (!tokens.PopIfPresent(")"))
			{
				if (argNames.Count > 0) tokens.PopExpected(",");

				Annotation annotation = tokens.IsNext("@") ? AnnotationParser.ParseAnnotation(tokens) : null;
				Token argName = tokens.Pop();
				Expression defaultValue = null;
				Parser.VerifyIdentifier(argName);
				if (tokens.PopIfPresent("="))
				{
					optionalArgFound = true;
					defaultValue = ExpressionParser.Parse(tokens, fd);
				}
				else if (optionalArgFound)
				{
					throw new ParserException(argName, "All optional arguments must come at the end of the argument list.");
				}
				argAnnotations.Add(annotation);
				argNames.Add(argName);
				defaultValues.Add(defaultValue);
			}

			IList<Executable> code = Parser.ParseBlock(parser, tokens, true, fd);

			fd.ArgNames = argNames.ToArray();
			fd.DefaultValues = defaultValues.ToArray();
			fd.ArgAnnotations = argAnnotations.ToArray();
			fd.Code = code.ToArray();

			return fd;
		}
Example #48
0
		private static Expression ParseInequalityComparison(TokenStream tokens, Executable owner)
		{
			Expression expr = ParseBitShift(tokens, owner);
			string next = tokens.PeekValue();
			if (next == "<" || next == ">" || next == "<=" || next == ">=")
			{
				// Don't allow chaining of inqeualities
				Token opToken = tokens.Pop();
				Expression rightExpr = ParseBitShift(tokens, owner);
				return new BinaryOpChain(expr, opToken, rightExpr, owner);
			}
			return expr;
		}
Example #49
0
		private static Executable ParseFor(Parser parser, TokenStream tokens, Executable owner)
		{
			Token forToken = tokens.PopExpected("for");
			tokens.PopExpected("(");

			if (Parser.IsValidIdentifier(tokens.PeekValue()) && tokens.PeekValue(1) == ":")
			{
				Token iteratorToken = tokens.Pop();
				if (Parser.IsReservedKeyword(iteratorToken.Value))
				{
					throw new ParserException(iteratorToken, "Cannot use this name for an iterator.");
				}
				tokens.PopExpected(":");
				Expression iterationExpression = ExpressionParser.Parse(tokens, owner);
				tokens.PopExpected(")");
				IList<Executable> body = Parser.ParseBlock(parser, tokens, false, owner);

				return new ForEachLoop(forToken, iteratorToken, iterationExpression, body, owner);
			}
			else
			{
				List<Executable> init = new List<Executable>();
				while (!tokens.PopIfPresent(";"))
				{
					if (init.Count > 0) tokens.PopExpected(",");
					init.Add(Parse(parser, tokens, true, false, false, owner));
				}
				Expression condition = null;
				if (!tokens.PopIfPresent(";"))
				{
					condition = ExpressionParser.Parse(tokens, owner);
					tokens.PopExpected(";");
				}
				List<Executable> step = new List<Executable>();
				while (!tokens.PopIfPresent(")"))
				{
					if (step.Count > 0) tokens.PopExpected(",");
					step.Add(Parse(parser, tokens, true, false, false, owner));
				}

				IList<Executable> body = Parser.ParseBlock(parser, tokens, false, owner);

				return new ForLoop(forToken, init, condition, step, body, owner);
			}
		}
Example #50
0
		private static Executable ParseSwitch(Parser parser, TokenStream tokens, Executable owner)
		{
			Token switchToken = tokens.PopExpected("switch");

			Expression explicitMax = null;
			Token explicitMaxToken = null;
			if (tokens.IsNext("{"))
			{
				explicitMaxToken = tokens.Pop();
				explicitMax = ExpressionParser.Parse(tokens, owner);
				tokens.PopExpected("}");
			}

			tokens.PopExpected("(");
			Expression condition = ExpressionParser.Parse(tokens, owner);
			tokens.PopExpected(")");
			tokens.PopExpected("{");
			List<List<Expression>> cases = new List<List<Expression>>();
			List<Token> firstTokens = new List<Token>();
			List<List<Executable>> code = new List<List<Executable>>();
			char state = '?'; // ? - first, O - code, A - case
			bool defaultEncountered = false;
			while (!tokens.PopIfPresent("}"))
			{
				if (tokens.IsNext("case"))
				{
					if (defaultEncountered)
					{
						throw new ParserException(tokens.Peek(), "default condition in a switch statement must be the last condition.");
					}

					Token caseToken = tokens.PopExpected("case");
					if (state != 'A')
					{
						cases.Add(new List<Expression>());
						firstTokens.Add(caseToken);
						code.Add(null);
						state = 'A';
					}
					cases[cases.Count - 1].Add(ExpressionParser.Parse(tokens, owner));
					tokens.PopExpected(":");
				}
				else if (tokens.IsNext("default"))
				{
					Token defaultToken = tokens.PopExpected("default");
					if (state != 'A')
					{
						cases.Add(new List<Expression>());
						firstTokens.Add(defaultToken);
						code.Add(null);
						state = 'A';
					}
					cases[cases.Count - 1].Add(null);
					tokens.PopExpected(":");
					defaultEncountered = true;
				}
				else
				{
					if (state != 'O')
					{
						cases.Add(null);
						firstTokens.Add(null);
						code.Add(new List<Executable>());
						state = 'O';
					}
					code[code.Count - 1].Add(ExecutableParser.Parse(parser, tokens, false, true, false, owner));
				}
			}

			return new SwitchStatement(switchToken, condition, firstTokens, cases, code, explicitMax, explicitMaxToken, owner);
		}
Example #51
0
		private static Expression ParseMultiplication(TokenStream tokens, Executable owner)
		{
			Expression expr = ParseNegate(tokens, owner);
			string next = tokens.PeekValue();
			while (MULTIPLICATION_OPS.Contains(next))
			{
				Token op = tokens.Pop();
				Expression right = ParseNegate(tokens, owner);
				expr = new BinaryOpChain(expr, op, right, owner);
				next = tokens.PeekValue();
			}
			return expr;
		}
Example #52
0
		private static Executable ParseConstructor(Parser parser, TokenStream tokens, Executable owner)
		{
			Token constructorToken = tokens.PopExpected("constructor");
			tokens.PopExpected("(");
			List<Token> argNames = new List<Token>();
			List<Expression> argValues = new List<Expression>();
			bool optionalArgFound = false;
			while (!tokens.PopIfPresent(")"))
			{
				if (argNames.Count > 0)
				{
					tokens.PopExpected(",");
				}

				Token argName = tokens.Pop();
				Parser.VerifyIdentifier(argName);
				Expression defaultValue = null;
				if (tokens.PopIfPresent("="))
				{
					defaultValue = ExpressionParser.Parse(tokens, owner);
					optionalArgFound = true;
				}
				else if (optionalArgFound)
				{
					throw new ParserException(argName, "All optional arguments must come at the end of the argument list.");
				}

				argNames.Add(argName);
				argValues.Add(defaultValue);
			}

			List<Expression> baseArgs = new List<Expression>();
			Token baseToken = null;
			if (tokens.PopIfPresent(":"))
			{
				baseToken = tokens.PopExpected("base");
				tokens.PopExpected("(");
				while (!tokens.PopIfPresent(")"))
				{
					if (baseArgs.Count > 0)
					{
						tokens.PopExpected(",");
					}

					baseArgs.Add(ExpressionParser.Parse(tokens, owner));
				}
			}

			IList<Executable> code = Parser.ParseBlock(parser, tokens, true, owner);

			return new ConstructorDefinition(constructorToken, argNames, argValues, baseArgs, code, baseToken, owner);
		}
Example #53
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;
		}
Example #54
0
		private static Executable ParseConst(Parser parser, TokenStream tokens, Executable owner)
		{
			Token constToken = tokens.PopExpected("const");
			Token nameToken = tokens.Pop();
			Parser.VerifyIdentifier(nameToken);
			tokens.PopExpected("=");
			Expression expression = ExpressionParser.Parse(tokens, owner);
			tokens.PopExpected(";");

			return new ConstStatement(constToken, nameToken, parser.CurrentNamespace, expression, owner);
		}