Golang でプログラミング言語を作る__Part16

Tuyoshi Akiyama
Aug 22, 2017 · 3 min read

前回までは、return文の解釈(evaluation)機能をつくりました。

今回は、ソースにエラーがある場合の処理を実装してきます。

特に、今回はinteranal error handlingについて、扱っていきます


まず、今回のエラーの処理としては、エラーオブジェクトを返すようにするのが目的になります。

その為には、エラーが発生したその瞬間に、上で定義したerrorオブジェクトを返す必要があります。

では、エラーのオブジェクトを定義します。

object/object.go

type Error struct {
Message string
}
func (e *Error) Type() ObjectType { return ERROR_OBJ }
func (e *Error) Inspect() string { return "ERROR: " + e.Message }

オブジェクトの定義をし終えたら、次の入力値をもつテストケースを作ります。

{
"5 + true;",
"type mismatch: INTEGER + BOOLEAN",
},
{
"5 + true; 5;",
"type mismatch: INTEGER + BOOLEAN",
},
{
"-true",
"unknown operator: -BOOLEAN",
},
{
"true + false;",
"unknown operator: BOOLEAN + BOOLEAN",
},
{
"5; true + false; 5",
"unknown operator: BOOLEAN + BOOLEAN",
},
{
"if (10 > 1) { true + false; }",
"unknown operator: BOOLEAN + BOOLEAN",
},
{
`
if (10 > 1) {
if (10 > 1) {
return true + false;
}
return 1;
}
`,
"unknown operator: BOOLEAN + BOOLEAN",
},
{
"foobar",
"identifier not found: foobar",
},

このテストをはしらせた時に、failすることを確認します。

実際にevalator側でエラーを処理する関数は、下の newError になります。

func newError(format string, a ...interface{}) *object.Error {
return &object.Error{Message: fmt.Sprintf(format, a...)}
}

これを、今までのコードの例外処理、つまり設定されている文法以外のソースコードが入力されたときの処理に当てはめます。

各値タイプのevaluatorに対して、このエラー関数を加えます。

更に、エラーが出された時に、すぐにエラーオブジェクトを出力するように、下の isError 関数を Eval 内の各分岐ないに加えます。

func isError(obj object.Object) bool {
if obj != nil {
return obj.Type() == object.ERROR_OBJ
}
return false
}

引数がエラータイプのオブジェクトである場合は、trueを返します。

最後にテストをした時に、全てpassすれば完了です。

次は、let statementのevaluator機能を実装していきます。

)
Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade