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
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
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
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
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
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))))
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
def declare_formal_args(formal_args): (LIST, fl) = formal_args for (FORMALARG, type, (ID, f)) in fl: symtab.declare(f, type)