156 lines
3.2 KiB
Go
156 lines
3.2 KiB
Go
package parser
|
|
|
|
import "fmt"
|
|
|
|
// Node represents any node in the AST
|
|
type Node interface {
|
|
String() string
|
|
}
|
|
|
|
// Statement represents statement nodes
|
|
type Statement interface {
|
|
Node
|
|
statementNode()
|
|
}
|
|
|
|
// Expression represents expression nodes
|
|
type Expression interface {
|
|
Node
|
|
expressionNode()
|
|
}
|
|
|
|
// Program represents the root of the AST
|
|
type Program struct {
|
|
Statements []Statement
|
|
}
|
|
|
|
func (p *Program) String() string {
|
|
var result string
|
|
for _, stmt := range p.Statements {
|
|
result += stmt.String() + "\n"
|
|
}
|
|
return result
|
|
}
|
|
|
|
// AssignStatement represents variable assignment
|
|
type AssignStatement struct {
|
|
Name *Identifier
|
|
Value Expression
|
|
}
|
|
|
|
func (as *AssignStatement) statementNode() {}
|
|
func (as *AssignStatement) String() string {
|
|
return fmt.Sprintf("%s = %s", as.Name.String(), as.Value.String())
|
|
}
|
|
|
|
// Identifier represents identifiers
|
|
type Identifier struct {
|
|
Value string
|
|
}
|
|
|
|
func (i *Identifier) expressionNode() {}
|
|
func (i *Identifier) String() string { return i.Value }
|
|
|
|
// NumberLiteral represents numeric literals
|
|
type NumberLiteral struct {
|
|
Value float64
|
|
}
|
|
|
|
func (nl *NumberLiteral) expressionNode() {}
|
|
func (nl *NumberLiteral) String() string { return fmt.Sprintf("%.2f", nl.Value) }
|
|
|
|
// StringLiteral represents string literals
|
|
type StringLiteral struct {
|
|
Value string
|
|
}
|
|
|
|
func (sl *StringLiteral) expressionNode() {}
|
|
func (sl *StringLiteral) String() string { return fmt.Sprintf(`"%s"`, sl.Value) }
|
|
|
|
// BooleanLiteral represents boolean literals
|
|
type BooleanLiteral struct {
|
|
Value bool
|
|
}
|
|
|
|
func (bl *BooleanLiteral) expressionNode() {}
|
|
func (bl *BooleanLiteral) String() string {
|
|
if bl.Value {
|
|
return "true"
|
|
}
|
|
return "false"
|
|
}
|
|
|
|
// NilLiteral represents nil literal
|
|
type NilLiteral struct{}
|
|
|
|
func (nl *NilLiteral) expressionNode() {}
|
|
func (nl *NilLiteral) String() string { return "nil" }
|
|
|
|
// InfixExpression represents binary operations
|
|
type InfixExpression struct {
|
|
Left Expression
|
|
Operator string
|
|
Right Expression
|
|
}
|
|
|
|
func (ie *InfixExpression) expressionNode() {}
|
|
func (ie *InfixExpression) String() string {
|
|
return fmt.Sprintf("(%s %s %s)", ie.Left.String(), ie.Operator, ie.Right.String())
|
|
}
|
|
|
|
// TablePair represents a key-value pair in a table
|
|
type TablePair struct {
|
|
Key Expression // nil for array-style elements
|
|
Value Expression
|
|
}
|
|
|
|
func (tp *TablePair) String() string {
|
|
if tp.Key == nil {
|
|
return tp.Value.String()
|
|
}
|
|
return fmt.Sprintf("%s = %s", tp.Key.String(), tp.Value.String())
|
|
}
|
|
|
|
// TableLiteral represents table literals {}
|
|
type TableLiteral struct {
|
|
Pairs []TablePair
|
|
}
|
|
|
|
func (tl *TableLiteral) expressionNode() {}
|
|
func (tl *TableLiteral) String() string {
|
|
var pairs []string
|
|
for _, pair := range tl.Pairs {
|
|
pairs = append(pairs, pair.String())
|
|
}
|
|
return fmt.Sprintf("{%s}", joinStrings(pairs, ", "))
|
|
}
|
|
|
|
// IsArray returns true if this table contains only array-style elements
|
|
func (tl *TableLiteral) IsArray() bool {
|
|
for _, pair := range tl.Pairs {
|
|
if pair.Key != nil {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
// joinStrings joins string slice with separator
|
|
func joinStrings(strs []string, sep string) string {
|
|
if len(strs) == 0 {
|
|
return ""
|
|
}
|
|
if len(strs) == 1 {
|
|
return strs[0]
|
|
}
|
|
|
|
var result string
|
|
for i, s := range strs {
|
|
if i > 0 {
|
|
result += sep
|
|
}
|
|
result += s
|
|
}
|
|
return result
|
|
}
|