Golang でプログラミング言語を作る__Part16
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機能を実装していきます。
