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() }