Example #1
0
def vardecl_stmt(node):

    (VARDECL, (ID, name), type, init_val) = node

    (ti, vi) = walk(init_val)
    symtab.declare(name, ('CONST', type, ('VALUE', coerce(type, ti)(vi))))

    return None
Example #2
0
def fundecl_stmt(node):

    (FUNDECL, (ID, name), type, arglist, body) = node

    context = symtab.get_config()
    funval = ('FUNVAL', type, arglist, body, context)
    symtab.declare(name, funval)

    return None
Example #3
0
def vardecl_stmt(node):

    (VARDECL, (ID, name), type, init_val) = node

    ti = walk(init_val)
    if not safe_assign(type, ti):
        raise ValueError(
            "type {} of initializer is not compatible with declaration type {}"
            .format(ti[0], type[0]))
    symtab.declare(name, type)
    return None
Example #4
0
def arraydecl_stmt(node):

    (ARRAYDECL, (ID, name), array_type, (LIST, init_val_list)) = node

    # we use the memory allocated for the list of initializers
    # as the memory for the array in the symbol table.
    # therefore we bind the list into the symbol table as
    # part of the declaration
    # Note: we only bind actual Python values into the symbol table,
    # therefore we need to convert the init_val_list into a list of values.

    symtab.declare(name, ('ARRAYVAL', array_type,
                          ('LIST', value_list(init_val_list))))

    return None
Example #5
0
def fundecl_stmt(node):

    (FUNDECL, (ID, name), type, arglist, body) = node

    symtab.declare(name, type)

    # unpack function type
    (FUNCTION_TYPE, ret_type, arglist_types) = type

    # typecheck body of function
    symtab.push_scope(ret_type=ret_type)
    declare_formal_args(arglist)
    walk(body)
    symtab.pop_scope()

    return None
Example #6
0
def declare_formal_args(formal_args, actual_val_args):
    '''
    Walk the formal argument list and declare the identifiers on that
    list using the corresponding actual args as initial values.
    NOTE: this is where we implement by-value argument passing for
          non-array arguments and by-reference passing for array arguments
    NOTE: the type coercion on scalars implements subtype polymorphism for functions
    '''
    (LIST, fl) = formal_args
    (LIST, avl) = actual_val_args

    for ((FORMALARG, tf, (ID, fs)), (ta, va)) in zip(fl, avl):
        # arrays are called by-reference, we use the memory
        # of the actual argument to declare the formal argument array
        if tf[0] == 'ARRAY_TYPE':
            symtab.declare(fs, ('ARRAYVAL', tf, ('LIST', va)))
        else:
            symtab.declare(fs, ('CONST', tf, ('VALUE', coerce(tf, ta)(va))))
Example #7
0
def arraydecl_stmt(node):

    (ARRAYDECL, (ID, name), type, (LIST, init_val_list)) = node
    (ARRAY_TYPE, base_type, (SIZE, size)) = type

    if not size > 0:
        raise ValueError("illegal array size")

    if len(init_val_list) != size:
        raise ValueError(
            "array size {} and length of initializer {} don't agree".format(
                size, len(init_val_list)))

    # walk through initializers and make sure they are type safe
    for ix in range(size):
        ti = walk(init_val_list[ix])
        if not safe_assign(base_type, ti):
            raise ValueError(
                "type {} of initializer is not compatible with declaration type {}"
                .format(ti[0], base_type[0]))

    symtab.declare(name, type)

    return None
Example #8
0
def declare_formal_args(formal_args):
    (LIST, fl) = formal_args

    for (FORMALARG, type, (ID, f)) in fl:
        symtab.declare(f, type)