コード例 #1
0
        private BlockNode ParseBlock()
        {
            BlockNode retn = new BlockNode();

            int expressionMatch = tokenStream.FindMatchingIndexNoAdvance(ExpressionTokenType.ExpressionOpen, ExpressionTokenType.ExpressionClose);

            if (expressionMatch == -1)
            {
                retn.Release();
                return(null);
            }

            tokenStream.Save();

            tokenStream.Advance();

            while (tokenStream.CurrentIndex != expressionMatch)
            {
                ASTNode statement = null;

                int current = tokenStream.CurrentIndex;

                if (!ParseStatement(ref statement))
                {
                    retn.Release();
                    tokenStream.Restore();
                    return(null);
                }

                if (current == tokenStream.CurrentIndex)
                {
                    throw new ParseException("fail recurse");
                }

                retn.statements.Add(statement);
            }

            tokenStream.Advance();

            return(retn);
        }
コード例 #2
0
        private bool ParseDeclaration(ref ASTNode node)
        {
            AttributeNode             attrNode   = null;
            LightList <AttributeNode> attributes = LightList <AttributeNode> .Get();

            while (ParseAttribute(ref attrNode))
            {
                attributes.Add(attrNode);
                if (tokenStream.Current != ExpressionTokenType.ArrayAccessOpen)
                {
                    break;
                }
            }

            if (attributes.size == 0)
            {
                LightList <AttributeNode> .Release(ref attributes);
            }

            if (tokenStream.Current != ExpressionTokenType.Identifier)
            {
                return(false);
            }

            // modifiers? -> returnType -> name -> signature -> openBrace * closeBrace

            tokenStream.Save();

            bool isStatic = false;

            if (tokenStream.Current == "static")
            {
                isStatic = true;
                tokenStream.Advance();
            }

            ExpressionParser            parser    = new ExpressionParser(tokenStream);
            StructList <LambdaArgument> signature = null;
            TypeLookup typeLookup = default;

            if (!parser.ParseTypePath(ref typeLookup))
            {
                goto fail;
            }

            tokenStream.Set(parser.GetTokenPosition());
            parser.Release(false);

            if (tokenStream.Current != ExpressionTokenType.Identifier)
            {
                goto fail;
            }

            string name = tokenStream.Current.value;

            tokenStream.Advance();

            // if semi colon then we have a field!
            if (tokenStream.Current == ExpressionTokenType.SemiColon)
            {
                tokenStream.Advance();
                node = new FieldNode()
                {
                    name       = name,
                    isStatic   = isStatic,
                    attributes = attributes,
                    typeLookup = typeLookup
                };
                return(true);
            }

            if (tokenStream.Current != ExpressionTokenType.ParenOpen)
            {
                goto fail;
            }

            signature = StructList <LambdaArgument> .Get();

            if (tokenStream.NextTokenIs(ExpressionTokenType.ParenClose))
            {
                tokenStream.Advance(2);
            }
            else
            {
                int matchingIndex = tokenStream.FindMatchingIndex(ExpressionTokenType.ParenOpen, ExpressionTokenType.ParenClose);

                if (matchingIndex == -1)
                {
                    goto fail;
                }

                TokenStream subStream = tokenStream.AdvanceAndReturnSubStream(matchingIndex);
                subStream.Advance();
                tokenStream.Advance();
                if (!ExpressionParser.ParseSignature(subStream, signature))
                {
                    goto fail;
                }

                for (int i = 0; i < signature.size; i++)
                {
                    if (signature.array[i].type == null)
                    {
                        throw new ParseException($"When defining a method you must specify a type for all arguments. Found identifier {signature.array[i].identifier} but no type was given.");
                    }
                }
            }

            if (tokenStream.Current != ExpressionTokenType.ExpressionOpen)
            {
                goto fail;
            }

            BlockNode block = ParseBlock();

            node = new MethodNode()
            {
                body             = block,
                returnTypeLookup = typeLookup,
                attributes       = attributes,
                name             = name,
                isStatic         = isStatic,
                signatureList    = signature != null?signature.ToArray() : s_EmptySignature
            };

            StructList <LambdaArgument> .Release(ref signature);

            parser.Release(false);

            return(true);

fail:
            {
                tokenStream.Restore();
                parser.Release(false);
                typeLookup.Release();
                signature?.Release();
                return(false);
            }
        }
コード例 #3
0
        private bool ParseIfStatement(ref ASTNode node)
        {
            if (tokenStream.Current != ExpressionTokenType.If)
            {
                return(false);
            }

            LightList <ElseIfNode> statements = LightList <ElseIfNode> .Get();

            tokenStream.Advance();

            ASTNode condition = null;

            if (!ParseParenExpression(ref condition))
            {
                throw new ParseException("Expected a condition statement wrapped in parentheses but failed.");
            }

            BlockNode thenBlock = ParseBlock();

            if (thenBlock == null)
            {
                throw new ParseException("Expected a block statement following an if statement but failed to parse the block");
            }

            if (tokenStream.Current != ExpressionTokenType.ElseIf && tokenStream.Current != ExpressionTokenType.Else)
            {
                node = new IfStatementNode()
                {
                    // elseIfStatements = statements.ToArray(),
                    condition = condition,
                    thenBlock = thenBlock
                };
                return(true);
            }

            while (tokenStream.Current == ExpressionTokenType.ElseIf)
            {
                tokenStream.Advance();

                ASTNode elseIfCondition = null;

                if (!ParseParenExpression(ref elseIfCondition))
                {
                    throw new ParseException("Expected a condition statement wrapped in parentheses but failed.");
                }

                BlockNode block = ParseBlock();

                if (block == null)
                {
                    throw new ParseException("Expected a block statement following an if statement but failed to parse the block");
                }

                statements.Add(new ElseIfNode()
                {
                    condition = elseIfCondition,
                    thenBlock = block
                });
            }

            BlockNode elseBlock = null;

            if (tokenStream.Current == ExpressionTokenType.Else)
            {
                tokenStream.Advance();
                elseBlock = ParseBlock();

                if (elseBlock == null)
                {
                    throw new ParseException("Expected a block statement following an else statement but failed to parse the block");
                }
            }

            node = new IfStatementNode()
            {
                condition        = condition,
                thenBlock        = thenBlock,
                elseIfStatements = statements.size == 0 ? null : statements.ToArray(),
                elseBlock        = elseBlock
            };

            statements.Release();

            return(true);
        }