Esempio n. 1
0
 public static void AssertTypeMatch(Token token, TokenType tokenType)
 {
     if (token.TokenType != tokenType)
     {
         RevnException.ThrowParserException($"{tokenType} expected", token);
     }
 }
Esempio n. 2
0
        private ExpressionAST ParseVariableAssignment()
        {
            var variable = new VariableExpressionAST();

            variable.IsToSet   = true;
            variable.IsMutable = parser.LastToken.TokenType == TokenType.Var;

            parser.ProceedToken(); // val/var を消費
            Assert.AssertTypeMatch(parser.LastToken, TokenType.Identifier);
            variable.Name = parser.LastToken.Value;

            parser.ProceedToken(); // 変数名を消費

            if (parser.LastToken.TokenType == TokenType.BlockStartOrColon)
            {
                parser.ProceedToken(); // : を消費
                Assert.AssertTypeMatch(parser.LastToken, TokenType.Identifier);
                variable.ReturnType = parser.LastToken.Value;
                parser.ProceedToken(); // 型を消費
            }

            if (parser.LastToken.TokenType != TokenType.Equals)
            {
                if (variable.ReturnType == null)
                {
                    RevnException.ThrowParserException($"Variable {variable.Name} must have a type.", parser.LastToken);
                }
                functionGenerator.AddVariable(variable);
                return(variable);
            }

            parser.ProceedToken(); // = を消費

            var assignment = new AssignmentAST
            {
                LHS = variable,
                RHS = GenerateExpressionAST()
            };

            if (variable.ReturnType == null)
            {
                variable.ReturnType = assignment.RHS.ReturnType;
            }
            functionGenerator.AddVariable(variable);

            return(assignment);
        }
Esempio n. 3
0
        private List <Argument> GenerateArgs()
        {
            Assert.AssertTypeMatch(parser.LastToken, TokenType.LParen);

            var args = new List <Argument>();

            Argument arg = new Argument();

            // 一回目のループで ( は消費される
            while (parser.ProceedToken().TokenType != TokenType.RParen)
            {
                // TODO 引数を区切るコンマの場合 arg を初期化
                // if (LastToken.TokenType == TokenType.Comma)
                arg.Name = parser.LastToken.Value;
                parser.ProceedToken(); // 引数名を消費

                if (parser.LastToken.TokenType != TokenType.BlockStartOrColon)
                {
                    RevnException.ThrowParserException("Excpected ':'", parser.LastToken);
                }
                parser.ProceedToken(); // : を消費

                arg.Type = parser.LastToken.Value;
                parser.ProceedToken(); // 型名を消費

                // TODO string だけ一応今は特別対応
                if (arg.Type.ToLower() == "string")
                {
                    arg.Type = "string";
                }

                // 配列だけ一応分けておく(多分プロパティになる気がする)
                if (parser.LastToken.TokenType == TokenType.LBracket)
                {
                    arg.Type += parser.LastToken.Value;
                    parser.ProceedToken();
                    arg.Type += parser.LastToken.Value;
                }

                args.Add(arg);
            }
            parser.ProceedToken(); // ) を消費

            return(args);
        }
Esempio n. 4
0
        private ExpressionAST ParseIdentifier(string inferedType)
        {
            string identifier = parser.LastToken.Value;

            parser.ProceedToken();

            while (parser.LastToken.TokenType == TokenType.Period)
            {
                parser.ProceedToken(); // . を消費
                Assert.AssertTypeMatch(parser.LastToken, TokenType.Identifier);
                identifier += "." + parser.LastToken.Value;
                parser.ProceedToken(); // 変数を消費
            }

            if (parser.LastToken.TokenType != TokenType.LParen)
            {
                if (!functionGenerator.HasLocalVariable(identifier))
                {
                    RevnException.ThrowParserException("Variable is not assigned.", parser.LastToken);
                }

                string type = functionGenerator.GetVariable(identifier).ReturnType;

                var variable = new VariableExpressionAST();
                variable.ReturnType = type;
                variable.Name       = identifier;
                variable.Index      = LocalVariableIndex;
                return(variable);
            }

            if (inferedType == null)
            {
                inferedType = "void";
            }

            parser.ProceedToken(); // ( を消費

            var args = new List <ExpressionAST>();

            if (parser.LastToken.TokenType != TokenType.RParen)
            {
                while (true)
                {
                    var arg = GenerateExpressionAST();
                    args.Add(arg);

                    if (parser.LastToken.TokenType == TokenType.RParen)
                    {
                        break;
                    }

                    if (parser.LastToken.TokenType != TokenType.Comma)
                    {
                        RevnException.ThrowParserException("Expected comma or )", parser.LastToken);
                    }
                    parser.ProceedToken(); // , を消費
                }
            }

            parser.ProceedToken(); // ) を消費

            return(new CallExpressionAST(identifier, args, inferedType));
        }