kmizu:質問者様がおそらく本当の意味で意図されているのは、インタプリタではなくおそらく構文解析の話かと思いますので、その観点からお答えしますね。それと、文末のセミコロンを省略できるような言語の話をされていると思うので、その前提でお答えします(JavaやCではセミコロンで文が終わるので、行頭に演算子を置くことは何ら問題がないので)。この話は構文解析に馴染みがないと多少理解しづらいかもしれませんが、ご承知いただければと思います。
まず、質問者様のおっしゃる通り、たとえば
var x = 1 +
2 // var x = 1 + 2
という変数宣言を許すが
var x = 1
+ 2
は許さない(あるいは二つの文に分割される)方が機械にとって優しいのは間違いありません。
行頭に演算子が置いてあった方が読みやすい、というのは以下のような例でしょうか。
condVariable =
condA
|| condB
|| condC
RubyやPythonのような言語ではこのようなコードをそのまま書くことができず、括弧で式全体をくくる必要があります。
一方、Scala言語では上記のような式をそのまま解釈できます。Scalaでは、
condVariable =
condA
を見た瞬間に変数宣言が終わったと決め打ちするのではなく、
改行の次の
||
まで読んでから「行が継続している」か「変数宣言が終わったか」を決定します。
文が終わったように見えても一つ先のトークン先を読んで「行が継続している」とみなせる場合はよきにはからってくれるわけです。上の例だと、次の行を先に読んで`||`があるから、まだ変数宣言は終わっていないと判断できるわけですね。
詳細なルールは若干ややこしいのですが、Scala Language Specification 2.13
chrome-extension://efaidnbmnnnibpcajpcglclefindmkaj/https://scala-lang.org/files/archive/spec/2.13/spec.pdf
の1.2 Newline Characters に書かれています。
JavaScript(ECMAScript)でも同じようなコードは書けますが、これは自動セミコロン挿入(Automatic Semicolon
Insertion)という仕様によって実現されているもので、Scalaの方法とは多少違います。こちらも少々ややこしいのですが、一言でいうと、本来不正なトークンが来たときにセミコロンを挿入するための仕組みと言えばいいでしょうか。ECMAScript
2023 Language Specification 12. 10 Automatic Semicolon
Insertionに仕組みの記述があります:https://tc39.es/ecma262/#sec-automatic-semicolon-insertion
質問者様の
> 行の値のようなものを持っておき、行頭に左オペランドが欠けた二項演算子や後置単項演算子があった場合、前行の値をロードする
というアプローチは、おそらく次の行の`||`を見た時点で、前の行に巻き戻して解析を続けるというアプローチかと思います。質問者様のおっしゃるようなアプローチは可能かどうかで言えば可能ですし、近年Python処理系にも採用されたParsing
Expression
Grammar(解析表現文法)ではそのようなやり方も比較的容易ですが、現実には「一つ先のトークン(演算子)を読んで判断する」とかJavaScriptのような「セミコロンを補完する」みたいなアプローチの方がやりやすいかと思います。
まとめると「そうしなくて済む工夫」は現実にあるしいくつかの言語では実装されている、ということになります。しかし一方で、調べた限りでは、Scalaと類似の文法を持つKotlinでは無理なようですし、SwiftやGoなどの言語でも無理なようです。全体としては、改行で文が終端できて、このような工夫もしている言語は少数派であると言えるかもしれません。