コード例 #1
0
ファイル: expressions.py プロジェクト: Yungzuck/pcbasic
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('%')
コード例 #2
0
ファイル: expressions.py プロジェクト: gilsim12/pcbasic
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('%')
コード例 #3
0
ファイル: expressions.py プロジェクト: Yungzuck/pcbasic
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)
コード例 #4
0
ファイル: expressions.py プロジェクト: gilsim12/pcbasic
def value_sgn(ins):
    """ SGN: get sign. """
    inp = vartypes.pass_number(parse_bracket(ins))
    if inp[0] == '%':
        inp_int = vartypes.integer_to_int_signed(inp)
        return vartypes.int_to_integer_signed(0 if inp_int==0 else (1 if inp_int > 0 else -1))
    else:
        return vartypes.int_to_integer_signed(fp.unpack(inp).sign())
コード例 #5
0
ファイル: expressions.py プロジェクト: Yungzuck/pcbasic
def value_lpos(ins):
    """ LPOS: get the current printer column. """
    num = vartypes.pass_int_unpack(parse_bracket(ins))
    util.range_check(0, 3, num)
    printer = state.io_state.devices['LPT' + max(1, num) + ':']
    if printer.device_file:
        return vartypes.int_to_integer_signed(printer.device_file.col)
    else:
        return vartypes.int_to_integer_signed(1)
コード例 #6
0
ファイル: expressions.py プロジェクト: Yungzuck/pcbasic
def value_sgn(ins):
    """ SGN: get sign. """
    inp = vartypes.pass_number(parse_bracket(ins))
    if inp[0] == '%':
        inp_int = vartypes.integer_to_int_signed(inp)
        return vartypes.int_to_integer_signed(0 if inp_int == 0 else (
            1 if inp_int > 0 else -1))
    else:
        return vartypes.int_to_integer_signed(fp.unpack(inp).sign())
コード例 #7
0
ファイル: expressions.py プロジェクト: gilsim12/pcbasic
def value_lpos(ins):
    """ LPOS: get the current printer column. """
    num = vartypes.pass_int_unpack(parse_bracket(ins))
    util.range_check(0, 3, num)
    printer = state.io_state.devices['LPT' + max(1, num) + ':']
    if printer.device_file:
        return vartypes.int_to_integer_signed(printer.device_file.col)
    else:
        return vartypes.int_to_integer_signed(1)
コード例 #8
0
ファイル: operators.py プロジェクト: gilsim12/pcbasic
def number_intdiv(left, right):
    """ Left\\right. """
    dividend = vartypes.pass_int_unpack(left)
    divisor = vartypes.pass_int_unpack(right)
    if divisor == 0:
        # division by zero, return single-precision maximum
        raise ZeroDivisionError(fp.Single(dividend<0, fp.Single.max.man, fp.Single.max.exp))
    if (dividend >= 0) == (divisor >= 0):
        return vartypes.int_to_integer_signed(dividend / divisor)
    else:
        return vartypes.int_to_integer_signed(-(abs(dividend) / abs(divisor)))
コード例 #9
0
ファイル: operators.py プロジェクト: gilsim12/pcbasic
def number_sgn(inp):
    """ Return the sign of a number. """
    if inp[0] == '%':
        i = vartypes.integer_to_int_signed(inp)
        if i > 0:
            return vartypes.int_to_integer_signed(1)
        elif i < 0:
            return vartypes.int_to_integer_signed(-1)
        else:
            return vartypes.int_to_integer_signed(0)
    elif inp[0] in ('!', '#'):
        return vartypes.int_to_integer_signed(fp.unpack(inp).sign())
    return inp
コード例 #10
0
ファイル: expressions.py プロジェクト: gilsim12/pcbasic
def value_play(ins):
    """ PLAY: get length of music queue. """
    voice = vartypes.pass_int_unpack(parse_bracket(ins))
    util.range_check(0, 255, voice)
    if not(is_pcjr_syntax and voice in (1, 2)):
        voice = 0
    return vartypes.int_to_integer_signed(state.console_state.sound.queue_length(voice))
コード例 #11
0
ファイル: expressions.py プロジェクト: Yungzuck/pcbasic
def value_play(ins):
    """ PLAY: get length of music queue. """
    voice = vartypes.pass_int_unpack(parse_bracket(ins))
    util.range_check(0, 255, voice)
    if not (is_pcjr_syntax and voice in (1, 2)):
        voice = 0
    return vartypes.int_to_integer_signed(
        state.console_state.sound.queue_length(voice))
コード例 #12
0
ファイル: expressions.py プロジェクト: Yungzuck/pcbasic
def value_pos(ins):
    """ POS: get the current screen column. """
    # parse the dummy argument, doesnt matter what it is as long as it's a legal expression
    parse_bracket(ins)
    col = state.console_state.col
    if col == state.console_state.screen.mode.width and state.console_state.overflow:
        # in overflow position, return column 1.
        col = 1
    return vartypes.int_to_integer_signed(col)
コード例 #13
0
ファイル: expressions.py プロジェクト: Yungzuck/pcbasic
def value_csrlin(ins):
    """ CSRLIN: get the current screen row. """
    row, col = state.console_state.row, state.console_state.col
    if (col == state.console_state.screen.mode.width
            and state.console_state.overflow
            and row < state.console_state.scroll_height):
        # in overflow position, return row+1 except on the last row
        row += 1
    return vartypes.int_to_integer_signed(row)
コード例 #14
0
ファイル: expressions.py プロジェクト: gilsim12/pcbasic
def value_csrlin(ins):
    """ CSRLIN: get the current screen row. """
    row, col = state.console_state.row, state.console_state.col
    if (col == state.console_state.screen.mode.width and
            state.console_state.overflow and
            row < state.console_state.scroll_height):
        # in overflow position, return row+1 except on the last row
        row += 1
    return vartypes.int_to_integer_signed(row)
コード例 #15
0
ファイル: expressions.py プロジェクト: Yungzuck/pcbasic
def value_pen(ins):
    """ PEN: poll the light pen. """
    fn = vartypes.pass_int_unpack(parse_bracket(ins))
    util.range_check(0, 9, fn)
    pen = state.console_state.pen.poll(fn)
    if pen is None or not state.basic_state.events.pen.enabled:
        # should return 0 or char pos 1 if PEN not ON
        pen = 1 if fn >= 6 else 0
    return vartypes.int_to_integer_signed(pen)
コード例 #16
0
ファイル: expressions.py プロジェクト: gilsim12/pcbasic
def value_pen(ins):
    """ PEN: poll the light pen. """
    fn = vartypes.pass_int_unpack(parse_bracket(ins))
    util.range_check(0, 9, fn)
    pen = state.console_state.pen.poll(fn)
    if pen is None or not state.basic_state.events.pen.enabled:
        # should return 0 or char pos 1 if PEN not ON
        pen = 1 if fn >= 6 else 0
    return vartypes.int_to_integer_signed(pen)
コード例 #17
0
ファイル: expressions.py プロジェクト: gilsim12/pcbasic
def value_pos(ins):
    """ POS: get the current screen column. """
    # parse the dummy argument, doesnt matter what it is as long as it's a legal expression
    parse_bracket(ins)
    col = state.console_state.col
    if col == state.console_state.screen.mode.width and state.console_state.overflow:
        # in overflow position, return column 1.
        col = 1
    return vartypes.int_to_integer_signed(col)
コード例 #18
0
ファイル: operators.py プロジェクト: gilsim12/pcbasic
def number_modulo(left, right):
    """ Left MOD right. """
    divisor = vartypes.pass_int_unpack(right)
    dividend = vartypes.pass_int_unpack(left)
    if divisor == 0:
        # division by zero, return single-precision maximum
        raise ZeroDivisionError(fp.Single(dividend<0, fp.Single.max.man, fp.Single.max.exp))
    mod = dividend % divisor
    if dividend < 0 or mod < 0:
        mod -= divisor
    return vartypes.int_to_integer_signed(mod)
コード例 #19
0
ファイル: flow.py プロジェクト: Yungzuck/pcbasic
def number_inc_gt(typechar, loopvar, stop, step, sgn):
    """ Increase number and check if it exceeds a limit. """
    if sgn == 0:
        return False
    if typechar in ('#', '!'):
        fp_left = fp.from_bytes(loopvar).iadd(step)
        loopvar[:] = fp_left.to_bytes()
        return fp_left.gt(stop) if sgn > 0 else stop.gt(fp_left)
    else:
        int_left = vartypes.integer_to_int_signed(vartypes.bytes_to_integer(loopvar)) + step
        loopvar[:] = vartypes.integer_to_bytes(vartypes.int_to_integer_signed(int_left))
        return int_left > stop if sgn > 0 else stop > int_left
コード例 #20
0
def ml_parse_const(gmls):
    """ Parse and return a constant value in a macro-language string. """
    c = util.skip(gmls, ml_whitepace)
    if c and c in string.digits:
        numstr = ''
        while c and c in string.digits:
            gmls.read(1)
            numstr += c
            c = util.skip(gmls, ml_whitepace)
        return vartypes.int_to_integer_signed(int(numstr))
    else:
        raise error.RunError(error.IFC)
コード例 #21
0
ファイル: draw_and_play.py プロジェクト: gilsim12/pcbasic
def ml_parse_const(gmls):
    """ Parse and return a constant value in a macro-language string. """
    c = util.skip(gmls, ml_whitepace)
    if c and c in string.digits:
        numstr = ''
        while c and c in string.digits:
            gmls.read(1)
            numstr += c
            c = util.skip(gmls, ml_whitepace)
        return vartypes.int_to_integer_signed(int(numstr))
    else:
        raise error.RunError(error.IFC)
コード例 #22
0
ファイル: operators.py プロジェクト: gilsim12/pcbasic
def number_abs(inp):
    """ Return the absolute value of a number. """
    if inp[0] == '%':
        val = abs(vartypes.integer_to_int_signed(inp))
        if val == 32768:
            return fp.pack(fp.Single.from_int(val))
        else:
            return vartypes.int_to_integer_signed(val)
    elif inp[0] in ('!', '#'):
        out = (inp[0], inp[1][:])
        out[1][-2] &= 0x7F
        return out
    return inp
コード例 #23
0
ファイル: flow.py プロジェクト: Yungzuck/pcbasic
def number_inc_gt(typechar, loopvar, stop, step, sgn):
    """ Increase number and check if it exceeds a limit. """
    if sgn == 0:
        return False
    if typechar in ('#', '!'):
        fp_left = fp.from_bytes(loopvar).iadd(step)
        loopvar[:] = fp_left.to_bytes()
        return fp_left.gt(stop) if sgn > 0 else stop.gt(fp_left)
    else:
        int_left = vartypes.integer_to_int_signed(
            vartypes.bytes_to_integer(loopvar)) + step
        loopvar[:] = vartypes.integer_to_bytes(
            vartypes.int_to_integer_signed(int_left))
        return int_left > stop if sgn > 0 else stop > int_left
コード例 #24
0
ファイル: expressions.py プロジェクト: gilsim12/pcbasic
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
ファイル: operators.py プロジェクト: gilsim12/pcbasic
def number_neg(inp):
    """ Return the negation of a number. """
    inp = vartypes.pass_number(inp)
    if inp[0] == '%':
        val = -vartypes.integer_to_int_signed(inp)
        if val == 32768:
            return fp.pack(fp.Single.from_int(val))
        else:
            return vartypes.int_to_integer_signed(val)
    elif inp[0] in ('!', '#'):
        out = (inp[0], inp[1][:])
        out[1][-2] ^= 0x80
        return out
    # pass strings on, let error happen somewhere else.
    return inp
コード例 #26
0
ファイル: expressions.py プロジェクト: gilsim12/pcbasic
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))
コード例 #27
0
ファイル: expressions.py プロジェクト: Yungzuck/pcbasic
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))
コード例 #28
0
ファイル: expressions.py プロジェクト: gilsim12/pcbasic
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)
コード例 #29
0
ファイル: expressions.py プロジェクト: Yungzuck/pcbasic
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)
コード例 #30
0
ファイル: expressions.py プロジェクト: gilsim12/pcbasic
def value_stick(ins):
    """ STICK: poll the joystick. """
    fn = vartypes.pass_int_unpack(parse_bracket(ins))
    util.range_check(0, 3, fn)
    return vartypes.int_to_integer_signed(state.console_state.stick.poll(fn))
コード例 #31
0
ファイル: expressions.py プロジェクト: gilsim12/pcbasic
def value_err(ins):
    """ ERR: get error code of last error. """
    return vartypes.int_to_integer_signed(state.basic_state.errn)
コード例 #32
0
ファイル: expressions.py プロジェクト: Yungzuck/pcbasic
def value_err(ins):
    """ ERR: get error code of last error. """
    return vartypes.int_to_integer_signed(state.basic_state.errn)
コード例 #33
0
ファイル: expressions.py プロジェクト: gilsim12/pcbasic
def value_len(ins):
    """ LEN: length of string. """
    return vartypes.int_to_integer_signed(
                vartypes.string_length(vartypes.pass_string(parse_bracket(ins))))
コード例 #34
0
ファイル: representation.py プロジェクト: Yungzuck/pcbasic
def tokenise_dec(ins, outs):
    """ Convert decimal expression in Python string to number token. """
    have_exp = False
    have_point = False
    word = ''
    kill = False
    while True:
        c = ins.read(1).upper()
        if not c:
            break
        elif c in '\x1c\x1d\x1f':
            # ASCII separator chars invariably lead to zero result
            kill = True
        elif c == '.' and not have_point and not have_exp:
            have_point = True
            word += c
        elif c in 'ED' and not have_exp:
            # there's a special exception for number followed by EL or EQ
            # presumably meant to protect ELSE and maybe EQV ?
            if c == 'E' and util.peek(ins).upper() in ('L', 'Q'):
                ins.seek(-1, 1)
                break
            else:
                have_exp = True
                word += c
        elif c in '-+' and (not word or word[-1] in 'ED'):
            # must be first token or in exponent
            word += c
        elif c in string.digits:
            word += c
        elif c in number_whitespace:
            # we'll remove this later but need to keep it for now
            # so we can reposition the stream on removing trailing whitespace
            word += c
        elif c in '!#' and not have_exp:
            word += c
            break
        elif c == '%':
            # swallow a %, but break parsing
            break
        else:
            ins.seek(-1, 1)
            break
    # ascii separators encountered: zero output
    if kill:
        word = '0'
    # don't claim trailing whitespace
    while len(word) > 0 and (word[-1] in number_whitespace):
        word = word[:-1]
        ins.seek(-1, 1)  # even if c==''
    # remove all internal whitespace
    trimword = ''
    for c in word:
        if c not in number_whitespace:
            trimword += c
    word = trimword
    # write out the numbers
    if len(word) == 1 and word in string.digits:
        # digit
        outs.write(chr(0x11 + str_to_int(word)))
    elif (not (have_exp or have_point or word[-1] in '!#')
          and str_to_int(word) <= 0x7fff and str_to_int(word) >= -0x8000):
        if str_to_int(word) <= 0xff and str_to_int(word) >= 0:
            # one-byte constant
            outs.write(tk.T_BYTE + chr(str_to_int(word)))
        else:
            # two-byte constant
            outs.write(tk.T_INT + str(
                vartypes.integer_to_bytes(
                    vartypes.int_to_integer_signed(str_to_int(word)))))
    else:
        mbf = str(str_to_float(word).to_bytes())
        if len(mbf) == 4:
            outs.write(tk.T_SINGLE + mbf)
        else:
            outs.write(tk.T_DOUBLE + mbf)
コード例 #35
0
ファイル: expressions.py プロジェクト: gilsim12/pcbasic
def value_asc(ins):
    """ ASC: ordinal ASCII value of a character. """
    s = var.copy_str(vartypes.pass_string(parse_bracket(ins)))
    if not s:
        raise error.RunError(error.IFC)
    return vartypes.int_to_integer_signed(ord(s[0]))
コード例 #36
0
ファイル: expressions.py プロジェクト: Yungzuck/pcbasic
def value_peek(ins):
    """ PEEK: read memory location. """
    addr = vartypes.pass_int_unpack(parse_bracket(ins), maxint=0xffff)
    if state.basic_state.protected and not state.basic_state.run_mode:
        raise error.RunError(error.IFC)
    return vartypes.int_to_integer_signed(machine.peek(addr))
コード例 #37
0
ファイル: representation.py プロジェクト: Yungzuck/pcbasic
def tokenise_dec(ins, outs):
    """ Convert decimal expression in Python string to number token. """
    have_exp = False
    have_point = False
    word = ''
    kill = False
    while True:
        c = ins.read(1).upper()
        if not c:
            break
        elif c in '\x1c\x1d\x1f':
            # ASCII separator chars invariably lead to zero result
            kill = True
        elif c == '.' and not have_point and not have_exp:
            have_point = True
            word += c
        elif c in 'ED' and not have_exp:
            # there's a special exception for number followed by EL or EQ
            # presumably meant to protect ELSE and maybe EQV ?
            if c == 'E' and util.peek(ins).upper() in ('L', 'Q'):
                ins.seek(-1, 1)
                break
            else:
                have_exp = True
                word += c
        elif c in '-+' and (not word or word[-1] in 'ED'):
            # must be first token or in exponent
            word += c
        elif c in string.digits:
            word += c
        elif c in number_whitespace:
            # we'll remove this later but need to keep it for now
            # so we can reposition the stream on removing trailing whitespace
            word += c
        elif c in '!#' and not have_exp:
            word += c
            break
        elif c == '%':
            # swallow a %, but break parsing
            break
        else:
            ins.seek(-1, 1)
            break
    # ascii separators encountered: zero output
    if kill:
        word = '0'
    # don't claim trailing whitespace
    while len(word)>0 and (word[-1] in number_whitespace):
        word = word[:-1]
        ins.seek(-1,1) # even if c==''
    # remove all internal whitespace
    trimword = ''
    for c in word:
        if c not in number_whitespace:
            trimword += c
    word = trimword
    # write out the numbers
    if len(word) == 1 and word in string.digits:
        # digit
        outs.write(chr(0x11+str_to_int(word)))
    elif (not (have_exp or have_point or word[-1] in '!#') and
                            str_to_int(word) <= 0x7fff and str_to_int(word) >= -0x8000):
        if str_to_int(word) <= 0xff and str_to_int(word) >= 0:
            # one-byte constant
            outs.write(tk.T_BYTE + chr(str_to_int(word)))
        else:
            # two-byte constant
            outs.write(tk.T_INT + str(vartypes.integer_to_bytes(vartypes.int_to_integer_signed(str_to_int(word)))))
    else:
        mbf = str(str_to_float(word).to_bytes())
        if len(mbf) == 4:
            outs.write(tk.T_SINGLE + mbf)
        else:
            outs.write(tk.T_DOUBLE + mbf)
コード例 #38
0
ファイル: operators.py プロジェクト: gilsim12/pcbasic
def number_not(right):
    """ Bitwise NOT, -x-1. """
    return vartypes.int_to_integer_signed(-vartypes.pass_int_unpack(right)-1)
コード例 #39
0
ファイル: expressions.py プロジェクト: gilsim12/pcbasic
def value_peek(ins):
    """ PEEK: read memory location. """
    addr = vartypes.pass_int_unpack(parse_bracket(ins), maxint=0xffff)
    if state.basic_state.protected and not state.basic_state.run_mode:
        raise error.RunError(error.IFC)
    return vartypes.int_to_integer_signed(machine.peek(addr))
コード例 #40
0
ファイル: expressions.py プロジェクト: gilsim12/pcbasic
def value_inp(ins):
    """ INP: get value from machine port. """
    port = vartypes.pass_int_unpack(parse_bracket(ins), maxint=0xffff)
    return vartypes.int_to_integer_signed(machine.inp(port))
コード例 #41
0
ファイル: expressions.py プロジェクト: Yungzuck/pcbasic
def value_asc(ins):
    """ ASC: ordinal ASCII value of a character. """
    s = var.copy_str(vartypes.pass_string(parse_bracket(ins)))
    if not s:
        raise error.RunError(error.IFC)
    return vartypes.int_to_integer_signed(ord(s[0]))
コード例 #42
0
ファイル: graphics.py プロジェクト: Yungzuck/pcbasic
 def draw(self, gml):
     """ DRAW: Execute a Graphics Macro Language string. """
     # don't convert to uppercase as VARPTR$ elements are case sensitive
     gmls = StringIO(gml)
     plot, goback = True, False
     while True:
         c = util.skip_read(gmls, draw_and_play.ml_whitepace).upper()
         if c == '':
             break
         elif c == ';':
             continue
         elif c == 'B':
             # do not draw
             plot = False
         elif c == 'N':
             # return to postiton after move
             goback = True
         elif c == 'X':
             # execute substring
             sub = draw_and_play.ml_parse_string(gmls)
             self.draw(str(sub))
         elif c == 'C':
             # set foreground colour
             # allow empty spec (default 0), but only if followed by a semicolon
             if util.skip(gmls, draw_and_play.ml_whitepace) == ';':
                 self.last_attr = 0
             else:
                 self.last_attr = draw_and_play.ml_parse_number(gmls)
         elif c == 'S':
             # set scale
             self.draw_scale = draw_and_play.ml_parse_number(gmls)
         elif c == 'A':
             # set angle
             # allow empty spec (default 0), but only if followed by a semicolon
             if util.skip(gmls, draw_and_play.ml_whitepace) == ';':
                 self.draw_angle = 0
             else:
                 self.draw_angle = 90 * draw_and_play.ml_parse_number(gmls)
         elif c == 'T':
             # 'turn angle' - set (don't turn) the angle to any value
             if gmls.read(1).upper() != 'A':
                 raise error.RunError(error.IFC)
             # allow empty spec (default 0), but only if followed by a semicolon
             if util.skip(gmls, draw_and_play.ml_whitepace) == ';':
                 self.draw_angle = 0
             else:
                 self.draw_angle = draw_and_play.ml_parse_number(gmls)
         # one-variable movement commands:
         elif c in ('U', 'D', 'L', 'R', 'E', 'F', 'G', 'H'):
             step = draw_and_play.ml_parse_number(gmls, default=vartypes.int_to_integer_signed(1))
             x0, y0 = self.last_point
             x1, y1 = 0, 0
             if c in ('U', 'E', 'H'):
                 y1 -= step
             elif c in ('D', 'F', 'G'):
                 y1 += step
             if c in ('L', 'G', 'H'):
                 x1 -= step
             elif c in ('R', 'E', 'F'):
                 x1 += step
             self.draw_step(x0, y0, x1, y1, plot, goback)
             plot = True
             goback = False
         # two-variable movement command
         elif c == 'M':
             relative =  util.skip(gmls, draw_and_play.ml_whitepace) in ('+','-')
             x = draw_and_play.ml_parse_number(gmls)
             if util.skip(gmls, draw_and_play.ml_whitepace) != ',':
                 raise error.RunError(error.IFC)
             else:
                 gmls.read(1)
             y = draw_and_play.ml_parse_number(gmls)
             x0, y0 = self.last_point
             if relative:
                 self.draw_step(x0, y0, x, y,  plot, goback)
             else:
                 if plot:
                     self.draw_line(x0, y0, x, y, self.last_attr)
                 self.last_point = x, y
                 if goback:
                     self.last_point = x0, y0
             plot = True
             goback = False
         elif c =='P':
             # paint - flood fill
             colour = draw_and_play.ml_parse_number(gmls)
             if util.skip_read(gmls, draw_and_play.ml_whitepace) != ',':
                 raise error.RunError(error.IFC)
             bound = draw_and_play.ml_parse_number(gmls)
             x, y = self.get_window_logical(*self.last_point)
             self.paint((x, y, False), None, colour, bound, None)
コード例 #43
0
ファイル: expressions.py プロジェクト: Yungzuck/pcbasic
def value_len(ins):
    """ LEN: length of string. """
    return vartypes.int_to_integer_signed(
        vartypes.string_length(vartypes.pass_string(parse_bracket(ins))))
コード例 #44
0
ファイル: expressions.py プロジェクト: Yungzuck/pcbasic
def value_inp(ins):
    """ INP: get value from machine port. """
    port = vartypes.pass_int_unpack(parse_bracket(ins), maxint=0xffff)
    return vartypes.int_to_integer_signed(machine.inp(port))
コード例 #45
0
ファイル: expressions.py プロジェクト: Yungzuck/pcbasic
def value_stick(ins):
    """ STICK: poll the joystick. """
    fn = vartypes.pass_int_unpack(parse_bracket(ins))
    util.range_check(0, 3, fn)
    return vartypes.int_to_integer_signed(state.console_state.stick.poll(fn))