yhara.jp

Recent Posts

言語実装tips:複数の式をまとめる

2024-12-17
Tech

このエントリは言語実装 - Qiita Advent Calendar 2024 - Qiitaの17日目の記事です。

今日は処理系実装上のTipsを一つ紹介します。

例:if式

たとえばC言語みたいに、

  if (a) {
    b
    c
  } else {
    d
  }

のようなif式をもつ言語を作りたいとします。文と式が分かれている言語にする場合、Rustで実装するとこんな感じになるでしょうか。

struct Stmt {
  ...
  ExprStmt(Box<Expr>)  //いわゆる式文。
}
struct Expr {
  IntLiteral(usize),
  ...
  If {
    cond_expr: Box<Expr>,
    then_clause: Vec<Stmt>,
    else_clause: Vec<Stmt>,
  }
}

一方、すべてが式の言語にする場合はどうでしょうか。なんとなく

struct Expr {
  IntLiteral(usize),
  ...
  If {
    cond_expr: Box<Expr>,
    then_clause: Vec<Expr>,
    else_clause: Vec<Expr>,
  }
}

みたいにthenとelseが複数のExprを持つ感じにしたくなりますが、ここに複文(ならぬ、複式?)を導入して

struct Expr {
  IntLiteral(usize),
  ...
  Stmts(Vec<Expr>) //連続した式を順に評価する。最後に評価した値をStmts全体の値とする。
  If {
    cond_expr: Box<Expr>,
    then_clause: Box<Expr>,  //単一の式、またはStmtsが入る
    else_clause: Box<Expr>,  //単一の式、またはStmtsが入る
  }
}

のようにするとわりと取り回しが良いです(良かったです)。

注意点

上記の場合、空のStmtsの扱いに注意する必要があります。簡単なのは何からの「ゼロ値」を導入し(C言語のnull、LispやRubyのnil、的な)、空のStmtsを作ろうとしたときは自動的にそれを挿入することです。

この場合意味論としては、例えば

  if (x) {
    print(x)
  } else {
  }

というif式は

  if (x) {
    print(x)
  } else {
    nil
  }

と等価になります。

More posts

Posts

(more...)

Articles

(more...)

Category

Ads

About

About the author
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy