예제 #1
0
def value_erdev(ins):
    """ ERDEV$: device error string; not implemented. """
    logging.warning("ERDEV or ERDEV$ function not implemented.")
    if util.skip_white_read_if(ins, ('$',)):
        return vartypes.null('$')
    else:
        return vartypes.null('%')
예제 #2
0
def value_erdev(ins):
    """ ERDEV$: device error string; not implemented. """
    logging.warning("ERDEV or ERDEV$ function not implemented.")
    if util.skip_white_read_if(ins, ('$', )):
        return vartypes.null('$')
    else:
        return vartypes.null('%')
예제 #3
0
def get_scalar(name):
    """ Retrieve the value of a scalar variable. """
    name = vartypes.complete_name(name)
    try:
        return (name[-1], state.basic_state.variables[name])
    except KeyError:
        return vartypes.null(name[-1])
예제 #4
0
파일: var.py 프로젝트: gilsim12/pcbasic
def get_scalar(name):
    """ Retrieve the value of a scalar variable. """
    name = vartypes.complete_name(name)
    try:
        return (name[-1], state.basic_state.variables[name])
    except KeyError:
        return vartypes.null(name[-1])
예제 #5
0
파일: devices.py 프로젝트: gilsim12/pcbasic
 def read_var(self, name):
     """ Read the value for a variable from a file (INPUT#). """
     typechar = name[0][-1]
     value, sep = self._input_entry(typechar, allow_past_end=False)
     if value is None:
         value = vartypes.null(typechar)
     return value, sep
예제 #6
0
def set_scalar(name, value=None):
    """ Assign a value to a variable. """
    name = vartypes.complete_name(name)
    type_char = name[-1]
    if value is not None:
        value = vartypes.pass_type(type_char, value)
    # update memory model
    # check if garbage needs collecting before allocating memory
    if name not in state.basic_state.var_memory:
        # don't add string length, string already stored
        size = (max(3, len(name)) + 1 + vartypes.byte_size[type_char])
        check_free_memory(size, error.OUT_OF_MEMORY)
        # first two bytes: chars of name or 0 if name is one byte long
        name_ptr = state.basic_state.var_current
        # byte_size first_letter second_letter_or_nul remaining_length_or_nul
        var_ptr = name_ptr + max(3, len(name)) + 1
        state.basic_state.var_current += max(3, len(name)) + 1 + vartypes.byte_size[name[-1]]
        state.basic_state.var_memory[name] = (name_ptr, var_ptr)
    # don't change the value if just checking allocation
    if value is None:
        if name in state.basic_state.variables:
            return
        else:
            value = vartypes.null(type_char)
    # copy buffers
    try:
        # in-place copy is crucial for FOR
        state.basic_state.variables[name][:] = value[1][:]
    except KeyError:
        # copy into new buffer if not existing
        state.basic_state.variables[name] = value[1][:]
예제 #7
0
def value_point(ins):
    """ POINT: get pixel attribute at screen location. """
    util.require_read(ins, ('(',))
    arg0 = parse_expression(ins)
    screen = state.console_state.screen
    if util.skip_white_read_if(ins, (',',)):
        # two-argument mode
        arg1 = parse_expression(ins)
        util.require_read(ins, (')',))
        if screen.mode.is_text_mode:
            raise error.RunError(error.IFC)
        return vartypes.int_to_integer_signed(screen.drawing.point(
                        (fp.unpack(vartypes.pass_single(arg0)),
                         fp.unpack(vartypes.pass_single(arg1)), False)))
    else:
        # single-argument mode
        util.require_read(ins, (')',))
        try:
            x, y = screen.drawing.last_point
            fn = vartypes.pass_int_unpack(arg0)
            if fn == 0:
                return vartypes.int_to_integer_signed(x)
            elif fn == 1:
                return vartypes.int_to_integer_signed(y)
            elif fn == 2:
                fx, _ = screen.drawing.get_window_logical(x, y)
                return fp.pack(fx)
            elif fn == 3:
                _, fy = screen.drawing.get_window_logical(x, y)
                return fp.pack(fy)
        except AttributeError:
            return vartypes.null('%')
예제 #8
0
def value_pmap(ins):
    """ PMAP: convert between logical and physical coordinates. """
    util.require_read(ins, ('(', ))
    coord = parse_expression(ins)
    util.require_read(ins, (',', ))
    mode = vartypes.pass_int_unpack(parse_expression(ins))
    util.require_read(ins, (')', ))
    util.range_check(0, 3, mode)
    screen = state.console_state.screen
    if screen.mode.is_text_mode:
        return vartypes.null('%')
    if mode == 0:
        value, _ = screen.drawing.get_window_physical(
            fp.unpack(vartypes.pass_single(coord)), fp.Single.zero)
        return vartypes.int_to_integer_signed(value)
    elif mode == 1:
        _, value = screen.drawing.get_window_physical(
            fp.Single.zero, fp.unpack(vartypes.pass_single(coord)))
        return vartypes.int_to_integer_signed(value)
    elif mode == 2:
        value, _ = screen.drawing.get_window_logical(
            vartypes.pass_int_unpack(coord), 0)
        return fp.pack(value)
    elif mode == 3:
        _, value = screen.drawing.get_window_logical(
            0, vartypes.pass_int_unpack(coord))
        return fp.pack(value)
예제 #9
0
def value_point(ins):
    """ POINT: get pixel attribute at screen location. """
    util.require_read(ins, ('(', ))
    arg0 = parse_expression(ins)
    screen = state.console_state.screen
    if util.skip_white_read_if(ins, (',', )):
        # two-argument mode
        arg1 = parse_expression(ins)
        util.require_read(ins, (')', ))
        if screen.mode.is_text_mode:
            raise error.RunError(error.IFC)
        return vartypes.int_to_integer_signed(
            screen.drawing.point(
                (fp.unpack(vartypes.pass_single(arg0)),
                 fp.unpack(vartypes.pass_single(arg1)), False)))
    else:
        # single-argument mode
        util.require_read(ins, (')', ))
        try:
            x, y = screen.drawing.last_point
            fn = vartypes.pass_int_unpack(arg0)
            if fn == 0:
                return vartypes.int_to_integer_signed(x)
            elif fn == 1:
                return vartypes.int_to_integer_signed(y)
            elif fn == 2:
                fx, _ = screen.drawing.get_window_logical(x, y)
                return fp.pack(fx)
            elif fn == 3:
                _, fy = screen.drawing.get_window_logical(x, y)
                return fp.pack(fy)
        except AttributeError:
            return vartypes.null('%')
예제 #10
0
파일: var.py 프로젝트: gilsim12/pcbasic
def set_scalar(name, value=None):
    """ Assign a value to a variable. """
    name = vartypes.complete_name(name)
    type_char = name[-1]
    if value is not None:
        value = vartypes.pass_type(type_char, value)
    # update memory model
    # check if garbage needs collecting before allocating memory
    if name not in state.basic_state.var_memory:
        # don't add string length, string already stored
        size = (max(3, len(name)) + 1 + vartypes.byte_size[type_char])
        check_free_memory(size, error.OUT_OF_MEMORY)
        # first two bytes: chars of name or 0 if name is one byte long
        name_ptr = state.basic_state.var_current
        # byte_size first_letter second_letter_or_nul remaining_length_or_nul
        var_ptr = name_ptr + max(3, len(name)) + 1
        state.basic_state.var_current += max(3, len(name)) + 1 + vartypes.byte_size[name[-1]]
        state.basic_state.var_memory[name] = (name_ptr, var_ptr)
    # don't change the value if just checking allocation
    if value is None:
        if name in state.basic_state.variables:
            return
        else:
            value = vartypes.null(type_char)
    # copy buffers
    try:
        # in-place copy is crucial for FOR
        state.basic_state.variables[name][:] = value[1][:]
    except KeyError:
        # copy into new buffer if not existing
        state.basic_state.variables[name] = value[1][:]
예제 #11
0
파일: devices.py 프로젝트: Yungzuck/pcbasic
 def read_var(self, name):
     """ Read the value for a variable from a file (INPUT#). """
     typechar = name[0][-1]
     value, sep = self._input_entry(typechar, allow_past_end=False)
     if value is None:
         value = vartypes.null(typechar)
     return value, sep
예제 #12
0
def value_eof(ins):
    """ EOF: get end-of-file. """
    util.skip_white(ins)
    num = vartypes.pass_int_unpack(parse_bracket(ins), maxint=0xffff)
    if num == 0:
        return vartypes.null('%')
    util.range_check(0, 255, num)
    the_file = devices.get_file(num, 'IR')
    return vartypes.bool_to_integer(the_file.eof())
예제 #13
0
def value_eof(ins):
    """ EOF: get end-of-file. """
    util.skip_white(ins)
    num = vartypes.pass_int_unpack(parse_bracket(ins), maxint=0xffff)
    if num == 0:
        return vartypes.null('%')
    util.range_check(0, 255, num)
    the_file = devices.get_file(num, 'IR')
    return vartypes.bool_to_integer(the_file.eof())
예제 #14
0
def value_right(ins):
    """ RIGHT$: get substring at the end of string. """
    util.require_read(ins, ('(', ))
    s = var.copy_str(vartypes.pass_string(parse_expression(ins)))
    util.require_read(ins, (',', ))
    stop = vartypes.pass_int_unpack(parse_expression(ins))
    util.require_read(ins, (')', ))
    util.range_check(0, 255, stop)
    if stop == 0:
        return vartypes.null('$')
    stop = min(stop, len(s))
    return state.basic_state.strings.store(s[-stop:])
예제 #15
0
def value_right(ins):
    """ RIGHT$: get substring at the end of string. """
    util.require_read(ins, ('(',))
    s = var.copy_str(vartypes.pass_string(parse_expression(ins)))
    util.require_read(ins, (',',))
    stop = vartypes.pass_int_unpack(parse_expression(ins))
    util.require_read(ins, (')',))
    util.range_check(0, 255, stop)
    if stop == 0:
        return vartypes.null('$')
    stop = min(stop, len(s))
    return state.basic_state.strings.store(s[-stop:])
예제 #16
0
def str_to_number(strval, allow_nonnum=True):
    """ Convert Python str to BASIC value. """
    ins = StringIO(strval)
    outs = StringIO()
    # skip spaces and line feeds (but not NUL).
    util.skip(ins, (' ', '\n'))
    tokenise_number(ins, outs)
    outs.seek(0)
    value = parse_value(outs)
    if not allow_nonnum and util.skip_white(ins) != '':
        # not everything has been parsed - error
        return None
    if not value:
        return vartypes.null('%')
    return value
예제 #17
0
def value_instr(ins):
    """ INSTR: find substring in string. """
    util.require_read(ins, ('(', ))
    big, small, n = '', '', 1
    # followed by coma so empty will raise STX
    s = parse_expression(ins)
    if s[0] != '$':
        n = vartypes.pass_int_unpack(s)
        util.range_check(1, 255, n)
        util.require_read(ins, (',', ))
        big = vartypes.pass_string(parse_expression(ins, allow_empty=True))
    else:
        big = vartypes.pass_string(s)
    util.require_read(ins, (',', ))
    small = vartypes.pass_string(parse_expression(ins, allow_empty=True))
    util.require_read(ins, (')', ))
    big, small = var.copy_str(big), var.copy_str(small)
    if big == '' or n > len(big):
        return vartypes.null('%')
    # BASIC counts string positions from 1
    find = big[n - 1:].find(small)
    if find == -1:
        return vartypes.null('%')
    return vartypes.int_to_integer_signed(n + find)
예제 #18
0
def value_instr(ins):
    """ INSTR: find substring in string. """
    util.require_read(ins, ('(',))
    big, small, n = '', '', 1
    # followed by coma so empty will raise STX
    s = parse_expression(ins)
    if s[0] != '$':
        n = vartypes.pass_int_unpack(s)
        util.range_check(1, 255, n)
        util.require_read(ins, (',',))
        big = vartypes.pass_string(parse_expression(ins, allow_empty=True))
    else:
        big = vartypes.pass_string(s)
    util.require_read(ins, (',',))
    small = vartypes.pass_string(parse_expression(ins, allow_empty=True))
    util.require_read(ins, (')',))
    big, small = var.copy_str(big), var.copy_str(small)
    if big == '' or n > len(big):
        return vartypes.null('%')
    # BASIC counts string positions from 1
    find = big[n-1:].find(small)
    if find == -1:
        return vartypes.null('%')
    return vartypes.int_to_integer_signed(n + find)
예제 #19
0
def str_to_number(strval, allow_nonnum=True):
    """ Convert Python str to BASIC value. """
    ins = StringIO(strval)
    outs = StringIO()
    # skip spaces and line feeds (but not NUL).
    util.skip(ins, (' ', '\n'))
    tokenise_number(ins, outs)
    outs.seek(0)
    value = parse_value(outs)
    if not allow_nonnum and util.skip_white(ins) != '':
        # not everything has been parsed - error
        return None
    if not value:
        return vartypes.null('%')
    return value
예제 #20
0
def value_mid(ins):
    """ MID$: get substring. """
    util.require_read(ins, ('(', ))
    s = var.copy_str(vartypes.pass_string(parse_expression(ins)))
    util.require_read(ins, (',', ))
    start = vartypes.pass_int_unpack(parse_expression(ins))
    if util.skip_white_read_if(ins, (',', )):
        num = vartypes.pass_int_unpack(parse_expression(ins))
    else:
        num = len(s)
    util.require_read(ins, (')', ))
    util.range_check(1, 255, start)
    util.range_check(0, 255, num)
    if num == 0 or start > len(s):
        return vartypes.null('$')
    start -= 1
    stop = start + num
    stop = min(stop, len(s))
    return state.basic_state.strings.store(s[start:stop])
예제 #21
0
def value_mid(ins):
    """ MID$: get substring. """
    util.require_read(ins, ('(',))
    s = var.copy_str(vartypes.pass_string(parse_expression(ins)))
    util.require_read(ins, (',',))
    start = vartypes.pass_int_unpack(parse_expression(ins))
    if util.skip_white_read_if(ins, (',',)):
        num = vartypes.pass_int_unpack(parse_expression(ins))
    else:
        num = len(s)
    util.require_read(ins, (')',))
    util.range_check(1, 255, start)
    util.range_check(0, 255, num)
    if num == 0 or start > len(s):
        return vartypes.null('$')
    start -= 1
    stop = start + num
    stop = min(stop, len(s))
    return state.basic_state.strings.store(s[start:stop])
예제 #22
0
def value_screen(ins):
    """ SCREEN: get char or attribute at a location. """
    util.require_read(ins, ('(',))
    row = vartypes.pass_int_unpack(parse_expression(ins))
    util.require_read(ins, (',',), err=error.IFC)
    col = vartypes.pass_int_unpack(parse_expression(ins))
    z = 0
    if util.skip_white_read_if(ins, (',',)):
        z = vartypes.pass_int_unpack(parse_expression(ins))
    cmode = state.console_state.screen.mode
    util.range_check(1, cmode.height, row)
    if state.console_state.view_set:
        util.range_check(state.console_state.view_start, state.console_state.scroll_height, row)
    util.range_check(1, cmode.width, col)
    util.range_check(0, 255, z)
    util.require_read(ins, (')',))
    if z and not cmode.is_text_mode:
        return vartypes.null('%')
    else:
        return vartypes.int_to_integer_signed(state.console_state.screen.apage.get_char_attr(row, col, z!=0))
예제 #23
0
def value_screen(ins):
    """ SCREEN: get char or attribute at a location. """
    util.require_read(ins, ('(', ))
    row = vartypes.pass_int_unpack(parse_expression(ins))
    util.require_read(ins, (',', ), err=error.IFC)
    col = vartypes.pass_int_unpack(parse_expression(ins))
    z = 0
    if util.skip_white_read_if(ins, (',', )):
        z = vartypes.pass_int_unpack(parse_expression(ins))
    cmode = state.console_state.screen.mode
    util.range_check(1, cmode.height, row)
    if state.console_state.view_set:
        util.range_check(state.console_state.view_start,
                         state.console_state.scroll_height, row)
    util.range_check(1, cmode.width, col)
    util.range_check(0, 255, z)
    util.require_read(ins, (')', ))
    if z and not cmode.is_text_mode:
        return vartypes.null('%')
    else:
        return vartypes.int_to_integer_signed(
            state.console_state.screen.apage.get_char_attr(row, col, z != 0))
예제 #24
0
def value_pmap(ins):
    """ PMAP: convert between logical and physical coordinates. """
    util.require_read(ins, ('(',))
    coord = parse_expression(ins)
    util.require_read(ins, (',',))
    mode = vartypes.pass_int_unpack(parse_expression(ins))
    util.require_read(ins, (')',))
    util.range_check(0, 3, mode)
    screen = state.console_state.screen
    if screen.mode.is_text_mode:
        return vartypes.null('%')
    if mode == 0:
        value, _ = screen.drawing.get_window_physical(fp.unpack(vartypes.pass_single(coord)), fp.Single.zero)
        return vartypes.int_to_integer_signed(value)
    elif mode == 1:
        _, value = screen.drawing.get_window_physical(fp.Single.zero, fp.unpack(vartypes.pass_single(coord)))
        return vartypes.int_to_integer_signed(value)
    elif mode == 2:
        value, _ = screen.drawing.get_window_logical(vartypes.pass_int_unpack(coord), 0)
        return fp.pack(value)
    elif mode == 3:
        _, value = screen.drawing.get_window_logical(0, vartypes.pass_int_unpack(coord))
        return fp.pack(value)
예제 #25
0
def value_exterr(ins):
    """ EXTERR: device error information; not implemented. """
    x = vartypes.pass_int_unpack(parse_bracket(ins))
    util.range_check(0, 3, x)
    logging.warning("EXTERR() function not implemented.")
    return vartypes.null('%')
예제 #26
0
def value_usr(ins):
    """ USR: get value of machine-code function; not implemented. """
    util.require_read(ins, tk.digit)
    parse_bracket(ins)
    logging.warning("USR() function not implemented.")
    return vartypes.null('%')
예제 #27
0
def value_usr(ins):
    """ USR: get value of machine-code function; not implemented. """
    util.require_read(ins, tk.digit)
    parse_bracket(ins)
    logging.warning("USR() function not implemented.")
    return vartypes.null('%')
예제 #28
0
def value_exterr(ins):
    """ EXTERR: device error information; not implemented. """
    x = vartypes.pass_int_unpack(parse_bracket(ins))
    util.range_check(0, 3, x)
    logging.warning("EXTERR() function not implemented.")
    return vartypes.null('%')