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.

114 lines
1.8 KiB
Go

package lox
import (
"bufio"
"fmt"
"golox/interpreter"
"golox/parser"
"golox/resolver"
"golox/scanner"
"golox/token"
"os"
)
type Lox struct {
hadError bool
hadRuntimeError bool
interpreter *interpreter.Interpreter
}
func New() *Lox {
l := &Lox{
hadError: false,
hadRuntimeError: false,
}
l.interpreter = interpreter.New(l)
return l
}
func (l *Lox) RunFile(path string) {
bytes, err := os.ReadFile(path)
if err != nil {
fmt.Println("Error reading file", path)
os.Exit(74)
}
l.run(string(bytes))
if l.hadError {
os.Exit(65)
}
if l.hadRuntimeError {
os.Exit(70)
}
}
func (l *Lox) RunPrompt() {
reader := bufio.NewReader(os.Stdin)
for {
fmt.Print("> ")
line, err := reader.ReadString('\n')
if err != nil {
fmt.Println(err)
os.Exit(74)
}
if line == "\n" {
break
}
l.run(line)
l.hadError = false
}
}
func (l *Lox) Error(line int, message string) {
l.hadError = true
l.report(line, "", message)
}
func (l *Lox) ErrorAtToken(t token.Token, message string) {
l.hadError = true
if t.Type == token.EOF {
l.report(t.Line, " at end", message)
} else {
l.report(t.Line, " at '"+t.Lexeme+"'", message)
}
}
func (l *Lox) RuntimeError(message string) {
l.hadRuntimeError = true
fmt.Println(message)
}
func (l *Lox) report(line int, where string, message string) {
fmt.Printf("[line %d] Error %s: %s\n", line, where, message)
}
func (l *Lox) run(source string) {
scanner := scanner.New(source, l)
tokens := scanner.ScanTokens()
parser := parser.New(tokens, l)
stmts := parser.Parse()
// Stop if there was a syntax error.
if l.hadError {
return
}
resolver := resolver.New(l.interpreter, l)
resolver.Resolve(stmts)
// Stop if there was a resolution error.
if l.hadError {
return
}
l.interpreter.Interpret(stmts)
}