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:generate go run ./gen-ast.go ./
|
||||
|
||||
package main
|
||||
|
@ -48,6 +49,7 @@ func main() {
|
|||
[]string{"Binary : left Expr, operator lexer.Token, right Expr",
|
||||
"Grouping : expression Expr",
|
||||
"Literal : value interface{}",
|
||||
// a literal can be any value that can be printed
|
||||
"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, "package main")
|
||||
fmt.Fprintln(f)
|
||||
fmt.Fprintln(f, "import \"" + modulePath + "/lexer\"")
|
||||
fmt.Fprintln(f, "import \""+modulePath+"/lexer\"")
|
||||
fmt.Fprintln(f)
|
||||
// Creates a dummy interface just to limit types which can be
|
||||
// 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) {
|
||||
fmt.Fprintln(f, "type " + typeName + " struct {")
|
||||
fmt.Fprintln(f, "type "+typeName+" struct {")
|
||||
|
||||
// Fields.
|
||||
var fields []string = strings.Split(fieldList, ", ")
|
||||
for _, field := range fields {
|
||||
fmt.Fprintln(f, "\t" + field)
|
||||
fmt.Fprintln(f, "\t"+field)
|
||||
}
|
||||
|
||||
fmt.Fprintln(f, "}")
|
||||
fmt.Fprintln(f)
|
||||
|
||||
// Interface dummy function
|
||||
fmt.Fprintln(f, "func (x "+typeName+") is"+ baseName +"() {}")
|
||||
fmt.Fprintln(f, "func (x "+typeName+") is"+baseName+"() {}")
|
||||
fmt.Fprintln(f)
|
||||
|
||||
// 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/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s=
|
||||
|
|
|
@ -88,7 +88,7 @@ var keywords = map[string]TokenType{
|
|||
|
||||
type Token struct {
|
||||
ttype TokenType
|
||||
lexeme string
|
||||
Lexeme string
|
||||
literal interface{}
|
||||
line int
|
||||
}
|
||||
|
@ -99,7 +99,7 @@ func NewToken(ttype TokenType, lexeme string, literal interface{}, line int) Tok
|
|||
}
|
||||
|
||||
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 {
|
||||
|
|
|
@ -10,16 +10,16 @@ import (
|
|||
"git.bonsai.cool/kayprish/pj1/pj1-go/util"
|
||||
)
|
||||
|
||||
func main() {
|
||||
if len(os.Args) > 2 {
|
||||
fmt.Println("Usage: pj1-go [script]")
|
||||
os.Exit(64)
|
||||
} else if len(os.Args) == 2 {
|
||||
runFile(os.Args[0])
|
||||
} else {
|
||||
runPrompt()
|
||||
}
|
||||
}
|
||||
// func main() {
|
||||
// if len(os.Args) > 2 {
|
||||
// fmt.Println("Usage: pj1-go [script]")
|
||||
// os.Exit(64)
|
||||
// } else if len(os.Args) == 2 {
|
||||
// runFile(os.Args[0])
|
||||
// } else {
|
||||
// runPrompt()
|
||||
// }
|
||||
// }
|
||||
|
||||
func runFile(path string) {
|
||||
bytes, err := ioutil.ReadFile(path)
|
||||
|
|
Loading…
Reference in a new issue