예제 #1
0
        public void ExampleProgramIsTokenizedCorrectly()
        {
            var reporter = new ErrorReporter();
            var lexer = new Lexer(@"..\..\example_program.txt", reporter, 8);
            TokenHelper(lexer, new PrintToken(), 0, 0);
            TokenHelper(lexer, new TextToken("Give a number"), 0, 6);
            TokenHelper(lexer, new SemicolonToken(), 0, 21);

            TokenHelper(lexer, new VarToken(), 1, 0);
            TokenHelper(lexer, new IdentifierToken("n"), 1, 4);
            TokenHelper(lexer, new ColonToken(), 1, 6);
            TokenHelper(lexer, new IntToken(), 1, 8);
            TokenHelper(lexer, new SemicolonToken(), 1, 11);

            TokenHelper(lexer, new ReadToken(), 2, 0);
            TokenHelper(lexer, new IdentifierToken("n"), 2, 5);
            TokenHelper(lexer, new SemicolonToken(), 2, 6);

            TokenHelper(lexer, new VarToken(), 3, 0);
            TokenHelper(lexer, new IdentifierToken("v"), 3, 4);
            TokenHelper(lexer, new ColonToken(), 3, 6);
            TokenHelper(lexer, new IntToken(), 3, 8);
            TokenHelper(lexer, new AssignmentToken(), 3, 12);
            TokenHelper(lexer, new NumberToken(1), 3, 15);
            TokenHelper(lexer, new SemicolonToken(), 3, 16);

            TokenHelper(lexer, new VarToken(), 4, 0);
            TokenHelper(lexer, new IdentifierToken("i"), 4, 4);
            TokenHelper(lexer, new ColonToken(), 4, 6);
            TokenHelper(lexer, new IntToken(), 4, 8);
            TokenHelper(lexer, new SemicolonToken(), 4, 11);

            TokenHelper(lexer, new ForToken(), 5, 0);
            TokenHelper(lexer, new IdentifierToken("i"), 5, 4);
            TokenHelper(lexer, new InToken(), 5, 6);
            TokenHelper(lexer, new NumberToken(1), 5, 9);
            TokenHelper(lexer, new RangeToken(), 5, 10);
            TokenHelper(lexer, new IdentifierToken("n"), 5, 12);
            TokenHelper(lexer, new DoToken(), 5, 14);

            TokenHelper(lexer, new IdentifierToken("v"), 6, 8);
            TokenHelper(lexer, new AssignmentToken(), 6, 10);
            TokenHelper(lexer, new IdentifierToken("v"), 6, 13);
            TokenHelper(lexer, new MultiplyToken(), 6, 15);
            TokenHelper(lexer, new IdentifierToken("i"), 6, 17);
            TokenHelper(lexer, new SemicolonToken(), 6, 18);

            TokenHelper(lexer, new EndToken(), 7, 0);
            TokenHelper(lexer, new ForToken(), 7, 4);
            TokenHelper(lexer, new SemicolonToken(), 7, 7);

            TokenHelper(lexer, new PrintToken(), 8, 0);
            TokenHelper(lexer, new TextToken("The result is: "), 8, 6);
            TokenHelper(lexer, new SemicolonToken(), 8, 23);

            TokenHelper(lexer, new PrintToken(), 9, 0);
            TokenHelper(lexer, new IdentifierToken("v"), 9, 6);
            TokenHelper(lexer, new SemicolonToken(), 9, 7);
            Assert.AreEqual(0, reporter.Errors.Count);
        }
        internal OperatorScanner(TextReader reader, ErrorReporter reporter)
            : base(reader, reporter)
        {
            twoCharacterOperators = new Dictionary<char, IDictionary<char, Type>>();
            twoCharacterOperators[':'] = new Dictionary<char, Type>();
            twoCharacterOperators[':']['='] = typeof(AssignmentToken);

            twoCharacterOperators['.'] = new Dictionary<char, Type>();
            twoCharacterOperators['.']['.'] = typeof(RangeToken);

            singleCharacterOperators = new Dictionary<char, Type>();

            singleCharacterOperators.Add('+', typeof(PlusToken));
            singleCharacterOperators.Add('-', typeof(MinusToken));
            singleCharacterOperators.Add('*', typeof(MultiplyToken));
            singleCharacterOperators.Add('/', typeof(DivideToken));
            singleCharacterOperators.Add('<', typeof(LessThanToken));
            singleCharacterOperators.Add('=', typeof(ComparisonToken));
            singleCharacterOperators.Add('&', typeof(AndToken));
            singleCharacterOperators.Add('!', typeof(NotToken));
            singleCharacterOperators.Add(';', typeof(SemicolonToken));
            singleCharacterOperators.Add(':', typeof(ColonToken));
            singleCharacterOperators.Add('(', typeof(LParenToken));
            singleCharacterOperators.Add(')', typeof(RParenToken));
        }
 internal WhitespaceScanner(TextReader reader, ErrorReporter reporter)
     : base(reader, reporter)
 {
     whitespace = new HashSet<char>();
     whitespace.Add(' ');
     whitespace.Add('\t');
     whitespace.Add('\n');
 }
예제 #4
0
        public void ParserParsesInvalidAssertStatement()
        {
            var reporter = new ErrorReporter();
            var parser = new Parser(
                new Lexer("../../Parsing/invalid_assert_statement.txt", reporter),
                reporter);

            var node = parser.Parse();

            ASTPreOrderMatches(
                node,
                new List<Node>{
                    new StatementsNode(0, 0),

                    new ErrorNode(),
                    new ErrorNode(),
                    new ErrorNode(),
                    new ErrorNode(),
                    new ErrorNode(),
                });

            Assert.AreEqual(5, reporter.Errors.Count);

            Assert.AreEqual(Error.SYNTAX_ERROR, reporter.Errors[0].Type);
            Assert.AreEqual(0, reporter.Errors[0].Line);
            Assert.AreEqual(7, reporter.Errors[0].Column);
            Assert.IsTrue(reporter.Errors[0].Message.ToLower().Contains("unexpected token <keyword - 'read'>"));

            Assert.AreEqual(Error.SYNTAX_ERROR, reporter.Errors[1].Type);
            Assert.AreEqual(1, reporter.Errors[1].Line);
            Assert.AreEqual(7, reporter.Errors[1].Column);
            Assert.IsTrue(reporter.Errors[1].Message.ToLower().Contains("expected token <operator - '('> but was <number - '4'>"));

            Assert.AreEqual(Error.SYNTAX_ERROR, reporter.Errors[2].Type);
            Assert.AreEqual(2, reporter.Errors[2].Line);
            Assert.AreEqual(9, reporter.Errors[2].Column);
            Assert.IsTrue(reporter.Errors[2].Message.ToLower().Contains("unexpected token <operator - ':='>"));

            Assert.AreEqual(Error.SYNTAX_ERROR, reporter.Errors[3].Type);
            Assert.AreEqual(3, reporter.Errors[3].Line);
            Assert.AreEqual(6, reporter.Errors[3].Column);
            Assert.IsTrue(reporter.Errors[3].Message.ToLower().Contains("expected token <operator - '('>"));

            Assert.AreEqual(Error.SYNTAX_ERROR, reporter.Errors[4].Type);
            Assert.AreEqual(4, reporter.Errors[4].Line);
            Assert.AreEqual(7, reporter.Errors[4].Column);
            Assert.IsTrue(reporter.Errors[4].Message.ToLower().Contains("unexpected token <keyword - 'assert'>"));
        }
예제 #5
0
        public Lexer(string path, ErrorReporter reporter, int spacesPerTab=8)
        {
            reader = new TextReader(path, spacesPerTab);
            this.reporter = reporter;
            reporter.Lines = reader.Lines;

            backtrackBuffer = new BacktrackBuffer(BACKTRACK_BUFFER_SIZE);

            scanners = new List<TokenScanner>();
            scanners.Add(new WhitespaceScanner(reader, reporter));
            scanners.Add(new CommentScanner(reader, reporter));
            scanners.Add(new IdentifierAndKeywordScanner(reader, reporter));
            scanners.Add(new IntegerScanner(reader, reporter));
            scanners.Add(new StringScanner(reader, reporter));
            scanners.Add(new OperatorScanner(reader, reporter));
        }
        internal IdentifierAndKeywordScanner(TextReader reader, ErrorReporter reporter)
            : base(reader, reporter)
        {
            keywords = new Dictionary<string, Type>();

            keywords.Add("var", typeof(VarToken));
            keywords.Add("for", typeof(ForToken));
            keywords.Add("end", typeof(EndToken));
            keywords.Add("in", typeof(InToken));
            keywords.Add("do", typeof(DoToken));
            keywords.Add("read", typeof(ReadToken));
            keywords.Add("print", typeof(PrintToken));
            keywords.Add("int", typeof(IntToken));
            keywords.Add("string", typeof(StringToken));
            keywords.Add("bool", typeof(BoolToken));
            keywords.Add("assert", typeof(AssertToken));
        }
예제 #7
0
        public void ExampleProgram2IsTokenizedCorrectly()
        {
            var reporter = new ErrorReporter();
            var lexer = new Lexer(@"..\..\example_program2.txt", reporter, 8);
            TokenHelper(lexer, new VarToken(), 0, 0);
            TokenHelper(lexer, new IdentifierToken("X"), 0, 4);
            TokenHelper(lexer, new ColonToken(), 0, 6);
            TokenHelper(lexer, new IntToken(), 0, 8);
            TokenHelper(lexer, new AssignmentToken(), 0, 12);
            TokenHelper(lexer, new NumberToken(4), 0, 15);
            TokenHelper(lexer, new PlusToken(), 0, 17);
            TokenHelper(lexer, new LParenToken(), 0, 19);
            TokenHelper(lexer, new NumberToken(6), 0, 20);
            TokenHelper(lexer, new MultiplyToken(), 0, 22);
            TokenHelper(lexer, new NumberToken(2), 0, 24);
            TokenHelper(lexer, new RParenToken(), 0, 25);
            TokenHelper(lexer, new SemicolonToken(), 0, 26);

            TokenHelper(lexer, new PrintToken(), 1, 0);
            TokenHelper(lexer, new IdentifierToken("X"), 1, 6);
            TokenHelper(lexer, new SemicolonToken(), 1, 7);
            Assert.AreEqual(0, reporter.Errors.Count);
        }
예제 #8
0
        public void EmptyProgramIsError()
        {
            var reporter = new ErrorReporter();
            var parser = new Parser(
                new Lexer("../../empty.txt", reporter),
                reporter);

            var node = parser.Parse();

            ASTPreOrderMatches(
               node,
               new List<Node>{
                    new StatementsNode(0, 0),
                    new ErrorNode(),
               });

            Assert.AreEqual(1, reporter.Errors.Count);

            Assert.AreEqual(Error.SYNTAX_ERROR, reporter.Errors[0].Type);
            Assert.AreEqual(0, reporter.Errors[0].Line);
            Assert.AreEqual(0, reporter.Errors[0].Column);
            Assert.IsTrue(reporter.Errors[0].Message.ToLower().Contains("program must contain at least a single statement"));
        }
예제 #9
0
        public void GetTokensHandlesIntegers()
        {
            var reporter = new ErrorReporter();
            var lexer = new Lexer(@"..\..\Lexing\valid_integers.txt", reporter);

            Assert.AreEqual(new NumberToken(123), lexer.NextToken());
            Assert.AreEqual(new NumberToken(0), lexer.NextToken());
            Assert.AreEqual(new NumberToken(9876543210), lexer.NextToken());
            Assert.AreEqual(0, reporter.Errors.Count);
        }
예제 #10
0
 public void GetTokenReturnsEOFOnEndOfFile()
 {
     var reporter = new ErrorReporter();
     var lexer = new Lexer(@"..\..\empty.txt", reporter);
     Assert.AreEqual(new EOFToken(), lexer.NextToken());
     Assert.AreEqual(0, reporter.Errors.Count);
 }
예제 #11
0
        public void GetTokenSetsLineAndColumnCorrectlyWith8SpacesPerTab()
        {
            var reporter = new ErrorReporter();
            var lexer = new Lexer(@"..\..\Lexing\line_and_column.txt", reporter, 8);

            Token token;

            token = lexer.NextToken();
            Assert.AreEqual(0, token.Line);
            Assert.AreEqual(0, token.Column);

            token = lexer.NextToken();
            Assert.AreEqual(0, token.Line);
            Assert.AreEqual(6, token.Column);

            token = lexer.NextToken();
            Assert.AreEqual(2, token.Line);
            Assert.AreEqual(0, token.Column);

            token = lexer.NextToken();
            Assert.AreEqual(4, token.Line);
            Assert.AreEqual(8, token.Column);

            token = lexer.NextToken();
            Assert.AreEqual(5, token.Line);
            Assert.AreEqual(16, token.Column);

            token = lexer.NextToken();
            Assert.AreEqual(7, token.Line);
            Assert.AreEqual(8, token.Column);

            token = lexer.NextToken();
            Assert.AreEqual(8, token.Line);
            Assert.AreEqual(8, token.Column);
            Assert.AreEqual(0, reporter.Errors.Count);
        }
예제 #12
0
        public void ReadStatementGeneratesCorrectCode()
        {
            var reporter = new ErrorReporter();
            var parser = new Parser(
                new Lexer("../../CodeGen/read_statement.txt", reporter),
                reporter);

            var node = parser.Parse();

            var semanticChecker = new SemanticChecker(reporter);

            node.Accept(semanticChecker);

            Assert.AreEqual(0, reporter.Errors.Count);

            var codeGenerator = new CodeGenerator(semanticChecker.SymbolTable, semanticChecker.Variables);
            node.Accept(codeGenerator);

            var bytecode = codeGenerator.Bytecodes;

            Assert.AreEqual(34, bytecode.Length);

            Assert.AreEqual(Bytecode.PUSH_INT, bytecode[0]);
            Assert.AreEqual(0, GetLongValue(bytecode, 1));
            Assert.AreEqual(Bytecode.STORE_VARIABLE, bytecode[9]);
            Assert.AreEqual(0, GetIntValue(bytecode, 10));

            Assert.AreEqual(Bytecode.PUSH_STRING, bytecode[14]);
            Assert.AreEqual(0, GetIntValue(bytecode, 15));
            Assert.AreEqual(Bytecode.STORE_VARIABLE, bytecode[19]);
            Assert.AreEqual(1, GetIntValue(bytecode, 20));

            Assert.AreEqual(Bytecode.READ_INT, bytecode[24]);
            Assert.AreEqual(0, GetIntValue(bytecode, 25));

            Assert.AreEqual(Bytecode.READ_STRING, bytecode[29]);
            Assert.AreEqual(1, GetIntValue(bytecode, 30));
        }
예제 #13
0
        public void GetTokenParsesOperatorsCorrectly()
        {
            var reporter = new ErrorReporter();
            var lexer = new Lexer(@"..\..\Lexing\operators.txt", reporter);

            Assert.AreEqual(new PlusToken(), lexer.NextToken());
            Assert.AreEqual(new MinusToken(), lexer.NextToken());
            Assert.AreEqual(new MultiplyToken(), lexer.NextToken());
            Assert.AreEqual(new DivideToken(), lexer.NextToken());
            Assert.AreEqual(new AssignmentToken(), lexer.NextToken());
            Assert.AreEqual(new LessThanToken(), lexer.NextToken());
            Assert.AreEqual(new ComparisonToken(), lexer.NextToken());
            Assert.AreEqual(new AndToken(), lexer.NextToken());
            Assert.AreEqual(new NotToken(), lexer.NextToken());
            Assert.AreEqual(new SemicolonToken(), lexer.NextToken());
            Assert.AreEqual(new ColonToken(), lexer.NextToken());
            Assert.AreEqual(new RangeToken(), lexer.NextToken());
            Assert.AreEqual(new LParenToken(), lexer.NextToken());
            Assert.AreEqual(new RParenToken(), lexer.NextToken());
            Assert.AreEqual(0, reporter.Errors.Count);
        }
예제 #14
0
        public void LexerPeekingWorksWithBacktracking()
        {
            var reporter = new ErrorReporter();
            var lexer = new Lexer(@"..\..\example_program.txt", reporter);

            lexer.NextToken();
            lexer.NextToken();
            lexer.NextToken();
            Assert.AreEqual(new VarToken(), lexer.PeekToken());

            lexer.Backtrack();
            Assert.AreEqual(new SemicolonToken(), lexer.PeekToken());
            Assert.AreEqual(new SemicolonToken(), lexer.NextToken());
            Assert.AreEqual(new VarToken(), lexer.PeekToken());
            Assert.AreEqual(new VarToken(), lexer.PeekToken());
            lexer.Backtrack();
            lexer.Backtrack();

            Assert.AreEqual(new TextToken("Give a number"), lexer.PeekToken());
            Assert.AreEqual(new TextToken("Give a number"), lexer.NextToken());
            Assert.AreEqual(0, reporter.Errors.Count);
        }
예제 #15
0
        public void VariableAssignmentGeneratesCorrectCode()
        {
            var reporter = new ErrorReporter();
            var parser = new Parser(
                new Lexer("../../CodeGen/variable_assignment.txt", reporter),
                reporter);

            var node = parser.Parse();

            var semanticChecker = new SemanticChecker(reporter);

            node.Accept(semanticChecker);

            Assert.AreEqual(0, reporter.Errors.Count);

            var codeGenerator = new CodeGenerator(semanticChecker.SymbolTable, semanticChecker.Variables);
            node.Accept(codeGenerator);

            var bytecode = codeGenerator.Bytecodes;
            Assert.AreEqual(99, bytecode.Length);

            Assert.AreEqual(Bytecode.PUSH_INT, bytecode[0]);
            Assert.AreEqual(0, GetLongValue(bytecode, 1));
            Assert.AreEqual(Bytecode.STORE_VARIABLE, bytecode[9]);
            Assert.AreEqual(0, GetIntValue(bytecode, 10));

            Assert.AreEqual(Bytecode.PUSH_STRING, bytecode[14]);
            Assert.AreEqual(0, GetIntValue(bytecode, 15));
            Assert.AreEqual(Bytecode.STORE_VARIABLE, bytecode[19]);
            Assert.AreEqual(1, GetIntValue(bytecode, 20));

            Assert.AreEqual(Bytecode.PUSH_FALSE, bytecode[24]);
            Assert.AreEqual(Bytecode.STORE_VARIABLE, bytecode[25]);
            Assert.AreEqual(2, GetIntValue(bytecode, 26));

            Assert.AreEqual(Bytecode.PUSH_INT, bytecode[30]);
            Assert.AreEqual(4, GetLongValue(bytecode, 31));
            Assert.AreEqual(Bytecode.PUSH_INT_VAR, bytecode[39]);
            Assert.AreEqual(0, GetIntValue(bytecode, 40));
            Assert.AreEqual(Bytecode.MUL, bytecode[44]);
            Assert.AreEqual(Bytecode.STORE_VARIABLE, bytecode[45]);
            Assert.AreEqual(0, GetIntValue(bytecode, 46));

            Assert.AreEqual(Bytecode.PUSH_STRING_VAR, bytecode[50]);
            Assert.AreEqual(1, GetIntValue(bytecode, 51));
            Assert.AreEqual(Bytecode.PUSH_STRING, bytecode[55]);
            Assert.AreEqual(1, GetIntValue(bytecode, 56));
            Assert.AreEqual(Bytecode.CONCAT, bytecode[60]);
            Assert.AreEqual(Bytecode.STORE_VARIABLE, bytecode[61]);
            Assert.AreEqual(1, GetIntValue(bytecode, 62));

            Assert.AreEqual(Bytecode.PUSH_INT_VAR, bytecode[66]);
            Assert.AreEqual(0, GetIntValue(bytecode, 67));
            Assert.AreEqual(Bytecode.PUSH_INT, bytecode[71]);
            Assert.AreEqual(9876543210, GetLongValue(bytecode, 72));
            Assert.AreEqual(Bytecode.IS_LESS_INT, bytecode[80]);
            Assert.AreEqual(Bytecode.NOT, bytecode[81]);
            Assert.AreEqual(Bytecode.PUSH_STRING_VAR, bytecode[82]);
            Assert.AreEqual(1, GetIntValue(bytecode, 83));
            Assert.AreEqual(Bytecode.PUSH_STRING, bytecode[87]);
            Assert.AreEqual(2, GetIntValue(bytecode, 88));
            Assert.AreEqual(Bytecode.IS_EQUAL_STRING, bytecode[92]);
            Assert.AreEqual(Bytecode.AND, bytecode[93]);
            Assert.AreEqual(Bytecode.STORE_VARIABLE, bytecode[94]);
            Assert.AreEqual(2, GetIntValue(bytecode, 95));
        }
예제 #16
0
        public void GetTokensHandlesInvalidIntegers()
        {
            var reporter = new ErrorReporter();
            var lexer = new Lexer(@"..\..\Lexing\invalid_integers.txt", reporter);

            Assert.AreEqual(new NumberToken(567), lexer.NextToken());
            Assert.AreEqual(new IdentifierToken("Hello"), lexer.NextToken());
            Assert.AreEqual(new NumberToken(1), lexer.NextToken());

            Assert.AreEqual(2, reporter.Errors.Count);

            Assert.AreEqual(Error.LEXICAL_ERROR, reporter.Errors[0].Type);
            Assert.AreEqual(0, reporter.Errors[0].Line);
            Assert.AreEqual(3, reporter.Errors[0].Column);
            Assert.IsTrue(reporter.Errors[0].Message.ToLower().Contains("invalid character"));

            Assert.AreEqual(Error.LEXICAL_ERROR, reporter.Errors[1].Type);
            Assert.AreEqual(1, reporter.Errors[1].Line);
            Assert.AreEqual(0, reporter.Errors[1].Column);
            Assert.IsTrue(reporter.Errors[1].Message.ToLower().Contains("number does not fit"));
        }
예제 #17
0
        public void LexerBackTrackingThrowsIfCalledTooManyTimes()
        {
            var reporter = new ErrorReporter();
            var lexer = new Lexer(@"..\..\example_program.txt", reporter);

            Assert.AreEqual(new PrintToken(), lexer.NextToken());
            Assert.AreEqual(new TextToken("Give a number"), lexer.NextToken());
            Assert.AreEqual(new SemicolonToken(), lexer.NextToken());
            lexer.NextToken();

            for (int i = 0; i < Lexer.BACKTRACK_BUFFER_SIZE; ++i)
            {
                lexer.Backtrack();
            }

            bool throws = false;
            try
            {
               lexer.Backtrack();
            } catch (InternalCompilerError e)
            {
                throws = true;
            }

            Assert.IsTrue(throws);
            Assert.AreEqual(0, reporter.Errors.Count);
        }
예제 #18
0
        public void GetTokenHandlesReservedWords()
        {
            var reporter = new ErrorReporter();
            var lexer = new Lexer(@"..\..\Lexing\keywords.txt", reporter);

            Assert.AreEqual(new VarToken(), lexer.NextToken());
            Assert.AreEqual(new ForToken(), lexer.NextToken());
            Assert.AreEqual(new EndToken(), lexer.NextToken());
            Assert.AreEqual(new InToken(), lexer.NextToken());
            Assert.AreEqual(new DoToken(), lexer.NextToken());
            Assert.AreEqual(new ReadToken(), lexer.NextToken());
            Assert.AreEqual(new PrintToken(), lexer.NextToken());
            Assert.AreEqual(new IntToken(), lexer.NextToken());
            Assert.AreEqual(new StringToken(), lexer.NextToken());
            Assert.AreEqual(new BoolToken(), lexer.NextToken());
            Assert.AreEqual(new AssertToken(), lexer.NextToken());
            Assert.AreEqual(0, reporter.Errors.Count);
        }
예제 #19
0
        public void GetTokenHandlesInvalidStrings()
        {
            var reporter = new ErrorReporter();
            var lexer = new Lexer(@"..\..\Lexing\invalid_strings.txt", reporter);

            Assert.AreEqual(new TextToken("invaliddescape"), lexer.NextToken());
            Assert.AreEqual(new TextToken("unterminated"), lexer.NextToken());
            Assert.AreEqual(new TextToken("valid for checking unterminated"), lexer.NextToken());

            Assert.AreEqual(2, reporter.Errors.Count);

            Assert.AreEqual(Error.LEXICAL_ERROR, reporter.Errors[0].Type);
            Assert.AreEqual(0, reporter.Errors[0].Line);
            Assert.AreEqual(9, reporter.Errors[0].Column);
            Assert.IsTrue(reporter.Errors[0].Message.ToLower().Contains("invalid escape sequence"));

            Assert.AreEqual(Error.LEXICAL_ERROR, reporter.Errors[1].Type);
            Assert.AreEqual(1, reporter.Errors[1].Line);
            Assert.AreEqual(13, reporter.Errors[1].Column);
            Assert.IsTrue(reporter.Errors[1].Message.ToLower().Contains("unmatched"));
        }
예제 #20
0
        public void GetTokenHandlesIdentifiers()
        {
            var reporter = new ErrorReporter();
            var lexer = new Lexer(@"..\..\Lexing\valid_identifiers.txt", reporter);

            Assert.AreEqual(new IdentifierToken("hello"), lexer.NextToken());
            Assert.AreEqual(new IdentifierToken("w_or_ld"), lexer.NextToken());
            Assert.AreEqual(new IdentifierToken("this_"), lexer.NextToken());
            Assert.AreEqual(new IdentifierToken("i123s"), lexer.NextToken());
            Assert.AreEqual(new IdentifierToken("a987"), lexer.NextToken());
            Assert.AreEqual(new IdentifierToken("t_12_es_190t"), lexer.NextToken());
            Assert.AreEqual(0, reporter.Errors.Count);
        }
예제 #21
0
        public void ForLoopGeneratesCorrectCode()
        {
            var reporter = new ErrorReporter();
            var parser = new Parser(
                new Lexer("../../CodeGen/for_statement.txt", reporter),
                reporter);

            var node = parser.Parse();

            var semanticChecker = new SemanticChecker(reporter);

            node.Accept(semanticChecker);

            Assert.AreEqual(0, reporter.Errors.Count);

            var codeGenerator = new CodeGenerator(semanticChecker.SymbolTable, semanticChecker.Variables);
            node.Accept(codeGenerator);

            var bytecode = codeGenerator.Bytecodes;

            Assert.AreEqual(348, bytecode.Length);

            Assert.AreEqual(Bytecode.PUSH_INT, bytecode[0]);
            Assert.AreEqual(0, GetLongValue(bytecode, 1));
            Assert.AreEqual(Bytecode.STORE_VARIABLE, bytecode[9]);
            Assert.AreEqual(0, GetIntValue(bytecode, 10));

            Assert.AreEqual(Bytecode.PUSH_INT, bytecode[14]);
            Assert.AreEqual(0, GetLongValue(bytecode, 15));
            Assert.AreEqual(Bytecode.STORE_VARIABLE, bytecode[23]);
            Assert.AreEqual(1, GetIntValue(bytecode, 24));

            // loop counter initialization
            Assert.AreEqual(Bytecode.PUSH_INT, bytecode[28]);
            Assert.AreEqual(0, GetLongValue(bytecode, 29));
            Assert.AreEqual(Bytecode.STORE_VARIABLE, bytecode[37]);
            Assert.AreEqual(0, GetIntValue(bytecode, 38));
            // end variable initialization
            Assert.AreEqual(Bytecode.PUSH_INT, bytecode[42]);
            Assert.AreEqual(5, GetLongValue(bytecode, 43));
            Assert.AreEqual(Bytecode.STORE_VARIABLE, bytecode[51]);
            Assert.AreEqual(4, GetIntValue(bytecode, 52));
            // body
            Assert.AreEqual(Bytecode.PUSH_INT_VAR, bytecode[56]);
            Assert.AreEqual(0, GetIntValue(bytecode, 57));
            Assert.AreEqual(Bytecode.PUSH_INT_VAR, bytecode[61]);
            Assert.AreEqual(1, GetIntValue(bytecode, 62));
            Assert.AreEqual(Bytecode.ADD, bytecode[66]);
            Assert.AreEqual(Bytecode.STORE_VARIABLE, bytecode[67]);
            Assert.AreEqual(1, GetIntValue(bytecode, 68));
            // loop counter update
            Assert.AreEqual(Bytecode.PUSH_INT_VAR, bytecode[72]);
            Assert.AreEqual(0, GetIntValue(bytecode, 73));
            Assert.AreEqual(Bytecode.PUSH_INT, bytecode[77]);
            Assert.AreEqual(1, GetLongValue(bytecode, 78));
            Assert.AreEqual(Bytecode.ADD, bytecode[86]);
            Assert.AreEqual(Bytecode.STORE_VARIABLE, bytecode[87]);
            Assert.AreEqual(0, GetIntValue(bytecode, 88));
            // start - end comparison
            Assert.AreEqual(Bytecode.PUSH_INT_VAR, bytecode[92]);
            Assert.AreEqual(0, GetIntValue(bytecode, 93));
            Assert.AreEqual(Bytecode.PUSH_INT_VAR, bytecode[97]);
            Assert.AreEqual(4, GetIntValue(bytecode, 98));
            Assert.AreEqual(Bytecode.IS_LESS_OR_EQUAL_INT, bytecode[102]);
            // jump based on above
            Assert.AreEqual(Bytecode.JUMP_IF_TRUE, bytecode[103]);
            Assert.AreEqual(56, GetIntValue(bytecode, 104));

            // loop counter initialization
            Assert.AreEqual(Bytecode.PUSH_INT_VAR, bytecode[108]);
            Assert.AreEqual(1, GetIntValue(bytecode, 109));
            Assert.AreEqual(Bytecode.STORE_VARIABLE, bytecode[113]);
            Assert.AreEqual(0, GetIntValue(bytecode, 114));
            // end variable initialization
            Assert.AreEqual(Bytecode.PUSH_INT, bytecode[118]);
            Assert.AreEqual(3, GetLongValue(bytecode, 119));
            Assert.AreEqual(Bytecode.PUSH_INT_VAR, bytecode[127]);
            Assert.AreEqual(1, GetIntValue(bytecode, 128));
            Assert.AreEqual(Bytecode.MUL, bytecode[132]);
            Assert.AreEqual(Bytecode.STORE_VARIABLE, bytecode[133]);
            Assert.AreEqual(5, GetIntValue(bytecode, 134));
            // body
            Assert.AreEqual(Bytecode.PUSH_INT_VAR, bytecode[138]);
            Assert.AreEqual(0, GetIntValue(bytecode, 139));
            Assert.AreEqual(Bytecode.PUSH_INT_VAR, bytecode[143]);
            Assert.AreEqual(1, GetIntValue(bytecode, 144));
            Assert.AreEqual(Bytecode.ADD, bytecode[148]);
            Assert.AreEqual(Bytecode.STORE_VARIABLE, bytecode[149]);
            Assert.AreEqual(1, GetIntValue(bytecode, 150));
            Assert.AreEqual(Bytecode.PUSH_INT_VAR, bytecode[154]);
            Assert.AreEqual(0, GetIntValue(bytecode, 155));
            Assert.AreEqual(Bytecode.PUSH_INT_VAR, bytecode[159]);
            Assert.AreEqual(1, GetIntValue(bytecode, 160));
            Assert.AreEqual(Bytecode.IS_LESS_INT, bytecode[164]);
            Assert.AreEqual(Bytecode.STORE_VARIABLE, bytecode[165]);
            Assert.AreEqual(2, GetIntValue(bytecode, 166));
            // loop counter update
            Assert.AreEqual(Bytecode.PUSH_INT_VAR, bytecode[170]);
            Assert.AreEqual(0, GetIntValue(bytecode, 171));
            Assert.AreEqual(Bytecode.PUSH_INT, bytecode[175]);
            Assert.AreEqual(1, GetLongValue(bytecode, 176));
            Assert.AreEqual(Bytecode.ADD, bytecode[184]);
            Assert.AreEqual(Bytecode.STORE_VARIABLE, bytecode[185]);
            Assert.AreEqual(0, GetIntValue(bytecode, 186));
            // start - end comparison
            Assert.AreEqual(Bytecode.PUSH_INT_VAR, bytecode[190]);
            Assert.AreEqual(0, GetIntValue(bytecode, 191));
            Assert.AreEqual(Bytecode.PUSH_INT_VAR, bytecode[195]);
            Assert.AreEqual(5, GetIntValue(bytecode, 196));
            Assert.AreEqual(Bytecode.IS_LESS_OR_EQUAL_INT, bytecode[200]);
            // jump based on above
            Assert.AreEqual(Bytecode.JUMP_IF_TRUE, bytecode[201]);
            Assert.AreEqual(138, GetIntValue(bytecode, 202));

            // outer loop counter initialization
            Assert.AreEqual(Bytecode.PUSH_INT, bytecode[206]);
            Assert.AreEqual(0, GetLongValue(bytecode, 207));
            Assert.AreEqual(Bytecode.STORE_VARIABLE, bytecode[215]);
            Assert.AreEqual(0, GetIntValue(bytecode, 216));
            // outer end variable initialization
            Assert.AreEqual(Bytecode.PUSH_INT, bytecode[220]);
            Assert.AreEqual(20, GetLongValue(bytecode, 221));
            Assert.AreEqual(Bytecode.STORE_VARIABLE, bytecode[229]);
            Assert.AreEqual(6, GetIntValue(bytecode, 230));
            // outer body
            // inner loop counter initialization
            Assert.AreEqual(Bytecode.PUSH_INT, bytecode[234]);
            Assert.AreEqual(20, GetLongValue(bytecode, 235));
            Assert.AreEqual(Bytecode.STORE_VARIABLE, bytecode[243]);
            Assert.AreEqual(1, GetIntValue(bytecode, 244));
            // inner end variable initialization
            Assert.AreEqual(Bytecode.PUSH_INT, bytecode[248]);
            Assert.AreEqual(40, GetLongValue(bytecode, 249));
            Assert.AreEqual(Bytecode.STORE_VARIABLE, bytecode[257]);
            Assert.AreEqual(7, GetIntValue(bytecode, 258));
            // inner body
            Assert.AreEqual(Bytecode.PUSH_INT, bytecode[262]);
            Assert.AreEqual(20, GetLongValue(bytecode, 263));
            Assert.AreEqual(Bytecode.STORE_VARIABLE, bytecode[271]);
            Assert.AreEqual(3, GetIntValue(bytecode, 272));
            // inner loop counter update
            Assert.AreEqual(Bytecode.PUSH_INT_VAR, bytecode[276]);
            Assert.AreEqual(1, GetIntValue(bytecode, 277));
            Assert.AreEqual(Bytecode.PUSH_INT, bytecode[281]);
            Assert.AreEqual(1, GetLongValue(bytecode, 282));
            Assert.AreEqual(Bytecode.ADD, bytecode[290]);
            Assert.AreEqual(Bytecode.STORE_VARIABLE, bytecode[291]);
            Assert.AreEqual(1, GetIntValue(bytecode, 292));
            // inner start - end comparison
            Assert.AreEqual(Bytecode.PUSH_INT_VAR, bytecode[296]);
            Assert.AreEqual(1, GetIntValue(bytecode, 297));
            Assert.AreEqual(Bytecode.PUSH_INT_VAR, bytecode[301]);
            Assert.AreEqual(7, GetIntValue(bytecode, 302));
            Assert.AreEqual(Bytecode.IS_LESS_OR_EQUAL_INT, bytecode[306]);
            // inner jump based on above
            Assert.AreEqual(Bytecode.JUMP_IF_TRUE, bytecode[307]);
            Assert.AreEqual(262, GetIntValue(bytecode, 308));
            // outer loop counter update
            Assert.AreEqual(Bytecode.PUSH_INT_VAR, bytecode[312]);
            Assert.AreEqual(0, GetIntValue(bytecode, 313));
            Assert.AreEqual(Bytecode.PUSH_INT, bytecode[317]);
            Assert.AreEqual(1, GetLongValue(bytecode, 318));
            Assert.AreEqual(Bytecode.ADD, bytecode[326]);
            Assert.AreEqual(Bytecode.STORE_VARIABLE, bytecode[327]);
            Assert.AreEqual(0, GetIntValue(bytecode, 328));
            // outer start - end comparison
            Assert.AreEqual(Bytecode.PUSH_INT_VAR, bytecode[332]);
            Assert.AreEqual(0, GetIntValue(bytecode, 333));
            Assert.AreEqual(Bytecode.PUSH_INT_VAR, bytecode[337]);
            Assert.AreEqual(6, GetIntValue(bytecode, 338));
            Assert.AreEqual(Bytecode.IS_LESS_OR_EQUAL_INT, bytecode[342]);
            // outer jump based on above
            Assert.AreEqual(Bytecode.JUMP_IF_TRUE, bytecode[343]);
            Assert.AreEqual(234, GetIntValue(bytecode, 344));
        }
예제 #22
0
        public void VariableDeclarationGeneratesCorrectCode()
        {
            var reporter = new ErrorReporter();
            var parser = new Parser(
                new Lexer("../../CodeGen/variable_declaration.txt", reporter),
                reporter);

            var node = parser.Parse();

            var semanticChecker = new SemanticChecker(reporter);

            node.Accept(semanticChecker);

            Assert.AreEqual(0, reporter.Errors.Count);

            var codeGenerator = new CodeGenerator(semanticChecker.SymbolTable, semanticChecker.Variables);
            node.Accept(codeGenerator);

            var bytecode = codeGenerator.Bytecodes;
            Assert.AreEqual(323, bytecode.Length);

            Assert.AreEqual(Bytecode.PUSH_INT, bytecode[0]);
            Assert.AreEqual(0, GetLongValue(bytecode, 1));
            Assert.AreEqual(Bytecode.STORE_VARIABLE, bytecode[9]);
            Assert.AreEqual(0, GetIntValue(bytecode, 10));

            Assert.AreEqual(Bytecode.PUSH_STRING, bytecode[14]);
            Assert.AreEqual(0, GetIntValue(bytecode, 15));
            Assert.AreEqual(Bytecode.STORE_VARIABLE, bytecode[19]);
            Assert.AreEqual(1, GetIntValue(bytecode, 20));

            Assert.AreEqual(Bytecode.PUSH_FALSE, bytecode[24]);
            Assert.AreEqual(Bytecode.STORE_VARIABLE, bytecode[25]);
            Assert.AreEqual(2, GetIntValue(bytecode, 26));

            Assert.AreEqual(Bytecode.PUSH_INT, bytecode[30]);
            Assert.AreEqual(323981, GetLongValue(bytecode, 31));
            Assert.AreEqual(Bytecode.STORE_VARIABLE, bytecode[39]);
            Assert.AreEqual(3, GetIntValue(bytecode, 40));

            Assert.AreEqual(Bytecode.PUSH_STRING, bytecode[44]);
            Assert.AreEqual(1, GetIntValue(bytecode, 45));
            Assert.AreEqual(Bytecode.STORE_VARIABLE, bytecode[49]);
            Assert.AreEqual(4, GetIntValue(bytecode, 50));

            Assert.AreEqual(Bytecode.PUSH_INT_VAR, bytecode[54]);
            Assert.AreEqual(0, GetIntValue(bytecode, 55));
            Assert.AreEqual(Bytecode.PUSH_INT, bytecode[59]);
            Assert.AreEqual(4, GetLongValue(bytecode, 60));
            Assert.AreEqual(Bytecode.IS_LESS_INT, bytecode[68]);
            Assert.AreEqual(Bytecode.STORE_VARIABLE, bytecode[69]);
            Assert.AreEqual(5, GetIntValue(bytecode, 70));

            Assert.AreEqual(Bytecode.PUSH_INT_VAR, bytecode[74]);
            Assert.AreEqual(3, GetIntValue(bytecode, 75));
            Assert.AreEqual(Bytecode.PUSH_INT, bytecode[79]);
            Assert.AreEqual(298, GetLongValue(bytecode, 80));
            Assert.AreEqual(Bytecode.IS_EQUAL_INT, bytecode[88]);
            Assert.AreEqual(Bytecode.STORE_VARIABLE, bytecode[89]);
            Assert.AreEqual(6, GetIntValue(bytecode, 90));

            Assert.AreEqual(Bytecode.PUSH_INT_VAR, bytecode[94]);
            Assert.AreEqual(0, GetIntValue(bytecode, 95));
            Assert.AreEqual(Bytecode.PUSH_INT_VAR, bytecode[99]);
            Assert.AreEqual(3, GetIntValue(bytecode, 100));
            Assert.AreEqual(Bytecode.IS_LESS_INT, bytecode[104]);
            Assert.AreEqual(Bytecode.NOT, bytecode[105]);
            Assert.AreEqual(Bytecode.STORE_VARIABLE, bytecode[106]);
            Assert.AreEqual(7, GetIntValue(bytecode, 107));

            Assert.AreEqual(Bytecode.PUSH_INT, bytecode[111]);
            Assert.AreEqual(2, GetLongValue(bytecode, 112));
            Assert.AreEqual(Bytecode.PUSH_INT, bytecode[120]);
            Assert.AreEqual(3, GetLongValue(bytecode, 121));
            Assert.AreEqual(Bytecode.ADD, bytecode[129]);
            Assert.AreEqual(Bytecode.STORE_VARIABLE, bytecode[130]);
            Assert.AreEqual(8, GetIntValue(bytecode, 131));

            Assert.AreEqual(Bytecode.PUSH_INT_VAR, bytecode[135]);
            Assert.AreEqual(0, GetIntValue(bytecode, 136));
            Assert.AreEqual(Bytecode.PUSH_INT_VAR, bytecode[140]);
            Assert.AreEqual(3, GetIntValue(bytecode, 141));
            Assert.AreEqual(Bytecode.SUB, bytecode[145]);
            Assert.AreEqual(Bytecode.STORE_VARIABLE, bytecode[146]);
            Assert.AreEqual(9, GetIntValue(bytecode, 147));

            Assert.AreEqual(Bytecode.PUSH_INT_VAR, bytecode[151]);
            Assert.AreEqual(0, GetIntValue(bytecode, 152));
            Assert.AreEqual(Bytecode.PUSH_INT_VAR, bytecode[156]);
            Assert.AreEqual(3, GetIntValue(bytecode, 157));
            Assert.AreEqual(Bytecode.MUL, bytecode[161]);
            Assert.AreEqual(Bytecode.STORE_VARIABLE, bytecode[162]);
            Assert.AreEqual(10, GetIntValue(bytecode, 163));

            Assert.AreEqual(Bytecode.PUSH_INT_VAR, bytecode[167]);
            Assert.AreEqual(0, GetIntValue(bytecode, 168));
            Assert.AreEqual(Bytecode.PUSH_INT_VAR, bytecode[172]);
            Assert.AreEqual(3, GetIntValue(bytecode, 173));
            Assert.AreEqual(Bytecode.DIV, bytecode[177]);
            Assert.AreEqual(Bytecode.STORE_VARIABLE, bytecode[178]);
            Assert.AreEqual(11, GetIntValue(bytecode, 179));

            Assert.AreEqual(Bytecode.PUSH_INT, bytecode[183]);
            Assert.AreEqual(2, GetLongValue(bytecode, 184));
            Assert.AreEqual(Bytecode.PUSH_INT, bytecode[192]);
            Assert.AreEqual(3, GetIntValue(bytecode, 193));
            Assert.AreEqual(Bytecode.MUL, bytecode[201]);
            Assert.AreEqual(Bytecode.PUSH_INT, bytecode[202]);
            Assert.AreEqual(4, GetLongValue(bytecode, 203));
            Assert.AreEqual(Bytecode.PUSH_INT, bytecode[211]);
            Assert.AreEqual(2, GetLongValue(bytecode, 212));
            Assert.AreEqual(Bytecode.DIV, bytecode[220]);
            Assert.AreEqual(Bytecode.SUB, bytecode[221]);
            Assert.AreEqual(Bytecode.STORE_VARIABLE, bytecode[222]);
            Assert.AreEqual(12, GetIntValue(bytecode, 223));

            Assert.AreEqual(Bytecode.PUSH_STRING_VAR, bytecode[227]);
            Assert.AreEqual(1, GetIntValue(bytecode, 228));
            Assert.AreEqual(Bytecode.PUSH_STRING, bytecode[232]);
            Assert.AreEqual(2, GetIntValue(bytecode, 233));
            Assert.AreEqual(Bytecode.CONCAT, bytecode[237]);
            Assert.AreEqual(Bytecode.STORE_VARIABLE, bytecode[238]);
            Assert.AreEqual(13, GetIntValue(bytecode, 239));

            Assert.AreEqual(Bytecode.PUSH_STRING_VAR, bytecode[243]);
            Assert.AreEqual(1, GetIntValue(bytecode, 244));
            Assert.AreEqual(Bytecode.PUSH_STRING, bytecode[248]);
            Assert.AreEqual(2, GetIntValue(bytecode, 249));
            Assert.AreEqual(Bytecode.IS_LESS_STRING, bytecode[253]);
            Assert.AreEqual(Bytecode.STORE_VARIABLE, bytecode[254]);
            Assert.AreEqual(14, GetIntValue(bytecode, 255));

            Assert.AreEqual(Bytecode.PUSH_STRING, bytecode[259]);
            Assert.AreEqual(3, GetIntValue(bytecode, 260));
            Assert.AreEqual(Bytecode.PUSH_STRING, bytecode[264]);
            Assert.AreEqual(4, GetIntValue(bytecode, 265));
            Assert.AreEqual(Bytecode.IS_EQUAL_STRING, bytecode[269]);
            Assert.AreEqual(Bytecode.STORE_VARIABLE, bytecode[270]);
            Assert.AreEqual(15, GetIntValue(bytecode, 271));

            Assert.AreEqual(Bytecode.PUSH_BOOLEAN_VAR, bytecode[275]);
            Assert.AreEqual(5, GetIntValue(bytecode, 276));
            Assert.AreEqual(Bytecode.PUSH_BOOLEAN_VAR, bytecode[280]);
            Assert.AreEqual(6, GetIntValue(bytecode, 281));
            Assert.AreEqual(Bytecode.IS_LESS_BOOLEAN, bytecode[285]);
            Assert.AreEqual(Bytecode.STORE_VARIABLE, bytecode[286]);
            Assert.AreEqual(16, GetIntValue(bytecode, 287));

            Assert.AreEqual(Bytecode.PUSH_BOOLEAN_VAR, bytecode[291]);
            Assert.AreEqual(5, GetIntValue(bytecode, 292));
            Assert.AreEqual(Bytecode.PUSH_BOOLEAN_VAR, bytecode[296]);
            Assert.AreEqual(6, GetIntValue(bytecode, 297));
            Assert.AreEqual(Bytecode.IS_EQUAL_BOOLEAN, bytecode[301]);
            Assert.AreEqual(Bytecode.STORE_VARIABLE, bytecode[302]);
            Assert.AreEqual(17, GetIntValue(bytecode, 303));

            Assert.AreEqual(Bytecode.PUSH_BOOLEAN_VAR, bytecode[307]);
            Assert.AreEqual(5, GetIntValue(bytecode, 308));
            Assert.AreEqual(Bytecode.PUSH_BOOLEAN_VAR, bytecode[312]);
            Assert.AreEqual(6, GetIntValue(bytecode, 313));
            Assert.AreEqual(Bytecode.AND, bytecode[317]);
            Assert.AreEqual(Bytecode.STORE_VARIABLE, bytecode[318]);
            Assert.AreEqual(18, GetIntValue(bytecode, 319));
        }
예제 #23
0
        public void GetTokenHandlesValidStrings()
        {
            var reporter = new ErrorReporter();
            var lexer = new Lexer(@"..\..\Lexing\valid_strings.txt", reporter);

            Assert.AreEqual(new TextToken("hello"), lexer.NextToken());
            Assert.AreEqual(new TextToken("wor\tld"), lexer.NextToken());
            Assert.AreEqual(new TextToken("thi\ns"), lexer.NextToken());
            Assert.AreEqual(new TextToken("\"is\""), lexer.NextToken());
            Assert.AreEqual(new TextToken("a\rtest"), lexer.NextToken());
            Assert.AreEqual(0, reporter.Errors.Count);
        }
예제 #24
0
        public void AssertGeneratesCorrectCode()
        {
            var reporter = new ErrorReporter();
            var parser = new Parser(
                new Lexer("../../CodeGen/assert_statement.txt", reporter),
                reporter);

            var node = parser.Parse();

            var semanticChecker = new SemanticChecker(reporter);

            node.Accept(semanticChecker);

            Assert.AreEqual(0, reporter.Errors.Count);

            var codeGenerator = new CodeGenerator(semanticChecker.SymbolTable, semanticChecker.Variables);
            node.Accept(codeGenerator);

            var bytecode = codeGenerator.Bytecodes;

            Assert.AreEqual(99, bytecode.Length);

            Assert.AreEqual(Bytecode.PUSH_FALSE, bytecode[0]);
            Assert.AreEqual(Bytecode.STORE_VARIABLE, bytecode[1]);
            Assert.AreEqual(0, GetIntValue(bytecode, 2));

            Assert.AreEqual(Bytecode.PUSH_FALSE, bytecode[6]);
            Assert.AreEqual(Bytecode.STORE_VARIABLE, bytecode[7]);
            Assert.AreEqual(1, GetIntValue(bytecode, 8));

            Assert.AreEqual(Bytecode.PUSH_INT, bytecode[12]);
            Assert.AreEqual(4, GetLongValue(bytecode, 13));
            Assert.AreEqual(Bytecode.PUSH_INT, bytecode[21]);
            Assert.AreEqual(6, GetLongValue(bytecode, 22));
            Assert.AreEqual(Bytecode.IS_LESS_INT, bytecode[30]);
            Assert.AreEqual(Bytecode.ASSERT, bytecode[31]);
            Assert.AreEqual(3, GetIntValue(bytecode, 32));

            Assert.AreEqual(Bytecode.PUSH_BOOLEAN_VAR, bytecode[36]);
            Assert.AreEqual(0, GetIntValue(bytecode, 37));
            Assert.AreEqual(Bytecode.PUSH_BOOLEAN_VAR, bytecode[41]);
            Assert.AreEqual(1, GetIntValue(bytecode, 42));
            Assert.AreEqual(Bytecode.AND, bytecode[46]);
            Assert.AreEqual(Bytecode.ASSERT, bytecode[47]);
            Assert.AreEqual(4, GetIntValue(bytecode, 48));

            Assert.AreEqual(Bytecode.PUSH_BOOLEAN_VAR, bytecode[52]);
            Assert.AreEqual(0, GetIntValue(bytecode, 53));
            Assert.AreEqual(Bytecode.NOT, bytecode[57]);
            Assert.AreEqual(Bytecode.ASSERT, bytecode[58]);
            Assert.AreEqual(5, GetIntValue(bytecode, 59));

            Assert.AreEqual(Bytecode.PUSH_BOOLEAN_VAR, bytecode[63]);
            Assert.AreEqual(0, GetIntValue(bytecode, 64));
            Assert.AreEqual(Bytecode.PUSH_BOOLEAN_VAR, bytecode[68]);
            Assert.AreEqual(1, GetIntValue(bytecode, 69));
            Assert.AreEqual(Bytecode.IS_EQUAL_BOOLEAN, bytecode[73]);
            Assert.AreEqual(Bytecode.PUSH_INT, bytecode[74]);
            Assert.AreEqual(4, GetLongValue(bytecode, 75));
            Assert.AreEqual(Bytecode.PUSH_INT, bytecode[83]);
            Assert.AreEqual(6, GetLongValue(bytecode, 84));
            Assert.AreEqual(Bytecode.IS_LESS_INT, bytecode[92]);
            Assert.AreEqual(Bytecode.IS_EQUAL_BOOLEAN, bytecode[93]);
            Assert.AreEqual(Bytecode.ASSERT, bytecode[94]);
            Assert.AreEqual(6, GetIntValue(bytecode, 95));
        }
예제 #25
0
        public void LexerBackTrackingThrowsIfCalledWithNonFullBufferTooManyTimes()
        {
            var reporter = new ErrorReporter();
            var lexer = new Lexer(@"..\..\example_program.txt", reporter);

            bool throws = false;
            try
            {
               lexer.Backtrack();
            }
            catch (InternalCompilerError e)
            {
                throws = true;
            }

            Assert.IsTrue(throws);
            Assert.AreEqual(0, reporter.Errors.Count);
        }
예제 #26
0
        public void GetTokenParsesHandlesInvalidCharacters()
        {
            var reporter = new ErrorReporter();
            var lexer = new Lexer(@"..\..\Lexing\invalid_characters.txt", reporter);

            Assert.AreEqual(new IdentifierToken("hello"), lexer.NextToken());
            Assert.AreEqual(new IdentifierToken("there"), lexer.NextToken());
            Assert.AreEqual(new TextToken("just"), lexer.NextToken());
            Assert.AreEqual(new IdentifierToken("testing"), lexer.NextToken());
            Assert.AreEqual(new NumberToken(1234), lexer.NextToken());

            Assert.AreEqual(4, reporter.Errors.Count);

            Assert.AreEqual(Error.LEXICAL_ERROR, reporter.Errors[0].Type);
            Assert.AreEqual(0, reporter.Errors[0].Line);
            Assert.AreEqual(0, reporter.Errors[0].Column);
            Assert.IsTrue(reporter.Errors[0].Message.ToLower().Contains("invalid start"));

            Assert.AreEqual(Error.LEXICAL_ERROR, reporter.Errors[1].Type);
            Assert.AreEqual(0, reporter.Errors[1].Line);
            Assert.AreEqual(6, reporter.Errors[1].Column);
            Assert.IsTrue(reporter.Errors[1].Message.ToLower().Contains("invalid start"));

            Assert.AreEqual(Error.LEXICAL_ERROR, reporter.Errors[2].Type);
            Assert.AreEqual(0, reporter.Errors[2].Line);
            Assert.AreEqual(18, reporter.Errors[2].Column);
            Assert.IsTrue(reporter.Errors[2].Message.ToLower().Contains("invalid start"));

            Assert.AreEqual(Error.LEXICAL_ERROR, reporter.Errors[3].Type);
            Assert.AreEqual(0, reporter.Errors[3].Line);
            Assert.AreEqual(26, reporter.Errors[3].Column);
            Assert.IsTrue(reporter.Errors[3].Message.ToLower().Contains("invalid start"));
        }
예제 #27
0
 internal StringScanner(TextReader reader, ErrorReporter reporter)
     : base(reader, reporter)
 {
 }
예제 #28
0
        public void GetTokenParsesHandlesInvalidOperators()
        {
            var reporter = new ErrorReporter();
            var lexer = new Lexer(@"..\..\Lexing\invalid_operators.txt", reporter);

            Assert.AreEqual(new IdentifierToken("this"), lexer.NextToken());
            Assert.AreEqual(new IdentifierToken("contains"), lexer.NextToken());
            Assert.AreEqual(new RangeToken(), lexer.NextToken());
            Assert.AreEqual(new IdentifierToken("invalid_operators"), lexer.NextToken());

            Assert.AreEqual(2, reporter.Errors.Count);

            Assert.AreEqual(Error.LEXICAL_ERROR, reporter.Errors[0].Type);
            Assert.AreEqual(0, reporter.Errors[0].Line);
            Assert.AreEqual(5, reporter.Errors[0].Column);
            Assert.IsTrue(reporter.Errors[0].Message.ToLower().Contains("invalid operator"));

            Assert.AreEqual(Error.LEXICAL_ERROR, reporter.Errors[1].Type);
            Assert.AreEqual(0, reporter.Errors[1].Line);
            Assert.AreEqual(17, reporter.Errors[1].Column);
            Assert.IsTrue(reporter.Errors[1].Message.ToLower().Contains("invalid operator"));
        }
예제 #29
0
        public void GetTokenParsesCommentsCorrectly()
        {
            var reporter = new ErrorReporter();
            var lexer = new Lexer(@"..\..\Lexing\comments.txt", reporter);

            Assert.AreEqual(new IdentifierToken("valid_token"), lexer.NextToken());
            Assert.AreEqual(new DivideToken(), lexer.NextToken());
            Assert.AreEqual(new IdentifierToken("anothertoken"), lexer.NextToken());
            Assert.AreEqual(new NumberToken(1234), lexer.NextToken());
            Assert.AreEqual(new TextToken("test"), lexer.NextToken());
            Assert.AreEqual(new EOFToken(), lexer.NextToken());
            Assert.AreEqual(0, reporter.Errors.Count);
        }
예제 #30
0
        public void PrintStatementGeneratesCorrectCode()
        {
            var reporter = new ErrorReporter();
            var parser = new Parser(
                new Lexer("../../CodeGen/print_statement.txt", reporter),
                reporter);

            var node = parser.Parse();

            var semanticChecker = new SemanticChecker(reporter);

            node.Accept(semanticChecker);

            Assert.AreEqual(0, reporter.Errors.Count);

            var codeGenerator = new CodeGenerator(semanticChecker.SymbolTable, semanticChecker.Variables);
            node.Accept(codeGenerator);

            var bytecode = codeGenerator.Bytecodes;
            Assert.AreEqual(134, bytecode.Length);

            Assert.AreEqual(Bytecode.PUSH_INT, bytecode[0]);
            Assert.AreEqual(0, GetLongValue(bytecode, 1));
            Assert.AreEqual(Bytecode.STORE_VARIABLE, bytecode[9]);
            Assert.AreEqual(0, GetIntValue(bytecode, 10));

            Assert.AreEqual(Bytecode.PUSH_STRING, bytecode[14]);
            Assert.AreEqual(0, GetIntValue(bytecode, 15));
            Assert.AreEqual(Bytecode.STORE_VARIABLE, bytecode[19]);
            Assert.AreEqual(1, GetIntValue(bytecode, 20));

            Assert.AreEqual(Bytecode.PUSH_INT, bytecode[24]);
            Assert.AreEqual(4, GetLongValue(bytecode, 25));
            Assert.AreEqual(Bytecode.PRINT_INT, bytecode[33]);

            Assert.AreEqual(Bytecode.PUSH_STRING, bytecode[34]);
            Assert.AreEqual(1, GetIntValue(bytecode, 35));
            Assert.AreEqual(Bytecode.PRINT_STRING, bytecode[39]);

            Assert.AreEqual(Bytecode.PUSH_INT, bytecode[40]);
            Assert.AreEqual(4, GetLongValue(bytecode, 41));
            Assert.AreEqual(Bytecode.PUSH_INT, bytecode[49]);
            Assert.AreEqual(9, GetLongValue(bytecode, 50));
            Assert.AreEqual(Bytecode.ADD, bytecode[58]);
            Assert.AreEqual(Bytecode.PRINT_INT, bytecode[59]);

            Assert.AreEqual(Bytecode.PUSH_STRING, bytecode[60]);
            Assert.AreEqual(2, GetIntValue(bytecode, 61));
            Assert.AreEqual(Bytecode.PUSH_STRING, bytecode[65]);
            Assert.AreEqual(3, GetIntValue(bytecode, 66));
            Assert.AreEqual(Bytecode.CONCAT, bytecode[70]);
            Assert.AreEqual(Bytecode.PRINT_STRING, bytecode[71]);

            Assert.AreEqual(Bytecode.PUSH_STRING, bytecode[72]);
            Assert.AreEqual(4, GetIntValue(bytecode, 73));
            Assert.AreEqual(Bytecode.PUSH_STRING, bytecode[77]);
            Assert.AreEqual(5, GetIntValue(bytecode, 78));
            Assert.AreEqual(Bytecode.CONCAT, bytecode[82]);
            Assert.AreEqual(Bytecode.STORE_VARIABLE, bytecode[83]);
            Assert.AreEqual(1, GetIntValue(bytecode, 84));
            Assert.AreEqual(Bytecode.PUSH_STRING_VAR, bytecode[88]);
            Assert.AreEqual(1, GetIntValue(bytecode, 89));
            Assert.AreEqual(Bytecode.PRINT_STRING, bytecode[93]);

            Assert.AreEqual(Bytecode.PUSH_INT, bytecode[94]);
            Assert.AreEqual(2, GetLongValue(bytecode, 95));
            Assert.AreEqual(Bytecode.PUSH_INT, bytecode[103]);
            Assert.AreEqual(3, GetLongValue(bytecode, 104));
            Assert.AreEqual(Bytecode.MUL, bytecode[112]);
            Assert.AreEqual(Bytecode.STORE_VARIABLE, bytecode[113]);
            Assert.AreEqual(0, GetIntValue(bytecode, 114));
            Assert.AreEqual(Bytecode.PUSH_INT_VAR, bytecode[118]);
            Assert.AreEqual(0, GetIntValue(bytecode, 119));
            Assert.AreEqual(Bytecode.PUSH_INT, bytecode[123]);
            Assert.AreEqual(1, GetLongValue(bytecode, 124));
            Assert.AreEqual(Bytecode.SUB, bytecode[132]);
            Assert.AreEqual(Bytecode.PRINT_INT, bytecode[133]);
        }