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 Expression // Changed from *Identifier to Expression for member access Value Expression } func (as *AssignStatement) statementNode() {} func (as *AssignStatement) String() string { return fmt.Sprintf("%s = %s", as.Name.String(), as.Value.String()) } // EchoStatement represents echo output statements type EchoStatement struct { Value Expression } func (es *EchoStatement) statementNode() {} func (es *EchoStatement) String() string { return fmt.Sprintf("echo %s", es.Value.String()) } // ElseIfClause represents an elseif condition type ElseIfClause struct { Condition Expression Body []Statement } func (eic *ElseIfClause) String() string { var body string for _, stmt := range eic.Body { body += "\t" + stmt.String() + "\n" } return fmt.Sprintf("elseif %s then\n%s", eic.Condition.String(), body) } // IfStatement represents conditional statements type IfStatement struct { Condition Expression Body []Statement ElseIfs []ElseIfClause Else []Statement } func (is *IfStatement) statementNode() {} func (is *IfStatement) String() string { var result string // If clause result += fmt.Sprintf("if %s then\n", is.Condition.String()) for _, stmt := range is.Body { result += "\t" + stmt.String() + "\n" } // ElseIf clauses for _, elseif := range is.ElseIfs { result += elseif.String() } // Else clause if len(is.Else) > 0 { result += "else\n" for _, stmt := range is.Else { result += "\t" + stmt.String() + "\n" } } result += "end" return result } // 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()) } // IndexExpression represents table[key] access type IndexExpression struct { Left Expression Index Expression } func (ie *IndexExpression) expressionNode() {} func (ie *IndexExpression) String() string { return fmt.Sprintf("%s[%s]", ie.Left.String(), ie.Index.String()) } // DotExpression represents table.key access type DotExpression struct { Left Expression Key string } func (de *DotExpression) expressionNode() {} func (de *DotExpression) String() string { return fmt.Sprintf("%s.%s", de.Left.String(), de.Key) } // 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 }