ゼロからはじめるスクリプト言語製作: 妥協する勇気(5日目)
前回、ユーザー入力を構造化した結果、コンソール表示がよく分からなくなってしまった。なので今日は、内部表現を文字列化するための対応を進めていこう。
ちなみに現状のコンソール表示は、↓こんな感じだ。
REPL の P は Print の P
System.Console.WriteLine() でコンソール表示するときは、渡すオブジェクトに ToString() メソッドが実装されている必要がある。
public override string ToString() を nil と atomv と cell それぞれに追加した結果、Type.cs は↓以下のようなコードになった。
※ 行頭「+」が変更後
@@ -8,11 +8,13 @@ namespace ToyLisp
public class nil : expr
{
+ public override string ToString() => "nil";
}
public class atomv : expr
{
public atomv(string val) => _val = val;
+ public override string ToString() => _val.ToString();
private string _val;
}
@@ -30,6 +32,13 @@ namespace ToyLisp
_cdr = (expressions.Skip(1).Count() > 0) ? new cell(expressions.Skip(1)) : new nil();
}
+ public override string ToString()
+ {
+ string str = (_car is cell) ? $"({_car.ToString()})" : $"{_car.ToString()}";
+ str += (_cdr is nil) ? "" : $" {_cdr.ToString()}";
+ return str;
+ }
+
public cell append(expr expression)
{
cell cur = this;
nil.ToString() と atomv.ToString() は各1行追加、cell.ToString() は7行追加。
え、これだけで良いのか…と感じたけど、本当にこれだけで良いみたいだ。
ビルドして実行してみると、コンソール表示は↓以下のように見やすくなっている。
一番外側の丸カッコが無くなってしまったけど、どうしよう。あまり実害ないので、一旦妥協して、このままで放置しておこう。
まあ順調だ。
今日はここまで、おつかれさま。
小さな発見
文字列に動的なものを埋め込みたいとき、C# では挿入文字列というものが使える。文字列リテラルを示すダブルクォーテーション「"」の手前に記号 $ を加えてから、リテラルに波カッコと変数や式を加える。
string str = (_car is cell) ? $"({_car.ToString()})" : $"{_car.ToString()}";
こういうフォーマッティングが使えると、変数を文字列リテラルでサンドイッチして連結する方法に比べて、ダブルクォーテーションをたくさん並べずに済むので、幾分、コーティングもラクだし、ソースコードが眺めやすくなる。
今回は使ってないけど、$”{~<変数や式>~,10}” とすると右揃え10桁指定になるようだ。ロケール対応をサポートすることもできるようだ。
この記事が気に入ったらサポートをしてみませんか?