def test_symbol_address_in_function_with_arguments(self):
        st = SymbolTable()

        integer = IntegerType()
        arrayinteger = ArrayType(integer, 3)

        # Create arguments
        argumentsList = ArgumentsList()
        argumentsList.add(Argument('a', integer))
        argumentsList.add(Argument('b', arrayinteger))

        # Create parameters
        parametersList = ParametersList()
        parametersList.add(Parameter(ConstantExpression(1, 'int')))
        parametersList.add(
            Parameter(
                VariableCallExpression(Symbol('b', arrayinteger, 0), None)))

        st.registerFunction('main', integer, argumentsList, True)
        function = st.getFunction('main', parametersList)

        st.openFunctionScope(function)
        self.assertEqual(st.getSymbol('a').address, 5)
        self.assertEqual(st.getSymbol('b').address, 6)
        st.registerSymbol('c', integer)
        self.assertEqual(st.getSymbol('c').address, 9)
        st.registerSymbol('d', arrayinteger)
        self.assertEqual(st.getSymbol('d').address, 10)
        st.registerSymbol('e', integer)
        self.assertEqual(st.getSymbol('e').address, 13)
        st.closeFunctionScope(function)

        self.assertEqual(function.getStaticSize(), 14)
        self.assertEqual(function.getParameterSize(), 4)
    def test_register_symbols_nested(self):
        st = SymbolTable()
        integer = IntegerType()
        real = RealType()
        boolean = BooleanType()
        character = CharacterType()

        st.registerSymbol('a', integer)

        st.openScope()
        st.registerSymbol('a', real)

        st.openScope()
        st.registerSymbol('a', boolean)

        st.openScope()
        st.registerSymbol('a', character)

        # Check
        self.assertEqual(type(st.getSymbol('a').basetype), CharacterType)

        st.closeScope()

        self.assertEqual(type(st.getSymbol('a').basetype), BooleanType)

        st.closeScope()

        self.assertEqual(type(st.getSymbol('a').basetype), RealType)

        st.closeScope()

        self.assertEqual(type(st.getSymbol('a').basetype), IntegerType)
    def test_function_register_with_unlimited_arguments(self):
        st = SymbolTable()
        integer = IntegerType()
        real = RealType()
        boolean = BooleanType()
        character = CharacterType()

        # Create arguments
        argumentsList = ArgumentsList()
        argumentsList.add(Argument('a', integer))
        argumentsList.makeUnlimited()

        # Create parameters
        parametersList = ParametersList()
        parametersList.add(Parameter(ConstantExpression(1, 'int')))
        parametersList.add(Parameter(ConstantExpression(3.14, 'float')))
        parametersList.add(Parameter(ConstantExpression(True, 'bool')))
        parametersList.add(Parameter(ConstantExpression(False, 'bool')))

        # Register basic function,  arguments
        st.registerFunction('printer', integer, argumentsList, True)

        # get basic function
        self.assertEqual(type(st.getFunction('printer', parametersList)),
                         Function)
    def test_symbol_call(self):
        st = SymbolTable()
        integer = IntegerType()
        real = RealType()
        boolean = BooleanType()
        character = CharacterType()

        st.registerSymbol('a', integer)

        # call in scope
        self.assertEqual(type(st.getSymbol('a').basetype), IntegerType)

        # call in nested scope
        st.openScope()
        self.assertEqual(type(st.getSymbol('a').basetype), IntegerType)

        # define in nested scope
        st.registerSymbol('a', character)

        # call in nested scope
        self.assertEqual(type(st.getSymbol('a').basetype), CharacterType)

        # call original in main scope
        st.closeScope()
        self.assertEqual(type(st.getSymbol('a').basetype), IntegerType)
    def test_function_register_and_get_no_arguments(self):
        st = SymbolTable()
        integer = IntegerType()
        real = RealType()
        boolean = BooleanType()
        character = CharacterType()

        # Register basic function, no arguments
        st.registerFunction('hello', integer, ArgumentsList(), True)

        # register function again, shouldn't work
        self.assertRaises(
            FunctionAlreadyRegisteredError, lambda: st.registerFunction(
                'hello', integer, ArgumentsList(), True))

        # register function again with other return type, shouldn't work
        self.assertRaises(
            FunctionAlreadyRegisteredError, lambda: st.registerFunction(
                'hello', boolean, ArgumentsList(), True))

        # get basic function
        self.assertEqual(type(st.getFunction('hello', ParametersList())),
                         Function)

        # get not known function, should not work
        self.assertRaises(FunctionNotRegisteredError,
                          lambda: st.getFunction('add', ParametersList()))
Beispiel #6
0
    def test_compile_function_arguments_no_statements(self):
        st = SymbolTable()

        integer = IntegerType()
        arrayinteger = ArrayType(integer, 3)

        # Create arguments
        argumentsList = ArgumentsList()
        argumentsList.add(Argument('a', integer))
        argumentsList.add(Argument('b', arrayinteger))

        # Create parameters
        parametersList = ParametersList()
        parametersList.add(Parameter(ConstantExpression(1, 'int')))
        parametersList.add(
            Parameter(
                VariableCallExpression(Symbol('b', arrayinteger, 0), None)))

        st.registerFunction('main', integer, argumentsList, True)
        function = st.getFunction('main', parametersList)
        st.openFunctionScope(function)

        st.closeFunctionScope(function)

        statement = FunctionStatement(function, [], True)

        self.assertEqual(function.getStaticSize(), 9)
        self.assertEqual(function.getParameterSize(), 4)
        self.assertEqual(statement.compile(), "main0:\nssp 9\nretp\n")
    def test_double_alias(self):
        st = SymbolTable()
        integer = IntegerType()

        st.registerAlias('integer', integer)
        self.assertRaises(AliasAlreadyRegisteredError,
                          lambda: st.registerAlias('integer', integer))
    def test_double_symbol_definition(self):
        st = SymbolTable()
        integer = IntegerType()

        st.registerSymbol('integer', integer)
        self.assertRaises(SymbolAlreadyRegisteredError,
                          lambda: st.registerSymbol('integer', integer))
    def test_symbol_address_in_function(self):
        st = SymbolTable()

        integer = IntegerType()
        arrayinteger = ArrayType(integer, 3)

        # Create arguments
        argumentsList = ArgumentsList()

        # Create parameters
        parametersList = ParametersList()

        st.registerFunction('main', integer, argumentsList, 0)
        function = st.getFunction('main', parametersList)

        st.openFunctionScope(function)
        st.registerSymbol('a', integer)
        self.assertEqual(st.getSymbol('a').address, 5)
        st.registerSymbol('b', arrayinteger)
        self.assertEqual(st.getSymbol('b').address, 6)
        st.registerSymbol('c', integer)
        self.assertEqual(st.getSymbol('c').address, 9)
        st.closeFunctionScope(function)

        self.assertEqual(function.getStaticSize(), 10)
        self.assertEqual(function.getParameterSize(), 0)
    def test_function_label(self):
        st = SymbolTable()
        integer = IntegerType()
        real = RealType()
        boolean = BooleanType()
        character = CharacterType()

        # Create arguments
        argumentsList = ArgumentsList()
        argumentsList.add(Argument('a', integer))
        argumentsList.add(Argument('b', real))

        # Create parameters
        parametersList = ParametersList()
        parametersList.add(Parameter(ConstantExpression(1, 'int')))
        parametersList.add(Parameter(ConstantExpression(3.14, 'float')))

        # Register basic function, no arguments
        st.registerFunction('add', integer, argumentsList, True)

        # Check for label
        self.assertEqual(st.getFunction('add', parametersList).label, 'add0')

        # Check for label in scope
        st.openScope()
        st.registerFunction('add', integer, argumentsList, True)
        self.assertEqual(st.getFunction('add', parametersList).label, 'add1')
        st.closeScope()
    def test_alias_register(self):
        st = SymbolTable()
        integer = IntegerType()

        st.registerAlias('integer', integer)
        self.assertEqual(type(st.getAlias('integer').basetype), IntegerType)

        # call unknown alias
        self.assertRaises(AliasNotRegisteredError, lambda: st.getAlias('a'))
    def test_function_scoped(self):
        st = SymbolTable()
        integer = IntegerType()
        real = RealType()
        boolean = BooleanType()
        character = CharacterType()

        # Create arguments
        argumentsList = ArgumentsList()
        argumentsList.add(Argument('a', integer))
        argumentsList.add(Argument('b', real))

        # Create parameters
        parametersList = ParametersList()
        parametersList.add(Parameter(ConstantExpression(1, 'int')))
        parametersList.add(Parameter(ConstantExpression(3.14, 'float')))

        # Register basic function, no arguments
        st.registerFunction('add', integer, argumentsList, True)

        # Call function in main scope
        self.assertEqual(type(st.getFunction('add', parametersList)), Function)

        # open scope and get function again
        st.openScope()
        self.assertEqual(type(st.getFunction('add', parametersList)), Function)

        # register function in scope
        st.registerFunction('divide', integer, argumentsList, True)

        # call new function in scope
        self.assertEqual(type(st.getFunction('add', parametersList)), Function)

        # close scope and call new created function, shouldn't work
        st.closeScope()
        self.assertRaises(FunctionNotRegisteredError,
                          lambda: st.getFunction('divide', parametersList))

        # open scope and register add again
        st.openScope()
        st.registerFunction('add', integer, argumentsList, True)
        self.assertEqual(type(st.getFunction('add', parametersList)), Function)
        self.assertRaises(
            FunctionAlreadyRegisteredError,
            lambda: st.registerFunction('add', integer, argumentsList, True))
        st.closeScope()

        # register function in higher scope and call in lower scope
        st.registerFunction('multiply', integer, argumentsList, True)
        st.openScope()
        self.assertEqual(type(st.getFunction('multiply', parametersList)),
                         Function)
        self.assertRaises(
            FunctionNotRegisteredError,
            lambda: st.getFunction('multiplynotexisting', parametersList))
        st.closeScope
    def test_not_registered_symbol_call(self):
        st = SymbolTable()
        integer = IntegerType()

        self.assertRaises(SymbolNotRegisteredError, lambda: st.getSymbol('a'))

        # open scope and register
        st.openScope()
        st.registerSymbol('a', integer)
        st.closeScope()

        self.assertRaises(SymbolNotRegisteredError, lambda: st.getSymbol('a'))
    def test_function_register_and_get_with_arguments(self):
        st = SymbolTable()
        integer = IntegerType()
        real = RealType()
        boolean = BooleanType()
        character = CharacterType()

        # Create arguments
        argumentsList = ArgumentsList()
        argumentsList.add(Argument('a', integer))
        argumentsList.add(Argument('b', real))

        # Create parameters
        parametersList = ParametersList()
        parametersList.add(Parameter(ConstantExpression(1, 'int')))
        parametersList.add(Parameter(ConstantExpression(3.14, 'float')))

        # fake ParametersList, has one parameters less
        fakeParametersList = ParametersList()
        fakeParametersList.add(Parameter(ConstantExpression(1, 'int')))

        # Register basic function,  arguments
        st.registerFunction('add', integer, argumentsList, True)

        # register function again, shouldn't work
        self.assertRaises(
            FunctionAlreadyRegisteredError,
            lambda: st.registerFunction('add', integer, argumentsList, True))

        # register function again with other return type, shouldn't work
        self.assertRaises(
            FunctionAlreadyRegisteredError,
            lambda: st.registerFunction('add', boolean, argumentsList, True))

        # get basic function
        self.assertEqual(type(st.getFunction('add', parametersList)), Function)

        # get not known function, should not work
        self.assertRaises(FunctionNotRegisteredError,
                          lambda: st.getFunction('hello', parametersList))

        # get the function with no arguments, shouldn't work
        self.assertRaises(FunctionNotRegisteredError,
                          lambda: st.getFunction('add', ParametersList()))

        # get the function with wrong arguments, shouldn't work
        self.assertRaises(FunctionNotRegisteredError,
                          lambda: st.getFunction('add', fakeParametersList))
Beispiel #15
0
def main(argv):
    parser = argparse.ArgumentParser(description='A C to Pcode compiler')
    parser.add_argument('file', help='The c file to be compiled')
    parser.add_argument('-o',
                        '--output',
                        help='Directory to write compiled C file')
    parser.add_argument('-saveast',
                        '--saveast',
                        help='Write the AST to a file',
                        action='store_true')
    parser.add_argument('-showast',
                        '--showast',
                        help='Print AST',
                        action='store_true')
    parser.add_argument('-n',
                        '--nocompile',
                        help='Disable the compilation phase',
                        action='store_true')
    args = vars(parser.parse_args())

    filepath = os.path.split(args["file"])
    filename = os.path.splitext(filepath[1])[0]
    outputpath = ""
    if (args["output"] != None):
        outputpath += args["output"] + "/"

    symboltable = SymbolTable()
    astBuilder = ASTBuilder(args["file"], symboltable)
    ast = astBuilder.build()

    print(symboltable)

    if (bool(args["nocompile"]) == False):
        compiled = ast.compile()

        # Write to file
        file = open(outputpath + filename + ".p", "w")
        file.write(compiled)
        file.close()

    # Should we serialize
    if (args["showast"] == True):
        astBuilder.serialize()

    if (args["saveast"] == True):
        file = open(outputpath + filename + ".ast", "w")
        file.write(astBuilder.serialize())
        file.close()
    def test_register_symbols(self):
        st = SymbolTable()
        integer = IntegerType()
        real = RealType()
        boolean = BooleanType()
        address = AddressType(integer)
        character = CharacterType()
        array = ArrayType(integer, 10)

        st.registerSymbol('int', integer)
        st.registerSymbol('float', real)
        st.registerSymbol('bool', boolean)
        st.registerSymbol('char', character)

        st.registerSymbol('ptr', address)
        st.registerSymbol('array', array)
Beispiel #17
0
def main(argv):
    pcode_file = open('pcode', 'w')
    input_stream = FileStream(argv[1])
    lexer = grammerLexer(input_stream)
    stream = CommonTokenStream(lexer)
    parser = grammerParser(stream)
    tree = parser.r()
    tree.getChildCount()
    symboltable = SymbolTable()
    astBuilder = ASTBuilder(tree, symboltable)
    function_list = astBuilder.build()
    print('mst 0', file=pcode_file)
    print('cup 0 functionmain', file=pcode_file)
    print('hlt', file=pcode_file)
    for function in function_list:
        pcode = function.compiler()
        for line in pcode:
            print(line, file=pcode_file)
Beispiel #18
0
    def test_compile_function_no_arguments_statements(self):
        st = SymbolTable()

        integer = IntegerType()
        arrayinteger = ArrayType(integer, 3)

        # Create arguments
        argumentsList = ArgumentsList()

        # Create parameters
        parametersList = ParametersList()

        st.registerFunction('main', integer, argumentsList, True)
        function = st.getFunction('main', parametersList)
        st.openFunctionScope(function)

        st.closeFunctionScope(function)

        statement = FunctionStatement(function, [], True)

        self.assertEqual(function.getStaticSize(), 5)
        self.assertEqual(function.getParameterSize(), 0)
        self.assertEqual(statement.compile(), "main0:\nssp 5\nretp\n")
    def test_scope_allocated(self):
        st = SymbolTable()

        integer = IntegerType()
        real = RealType()
        boolean = BooleanType()
        character = CharacterType()
        address = AddressType(integer)

        array = ArrayType(integer, 10)

        st.registerSymbol('a', integer)
        st.registerSymbol('b', real)
        st.registerSymbol('c', boolean)
        st.registerSymbol('d', character)
        st.registerSymbol('e', address)

        self.assertEqual(st.scope.allocated, 5)
        self.assertEqual(st.scope.getTotalAllocated(), 5)

        st.openScope()
        st.registerSymbol('a', integer)
        st.registerSymbol('b', real)
        st.registerSymbol('c', boolean)
        st.registerSymbol('d', character)
        st.registerSymbol('e', address)

        self.assertEqual(st.scope.allocated, 5)
        self.assertEqual(st.scope.getTotalAllocated(), 5)
        st.closeScope()

        self.assertEqual(st.scope.allocated, 5)
        self.assertEqual(st.scope.getTotalAllocated(), 10)
        st.registerSymbol('f', array)

        self.assertEqual(st.scope.allocated, 15)
        self.assertEqual(st.scope.getTotalAllocated(), 20)
    def test_function_parameter_size_array_full(self):
        st = SymbolTable()
        integer = IntegerType()
        arrayinteger = ArrayType(integer, 3)

        # Create arguments
        argumentsList = ArgumentsList()
        argumentsList.add(Argument('a', integer))
        argumentsList.add(Argument('b', arrayinteger))

        # Create array
        st.registerSymbol('b', arrayinteger)

        # Create parameters
        parametersList = ParametersList()
        parametersList.add(Parameter(ConstantExpression(1, 'int')))
        parametersList.add(
            Parameter(VariableCallExpression(st.getSymbol('b'), None)))

        # Register basic function, no arguments
        st.registerFunction('add', integer, argumentsList, True)
        function = st.getFunction('add', parametersList)

        self.assertEqual(function.getParameterSize(), 4)
 def test_close_main_scope(self):
     # Should crash
     st = SymbolTable()
     self.assertRaises(ScopeError, lambda: st.closeScope())
 def test_close_too_much_scopes(self):
     st = SymbolTable()
     st.openScope()
     st.closeScope()
     self.assertRaises(ScopeError, lambda: st.closeScope())
Beispiel #23
0
import os
import argparse
from src.ASTBuilder import ASTBuilder
from src.SymbolTable.SymbolTable import SymbolTable

basics = ["and_or", "arithmetic", "bool", "if", "read_write", "while"]
bonus = [
    "break", "continue", "dowhile", "for", "odd", "real", "repeatuntil", "xor"
]
program = ["factorial", "LCM", "prime"]

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("type",
                        type=str,
                        help="type in the func kind you want to test")
    parser.add_argument("test",
                        type=str,
                        help="type in which func you want to test")
    args = parser.parse_args()
    test_path = r"C:\Users\robin\Desktop\CX_compiler\tests\tests_" + args.type + r"\test_" + args.test + ".txt"
    # test_bonus_path = r"C:\Users\robin\Desktop\CX_compiler\tests\tests_bonus\test_" + args.test + ".txt"
    # test_program_path = r"C:\Users\robin\Desktop\CX_compiler\tests\tests_program" + "\\" + args.test + ".txt"
    symbol_table = SymbolTable()
    ast = ASTBuilder(test_path, symbol_table)
    ast = ast.build()
    compiled_codes = ast.compile()
    output_path = r"C:\Users\robin\Desktop\CX_compiler\tests\out.p"
    output_file = open(output_path, "w")
    print(compiled_codes, file=output_file)
 def test_open_and_close_scope(self):
     st = SymbolTable()
     st.openScope()
     st.closeScope()