206 lines
4.1 KiB
Go
206 lines
4.1 KiB
Go
package types
|
|
|
|
import "fmt"
|
|
|
|
// Node represents a node in the abstract syntax tree
|
|
type Node interface {
|
|
String() string
|
|
}
|
|
|
|
// Statement represents any statement
|
|
type Statement interface {
|
|
Node
|
|
statementNode()
|
|
}
|
|
|
|
// Expression represents any expression
|
|
type Expression interface {
|
|
Node
|
|
expressionNode()
|
|
}
|
|
|
|
// --- Expressions ---
|
|
|
|
// LiteralExpr represents a literal value
|
|
type LiteralExpr struct {
|
|
Value any
|
|
}
|
|
|
|
func (l LiteralExpr) expressionNode() {}
|
|
func (l LiteralExpr) String() string { return fmt.Sprintf("%v", l.Value) }
|
|
|
|
// BinaryExpr represents a binary operation
|
|
type BinaryExpr struct {
|
|
Left Expression
|
|
Operator Token
|
|
Right Expression
|
|
}
|
|
|
|
func (b BinaryExpr) expressionNode() {}
|
|
func (b BinaryExpr) String() string {
|
|
return fmt.Sprintf("(%s %s %s)", b.Left.String(), b.Operator.Lexeme, b.Right.String())
|
|
}
|
|
|
|
// VariableExpr represents a variable reference
|
|
type VariableExpr struct {
|
|
Name Token
|
|
}
|
|
|
|
func (v VariableExpr) expressionNode() {}
|
|
func (v VariableExpr) String() string { return v.Name.Lexeme }
|
|
|
|
// CallExpr represents a function call
|
|
type CallExpr struct {
|
|
Callee Expression
|
|
Paren Token
|
|
Arguments []Expression
|
|
}
|
|
|
|
func (c CallExpr) expressionNode() {}
|
|
func (c CallExpr) String() string {
|
|
args := ""
|
|
for i, arg := range c.Arguments {
|
|
if i > 0 {
|
|
args += ", "
|
|
}
|
|
args += arg.String()
|
|
}
|
|
return fmt.Sprintf("%s(%s)", c.Callee.String(), args)
|
|
}
|
|
|
|
// --- Statements ---
|
|
|
|
// ExpressionStmt represents an expression statement
|
|
type ExpressionStmt struct {
|
|
Expression Expression
|
|
}
|
|
|
|
func (e ExpressionStmt) statementNode() {}
|
|
func (e ExpressionStmt) String() string { return e.Expression.String() }
|
|
|
|
// AssignStmt represents a variable assignment
|
|
type AssignStmt struct {
|
|
Name Token
|
|
Value Expression
|
|
}
|
|
|
|
func (a AssignStmt) statementNode() {}
|
|
func (a AssignStmt) String() string {
|
|
return fmt.Sprintf("%s = %s", a.Name.Lexeme, a.Value.String())
|
|
}
|
|
|
|
// FunctionStmt represents a function declaration
|
|
type FunctionStmt struct {
|
|
Name Token
|
|
Params []Token
|
|
IsVariadic bool
|
|
Body []Statement
|
|
}
|
|
|
|
func (f FunctionStmt) statementNode() {}
|
|
func (f FunctionStmt) String() string {
|
|
params := ""
|
|
for i, param := range f.Params {
|
|
if i > 0 {
|
|
params += ", "
|
|
}
|
|
params += param.Lexeme
|
|
}
|
|
|
|
if f.IsVariadic {
|
|
if len(f.Params) > 0 {
|
|
params += ", ..."
|
|
} else {
|
|
params += "..."
|
|
}
|
|
}
|
|
|
|
return fmt.Sprintf("fn %s(%s) ... end", f.Name.Lexeme, params)
|
|
}
|
|
|
|
// FunctionStmt represents a function expression (anonymous function)
|
|
type FunctionExpr struct {
|
|
Params []Token
|
|
IsVariadic bool
|
|
Body []Statement
|
|
}
|
|
|
|
func (f FunctionExpr) expressionNode() {}
|
|
func (f FunctionExpr) String() string {
|
|
params := ""
|
|
for i, param := range f.Params {
|
|
if i > 0 {
|
|
params += ", "
|
|
}
|
|
params += param.Lexeme
|
|
}
|
|
|
|
if f.IsVariadic {
|
|
if len(f.Params) > 0 {
|
|
params += ", ..."
|
|
} else {
|
|
params += "..."
|
|
}
|
|
}
|
|
|
|
return fmt.Sprintf("fn(%s) ... end", params)
|
|
}
|
|
|
|
// ReturnStmt represents a return statement
|
|
type ReturnStmt struct {
|
|
Keyword Token
|
|
Value Expression
|
|
}
|
|
|
|
func (r ReturnStmt) statementNode() {}
|
|
func (r ReturnStmt) String() string {
|
|
if r.Value == nil {
|
|
return "return"
|
|
}
|
|
return fmt.Sprintf("return %s", r.Value.String())
|
|
}
|
|
|
|
// IfStmt represents an if statement
|
|
type IfStmt struct {
|
|
Condition Expression
|
|
ThenBranch []Statement
|
|
ElseIfs []struct {
|
|
Condition Expression
|
|
Body []Statement
|
|
}
|
|
ElseBranch []Statement
|
|
}
|
|
|
|
func (i IfStmt) statementNode() {}
|
|
func (i IfStmt) String() string { return "if ... then ... end" }
|
|
|
|
// EchoStmt represents an echo statement
|
|
type EchoStmt struct {
|
|
Keyword Token
|
|
Value Expression
|
|
}
|
|
|
|
func (e EchoStmt) statementNode() {}
|
|
func (e EchoStmt) String() string { return fmt.Sprintf("echo %s", e.Value.String()) }
|
|
|
|
// UnaryExpr represents a unary operation
|
|
type UnaryExpr struct {
|
|
Operator Token
|
|
Right Expression
|
|
}
|
|
|
|
func (u UnaryExpr) expressionNode() {}
|
|
func (u UnaryExpr) String() string {
|
|
return fmt.Sprintf("(%s%s)", u.Operator.Lexeme, u.Right.String())
|
|
}
|
|
|
|
// BlockStmt represents a block of statements
|
|
type BlockStmt struct {
|
|
Statements []Statement
|
|
}
|
|
|
|
func (b BlockStmt) statementNode() {}
|
|
func (b BlockStmt) String() string {
|
|
return "{ ... }"
|
|
}
|