示例#1
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)
示例#2
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 representation.ascii_digits:
        numstr = ''
        while c and c in representation.ascii_digits:
            gmls.read(1)
            numstr += c
            c = util.skip(gmls, ml_whitepace)
        return representation.str_to_value_keep(('$', numstr))
    else:
        raise error.RunError(error.IFC)
示例#3
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)
示例#4
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 representation.str_to_value_keep(('$', numstr))
    else:
        raise error.RunError(error.IFC)
示例#5
0
def ml_parse_indices(gmls):
    """ Parse constant array indices. """
    indices = []
    c = util.skip(gmls, ml_whitepace)
    if c in ('[', '('):
        gmls.read(1)
        while True:
            indices.append(ml_parse_const_int(gmls))
            c = util.skip(gmls, ml_whitepace)
            if c == ',':
                gmls.read(1)
            else:
                break
        util.require_read(gmls, (']', ')'))
    return indices
示例#6
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
示例#7
0
def ml_parse_indices(gmls):
    """ Parse constant array indices. """
    indices = []
    c = util.skip(gmls, ml_whitepace)
    if c in ('[', '('):
        gmls.read(1)
        while True:
            indices.append(ml_parse_const_int(gmls))
            c = util.skip(gmls, ml_whitepace)
            if c == ',':
                gmls.read(1)
            else:
                break
        util.require_read(gmls, (']', ')'))
    return indices
示例#8
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
示例#9
0
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
示例#10
0
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
示例#11
0
def str_to_value_keep(strval, allow_nonnum=True):
    """ Convert BASIC string to BASIC value. """
    if strval == ('$', ''):
        return vartypes.null['%']
    strval = str(vartypes.pass_string_unpack(strval))
    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 = util.parse_value(outs)
    if not allow_nonnum:
        if util.skip_white(ins) != '':
            # not everything has been parsed - error
            return None    
    return value
示例#12
0
 def ld_subsets(mat):
     A = sympy.Matrix(mat).transpose().echelon_form() % 2
     n = A.shape[1]
     b = sympy.zeros(n, 1)
     solutions = sympy.linsolve((A, b), sympy.symbols(f't:{n}'))
     parameters = solutions.free_symbols
     for solution in solutions:
         for values in skip(1, product(*([range(2)] * len(parameters)))):
             subs = {t: v for (t, v) in zip(parameters, values)}
             subbed = [a % 2 for a in solution.subs(subs)]
             yield list(i for (i, bit) in enumerate(subbed) if bit)
示例#13
0
def str_to_value_keep(strval, allow_nonnum=True):
    """ Convert BASIC string to BASIC value (VAL). """
    if strval == ('$', ''):
        if allow_nonnum:
            return vartypes.null['%']
        else:
            return None
    strval = str(vartypes.pass_string_unpack(strval))
    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:
        if util.skip_white(ins) != '':
            # not everything has been parsed - error
            return None
    return value
示例#14
0
def tokenise_word(ins, outs):
    """ Convert a keyword to tokenised form. """
    word = ''
    while True: 
        c = ins.read(1).upper()
        word += c
        # special cases 'GO     TO' -> 'GOTO', 'GO SUB' -> 'GOSUB'    
        if word == 'GO':
            pos = ins.tell()
            # GO SUB allows 1 space
            if util.peek(ins, 4) == ' SUB':
                word = 'GOSUB'
                ins.read(4)
            else:
                # GOTO allows any number of spaces
                nxt = util.skip(ins, whitespace)
                if ins.read(2) == 'TO':
                    word = 'GOTO'
                else:
                    ins.seek(pos)
            if word in ('GOTO', 'GOSUB'):
                nxt = util.peek(ins).upper()
                if nxt in name_chars:
                    ins.seek(pos)
                    word = 'GO'
                else:
                    pass
        if word in keyword_to_token:
            # ignore if part of a longer name, except FN, SPC(, TAB(, USR
            if word not in ('FN', 'SPC(', 'TAB(', 'USR'):
                nxt = util.peek(ins).upper()
                if nxt in name_chars:  
                    continue
            token = keyword_to_token[word]
            # handle special case ELSE -> :ELSE
            if word == 'ELSE':
                outs.write(':' + token)
            # handle special case WHILE -> WHILE+
            elif word == 'WHILE':
                outs.write(token + tk.O_PLUS)
            else:
                outs.write(token)
            break
        # allowed names: letter + (letters, numbers, .)    
        elif not(c in name_chars): 
            if c!='':
                word = word[:-1]
                ins.seek(-1, 1)
            outs.write(word)            
            break
    return word
示例#15
0
def tokenise_word(ins, outs):
    """ Convert a keyword to tokenised form. """
    word = ''
    while True:
        c = ins.read(1).upper()
        word += c
        # special cases 'GO     TO' -> 'GOTO', 'GO SUB' -> 'GOSUB'
        if word == 'GO':
            pos = ins.tell()
            # GO SUB allows 1 space
            if util.peek(ins, 4) == ' SUB':
                word = 'GOSUB'
                ins.read(4)
            else:
                # GOTO allows any number of spaces
                nxt = util.skip(ins, ascii_whitespace)
                if ins.read(2) == 'TO':
                    word = 'GOTO'
                else:
                    ins.seek(pos)
            if word in ('GOTO', 'GOSUB'):
                nxt = util.peek(ins).upper()
                if nxt and nxt in name_chars:
                    ins.seek(pos)
                    word = 'GO'
        if word in keyword_to_token:
            # ignore if part of a longer name, except FN, SPC(, TAB(, USR
            if word not in ('FN', 'SPC(', 'TAB(', 'USR'):
                nxt = util.peek(ins).upper()
                if nxt and nxt in name_chars:
                    continue
            token = keyword_to_token[word]
            # handle special case ELSE -> :ELSE
            if word == 'ELSE':
                outs.write(':' + token)
            # handle special case WHILE -> WHILE+
            elif word == 'WHILE':
                outs.write(token + tk.O_PLUS)
            else:
                outs.write(token)
            break
        # allowed names: letter + (letters, numbers, .)
        elif not c:
            outs.write(word)
            break
        elif c not in name_chars:
            word = word[:-1]
            ins.seek(-1, 1)
            outs.write(word)
            break
    return word
示例#16
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.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)))
示例#17
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.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)))
示例#18
0
 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.pack_int(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)
示例#19
0
 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)
示例#20
0
 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(5)
             # 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.pack_int(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(5)
             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(5)
             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)
示例#21
0
def test_transf_not_implemented():
    meths = ['fourier', 'taylor']
    kernel = _kernels.Maternp(p=0)
    for meth in meths:
        with pytest.raises(NotImplementedError):
            getattr(kernel, meth)(True, None)
        with pytest.raises(NotImplementedError):
            getattr(kernel, meth)(None, True)
        with pytest.raises(NotImplementedError):
            getattr(kernel, meth)(True, True)


#####################  XFAILS/SKIPS  #####################

util.skip(TestAR, 'test_normalized')
util.skip(TestMA, 'test_normalized')

# TODO These are isotropic kernels with the input='soft' option. The problems
# arise where x == y. => use make_jaxpr to debug?
util.xfail(TestWendland, 'test_positive_deriv2_nd')
util.xfail(TestWendland, 'test_double_diff_nd_second_chopped')
util.xfail(TestWendland, 'test_continuous_at_zero_2')
util.xfail(TestWendland, 'test_jit_deriv2_nd')
util.xfail(TestCausalExpQuad, 'test_positive_deriv2_nd')
util.xfail(TestCausalExpQuad, 'test_double_diff_nd_second_chopped')
util.xfail(TestCausalExpQuad, 'test_continuous_at_zero_2')

# TODO some xpass, likely numerical precision problems
util.xfail(TestWendland, 'test_positive_deriv2')  # normally xpasses
util.xfail(TestCausalExpQuad, 'test_positive_deriv2')  # NOT 1 - erf cancel
示例#22
0
文件: sound.py 项目: nony05/pcbasic
 def play(self, mml_list):
     """ Parse a list of Music Macro Language strings. """
     gmls_list = []
     for mml in mml_list:
         gmls = StringIO()
         # don't convert to uppercase as VARPTR$ elements are case sensitive
         gmls.write(str(mml))
         gmls.seek(0)
         gmls_list.append(gmls)
     next_oct = 0
     total_time = [0, 0, 0, 0]
     voices = range(3)
     while True:
         if not voices:
             break
         for voice in voices:
             vstate = self.play_state[voice]
             gmls = gmls_list[voice]
             c = util.skip_read(gmls, draw_and_play.ml_whitepace).upper()
             if c == "":
                 voices.remove(voice)
                 continue
             elif c == ";":
                 continue
             elif c == "X":
                 # execute substring
                 sub = draw_and_play.ml_parse_string(gmls)
                 pos = gmls.tell()
                 rest = gmls.read()
                 gmls.truncate(pos)
                 gmls.write(str(sub))
                 gmls.write(rest)
                 gmls.seek(pos)
             elif c == "N":
                 note = draw_and_play.ml_parse_number(gmls)
                 dur = vstate.length
                 c = util.skip(gmls, draw_and_play.ml_whitepace).upper()
                 if c == ".":
                     gmls.read(1)
                     dur *= 1.5
                 if note > 0 and note <= 84:
                     self.play_sound(
                         note_freq[note - 1], dur * vstate.tempo, vstate.speed, volume=vstate.volume, voice=voice
                     )
                     total_time[voice] += dur * vstate.tempo
                 elif note == 0:
                     self.play_sound(0, dur * vstate.tempo, vstate.speed, volume=0, voice=voice)
                     total_time[voice] += dur * vstate.tempo
             elif c == "L":
                 vstate.length = 1.0 / draw_and_play.ml_parse_number(gmls)
             elif c == "T":
                 vstate.tempo = 240.0 / draw_and_play.ml_parse_number(gmls)
             elif c == "O":
                 vstate.octave = min(6, max(0, draw_and_play.ml_parse_number(gmls)))
             elif c == ">":
                 vstate.octave += 1
                 if vstate.octave > 6:
                     vstate.octave = 6
             elif c == "<":
                 vstate.octave -= 1
                 if vstate.octave < 0:
                     vstate.octave = 0
             elif c in ("A", "B", "C", "D", "E", "F", "G", "P"):
                 note = c
                 dur = vstate.length
                 while True:
                     c = util.skip(gmls, draw_and_play.ml_whitepace).upper()
                     if not c:
                         break
                     elif c == ".":
                         gmls.read(1)
                         dur *= 1.5
                     elif c in representation.ascii_digits:
                         numstr = ""
                         while c and c in representation.ascii_digits:
                             gmls.read(1)
                             numstr += c
                             c = util.skip(gmls, draw_and_play.ml_whitepace)
                         length = vartypes.pass_int_unpack(representation.str_to_value_keep(("$", numstr)))
                         dur = 1.0 / float(length)
                     elif c in ("#", "+"):
                         gmls.read(1)
                         note += "#"
                     elif c == "-":
                         gmls.read(1)
                         note += "-"
                     else:
                         break
                 if note == "P":
                     self.play_sound(0, dur * vstate.tempo, vstate.speed, volume=vstate.volume, voice=voice)
                     total_time[voice] += dur * vstate.tempo
                 else:
                     try:
                         self.play_sound(
                             note_freq[(vstate.octave + next_oct) * 12 + notes[note]],
                             dur * vstate.tempo,
                             vstate.speed,
                             volume=vstate.volume,
                             voice=voice,
                         )
                         total_time[voice] += dur * vstate.tempo
                     except KeyError:
                         raise error.RunError(error.IFC)
                 next_oct = 0
             elif c == "M":
                 c = util.skip_read(gmls, draw_and_play.ml_whitepace).upper()
                 if c == "N":
                     vstate.speed = 7.0 / 8.0
                 elif c == "L":
                     vstate.speed = 1.0
                 elif c == "S":
                     vstate.speed = 3.0 / 4.0
                 elif c == "F":
                     self.foreground = True
                 elif c == "B":
                     self.foreground = False
                 else:
                     raise error.RunError(error.IFC)
             elif c == "V" and (pcjr_sound == "tandy" or (pcjr_sound == "pcjr" and self.sound_on)):
                 vstate.volume = min(15, max(0, draw_and_play.ml_parse_number(gmls)))
             else:
                 raise error.RunError(error.IFC)
     max_time = max(total_time)
     for voice in range(3):
         if total_time[voice] < max_time:
             self.play_sound(0, max_time - total_time[voice], 1, 0, voice)
     if self.foreground:
         self.wait_all_music()
示例#23
0
文件: sound.py 项目: Yungzuck/pcbasic
 def play(self, mml_list):
     """ Parse a list of Music Macro Language strings. """
     gmls_list = []
     for mml in mml_list:
         gmls = StringIO()
         # don't convert to uppercase as VARPTR$ elements are case sensitive
         gmls.write(str(mml))
         gmls.seek(0)
         gmls_list.append(gmls)
     next_oct = 0
     total_time = [0, 0, 0, 0]
     voices = range(3)
     while True:
         if not voices:
             break
         for voice in voices:
             vstate = self.play_state[voice]
             gmls = gmls_list[voice]
             c = util.skip_read(gmls, draw_and_play.ml_whitepace).upper()
             if c == '':
                 voices.remove(voice)
                 continue
             elif c == ';':
                 continue
             elif c == 'X':
                 # execute substring
                 sub = draw_and_play.ml_parse_string(gmls)
                 pos = gmls.tell()
                 rest = gmls.read()
                 gmls.truncate(pos)
                 gmls.write(str(sub))
                 gmls.write(rest)
                 gmls.seek(pos)
             elif c == 'N':
                 note = draw_and_play.ml_parse_number(gmls)
                 dur = vstate.length
                 c = util.skip(gmls, draw_and_play.ml_whitepace).upper()
                 if c == '.':
                     gmls.read(1)
                     dur *= 1.5
                 if note > 0 and note <= 84:
                     self.play_sound(note_freq[note - 1],
                                     dur * vstate.tempo,
                                     vstate.speed,
                                     volume=vstate.volume,
                                     voice=voice)
                     total_time[voice] += dur * vstate.tempo
                 elif note == 0:
                     self.play_sound(0,
                                     dur * vstate.tempo,
                                     vstate.speed,
                                     volume=0,
                                     voice=voice)
                     total_time[voice] += dur * vstate.tempo
             elif c == 'L':
                 vstate.length = 1. / draw_and_play.ml_parse_number(gmls)
             elif c == 'T':
                 vstate.tempo = 240. / draw_and_play.ml_parse_number(gmls)
             elif c == 'O':
                 vstate.octave = min(
                     6, max(0, draw_and_play.ml_parse_number(gmls)))
             elif c == '>':
                 vstate.octave += 1
                 if vstate.octave > 6:
                     vstate.octave = 6
             elif c == '<':
                 vstate.octave -= 1
                 if vstate.octave < 0:
                     vstate.octave = 0
             elif c in ('A', 'B', 'C', 'D', 'E', 'F', 'G', 'P'):
                 note = c
                 dur = vstate.length
                 while True:
                     c = util.skip(gmls, draw_and_play.ml_whitepace).upper()
                     if not c:
                         break
                     elif c == '.':
                         gmls.read(1)
                         dur *= 1.5
                     elif c in string.digits:
                         numstr = ''
                         while c and c in string.digits:
                             gmls.read(1)
                             numstr += c
                             c = util.skip(gmls, draw_and_play.ml_whitepace)
                         # NOT ml_parse_number, only literals allowed here!
                         length = int(numstr)
                         dur = 1. / float(length)
                     elif c in ('#', '+'):
                         gmls.read(1)
                         note += '#'
                     elif c == '-':
                         gmls.read(1)
                         note += '-'
                     else:
                         break
                 if note == 'P':
                     self.play_sound(0,
                                     dur * vstate.tempo,
                                     vstate.speed,
                                     volume=vstate.volume,
                                     voice=voice)
                     total_time[voice] += dur * vstate.tempo
                 else:
                     try:
                         self.play_sound(
                             note_freq[(vstate.octave + next_oct) * 12 +
                                       notes[note]],
                             dur * vstate.tempo,
                             vstate.speed,
                             volume=vstate.volume,
                             voice=voice)
                         total_time[voice] += dur * vstate.tempo
                     except KeyError:
                         raise error.RunError(error.IFC)
                 next_oct = 0
             elif c == 'M':
                 c = util.skip_read(gmls,
                                    draw_and_play.ml_whitepace).upper()
                 if c == 'N':
                     vstate.speed = 7. / 8.
                 elif c == 'L':
                     vstate.speed = 1.
                 elif c == 'S':
                     vstate.speed = 3. / 4.
                 elif c == 'F':
                     self.foreground = True
                 elif c == 'B':
                     self.foreground = False
                 else:
                     raise error.RunError(error.IFC)
             elif c == 'V' and (pcjr_sound == 'tandy' or
                                (pcjr_sound == 'pcjr' and self.sound_on)):
                 vstate.volume = min(
                     15, max(0, draw_and_play.ml_parse_number(gmls)))
             else:
                 raise error.RunError(error.IFC)
     max_time = max(total_time)
     for voice in range(3):
         if total_time[voice] < max_time:
             self.play_sound(0, max_time - total_time[voice], 1, 0, voice)
     if self.foreground:
         self.wait_all_music()
示例#24
0
def tokenise_line(line):
    """ Convert an ascii program line to tokenised form. """
    ins = StringIO(line)
    outs = StringIO()
    # skip whitespace at start of line
    d = util.skip(ins, ascii_whitespace)
    if d == '':
        # empty line at EOF
        return outs
    # read the line number
    tokenise_line_number(ins, outs)
    # expect line number
    allow_jumpnum = False
    # expect number (6553 6 -> the 6 is encoded as \x17)
    allow_number = True
    # flag for SPC( or TAB( as numbers can follow the closing bracket
    spc_or_tab = False
    # parse through elements of line
    while True:
        # peek next character, convert to uppercase
        c = util.peek(ins).upper()
        # anything after NUL is ignored till EOL
        if c == '\0':
            ins.read(1)
            ascii_read_to(ins, ('', '\r'))
            break
        # end of line
        elif c in ('', '\r'):
            break
        # handle whitespace
        elif c in ascii_whitespace:
            ins.read(1)
            outs.write(c)
        # handle string literals
        elif util.peek(ins) == '"':
            tokenise_literal(ins, outs)
        # handle jump numbers
        elif allow_number and allow_jumpnum and c in ascii_digits + '.':
            tokenise_jump_number(ins, outs)
        # handle numbers
        # numbers following var names with no operator or token in between
        # should not be parsed, eg OPTION BASE 1
        # note we don't include leading signs, encoded as unary operators
        # number starting with . or & are always parsed
        elif c in ('&', '.') or (allow_number and not allow_jumpnum
                                 and c in ascii_digits):
            representation.tokenise_number(ins, outs)
        # operator keywords ('+', '-', '=', '/', '\\', '^', '*', '<', '>'):
        elif c in ascii_operators:
            ins.read(1)
            # operators don't affect line number mode - can do line number
            # arithmetic and RENUM will do the strangest things
            # this allows for 'LIST 100-200' etc.
            outs.write(keyword_to_token[c])
            allow_number = True
        # special case ' -> :REM'
        elif c == "'":
            ins.read(1)
            outs.write(':' + tk.REM + tk.O_REM)
            tokenise_rem(ins, outs)
        # special case ? -> PRINT
        elif c == '?':
            ins.read(1)
            outs.write(tk.PRINT)
            allow_number = True
        # keywords & variable names
        elif c in ascii_uppercase:
            word = tokenise_word(ins, outs)
            # handle non-parsing modes
            if (word in ('REM', "'")
                    or (word == 'DEBUG' and word in keyword_to_token)):
                tokenise_rem(ins, outs)
            elif word == "DATA":
                tokenise_data(ins, outs)
            else:
                allow_jumpnum = (word in linenum_words)
                # numbers can follow tokenised keywords
                # (which does not include the word 'AS')
                allow_number = (word in keyword_to_token)
                if word in ('SPC(', 'TAB('):
                    spc_or_tab = True
        else:
            ins.read(1)
            if c in (',', '#', ';'):
                # can separate numbers as well as jumpnums
                allow_number = True
            elif c in ('(', '['):
                allow_jumpnum, allow_number = False, True
            elif c == ')' and spc_or_tab:
                spc_or_tab = False
                allow_jumpnum, allow_number = False, True
            else:
                allow_jumpnum, allow_number = False, False
            # replace all other nonprinting chars by spaces;
            # HOUSE 0x7f is allowed.
            outs.write(c if ord(c) >= 32 and ord(c) <= 127 else ' ')
    outs.seek(0)
    return outs
示例#25
0
def tokenise_line(line):
    """ Convert an ascii program line to tokenised form. """
    ins = StringIO(line)
    outs = StringIO()          
    # skip whitespace at start of line
    d = util.skip(ins, whitespace)
    if d == '':
        # empty line at EOF
        return outs
    # read the line number
    tokenise_line_number(ins, outs)
    # expect line number
    allow_jumpnum = False
    # expect number (6553 6 -> the 6 is encoded as \x17)
    allow_number = True
    # flag for SPC( or TAB( as numbers can follow the closing bracket
    spc_or_tab = False
    # parse through elements of line
    while True: 
        # peek next character, convert to uppercase
        c = util.peek(ins).upper()
        # anything after NUL is ignored till EOL
        if c == '\0':
            ins.read(1)
            ascii_read_to(ins, ('', '\r'))
            break
        # end of line    
        elif c in ('', '\r'):
            break
        # handle whitespace
        elif c in whitespace:
            ins.read(1)
            outs.write(c)
        # handle string literals    
        elif util.peek(ins) == '"':
            tokenise_literal(ins, outs)
        # handle jump numbers
        elif allow_number and allow_jumpnum and c in ascii_digits + ('.',):
            tokenise_jump_number(ins, outs) 
        # handle numbers
        # numbers following var names with no operator or token in between 
        # should not be parsed, eg OPTION BASE 1
        # note we don't include leading signs, encoded as unary operators
        # number starting with . or & are always parsed
        elif c in ('&', '.') or (allow_number and 
                                  not allow_jumpnum and c in ascii_digits):
            representation.tokenise_number(ins, outs)
        # operator keywords ('+', '-', '=', '/', '\\', '^', '*', '<', '>'):    
        elif c in ascii_operators: 
            ins.read(1)
            # operators don't affect line number mode - can do line number 
            # arithmetic and RENUM will do the strangest things
            # this allows for 'LIST 100-200' etc.
            outs.write(keyword_to_token[c])    
            allow_number = True
        # special case ' -> :REM'
        elif c == "'":
            ins.read(1)
            outs.write(':' + tk.REM + tk.O_REM)
            tokenise_rem(ins, outs)
        # special case ? -> PRINT 
        elif c == '?':
            ins.read(1)
            outs.write(tk.PRINT)
            allow_number = True
        # keywords & variable names       
        elif c in ascii_uppercase:
            word = tokenise_word(ins, outs)
            # handle non-parsing modes
            if (word in ('REM', "'") or 
                            (word == 'DEBUG' and word in keyword_to_token)):
                tokenise_rem(ins, outs)
            elif word == "DATA":    
                tokenise_data(ins, outs)
            else:    
                allow_jumpnum = (word in linenum_words)
                # numbers can follow tokenised keywords 
                # (which does not include the word 'AS')
                allow_number = (word in keyword_to_token)
                if word in ('SPC(', 'TAB('):
                    spc_or_tab = True
        else:
            ins.read(1)
            if c in (',', '#', ';'):
                # can separate numbers as well as jumpnums
                allow_number = True
            elif c in ('(', '['):
                allow_jumpnum, allow_number = False, True
            elif c == ')' and spc_or_tab:
                spc_or_tab = False
                allow_jumpnum, allow_number = False, True
            else:
                allow_jumpnum, allow_number = False, False
            # replace all other nonprinting chars by spaces; 
            # HOUSE 0x7f is allowed.
            outs.write(c if ord(c) >= 32 and ord(c) <= 127 else ' ')
    outs.seek(0)
    return outs
示例#26
0
文件: sound.py 项目: gilsim12/pcbasic
 def play(self, mml_list):
     """ Parse a list of Music Macro Language strings. """
     gmls_list = []
     for mml in mml_list:
         gmls = StringIO()
         # don't convert to uppercase as VARPTR$ elements are case sensitive
         gmls.write(str(mml))
         gmls.seek(0)
         gmls_list.append(gmls)
     next_oct = 0
     total_time = [0, 0, 0, 0]
     voices = range(3)
     while True:
         if not voices:
             break
         for voice in voices:
             vstate = self.play_state[voice]
             gmls = gmls_list[voice]
             c = util.skip_read(gmls, draw_and_play.ml_whitepace).upper()
             if c == '':
                 voices.remove(voice)
                 continue
             elif c == ';':
                 continue
             elif c == 'X':
                 # execute substring
                 sub = draw_and_play.ml_parse_string(gmls)
                 pos = gmls.tell()
                 rest = gmls.read()
                 gmls.truncate(pos)
                 gmls.write(str(sub))
                 gmls.write(rest)
                 gmls.seek(pos)
             elif c == 'N':
                 note = draw_and_play.ml_parse_number(gmls)
                 dur = vstate.length
                 c = util.skip(gmls, draw_and_play.ml_whitepace).upper()
                 if c == '.':
                     gmls.read(1)
                     dur *= 1.5
                 if note > 0 and note <= 84:
                     self.play_sound(note_freq[note-1], dur*vstate.tempo,
                                      vstate.speed, volume=vstate.volume,
                                      voice=voice)
                     total_time[voice] += dur*vstate.tempo
                 elif note == 0:
                     self.play_sound(0, dur*vstate.tempo, vstate.speed,
                                     volume=0, voice=voice)
                     total_time[voice] += dur*vstate.tempo
             elif c == 'L':
                 vstate.length = 1./draw_and_play.ml_parse_number(gmls)
             elif c == 'T':
                 vstate.tempo = 240./draw_and_play.ml_parse_number(gmls)
             elif c == 'O':
                 vstate.octave = min(6, max(0, draw_and_play.ml_parse_number(gmls)))
             elif c == '>':
                 vstate.octave += 1
                 if vstate.octave > 6:
                     vstate.octave = 6
             elif c == '<':
                 vstate.octave -= 1
                 if vstate.octave < 0:
                     vstate.octave = 0
             elif c in ('A', 'B', 'C', 'D', 'E', 'F', 'G', 'P'):
                 note = c
                 dur = vstate.length
                 while True:
                     c = util.skip(gmls, draw_and_play.ml_whitepace).upper()
                     if not c:
                         break
                     elif c == '.':
                         gmls.read(1)
                         dur *= 1.5
                     elif c in string.digits:
                         numstr = ''
                         while c and c in string.digits:
                             gmls.read(1)
                             numstr += c
                             c = util.skip(gmls, draw_and_play.ml_whitepace)
                         # NOT ml_parse_number, only literals allowed here!
                         length = int(numstr)
                         dur = 1. / float(length)
                     elif c in ('#', '+'):
                         gmls.read(1)
                         note += '#'
                     elif c == '-':
                         gmls.read(1)
                         note += '-'
                     else:
                         break
                 if note == 'P':
                     self.play_sound(0, dur * vstate.tempo, vstate.speed,
                                     volume=vstate.volume, voice=voice)
                     total_time[voice] += dur*vstate.tempo
                 else:
                     try:
                         self.play_sound(
                             note_freq[(vstate.octave+next_oct)*12 + notes[note]],
                             dur * vstate.tempo, vstate.speed,
                             volume=vstate.volume, voice=voice)
                         total_time[voice] += dur*vstate.tempo
                     except KeyError:
                         raise error.RunError(error.IFC)
                 next_oct = 0
             elif c == 'M':
                 c = util.skip_read(gmls, draw_and_play.ml_whitepace).upper()
                 if c == 'N':
                     vstate.speed = 7./8.
                 elif c == 'L':
                     vstate.speed = 1.
                 elif c == 'S':
                     vstate.speed = 3./4.
                 elif c == 'F':
                     self.foreground = True
                 elif c == 'B':
                     self.foreground = False
                 else:
                     raise error.RunError(error.IFC)
             elif c == 'V' and (self.capabilities == 'tandy' or
                                 (self.capabilities == 'pcjr' and self.sound_on)):
                 vstate.volume = min(15,
                                 max(0, draw_and_play.ml_parse_number(gmls)))
             else:
                 raise error.RunError(error.IFC)
     max_time = max(total_time)
     for voice in range(3):
         if total_time[voice] < max_time:
             self.play_sound(0, max_time - total_time[voice], 1, 0, voice)
     if self.foreground:
         self.wait_all_music()