def handle_call(name, actual_arglist): ''' handle calls for both call statements and call expressions. ''' # unpack the funval and type tuples (FUNVAL, type, formal_arglist, body, context) = symtab.lookup_sym(name) (FUNCTION_TYPE, ret_type, arg_types) = type # set up the environment for static scoping and then execute the function actual_val_args = eval_actual_args(actual_arglist) save_symtab = symtab.get_config() symtab.set_config(context) symtab.push_scope(ret_type) declare_formal_args(formal_arglist, actual_val_args) # execute function return_value = None try: walk(body) except ReturnValue as val: return_value = val.value # NOTE: popping the function scope is not necessary because we # are restoring the original symtab configuration symtab.set_config(save_symtab) return return_value
def id_exp(node): (ID, name) = node val = symtab.lookup_sym(name) return val
def assign_stmt(node): (ASSIGN, (ID, name), exp) = node (t, v) = walk(exp) (CONST, ts, (VALUE, vs)) = symtab.lookup_sym(name) symtab.update_sym(name, ('CONST', ts, ('VALUE', coerce(ts, t)(v)))) return None
def get_stmt(node): (GET, (ID, name)) = node (CONST, type, value) = symtab.lookup_sym(name) s = input("Value for " + name + '? ') try: # cannot use coerce here because that would be going # down the type hierarchy which is not supported if type[0] == 'STRING_TYPE': new_value = s elif type[0] == 'FLOAT_TYPE': new_value = float(s) elif type[0] == 'INTEGER_TYPE': new_value = int(s) else: raise ValueError("input not supported for this type") except ValueError: raise ValueError("expected a {} value for {}".format(type[0], name)) symtab.update_sym(name, ('CONST', type, ('VALUE', new_value))) return None
def id_exp(node): (ID, name) = node (CONST, type, (VALUE, value)) = symtab.lookup_sym(name) return (type, value)