118 lines
2.1 KiB
Go
118 lines
2.1 KiB
Go
package ast
|
|
|
|
import (
|
|
"azalea/schema/token"
|
|
"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
|
|
number string
|
|
name string
|
|
*Expr
|
|
}
|
|
|
|
func NewExprList(expr any) (ExprList, error) {
|
|
return ExprList{expr.(Expr)}, nil
|
|
}
|
|
|
|
func NewStringVal(val *token.Token) (Val, error) {
|
|
return Val{string: string(val.Lit)}, nil
|
|
}
|
|
|
|
func NewNumberVal(val *token.Token) (Val, error) {
|
|
return Val{number: string(val.Lit)}, nil
|
|
}
|
|
|
|
func NewNameVal(val *token.Token) (Val, error) {
|
|
return Val{name: string(val.Lit)}, nil
|
|
}
|
|
|
|
func NewExprVal(val any) (Val, error) {
|
|
expr := val.(Expr)
|
|
return Val{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 != "" {
|
|
return v.string
|
|
}
|
|
if v.number != "" {
|
|
num, _ := strconv.ParseInt(v.number, 0, 64)
|
|
return strconv.FormatInt(num, 10)
|
|
}
|
|
if v.name != "" {
|
|
return v.name
|
|
}
|
|
if v.Expr != nil {
|
|
return v.Expr.String()
|
|
}
|
|
return "<nil>"
|
|
}
|