-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
66 lines (57 loc) · 1.46 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
package main
import (
"fmt"
"lang/eval"
"lang/lexer"
"lang/object"
"lang/parser"
"os"
"strconv"
"strings"
)
func printError(code string, msg string) {
split := strings.SplitAfterN(msg, " ", 2)
pos := strings.Split(split[0], ",")
row, _ := strconv.Atoi(strings.Split(pos[0], "[")[1])
col, _ := strconv.Atoi(strings.Split(pos[1], "]")[0])
println()
rowNumber := strconv.Itoa(row) + ": "
println(rowNumber, strings.Split(code, "\n")[row-1])
println(strings.Repeat(" ", col+len(rowNumber)) + ("^ ") + split[1])
}
func main() {
file := os.Args[1]
bytes, err := os.ReadFile(file)
if err != nil {
fmt.Printf("file not found %s\n", file)
return
}
code := string(bytes) + "\nmain();"
l := lexer.NewLexer(string(code))
// emit tokens, need to comment everyting else
// for l.NextToken().Type != token.EOF {
// fmt.Printf("%#v\n", l.NextToken())
// }
p := parser.NewParser(l)
program := p.Parse()
if len(p.Errors()) != 0 {
for _, err := range p.Errors() {
printError(code, err)
return
}
}
// uncomment to see AST, redirect to file if tree is too wide
// parser.DrawTree(program)
// prevents output if an error occurs, since this is currently an interpreter
// not a compiler
f := eval.SetupStdout()
defer f.Close()
evaluated := eval.Eval(program, object.NewScope())
if evaluated.Type() == object.ERROR_OBJ {
printError(code, evaluated.Inspect())
return
}
stdout, _ := os.ReadFile(f.Name())
print(string(stdout))
print(evaluated.Inspect())
}