def test_string(self): let = ast.LetStatement( token.Token(token.LET, "let"), ast.Identifier(token.Token(token.IDENT, "myVar"), "myVar"), ast.Identifier(token.Token(token.IDENT, "anotherVar"), "anotherVar")) program = ast.Program([let]) self.assertEqual(str(program), "let myVar = anotherVar;")
def parse_let_statement(self): stmt = ast.LetStatement(self.cur_token) if not self.expect_peek(token.IDENT): return None stmt.name = ast.Identifier(self.cur_token, self.cur_token.Literal) if not self.expect_peek(token.ASSIGN): return None self.next_token() stmt.value = self.parse_expression(Precedence.LOWEST.value) if self.peek_token_is(token.SEMICOLON): self.next_token() return stmt
def test_string(self): program = ast.Program(Statements=[ ast.LetStatement(Token=token.Token(Type=token.LET, Literal='let'), Name=ast.Identifier(Token=token.Token( Type=token.IDENT, Literal='myVar'), Value='myVar'), Value=ast.Identifier(Token=token.Token( Type=token.IDENT, Literal='anotherVar'), Value='anotherVar')) ]) if program.String() != 'let myVar = anotherVar;': self.fail('program.String() wrong. got=\'%s\'' % program.String())
def test_string(): program = ast.Program() statements = [ ast.LetStatement( token=token.Token(token.LET, "let"), name=ast.Identifier(token=token.Token(token.IDENT, "myVar"), value="myVar"), value=ast.Identifier(token=token.Token(token.IDENT, "anotherVar"), value="anotherVar"), ) ] program.statements = statements assert str(program) == "let myVar = anotherVar"
def test_string(): program = ast.Program([ ast.LetStatement( token.Token(token.LET, 'let'), ast.Identifier( token.Token(token.IDENT, 'myVar'), 'myVar' ), ast.Identifier( token.Token(token.IDENT, 'anotherVar'), 'anotherVar' ) ) ]) assert program.string() == 'let myVar = anotherVar;', "program.string() wrong. got='{}'".format(program.string())
def parse_let_statement(self) -> Optional[ast.LetStatement]: stmt_token = self.cur_token if not self.expect_peek(token.IDENT): return None name = ast.Identifier(token=self.cur_token, value=self.cur_token.literal) if not self.expect_peek(token.ASSIGN): return None self.next_token() value = self.parse_expression(OperatorPrecedence.LOWEST) if self.peek_token_is(token.SEMICOLON): self.next_token() return ast.LetStatement(token=stmt_token, name=name, value=value)
def parseLetStatement(self) -> Optional[ast.LetStatement]: curToken = self.curToken if not self.expectPeek(token.IDENT): return None name = ast.Identifier(Token=self.curToken, Value=self.curToken.Literal) if not self.expectPeek(token.ASSIGN): return None self.nextToken() value = self.parseExpression(LOWEST) if not value: return None stmt = ast.LetStatement(Token=curToken, Name=name, Value=value) if self.peekTokenIs(token.SEMICOLON): self.nextToken() return stmt
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))
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))