예제 #1
0
def _bool_eq(left, right):
    """ Return true if left == right, false otherwise. """
    if left[0] == '$':
        return var.copy_str(vartypes.pass_string(left)) == var.copy_str(vartypes.pass_string(right))
    else:
        left, right = vartypes.pass_most_precise(left, right)
        if left[0] in ('#', '!'):
            return fp.unpack(left).equals(fp.unpack(right))
        else:
            return vartypes.integer_to_int_signed(left) == vartypes.integer_to_int_signed(right)
예제 #2
0
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.parse_scalar(gmls, err=error.IFC)
        indices = ml_parse_indices(gmls)
        sub = var.get_variable(name, indices)
        util.require_read(gmls, (';',), err=error.IFC)
        return var.copy_str(vartypes.pass_string(sub, err=error.IFC))
    else:
        # varptr$
        return var.copy_str(
                vartypes.pass_string(get_value_for_varptrstr(gmls.read(3))))
예제 #3
0
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.parse_scalar(gmls, err=error.IFC)
        indices = ml_parse_indices(gmls)
        sub = var.get_variable(name, indices)
        util.require_read(gmls, (';', ), err=error.IFC)
        return var.copy_str(vartypes.pass_string(sub, err=error.IFC))
    else:
        # varptr$
        return var.copy_str(
            vartypes.pass_string(get_value_for_varptrstr(gmls.read(3))))
예제 #4
0
def value_environ(ins):
    """ ENVIRON$: get environment string. """
    util.require_read(ins, ('$',))
    expr = parse_bracket(ins)
    if expr[0] == '$':
        return state.basic_state.strings.store(shell.get_env(var.copy_str(expr)))
    else:
        expr = vartypes.pass_int_unpack(expr)
        util.range_check(1, 255, expr)
        return state.basic_state.strings.store(shell.get_env_entry(expr))
예제 #5
0
def value_environ(ins):
    """ ENVIRON$: get environment string. """
    util.require_read(ins, ('$', ))
    expr = parse_bracket(ins)
    if expr[0] == '$':
        return state.basic_state.strings.store(
            shell.get_env(var.copy_str(expr)))
    else:
        expr = vartypes.pass_int_unpack(expr)
        util.range_check(1, 255, expr)
        return state.basic_state.strings.store(shell.get_env_entry(expr))
예제 #6
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:])
예제 #7
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:])
예제 #8
0
def _bool_gt(left, right):
    """ Ordering: return -1 if left > right, 0 otherwise. """
    if left[0] == '$':
        left, right = var.copy_str(vartypes.pass_string(left)), var.copy_str(vartypes.pass_string(right))
        shortest = min(len(left), len(right))
        for i in range(shortest):
            if left[i] > right[i]:
                return True
            elif left[i] < right[i]:
                return False
        # the same so far...
        # the shorter string is said to be less than the longer,
        # provided they are the same up till the length of the shorter.
        if len(left) > len(right):
            return True
        # left is shorter, or equal strings
        return False
    else:
        left, right = vartypes.pass_most_precise(left, right)
        if left[0] in ('#', '!'):
            return fp.unpack(left).gt(fp.unpack(right))
        else:
            return vartypes.integer_to_int_signed(left) > vartypes.integer_to_int_signed(right)
예제 #9
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)
예제 #10
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)
예제 #11
0
def value_string(ins):
    """ STRING$: repeat characters. """
    util.require_read(ins, ('(', ))
    n = vartypes.pass_int_unpack(parse_expression(ins))
    util.range_check(0, 255, n)
    util.require_read(ins, (',', ))
    j = parse_expression(ins)
    if j[0] == '$':
        j = var.copy_str(j)
        util.range_check(1, 255, len(j))
        j = ord(j[0])
    else:
        j = vartypes.pass_int_unpack(j)
        util.range_check(0, 255, j)
    util.require_read(ins, (')', ))
    return state.basic_state.strings.store(chr(j) * n)
예제 #12
0
def value_string(ins):
    """ STRING$: repeat characters. """
    util.require_read(ins, ('(',))
    n = vartypes.pass_int_unpack(parse_expression(ins))
    util.range_check(0, 255, n)
    util.require_read(ins, (',',))
    j = parse_expression(ins)
    if j[0] == '$':
        j = var.copy_str(j)
        util.range_check(1, 255, len(j))
        j = ord(j[0])
    else:
        j = vartypes.pass_int_unpack(j)
        util.range_check(0, 255, j)
    util.require_read(ins, (')',))
    return state.basic_state.strings.store(chr(j)*n)
예제 #13
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])
예제 #14
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])
예제 #15
0
파일: debug.py 프로젝트: Yungzuck/pcbasic
def debug_step(linum):
    """ Execute traces and watches on a program step. """
    if not debug_mode:
        return
    outstr = ''
    if debug_tron:
        outstr += ('['+('%i' % linum) +']')
    for (expr, outs) in watch_list:
        outstr += (' ' + expr +' = ')
        outs.seek(2)
        try:
            val = expressions.parse_expression(outs)
            if val[0] == '$':
                outstr += '"' + var.copy_str(val) + '"'
            else:
                outstr += representation.number_to_str(val, screen=False)
        except Exception as e:
            debug_handle_exc(e)
    if outstr:
        logging.debug(outstr)
예제 #16
0
파일: debug.py 프로젝트: gilsim12/pcbasic
def debug_step(linum):
    """ Execute traces and watches on a program step. """
    if not debug_mode:
        return
    outstr = ''
    if debug_tron:
        outstr += ('['+('%i' % linum) +']')
    for (expr, outs) in watch_list:
        outstr += (' ' + expr +' = ')
        outs.seek(2)
        try:
            val = expressions.parse_expression(outs)
            if val[0] == '$':
                outstr += '"' + var.copy_str(val) + '"'
            else:
                outstr += representation.number_to_str(val, screen=False)
        except Exception as e:
            debug_handle_exc(e)
    if outstr:
        logging.debug(outstr)
예제 #17
0
def value_cvd(ins):
    """ CVD: return the double-precision value of a byte representation. """
    cstr = var.copy_str(vartypes.pass_string(parse_bracket(ins)))
    if len(cstr) < 8:
        raise error.RunError(error.IFC)
    return ('#', bytearray(cstr[:8]))
예제 #18
0
def value_cvi(ins):
    """ CVI: return the int value of a byte representation. """
    cstr = var.copy_str(vartypes.pass_string(parse_bracket(ins)))
    if len(cstr) < 2:
        raise error.RunError(error.IFC)
    return vartypes.bytes_to_integer(cstr[:2])
예제 #19
0
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]))
예제 #20
0
def value_val(ins):
    """ VAL: number value of a string. """
    return representation.str_to_number(
        var.copy_str(vartypes.pass_string(parse_bracket(ins))))
예제 #21
0
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]))
예제 #22
0
def string_concat(left, right):
    """ Concatenate strings. """
    return state.basic_state.strings.store(var.copy_str(vartypes.pass_string(left)) + var.copy_str(vartypes.pass_string(right)))
예제 #23
0
def value_val(ins):
    """ VAL: number value of a string. """
    return representation.str_to_number(var.copy_str(vartypes.pass_string(parse_bracket(ins))))
예제 #24
0
def value_cvd(ins):
    """ CVD: return the double-precision value of a byte representation. """
    cstr = var.copy_str(vartypes.pass_string(parse_bracket(ins)))
    if len(cstr) < 8:
        raise error.RunError(error.IFC)
    return ('#', bytearray(cstr[:8]))
예제 #25
0
def value_cvs(ins):
    """ CVS: return the single-precision value of a byte representation. """
    cstr = var.copy_str(vartypes.pass_string(parse_bracket(ins)))
    if len(cstr) < 4:
        raise error.RunError(error.IFC)
    return ('!', bytearray(cstr[:4]))
예제 #26
0
def value_cvi(ins):
    """ CVI: return the int value of a byte representation. """
    cstr = var.copy_str(vartypes.pass_string(parse_bracket(ins)))
    if len(cstr) < 2:
        raise error.RunError(error.IFC)
    return vartypes.bytes_to_integer(cstr[:2])
예제 #27
0
def value_cvs(ins):
    """ CVS: return the single-precision value of a byte representation. """
    cstr = var.copy_str(vartypes.pass_string(parse_bracket(ins)))
    if len(cstr) < 4:
        raise error.RunError(error.IFC)
    return ('!', bytearray(cstr[:4]))