|
|
|
|
@ -619,3 +619,80 @@ func TestInterpretWhileStatement(t *testing.T) {
|
|
|
|
|
t.Errorf("run() = %v; want %v", out, expected)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestInterpretFunctionStatement(t *testing.T) {
|
|
|
|
|
i := New(errors.NewMockErrorLogger())
|
|
|
|
|
functionStmt := &ast.FunctionStmt{
|
|
|
|
|
Name: token.Token{Type: token.IDENTIFIER, Lexeme: "foo"},
|
|
|
|
|
Params: []token.Token{},
|
|
|
|
|
Body: []ast.Stmt{&ast.BlockStmt{Statements: []ast.Stmt{}}},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
i.VisitFunctionStmt(functionStmt)
|
|
|
|
|
result := i.env.get("foo")
|
|
|
|
|
if result == nil {
|
|
|
|
|
t.Errorf("expected function, got nil")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestInterpretFunctionCall(t *testing.T) {
|
|
|
|
|
i := New(errors.NewMockErrorLogger())
|
|
|
|
|
functionStmt := &ast.FunctionStmt{
|
|
|
|
|
Name: token.Token{Type: token.IDENTIFIER, Lexeme: "foo"},
|
|
|
|
|
Params: []token.Token{},
|
|
|
|
|
Body: []ast.Stmt{&ast.BlockStmt{Statements: []ast.Stmt{&ast.PrintStmt{Expression: &ast.LiteralExpr{Value: 42.0}}}}},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
i.VisitFunctionStmt(functionStmt)
|
|
|
|
|
|
|
|
|
|
callExpr := &ast.CallExpr{
|
|
|
|
|
Callee: &ast.VariableExpr{Name: token.Token{Type: token.IDENTIFIER, Lexeme: "foo"}},
|
|
|
|
|
Arguments: []ast.Expr{},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
i.VisitCallExpr(callExpr)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestInterpretFunctionCallWithArguments(t *testing.T) {
|
|
|
|
|
i := New(errors.NewMockErrorLogger())
|
|
|
|
|
functionStmt := &ast.FunctionStmt{
|
|
|
|
|
Name: token.Token{Type: token.IDENTIFIER, Lexeme: "foo"},
|
|
|
|
|
Params: []token.Token{{Type: token.IDENTIFIER, Lexeme: "a"}},
|
|
|
|
|
Body: []ast.Stmt{&ast.BlockStmt{Statements: []ast.Stmt{&ast.PrintStmt{Expression: &ast.VariableExpr{Name: token.Token{Type: token.IDENTIFIER, Lexeme: "a"}}}}}},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
i.VisitFunctionStmt(functionStmt)
|
|
|
|
|
|
|
|
|
|
callExpr := &ast.CallExpr{
|
|
|
|
|
Callee: &ast.VariableExpr{Name: token.Token{Type: token.IDENTIFIER, Lexeme: "foo"}},
|
|
|
|
|
Arguments: []ast.Expr{
|
|
|
|
|
&ast.LiteralExpr{Value: 42.0},
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
i.VisitCallExpr(callExpr)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestInterpretFunctionCallWithWrongNumberOfArguments(t *testing.T) {
|
|
|
|
|
i := New(errors.NewMockErrorLogger())
|
|
|
|
|
functionStmt := &ast.FunctionStmt{
|
|
|
|
|
Name: token.Token{Type: token.IDENTIFIER, Lexeme: "foo"},
|
|
|
|
|
Params: []token.Token{{Type: token.IDENTIFIER, Lexeme: "a"}},
|
|
|
|
|
Body: []ast.Stmt{&ast.BlockStmt{Statements: []ast.Stmt{}}},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
i.VisitFunctionStmt(functionStmt)
|
|
|
|
|
|
|
|
|
|
callExpr := &ast.CallExpr{
|
|
|
|
|
Callee: &ast.VariableExpr{Name: token.Token{Type: token.IDENTIFIER, Lexeme: "foo"}},
|
|
|
|
|
Arguments: []ast.Expr{},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
defer func() {
|
|
|
|
|
if r := recover(); r != "Expected 1 arguments but got 0 [line 0]" {
|
|
|
|
|
t.Errorf("expected panic with 'expected 1 arguments but got 0', got %v", r)
|
|
|
|
|
}
|
|
|
|
|
}()
|
|
|
|
|
|
|
|
|
|
i.VisitCallExpr(callExpr)
|
|
|
|
|
}
|
|
|
|
|
|