Simplified file structure
This commit is contained in:
parent
cacee7260a
commit
a466281307
219 changed files with 453 additions and 457 deletions
149
src/expression/Expression.go
Normal file
149
src/expression/Expression.go
Normal file
|
@ -0,0 +1,149 @@
|
|||
package expression
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"git.akyoto.dev/cli/q/src/token"
|
||||
)
|
||||
|
||||
// Expression is a binary tree with an operator on each node.
|
||||
type Expression struct {
|
||||
Parent *Expression
|
||||
Children []*Expression
|
||||
Token token.Token
|
||||
Value int
|
||||
Precedence int8
|
||||
IsFolded bool
|
||||
}
|
||||
|
||||
// New creates a new expression.
|
||||
func New() *Expression {
|
||||
return &Expression{}
|
||||
}
|
||||
|
||||
// NewLeaf creates a new leaf node.
|
||||
func NewLeaf(t token.Token) *Expression {
|
||||
return &Expression{
|
||||
Token: t,
|
||||
}
|
||||
}
|
||||
|
||||
// AddChild adds a child to the expression.
|
||||
func (expr *Expression) AddChild(child *Expression) {
|
||||
if expr.Children == nil {
|
||||
expr.Children = make([]*Expression, 0, 2)
|
||||
}
|
||||
|
||||
expr.Children = append(expr.Children, child)
|
||||
child.Parent = expr
|
||||
}
|
||||
|
||||
// Count counts how often the given token appears in the expression.
|
||||
func (expr *Expression) Count(buffer []byte, kind token.Kind, name string) uint8 {
|
||||
count := uint8(0)
|
||||
|
||||
expr.EachLeaf(func(leaf *Expression) error {
|
||||
if leaf.Token.Kind == kind && leaf.Token.Text(buffer) == name {
|
||||
count++
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
return count
|
||||
}
|
||||
|
||||
// Reset resets all values to the default.
|
||||
func (expr *Expression) Reset() {
|
||||
expr.Parent = nil
|
||||
|
||||
if expr.Children != nil {
|
||||
expr.Children = expr.Children[:0]
|
||||
}
|
||||
|
||||
expr.Token.Reset()
|
||||
expr.Value = 0
|
||||
expr.Precedence = 0
|
||||
expr.IsFolded = false
|
||||
}
|
||||
|
||||
// EachLeaf iterates through all leaves in the tree.
|
||||
func (expr *Expression) EachLeaf(call func(*Expression) error) error {
|
||||
if expr.IsLeaf() {
|
||||
return call(expr)
|
||||
}
|
||||
|
||||
for _, child := range expr.Children {
|
||||
err := child.EachLeaf(call)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// RemoveChild removes a child from the expression.
|
||||
func (expr *Expression) RemoveChild(child *Expression) {
|
||||
for i, c := range expr.Children {
|
||||
if c == child {
|
||||
expr.Children = append(expr.Children[:i], expr.Children[i+1:]...)
|
||||
child.Parent = nil
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Replace replaces the tree with the new expression and adds the previous expression to it.
|
||||
func (expr *Expression) Replace(tree *Expression) {
|
||||
if expr.Parent != nil {
|
||||
expr.Parent.Children[len(expr.Parent.Children)-1] = tree
|
||||
tree.Parent = expr.Parent
|
||||
}
|
||||
|
||||
tree.AddChild(expr)
|
||||
}
|
||||
|
||||
// IsLeaf returns true if the expression has no children.
|
||||
func (expr *Expression) IsLeaf() bool {
|
||||
return len(expr.Children) == 0
|
||||
}
|
||||
|
||||
// LastChild returns the last child.
|
||||
func (expr *Expression) LastChild() *Expression {
|
||||
return expr.Children[len(expr.Children)-1]
|
||||
}
|
||||
|
||||
// String generates a textual representation of the expression.
|
||||
func (expr *Expression) String(source []byte) string {
|
||||
builder := strings.Builder{}
|
||||
expr.write(&builder, source)
|
||||
return builder.String()
|
||||
}
|
||||
|
||||
// write generates a textual representation of the expression.
|
||||
func (expr *Expression) write(builder *strings.Builder, source []byte) {
|
||||
if expr.IsLeaf() {
|
||||
builder.WriteString(expr.Token.Text(source))
|
||||
return
|
||||
}
|
||||
|
||||
builder.WriteByte('(')
|
||||
|
||||
switch expr.Token.Kind {
|
||||
case token.Call:
|
||||
builder.WriteString("λ")
|
||||
case token.Array:
|
||||
builder.WriteString("@")
|
||||
default:
|
||||
builder.WriteString(expr.Token.Text(source))
|
||||
}
|
||||
|
||||
for _, child := range expr.Children {
|
||||
builder.WriteByte(' ')
|
||||
child.write(builder, source)
|
||||
}
|
||||
|
||||
builder.WriteByte(')')
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue