[ create a new paste ] login | about

Link: http://codepad.org/EqMhkKte    [ raw code | output | fork ]

Python, pasted on May 1:
# -*- 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()


Output:
-19
1
TRUE
is
here
100
97
0
1
2
3
4
5
6
7
8
9
100
[1, 10]
[1, 10, 10, 9]
[1, 10, 10, 9, 90, 8]
[1, 10, 10, 9, 90, 8, 720, 7]
[1, 10, 10, 9, 90, 8, 720, 7, 5040, 6]
[1, 10, 10, 9, 90, 8, 720, 7, 5040, 6, 30240, 5]
[1, 10, 10, 9, 90, 8, 720, 7, 5040, 6, 30240, 5, 151200, 4]
[1, 10, 10, 9, 90, 8, 720, 7, 5040, 6, 30240, 5, 151200, 4, 604800, 3]
[1, 10, 10, 9, 90, 8, 720, 7, 5040, 6, 30240, 5, 151200, 4, 604800, 3, 1814400, 2]
[1, 10, 10, 9, 90, 8, 720, 7, 5040, 6, 30240, 5, 151200, 4, 604800, 3, 1814400, 2, 3628800, 1]
[1, 10, 10, 9, 90, 8, 720, 7, 5040, 6, 30240, 5, 151200, 4, 604800, 3, 1814400, 2, 3628800, 1, 3628800, 0]
[1, 10, 10, 9, 90, 8, 720, 7, 5040, 6, 30240, 5, 151200, 4, 604800, 3, 1814400, 2, 3628800]
[1, 10, 10, 9, 90, 8, 720, 7, 5040, 6, 30240, 5, 151200, 4, 604800, 3, 3628800]
[1, 10, 10, 9, 90, 8, 720, 7, 5040, 6, 30240, 5, 151200, 4, 3628800]
[1, 10, 10, 9, 90, 8, 720, 7, 5040, 6, 30240, 5, 3628800]
[1, 10, 10, 9, 90, 8, 720, 7, 5040, 6, 3628800]
[1, 10, 10, 9, 90, 8, 720, 7, 3628800]
[1, 10, 10, 9, 90, 8, 3628800]
[1, 10, 10, 9, 3628800]
[1, 10, 3628800]
[3628800]
3628800


Create a new paste based on this one


Comments: