言語のしくみを読む

./strem ../examples/02hello.strmで実行
main.cのmain関数内のnode_parse_file(&state,argv[i])で止める
node.c内のnode_parse_file(parse_state p,const char fname)
fnameにはコマンドライン引数"../examples/02hello.strm"が入っている
fnameで指示されたファイルをリードモードで開いて読み込む。
実際にパースしているのはnode_parse_input関数。
yyrestart,yyparse関数内は複雑そうで見ていない。

結果は渡されたstate変数のlvalフィールドに格納されている。

通常はverbose変数はFALSEになっているがこれをTRUEにして
パースされたnodeを表示させてみる。

STMTS:
OP:
op: |
ARRAY:
VALUE(STRING): “Hello World
IDENT: STDOUT

もともとのスクリプト
[“Hello World”] | STDOUT

他のスクリプトも表示させてみる。

01car.strm
スクリプト
STDIN | STDOUT
パース展開
STMTS:
 OP:
  op: |
  IDENT: STDIN
  IDENT: STDOUT

03fizzbuzz.strm
スクリプト
seq(100) | {x ->
  if x % 15 == 0 {
    "FizzBuzz"
  }
  else if x % 3 == 0 {
    "Fizz"
  }
  else if x % 5 == 0 {
    "Buzz"
  }
  else {
    x
  }
} | STDOUT
パース展開
STMTS:
 OP:
  op: |
  OP:
   op: |
   CALL:
     NIL
     seq
     ARRAY:
      VALUE(NUMBER): 100
     NIL
   LAMBDA:
    ARGS(1):
     x
    IF:
     OP:
      op: ==
      OP:
       op: %
       IDENT: x
       VALUE(NUMBER): 15
      VALUE(NUMBER): 0
    THEN:
     VALUE(STRING): "FizzBuzz"
    ELSE:
     IF:
      OP:
       op: ==
       OP:
        op: %
        IDENT: x
        VALUE(NUMBER): 3
       VALUE(NUMBER): 0
     THEN:
      VALUE(STRING): "Fizz"
     ELSE:
      IF:
       OP:
        op: ==
        OP:
         op: %
         IDENT: x
         VALUE(NUMBER): 5
        VALUE(NUMBER): 0
      THEN:
       VALUE(STRING): "Buzz"
      ELSE:
       IDENT: x
  IDENT: STDOUT

04emit.strm
スクリプト
seq(100) | {x -> emit x, x} | STDOUT
パース展開
      STMTS:
      OP:
      op: |
      OP:
      op: |
      CALL:
      NIL
      seq
      ARRAY:
      VALUE(NUMBER): 100
      NIL
      LAMBDA:
      ARGS(1):
      x
      EMIT:
      ARRAY:
      IDENT: x
      IDENT: x
      IDENT: STDOUT

05skip.strm
スクリプト
seq(100) | {x -> if x % 2 == 1 {skip}; x} | STDOUT
パース展開
    STMTS:
    OP:
    op: |
    OP:
    op: |
    CALL:
    NIL
    seq
    ARRAY:
    VALUE(NUMBER): 100
    NIL
    LAMBDA:
    ARGS(1):
    x
    STMTS:
    IF:
    OP:
    op: ==
    OP:
            op: %
            IDENT: x
            VALUE(NUMBER): 2
    VALUE(NUMBER): 1
    THEN:
    IDENT: skip
    IDENT: x
    IDENT: STDOUT

06echo.strm
スクリプト
    tcp_server(8007) | {s ->
    s | s
    }
パース展開

    STMTS:
    OP:
    op: |
    CALL:
    NIL
    tcp_server
    ARRAY:
    VALUE(NUMBER): 8007
    NIL
    LAMBDA:
    ARGS(1):
    s
    OP:
    op: |
    IDENT: s
    IDENT: s

07netcat.strm
スクリプト
    s = tcp_socket("localhost", 8007)
    STDIN | s
    s | STDOUT
パース展開
    STMTS:
    LET: s
    CALL:
    NIL
    tcp_socket
    ARRAY:
    VALUE(STRING): "localhost"
    VALUE(NUMBER): 8007
    NIL
    OP:
    op: |
    IDENT: STDIN
    IDENT: s
    OP:
    op: |
    IDENT: s
    IDENT: STDOUT

08chat.strm
スクリプト
broadcast = chan()
tcp_server(8008) | {s ->
  broadcast | s   # connect to broadcast channel
  s | broadcast   # broadcast incoming message
}
パース展開
  STMTS:
  LET: broadcast
    CALL:
      NIL
      chan
      ARRAY:
      NIL
  OP:
    op: |
    CALL:
      NIL
      tcp_server
      ARRAY:
      VALUE(NUMBER): 8008
      NIL
    LAMBDA:
    ARGS(1):
      s
    STMTS:
      OP:
      op: |
      IDENT: broadcast
      IDENT: s
      OP:
      op: |
      IDENT: s
      IDENT: broadcast