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

Tuyoshi Akiyama
Aug 22, 2017 · 4 min read

前回の続きから入ります。今回はif文タイプのevaluatorを作っていきます。

if文は、conditionに合致した時(TRUEである)のみ、そのblock”{}”内の式が実行されます。なので、まずは条件分を先に解釈してTRUE/FALSEを判断していく必要があります。

ここでは、trueは、falseとnullではない全ての値としています。

では、今回もTDDで実装してきます。


evaluator/evaluator_test.go

func TestIfElseExpression(t *testing.T) {
tests := []struct {
input string
expected interface{}
}{
{"if (true) { 10 }", 10},
{"if (false) { 10 }", nil},
{"if (1) { 10 }", 10},
{"if (1 < 2) { 10 }", 10},
{"if (1 > 2) { 10 }", nil},
{"if (1 > 2) { 10 } else { 20 }", 20},
{"if (1 < 2) { 10 } else { 20 }", 10},
}
for _, tt := range tests {
evaluated := testEval(tt.input)
integer, ok := tt.expected.(int)
if ok {
testIntegerObject(t, evaluated, int64(integer))
} else {
testNullObject(t, evaluated)
}
}
}

また、 testNullObject は次のような処理になります。

if文の処理が何も返さない、つまり引数のオブジェクトがnilの時に、下の処理に移ります。

func testNullObject(t *testing.T, obj object.Object) bool {
if obj != NULL {
t.Errorf("object is not NULL, got=%T(%+v)", obj, obj)
return false
}
return true
}

このテストがfailすることを確認したら、evaluatorを実装します。

func Eval(node ast.Node, env *object.Environment) object.Object {
switch node := node.(type) {
// [...]
case *ast.BlockStatement:
return evalBlockStatement(node, env)

// [...]
case *ast.IfExpression:
return evalIfExpression(node, env)
// [...]
}

また、evaluatorに渡されるASTノードがIf文タイプの値であった時に、次の evalIfExpression() 関数に渡されます。

func evalIfExpression(ie *ast.IfExpression, env *object.Environment) object.Object {
condition := Eval(ie.Condition, env)
if isError(condition) {
return condition
}
if isTruthy(condition) {
return Eval(ie.Consequence, env)
} else if ie.Alternative != nil {
return Eval(ie.Alternative, env)
} else {
return NULL
}
}

isTruthy 関数は、条件式がfalseやnullならfalseを、それ以外の値全てをtrueを返すものになります。

ここで、条件に基づく実行(evaluation)する文の分岐が、行われています。

最後にテストを走らせて、passすることを確認します。

次は、return文の解釈に取り組んでいきます。

)
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