言語を自作してみた(3)(コード付き)

# 自作言語のお時間です
モンエナって飲み続けると禿げるのか疑問に思っているdangomushiです。
カフェインだとどうか立証はされてないらしいけど気になるのは糖分なんだよなぁ。

# またまた作りました。

最近は言語を自作するのがマイブームです。処理系とかむずいよ、、、
今回は、正規表現とかいろいろ取り入れてます。~~その代わり機能が少ない~~

### 諸連絡です。

自分の技量を高めるためにもブログ始めました。ここ（http://dangomushi.starfree.jp）
からどうぞ。まだ記事は少ないですが、随時更新の予定ですのでぜひ見てみてください！

# 実装

```python:main.py
import sys, re, os, pickle, shelve

#TODO:トークン分割
class Token:
    def __init__(self, data):
        self.enum = {   "NAME":r"[a-zA-Z]+", 
                        "SYMBOL":r'[\-=!\+\?]+', 
                        "FUNC":r"^def", 
                        "NUM":r"[0-9]+", 
                        "MOLD":r"[int str list dict bool println]+"
                    }
        self.funcs = ["println"]
        self.data = data.replace(" ", "")

    #TODO:変数
    def tokenVal(self):
        val = re.search(self.enum["NAME"], self.data)
        if val != None:
            return val.group()
        else:
            return ""
    
    #TODO:記号
    def tokenSysnbol(self):
        synbol = re.search(self.enum["SYMBOL"], self.data)
        if synbol != None:
            return synbol.group()
        else:
            return ""
    
    #TODO:関数
    def tokenFunc(self):
        func = re.search(self.enum["FUNC"], self.data)
        if func != None:
            return func.group()
        else:
            return ""
    
    def tokenNum(self):
        num = re.search(self.enum["NUM"], self.data)
        if num != None:
            return num.group()
        else:
            return ""
    
    def tokenMold(self):
        mold = re.search(self.enum["MOLD"], self.data)
        if mold != None:
                return mold.group()
        else:
                return ""

    #TODO:main関数
    def tokenMain(self, i):
        m = self.tokenMold()
        v = self.tokenVal()
        s = self.tokenSysnbol()
        f = self.tokenFunc()
        n = self.tokenNum()
        Err().tokenErr(m, v)
        v = v.replace(m, "")
        Parse(m, v, s, f, n, self.data).run(i)

class Err:
    #TODO:m(型)=data
    @staticmethod
    def tokenErr(data, data2):
        errtok = ["def", "int", "str", "in", "and", "None", "True", "False", "bool"]
        funcs = ["println"]
        if data in errtok:
            pass
        else:
            if data in funcs:
                pass
            else:
                print("Err: tokenErr. {} is can't use.".format(data))
                sys.exit()

#TODO:構文解析
class Parse:
    def __init__(self, mold, val, sym, func, num, data):
        self.mold = mold
        self.val = val
        self.sym = sym
        self.func = func
        self.num = num
        self.data = data
    def run(self, dic):
        self.dic = dic
        if self.data.startswith("int"):
            self.dic[self.val] = self.num
            print(self.dic)

        
        elif self.data.startswith("println"):
            self.data = self.data.replace("println", "").replace(")", "(").replace("(", "")
            if self.data in self.dic:
                print(self.dic[self.data])
            else:
                print(self.data)

def main():
    dic = {}

    while True:
        Token(input(">")).tokenMain(dic)

if __name__ == '__main__':
    main()

```

とりあえずまだ対話型です。コードが長く、変なところに引数があったりしますが気にしないでください。もし気に入らなければ読者の皆様で改造しちゃってください。Ommega言語のコンセプトは「フリー言語」ですから！

## まとめ

今回は「Omega言語-正規表現対応ver」を作りました。機会があればGithubに上げて追記します。
改善点としては、
- 関数が少なすぎる
- コードが酷い
- 前回「関数定義実装したい」とか言ってたくせにしてない
- (趣味、解釈などにもよりますが)対話型

などがありますので、次回はそれらを改善して記事にしようと思います！
それでは、また次の記事でお会いしましょう！
さようなら！