Ejemplo n.º 1
0
def test_call_expression_parsing():
    source = "add(1, 2 * 3, 4 + 5);"

    l = Lexer(source)
    p = Parser(l)

    program = p.parse_program()
    assert p.errors == []

    assert len(program.statements) == 1

    stmt = program.statements[0]

    assert isinstance(stmt, ast.ExpressionStatement)

    assert isinstance(stmt.expression, ast.CallExpression)

    assert stmt.expression.function.value == "add"

    assert len(stmt.expression.arguments) == 3

    assert stmt.expression == ast.CallExpression(
        token=Token(tok_type="(", literal="("),
        function=ast.Identifier(token=Token(tok_type="IDENT", literal="add"),
                                value="add"),
        arguments=[
            ast.IntegerLiteral(token=Token(tok_type="INT", literal="1"),
                               value=1),
            ast.InfixExpression(
                token=Token(tok_type="*", literal="*"),
                left=ast.IntegerLiteral(token=Token(tok_type="INT",
                                                    literal="2"),
                                        value=2),
                operator="*",
                right=ast.IntegerLiteral(token=Token(tok_type="INT",
                                                     literal="3"),
                                         value=3),
            ),
            ast.InfixExpression(
                token=Token(tok_type="+", literal="+"),
                left=ast.IntegerLiteral(token=Token(tok_type="INT",
                                                    literal="4"),
                                        value=4),
                operator="+",
                right=ast.IntegerLiteral(token=Token(tok_type="INT",
                                                     literal="5"),
                                         value=5),
            ),
        ],
    )

    assert str(stmt.expression) == "add(1, (2 * 3), (4 + 5))"
Ejemplo n.º 2
0
 def parseIntegerLiteral(self) -> Optional[ast.Expression]:
     try:
         value = int(self.curToken.Literal)
     except ValueError:
         msg = 'could not parse %s as integer' % self.curToken.Literal
         self.errors.append(msg)
         return None
     lit = ast.IntegerLiteral(Token=self.curToken, Value=value)
     return lit
Ejemplo n.º 3
0
    def parse_integer_literal(self) -> Union[ast.Expression, None]:
        lit = ast.IntegerLiteral(self.cur_token)

        if not self.cur_token.literal.isdigit():
            msg = "could not parse '{}' as integer".format(
                self.cur_token.literal)
            self.errors.append(msg)
            return None

        lit.value = int(self.cur_token.literal)

        return lit
Ejemplo n.º 4
0
 def parse_integer_literal(self):
     # begin = self.tracer.trace('parse_integer_literal')
     lit = ast.IntegerLiteral(self.cur_token)
     try:
         value = int(self.cur_token.Literal)
         lit.value = value
         # self.tracer.untrace(begin)
         return lit
     except ValueError:
         msg = 'could not parse {} as integer'.format(self.cur_token)
         self.errors.append(msg)
         return None
Ejemplo n.º 5
0
def convert_object_to_astnode(obj):
    if isinstance(obj, object.Integer):
        t = token.Token(Type=token.INT, Literal=str(obj.value))
        return ast.IntegerLiteral(t, obj.value)
    if isinstance(obj, object.Boolean):
        if obj.value:
            t = token.Token(Type=token.TRUE, Literal='true')
        else:
            t = token.Token(Type=token.FALSE, Literal='false')
        return ast.Boolean(t, obj.value)
    if isinstance(obj, object.Quote):
        # Quote already has the ASTNode object so just return it!
        return obj.node
    return None
Ejemplo n.º 6
0
def convertObjectToASTNode(obj: object.Object) -> ast.Node:
    t: token.Token
    if type(obj) == object.Integer:
        t = token.Token(Type=token.INT, Literal='%s' % obj.Value)
        return ast.IntegerLiteral(Token=t, Value=obj.Value)
    elif type(obj) == object.Boolean:
        if obj.Value:
            t = token.Token(Type=token.TRUE, Literal='true')
        else:
            t = token.Token(Type=token.FALSE, Literal='false')
        return ast.Boolean(Token=t, Value=obj.Value)
    elif type(obj) == object.Quote:
        obj = cast(object.Quote, obj)
        return obj.Node
    else:
        # TODO: xxx
        return ast.Node()
Ejemplo n.º 7
0
    def test_modify(self):
        one: Callable[[], ast.Expression] = lambda: ast.IntegerLiteral(
            Token=token.Token(token.INT, 'Unknown'), Value=1)
        two: Callable[[], ast.Expression] = lambda: ast.IntegerLiteral(
            Token=token.Token(token.INT, 'Unknown'), Value=2)

        def turnOneIntoTwo(node: ast.Node) -> ast.Node:
            integer = node
            if type(node) != ast.IntegerLiteral:
                return node

            if integer.Value != 1:
                return node

            integer.Value = 2
            return integer

        @dataclass
        class Test:
            input: ast.Node
            expected: ast.Node

        tests: List[Test] = [
            Test(one(), two()),
            Test(
                ast.Program(Statements=[
                    ast.ExpressionStatement(Token=token.Token(
                        token.INT, 'Unknown'),
                                            ExpressionValue=one()),
                ]),
                ast.Program(Statements=[
                    ast.ExpressionStatement(Token=token.Token(
                        token.INT, 'Unknown'),
                                            ExpressionValue=two()),
                ])),
            Test(
                ast.InfixExpression(Token=token.Token(token.ILLEGAL,
                                                      'ILLEGAL'),
                                    Left=one(),
                                    Operator='+',
                                    Right=two()),
                ast.InfixExpression(Token=token.Token(token.ILLEGAL,
                                                      'ILLEGAL'),
                                    Left=two(),
                                    Operator='+',
                                    Right=two())),
            Test(
                ast.InfixExpression(Token=token.Token(token.ILLEGAL,
                                                      'ILLEGAL'),
                                    Left=two(),
                                    Operator='+',
                                    Right=one()),
                ast.InfixExpression(Token=token.Token(token.ILLEGAL,
                                                      'ILLEGAL'),
                                    Left=two(),
                                    Operator='+',
                                    Right=two())),
            Test(
                ast.IndexExpression(Token=token.Token(token.ILLEGAL,
                                                      'ILLEGAL'),
                                    Left=one(),
                                    Index=one()),
                ast.IndexExpression(Token=token.Token(token.ILLEGAL,
                                                      'ILLEGAL'),
                                    Left=two(),
                                    Index=two())),
            Test(
                ast.PrefixExpression(Token=token.Token(token.ILLEGAL,
                                                       'ILLEGAL'),
                                     Operator='-',
                                     Right=one()),
                ast.PrefixExpression(Token=token.Token(token.ILLEGAL,
                                                       'ILLEGAL'),
                                     Operator='-',
                                     Right=two())),
            Test(
                ast.IfExpression(
                    Token=token.Token(token.ILLEGAL, 'ILLEGAL'),
                    Condition=one(),
                    Consequence=ast.BlockStatement(
                        Token=token.Token(token.ILLEGAL, 'ILLEGAL'),
                        Statements=[
                            ast.ExpressionStatement(Token=token.Token(
                                token.ILLEGAL, 'ILLEGAL'),
                                                    ExpressionValue=one())
                        ]),
                    Alternative=ast.BlockStatement(
                        Token=token.Token(token.ILLEGAL, 'ILLEGAL'),
                        Statements=[
                            ast.ExpressionStatement(Token=token.Token(
                                token.ILLEGAL, 'ILLEGAL'),
                                                    ExpressionValue=one())
                        ]),
                ),
                ast.IfExpression(
                    Token=token.Token(token.ILLEGAL, 'ILLEGAL'),
                    Condition=two(),
                    Consequence=ast.BlockStatement(
                        Token=token.Token(token.ILLEGAL, 'ILLEGAL'),
                        Statements=[
                            ast.ExpressionStatement(Token=token.Token(
                                token.ILLEGAL, 'ILLEGAL'),
                                                    ExpressionValue=two())
                        ]),
                    Alternative=ast.BlockStatement(
                        Token=token.Token(token.ILLEGAL, 'ILLEGAL'),
                        Statements=[
                            ast.ExpressionStatement(Token=token.Token(
                                token.ILLEGAL, 'ILLEGAL'),
                                                    ExpressionValue=two())
                        ]))),
            Test(
                ast.IndexExpression(Token=token.Token(token.ILLEGAL,
                                                      'ILLEGAL'),
                                    Left=one(),
                                    Index=one()),
                ast.IndexExpression(Token=token.Token(token.ILLEGAL,
                                                      'ILLEGAL'),
                                    Left=two(),
                                    Index=two())),
            Test(
                ast.ReturnStatement(Token=token.Token(token.ILLEGAL,
                                                      'ILLEGAL'),
                                    ReturnValue=one()),
                ast.ReturnStatement(Token=token.Token(token.ILLEGAL,
                                                      'ILLEGAL'),
                                    ReturnValue=two())),
            Test(
                ast.LetStatement(Token=token.Token(token.ILLEGAL, 'ILLEGAL'),
                                 Value=one(),
                                 Name=''),
                ast.LetStatement(Token=token.Token(token.ILLEGAL, 'ILLEGAL'),
                                 Value=two(),
                                 Name=''),
            ),
            Test(
                ast.FunctionLiteral(
                    Token=token.Token(token.ILLEGAL, 'ILLEGAL'),
                    Parameters=[],
                    Body=ast.BlockStatement(
                        Token=token.Token(token.ILLEGAL, 'ILLEGAL'),
                        Statements=[
                            ast.ExpressionStatement(Token=token.Token(
                                token.ILLEGAL, 'ILLEGAL'),
                                                    ExpressionValue=one()),
                        ])),
                ast.FunctionLiteral(
                    Token=token.Token(token.ILLEGAL, 'ILLEGAL'),
                    Parameters=[],
                    Body=ast.BlockStatement(
                        Token=token.Token(token.ILLEGAL, 'ILLEGAL'),
                        Statements=[
                            ast.ExpressionStatement(Token=token.Token(
                                token.ILLEGAL, 'ILLEGAL'),
                                                    ExpressionValue=two()),
                        ])),
            ),
            Test(
                ast.ArrayLiteral(Token=token.Token(token.ILLEGAL, 'ILLEGAL'),
                                 Elements=[one(), one()]),
                ast.ArrayLiteral(Token=token.Token(token.ILLEGAL, 'ILLEGAL'),
                                 Elements=[two(), two()]),
            ),
        ]

        for tt in tests:
            modified = ast.Modify(tt.input, turnOneIntoTwo)

            if modified != tt.expected:
                self.fail('not equal. got=%s, want=%s' %
                          (modified, tt.expected))

        hashLiteral = ast.HashLiteral(
            Token=token.Token(token.ILLEGAL, 'ILLEGAL'),
            Pairs=[
                (one(), one()),
                (one(), one()),
            ],
        )

        ast.Modify(hashLiteral, turnOneIntoTwo)

        for key, val in hashLiteral.Pairs:
            if key.Value != 2:
                self.fail('value is not %s, got=%s' % (2, key.Value))

            if val.Value != 2:
                self.fail('value is not %s, got=%s' % (2, val.Value))
Ejemplo n.º 8
0
 def parse_integer_literal(self) -> ast.Node:
     return ast.IntegerLiteral(token=self.cur_token,
                               value=int(self.cur_token.literal))
Ejemplo n.º 9
0
    def test_modify(self):
        one = lambda: ast.ExpressionStatement(expression=ast.IntegerLiteral(
            value=1))
        two = lambda: ast.ExpressionStatement(expression=ast.IntegerLiteral(
            value=2))

        def turn_one_into_two(node):
            """ Modifier function to convert IntegerLiteral of value 1 to 2 """
            integer = node
            if not isinstance(integer, ast.IntegerLiteral):
                return node
            elif integer.value != 1:
                return node
            integer.value = 2
            return integer

        tests = [
            (one(),
             ast.ExpressionStatement(expression=ast.IntegerLiteral(value=2))),
            (two(),
             ast.ExpressionStatement(expression=ast.IntegerLiteral(value=2))),
            (ast.InfixExpression(operator="+", left=one(), right=two()),
             ast.InfixExpression(operator="+", left=two(), right=two())),
            (ast.InfixExpression(operator="+", left=two(), right=one()),
             ast.InfixExpression(operator="+", left=two(), right=two())),
            (ast.PrefixExpression(operator="-", right=one()),
             ast.PrefixExpression(operator="-", right=two())),
            (ast.IndexExpression(left=one(), index=one()),
             ast.IndexExpression(left=two(), index=two())),
            (ast.IfExpression(
                condition=one(),
                consequence=ast.BlockStatement(
                    statements=[ast.ExpressionStatement(expression=one())]),
                alternative=ast.BlockStatement(
                    statements=[ast.ExpressionStatement(expression=one())])),
             ast.IfExpression(
                 condition=two(),
                 consequence=ast.BlockStatement(
                     statements=[ast.ExpressionStatement(expression=two())]),
                 alternative=ast.BlockStatement(
                     statements=[ast.ExpressionStatement(expression=two())]))),
            (ast.ReturnStatement(return_value=one()),
             ast.ReturnStatement(return_value=two())),
            (ast.LetStatement(value=one()), ast.LetStatement(value=two())),
            (ast.FunctionLiteral(
                parameters=[],
                body=ast.BlockStatement(
                    statements=[ast.ExpressionStatement(expression=one())])),
             ast.FunctionLiteral(
                 parameters=[],
                 body=ast.BlockStatement(
                     statements=[ast.ExpressionStatement(expression=two())]))),
            (ast.ArrayLiteral(elements=[one(), one()]),
             ast.ArrayLiteral(elements=[two(), two()]))
        ]
        for t in tests:
            modified = modify.Modify(t[0], turn_one_into_two)
            deep_equals = (modified == t[1])
            self.assertTrue(deep_equals,
                            'not equal. got={} want={}'.format(modified, t[1]))
        # HashLiteral needs to be tested slightly different
        hash_literal = ast.HashLiteral(pairs={one(): one(), two(): two()})
        hash_literal = modify.Modify(hash_literal, turn_one_into_two)
        for key, value in hash_literal.pairs.items():
            self.assertTrue(key == two(),
                            'value is not {}. got={}'.format(2, key))
            self.assertTrue(value == two(),
                            'value is not {}. got={}'.format(2, value))