Files
azalea/schema/ast/ast.go
2026-01-28 19:52:13 -06:00

150 lines
3.0 KiB
Go

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 NewIStringVal(val *token.Token) (Val, error) {
s, err := util.InterpretString(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 "<nil>"
}