def test_double_symbol_definition(self): st = SymbolTable() integer = IntegerType() st.registerSymbol('integer', integer) self.assertRaises(SymbolAlreadyRegisteredError, lambda: st.registerSymbol('integer', integer))
def test_double_alias(self): st = SymbolTable() integer = IntegerType() st.registerAlias('integer', integer) self.assertRaises(AliasAlreadyRegisteredError, lambda: st.registerAlias('integer', integer))
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_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_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_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()))
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))
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 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_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 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)
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_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_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_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_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_close_main_scope(self): # Should crash st = SymbolTable() self.assertRaises(ScopeError, lambda: st.closeScope())
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_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_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)
def test_open_and_close_scope(self): st = SymbolTable() st.openScope() st.closeScope()
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_close_too_much_scopes(self): st = SymbolTable() st.openScope() st.closeScope() self.assertRaises(ScopeError, lambda: st.closeScope())
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