2007年6月14日木曜日

KEMURIのインタプリタ

プログラミング言語KEMURIのインタープリタ。
言語をつくる基本はこんな単純なものなのでしょうね…。

エラー報告を詳しくした関係で100行オーバー。
西尾泰和さんによるPythonによる実装はこちら

どうやら正常に動作していないようです。ただいま原因解明中。// HSPで記述されたKEMURIのインタープリタ
#runtime "hsp3cl"

// エラーコードの定義
#enum ERROR_NO_ERROR = 0
#enum ERROR_UNKNOWN_COMMAND
#enum ERROR_STACK_EMPTY

    goto *start

// スタック用命令をグローバル空間にて定義
#deffunc push int arg1
    if count >= 0 {
        stack(count) = arg1
        count++
    }
    return

#defcfunc pop
    count--
    if count < 0 {
        error = ERROR_STACK_EMPTY
        return 0
    }
    return stack(count)

// 処理の開始
*start
    mes "KEMURI インタープリタ v1.0"
    mes "=========================="
    mes "コマンドを入力してください"
    dim stack, 16
    gosub *get
    gosub *exe
    gosub *show
    end

// コマンドを取得する
*get
    command = ""
    input command, 01
    getstr command, command // 改行コードを取り除く
    return

// コマンドを解析し、実行
*exe
    error = 0
    repeat strlen(command)
        switch peek(command, cnt)
        case '^'
            push pop()^pop()
            swbreak
        case '~'
            push $ff - pop()
            swbreak
        case '"'
            tmp = pop()
            push tmp : push tmp
            swbreak
        case 39 ; 'の文字コード
            z = pop() : y = pop() : x = pop()
            push y : push x : push z
            swbreak
        case '`'
            push 'H' : push 'e' : push 'l' : push 'l' : push 'o' : push ',' : push ' '
            push 'W' : push 'o' : push 'r' : push 'l' : push 'd' : push '!'
            swbreak
        case '|'
            sdim message, count + 1
            repeat count
                poke message, count-1pop()
            loop
            mes message
            swbreak
        default
            error = ERROR_UNKNOWN_COMMAND
            swbreak
        swend
        if error {
            errorPos = cnt
            break
        }
    loop
    return

// 結果やエラーの表示
*show
    switch error
    case ERROR_NO_ERROR
        mes "処理が正常に終了しました"
        swbreak
    case ERROR_UNKNOWN_COMMAND
        mes "エラー:規定されていないコードが見つかりました"
        mes "利用できるのは\" ' ` ~ ^ |の6つのみです"
        swbreak
    case ERROR_STACK_EMPTY
        mes "エラー:空のスタックから取り出そうとしました"
        swbreak
    default
        mes "エラー:未知のエラーが発生しました"
        swbreak
    swend
    if error != ERROR_NO_ERROR {
        mes "エラー発生箇所:" + errorPos + "文字目の" + strmid(command, errorPos, 1)
    }
    return

0 件のコメント: