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 __init__(self, leftExpression, rightExpression, operation): Expression.__init__(self, None) self.operation = operation self.leftExpression = leftExpression self.rightExpression = rightExpression # Determine the type of the expression # check if types of 2 expressions are the same if (self.leftExpression.basetype != self.rightExpression.basetype): raise RuntimeError( "The two types of the expressions in the logic expression should be the same" ) if (not isinstance(self.leftExpression.basetype, BooleanType)): raise RuntimeError( "Left side of logic expression should be a bool, now: " + str(type(self.leftExpression.basetype))) if (not isinstance(self.rightExpression.basetype, BooleanType)): raise RuntimeError( "Right side of logic expression should be a bool, now: " + str(type(self.rightExpression.basetype))) # set the type of this expression self.basetype = BooleanType()
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_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_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_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_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 buildType(self, tree): """Build Type""" token = None basetype = None if (tree.getChildCount() == 1): token = tree.getChild(0).getPayload() if (not isinstance(token, Token)): raise RuntimeError("Invalid type identifier: '" + tree.getText() + "'") if (token.type == CLexer.VOID): return VoidType() elif (token.type == CLexer.IDENTIFIER): if (tree.getChild(0).getText() == "bool"): return BooleanType() elif (tree.getChild(0).getText() == "char"): return CharacterType() elif (tree.getChild(0).getText() == "int"): return IntegerType() elif (tree.getChild(0).getText() == "float"): return RealType() elif (tree.getChild(0).getText() == "double"): return RealType() else: # Alias, check the symbol Table return self.sym.getAlias( tree.getChild(0).getText()).basetype else: raise RuntimeError("Invalid type identifier: '" + tree.getText() + "'") elif (tree.getChildCount() == 2): token = tree.getChild(0).getPayload() # Const Type if (isinstance(token, Token) and token.type == CLexer.CONST): return self.buildType(tree.getChild(1)).setConst(True) token = tree.getChild(1).getPayload() if (not isinstance(token, Token)): raise RuntimeError("Invalid type identifier: '" + tree.getText() + "'") if (token.type == CLexer.STAR): return AddressType(self.buildType(tree.getChild(0))) elif (token.type == CLexer.CONST): return self.buildType(tree.getChild(0)).setConst(True) else: raise RuntimeError("Invalid type identifier: '" + tree.getText() + "'") else: raise RuntimeError("Invalid type identifier: '" + tree.getText() + "'")
def __init__(self, leftExpression, rightExpression, operation): Expression.__init__(self, None) self.operation = operation self.leftExpression = leftExpression self.rightExpression = rightExpression # Determine the type of the expression # check if types of 2 expressions are the same if(self.leftExpression.basetype != self.rightExpression.basetype): raise RuntimeError("The two types of the expressions in the arithmetic expression should be the same") # set the type of this expression self.basetype = BooleanType()
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_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 __init__(self, value, basetype): Expression.__init__(self, None) if(basetype == "bool"): self.basetype = BooleanType() self.value = BooleanData(value) elif(basetype == "char"): self.basetype = CharacterType() self.value = CharacterData(value) elif(basetype == "int"): self.basetype = IntegerType() self.value = IntegerData(value) elif(basetype == "float"): self.basetype = RealType() self.value = RealData(value) elif(basetype == "string"): self.basetype = AddressType(ArrayType(CharacterType(), len(value))) self.value = StringData(value + "\0") else: raise RuntimeError("Trying to create constantexpession with unkown type")
def compile(self): self.sym.openLoop() # Get begin and end label begin = self.sym.getBeginLoop() end = self.sym.getEndLoop() code = "" # compile the initial expression if (self.initExpression != None): code += self.initExpression.compile() # Mark begin of loop code += str(begin) + ":\n" # Check if check is an boolean Expression if (type(self.checkExpression.basetype) != type(BooleanType())): raise RuntimeError( "Check condition in for loop should be of boolean type") # Compile check code += self.checkExpression.compile() code += "fjp " + str(end) + "\n" # Compile the statement code += self.statement.compile() # compile the update code += self.updateExpression.compile() # Jump to begin with unconditional Jump code += "ujp " + str(begin) + "\n" # Mark end of for loop code += str(end) + ":\n" self.sym.closeLoop() return code
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)