Open17

自作言語メモ【javascript】

freefree

https://3iz.jp/
このサイトを見ながら自作言語を作ったりしています(インタプリタ)
今作っている自作言語の問題は、0を表示させようとしても何も表示されないことです

freefree

もう一回0を表示させようとしたら、何もしていないのに、0と表示されましたw

freefree

while文完成(ifやforはまだ)

コード例

i: int = 0
while (i <= 5) {
    println(i)
    i += 1
}
freefree

ifとelifとelse完成したからもしかしたらfizzbuzz作れるかも?

freefree

fizzbuzz出来なかった...
コード

i: int = 1
while (i <= 100) {
    if (i % 3 == 0 && i % 5 == 0) {
        println("fizzbuzz")

    } elif (i % 3 == 0) {
        println("fizz")

    } elif (i % 5 == 0) {
        println("buzz")

    } else {
        println(i)
    }
    i += 1
}

エラー

ParserError: there is no ) in the tokens
tokens = ["&&", "i", "%", "5", "==", "0", ")", "{", "println", "(", ""fizzbuzz"", ")", "}", "elif", "(", 
"i", "%", "3", "==", "0", ")", "{", "println", "(", ""fizz"", ")", "}", "elif", "(", "i", "%", "5", "==", "0",
")", "{", "println", "(", ""buzz"", ")", "}", "else", "{", "println", "(", "i", ")", "}", "i", "+=", "1", "}", 
"+", "+", "i", ":", "int", "=", "1", "if", "(", "i", "%", "3", "==", "0", "&&", "i", "%", "5", "==", "0", 
")", "{", "println", "(", ""fizzbuzz"", ")", "}", "elif", "(", "i", "%", "3", "==", "0", ")", "{", "println", "
(", ""fizz"", ")", "}", "elif", "(", "i", "%", "5", "==", "0", ")", "{", "println", "(", ""buzz"", ")", "}", 
"else", "{", "println", "(", "i", ")", "}"]
freefree

parserのlogic関数を呼び出していないからこのエラーが出たのは分かったけど、もう一回やってみたら、TypeError: "NaN" does not fit the typeってエラー出た

freefree
//make the brackets ast
const brackets = (tokens) => {
    let ast = {};

    let op;
    if (op = accept(tokens, "(")) {
        let right = comma(tokens);

        op += expect(tokens, ")");

        return right;
    }

    ast = logic(tokens);

    return ast;
}

これを

//make the brackets ast
const brackets = (tokens) => {
    let ast = {};

    let left = logic(tokens);

    let op;
    if (op = accept(tokens, "(")) {
        let right = comma(tokens);

        op += expect(tokens, ")");

        return right;
    }

    ast = left;

    return ast;
}

にするとエラーが出る謎

freefree

さっきのコメントの謎か解決しました。
なぜかと言うと、先にlogic関数を使うとtokensが減ってしまって括弧などが見つからないからっぽいです。

freefree

fizzbuzzのastが

{
  left: { left: 'i', type: 'int', op: ':=', right: '1' },
  op: ';',
  right: {
    left: {
      left: 'while',
      op: '()',
      right: { left: 'i', op: '<=', right: '100' }
    },
    op: '{}',
    right: {
      left: {
        left: {
          left: {
            left: 'if',
            op: '()',
            right: {
              left: 'i',
              op: '%',
              right: {
                left: '3',
                op: '==',
                right: {
                  left: '0',
                  op: '&&',
                  right: {
                    left: 'i',
                    op: '%',
                    right: { left: '5', op: '==', right: '0' }
                  }
                }
              }
            }
          },
          op: '{}',
          right: { left: 'println', op: '()', right: '"fizzbuzz"' }
        },
        op: 'space',
        right: {
          left: {
            left: {
              left: 'elif',
              op: '()',
              right: {
                left: 'i',
                op: '%',
                right: { left: '3', op: '==', right: '0' }
              }
            },
            op: '{}',
            right: { left: 'println', op: '()', right: '"fizz"' }
          },
          op: 'space',
          right: {
            left: {
              left: {
                left: 'elif',
                op: '()',
                right: {
                  left: 'i',
                  op: '%',
                  right: { left: '5', op: '==', right: '0' }
                }
              },
              op: '{}',
              right: { left: 'println', op: '()', right: '"buzz"' }
            },
            op: 'space',
            right: {
              left: 'else',
              op: '{}',
              right: { left: 'println', op: '()', right: 'i' }
            }
          }
        }
      },
      op: ';',
      right: { left: 'i', op: '+=', right: '1' }
    }
  }
}

になってしまう

freefree

%を優先すべきか==を優先すべきか

freefree

%を優先しても==を優先しても変わらないかった

freefree
{
    left: 'i',
    op: '%',
    right: { left: '3', op: '==', right: '0' }
}

このastを

{
    left: { left: 'i', op: "%", right: '3' },
    op: "==",
    right: '0',
}

これにしたい

freefree

とりあえずコードを、

i: int = 1

while (i <= 100) {
    if (i % 15 == 0) {
        println("fizzbuzz")

    } elif (i % 3 == 0) {
        println("fizz")

    } elif (i % 5 == 0) {
        println("buzz")

    } else {
        println(i)
    }

    i += 1
}

にして、構文解析をしやすくしました。

freefree

その後ちょっと色々してみたら、fizzbuzz出来ました!
コード

main.flow
i: int = 1

while (i <= 100) {
    if ((i % 15) == 0) {
        println("fizzbuzz")

    } elif ((i % 3) == 0) {
        println("fizz")

    } elif ((i % 5) == 0) {
        println("buzz")

    } else {
        println(i)
    }
    
    i += 1
}