feat/schema: add ast and test
This commit is contained in:
117
schema/ast/ast.go
Normal file
117
schema/ast/ast.go
Normal file
@@ -0,0 +1,117 @@
|
||||
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>"
|
||||
}
|
||||
Reference in New Issue
Block a user