-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
85 lines (73 loc) · 1.28 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
package main
import (
"bufio"
"fmt"
"log"
"os"
"golox/pkg/interpreter"
"golox/pkg/parser"
"golox/pkg/resolver"
"golox/pkg/scanner"
)
func main() {
if len(os.Args) > 2 {
log.Fatal("Usage golox [script]")
} else if len(os.Args) == 2 {
runFile(os.Args[1])
} else {
runPrompt()
}
}
func runFile(path string) {
bytes, err := os.ReadFile(path)
if err != nil {
log.Fatal(err)
}
stmts, err := scanAndParse(string(bytes))
if err != nil {
os.Exit(65)
}
i := interpreter.NewInterpreter()
r := resolver.NewResolver(i)
err = r.Resolve(stmts)
if err != nil {
os.Exit(65)
}
err = i.Interpret(stmts)
if err != nil {
os.Exit(70)
}
}
func runPrompt() {
s := bufio.NewScanner(os.Stdin)
i := interpreter.NewInterpreter()
fmt.Print("> ")
for s.Scan() {
stmts, err := scanAndParse(s.Text())
if err == nil {
r := resolver.NewResolver(i)
err = r.Resolve(stmts)
}
if err == nil {
i.Interpret(stmts)
}
fmt.Print("> ")
}
if err := s.Err(); err == nil {
fmt.Println("bye")
os.Exit(0)
}
}
func scanAndParse(source string) ([]parser.Stmt, error) {
s := scanner.NewScanner(source)
err := s.ScanTokens()
if err != nil {
return nil, err
}
p := parser.NewParser(s.Tokens)
stmts, err := p.Parse()
if err != nil {
return nil, err
}
return stmts, nil
}