static void Main(string[] args)
        {
            Commands cmd;

            try {
                cmd = ParseArgs(args);
            } catch (UnexpectedEndOfArgsException e) {
                Console.Error.WriteLine(e.ToString());
                Help();
                return;
            } catch (Exception e) {
                Console.Error.WriteLine(e.Message);
                Help();
                return;
            }

            if (cmd.NeedHelp)
            {
                Help();
                return;
            }

            if (!cmd.InputFile.EndsWith(".rbl"))
            {
                Console.Error.WriteLine("rbc expect files ends with .rbl");
                return;
            }

            try {
                cmd.InputFileStream = new FileStream(cmd.InputFile, FileMode.Open);
            } catch (Exception e) {
                Console.Error.WriteLine(
                    $"rbc thrown an exception when opening file: {cmd.InputFile}");
                Console.Error.WriteLine(e.Message);
                return;
            }

            cmd.OutputFileStream = new FileStream(cmd.OutputFile, FileMode.OpenOrCreate);
            var logger = Logger.GetByName("rbc-dev.log");

            logger.CopyToStdout = true;
            var lexer  = new RbLexer(cmd.InputFileStream);
            var parser = new RbParser(lexer);
            var codes  = parser.Parse();

            if (parser.HasError)
            {
                return;
            }

            var _generator = new ClrIlGenerator(cmd, (CodeBlockAstNode)codes);

            _generator.Check();
        }
 public void TestParseAst2()
 {
     using var sourceStream = new FileStream("TestCode/TestParse2.rbl",
                                             FileMode.Open);
     ILanguageLexer  lexer       = new RbLexer(sourceStream);
     ILanguageParser parser      = new RbParser(lexer);
     var             actualAst   = parser.Parse();
     var             expectedAst = new CodeBlockAstNode(new BasicAstNode[] {
         new FunctionAstNode(
             new FunctionPrototypeAstNode(new FunctionParameter[] {
             new("i64", "i")
         }, "EatInt", "void", null),
        public void TestParseAst1()
        {
            using var sourceStream = new FileStream("TestCode/TestParse1.rbl",
                                                    FileMode.Open);
            ILanguageLexer  lexer       = new RbLexer(sourceStream);
            ILanguageParser parser      = new RbParser(lexer);
            var             actualAst   = parser.Parse();
            var             expectedAst = new CodeBlockAstNode(new BasicAstNode[] {
                new FunctionAstNode(
                    new FunctionPrototypeAstNode(
                        new[] {
                    new FunctionParameter("str", "s")
                }, "WriteLine", "void", new[] { "@import" }
                        ), null
                    ),
                new VariableDefineAstNode("str", "greeting",
                                          new StringAstNode("\"Hello world!\\nI'm running on CLR!\"")),
                new FunctionAstNode(
                    new FunctionPrototypeAstNode(
                        new[] {
                    new FunctionParameter("i64", "n")
                }, "fib", "i64", null
                        ), new CodeBlockAstNode(
                        new BasicAstNode[] {
                    new IfElseAstNode(
                        new BinaryOperatorAstNode("==",
                                                  new IdentifierAstNode("n"),
                                                  new IntegerAstNode(1)),
                        new CodeBlockAstNode(new BasicAstNode[] {
                        new ReturnAstNode(new IntegerAstNode(1))
                    }), null
                        ),
                    new ReturnAstNode(new BinaryOperatorAstNode("*",
                                                                new IdentifierAstNode("n"),
                                                                new FunctionCallingAstNode("fib", new BasicAstNode[] {
                        new BinaryOperatorAstNode("-",
                                                  new IdentifierAstNode("n"), new IntegerAstNode(1))
                    })
                                                                ))
                }
                        )
                    ),
                new FunctionAstNode(
                    new FunctionPrototypeAstNode(
                        new[] {
                    new FunctionParameter("str", "s")
                }, "foo", "i64", null
                        ), new CodeBlockAstNode(new BasicAstNode[] {
                    new FunctionCallingAstNode("WriteLine",
                                               new BasicAstNode[] { new IdentifierAstNode("s") }),
                    new VariableDefineAstNode("i64", "isNull",
                                              new BinaryOperatorAstNode("+",
                                                                        new IntegerAstNode(10),
                                                                        new UnaryOperatorAstNode("not",
                                                                                                 new UnaryOperatorAstNode("address_of",
                                                                                                                          new IdentifierAstNode("s")
                                                                                                                          )
                                                                                                 )
                                                                        )
                                              ),
                    new ReturnAstNode(
                        new FunctionCallingAstNode("fib", new BasicAstNode[] {
                        new IntegerAstNode(10)
                    }))
                })
                    ),
                new FunctionCallingAstNode("foo", new BasicAstNode[] {
                    new IdentifierAstNode("greeting")
                })
            });
            var tester = new TestAstHelper(expectedAst, actualAst);

            tester.Test();
        }