package varaq import ( "fmt" "strings" ) type Expr struct { Tok TokenType Exprs []Expr Value any Count int } type Parser struct { tokens []Token pos int end int } func (p Parser) curr() Token { return p.tokens[p.pos] } func parse(p Parser, stop TokenType, tt TokenType) (Expr, int) { code := Expr{tt, make([]Expr, 0), nil, 0} for { if p.pos < 0 || p.pos > p.end-1 { break } if p.curr().Toktype == stop { p.pos += 1 break } if p.curr().Toktype == LEFTBRACE { p.pos += 1 ex, pos := parse(p, RIGHTBRACE, FUNCTION) p.pos = pos code.Exprs = append(code.Exprs, ex) code.Count += 1 } else if p.curr().Toktype == LEFTPAREN { p.pos += 1 ex, pos := parse(p, RIGHTPAREN, LIST) p.pos = pos code.Exprs = append(code.Exprs, ex) code.Count += 1 } else { code.Exprs = append(code.Exprs, Expr{p.curr().Toktype, nil, p.curr().Literal, 0}) p.pos += 1 } } return code, p.pos } func Parse(tokens []Token) Expr { parser := Parser{tokens, 0, len(tokens)} ex, _ := parse(parser, EOF, SCRIPT) return ex } func PrintDump(code Expr, depth int) { for _, c := range code.Exprs { if c.Tok == FUNCTION { depth += 1 fmt.Printf("%s %s\n", strings.Repeat("-", depth), c.Tok) PrintDump(c, depth) depth -= 1 } else if c.Tok == LIST { depth += 1 fmt.Printf("%s %s\n", strings.Repeat("-", depth), c.Tok) PrintDump(c, depth) depth -= 1 } else { fmt.Printf("%s %s: %v\n", strings.Repeat("-", depth), c.Tok, c.Value) } } }