Ejemplo n.º 1
0
 def _input_entry(self, typechar, allow_past_end):
     """ Read a number or string entry for INPUT """
     word, blanks = '', ''
     last = self._skip_whitespace(self.whitespace_input)
     # read first non-whitespace char
     c = self.read(1)
     # LF escapes quotes
     # may be true if last == '', hence "in ('\n', '\0')" not "in '\n0'"
     quoted = (c == '"' and typechar == '$' and last not in ('\n', '\0'))
     if quoted:
         c = self.read(1)
     # LF escapes end of file, return empty string
     if not c and not allow_past_end and last not in ('\n', '\0'):
         raise error.RunError(error.INPUT_PAST_END)
     # we read the ending char before breaking the loop
     # this may raise FIELD OVERFLOW
     # on reading from a KYBD: file, control char replacement takes place
     # which means we need to use read() not read_raw()
     while c and not ((typechar != '$' and c in self.soft_sep) or
                     (c in ',\r' and not quoted)):
         if c == '"' and quoted:
             # whitespace after quote will be skipped below
             break
         elif c == '\n' and not quoted:
             # LF, LFCR are dropped entirely
             c = self.read(1)
             if c == '\r':
                 c = self.read(1)
             continue
         elif c == '\0':
             # NUL is dropped even within quotes
             pass
         elif c in self.whitespace_input and not quoted:
             # ignore whitespace in numbers, except soft separators
             # include internal whitespace in strings
             if typechar == '$':
                 blanks += c
         else:
             word += blanks + c
             blanks = ''
         if len(word) + len(blanks) >= 255:
             break
         if not quoted:
             c = self.read(1)
         else:
             # no CRLF replacement inside quotes.
             # -- but should there be KYBD: control char replacement?
             c = self.read_raw(1)
     # if separator was a whitespace char or closing quote
     # skip trailing whitespace before any comma or hard separator
     if c and c in self.whitespace_input or (quoted and c == '"'):
         self._skip_whitespace(' ')
         if (self.next_char in ',\r'):
             c = self.read(1)
     # file position is at one past the separator char
     # convert result to requested type, be strict about non-numeric chars
     value = vartypes.pack_string(bytearray(word))
     if typechar != '$':
         value = representation.str_to_value_keep(value, allow_nonnum=False)
     return value, c
Ejemplo n.º 2
0
 def _input_entry(self, typechar, allow_past_end):
     """ Read a number or string entry for INPUT """
     word, blanks = '', ''
     last = self._skip_whitespace(self.whitespace_input)
     # read first non-whitespace char
     c = self.read(1)
     # LF escapes quotes
     # may be true if last == '', hence "in ('\n', '\0')" not "in '\n0'"
     quoted = (c == '"' and typechar == '$' and last not in ('\n', '\0'))
     if quoted:
         c = self.read(1)
     # LF escapes end of file, return empty string
     if not c and not allow_past_end and last not in ('\n', '\0'):
         raise error.RunError(error.INPUT_PAST_END)
     # we read the ending char before breaking the loop
     # this may raise FIELD OVERFLOW
     # on reading from a KYBD: file, control char replacement takes place
     # which means we need to use read() not read_raw()
     while c and not ((typechar != '$' and c in self.soft_sep) or
                      (c in ',\r' and not quoted)):
         if c == '"' and quoted:
             # whitespace after quote will be skipped below
             break
         elif c == '\n' and not quoted:
             # LF, LFCR are dropped entirely
             c = self.read(1)
             if c == '\r':
                 c = self.read(1)
             continue
         elif c == '\0':
             # NUL is dropped even within quotes
             pass
         elif c in self.whitespace_input and not quoted:
             # ignore whitespace in numbers, except soft separators
             # include internal whitespace in strings
             if typechar == '$':
                 blanks += c
         else:
             word += blanks + c
             blanks = ''
         if len(word) + len(blanks) >= 255:
             break
         if not quoted:
             c = self.read(1)
         else:
             # no CRLF replacement inside quotes.
             # -- but should there be KYBD: control char replacement?
             c = self.read_raw(1)
     # if separator was a whitespace char or closing quote
     # skip trailing whitespace before any comma or hard separator
     if c and c in self.whitespace_input or (quoted and c == '"'):
         self._skip_whitespace(' ')
         if (self.next_char in ',\r'):
             c = self.read(1)
     # file position is at one past the separator char
     # convert result to requested type, be strict about non-numeric chars
     value = vartypes.pack_string(bytearray(word))
     if typechar != '$':
         value = representation.str_to_value_keep(value, allow_nonnum=False)
     return value, c
Ejemplo n.º 3
0
 def _input_entry(self, typechar, allow_past_end):
     """ Read a number or string entry from KYBD: for INPUT# """
     word, blanks = '', ''
     if self.input_last:
         c, self.input_last = self.input_last, ''
     else:
         last = self._skip_whitespace(self.whitespace_input)
         # read first non-whitespace char
         c = self.read(1)
     # LF escapes quotes
     # may be true if last == '', hence "in ('\n', '\0')" not "in '\n0'"
     quoted = (c == '"' and typechar == '$' and last not in ('\n', '\0'))
     if quoted:
         c = self.read(1)
     # LF escapes end of file, return empty string
     if not c and not allow_past_end and last not in ('\n', '\0'):
         raise error.RunError(error.INPUT_PAST_END)
     # we read the ending char before breaking the loop
     # this may raise FIELD OVERFLOW
     # on reading from a KYBD: file, control char replacement takes place
     # which means we need to use read() not read_raw()
     parsing_trail = False
     while c and not (c in ',\r' and not quoted):
         if c == '"' and quoted:
             parsing_trail = True
         elif c == '\n' and not quoted:
             # LF, LFCR are dropped entirely
             c = self.read(1)
             if c == '\r':
                 c = self.read(1)
             continue
         elif c == '\0':
             # NUL is dropped even within quotes
             pass
         elif c in self.whitespace_input and not quoted:
             # ignore whitespace in numbers, except soft separators
             # include internal whitespace in strings
             if typechar == '$':
                 blanks += c
         else:
             word += blanks + c
             blanks = ''
         if len(word) + len(blanks) >= 255:
             break
         # there should be KYBD: control char replacement here even if quoted
         c = self.read(1)
         if parsing_trail:
             if c not in self.whitespace_input:
                 if c not in (',', '\r'):
                     self.input_last = c
                 break
         parsing_trail = parsing_trail or (typechar != '$' and c == ' ')
     # file position is at one past the separator char
     # convert result to requested type, be strict about non-numeric chars
     value = vartypes.pack_string(bytearray(word))
     if typechar != '$':
         value = representation.str_to_value_keep(value, allow_nonnum=False)
     return value, c
Ejemplo n.º 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)
Ejemplo n.º 5
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)
Ejemplo n.º 6
0
def value_val(ins):
    """ VAL: number value of a string. """
    val = representation.str_to_value_keep(parse_bracket(ins))
    return val if val else vartypes.null['%']
Ejemplo n.º 7
0
 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 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. / 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()
Ejemplo n.º 8
0
 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()
Ejemplo n.º 9
0
def value_val(ins):
    """ VAL: number value of a string. """
    val = representation.str_to_value_keep(parse_bracket(ins))
    return val if val else vartypes.null['%']