def ml_parse_value(gmls, default=None): """ Parse a value in a macro-language string. """ c = util.skip(gmls, ml_whitepace) sgn = -1 if c == '-' else 1 if c in ('+', '-'): gmls.read(1) c = util.peek(gmls) # don't allow default if sign is given default = None if c == '=': gmls.read(1) c = util.peek(gmls) if len(c) == 0: raise error.RunError(error.IFC) elif ord(c) > 8: name = util.get_var_name(gmls) indices = ml_parse_indices(gmls) step = var.get_var_or_array(name, indices) util.require_read(gmls, (';',), err=error.IFC) else: # varptr$ step = get_value_for_varptrstr(gmls.read(3)) elif c and c in string.digits: step = ml_parse_const(gmls) elif default is not None: step = default else: raise error.RunError(error.IFC) if sgn == -1: step = vartypes.number_neg(step) return step
def ml_parse_value(gmls, default=None): """ Parse a value in a macro-language string. """ c = util.skip(gmls, ml_whitepace) sgn = -1 if c == '-' else 1 if not c: raise error.RunError(error.IFC) if c in ('+', '-'): gmls.read(1) c = util.peek(gmls) # don't allow default if sign is given default = None if c == '=': gmls.read(1) c = util.peek(gmls) if len(c) == 0: raise error.RunError(error.IFC) elif ord(c) > 8: name = util.get_var_name(gmls) indices = ml_parse_indices(gmls) step = var.get_var_or_array(name, indices) util.require_read(gmls, (';',), err=error.IFC) else: # varptr$ step = get_value_for_varptrstr(gmls.read(3)) elif c in representation.ascii_digits: step = ml_parse_const(gmls) elif default is not None: step = default else: raise error.RunError(error.IFC) if sgn == -1: step = vartypes.number_neg(step) return step
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 get_var_or_array_name(ins): """ Helper function: parse a variable or array name. """ name = util.get_var_name(ins) indices = [] if util.skip_white_read_if(ins, ('[', '(')): # it's an array, read indices indices = parse_int_list(ins, 255, 9) # subscript out of range while len(indices) > 0 and indices[-1] is None: indices = indices[:-1] if None in indices: raise error.RunError(error.STX) util.require_read(ins, (']', ')')) return name, indices
def ml_parse_string(gmls): """ Parse a string value in a macro-language string. """ c = util.skip(gmls, ml_whitepace) if len(c) == 0: raise error.RunError(error.IFC) elif ord(c) > 8: name = util.get_var_name(gmls, err=error.IFC) indices = ml_parse_indices(gmls) sub = var.get_var_or_array(name, indices) util.require_read(gmls, (';',), err=error.IFC) return vartypes.pass_string_unpack(sub, err=error.IFC) else: # varptr$ return vartypes.pass_string_unpack(get_value_for_varptrstr(gmls.read(3)))
def ml_parse_string(gmls): """ Parse a string value in a macro-language string. """ c = util.skip(gmls, ml_whitepace) if len(c) == 0: raise error.RunError(error.IFC) elif ord(c) > 8: name = util.get_var_name(gmls) indices = ml_parse_indices(gmls) sub = var.get_var_or_array(name, indices) util.require_read(gmls, (';',), err=error.IFC) return vartypes.pass_string_unpack(sub, err=error.IFC) else: # varptr$ return vartypes.pass_string_unpack(get_value_for_varptrstr(gmls.read(3)))
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)