closures/anon

This commit is contained in:
Sky Johnson 2025-05-07 08:26:49 -05:00
parent f1ac9b1657
commit d4aa7cc282
5 changed files with 88 additions and 4 deletions

View File

@ -41,4 +41,14 @@ elseif otherExpression() then
else
// final thing
end
// Table order is preserved, unlike Lua
table = {
anything = "foo",
123 = "arg"
}
echo table["anything"] // outputs foo
echo table.anything // outputs foo
table.rawr = "mega"
table["mega"] = "rawr"
```

View File

@ -91,9 +91,10 @@ func (a AssignStmt) String() string {
// FunctionStmt represents a function declaration
type FunctionStmt struct {
Name Token
Params []Token
Body []Statement
Name Token
Params []Token
IsVariadic bool
Body []Statement
}
func (f FunctionStmt) statementNode() {}
@ -105,9 +106,46 @@ func (f FunctionStmt) String() string {
}
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

View File

@ -34,6 +34,10 @@ const (
OP_JUMP_IF_FALSE
OP_CALL
OP_RETURN
OP_CLOSURE
OP_GET_UPVALUE
OP_SET_UPVALUE
OP_CLOSE_UPVALUE
)
// String returns the string representation of an OpCode
@ -44,7 +48,8 @@ func (op OpCode) String() string {
"OP_SET_GLOBAL", "OP_EQUAL", "OP_GREATER", "OP_LESS",
"OP_ADD", "OP_SUBTRACT", "OP_MULTIPLY", "OP_DIVIDE",
"OP_NOT", "OP_NEGATE", "OP_PRINT", "OP_JUMP",
"OP_JUMP_IF_FALSE", "OP_CALL", "OP_RETURN",
"OP_JUMP_IF_FALSE", "OP_CALL", "OP_RETURN", "OP_CLOSURE",
"OP_GET_UPVALUE", "OP_SET_UPVALUE", "OP_CLOSE_UPVALUE",
}
return names[op]
}
@ -66,11 +71,18 @@ type Chunk struct {
type Function struct {
Name string
Arity int
IsVariadic bool
Chunk *Chunk
Upvalues []Upvalue
LocalCount int
UpvalueCount int
}
type Closure struct {
Function *Function
Upvalues []*Upvalue
}
// Environment represents a variable scope
type Environment struct {
Values map[string]Value
@ -84,3 +96,9 @@ func NewEnvironment(enclosing *Environment) *Environment {
Enclosing: enclosing,
}
}
// Upvalue support for closures
type Upvalue struct {
Index uint8
IsLocal bool
}

View File

@ -55,6 +55,7 @@ const (
LEFT_PAREN // (
RIGHT_PAREN // )
COMMA // ,
ELLIPSIS // ...
)
// String returns the string representation of the token type
@ -96,4 +97,5 @@ var tokenNames = [...]string{
LEFT_PAREN: "LEFT_PAREN",
RIGHT_PAREN: "RIGHT_PAREN",
COMMA: "COMMA",
ELLIPSIS: "ELLIPSIS",
}

View File

@ -12,6 +12,7 @@ const (
STRING_TYPE
FUNCTION_TYPE
TABLE_TYPE
CLOSURE_TYPE
)
// Value interface represents any value in the language at runtime
@ -104,3 +105,18 @@ func (t TableValue) Type() ValueType {
func (t TableValue) String() string {
return fmt.Sprintf("<table: %p>", &t)
}
type ClosureValue struct {
Closure *Closure
}
func (c ClosureValue) Type() ValueType {
return CLOSURE_TYPE
}
func (c ClosureValue) String() string {
if c.Closure.Function.Name == "" {
return "<anonymous function>"
}
return fmt.Sprintf("<function %s>", c.Closure.Function.Name)
}