PLYの中にBASIC処理系が入ってた

PLYPython製のlexer,yaccなんですが、その中のexampleとしてBASIC処理系が入っていました。BASIC言語はさわった事が無かったので、次のようなシェルを作って遊んでみました。一応、viとも連携してファイルを編集(edit_ fpath)、削除(rm fpath)、そしてBASICの実行(run_ fpath)ができるんですよ。

#!/usr/bin/env python2.6
import os
import subprocess
import cmd
import sys
sys.path.insert(0,"./third_party/")
import util
import dircache
import basiclex
import basparse
import basinterp
class CUI(cmd.Cmd):
    prompt = "BASIC> "
    editor = os.environ.get('EDITOR', 'vi')
    def __init__(self, completekey='tab', stdin=None, stdout=None):
        cmd.Cmd.__init__(self, completekey, stdin, stdout)
        self.current_file = ''
    def default(self, line):
        pass
    def do_EOF(self, args):
        self.stdout.write("Exit!\n")
        return 1
    do_quit_ = do_EOF
    def do_edit_(self, path):
        path = self.valid_path(path)
        if not path:
            return
        cmd = "%s %s" % (self.editor, path)
        proc = subprocess.call(cmd, shell=True, close_fds='posix',
                                     env=dict(os.environ), cwd=None)
        if os.path.exists(path):
            self.current_file = path
    def valid_path(self, path):
        if not path:
            if self.current_file:
                return self.current_file
            else:
                return ''
        return path
    def do_run_(self, path):
        path = self.valid_path(path)
        if not path:
            return
        data = open(path, 'r').read()
        try:
            prog = basparse.parse(data)
            if not prog: raise SystemExit
            b = basinterp.BasicInterpreter(prog)
            b.run()
        except :
            pass
        finally:
            if os.path.exists(path):
                self.current_file = path
    def do_rm_(self, path):
        path = self.valid_path(path)
        if not os.path.exists(path):
            return
        os.remove(path)
    def complete_run_(self, *args):
        return complate_path(*args)
    complete_rm_ = complete_edit_ = complete_run_
def complate_path(ignore, line, *ignores):
    path = line.split()[1]
    fname = ''    
    if path == '' or path == '.':
        path = './'
    else:
        if '/' in path:
            i = path.rfind('/')
            fname = path[i+1:]
            path = path[:i]
        else:
            fname = path
            path = './'
    return [name for name in dircache.listdir(path) if name.startswith(fname)]
if __name__ == '__main__':
    CUI().cmdloop()

BASICのhello worldはこんな風になるみたいですね。左に数字を書くのが面倒な感じです。

5  REM HELLO WORLD PROGAM
10 PRINT "HELLO WORLD"
99 END