codepad
[
create a new paste
]
login
|
about
Language:
C
C++
D
Haskell
Lua
OCaml
PHP
Perl
Plain Text
Python
Ruby
Scheme
Tcl
# -*- coding: utf-8 -*- import re class forth(): Stack = [] FunctionList = {} VariableList = {} ParsedCode = [] def __init__(self, text): pc = self.perse(text) #空文字列を取り除く for x in pc: if x != '': self.ParsedCode.append(x) pass def __del__(self): pass def perse(self, text): ret = "" for x in text.split("\n"): t = x.split("#") ret += t[0] + " " return re.split("\s+", ret) def execute(self): cl = self.ParsedCode pc = [0] nc = [0] self._execute(cl, pc, nc) def _execute(self, cl, pc , nc): while(pc[0] < len(cl)): if (self.operator(cl, pc, nc)): pass #operatorが評価されたので、スタックに積まない else: try: #数値化できれば数値化する i = int(cl[pc[0]]) self.Stack.append(i) except: #数値化できないので、文字列として積む self.Stack.append(cl[pc[0]]) pc[0] += 1 def operator(self, cl, pc, nc): #stack の回転関数 上からn個をm回回転させる n>mが前提 def rot_p(n,m): front = self.Stack[:len(self.Stack) - n] back = self.Stack[-n:] self.Stack = front + back[-m:] + back[:n - m] ope = cl[pc[0]] #四則演算系 if ope == "+": self.Stack.append(self.Stack.pop() + self.Stack.pop()) elif ope == "-": rot_p(2,1) self.Stack.append(self.Stack.pop() - self.Stack.pop()) elif ope == "*": self.Stack.append(self.Stack.pop() * self.Stack.pop()) elif ope == "/": rot_p(2,1) self.Stack.append(self.Stack.pop() / self.Stack.pop()) #比較演算系 elif ope == "<": rot_p(2,1) self.Stack.append(int(self.Stack.pop() < self.Stack.pop())) elif ope == "<=": rot_p(2,1) self.Stack.append(int(self.Stack.pop() <= self.Stack.pop())) elif ope == ">": rot_p(2,1) self.Stack.append(int(self.Stack.pop() > self.Stack.pop())) elif ope == ">=": rot_p(2,1) self.Stack.append(int(self.Stack.pop() >= self.Stack.pop())) elif ope == "==" or ope == "=": rot_p(2,1) self.Stack.append(int(self.Stack.pop() == self.Stack.pop())) elif ope == "<>" or ope == "!=": rot_p(2,1) self.Stack.append(int(self.Stack.pop() != self.Stack.pop())) #ビット演算系 elif ope == "|": self.Stack.append(int(self.Stack.pop() | self.Stack.pop())) elif ope == "&": self.Stack.append(int(self.Stack.pop() & self.Stack.pop())) elif ope == "^": self.Stack.append(int(self.Stack.pop() ^ self.Stack.pop())) elif ope == "~": self.Stack.append(int(~self.Stack.pop())) #論理演算系 めんどくさいのでドモルガンの定理を利用 elif ope == "or": self.Stack.append(int(not self.Stack.pop() and not self.Stack.pop())) elif ope == "and": self.Stack.append(int(not self.Stack.pop() or not self.Stack.pop())) elif ope == "not": self.Stack.append(int(not self.Stack.pop)) #スタック操作系 elif ope == "dup": s = self.Stack.pop() self.Stack.append(s) self.Stack.append(s) elif ope == "load": n = self.Stack.pop() self.Stack.append(self.Stack[-n]) elif ope == "drop": self.Stack.pop() elif ope == "swap": rot_p(2,1) elif ope == "rot": rot_p(3,1) elif ope == "over": self.Stack.append(self.Stack[-2]) elif ope == "dump": print self.Stack #表示系 elif ope == ".": print self.Stack.pop() elif ope =="if": if self.Stack.pop(): nc[0] += 1 pass else: #elseか、endifまで読み飛ばす n = 0 while(True): pc[0] += 1 o = cl[pc[0]] if o == "if": n += 1 elif o == "else": if n == 0: nc[0] += 1 break elif o == "endif": if n == 0: break else: n -= 1 elif ope == "else": #endif まで読み飛ばす n = 0 while(True): pc[0] += 1 o = cl[pc[0]] if o == "if": n += 1 elif o == "endif": if n == 0: break else: n -= 1 elif ope == "endif": pass #手続きの宣言 elif ope == ":" : #これdefか何かに変える? pc[0] += 1 name = cl[pc[0]] self.FunctionList[name] = [] while(True): pc[0] += 1 c = cl[pc[0]] if c == ";": break else: self.FunctionList[name].append(c) elif self.FunctionList.has_key(ope): self._execute(self.FunctionList[ope],[0],[0]) #変数の代入と参照 elif ope == "!": name = self.Stack.pop() self.VariableList[name] = self.Stack.pop() elif ope == "@": name = self.Stack.pop() self.Stack.append(self.VariableList[name]) #while文 elif ope == "while": if self.Stack.pop(): pass else: #対応するrepeat まで読み飛ばす n = 0 while(True): pc[0] += 1 o = cl[pc[0]] if o == "while": n += 1 elif o == "repeat": if n == 0: break else: n -= 1 elif ope == "repeat": #whileの一個前まで戻る n = 0 while(True): pc[0] -= 1 o = cl[pc[0]] if o == "while": if n == 0: #一個前に戻す pc[0] -= 1 break else: n -= 1 elif o == "repeat": n += 1 else: return False return True f = forth( ''' 1 20 - . # 1-20をして表示する 1 10 < . # 1<10をして表示する 1 if # スタックの一番上を評価する here is TRUE . . . # trueならここが実行される 0 if NOTCOMING . # こない endif else here is FALSE . . . # falseならばここが実行される endif 100 n ! # nに100を代入する n @ . # nを参照して表示する : hoge n @ 1 - n ! ; # void hoge(){n = n - 1} を定義する hoge hoge hoge # hogeを三回実行する n @ . # nを表示してみる(97が表示される) # 0~9までカウントする 0 n ! # nに0を代入する 1 # スタックの一番上が真ならwhileを実行 while n @ . # nの値を表示する n @ 1 + n ! # n=n+1 n @ 10 < # n < 10 をpushする repeat # whileに戻る : square dup * ; # 二乗する関数を定義する 10 square . : fac # 再帰で階乗を書いてみる。スタックを二個引数に取る dump # 突入時にメモリダンプしてみる dup if over over * over 1 - fac rot drop drop # ローカル変数を開放する(?) dump else drop endif ; 1 10 fac . # 1*10!の意味 ''') f.execute()
Private
[
?
]
Run code
Submit