F# PPAPインタープリタ

あんどーなつ
記事: 171
登録日時: 8年前
連絡を取る:

F# PPAPインタープリタ

投稿記事 by あんどーなつ » 8年前

ピコ太郎のPPAPをもとにインタープリタを作ってみました。
ネタとしては既出かもしれないですが、やはり作りたかったので。

CODE:

// ppap.fs --- PPAP言語インタープリタ

let firstLetterToUpper (str : string) : string =
    let a = str.ToCharArray()
    if a.Length  0 then a.[0]  -1

[]
let main (argv: string[]) =
    printfn "PPAP language interpreter"
    printfn ""
    printfn "#help と入力するとヘルプを表示します。"
    
    let mutable isEnd = false
    let s = new System.Collections.Generic.Stack()
    let err() = printfn "不正な文法です。"
    while not isEnd do
        printf "> "
        let inst = stdin.ReadLine().Split() |> List.ofArray
        match inst with
        | ["#help"] ->
            printfn "I have a . : スタックにを挿入します。"
            printfn "Ahh!!              : スタックに挿入した2つの識別子を"
            printfn "                     ハイフンで逆順で連結して表示します。"
            printfn "[Enter]            : スタックに識別子が2つ格納されている"
            printfn "                     場合は、2つの識別子を表示し、"
            printfn "                     それらからなる造語をスタックに"
            printfn "                     格納します。"
            printfn "                     スタックに識別子が1つ格納されている"
            printfn "                     場合は、それを表示します。"
            printfn "#quit              : インタープリタを終了します。"
            printfn "#help              : このヘルプを表示します。"
        | ["#quit"] | ["#q"] -> isEnd 
            let ident = if identPlusDot.Length >= 2 then
                            identPlusDot.[0..identPlusDot.Length - 2]
                        else ""
            if identPlusDot.Length  '.' then err()
            elif a  "a" && a  "an" then err()
            elif a = "a" && isVowel ident.[0] then err()
            elif a = "an" && not (isVowel ident.[0]) then err()
            else s.Push(ident) |> ignore
        | ["Ahh!!"] -> let s1 = if (s.Count)  0 then (s.Pop()) else ""
                       let s2 = if (s.Count)  0 then (s.Pop()) else ""
                       s.Push ( (firstLetterToUpper s1)
                                + "-" + (firstLetterToUpper s2) )
                       printfn "%s %s !" (firstLetterToUpper s1) s2
        | [""] -> if s.Count = 2 then
                      let s1, s2 = s.Pop(), s.Pop()
                      let swapped = s1.Split([|'-'|])
                                    |> fun x -> x.[1] + "-" + x.[0]
                      s.Push (swapped + "-" + s2)
                      printfn "%s ! %s !"
                              s2
                              s1
                  elif s.Count = 1 then
                      printfn "%s" (s.Pop())
                  else
                      printfn "不正な呼び出しです。"
        | _ -> err()
    0
実行結果

CODE:

PPAP language interpreter

#help と入力するとヘルプを表示します。
> #help
I have a . : スタックにを挿入します。
Ahh!!              : スタックに挿入した2つの識別子を
                     ハイフンで逆順で連結して表示します。
[Enter]            : スタックに識別子が2つ格納されている
                     場合は、2つの識別子を表示し、
                     それらからなる造語をスタックに
                     格納します。
                     スタックに識別子が1つ格納されている
                     場合は、それを表示します。
#quit              : インタープリタを終了します。
#help              : このヘルプを表示します。
> I have a pen.
> I have an apple.
> Ahh!!
Apple pen !
> I have a pen.
> I have a pineapple.
> Ahh!!
Pineapple pen !
>
Apple-Pen ! Pineapple-Pen !
>
Pen-Pineapple-Apple-Pen
> #quit

コメントはまだありません。