def declare_param(self, id_: str, lineno: int, type_=None, is_array=False): """ Declares a parameter Check if entry.declared is False. Otherwise raises an error. """ if not self.check_is_undeclared(id_, lineno, classname='parameter', scope=self.current_scope, show_error=True): return None if is_array: entry = self.declare( id_, lineno, symbols.VARARRAY(id_, symbols.BOUNDLIST(), lineno, None, type_)) entry.callable = True entry.scope = SCOPE.parameter else: entry = self.declare(id_, lineno, symbols.PARAMDECL(id_, lineno, type_)) if entry is None: return entry.declared = True if entry.type_.implicit: warning_implicit_type(lineno, id_, type_) return entry
def declare_array(self, id_, lineno, type_, bounds, default_value=None, addr=None): """ Declares an array in the symbol table (VARARRAY). Error if already exists. The optional parameter addr specifies if the array elements must be placed at an specific (constant) memory address. """ assert isinstance(type_, symbols.TYPEREF) assert isinstance(bounds, symbols.BOUNDLIST) if not self.check_class(id_, CLASS.array, lineno, scope=self.current_scope): return None entry = self.get_entry(id_, self.current_scope) if entry is None: entry = self.declare(id_, lineno, symbols.VARARRAY(id_, bounds, lineno, type_=type_)) if not entry.declared: if entry.callable: syntax_error(lineno, "Array '%s' must be declared before use. " "First used at line %i" % (id_, entry.lineno)) return None else: if entry.scope == SCOPE.parameter: syntax_error(lineno, "variable '%s' already declared as a " "parameter at line %i" % (id_, entry.lineno)) else: syntax_error(lineno, "variable '%s' already declared at " "line %i" % (id_, entry.lineno)) return None if entry.type_ != self.basic_types[TYPE.unknown] and entry.type_ != type_: if not type_.implicit: syntax_error(lineno, "Array suffix for '%s' is for type '%s' " "but declared as '%s'" % (entry.name, entry.type_, type_)) return None type_.implicit = False type_ = entry.type_ if type_.implicit: warning_implicit_type(lineno, id_, type_) if not isinstance(entry, symbols.VARARRAY): entry = symbols.VAR.to_vararray(entry, bounds) entry.declared = True entry.type_ = type_ entry.scope = SCOPE.global_ if self.current_scope == self.global_scope else SCOPE.local entry.default_value = default_value entry.callable = True entry.class_ = CLASS.array entry.lbound_used = entry.ubound_used = False # Flag to true when LBOUND/UBOUND used somewhere in the code entry.addr = addr __DEBUG__('Entry %s declared with class %s at scope %i' % (id_, CLASS.to_string(entry.class_), self.current_scope)) return entry
def setUp(self): zxbpp.init() l1 = 1 l2 = 2 l3 = 3 l4 = 4 b = symbols.BOUND(l1, l2) c = symbols.BOUND(l3, l4) self.bounds = symbols.BOUNDLIST.make_node(None, b, c) self.arr = symbols.VARARRAY('test', self.bounds, 1, type_=Type.ubyte) self.arg = symbols.ARGLIST(symbols.ARGUMENT(symbols.NUMBER(2, 1, type_=Type.uinteger), 1), symbols.ARGUMENT(symbols.NUMBER(3, 1, type_=Type.uinteger), 1)) gl.SYMBOL_TABLE = SymbolTable() # Clears stderr and prepares for capturing it config.OPTIONS.remove_option('stderr') config.OPTIONS.add_option('stderr', None, StringIO()) config.OPTIONS.add_option_if_not_defined('explicit', None, False)
def test_entry__setter(self): aa = symbols.ARRAYACCESS(self.arr, self.arg, 2) ar2 = symbols.VARARRAY('test2', self.bounds, 1, type_=Type.ubyte) aa.entry = ar2 self.assertIs(aa.entry, ar2)
def test_memsize(self): arr = symbols.VARARRAY('test', self.bounds, 1, type_=Type.ubyte) self.assertEqual(arr.memsize, 2 * TYPE.size(gl.PTR_TYPE))
def test_size(self): arr = symbols.VARARRAY('test', self.bounds, 1, type_=Type.ubyte) self.assertEqual(arr.size, arr.type_.size * arr.count)
def test_count(self): arr = symbols.VARARRAY('test', self.bounds, 1) self.assertEqual( arr.count, functools.reduce(lambda x, y: x * y, (x.count for x in self.bounds)))
def test_bounds(self): arr = symbols.VARARRAY('test', self.bounds, 1) self.assertEqual(arr.bounds, self.bounds)
def test__init__(self): arr = symbols.VARARRAY('test', self.bounds, 1, type_=Type.ubyte) self.assertEqual(arr.class_, CLASS.array) self.assertEqual(arr.type_, Type.ubyte)
def test_memsize(self): arr = symbols.VARARRAY('test', self.bounds, 1, type_=Type.ubyte) self.assertEqual( arr.memsize, arr.size + 1 + TYPE.size(gl.BOUND_TYPE) * len(arr.bounds))