Exemplo n.º 1
0
def assign_stmt(node):

    (ASSIGN, oper, rexp) = node
    assert_match(ASSIGN, 'assign')
    (OPER, lexp, fix) = oper

    if lexp[0] == 'id':  #('id', name)
        # grab everything we know about variable named id
        name = lexp[1]
        (sym_type, data_type, val) = state.symbol_table.lookup_sym(name)

        # compute rhs value of assignment stmt
        (t1, v1, p1) = walk(oper)
        (t2, v2, p2) = walk(rexp)
        if not safe_assign(data_type, t2):
            raise ValueError(\
                "a value of type {} cannot be assigned to the variable {} of type {}"\
                .format(t2,name,data_type))

        # update symbol table with new value
        value = (sym_type, data_type, conversion_fun(data_type, t2)(v2))
        state.symbol_table.update_sym(name, value)
        handle_suffix(p1 + p2)

    elif lexp[0] == 'array-access':  # ('array-access', id, exp)
        # grab everything we know about the array named id
        name = lexp[1]
        (ARRAY_VAL, data_type, memory) = state.symbol_table.lookup_sym(name)
        if ARRAY_VAL != 'array-val':  # make sure we are seeing an array-val
            raise ValueError("cannot index non-array {}".format(name))
        (ARRAY_TYPE, size_val, elem_type) = data_type
        assert_match(ARRAY_TYPE, 'array-type')

        # grab the index expression value and do error checking
        (ix_type, ix_val) = walk(lexp[2])
        if ix_type[0] != 'integer':
            raise ValueError("illegal index value {}".format(ix_val))
        if ix_val not in range(size_val):
            raise ValueError("index {} for {} out of bounds".format(
                ix_val, name))

        # compute the rhs value of the assignment stmt
        (t1, v1, p1) = walk(lexp)
        (t2, v2, p2) = walk(rexp)
        if not safe_assign(elem_type, t2):
            raise ValueError(\
                "a value of type {} cannot be assigned to the elements of {} of type {}"\
                .format(t2,name,elem_type))

        # update the memory cell for this array access
        memory[ix_val] = conversion_fun(elem_type, t2)(v2)
        handle_suffix(p1 + p2)

    else:
        raise ValueError("illegal left side {} of assignment".format(lexp[0]))
Exemplo n.º 2
0
    def declare_array(self, sym, array_type, init_val):
        '''
        declare an array in the current scope.
        '''
        # first we need to check whether the symbol was already declared
        # at this scope
        if sym in self.scoped_symtab[CURR_SCOPE]:
            raise ValueError("symbol {} already declared".format(sym))

        # unpack the array type
        (ARRAY_TYPE, size, elem_type) = array_type

        # look at the initializer
        if init_val[0] == 'nil':
            memory = [
                conversion_fun(elem_type, ('integer', ))(0)
                for i in range(size)
            ]
        else:
            memory = _compute_array_initializer(elem_type, init_val)
            if len(memory) != size:
                raise ValueError("size of initializer does not match array {}"\
                                 .format(sym))

        # declare symbol in current scope
        val = ('array-val', array_type, memory)
        self.scoped_symtab[CURR_SCOPE].update({sym: val})
Exemplo n.º 3
0
    def declare_scalar(self, sym, data_type, init_val):
        '''
        declare a scalar in the current scope.
        '''
        # first we need to check whether the symbol was already declared
        # at this scope
        if sym in self.scoped_symtab[CURR_SCOPE]:
            raise ValueError("symbol {} already declared".format(sym))

        # look at init value
        if init_val[0] == 'nil':
            init_val = conversion_fun(data_type, ('integer', ))(0)
        else:
            (t, v, post) = init_val
            if safe_assign(data_type, t):
                init_val = conversion_fun(data_type, t)(v)
            else:
                raise ValueError("illegal init value {}".format(v))

        # enter the symbol with its value in the current scope
        val = ('scalar-val', data_type, init_val)
        self.scoped_symtab[CURR_SCOPE].update({sym: val})
Exemplo n.º 4
0
def _compute_array_initializer(elem_type, initializer):
    '''
    array initializers come in two flavors:
    (a) as a list of values
    (b) as an expression that represent sufficient init values for the array
    here we check and compute the actual memory for the array.
    '''
    if initializer[0] == 'nil':
        return []
    elif initializer[0] == 'seq':
        (SEQ, (t, v), next) = initializer
        if not safe_assign(elem_type, t):
            raise ValueError(\
                "illegal array initializer {}"\
                .format(v))
        return [conversion_fun(elem_type, t)(v)] + _compute_array_initializer(
            elem_type, next)
    elif initializer[0][0] == 'array-type':
        return list(initializer[1])
    else:
        raise ValueError("illegal array initializer {}".format(initializer))