ところてん #5420(2008/01/21 14:12 GMT) [ Python ] Rating0/0=0.00
空気を読まずにPython実装のForthを投下してみる。 未踏ユースOBの合宿で夏くらいに作ったものです。 糞コード過ぎて、読み直したら読めないwww カッコなんて不要です。えらい人にはそれがわからんのですよ。 #そのうちForthでどう書くの問題を解くか。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293
# -*- coding: utf-8 -*- import re class forth(): def __init__(self, text): self.Stack = [] self.FunctionList = {} self.VariableList = {} self.ParsedCode = [] 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()
Rating0/0=0.00-0+
[ reply ]
ところてん
#5420()
[
Python
]
Rating0/0=0.00
Rating0/0=0.00-0+
[ reply ]