def value_to_str_keep(inp, screen=False, write=False, allow_empty_expression=False): """ Convert BASIC number to BASIC string. """ # screen=False means in a program listing # screen=True is used for screen, str$ and sequential files if not inp: if allow_empty_expression: return ('$', '') else: raise error.RunError(error.STX) typechar = inp[0] if typechar == '$': return ('$', inp[1]) elif typechar == '%': if screen and not write and vartypes.unpack_int(inp) >= 0: return ('$', ' ' + str(vartypes.unpack_int(inp))) else: return ('$', str(vartypes.unpack_int(inp))) elif typechar == '!': return ('$', float_to_str(fp.unpack(inp), screen, write)) elif typechar == '#': return ('$', float_to_str(fp.unpack(inp), screen, write)) else: raise error.RunError(error.STX)
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 value_sgn(ins): """ SGN: get sign. """ inp = vartypes.pass_number_keep(parse_bracket(ins)) if inp[0] == '%': inp_int = vartypes.unpack_int(inp) return vartypes.pack_int(0 if inp_int==0 else (1 if inp_int > 0 else -1)) else: return vartypes.pack_int(fp.unpack(inp).sign() )
def vcaret(left, right): """ Left^right. """ if (left[0] == '#' or right[0] == '#') and option_double: return fp.pack( fp.power(fp.unpack(vartypes.pass_double_keep(left)), fp.unpack(vartypes.pass_double_keep(right))) ) else: if right[0] == '%': return fp.pack( fp.unpack(vartypes.pass_single_keep(left)).ipow_int(vartypes.unpack_int(right)) ) else: return fp.pack( fp.power(fp.unpack(vartypes.pass_single_keep(left)), fp.unpack(vartypes.pass_single_keep(right))) )
def value_sgn(ins): """ SGN: get sign. """ inp = vartypes.pass_number_keep(parse_bracket(ins)) if inp[0] == '%': inp_int = vartypes.unpack_int(inp) return vartypes.pack_int(0 if inp_int == 0 else ( 1 if inp_int > 0 else -1)) else: return vartypes.pack_int(fp.unpack(inp).sign())
def value_to_str_keep(inp, screen=False, write=False, allow_empty_expression=False): """ Convert BASIC number to BASIC string. """ # screen=False means in a program listing # screen=True is used for screen, str$ and sequential files if not inp: if allow_empty_expression: return ('$', '') else: raise error.RunError(2) typechar = inp[0] if typechar == '$': return ('$', inp[1]) elif typechar == '%': if screen and not write and vartypes.unpack_int(inp) >= 0: return ('$', ' '+ int_to_str(vartypes.unpack_int(inp)) ) else: return ('$', int_to_str(vartypes.unpack_int(inp))) elif typechar == '!': return ('$', float_to_str(fp.unpack(inp), screen, write) ) elif typechar == '#': return ('$', float_to_str(fp.unpack(inp), screen, write) ) else: raise error.RunError(2)
def vcaret(left, right): """ Left^right. """ if (left[0] == '#' or right[0] == '#') and option_double: return fp.pack( fp.power(fp.unpack(vartypes.pass_double_keep(left)), fp.unpack(vartypes.pass_double_keep(right)))) else: if right[0] == '%': return fp.pack( fp.unpack(vartypes.pass_single_keep(left)).ipow_int( vartypes.unpack_int(right))) else: return fp.pack( fp.power(fp.unpack(vartypes.pass_single_keep(left)), fp.unpack(vartypes.pass_single_keep(right))))
def number_unpack(value): """ Unpack a number value. """ if value[0] in ('#', '!'): return fp.unpack(value) else: return vartypes.unpack_int(value)