Exemple #1
0
    def test_functions_recursion(self):
        # fun f(a,b) {if a = 0 {ret b} else {ret f(a-1,b+1)}}\nx:=f(5,0)
        tree = \
            Program([
                Fun(Identifier('f'), [Identifier('a'), Identifier('b')], Program([
                    If(Comparison(Identifier('a'), TokenType.EQUAL, Literal(0)),
                       Program([Ret(Identifier('b'))]),
                       Program([Ret(FunCall(Identifier('f'),
                                            [Binary(Identifier('a'), TokenType.MINUS, Literal(1)),
                                             Binary(Identifier('b'), TokenType.PLUS, Literal(1))]))])
                       )
                ])),
                Assign(Identifier('x'), FunCall(Identifier('f'), [Literal(5), Literal(0)]))
            ])
        interpreter = Interpreter()
        self.assertEqual(5, interpreter.interpret(tree)['x'])

        # fun odd(n) {
        #     if n = 0 {
        #         ret false
        #     }
        #     ret even(n-1)
        # }
        #
        # fun even(n) {
        #     if n = 0 {
        #         ret true
        #     }
        #     ret odd(n-1)
        # }
        #
        # a := even(5)
        # b :=  odd(5)
        # c :=  even(10)
        # d :=  odd(10)
        tree = \
            Program([
                Fun(Identifier('odd'), [Identifier('n')], Program([
                    If(Comparison(Identifier('n'), TokenType.EQUAL, Literal(0)),
                       Program([Ret(Literal(False))]),
                       Program([])),
                    Ret(FunCall(Identifier('even'), [Binary(Identifier('n'), TokenType.MINUS, Literal(1))]))
                ])),
                Fun(Identifier('even'), [Identifier('n')], Program([
                    If(Comparison(Identifier('n'), TokenType.EQUAL, Literal(0)),
                       Program([Ret(Literal(True))]),
                       Program([])),
                    Ret(FunCall(Identifier('odd'), [Binary(Identifier('n'), TokenType.MINUS, Literal(1))]))
                ])),
                Assign(Identifier('a'), FunCall(Identifier('even'), [Literal(5)])),
                Assign(Identifier('b'), FunCall(Identifier('odd'), [Literal(5)])),
                Assign(Identifier('c'), FunCall(Identifier('even'), [Literal(10)])),
                Assign(Identifier('d'), FunCall(Identifier('odd'), [Literal(10)]))
            ])
        interpreter = Interpreter()
        env = interpreter.interpret(tree)
        self.assertEqual(False, env['a'])
        self.assertEqual(True, env['b'])
        self.assertEqual(True, env['c'])
        self.assertEqual(False, env['d'])
Exemple #2
0
    def test_higher_order_functions(self):
        # fun f(g, x) {ret g(g(x))}\nfun g(x) {ret x+1}\ny:=f(g, 3)
        tree = \
            Program([Fun(Identifier('f'), [Identifier('g'), Identifier('x')],
                         Program([Ret(FunCall(Identifier('g'), [FunCall(Identifier('g'), [Identifier('x')])]))])),
                     Fun(Identifier('g'), [Identifier('x')],
                         Program([Ret(Binary(Identifier('x'), TokenType.PLUS, Literal(1)))])),
                     Assign(Identifier('y'), FunCall(Identifier('f'), [Identifier('g'), Literal(3)]))])
        interpreter = Interpreter()
        self.assertEqual(5, interpreter.interpret(tree)['y'])

        # fun f() {fun g() {ret 1}\nret g}\nx := f()()
        tree = \
            Program([Fun(Identifier('f'), [],
                         Program([Fun(Identifier('g'), [], Program([Ret(Literal(1))])), Ret(Identifier('g'))])),
                     Assign(Identifier('x'), FunCall(FunCall(Identifier('f'), []), []))])
        interpreter = Interpreter()
        env = interpreter.interpret(tree)
        self.assertEqual(1, env['x'])
        self.assertFalse('g' in env)

        # fun double(f) {fun g(x) {ret f(f(x))}\n ret g}\nfun g(x) {ret x+1}\nd:= double(g)\na:=d(3)\nb:=d(5)
        tree = \
            Program([Fun(Identifier('double'), [Identifier('f')], Program([Fun(Identifier('g'), [Identifier('x')],
                                                                               Program([Ret(FunCall(Identifier('f'), [
                                                                                   FunCall(Identifier('f'),
                                                                                           [Identifier('x')])]))])),
                                                                           Ret(Identifier('g'))])),
                     Fun(Identifier('g'), [Identifier('x')],
                         Program([Ret(Binary(Identifier('x'), TokenType.PLUS, Literal(1)))])),
                     Assign(Identifier('d'), FunCall(Identifier('double'), [Identifier('g')])),
                     Assign(Identifier('a'), FunCall(Identifier('d'), [Literal(3)])),
                     Assign(Identifier('b'), FunCall(Identifier('d'), [Literal(5)]))])
        interpreter = Interpreter()
        env = interpreter.interpret(tree)
        self.assertEqual(5, env['a'])
        self.assertEqual(7, env['b'])

        # fun counter() {i := 0\nfun count() {i := i+1\nret i}\n ret count}\nc := counter()\na := c()\nb := c()
        tree = \
            Program([Fun(Identifier('counter'), [], Program([Assign(Identifier('i'), Literal(0)),
                                                             Fun(Identifier('count'), [], Program([Assign(
                                                                 Identifier('i'),
                                                                 Binary(Identifier('i'), TokenType.PLUS, Literal(1))),
                                                                                                   Ret(Identifier(
                                                                                                       'i'))])),
                                                             Ret(Identifier('count'))])),
                     Assign(Identifier('c'), FunCall(Identifier('counter'), [])),
                     Assign(Identifier('a'), FunCall(Identifier('c'), [])),
                     Assign(Identifier('b'), FunCall(Identifier('c'), []))])
        interpreter = Interpreter()
        env = interpreter.interpret(tree)
        self.assertEqual(1, env['a'])
        self.assertEqual(2, env['b'])
Exemple #3
0
 def test_expression_statements(self):
     # fun f() {print(5)}\n10+4\nf()
     tree = \
         Program([Fun(Identifier('f'), [], Program([ExprStmt(FunCall(Identifier('print'), [Literal(5)]))])),
                  ExprStmt(Binary(Literal(10), TokenType.PLUS, Literal(4))), ExprStmt(FunCall(Identifier('f'), []))])
     interpreter = Interpreter()
     saved_stdout = sys.stdout
     try:
         out = StringIO()
         sys.stdout = out
         interpreter.interpret(tree)
         output = out.getvalue().strip()
         self.assertEqual('5', output)
     finally:
         sys.stdout = saved_stdout
Exemple #4
0
 def test_assignment(self):
     tree = \
         Program([Assign(Identifier('x'), Literal(5.2)),
                  Assign(Identifier('y'), LogicalBinary(LogicalUnary(TokenType.NOT, Literal(True)), TokenType.OR, Literal(True))),
                  Assign(Identifier('z'), StringBinary(Literal('asd'), TokenType.HASH, Identifier('y')))])
     interpreter = Interpreter()
     env = interpreter.interpret(tree)
     self.assertAlmostEqual(5.2, env['x'])
     self.assertEqual(True, env['y'])
     self.assertEqual('asdtrue', env['z'])
Exemple #5
0
    def test_control_structures(self):
        # x := 0\nif 2 < 3 {x := 5}
        tree = \
            Program([Assign(Identifier('x'), Literal(0)), If(Comparison(Literal(2), TokenType.L, Literal(3)),
                                                    Program([Assign(Identifier('x'), Literal(5))]), Program([]))])
        interpreter = Interpreter()
        self.assertEqual(5, interpreter.interpret(tree)['x'])

        # x := 0\nif 2 > 3 {x := 5}
        tree = \
            Program([Assign(Identifier('x'), Literal(0)), If(Comparison(Literal(3), TokenType.L, Literal(2)),
                                                    Program([Assign(Identifier('x'), Literal(5))]), Program([]))])
        interpreter = Interpreter()
        self.assertEqual(0, interpreter.interpret(tree)['x'])

        # x := 0\nwhile x < 10 {x := x + 1}\nb := x = 10
        tree = \
            Program([Assign(Identifier('x'), Literal(0)), While(Comparison(Identifier('x'), TokenType.L, Literal(10)),
                                                       Program([Assign(Identifier('x'), Binary(Identifier('x'), TokenType.PLUS, Literal(1)))])),
                     Assign(Identifier('b'), Comparison(Identifier('x'), TokenType.EQUAL, Literal(10)))])
        interpreter = Interpreter()
        env = interpreter.interpret(tree)
        self.assertEqual(10, env['x'])
        self.assertEqual(True, env['b'])
Exemple #6
0
 def test_print(self):
     tree = \
         Program([ExprStmt(FunCall(Identifier('print'), [Identifier('x')])), ExprStmt(FunCall(Identifier('print'),[
             LogicalBinary(Identifier('y'), TokenType.AND, Literal(False))])),
                  ExprStmt(FunCall(Identifier('print'), [Literal('asd')]))])
     env = {'x': 5, 'y': True}
     interpreter = Interpreter(env)
     saved_stdout = sys.stdout
     try:
         out = StringIO()
         sys.stdout = out
         self.assertEqual(env, interpreter.interpret(tree))
         output = out.getvalue().strip()
         self.assertEqual(output, '5\nfalse\nasd')
     finally:
         sys.stdout = saved_stdout
Exemple #7
0
def run(src: str) -> None:
    global env

    #tokenization
    tkz = Tokenizer()
    tokens, err = tkz.tokenize(src)

    if tok_debug:
        for i in tokens:
            print(i)

    if display_errors(err, "LOX: SYNTAX ERROR"):
        return

    #don't send single EOF token to parser
    #this allows parser to make stricter assertions while generating the AST
    if tokens[0].type == TokenType.EOF:
        return

    #parsing
    prs = Parser()
    program, err = prs.parse(tokens)

    if parse_debug:
        for tree in program:
            print(tree)

    if display_errors(err, "LOX: GRAMMAR ERROR"):
        return

    #interpretation
    itr = Interpreter(env)
    exit_status, err, env = itr.interpret(program)
    display_errors(err, "LOX: RUNTIME ERROR")

    if env_debug:
        print(env.map)
Exemple #8
0
    def test_functions_basics(self):
        # x:=2\nfun f(x) {y:=1\nret x ^ 2\nret x}\nx := f(x + 1)
        tree = \
            Program([Assign(Identifier('x'), Literal(2)), Fun(Identifier('f'), [Identifier('x')], Program([
                Assign(Identifier('y'), Literal(1)),
                Ret(Binary(Identifier('x'), TokenType.POW, Literal(2))), Ret(Identifier('x'))])),
            Assign(Identifier('x'), FunCall(Identifier('f'), [Binary(Identifier('x'), TokenType.PLUS, Literal(1))]))])
        interpreter = Interpreter()
        env = interpreter.interpret(tree)
        self.assertEqual(9, env['x'])
        self.assertEqual(9, env['f'].env['x'])
        self.assertFalse('y' in env)

        # x:=1\nfun f() {ret x}\nx:=2\ny := f()
        tree = \
            Program([Assign(Identifier('x'), Literal(1)),
                     Fun(Identifier('f'), [], Program([Ret(Identifier('x'))])),
                     Assign(Identifier('x'), Literal(2)),
                     Assign(Identifier('y'), FunCall(Identifier('f'), []))])
        interpreter = Interpreter()
        env = interpreter.interpret(tree)
        self.assertEqual(2, env['y'])

        # x:=1\nfun f() {x := 2}\nf()
        tree = \
            Program([Assign(Identifier('x'), Literal(1)), Fun(Identifier('f'), [], Program([
                Assign(Identifier('x'), Literal(2))
            ])),ExprStmt(FunCall(Identifier('f'), []))])
        interpreter = Interpreter()
        env = interpreter.interpret(tree)
        self.assertEqual(2, env['x'])

        # a := 'global'\nb1 := '1'\n b2 := '2'\nfun outer() {fun showA() {ret a}\nb1 := showA()\na := 'inner'\nb2 := showA()}\nouter()
        tree = \
            Program([Assign(Identifier('a'), Literal(
                'global')), Assign(Identifier('b1'), Literal(
                '1')),Assign(Identifier('b2'), Literal(
                '2')),Fun(Identifier('outer'), [],
                                Program([Fun(Identifier('showA'), [], Program([Ret(Identifier('a'))])),
                                         Assign(Identifier('b1'), FunCall(Identifier('showA'), [])),
                                         Assign(Identifier('a'), Literal('inner')),
                                         Assign(Identifier('b2'), FunCall(Identifier('showA'), []))])),
                     ExprStmt(FunCall(Identifier('outer'), []))])
        interpreter = Interpreter()
        env = interpreter.interpret(tree)
        self.assertEqual('global', env['b1'])
        self.assertEqual('inner', env['b2'])

        # fun f() {print(a)\na:=10}\na:=20\nf()\nprint(a)
        tree = \
            Program([Fun(Identifier('f'), [], Program(
                [ExprStmt(FunCall(Identifier('print'), [Identifier('a')])), Assign(Identifier('a'), Literal(10))])),
                     Assign(Identifier('a'), Literal(20)), ExprStmt(FunCall(Identifier('f'), [])),
                     ExprStmt(FunCall(Identifier('print'), [Identifier('a')]))])
        interpreter = Interpreter()
        saved_stdout = sys.stdout
        try:
            out = StringIO()
            sys.stdout = out
            env = interpreter.interpret(tree)
            output = out.getvalue().strip()
            self.assertEqual('20\n10', output)
        finally:
            sys.stdout = saved_stdout

        # fun f(x) {x := 10\nret x}\n x:=5\ny := f(x)
        tree = \
            Program([Fun(Identifier('f'), [Identifier('x')], Program([
                Assign(Identifier('x'), Literal(10)), Ret(Identifier('x'))
            ])), Assign(Identifier('x'), Literal(5)), Assign(Identifier('y'), FunCall(Identifier('f'), [Identifier('x')]))])
        interpreter = Interpreter()
        env = interpreter.interpret(tree)
        self.assertEqual(5, env['x'])
        self.assertEqual(10, env['y'])
Exemple #9
0
from src.lexer import Lexer
from src.parser import Parser
from src.interpreter import Interpreter
from src.semantic_analyzer import SemanticAnalyzer

__all__ = ("Lexer", "Parser", "Interpreter", "SemanticAnalyzer")

if __name__ == "__main__":
    import sys

    with open(sys.argv[1]) as f:
        text = f.read()

    lexer = Lexer(text)
    parser = Parser(lexer)
    tree = parser.parse()
    semantic_analyzer = SemanticAnalyzer()
    semantic_analyzer.visit(tree)

    interpreter = Interpreter(tree)
    result = interpreter.interpret()

    print()
    print("Runtime GLOBAL_MEMORY contents:")
    for k, v in sorted(interpreter.GLOBAL_SCOPE.items()):
        print("%s = %s" % (k, v))
Exemple #10
0
def process_file(filename):
    with open(filename, "r") as file:
        text = file.read()
        interpreter = Interpreter(text)
        result = interpreter.interpret()
        print(interpreter.GLOBAL_VARS)