go-pkg/rsql/ast.go
2024-01-22 16:00:58 -07:00

256 lines
5.5 KiB
Go

package rsql
import (
"bytes"
"strings"
)
// Node is the smallest unit of ast
type Node interface {
TokenLiteral() string
String() string
}
// Statement is a executable tree
type Statement interface {
Node
statementNode()
}
// Expression is a portion of tree
type Expression interface {
Node
expressionNode()
}
// Identifier is a variable name
type Identifier struct {
Token Token
Value string
}
func (i *Identifier) expressionNode() {}
// TokenLiteral returns the literal value of a token
func (i *Identifier) TokenLiteral() string { return i.Token.Literal }
// String returns a string representation of value
func (i *Identifier) String() string { return i.Value }
// Integer is a numeric value
type Integer struct {
Token Token
Value int64
}
func (i *Integer) expressionNode() {}
// TokenLiteral returns the literal value of a token
func (i *Integer) TokenLiteral() string { return i.Token.Literal }
// String returns a string representation of value
func (i *Integer) String() string { return i.Token.Literal }
// Float is a floating point value
type Float struct {
Token Token
Value float64
}
func (i *Float) expressionNode() {}
// TokenLiteral returns the literal value of a token
func (i *Float) TokenLiteral() string { return i.Token.Literal }
// String returns a string representation of value
func (i *Float) String() string { return i.Token.Literal }
// Bool is a boolean value
type Bool struct {
Token Token
Value bool
}
func (i *Bool) expressionNode() {}
// TokenLiteral returns the literal value of a token
func (i *Bool) TokenLiteral() string { return i.Token.Literal }
// String returns a string representation of value
func (i *Bool) String() string { return i.Token.Literal }
// Null is an empty value
type Null struct {
Token Token
}
func (i *Null) expressionNode() {}
// TokenLiteral returns the literal value of a token
func (i *Null) TokenLiteral() string { return i.Token.Literal }
// String returns a string representation of value
func (i *Null) String() string { return i.Token.Literal }
// String is an array of codepoints
type String struct {
Token Token
Value string
}
func (i *String) expressionNode() {}
// TokenLiteral returns the literal value of a token
func (i *String) TokenLiteral() string { return i.Token.Literal }
// String returns a string representation of value
func (i *String) String() string {
var out bytes.Buffer
out.WriteRune('"')
out.WriteString(i.Value)
out.WriteRune('"')
return out.String()
}
// Array is an array of tokens
type Array struct {
Token Token
Elements []Expression
}
func (a *Array) expressionNode() {}
// TokenLiteral returns the literal value of a token
func (a *Array) TokenLiteral() string { return a.Token.Literal }
// String returns a string representation of value
func (a *Array) String() string {
var out bytes.Buffer
var elements []string
for _, el := range a.Elements {
elements = append(elements, el.String())
}
out.WriteRune('(')
out.WriteString(strings.Join(elements, ","))
out.WriteRune(')')
return out.String()
}
// Program is a collection of statements
type Program struct {
Statements []Statement
Args map[string]string
}
func (p *Program) expressionNode() {}
// TokenLiteral returns the literal value of a token
func (p *Program) TokenLiteral() string {
if len(p.Statements) > 0 {
return p.Statements[0].TokenLiteral()
}
return ""
}
// String returns a string representation of value
func (p *Program) String() string {
var out bytes.Buffer
for _, s := range p.Statements {
out.WriteString(s.String())
}
if len(p.Args) > 0 {
out.WriteRune('|')
for a, b := range p.Args {
out.WriteRune(' ')
out.WriteString(a)
out.WriteRune(':')
out.WriteString(b)
}
}
return out.String()
}
// ExpressionStatement is a collection of expressions
type ExpressionStatement struct {
Token Token
Expression Expression
}
func (ExpressionStatement) statementNode() {}
// TokenLiteral returns the literal value of a token
func (e ExpressionStatement) TokenLiteral() string { return e.Token.Literal }
// String returns a string representation of value
func (e ExpressionStatement) String() string {
if e.Expression != nil {
return e.Expression.String()
}
return ""
}
// PrefixExpression is an expression with a preceeding operator
type PrefixExpression struct {
Token Token
Operator string
Right Expression
}
func (p *PrefixExpression) expressionNode() {}
// TokenLiteral returns the literal value of a token
func (p *PrefixExpression) TokenLiteral() string { return p.Token.Literal }
// String returns a string representation of value
func (p *PrefixExpression) String() string {
var out bytes.Buffer
out.WriteRune('(')
out.WriteString(p.Operator)
out.WriteString(p.Right.String())
out.WriteRune(')')
return out.String()
}
// InfixExpression is two expressions with a infix operator
type InfixExpression struct {
Token Token
Left Expression
Operator string
Right Expression
}
func (i *InfixExpression) expressionNode() {}
// TokenLiteral returns the literal value of a token
func (i *InfixExpression) TokenLiteral() string { return i.Token.Literal }
// String returns a string representation of value
func (i *InfixExpression) String() string {
var out bytes.Buffer
out.WriteRune('(')
if i.Left != nil {
out.WriteString(i.Left.String())
} else {
out.WriteString("nil")
}
out.WriteString(i.Operator)
if i.Right != nil {
out.WriteString(i.Right.String())
} else {
out.WriteString("nil")
}
out.WriteRune(')')
return out.String()
}