package ast import ( "azalea/schema/token" "azalea/schema/util" "strconv" "strings" ) type Schema ExprList type ExprList []Expr type Expr struct { Name string Left *Val Right *Val } type ValList []Val type Val struct { string *string rune *rune int *int64 float *float64 imaginary *complex128 name *string *Expr } func NewStringVal(val *token.Token) (Val, error) { s, err := strconv.Unquote(string(val.Lit)) return Val{string: &s}, err } func NewRuneVal(val *token.Token) (Val, error) { r := util.RuneValue(val.Lit) return Val{rune: &r}, nil } func NewIntVal(val *token.Token) (Val, error) { i, err := strconv.ParseInt(string(val.Lit), 0, 64) return Val{int: &i}, err } func NewFloatVal(val *token.Token) (Val, error) { f, err := strconv.ParseFloat(string(val.Lit), 64) return Val{float: &f}, err } func NewComplexVal(val *token.Token) (Val, error) { c, err := strconv.ParseComplex(string(val.Lit), 128) return Val{imaginary: &c}, err } func NewNameVal(val *token.Token) (Val, error) { name := string(val.Lit) return Val{name: &name}, nil } func NewExprVal(val any) (Val, error) { expr := val.(Expr) return Val{Expr: &expr}, nil } func NewExprList(expr any) (ExprList, error) { return ExprList{expr.(Expr)}, nil } func AppendExpr(exprList, expr any) (ExprList, error) { return append(exprList.(ExprList), expr.(Expr)), nil } func NewValList(val any) (ValList, error) { return ValList{val.(Val)}, nil } func AppendVal(valList, val any) (ValList, error) { return append(valList.(ValList), val.(Val)), nil } func NewExpr(name *token.Token, left any, right any) (Expr, error) { var l Val var r Val if left != nil { l = left.(Val) } if right != nil { r = right.(Val) } return Expr{string(name.Lit), &l, &r}, nil } func ListExpr(val any) (Expr, error) { vals := val.(ValList) root := Expr{ Name: ".", } current := &root for _, val := range vals[:len(vals)-2] { current.Left = &val current.Right = &Val{ Expr: &Expr{ Name: ".", }} current = current.Right.Expr } current.Left = &vals[len(vals)-2] current.Right = &vals[len(vals)-1] return root, nil } func (e Expr) String() string { sb := new(strings.Builder) sb.WriteRune('(') sb.WriteString(e.Name) sb.WriteRune(' ') if e.Left != nil { sb.WriteString(e.Left.String()) } sb.WriteRune(' ') if e.Left != nil { sb.WriteString(e.Right.String()) } sb.WriteRune(')') return sb.String() } func (v *Val) String() string { if v.string != nil { return *v.string } if v.rune != nil { return string(*v.rune) } if v.int != nil { return strconv.FormatInt(*v.int, 10) } if v.float != nil { return strconv.FormatFloat(*v.float, 'g', -1, 64) } if v.imaginary != nil { return strconv.FormatComplex(*v.imaginary, 'g', -1, 128) } if v.name != nil { return *v.name } if v.Expr != nil { return v.Expr.String() } return "" }