Beispiel #1
0
        private static void ParseFieldList(Lexer.Lexer lexer, out List <Exp> ks, out List <Exp> vs)
        {
            ks = null;
            vs = null;

            if (lexer.LookAhead() != ETokenType.SepRCurly)
            {
                ParseField(lexer, out var k, out var v);

                ks = new List <Exp> {
                    k
                };
                vs = new List <Exp> {
                    v
                };

                while (IsFieldSep(lexer.LookAhead()))
                {
                    lexer.NextToken(out _, out _, out _);
                    if (lexer.LookAhead() != ETokenType.SepRCurly)
                    {
                        ParseField(lexer, out k, out v);
                        ks.Add(k);
                        vs.Add(v);
                    }
                    else
                    {
                        break;
                    }
                }
            }
        }
Beispiel #2
0
        private static Exp ParseExp3(Lexer.Lexer lexer)
        {
            var exp = ParseExp2(lexer);

            while (true)
            {
                switch (lexer.LookAhead())
                {
                case ETokenType.OpMul:
                case ETokenType.OpMod:
                case ETokenType.OpDiv:
                case ETokenType.OpIDiv:
                {
                    lexer.NextToken(out var line, out var op, out _);
                    var arith = new BinopExp
                    {
                        Line = line,
                        Op   = op,
                        Exp1 = exp,
                        Exp2 = ParseExp2(lexer)
                    };
                    exp = OptimizeArithBinaryOp(arith);
                    break;
                }

                default:
                    return(exp);
                }
            }
        }
Beispiel #3
0
        private static Exp ParseExp5(Lexer.Lexer lexer)
        {
            var exp = ParseExp4(lexer);

            if (lexer.LookAhead() != ETokenType.OpConcat)
            {
                return(exp);
            }

            var line = 0;
            var exps = new List <Exp> {
                exp
            };

            while (lexer.LookAhead() == ETokenType.OpConcat)
            {
                lexer.NextToken(out line, out _, out _);
                exps.Add(ParseExp4(lexer));
            }

            return(new ConcatExp
            {
                Line = line,
                Exps = exps
            });
        }
Beispiel #4
0
        private static Exp ParseExp6(Lexer.Lexer lexer)
        {
            var exp = ParseExp5(lexer);

            while (true)
            {
                switch (lexer.LookAhead())
                {
                case ETokenType.OpShl:
                case ETokenType.OpShr:
                {
                    lexer.NextToken(out var line, out var op, out _);
                    var shx = new BinopExp
                    {
                        Line = line,
                        Op   = op,
                        Exp1 = exp,
                        Exp2 = ParseExp5(lexer)
                    };
                    exp = OptimizeBitwiseBinaryOp(shx);
                    break;
                }

                default:
                    return(exp);
                }
            }
        }
Beispiel #5
0
        private static void ParseField(Lexer.Lexer lexer, out Exp k, out Exp v)
        {
            k = null;
            v = null;

            if (lexer.LookAhead() == ETokenType.SepLBracket)
            {
                lexer.NextToken(out _, out _, out _);
                k = ParseExp(lexer);
                lexer.NextTokenOfKind(ETokenType.SepRBracket, out _, out _);
                lexer.NextTokenOfKind(ETokenType.OpAssign, out _, out _);
                v = ParseExp(lexer);
                return;
            }

            var exp = ParseExp(lexer);

            if (exp is NameExp nameExp)
            {
                if (lexer.LookAhead() == ETokenType.OpAssign)
                {
                    lexer.NextToken(out _, out _, out _);
                    k = new StringExp {
                        Line = nameExp.Line, Str = nameExp.Name
                    };
                    v = ParseExp(lexer);
                    return;
                }
            }

            v = exp;
        }
        private Program TestParseProgram(string input)
        {
            var l = new Lexer.Lexer(input);
            var p = new Parser.Parser(l);

            return(p.ParseProgram());
        }
Beispiel #7
0
        private static List<Exp> ParseRetExps(Lexer.Lexer lexer)
        {
            if (lexer.LookAhead() != ETokenType.KwReturn)
                return null;

            lexer.NextToken(out _, out _, out _);

            var ret = new List<Exp>();

            switch (lexer.LookAhead())
            {
                case ETokenType.Eof:
                case ETokenType.KwEnd:
                case ETokenType.KwElse:
                case ETokenType.KwElseIf:
                case ETokenType.KwUntil:
                    return ret;

                case ETokenType.SepSemi:
                    lexer.NextToken(out _, out _, out _);
                    return ret;

                default:
                    var exps = ParseExpList(lexer);
                    if (lexer.LookAhead() == ETokenType.SepSemi)
                        lexer.NextToken(out _, out _, out _);
                    return exps;
            }
        }
Beispiel #8
0
        public void TestBooleanExpression()
        {
            var tests = new Dictionary <string, bool>
            {
                { "true;", true },
                { "false;", false }
            };

            foreach (var tt in tests)
            {
                var l       = new Lexer.Lexer(tt.Key);
                var p       = new Parser(l);
                var program = p.ParseProgram();
                CheckParserErrors(p);

                Assert.AreEqual(1, program.Statements.Count, $"program has not enough statements. got={program.Statements.Count}");

                var stmt = program.Statements[0] as ExpressionStatement;
                Assert.IsNotNull(stmt, $"program.Statement[0] is not IntegerLiteral. got={program.Statements[0].GetType().Name}");
                Assert.IsNotNull(stmt.Expression, "stmt.Expression is null");

                var ident = stmt.Expression as Boolean;
                Assert.IsNotNull(ident, $"exp is not Boolean. got={stmt.Expression.GetType().Name}");
                Assert.AreEqual(tt.Value, ident.Value, $"ident.Value not {tt.Value}. got={ident.Value}");
                Assert.AreEqual(tt.Value.ToString().ToLower(), ident.TokenLiteral, $"ident.TokenLiteral not {tt.Value.ToString().ToLower()}. got={ident.TokenLiteral}");
            }
        }
Beispiel #9
0
        public void TestCallExpressionParsing()
        {
            const string input = "add(1, 2 * 3, 4 + 5);";

            var l       = new Lexer.Lexer(input);
            var p       = new Parser(l);
            var program = p.ParseProgram();

            CheckParserErrors(p);

            Assert.AreEqual(1, program.Statements.Count, $"program.Statements does not contain 1 statement. got={program.Statements.Count}");

            var stmt = program.Statements[0] as ExpressionStatement;

            Assert.IsNotNull(stmt, $"stmt is not ast.ExpressionStatement. got={program.Statements[0].GetType().Name}");

            var exp = stmt.Expression as CallExpression;

            Assert.IsNotNull(exp, $"stmt.Expression is not ast.CallExpression. got={stmt.Expression.GetType().Name}");

            TestIdentifier(exp.Function, "add");

            Assert.AreEqual(3, exp.Arguments.Count, $"wrong length of arguments. got={exp.Arguments.Count}");

            TestLiteralExpression(exp.Arguments[0], 1);
            TestInfixExpression(exp.Arguments[1], 2, "*", 3);
            TestInfixExpression(exp.Arguments[2], 4, "+", 5);
        }
Beispiel #10
0
        public void TestIfExpression()
        {
            const string input   = "if (x < y) { x }";
            var          l       = new Lexer.Lexer(input);
            var          p       = new Parser(l);
            var          program = p.ParseProgram();

            CheckParserErrors(p);

            Assert.AreEqual(1, program.Statements.Count, $"program.Body does not contain 1 statement. got={program.Statements.Count}");

            var stmt = program.Statements[0] as ExpressionStatement;

            Assert.IsNotNull(stmt, $"program.Statements[0] is not ast.ExpressionStatement. got={program.Statements[0].GetType().Name}");

            var exp = stmt.Expression as IfExpression;

            Assert.IsNotNull(exp, $"stmt.Expression is not ast.IfExpression. got={stmt.Expression.GetType().Name}");

            TestInfixExpression(exp.Condition, "x", "<", "y");

            Assert.AreEqual(1, exp.Consequence.Statements.Count, $"consequence is not 1 statement. got={exp.Consequence.Statements.Count}");

            var consequence = exp.Consequence.Statements[0] as ExpressionStatement;

            Assert.IsNotNull(consequence, $"Statements[0] is not ast.ExpressionStatement. got={exp.Consequence.Statements[0].GetType().Name}");

            TestIdentifier(consequence.Expression, "x");

            Assert.IsNull(exp.Alternative, $"exp.Alternative.Statements was not nil. got={exp.Alternative}");
        }
Beispiel #11
0
        private static Exp ParseExp10(Lexer.Lexer lexer)
        {
            var exp = ParseExp9(lexer);

            while (true)
            {
                switch (lexer.LookAhead())
                {
                case ETokenType.OpLt:
                case ETokenType.OpGt:
                case ETokenType.OpNe:
                case ETokenType.OpLe:
                case ETokenType.OpGe:
                case ETokenType.OpEq:
                {
                    lexer.NextToken(out var line, out var op, out _);
                    exp = new BinopExp
                    {
                        Line = line,
                        Op   = op,
                        Exp1 = exp,
                        Exp2 = ParseExp9(lexer)
                    };
                    break;
                }

                default:
                    return(exp);
                }
            }
        }
Beispiel #12
0
        public void TestReturnStatements()
        {
            var tests = new Dictionary <string, object>
            {
                { "return 5;", 5 },
                { "return true;", true },
                { "return foobar;", "foobar" }
            };

            foreach (var tt in tests)
            {
                var l       = new Lexer.Lexer(tt.Key);
                var p       = new Parser(l);
                var program = p.ParseProgram();
                CheckParserErrors(p);

                Assert.AreEqual(1, program.Statements.Count, $"program.Statements does not contain 1 statement. got={program.Statements.Count}");

                var stmt       = program.Statements[0];
                var returnStmt = stmt as ReturnStatement;
                Assert.IsNotNull(returnStmt, $"stmt not ReturnStatement. got={stmt.GetType().Name}");
                Assert.AreEqual("return", returnStmt.TokenLiteral, $"returnStmt.TokenLiteral not 'return', got {returnStmt.TokenLiteral}");
                TestLiteralExpression(returnStmt.ReturnValue, tt.Value);
            }
        }
Beispiel #13
0
        public void TestMacroLiteralParsing()
        {
            const string input = "macro(x, y) { x + y; }";

            var l       = new Lexer.Lexer(input);
            var p       = new Parser(l);
            var program = p.ParseProgram();

            CheckParserErrors(p);

            Assert.AreEqual(1, program.Statements.Count, $"program.Statements does not contain 1 statement. got={program.Statements.Count}");

            var stmt = program.Statements[0] as ExpressionStatement;

            Assert.IsNotNull(stmt, $"program.Statements[0] is not ast.ExpressionStatement. got={program.Statements[0].GetType().Name}");

            var macro = stmt.Expression as MacroLiteral;

            Assert.IsNotNull(macro, $"stmt.Expression is not ast.MacroLiteral. got={stmt.Expression.GetType().Name}");

            Assert.AreEqual(2, macro.Parameters.Count, $"macro literal parameters wrong. want 2, got={macro.Parameters.Count}");

            TestLiteralExpression(macro.Parameters[0], "x");
            TestLiteralExpression(macro.Parameters[1], "y");

            Assert.AreEqual(1, macro.Body.Statements.Count, $"macro.Body.Statements has not 1 statement. got={macro.Body.Statements.Count}");

            var bodyStmt = macro.Body.Statements[0] as ExpressionStatement;

            Assert.IsNotNull(bodyStmt, $"macro body stmt is not ast.ExpressionStatement. got={macro.Body.Statements[0].GetType().Name}");

            TestInfixExpression(bodyStmt.Expression, "x", "+", "y");
        }
Beispiel #14
0
        public void TestParsingHashLiteralsWithExpressions()
        {
            const string input = "{\"one\": 0 + 1, \"two\": 10 - 8, \"three\": 15 / 5}";

            var l       = new Lexer.Lexer(input);
            var p       = new Parser(l);
            var program = p.ParseProgram();

            CheckParserErrors(p);

            var stmt = program.Statements[0] as ExpressionStatement;
            var hash = stmt.Expression as HashLiteral;

            Assert.IsNotNull(hash, $"exp is not HashLiteral. got={stmt.Expression.GetType().Name}");

            Assert.AreEqual(3, hash.Pairs.Count, $"hash.Pairs has wrong length. got={hash.Pairs.Count}");

            var tests = new Dictionary <string, Action <IExpression> >
            {
                { "one", e => TestInfixExpression(e, 0, "+", 1) },
                { "two", e => TestInfixExpression(e, 10, "-", 8) },
                { "three", e => TestInfixExpression(e, 15, "/", 5) },
            };

            foreach (var pair in hash.Pairs)
            {
                var literal = pair.Key as StringLiteral;
                Assert.IsNotNull(literal, $"key is not ast.StringLiteral. got={pair.Key.GetType().Name}");

                Assert.IsTrue(tests.ContainsKey(literal.ToString()));

                var testFunc = tests[literal.ToString()];
                testFunc(pair.Value);
            }
        }
Beispiel #15
0
 private static Stat ParseBreakStat(Lexer.Lexer lexer)
 {
     lexer.NextTokenOfKind(ETokenType.KwBreak, out _, out _);
     return(new BreakStat {
         Line = lexer.Line
     });
 }
Beispiel #16
0
        public void TestMethod3()
        {
            Lexer.Lexer lexer = new Lexer.Lexer();

            lexer.AddDefinition(new TokenDefinition {
                Regex = new Regex("[Aa][Dd][Dd]"), Type = TokenTyp.Add
            });
            lexer.AddDefinition(new TokenDefinition {
                Regex = new Regex("\\("), Type = TokenTyp.OpenParenthesis
            });
            lexer.AddDefinition(new TokenDefinition {
                Regex = new Regex("\\)"), Type = TokenTyp.CloseParenthesis
            });
            lexer.AddDefinition(new TokenDefinition {
                Regex = new Regex(","), Type = TokenTyp.Comma
            });
            lexer.AddDefinition(new TokenDefinition {
                Regex = new Regex(@"\d+"), Type = TokenTyp.Number
            });
            lexer.AddDefinition(new TokenDefinition {
                Regex = new Regex(@"\s+"), Type = TokenTyp.Whitespace, IsIgnored = true
            });

            LanguageParser parser = new LanguageParser();
            int            res    = parser.Parse(lexer.Tokenize("ADD(ADD(1,ADD(1,3)) ,ADD(1,5)").ToList());

            Assert.AreEqual(res, 11);
        }
Beispiel #17
0
        private static Stat ParseIfStat(Lexer.Lexer lexer)
        {
            var exps   = new List <Exp>();
            var blocks = new List <Block>();

            lexer.NextTokenOfKind(ETokenType.KwIf, out _, out _);
            exps.Add(ParseExp(lexer));

            lexer.NextTokenOfKind(ETokenType.KwThen, out _, out _);
            blocks.Add(ParseBlock(lexer));

            while (lexer.LookAhead() == ETokenType.KwElseIf)
            {
                lexer.NextToken(out _, out _, out _);
                exps.Add(ParseExp(lexer));
                lexer.NextTokenOfKind(ETokenType.KwThen, out _, out _);
                blocks.Add(ParseBlock(lexer));
            }

            if (lexer.LookAhead() == ETokenType.KwElse)
            {
                lexer.NextToken(out _, out _, out _);
                exps.Add(new TrueExp {
                    Line = lexer.Line
                });
                blocks.Add(ParseBlock(lexer));
            }

            lexer.NextTokenOfKind(ETokenType.KwEnd, out _, out _);
            return(new IfStat {
                Exps = exps, Blocks = blocks
            });
        }
Beispiel #18
0
        public void SetTextAsThisToken(string rawText)
        {
            //Stream stream = new MemoryStream(UnicodeEncoding.UTF8.GetBytes(rawText));
            StreamReader stream = new StreamReader(new MemoryStream(Globals.LpcInternalCodec.GetBytes(rawText)), Globals.LpcFileCodec, false);
            ParseMap     map;
            SyntaxRules  lpcRules = new SyntaxRules(out map);

            Scanner.Scanner scanner = new Scanner.Scanner(stream);
            Lexer.Lexer     lexer   = new Lexer.Lexer(scanner);
            Parser          parser  = new Parser(lexer, map);

            foreach (Token token in parser.LPCTokens)
            {
                if (token.Lexmes.Count > 0)
                {
                    Token copy = token;
                    Type = copy.Type;
                    object tempLexmes = copy.Lexmes.ToArray().Clone();
                    this.Lexmes = new List <Stellarmass.LPC.Lexer.Lexme>((Lexer.Lexme[])tempLexmes);

                    for (int outter = 0; outter < copy.Children.Count; outter++)
                    {
                        this.Children.Add(new List <Token>());
                        foreach (Token t in copy.Children[outter])
                        {
                            this.Children[outter].Add(new Token(t));
                        }
                    }
                    return;
                }
            }
            return;
        }
Beispiel #19
0
 public Engine(Lexer.Lexer lexer, MetadataHost host)
 {
     mLexer = lexer;
     Host = host;
     InitializeKeywords();
     Move();
 }
Beispiel #20
0
        public void Start(TextReader reader, TextWriter writer)
        {
            var env      = new Environment();
            var macroEnv = new Environment();

            while (true)
            {
                writer.Write(Prompt);
                var line = reader.ReadLine();
                if (string.IsNullOrEmpty(line))
                {
                    return;
                }

                var l = new Lexer.Lexer(line);
                var p = new Parser.Parser(l);

                var program = p.ParseProgram();
                if (p.Errors.Any())
                {
                    PrintParserErrors(writer, p.Errors);
                    continue;
                }

                var evaluator = new Evaluator.Evaluator();
                evaluator.DefineMacros(program, macroEnv);
                var expanded  = evaluator.ExpandMacros(program, macroEnv);
                var evaluated = evaluator.Eval(expanded, env);
                if (evaluated != null)
                {
                    writer.WriteLine(evaluated.Inspect());
                }
            }
        }
Beispiel #21
0
        public void TestExpressionFunctionReturnTypeBinding()
        {
            const string src = "namespace MyNamespace" +
                               "{" +
                               "    class MyClass" +
                               "    {" +
                               "        func Add(int a, int b) -> return new MyClass2()" +
                               "    }" +
                               "" +
                               "    class MyClass2" +
                               "    {" +
                               "        " +
                               "    }" +
                               "}";

            var lexer = new Lexer.Lexer();
            var tokens = lexer.Lex(src);
            var parser = new Parser.Parser(tokens);

            var ast = parser.Parse();

            var binder = new Binder();
            var semanticModel = binder.Bind(new List<CompilationUnitSyntax> { ast }).Single();

            var boundNamespace = semanticModel.Namespaces.Single(x => x.Name == "MyNamespace");
            var expectedFunctionReturnType = boundNamespace.Types.Single(x => x.Name == "MyClass2");
            var function = boundNamespace.Types.Single(x => x.Name == "MyClass").Functions.Single(x => x.Name == "Add");
            Assert.AreSame(expectedFunctionReturnType, function.ReturnType);
        }
Beispiel #22
0
        public void TestParsingHashLiteralsIntegerKeys()
        {
            const string input = "{1: 1, 2: 2, 3: 3}";

            var l       = new Lexer.Lexer(input);
            var p       = new Parser(l);
            var program = p.ParseProgram();

            CheckParserErrors(p);

            var stmt = program.Statements[0] as ExpressionStatement;
            var hash = stmt.Expression as HashLiteral;

            Assert.IsNotNull(hash, $"exp is not HashLiteral. got={stmt.Expression.GetType().Name}");

            var expected = new Dictionary <string, long>
            {
                { "1", 1 },
                { "2", 2 },
                { "3", 3 }
            };

            foreach (var pair in hash.Pairs)
            {
                var literal = pair.Key as IntegerLiteral;
                Assert.IsNotNull(literal, $"key is not ast.IntegerLiteral. got={pair.Key.GetType().Name}");

                var expectedValue = expected[literal.ToString()];

                TestIntegerLiteral(pair.Value, expectedValue);
            }
        }
Beispiel #23
0
        public Parser(Lexer.Lexer lexer)
        {
            this.lexer  = lexer;
            this.errors = new List <string>();

            this.nextToken();
            this.nextToken();
        }
Beispiel #24
0
 private static Stat ParseGotoStat(Lexer.Lexer lexer)
 {
     lexer.NextTokenOfKind(ETokenType.KwGoto, out _, out _);
     lexer.NextIdentifier(out _, out var name);
     return(new GotoStat {
         Name = name
     });
 }
Beispiel #25
0
        public static Block Parse(string chunk, string chunkName)
        {
            var lexer = new Lexer.Lexer(chunk, chunkName);
            var block = ParseBlock(lexer);

            lexer.NextTokenOfKind(ETokenType.Eof, out _, out _);
            return(block);
        }
Beispiel #26
0
 private static Stat ParseLabelStat(Lexer.Lexer lexer)
 {
     lexer.NextTokenOfKind(ETokenType.SepLabel, out _, out _);
     lexer.NextIdentifier(out _, out var name);
     lexer.NextTokenOfKind(ETokenType.SepLabel, out _, out _);
     return(new LabelStat {
         Name = name
     });
 }
        private IObject TestEval(string input)
        {
            var l       = new Lexer.Lexer(input);
            var p       = new Parser.Parser(l);
            var program = p.ParseProgram();
            var env     = new Environment();

            return(new Evaluator().Eval(program, env));
        }
Beispiel #28
0
 private static Block ParseBlock(Lexer.Lexer lexer)
 {
     return new Block
     {
         Stats = ParseStats(lexer),
         RetExps = ParseRetExps(lexer),
         LastLine = lexer.Line
     };
 }
Beispiel #29
0
        private static Stat ParseDoStat(Lexer.Lexer lexer)
        {
            lexer.NextTokenOfKind(ETokenType.KwDo, out _, out _);
            var block = ParseBlock(lexer);

            lexer.NextTokenOfKind(ETokenType.KwEnd, out _, out _);
            return(new DoStat {
                Block = block
            });
        }
Beispiel #30
0
 public Parser(Lexer.Lexer input, int lookaheadCount)
 {
     this.input          = input;
     this.lookaheadCount = lookaheadCount;
     lookahead           = new Token[lookaheadCount];
     for (int i = 1; i <= lookaheadCount; i++)
     {
         ConsumeNextToken();
     }
 }
Beispiel #31
0
        private static Exp ParseNumberExp(Lexer.Lexer lexer)
        {
            lexer.NextToken(out var line, out _, out var token);

            var numberStyle = NumberStyles.Number;
            var e           = 1.0;

            if (token.StartsWith("0x"))
            {
                token = token.Substring(2);
                if (token.Contains("p"))
                {
                    var eIdx = token.IndexOf("p");
                    var t    = LuaFloat.Parse("1" + token.Substring(eIdx).Replace("p", "e"));
                    var d    = t > 1 ? 0.1 : 10;
                    while (t != 1)
                    {
                        e *= d > 1 ? 0.5 : 2;
                        t *= d;
                    }

                    token = token.Substring(0, eIdx);
                }

                numberStyle = NumberStyles.HexNumber;
            }

            if (LuaInt.TryParse(token, numberStyle, new NumberFormatInfo(), out var result))
            {
                if (e != 1.0)
                {
                    return new FloatExp {
                               Line = line, Val = result * e
                    }
                }
                ;

                return(new IntegerExp {
                    Line = line, Val = result
                });
            }

            if (LuaFloat.TryParse(token, out var fResult))
            {
                return new FloatExp {
                           Line = line, Val = fResult
                }
            }
            ;

            Debug.Panic("not a number: " + token);
            return(null);
        }
    }
}
Beispiel #32
0
        /// <summary>
        /// コンパイルするコードを指定してコンパイルし、実行します。
        /// </summary>
        /// <param name="code">コンパイルされるコード文字列。</param>
        /// <returns>コンパイルに成功したとき true、それ以外のとき false。</returns>
        public LuryObject Evaluate(string code)
        {
            var lexer           = new Lexer.Lexer(code + '\n');
            var succeedTokenize = lexer.Tokenize();

            lexer.Logger.CopyTo(this.OutputLogger);

            if (!succeedTokenize)
            {
                return(null);
            }

            var globalContext = new LuryContext();

            Intrinsic.SetBuiltInFunctions(globalContext);

            var     parser  = new Parser();
            Routine routine = null;

            // parsing
            try
            {
                routine = (Routine)parser.yyparse(new Lex2yyInput(lexer), new yydebug.yyDebugSimple());
            }
            catch (yyParser.yyException ex)
            {
                this.ReportyyException(ex, code);
                return(null);
            }

            // running
            if (routine == null)
            {
                return(null);
            }
            else
            {
                try
                {
                    var exit = routine.Evaluate(globalContext);

                    if (exit.ExitReason == StatementExitReason.Break)
                    {
                        throw new LuryException(LuryExceptionType.WrongBreak);
                    }

                    return(exit.ReturnValue);
                }
                catch (LuryException ex)
                {
                    Console.Error.WriteLine(ex.Message);
                    return(null);
                }
            }
        }
Beispiel #33
0
        public void TestClass()
        {
            var lexer = new Lexer.Lexer();
            var tokens =
                lexer.Lex(
                    string.Format(NamespaceSource, string.Format(ClassSource, string.Empty, string.Empty, string.Empty)));
            var parser = new Parser.Parser(tokens);

            var ast = parser.Parse();
            Assert.IsInstanceOf<CompilationUnitSyntax>(ast);
            Assert.IsNotEmpty(ast.Namespaces);
            Assert.IsNotEmpty(ast.Namespaces[0].Classes);
            Assert.AreEqual("ClassSample", ast.Namespaces[0].Classes[0].Name.Value);
            Assert.AreEqual("DSampleProtocol", ast.Namespaces[0].Classes[0].ProtocolName.Value);
        }
Beispiel #34
0
        public void TestExpressionFunction()
        {
            const string functionSource = "func FunctionSample(int a, int b, int c) -> return a * b * c";

            var lexer = new Lexer.Lexer();
            var tokens =
                lexer.Lex(
                    string.Format(
                        NamespaceSource,
                        string.Format(ClassSource, functionSource, string.Empty, string.Empty)));
            var parser = new Parser.Parser(tokens);

            var ast = parser.Parse();
            Assert.IsNotEmpty(ast.Namespaces[0].Classes[0].Functions);
            Assert.IsInstanceOf<FunctionSyntax>(ast.Namespaces[0].Classes[0].Functions[0]);
            Assert.AreEqual("FunctionSample", ast.Namespaces[0].Classes[0].Functions[0].Name.Value);
        }
Beispiel #35
0
        public void TestFieldTypeToVariableBinding()
        {
            const string src = "namespace MyNamespace" +
                               "{" +
                               "    class MyClass" +
                               "    {" +
                               "        var field : false" +
                               "        var field2 : new MyClass2()" +
                               "        func MyFunc()" +
                               "        {" +
                               "            var i : field" +
                               "            var i2 : field2" +
                               "        }" +
                               "    }" +
                               "" +
                               "    class MyClass2" +
                               "    {" +
                               "        " +
                               "    }" +
                               "}";

            var lexer = new Lexer.Lexer();
            var tokens = lexer.Lex(src);
            var parser = new Parser.Parser(tokens);

            var ast = parser.Parse();

            var binder = new Binder();
            var semanticModel = binder.Bind(new List<CompilationUnitSyntax> { ast }).Single();

            var boundNamespace = semanticModel.Namespaces.Single(x => x.Name == "MyNamespace");
            var referencedBoundType = boundNamespace.Types.Single(x => x.Name == "MyClass2");
            var boundType = boundNamespace.Types.Single(x => x.Name == "MyClass");
            var boundFunction = (BoundFunction)boundType.Functions.Single(x => x.Name == "MyFunc");
            Assert.IsInstanceOf<BoolCompilerGeneratedType>(
                ((IBoundMember)((BoundScopeStatement)boundFunction.Statements).Statements[0]).Type);
            Assert.AreSame(
                ((IBoundMember)((BoundScopeStatement)boundFunction.Statements).Statements[1]).Type,
                referencedBoundType);
        }
Beispiel #36
0
        public void Test_GenericConstraints(string constraint)
        {
            const string template = "class SomeGenericClass!(T) where T {0}";

            var parserFunc = new Action<string>(
                opSrc =>
                {
                    var lexer = new Lexer.Lexer();
                    var tokens = lexer.Lex(string.Format(template, opSrc));
                    var parser = new Parser.Parser(tokens);
                    parser.Parse();
                });

            Assert.That(() => parserFunc(constraint), Throws.Nothing);
        }
Beispiel #37
0
        public void Test_GenericLocalFunction_Call()
        {
            const string src = "namespace MyNamespace" +
                               "{" +
                               "    func GenericFunction!(TypeA, TypeB)(TypeA a, TypeB b)" +
                               "    {" +
                               "        let anonFunc : func!(TypeX, TypeY)(TypeX x, TypeY y) -> return x" +
                               "        anonFunc!(a, a)" +
                               "    }" +
                               "}";

            var lexer = new Lexer.Lexer();
            var tokens = lexer.Lex(src);
            var parser = new Parser.Parser(tokens);

            Assert.DoesNotThrow(() => parser.Parse());
        }
Beispiel #38
0
        public void Test_InvalidOperatorNames_Throw()
        {
            const string template = "namespace MyNamespace" +
                                    "{{" +
                                    "    class MyClass2" +
                                    "    {{" +
                                    "        {0}" +
                                    "    }}" +
                                    "}}";

            var parserFunc = new Action<string>(
                opSrc =>
                {
                    var lexer = new Lexer.Lexer();
                    var tokens = lexer.Lex(string.Format(template, opSrc));
                    var parser = new Parser.Parser(tokens);
                    parser.Parse();
                });

            Assert.That(() => parserFunc("operator Addd(MyClassName opA, MyClassName opB) -> return true"), Throws.InstanceOf<KiwiSyntaxException>().With.Message.EqualTo("Invalid operator function name 'Addd'"));
        }
Beispiel #39
0
        public void Test_primary_Constructor()
        {
            const string code = @"namespace MyNamespace" +
                                    "{" +
                                    "    class MyClass" +
                                    "    {" +
                                    "       primary Constructor(int val)" +
                                    "       {" +
                                    "       }" +
                                    "    }" +
                                    "}";

            var parserFunc = new Action<string>(
                opSrc =>
                {
                    var lexer = new Lexer.Lexer();
                    var tokens = lexer.Lex(opSrc);
                    var parser = new Parser.Parser(tokens);
                    parser.Parse();
                });

            Assert.That(() => parserFunc(code), Throws.Nothing);
        }
Beispiel #40
0
        public void Test_IsExpression_ThrowsTypeNotDefined()
        {
            const string src = "namespace MyNamespace" +
                               "{" +
                               "    class MyClass" +
                               "    {" +
                               "        func Add(int a, int b) -> return a * b" +
                               "    }" +
                               "" +
                               "    class MyClass2" +
                               "    {" +
                               "        var myClassField : new MyClass()" +
                               "        func Foo() -> bool" +
                               "        {" +
                               "            return myClassField is MyClassS" +
                               "        }" +
                               "    }" +
                               "}";

            var lexer = new Lexer.Lexer();
            var tokens = lexer.Lex(src);
            var parser = new Parser.Parser(tokens);

            var ast = parser.Parse();

            var binder = new Binder();

            Assert.That(
                () => binder.Bind(new List<CompilationUnitSyntax>() { ast }),
                Throws.InstanceOf<KiwiSemanticException>().With.Message.EqualTo("MyClassS undefined Type"));
        }
Beispiel #41
0
        public void Test_IsExpression()
        {
            const string src = "namespace MyNamespace" +
                               "{" +
                               "    class MyClass" +
                               "    {" +
                               "        func Add(int a, int b) -> return a * b" +
                               "    }" +
                               "" +
                               "    class MyClass2" +
                               "    {" +
                               "        var myClassField : new MyClass()" +
                               "        func Foo() -> bool" +
                               "        {" +
                               "            return myClassField is MyClass" +
                               "        }" +
                               "    }" +
                               "}";

            var lexer = new Lexer.Lexer();
            var tokens = lexer.Lex(src);
            var parser = new Parser.Parser(tokens);

            var ast = parser.Parse();

            var binder = new Binder();

            var boundCompilationUnit = binder.Bind(new List<CompilationUnitSyntax>() { ast }).Single();
            var type = boundCompilationUnit.Namespaces[0].Types.Single(x => x.Name == "MyClass");
            var function =
                (BoundFunction)
                boundCompilationUnit.Namespaces[0].Types.Single(x => x.Name == "MyClass2")
                                                  .Functions.Single(x => x.Name == "Foo");
            var returnStatement = (BoundReturnStatement)((BoundScopeStatement)function.Statements).Statements[0];
            var boundBinaryExpression = (BoundBinaryExpression)returnStatement.Expression;
            Assert.AreEqual(BinaryOperators.Is, boundBinaryExpression.Operator);
            Assert.IsInstanceOf<BoundTypeExpression>(boundBinaryExpression.Right);
            Assert.AreSame(((BoundTypeExpression)boundBinaryExpression.Right).ReferencedType, type);
        }
Beispiel #42
0
        public void Test_InfixCall_Types()
        {
            const string src = "namespace MyNamespace" +
                               "{" +
                               "    class MyClass2" +
                               "    {" +
                               "        infix func Add(int a, int b) -> return a + b" +
                               "        func Foo()" +
                               "        {" +
                               "            var a : 1 Add 2" +
                               "        }" +
                               "    }" +
                               "}";

            var lexer = new Lexer.Lexer();
            var tokens = lexer.Lex(src);
            var parser = new Parser.Parser(tokens);

            var ast = parser.Parse();
            var binder = new Binder();
            var boundCompilationUnits = binder.Bind(new List<CompilationUnitSyntax>() { ast });

            var myClass2Type = boundCompilationUnits[0].Namespaces[0].Types.Single();
            var fooFunction = myClass2Type.Functions.Single(x => x.Name == "Foo");
            var addFunction = myClass2Type.Functions.Single(x => x.Name == "Add");

            Assert.IsInstanceOf<BoundFunction>(addFunction);
            Assert.IsTrue(((BoundFunction)addFunction).IsInfixFunction);
            Assert.IsInstanceOf<BoundFunction>(fooFunction);
            var boundFunction = (BoundFunction)fooFunction;
            Assert.IsInstanceOf<BoundScopeStatement>(boundFunction.Statements);
            var boundScopeStatement = (BoundScopeStatement)boundFunction.Statements;
            Assert.IsInstanceOf<BoundVariableDeclarationStatement>(boundScopeStatement.Statements[0]);
            var boundVariableDeclarationStatement = (BoundVariableDeclarationStatement)boundScopeStatement.Statements[0];
            Assert.IsInstanceOf<BoundInvocationExpression>(boundVariableDeclarationStatement.BoundExpression);
            var boundInvocationExpression = (BoundInvocationExpression)boundVariableDeclarationStatement.BoundExpression;
            Assert.IsInstanceOf<BoundMemberExpression>(boundInvocationExpression.ToInvoke);
            var boundMemberExpression = (BoundMemberExpression)boundInvocationExpression.ToInvoke;
            Assert.AreSame(addFunction, boundMemberExpression.BoundMember);
        }
Beispiel #43
0
        public void Test_IfStatement_IfConditionMustBeBool()
        {
            const string src = "namespace MyNamespace" +
                               "{" +
                               "    class MyClass" +
                               "    {" +
                               "        func Add(int a, int b) " +
                               "        { " +
                               "            if(a)" +
                               "            {" +
                               "                " +
                               "            }" +
                               "        }" +
                               "    }" +
                               "" +
                               "}";

            var lexer = new Lexer.Lexer();
            var tokens = lexer.Lex(src);
            var parser = new Parser.Parser(tokens);

            var ast = parser.Parse();

            var binder = new Binder();

            Assert.That(
                () => binder.Bind(new List<CompilationUnitSyntax>() { ast }),
                Throws.InstanceOf<KiwiSemanticException>().With.Message.EqualTo("If condition must be of Type Bool"));
        }
Beispiel #44
0
        public void Test_TryCatch()
        {
            const string src = "namespace MyNamespace" +
                               "{" +
                               "    class GenericClass(TypeA, TypeB)" +
                               "    {" +
                               "        Constructor(TypeA arg1, TypeB arg2)" +
                               "        {" +
                               "            Try" +
                               "            {" +
                               "            }" +
                               "            catch(Error)" +
                               "            {" +
                               "            }" +
                               "        }" +
                               "    }" +
                               "}";

            var lexer = new Lexer.Lexer();
            var tokens = lexer.Lex(src);
            var parser = new Parser.Parser(tokens);

            Assert.DoesNotThrow(() => parser.Parse());
        }
Beispiel #45
0
        public void Test_ValidOperatorNames_DontThrow(string opCode)
        {
            const string template = "namespace MyNamespace" +
                                    "{{" +
                                    "    class MyClass2" +
                                    "    {{" +
                                    "        {0}" +
                                    "    }}" +
                                    "}}";

            var parserFunc = new Action<string>(
                opSrc =>
                {
                    var lexer = new Lexer.Lexer();
                    var tokens = lexer.Lex(string.Format(template, opSrc));
                    var parser = new Parser.Parser(tokens);
                    parser.Parse();
                });

            Assert.That(() => parserFunc(opCode), Throws.Nothing);
        }
Beispiel #46
0
        public void Test_VariableWithSameName_Throws()
        {
            const string src = "namespace MyNamespace" +
                               "{" +
                               "    class MyClass" +
                               "    {" +
                               "        func Add(int a, int b)" +
                               "        {" +
                               "            var a : 1" +
                               "            var b : 2" +
                               "            var a : 1" +
                               "        }" +
                               "    }" +
                               "}";

            var lexer = new Lexer.Lexer();
            var tokens = lexer.Lex(src);
            var parser = new Parser.Parser(tokens);

            var ast = parser.Parse();

            var binder = new Binder();
            Assert.That(
                () => binder.Bind(new List<CompilationUnitSyntax> { ast }),
                Throws.TypeOf<KiwiSemanticException>().With.Message.EqualTo("a already defined."));
        }
Beispiel #47
0
        public void Test_ArrayAccessInvalidParameter_Throws()
        {
            const string src = "namespace MyNamespace" +
                               "{" +
                               "    class MyClass" +
                               "    {" +
                               "        func Add(int a, int b)" +
                               "        {   " +
                               "            var c : new int[1][1]" +
                               "            var d : c[1]" +
                               "        }" +
                               "    }" +
                               "}";

            var lexer = new Lexer.Lexer();
            var tokens = lexer.Lex(src);
            var parser = new Parser.Parser(tokens);

            var ast = parser.Parse();

            var binder = new Binder();

            Assert.That(
                () => binder.Bind(new List<CompilationUnitSyntax>() { ast }),
                Throws.InstanceOf<KiwiSemanticException>()
                      .With.Message.EqualTo("Parameter count (1) must match array dimension count (2)"));
        }
Beispiel #48
0
        public void Test_MemberAccessExpressionBinding()
        {
            const string src = "namespace MyNamespace" +
                               "{" +
                               "    class MyClass" +
                               "    {" +
                               "        func Add(int a, int b) -> return a * b" +
                               "    }" +
                               "" +
                               "    class MyClass2" +
                               "    {" +
                               "        var addMethod : new MyClass().Add" +
                               "    }" +
                               "}";

            var lexer = new Lexer.Lexer();
            var tokens = lexer.Lex(src);
            var parser = new Parser.Parser(tokens);

            var ast = parser.Parse();

            var binder = new Binder();

            var boundCompilationUnit = binder.Bind(new List<CompilationUnitSyntax>() { ast }).Single();
            var function =
                boundCompilationUnit.Namespaces[0].Types.Single(x => x.Name == "MyClass")
                                                  .Functions.Single(x => x.Name == "Add");
            var field =
                boundCompilationUnit.Namespaces[0].Types.Single(x => x.Name == "MyClass2")
                                                  .Fields.Single(x => x.Name == "addMethod");
            Assert.That(
                () => field.Type,
                Is.InstanceOf<FunctionCompilerGeneratedType>()
                  .And.Property("ReturnType")
                  .InstanceOf<IntCompilerGeneratedType>());
            CollectionAssert.AllItemsAreInstancesOfType(
                ((FunctionCompilerGeneratedType)field.Type).ParameterTypes,
                typeof(IntCompilerGeneratedType));
        }
Beispiel #49
0
        public void Test_Optional()
        {
            const string src = "namespace MyNamespace" +
                               "{" +
                               "    class Class" +
                               "    {" +
                               "        Constructor(Optional!(int) i, Optional!(string) s)" +
                               "        {" +
                               "        }" +
                               "    }" +
                               "}";

            var lexer = new Lexer.Lexer();
            var tokens = lexer.Lex(src);
            var parser = new Parser.Parser(tokens);

            Assert.DoesNotThrow(() => parser.Parse());
        }
Beispiel #50
0
        public void Test_ObjectCreationExpression_ThrowsNoConstructorWithoutArguments()
        {
            const string src = "namespace MyNamespace" +
                               "{" +
                               "    class MyClass" +
                               "    {" +
                               "        Constructor(int a){}" +
                               "    }" +
                               "    class MyClass2" +
                               "    {" +
                               "        func Foo()" +
                               "        {" +
                               "            var a : new MyClass()" +
                               "        }" +
                               "    }" +
                               "}";

            var lexer = new Lexer.Lexer();
            var tokens = lexer.Lex(src);
            var parser = new Parser.Parser(tokens);

            var ast = parser.Parse();

            var binder = new Binder();

            Assert.That(
                () => binder.Bind(new List<CompilationUnitSyntax>() { ast }),
                Throws.InstanceOf<KiwiSemanticException>()
                      .With.Message.EqualTo("MyNamespace.MyClass has no constructor without arguments."));
        }
Beispiel #51
0
        public void Test_Infix_NamespaceLevel()
        {
            const string src = "namespace MyNamespace" +
                               "{" +
                               "    infix func Add(int a, int b) -> return a + b" +
                               "    class MyClass2" +
                               "    {" +
                               "        func Foo()" +
                               "        {" +
                               "            var a : 1 Add 2" +
                               "        }" +
                               "    }" +
                               "}";

            var lexer = new Lexer.Lexer();
            var tokens = lexer.Lex(src);
            var parser = new Parser.Parser(tokens);

            var ast = parser.Parse();
            var namespaceSyntax = ast.Namespaces.Single(x => x.Name.Value == "MyNamespace");
            var infixFunction = namespaceSyntax.Functions.Single(x=>x.Name.Value == "Add");
            Assert.IsInstanceOf<InfixFunctionSyntax>(infixFunction);
        }
Beispiel #52
0
        public void Test_Operator_FunctionMapping()
        {
            const string src = "namespace MyNamespace" +
                               "{" +
                               "    class MyClass2" +
                               "    {" +
                               "        operator Add(MyClass2 opA, MyClass2 opB) -> return new MyClass2()" +
                               "        operator Sub(MyClass2 opA, MyClass2 opB) -> return new MyClass2()" +
                               "        operator Mult(MyClass2 opA, MyClass2 opB) -> return new MyClass2()" +
                               "        operator Div(MyClass2 opA, MyClass2 opB) -> return new MyClass2()" +
                               "        operator Pow(MyClass2 opA, MyClass2 opB) -> return new MyClass2()" +
                               "        operator Range(MyClass2 opA, MyClass2 opB) -> return new MyClass2[1]" +
                               "        operator In(MyClass2 opA, MyClass2 opB) -> return true" +
                               "    }" +
                               "    " +
                               "    class TestClass" +
                               "    {" +
                               "        func TestBinaryFunc()" +
                               "        {" +
                               "            var instance : new MyClass2()" +
                               "            var testAdd : instance + new MyClass2()" +
                               "            var testSub : instance - new MyClass2()" +
                               "            var testMult : instance * new MyClass2()" +
                               "            var testDiv : instance / new MyClass2()" +
                               "            var testPow : instance ^ new MyClass2()" +
                               "            var testRange : instance..newMyClass2()" +
                               "            var testIn : instance in new myClass2[10]" +
                               "        }" +
                               "" +
                               "" +
                               "        func TestAssignFunc()" +
                               "        {" +
                               "            var instance : None MyClass2" +
                               "            instance +: new MyClass2()" +
                               "            instance -: new MyClass2()" +
                               "            instance *: new MyClass2()" +
                               "            instance ^: new MyClass2()" +
                               "            instance /: new MyClass2()" +
                               "        }" +
                               "    }" +
                               "}";

            var lexer = new Lexer.Lexer();
            var tokens = lexer.Lex(src);
            var parser = new Parser.Parser(tokens);

            var ast = parser.Parse();
            var binder = new Binder();
            var boundCompilationUnit = binder.Bind(new List<CompilationUnitSyntax>() { ast }).Single();

            var boundNamespace = boundCompilationUnit.Namespaces.Single(x=>x.Name== "MyNamespace");
            var operatorClass = boundNamespace.Types.Single(x=>x.Name== "MyClass2");
            var testClass = boundNamespace.Types.Single(x=>x.Name == "TestClass");
            var testBinaryFunc = testClass.Functions.Single(x=>x.Name== "TestBinaryFunc");
            var testAssignFunc = testClass.Functions.Single(x=>x.Name== "TestAssignFunc");
        }
Beispiel #53
0
        public void Test_GenericFunction_NamespaceLevel()
        {
            const string src = "namespace MyNamespace" +
                               "{" +
                               "    func GenericFunction!(TypeA, TypeB)(TypeA a, TypeB b)" +
                               "    {" +
                               "    }" +
                               "}";

            var lexer = new Lexer.Lexer();
            var tokens = lexer.Lex(src);
            var parser = new Parser.Parser(tokens);

            Assert.DoesNotThrow(() => parser.Parse());
        }
Beispiel #54
0
        public void Test_RecursivExpressionFunction_DoesThrow()
        {
            const string src = "namespace MyNamespace" +
                               "{" +
                               "    class MyClass" +
                               "    {" +
                               "        func Add(int a, int b) -> return Add(1, 2)" +
                               "    }" +
                               "" +
                               "}";

            var lexer = new Lexer.Lexer();
            var tokens = lexer.Lex(src);
            var parser = new Parser.Parser(tokens);

            var ast = parser.Parse();

            var binder = new Binder();

            Assert.That(
                () => binder.Bind(new List<CompilationUnitSyntax>() { ast }),
                Throws.InstanceOf<KiwiSemanticException>().With.Message.EqualTo("Add Type cannot be inferred"));
        }
Beispiel #55
0
        public void Test_GenericClass()
        {
            const string src = "namespace MyNamespace" +
                               "{" +
                               "    class GenericClass(TypeA, TypeB)" +
                               "    {" +
                               "        var mutable1 : None TypeA;" +
                               "        var mutable2 : None TypeB;" +
                               "        Constructor(TypeA arg1, TypeB arg2)" +
                               "        {" +
                               "            mutable1 : arg1;" +
                               "            mutable2 : arg2;" +
                               "        }" +
                               "    }" +
                               "}";

            var lexer = new Lexer.Lexer();
            var tokens = lexer.Lex(src);
            var parser = new Parser.Parser(tokens);

            Assert.DoesNotThrow(() => parser.Parse());
        }
Beispiel #56
0
        public void Test_Scope_VariableNotDefined()
        {
            const string src = "namespace MyNamespace" +
                               "{" +
                               "    class MyClass" +
                               "    {" +
                               "        func Add(int a, int b) " +
                               "        { " +
                               "            {" +
                               "                var i : 1337 + b" +
                               "            }" +
                               "            var c : a * b * i" +
                               "        }" +
                               "    }" +
                               "" +
                               "}";

            var lexer = new Lexer.Lexer();
            var tokens = lexer.Lex(src);
            var parser = new Parser.Parser(tokens);

            var ast = parser.Parse();

            var binder = new Binder();

            Assert.That(
                () => binder.Bind(new List<CompilationUnitSyntax>() { ast }),
                Throws.InstanceOf<KiwiSemanticException>().With.Message.EqualTo("i not defined"));
        }
Beispiel #57
0
        public void Test_Function_VisibilityModifiers(string code)
        {
            const string template = "namespace MyNamespace" +
                                    "{{" +
                                    "    class MyClass" +
                                    "    {{" +
                                    "        {0}" +
                                    "    }}" +
                                    "}}";

            var parserFunc = new Action<string>(
                opSrc =>
                {
                    var lexer = new Lexer.Lexer();
                    var tokens = lexer.Lex(string.Format(template, opSrc));
                    var parser = new Parser.Parser(tokens);
                    parser.Parse();
                });

            Assert.That(() => parserFunc(code), Throws.Nothing);
        }
Beispiel #58
0
        public void Test_SwitchStatement_CasesTypeMustMatchSwitchConditionType()
        {
            const string src = "namespace MyNamespace" +
                               "{" +
                               "    class MyClass" +
                               "    {" +
                               "        func Add(int a, int b) " +
                               "        { " +
                               "            switch(a)" +
                               "            {" +
                               "                case \"LOL\" -> Add(1, 0)" +
                               "            }" +
                               "        }" +
                               "    }" +
                               "" +
                               "}";

            var lexer = new Lexer.Lexer();
            var tokens = lexer.Lex(src);
            var parser = new Parser.Parser(tokens);

            var ast = parser.Parse();

            var binder = new Binder();

            Assert.That(
                () => binder.Bind(new List<CompilationUnitSyntax>() { ast }),
                Throws.InstanceOf<KiwiSemanticException>()
                      .With.Message.EqualTo("Switch cases condition type must match switch condition type"));
        }
Beispiel #59
0
        public void Test_IfElseExpression_IfTrueIfFalseTypeMustBeEqual()
        {
            const string src = "namespace MyNamespace" +
                               "{" +
                               "    class MyClass" +
                               "    {" +
                               "        func Add(int a, float b) -> return if(true) a else b" +
                               "    }" +
                               "" +
                               "}";

            var lexer = new Lexer.Lexer();
            var tokens = lexer.Lex(src);
            var parser = new Parser.Parser(tokens);

            var ast = parser.Parse();

            var binder = new Binder();

            Assert.That(
                () => binder.Bind(new List<CompilationUnitSyntax>() { ast }),
                Throws.InstanceOf<KiwiSemanticException>()
                      .With.Message.EqualTo("IfTrue and IfFalse expression Type must match"));
        }
Beispiel #60
0
        public void TestExpressions(string statementSource, Type type)
        {
            var lexer = new Lexer.Lexer();
            var tokens =
                lexer.Lex(
                    string.Format(
                        NamespaceSource,
                        string.Format(
                            ClassSource,
                            string.Format(FunctionSource, statementSource),
                            string.Empty,
                            string.Empty)));
            var parser = new Parser.Parser(tokens);

            var ast = parser.Parse();
            Assert.IsInstanceOf(
                type,
                ((ReturnStatementSyntax)((ScopeStatementSyntax)ast.Namespaces[0].Classes[0].Functions[0].Statements).Statements[0]).Expression);
        }