PLYの中にBASIC処理系が入ってた
PLYはPython製の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