Exemplo n.º 1
0
def parse_literal(ins):
    """ Compute the value of the literal at the current code pointer. """
    d = util.skip_white(ins)
    # string literal
    if d == '"':
        ins.read(1)
        if ins == state.basic_state.bytecode:
            address = ins.tell() + memory.code_start
        else:
            address = None
        output = bytearray()
        # while tokenised numbers inside a string literal will be printed as tokenised numbers, they don't actually execute as such:
        # a \00 character, even if inside a tokenised number, will break a string literal (and make the parser expect a
        # line number afterwards, etc. We follow this.
        d = ins.read(1)
        while d not in tk.end_line + ('"', ):
            output += d
            d = ins.read(1)
        if d == '\0':
            ins.seek(-1, 1)
        # store for easy retrieval, but don't reserve space in string memory
        return state.basic_state.strings.store(output, address)
    # number literals as ASCII are accepted in tokenised streams. only if they start with a figure (not & or .)
    # this happens e.g. after non-keywords like AS. They are not acceptable as line numbers.
    elif d in string.digits:
        outs = StringIO()
        representation.tokenise_number(ins, outs)
        outs.seek(0)
        return representation.parse_value(outs)
    # number literals
    elif d in tk.number:
        return representation.parse_value(ins)
    # gw-basic allows adding line numbers to numbers
    elif d == tk.T_UINT:
        return vartypes.int_to_integer_unsigned(util.parse_jumpnum(ins))
    else:
        raise error.RunError(error.STX)
Exemplo n.º 2
0
def parse_literal(ins):
    """ Compute the value of the literal at the current code pointer. """
    d = util.skip_white(ins)
    # string literal
    if d == '"':
        ins.read(1)
        if ins == state.basic_state.bytecode:
            address = ins.tell() + memory.code_start
        else:
            address = None
        output = bytearray()
        # while tokenised numbers inside a string literal will be printed as tokenised numbers, they don't actually execute as such:
        # a \00 character, even if inside a tokenised number, will break a string literal (and make the parser expect a
        # line number afterwards, etc. We follow this.
        d = ins.read(1)
        while d not in tk.end_line + ('"',):
            output += d
            d = ins.read(1)
        if d == '\0':
            ins.seek(-1, 1)
        # store for easy retrieval, but don't reserve space in string memory
        return state.basic_state.strings.store(output, address)
    # number literals as ASCII are accepted in tokenised streams. only if they start with a figure (not & or .)
    # this happens e.g. after non-keywords like AS. They are not acceptable as line numbers.
    elif d in string.digits:
        outs = StringIO()
        representation.tokenise_number(ins, outs)
        outs.seek(0)
        return representation.parse_value(outs)
    # number literals
    elif d in tk.number:
        return representation.parse_value(ins)
    # gw-basic allows adding line numbers to numbers
    elif d == tk.T_UINT:
        return vartypes.int_to_integer_unsigned(util.parse_jumpnum(ins))
    else:
        raise error.RunError(error.STX)
Exemplo n.º 3
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
Exemplo n.º 4
0
def parse_expr_unit(ins):
    """ Compute the value of the expression unit at the current code pointer. """
    d = util.skip_white(ins)
    # string literal
    if d == '"':
        ins.read(1)
        output = bytearray()
        # while tokenised nmbers inside a string literal will be printed as tokenised numbers, they don't actually execute as such:
        # a \00 character, even if inside a tokenised number, will break a string literal (and make the parser expect a
        # line number afterwards, etc. We follow this.
        d = ins.read(1)
        while d not in tk.end_line + ('"',):
            output += d
            d = ins.read(1)
        if d == '\0':
            ins.seek(-1, 1)
        return vartypes.pack_string(output)
    # variable name
    elif d in string.ascii_uppercase:
        name, indices = get_var_or_array_name(ins)
        return var.get_var_or_array(name, indices)
    # number literals as ASCII are accepted in tokenised streams. only if they start with a figure (not & or .)
    # this happens e.g. after non-keywords like AS. They are not acceptable as line numbers.
    elif d in string.digits:
        outs = StringIO()
        representation.tokenise_number(ins, outs)
        outs.seek(0)
        return representation.parse_value(outs)
    # number literals
    elif d in tk.number:
        return representation.parse_value(ins)
    # gw-basic allows adding line numbers to numbers
    elif d == tk.T_UINT:
        return vartypes.pack_int(util.parse_jumpnum(ins))
    # brackets
    elif d == '(':
        return parse_bracket(ins)
    # single-byte tokens
    else:
        ins.read(1)
        if d == tk.INPUT:         return value_input(ins)
        elif d == tk.SCREEN:      return value_screen(ins)
        elif d == tk.USR:         return value_usr(ins)
        elif d == tk.FN:          return value_fn(ins)
        elif d == tk.NOT:         return value_not(ins)
        elif d == tk.ERL:         return value_erl(ins)
        elif d == tk.ERR:         return value_err(ins)
        elif d == tk.STRING:      return value_string(ins)
        elif d == tk.INSTR:       return value_instr(ins)
        elif d == tk.VARPTR:      return value_varptr(ins)
        elif d == tk.CSRLIN:      return value_csrlin(ins)
        elif d == tk.POINT:       return value_point(ins)
        elif d == tk.INKEY:       return value_inkey(ins)
        elif d == tk.O_PLUS:      return parse_expr_unit(ins)
        elif d == tk.O_MINUS:     return value_neg(ins)
        # two-byte tokens
        elif d == '\xFD':
            d += ins.read(1)
            if d == tk.CVI:       return value_cvi(ins)
            elif d == tk.CVS:     return value_cvs(ins)
            elif d == tk.CVD:     return value_cvd(ins)
            elif d == tk.MKI:     return value_mki(ins)
            elif d == tk.MKS:     return value_mks(ins)
            elif d == tk.MKD:     return value_mkd(ins)
            elif d == tk.EXTERR:  return value_exterr(ins)
        # two-byte tokens
        elif d == '\xFE':
            d += ins.read(1)
            if d == tk.DATE:      return value_date(ins)
            elif d == tk.TIME:    return value_time(ins)
            elif d == tk.PLAY:    return value_play(ins)
            elif d == tk.TIMER:   return value_timer(ins)
            elif d == tk.ERDEV:   return value_erdev(ins)
            elif d == tk.IOCTL:   return value_ioctl(ins)
            elif d == tk.ENVIRON: return value_environ(ins)
            elif d == tk.PMAP:    return value_pmap(ins)
        # two-byte tokens
        elif d == '\xFF':
            d += ins.read(1)
            if d == tk.LEFT:    return value_left(ins)
            elif d == tk.RIGHT: return value_right(ins)
            elif d == tk.MID:   return value_mid(ins)
            elif d == tk.SGN:   return value_sgn(ins)
            elif d == tk.INT:   return value_int(ins)
            elif d == tk.ABS:   return value_abs(ins)
            elif d == tk.SQR:   return value_sqr(ins)
            elif d == tk.RND:   return value_rnd(ins)
            elif d == tk.SIN:   return value_sin(ins)
            elif d == tk.LOG:   return value_log(ins)
            elif d == tk.EXP:   return value_exp(ins)
            elif d == tk.COS:   return value_cos(ins)
            elif d == tk.TAN:   return value_tan(ins)
            elif d == tk.ATN:   return value_atn(ins)
            elif d == tk.FRE:   return value_fre(ins)
            elif d == tk.INP:   return value_inp(ins)
            elif d == tk.POS:   return value_pos(ins)
            elif d == tk.LEN:   return value_len(ins)
            elif d == tk.STR:   return value_str(ins)
            elif d == tk.VAL:   return value_val(ins)
            elif d == tk.ASC:   return value_asc(ins)
            elif d == tk.CHR:   return value_chr(ins)
            elif d == tk.PEEK:  return value_peek(ins)
            elif d == tk.SPACE: return value_space(ins)
            elif d == tk.OCT:   return value_oct(ins)
            elif d == tk.HEX:   return value_hex(ins)
            elif d == tk.LPOS:  return value_lpos(ins)
            elif d == tk.CINT:  return value_cint(ins)
            elif d == tk.CSNG:  return value_csng(ins)
            elif d == tk.CDBL:  return value_cdbl(ins)
            elif d == tk.FIX:   return value_fix(ins)
            elif d == tk.PEN:   return value_pen(ins)
            elif d == tk.STICK: return value_stick(ins)
            elif d == tk.STRIG: return value_strig(ins)
            elif d == tk.EOF:   return value_eof(ins)
            elif d == tk.LOC:   return value_loc(ins)
            elif d == tk.LOF:   return value_lof(ins)
        else:
            return None
Exemplo n.º 5
0
def parse_expr_unit(ins):
    """ Compute the value of the expression unit at the current code pointer. """
    d = util.skip_white(ins)
    # string literal
    if d == '"':
        ins.read(1)
        output = bytearray()
        # while tokenised nmbers inside a string literal will be printed as tokenised numbers, they don't actually execute as such:
        # a \00 character, even if inside a tokenised number, will break a string literal (and make the parser expect a 
        # line number afterwards, etc. We follow this.
        d = ins.read(1)
        while d not in util.end_line + ('"',):
            output += d
            d = ins.read(1)
        if d == '\0':
            ins.seek(-1, 1)
        return vartypes.pack_string(output)
    # variable name
    elif d >= 'A' and d <= 'Z':
        name, indices = get_var_or_array_name(ins)
        return var.get_var_or_array(name, indices)
    # number literals as ASCII are accepted in tokenised streams. only if they start with a figure (not & or .)
    # this happens e.g. after non-keywords like AS. They are not acceptable as line numbers.
    elif d >= '0' and d <= '9':
        outs = StringIO()
        representation.tokenise_number(ins, outs)
        outs.seek(0)
        return util.parse_value(outs)
    # number literals
    elif d in token.number:
        return util.parse_value(ins)   
    # gw-basic allows adding line numbers to numbers     
    elif d == token.T_UINT:
        return vartypes.pack_int(util.parse_jumpnum(ins))
    # brackets
    elif d == '(':
        return parse_bracket(ins)
    # single-byte tokens 
    else:
        ins.read(1)       
        if d == '\x85':         return value_input(ins)
        elif d == '\xC8':       return value_screen(ins)
        elif d == '\xD0':       return value_usr(ins)
        elif d == '\xD1':       return value_fn(ins)
        elif d == '\xD3':       return value_not(ins)
        elif d == '\xD4':       return value_erl(ins)
        elif d == '\xD5':       return value_err(ins)
        elif d == '\xD6':       return value_string(ins)
        elif d == '\xD8':       return value_instr(ins)    
        elif d == '\xDA':       return value_varptr(ins)
        elif d == '\xDB':       return value_csrlin(ins)
        elif d == '\xDC':       return value_point(ins)
        elif d == '\xDE':       return value_inkey(ins)
        elif d == '\xE9':       return parse_expr_unit(ins)
        elif d == '\xEA':       return value_neg(ins)     
        # two-byte tokens
        elif d == '\xFD':
            d = ins.read(1)
            if d == '\x81':      return value_cvi(ins)
            elif d =='\x82':     return value_cvs(ins)
            elif d =='\x83':     return value_cvd(ins)
            elif d =='\x84':     return value_mki(ins)
            elif d =='\x85':     return value_mks(ins)
            elif d =='\x86':     return value_mkd(ins)
            elif d == '\x8b':    return value_exterr(ins)
        # two-byte tokens
        elif d == '\xFE':
            d = ins.read(1)        
            if d == '\x8D':      return value_date(ins)
            elif d == '\x8E':    return value_time(ins)
            elif d == '\x93':    return value_play(ins)
            elif d == '\x94':    return value_timer(ins)
            elif d == '\x95':    return value_erdev(ins)
            elif d == '\x96':    return value_ioctl(ins)
            elif d == '\x9B':    return value_environ(ins)
            elif d == '\x9E':    return value_pmap(ins)
        # two-byte tokens                    
        elif d == '\xFF':
            d = ins.read(1)
            if d == '\x81':     return value_left(ins)
            elif d == '\x82':   return value_right(ins)
            elif d == '\x83':   return value_mid(ins)
            elif d == '\x84':   return value_sgn(ins)
            elif d == '\x85':   return value_int(ins)
            elif d == '\x86':   return value_abs(ins)
            elif d == '\x87':   return value_sqrt(ins)
            elif d == '\x88':   return value_rnd(ins)
            elif d == '\x89':   return value_sin(ins)
            elif d == '\x8a':   return value_log(ins)
            elif d == '\x8b':   return value_exp(ins)
            elif d == '\x8c':   return value_cos(ins)
            elif d == '\x8D':   return value_tan(ins)
            elif d == '\x8E':   return value_atn(ins)
            elif d == '\x8F':   return value_fre(ins)
            elif d == '\x90':   return value_inp(ins)
            elif d == '\x91':   return value_pos(ins)
            elif d == '\x92':   return value_len(ins)
            elif d == '\x93':   return value_str(ins)
            elif d == '\x94':   return value_val(ins)
            elif d == '\x95':   return value_asc(ins)
            elif d == '\x96':   return value_chr(ins)
            elif d == '\x97':   return value_peek(ins)
            elif d == '\x98':   return value_space(ins)
            elif d == '\x99':   return value_oct(ins)
            elif d == '\x9A':   return value_hex(ins)
            elif d == '\x9B':   return value_lpos(ins)
            elif d == '\x9C':   return value_cint(ins)
            elif d == '\x9D':   return value_csng(ins)
            elif d == '\x9E':   return value_cdbl(ins)
            elif d == '\x9F':   return value_fix(ins)    
            elif d == '\xA0':   return value_pen(ins)
            elif d == '\xA1':   return value_stick(ins)
            elif d == '\xA2':   return value_strig(ins)
            elif d == '\xA3':   return value_eof(ins)
            elif d == '\xA4':   return value_loc(ins)
            elif d == '\xA5':   return value_lof(ins)
        else:
            return None
Exemplo n.º 6
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
Exemplo n.º 7
0
def parse_expr_unit(ins):
    """ Compute the value of the expression unit at the current code pointer. """
    d = util.skip_white(ins)
    # string literal
    if d == '"':
        ins.read(1)
        output = bytearray()
        # while tokenised nmbers inside a string literal will be printed as tokenised numbers, they don't actually execute as such:
        # a \00 character, even if inside a tokenised number, will break a string literal (and make the parser expect a
        # line number afterwards, etc. We follow this.
        d = ins.read(1)
        while d not in tk.end_line + ('"', ):
            output += d
            d = ins.read(1)
        if d == '\0':
            ins.seek(-1, 1)
        return vartypes.pack_string(output)
    # variable name
    elif d in string.ascii_uppercase:
        name, indices = get_var_or_array_name(ins)
        return var.get_var_or_array(name, indices)
    # number literals as ASCII are accepted in tokenised streams. only if they start with a figure (not & or .)
    # this happens e.g. after non-keywords like AS. They are not acceptable as line numbers.
    elif d in string.digits:
        outs = StringIO()
        representation.tokenise_number(ins, outs)
        outs.seek(0)
        return representation.parse_value(outs)
    # number literals
    elif d in tk.number:
        return representation.parse_value(ins)
    # gw-basic allows adding line numbers to numbers
    elif d == tk.T_UINT:
        return vartypes.pack_int(util.parse_jumpnum(ins))
    # brackets
    elif d == '(':
        return parse_bracket(ins)
    # single-byte tokens
    else:
        ins.read(1)
        if d == tk.INPUT: return value_input(ins)
        elif d == tk.SCREEN: return value_screen(ins)
        elif d == tk.USR: return value_usr(ins)
        elif d == tk.FN: return value_fn(ins)
        elif d == tk.NOT: return value_not(ins)
        elif d == tk.ERL: return value_erl(ins)
        elif d == tk.ERR: return value_err(ins)
        elif d == tk.STRING: return value_string(ins)
        elif d == tk.INSTR: return value_instr(ins)
        elif d == tk.VARPTR: return value_varptr(ins)
        elif d == tk.CSRLIN: return value_csrlin(ins)
        elif d == tk.POINT: return value_point(ins)
        elif d == tk.INKEY: return value_inkey(ins)
        elif d == tk.O_PLUS: return parse_expr_unit(ins)
        elif d == tk.O_MINUS:
            return value_neg(ins)
            # two-byte tokens
        elif d == '\xFD':
            d += ins.read(1)
            if d == tk.CVI: return value_cvi(ins)
            elif d == tk.CVS: return value_cvs(ins)
            elif d == tk.CVD: return value_cvd(ins)
            elif d == tk.MKI: return value_mki(ins)
            elif d == tk.MKS: return value_mks(ins)
            elif d == tk.MKD: return value_mkd(ins)
            elif d == tk.EXTERR: return value_exterr(ins)
        # two-byte tokens
        elif d == '\xFE':
            d += ins.read(1)
            if d == tk.DATE: return value_date(ins)
            elif d == tk.TIME: return value_time(ins)
            elif d == tk.PLAY: return value_play(ins)
            elif d == tk.TIMER: return value_timer(ins)
            elif d == tk.ERDEV: return value_erdev(ins)
            elif d == tk.IOCTL: return value_ioctl(ins)
            elif d == tk.ENVIRON: return value_environ(ins)
            elif d == tk.PMAP: return value_pmap(ins)
        # two-byte tokens
        elif d == '\xFF':
            d += ins.read(1)
            if d == tk.LEFT: return value_left(ins)
            elif d == tk.RIGHT: return value_right(ins)
            elif d == tk.MID: return value_mid(ins)
            elif d == tk.SGN: return value_sgn(ins)
            elif d == tk.INT: return value_int(ins)
            elif d == tk.ABS: return value_abs(ins)
            elif d == tk.SQR: return value_sqr(ins)
            elif d == tk.RND: return value_rnd(ins)
            elif d == tk.SIN: return value_sin(ins)
            elif d == tk.LOG: return value_log(ins)
            elif d == tk.EXP: return value_exp(ins)
            elif d == tk.COS: return value_cos(ins)
            elif d == tk.TAN: return value_tan(ins)
            elif d == tk.ATN: return value_atn(ins)
            elif d == tk.FRE: return value_fre(ins)
            elif d == tk.INP: return value_inp(ins)
            elif d == tk.POS: return value_pos(ins)
            elif d == tk.LEN: return value_len(ins)
            elif d == tk.STR: return value_str(ins)
            elif d == tk.VAL: return value_val(ins)
            elif d == tk.ASC: return value_asc(ins)
            elif d == tk.CHR: return value_chr(ins)
            elif d == tk.PEEK: return value_peek(ins)
            elif d == tk.SPACE: return value_space(ins)
            elif d == tk.OCT: return value_oct(ins)
            elif d == tk.HEX: return value_hex(ins)
            elif d == tk.LPOS: return value_lpos(ins)
            elif d == tk.CINT: return value_cint(ins)
            elif d == tk.CSNG: return value_csng(ins)
            elif d == tk.CDBL: return value_cdbl(ins)
            elif d == tk.FIX: return value_fix(ins)
            elif d == tk.PEN: return value_pen(ins)
            elif d == tk.STICK: return value_stick(ins)
            elif d == tk.STRIG: return value_strig(ins)
            elif d == tk.EOF: return value_eof(ins)
            elif d == tk.LOC: return value_loc(ins)
            elif d == tk.LOF: return value_lof(ins)
        else:
            return None