def value_fn(ins): """ FN: get value of user-defined function. """ fnname = util.get_var_name(ins) try: varnames, fncode = state.basic_state.functions[fnname] except KeyError: raise error.RunError(error.UNDEFINED_USER_FUNCTION) # save existing vars varsave = {} for name in varnames: if name in state.basic_state.variables: # copy the *value* - set_var is in-place it's safe for FOR loops varsave[name] = state.basic_state.variables[name][:] # read variables if util.skip_white_read_if(ins, ('(',)): exprs = parse_expr_list(ins, len(varnames), err=error.STX) if None in exprs: raise error.RunError(error.STX) for i in range(len(varnames)): var.set_var(varnames[i], exprs[i]) util.require_read(ins, (')',)) # execute the code fns = StringIO(fncode) fns.seek(0) value = parse_expression(fns) # restore existing vars for name in varsave: # re-assign the stored value state.basic_state.variables[name][:] = varsave[name] return value
def value_fn(ins): """ FN: get value of user-defined function. """ fnname = util.get_var_name(ins) try: varnames, fncode = state.basic_state.functions[fnname] except KeyError: raise error.RunError(error.UNDEFINED_USER_FUNCTION) # save existing vars varsave = {} for name in varnames: if name in state.basic_state.variables: # copy the *value* - set_var is in-place it's safe for FOR loops varsave[name] = state.basic_state.variables[name][:] # read variables if util.skip_white_read_if(ins, ('(', )): exprs = parse_expr_list(ins, len(varnames), err=error.STX) if None in exprs: raise error.RunError(error.STX) for i in range(len(varnames)): var.set_var(varnames[i], exprs[i]) util.require_read(ins, (')', )) # execute the code fns = StringIO(fncode) fns.seek(0) value = parse_expression(fns) # restore existing vars for name in varsave: # re-assign the stored value state.basic_state.variables[name][:] = varsave[name] return value
def loop_init(ins, forpos, nextpos, varname, start, stop, step): """ Initialise a FOR loop. """ # set start to start-step, then iterate - slower on init but allows for faster iterate var.set_var(varname, vartypes.number_add(start, vartypes.number_neg(step))) # NOTE: all access to varname must be in-place into the bytearray - no assignments! sgn = vartypes.unpack_int(vartypes.number_sgn(step)) state.basic_state.for_next_stack.append((forpos, nextpos, varname[-1], state.basic_state.variables[varname], number_unpack(stop), number_unpack(step), sgn)) ins.seek(nextpos)
def set_gwbasic_vars(self, dictionary): """ Retrieve variables from Python script """ for new_var_name, new_var_value in dictionary.iteritems(): var_name = self.name_recover(new_var_name) if type(new_var_value) == str: if var_name[-1] != '$': raise Exception("Type mismatch. Variable name is %s, but a string value was received (%s)" % (new_var_name , new_var_value)) ins = cStringIO.StringIO(var_name) var_name = util.get_var_name(ins) var.set_var(var_name, vartypes.pack_string(bytearray(new_var_value + "\0"))) elif type(new_var_value) == int: if var_name[-1] != '%': raise Exception("Type mismatch. Variable name is %s, but a integer value was received (%d)" % (new_var_name , new_var_value)) ins = cStringIO.StringIO(var_name) var_name = util.get_var_name(ins) var.set_var(var_name, vartypes.pack_int(new_var_value)) elif type(new_var_value) == float: if var_name[-1] == '!': ins = cStringIO.StringIO(var_name) var_name = util.get_var_name(ins) bytearray_val = fp.Single.from_value(new_var_value).to_bytes() var.set_var(var_name, ('!', bytearray_val)) elif var_name[-1] == '#': ins = cStringIO.StringIO(var_name) var_name = util.get_var_name(ins) bytearray_val = fp.Double.from_value(new_var_value).to_bytes() var.set_var(var_name, ('#', bytearray_val)) else: raise Exception("Type mismatch. Variable name is %s, but a floating-point value was received (%f)" % (new_var_name , new_var_value)) elif type(new_var_value) == list: matrix = np.array(new_var_value) dimensions = matrix.shape if var_name in state.basic_state.arrays.keys(): var.erase_array(var_name) dimensions = [x for x in dimensions] var.dim_array(var_name, dimensions) indexes = [list(xrange(d)) for d in dimensions] indexes = list(itertools.product(*indexes)) for index in indexes: item_value = new_var_value for coord in index: item_value = item_value[coord] if var_name[-1] == '$': matrix_element = vartypes.pack_string(bytearray(item_value + "\0")) elif var_name[-1] == '%': matrix_element = vartypes.pack_int(item_value) elif var_name[-1] == '!': matrix_element = ( '!', fp.Single.from_value(item_value).to_bytes()) elif var_name[-1] == '#': matrix_element = ('#', fp.Double.from_value(item_value).to_bytes()) else: raise Exception("Array type unknown for variable %s" % new_var_name) try: var.set_var_or_array(var_name, index, matrix_element) except: import traceback traceback.print_exc() else: logging.debug('Received variable was not processed: %s.', new_var_name)