Compare commits
No commits in common. "04e669c15630516be06849b0a647fbd751152bb9" and "c7d48e3640966e2edb13d32bf57363e644e6d936" have entirely different histories.
04e669c156
...
c7d48e3640
56
pj1-go/ast-print.go
Normal file
56
pj1-go/ast-print.go
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func print(expr Expr) string {
|
||||||
|
switch e := expr.(type) {
|
||||||
|
case Binary:
|
||||||
|
return parenthesize(e.operator.Lexeme,
|
||||||
|
e.left,
|
||||||
|
e.right)
|
||||||
|
case Grouping:
|
||||||
|
return parenthesize("group", e.expression)
|
||||||
|
case Literal:
|
||||||
|
if e.value == nil {
|
||||||
|
return "nil"
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%v", e.value)
|
||||||
|
case Unary:
|
||||||
|
return parenthesize(e.operator.Lexeme, e.right)
|
||||||
|
}
|
||||||
|
return "ERROR: reached impossible branch in print function"
|
||||||
|
}
|
||||||
|
|
||||||
|
func parenthesize(name string, exprs ...Expr) string {
|
||||||
|
var sb strings.Builder
|
||||||
|
|
||||||
|
sb.WriteString("(" + name)
|
||||||
|
|
||||||
|
for _, expr := range exprs {
|
||||||
|
sb.WriteString(" ")
|
||||||
|
sb.WriteString(print(expr))
|
||||||
|
}
|
||||||
|
sb.WriteString(")")
|
||||||
|
|
||||||
|
return sb.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// This was briefly a testing function for the AST class at the end of ch. 5
|
||||||
|
/*
|
||||||
|
func main() {
|
||||||
|
var expression Expr = Binary{
|
||||||
|
Unary{
|
||||||
|
lexer.NewToken(lexer.MINUS, "-", nil, 1),
|
||||||
|
Literal{123},
|
||||||
|
},
|
||||||
|
lexer.NewToken(lexer.STAR, "*", nil, 1),
|
||||||
|
Grouping{
|
||||||
|
Literal{45.67},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
fmt.Println(print(expression))
|
||||||
|
}
|
||||||
|
*/
|
|
@ -1,4 +1,5 @@
|
||||||
//go:build generate
|
//go:build generate
|
||||||
|
|
||||||
//go:generate go run ./gen-ast.go ./
|
//go:generate go run ./gen-ast.go ./
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
@ -48,6 +49,7 @@ func main() {
|
||||||
[]string{"Binary : left Expr, operator lexer.Token, right Expr",
|
[]string{"Binary : left Expr, operator lexer.Token, right Expr",
|
||||||
"Grouping : expression Expr",
|
"Grouping : expression Expr",
|
||||||
"Literal : value interface{}",
|
"Literal : value interface{}",
|
||||||
|
// a literal can be any value that can be printed
|
||||||
"Unary : operator lexer.Token, right Expr"})
|
"Unary : operator lexer.Token, right Expr"})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,7 +74,7 @@ func defineAst(outputDir string, baseName string, types []string) {
|
||||||
fmt.Fprintln(f, "// Code generated by tools/gen-ast.go DO NOT EDIT.")
|
fmt.Fprintln(f, "// Code generated by tools/gen-ast.go DO NOT EDIT.")
|
||||||
fmt.Fprintln(f, "package main")
|
fmt.Fprintln(f, "package main")
|
||||||
fmt.Fprintln(f)
|
fmt.Fprintln(f)
|
||||||
fmt.Fprintln(f, "import \"" + modulePath + "/lexer\"")
|
fmt.Fprintln(f, "import \""+modulePath+"/lexer\"")
|
||||||
fmt.Fprintln(f)
|
fmt.Fprintln(f)
|
||||||
// Creates a dummy interface just to limit types which can be
|
// Creates a dummy interface just to limit types which can be
|
||||||
// considered an "Expr"
|
// considered an "Expr"
|
||||||
|
@ -91,19 +93,19 @@ func defineAst(outputDir string, baseName string, types []string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func defineType(f io.Writer, baseName string, typeName string, fieldList string) {
|
func defineType(f io.Writer, baseName string, typeName string, fieldList string) {
|
||||||
fmt.Fprintln(f, "type " + typeName + " struct {")
|
fmt.Fprintln(f, "type "+typeName+" struct {")
|
||||||
|
|
||||||
// Fields.
|
// Fields.
|
||||||
var fields []string = strings.Split(fieldList, ", ")
|
var fields []string = strings.Split(fieldList, ", ")
|
||||||
for _, field := range fields {
|
for _, field := range fields {
|
||||||
fmt.Fprintln(f, "\t" + field)
|
fmt.Fprintln(f, "\t"+field)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Fprintln(f, "}")
|
fmt.Fprintln(f, "}")
|
||||||
fmt.Fprintln(f)
|
fmt.Fprintln(f)
|
||||||
|
|
||||||
// Interface dummy function
|
// Interface dummy function
|
||||||
fmt.Fprintln(f, "func (x "+typeName+") is"+ baseName +"() {}")
|
fmt.Fprintln(f, "func (x "+typeName+") is"+baseName+"() {}")
|
||||||
fmt.Fprintln(f)
|
fmt.Fprintln(f)
|
||||||
|
|
||||||
// TODO: may have to generate constructor, according to top of
|
// TODO: may have to generate constructor, according to top of
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
git.bonsai.cool/kayprish/pj1/pj1-go v0.0.0-20240807135935-04e669c15630 h1:SO1oOi4BAVPmoCkBCeZEcNXiCDZJrM49Y5Fhm/bBuBU=
|
||||||
|
git.bonsai.cool/kayprish/pj1/pj1-go v0.0.0-20240807135935-04e669c15630/go.mod h1:f4dHsvhBf6lTSjuA+gqssxFOHdkOjPnS4QeufMWvHOM=
|
||||||
golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
|
golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
|
||||||
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s=
|
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s=
|
||||||
|
|
|
@ -88,7 +88,7 @@ var keywords = map[string]TokenType{
|
||||||
|
|
||||||
type Token struct {
|
type Token struct {
|
||||||
ttype TokenType
|
ttype TokenType
|
||||||
lexeme string
|
Lexeme string
|
||||||
literal interface{}
|
literal interface{}
|
||||||
line int
|
line int
|
||||||
}
|
}
|
||||||
|
@ -99,7 +99,7 @@ func NewToken(ttype TokenType, lexeme string, literal interface{}, line int) Tok
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t Token) String() string {
|
func (t Token) String() string {
|
||||||
return fmt.Sprintf("%v %v %v", t.ttype, t.lexeme, t.literal)
|
return fmt.Sprintf("%v %v %v", t.ttype, t.Lexeme, t.literal)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Lexer struct {
|
type Lexer struct {
|
||||||
|
|
|
@ -10,16 +10,16 @@ import (
|
||||||
"git.bonsai.cool/kayprish/pj1/pj1-go/util"
|
"git.bonsai.cool/kayprish/pj1/pj1-go/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
// func main() {
|
||||||
if len(os.Args) > 2 {
|
// if len(os.Args) > 2 {
|
||||||
fmt.Println("Usage: pj1-go [script]")
|
// fmt.Println("Usage: pj1-go [script]")
|
||||||
os.Exit(64)
|
// os.Exit(64)
|
||||||
} else if len(os.Args) == 2 {
|
// } else if len(os.Args) == 2 {
|
||||||
runFile(os.Args[0])
|
// runFile(os.Args[0])
|
||||||
} else {
|
// } else {
|
||||||
runPrompt()
|
// runPrompt()
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
func runFile(path string) {
|
func runFile(path string) {
|
||||||
bytes, err := ioutil.ReadFile(path)
|
bytes, err := ioutil.ReadFile(path)
|
||||||
|
|
Loading…
Reference in a new issue