You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
277 lines
6.0 KiB
Go
277 lines
6.0 KiB
Go
package resolver
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"golox/ast"
|
|
"golox/errors"
|
|
"golox/interpreter"
|
|
"golox/token"
|
|
)
|
|
|
|
func TestResolver_VisitBlockStmt(t *testing.T) {
|
|
logger := errors.NewMockErrorLogger()
|
|
interp := &interpreter.Interpreter{}
|
|
resolver := New(interp, logger)
|
|
|
|
blockStmt := &ast.BlockStmt{
|
|
Statements: []ast.Stmt{},
|
|
}
|
|
|
|
resolver.VisitBlockStmt(blockStmt)
|
|
|
|
if len(resolver.scopes) != 0 {
|
|
t.Errorf("expected scopes to be empty, got %v", resolver.scopes)
|
|
}
|
|
}
|
|
|
|
func TestResolver_VisitVarStmt(t *testing.T) {
|
|
logger := errors.NewMockErrorLogger()
|
|
interp := &interpreter.Interpreter{}
|
|
resolver := New(interp, logger)
|
|
|
|
varStmt := &ast.VarStmt{
|
|
Name: token.Token{Lexeme: "a"},
|
|
Initializer: nil,
|
|
}
|
|
|
|
resolver.VisitVarStmt(varStmt)
|
|
|
|
if len(logger.Errors) != 0 {
|
|
t.Errorf("expected no errors, got %v", logger.Errors)
|
|
}
|
|
}
|
|
|
|
func TestResolver_VisitVariableExpr(t *testing.T) {
|
|
logger := errors.NewMockErrorLogger()
|
|
interp := &interpreter.Interpreter{}
|
|
resolver := New(interp, logger)
|
|
|
|
varExpr := &ast.VariableExpr{
|
|
Name: token.Token{Lexeme: "a"},
|
|
}
|
|
|
|
resolver.VisitVariableExpr(varExpr)
|
|
|
|
if len(logger.Errors) != 0 {
|
|
t.Errorf("expected no errors, got %v", logger.Errors)
|
|
}
|
|
}
|
|
|
|
func TestResolver_VisitAssignExpr(t *testing.T) {
|
|
logger := errors.NewMockErrorLogger()
|
|
interp := &interpreter.Interpreter{}
|
|
resolver := New(interp, logger)
|
|
|
|
assignExpr := &ast.AssignExpr{
|
|
Name: token.Token{Lexeme: "a"},
|
|
Value: &ast.LiteralExpr{Value: 42},
|
|
}
|
|
|
|
resolver.VisitAssignExpr(assignExpr)
|
|
|
|
if len(logger.Errors) != 0 {
|
|
t.Errorf("expected no errors, got %v", logger.Errors)
|
|
}
|
|
}
|
|
|
|
func TestResolver_VisitFunctionStmt(t *testing.T) {
|
|
logger := errors.NewMockErrorLogger()
|
|
interp := &interpreter.Interpreter{}
|
|
resolver := New(interp, logger)
|
|
|
|
funcStmt := &ast.FunctionStmt{
|
|
Name: token.Token{Lexeme: "foo"},
|
|
Params: []token.Token{},
|
|
Body: []ast.Stmt{},
|
|
}
|
|
|
|
resolver.VisitFunctionStmt(funcStmt)
|
|
|
|
if len(logger.Errors) != 0 {
|
|
t.Errorf("expected no errors, got %v", logger.Errors)
|
|
}
|
|
}
|
|
|
|
func TestResolver_VisitReturnStmt(t *testing.T) {
|
|
logger := errors.NewMockErrorLogger()
|
|
interp := &interpreter.Interpreter{}
|
|
resolver := New(interp, logger)
|
|
|
|
returnStmt := &ast.ReturnStmt{
|
|
Keyword: token.Token{Lexeme: "return"},
|
|
Value: &ast.LiteralExpr{Value: 42},
|
|
}
|
|
|
|
resolver.currFunc = FunctionFuncType
|
|
resolver.VisitReturnStmt(returnStmt)
|
|
|
|
if len(logger.Errors) != 0 {
|
|
t.Errorf("expected no errors, got %v", logger.Errors)
|
|
}
|
|
}
|
|
|
|
func TestResolver_VisitIfStmt(t *testing.T) {
|
|
logger := errors.NewMockErrorLogger()
|
|
interp := &interpreter.Interpreter{}
|
|
resolver := New(interp, logger)
|
|
|
|
ifStmt := &ast.IfStmt{
|
|
Condition: &ast.LiteralExpr{Value: true},
|
|
ThenBranch: &ast.BlockStmt{
|
|
Statements: []ast.Stmt{},
|
|
},
|
|
ElseBranch: nil,
|
|
}
|
|
|
|
resolver.VisitIfStmt(ifStmt)
|
|
|
|
if len(logger.Errors) != 0 {
|
|
t.Errorf("expected no errors, got %v", logger.Errors)
|
|
}
|
|
}
|
|
|
|
func TestResolver_VisitWhileStmt(t *testing.T) {
|
|
logger := errors.NewMockErrorLogger()
|
|
interp := &interpreter.Interpreter{}
|
|
resolver := New(interp, logger)
|
|
|
|
whileStmt := &ast.WhileStmt{
|
|
Condition: &ast.LiteralExpr{Value: true},
|
|
Body: &ast.BlockStmt{
|
|
Statements: []ast.Stmt{},
|
|
},
|
|
}
|
|
|
|
resolver.VisitWhileStmt(whileStmt)
|
|
|
|
if len(logger.Errors) != 0 {
|
|
t.Errorf("expected no errors, got %v", logger.Errors)
|
|
}
|
|
}
|
|
|
|
func TestResolver_VisitExpressionStmt(t *testing.T) {
|
|
logger := errors.NewMockErrorLogger()
|
|
interp := &interpreter.Interpreter{}
|
|
resolver := New(interp, logger)
|
|
|
|
exprStmt := &ast.ExpressionStmt{
|
|
Expression: &ast.LiteralExpr{Value: 42},
|
|
}
|
|
|
|
resolver.VisitExpressionStmt(exprStmt)
|
|
|
|
if len(logger.Errors) != 0 {
|
|
t.Errorf("expected no errors, got %v", logger.Errors)
|
|
}
|
|
}
|
|
|
|
func TestResolver_Resolve(t *testing.T) {
|
|
logger := errors.NewMockErrorLogger()
|
|
interp := &interpreter.Interpreter{}
|
|
resolver := New(interp, logger)
|
|
|
|
stmts := []ast.Stmt{
|
|
&ast.BlockStmt{
|
|
Statements: []ast.Stmt{
|
|
&ast.VarStmt{
|
|
Name: token.Token{Lexeme: "a"},
|
|
Initializer: nil,
|
|
},
|
|
&ast.VarStmt{
|
|
Name: token.Token{Lexeme: "a"},
|
|
Initializer: nil,
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
resolver.Resolve(stmts)
|
|
|
|
if len(logger.Errors) != 1 {
|
|
t.Errorf("expected 1 error, got %v", logger.Errors)
|
|
}
|
|
}
|
|
|
|
func TestResolver_ResolveStmt(t *testing.T) {
|
|
logger := errors.NewMockErrorLogger()
|
|
interp := &interpreter.Interpreter{}
|
|
resolver := New(interp, logger)
|
|
|
|
stmt := &ast.VarStmt{
|
|
Name: token.Token{Lexeme: "a"},
|
|
Initializer: nil,
|
|
}
|
|
|
|
resolver.resolveStmt(stmt)
|
|
|
|
if len(logger.Errors) != 0 {
|
|
t.Errorf("expected no errors, got %v", logger.Errors)
|
|
}
|
|
}
|
|
|
|
func TestResolver_ResolveExpr(t *testing.T) {
|
|
logger := errors.NewMockErrorLogger()
|
|
interp := &interpreter.Interpreter{}
|
|
resolver := New(interp, logger)
|
|
|
|
expr := &ast.LiteralExpr{Value: 42}
|
|
|
|
resolver.resolveExpr(expr)
|
|
|
|
if len(logger.Errors) != 0 {
|
|
t.Errorf("expected no errors, got %v", logger.Errors)
|
|
}
|
|
}
|
|
|
|
func TestResolver_Declare(t *testing.T) {
|
|
logger := errors.NewMockErrorLogger()
|
|
interp := &interpreter.Interpreter{}
|
|
resolver := New(interp, logger)
|
|
|
|
resolver.beginScope()
|
|
resolver.declare(&token.Token{Lexeme: "a"})
|
|
|
|
if len(resolver.scopes) != 1 {
|
|
t.Errorf("expected 1 scope, got %v", resolver.scopes)
|
|
}
|
|
}
|
|
|
|
func TestResolver_Define(t *testing.T) {
|
|
logger := errors.NewMockErrorLogger()
|
|
interp := &interpreter.Interpreter{}
|
|
resolver := New(interp, logger)
|
|
|
|
resolver.beginScope()
|
|
resolver.define(&token.Token{Lexeme: "a"})
|
|
|
|
if len(resolver.scopes) != 1 {
|
|
t.Errorf("expected 1 scope, got %v", resolver.scopes)
|
|
}
|
|
}
|
|
|
|
func TestResolver_BeginScope(t *testing.T) {
|
|
logger := errors.NewMockErrorLogger()
|
|
interp := &interpreter.Interpreter{}
|
|
resolver := New(interp, logger)
|
|
|
|
resolver.beginScope()
|
|
|
|
if len(resolver.scopes) != 1 {
|
|
t.Errorf("expected 1 scope, got %v", resolver.scopes)
|
|
}
|
|
}
|
|
|
|
func TestResolver_EndScope(t *testing.T) {
|
|
logger := errors.NewMockErrorLogger()
|
|
interp := &interpreter.Interpreter{}
|
|
resolver := New(interp, logger)
|
|
|
|
resolver.beginScope()
|
|
resolver.endScope()
|
|
|
|
if len(resolver.scopes) != 0 {
|
|
t.Errorf("expected 0 scopes, got %v", resolver.scopes)
|
|
}
|
|
}
|