Example #1
0
    def test_make_node(self):
        self.clearOutput()
        l = symbols.NUMBER(2, lineno=1)
        u = symbols.NUMBER(3, lineno=2)
        symbols.BOUND.make_node(l, u, 3)
        self.assertEqual(self.stderr, '')

        l = symbols.NUMBER(4, lineno=1)
        symbols.BOUND.make_node(l, u, 3)
        self.assertEqual(
            self.stderr,
            '(stdin):3: Lower array bound must be less or equal to upper one\n'
        )

        self.clearOutput()
        l = symbols.NUMBER(-4, lineno=1)
        symbols.BOUND.make_node(l, u, 3)
        self.assertEqual(self.stderr,
                         '(stdin):3: Array bounds must be greater than 0\n')

        self.clearOutput()
        l = symbols.VAR('a', 10)
        symbols.BOUND.make_node(l, u, 3)
        self.assertEqual(self.stderr,
                         '(stdin):3: Array bounds must be constants\n')
Example #2
0
    def declare_variable(self, id_, lineno, type_, default_value=None):
        """ Like the above, but checks that entry.declared is False.
        Otherwise raises an error.

        Parameter default_value specifies an initialized variable, if set.
        """
        assert isinstance(type_, symbols.TYPEREF)
        if not self.check_is_undeclared(id_, lineno, scope=self.current_scope, show_error=False):
            entry = self.get_entry(id_)
            if entry.scope == SCOPE.parameter:
                syntax_error(lineno,
                             "Variable '%s' already declared as a parameter "
                             "at %s:%i" % (id_, entry.filename, entry.lineno))
            else:
                syntax_error(lineno, "Variable '%s' already declared at "
                                     "%s:%i" % (id_, entry.filename, entry.lineno))
            return None

        if not self.check_class(id_, CLASS.var, lineno, scope=self.current_scope):
            return None

        entry = (self.get_entry(id_, scope=self.current_scope) or
                 self.declare(id_, lineno, symbols.VAR(id_, lineno, class_=CLASS.var)))
        __DEBUG__("Entry %s declared with class %s at scope %i" % (entry.name, CLASS.to_string(entry.class_),
                                                                   self.current_scope))

        if entry.type_ is None or entry.type_ == self.basic_types[TYPE.unknown]:
            entry.type_ = type_

        if entry.type_ != type_:
            if not type_.implicit and entry.type_ is not None:
                syntax_error(lineno,
                             "'%s' suffix is for type '%s' but it was "
                             "declared as '%s'" %
                             (id_, entry.type_, type_))
                return None

        entry.scope = SCOPE.global_ if self.current_scope == self.global_scope else SCOPE.local
        entry.callable = False
        entry.class_ = CLASS.var  # HINT: class_ attribute could be erased if access_id was used.
        entry.declared = True  # marks it as declared

        if entry.type_.implicit and entry.type_ != self.basic_types[TYPE.unknown]:
            warning_implicit_type(lineno, id_, entry.type_.name)

        if default_value is not None and entry.type_ != default_value.type_:
            if is_number(default_value):
                default_value = symbols.TYPECAST.make_node(entry.type_, default_value,
                                                           lineno)
                if default_value is None:
                    return None
            else:
                syntax_error(lineno,
                             "Variable '%s' declared as '%s' but initialized "
                             "with a '%s' value" %
                             (id_, entry.type_, default_value.type_))
                return None

        entry.default_value = default_value
        return entry
Example #3
0
 def setUp(self):
     zxbpp.init()
     self.l = symbols.VAR('a', lineno=1, type_=Type.ubyte)
     self.r = symbols.NUMBER(3, lineno=2)
     self.b = symbols.BINARY('PLUS', self.l, self.r, lineno=3)
     self.st = symbols.STRING("ZXBASIC", lineno=1)
     if OPTIONS.has_option('stderr'):
         OPTIONS.remove_option('stderr')
     OPTIONS.add_option('stderr', type_=None, default_value=StringIO())
Example #4
0
 def test_make_node_wrong(self):
     bad_index = symbols.VAR(
         'a', 0, type_=gl.SYMBOL_TABLE.basic_types[gl.TYPE.string])
     s = symbols.STRSLICE.make_node(1, self.str_, bad_index, bad_index)
     self.assertIsNone(s)
Example #5
0
 def setUp(self):
     self.v = symbols.VAR('v', 1)  # This also tests __init__