closures/anon
This commit is contained in:
parent
f1ac9b1657
commit
d4aa7cc282
10
README.md
10
README.md
@ -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"
|
||||
```
|
||||
|
44
types/ast.go
44
types/ast.go
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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",
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user