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
|
else
|
||||||
// final thing
|
// final thing
|
||||||
end
|
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
|
// FunctionStmt represents a function declaration
|
||||||
type FunctionStmt struct {
|
type FunctionStmt struct {
|
||||||
Name Token
|
Name Token
|
||||||
Params []Token
|
Params []Token
|
||||||
Body []Statement
|
IsVariadic bool
|
||||||
|
Body []Statement
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f FunctionStmt) statementNode() {}
|
func (f FunctionStmt) statementNode() {}
|
||||||
@ -105,9 +106,46 @@ func (f FunctionStmt) String() string {
|
|||||||
}
|
}
|
||||||
params += param.Lexeme
|
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)
|
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
|
// ReturnStmt represents a return statement
|
||||||
type ReturnStmt struct {
|
type ReturnStmt struct {
|
||||||
Keyword Token
|
Keyword Token
|
||||||
|
@ -34,6 +34,10 @@ const (
|
|||||||
OP_JUMP_IF_FALSE
|
OP_JUMP_IF_FALSE
|
||||||
OP_CALL
|
OP_CALL
|
||||||
OP_RETURN
|
OP_RETURN
|
||||||
|
OP_CLOSURE
|
||||||
|
OP_GET_UPVALUE
|
||||||
|
OP_SET_UPVALUE
|
||||||
|
OP_CLOSE_UPVALUE
|
||||||
)
|
)
|
||||||
|
|
||||||
// String returns the string representation of an OpCode
|
// 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_SET_GLOBAL", "OP_EQUAL", "OP_GREATER", "OP_LESS",
|
||||||
"OP_ADD", "OP_SUBTRACT", "OP_MULTIPLY", "OP_DIVIDE",
|
"OP_ADD", "OP_SUBTRACT", "OP_MULTIPLY", "OP_DIVIDE",
|
||||||
"OP_NOT", "OP_NEGATE", "OP_PRINT", "OP_JUMP",
|
"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]
|
return names[op]
|
||||||
}
|
}
|
||||||
@ -66,11 +71,18 @@ type Chunk struct {
|
|||||||
type Function struct {
|
type Function struct {
|
||||||
Name string
|
Name string
|
||||||
Arity int
|
Arity int
|
||||||
|
IsVariadic bool
|
||||||
Chunk *Chunk
|
Chunk *Chunk
|
||||||
|
Upvalues []Upvalue
|
||||||
LocalCount int
|
LocalCount int
|
||||||
UpvalueCount int
|
UpvalueCount int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Closure struct {
|
||||||
|
Function *Function
|
||||||
|
Upvalues []*Upvalue
|
||||||
|
}
|
||||||
|
|
||||||
// Environment represents a variable scope
|
// Environment represents a variable scope
|
||||||
type Environment struct {
|
type Environment struct {
|
||||||
Values map[string]Value
|
Values map[string]Value
|
||||||
@ -84,3 +96,9 @@ func NewEnvironment(enclosing *Environment) *Environment {
|
|||||||
Enclosing: enclosing,
|
Enclosing: enclosing,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Upvalue support for closures
|
||||||
|
type Upvalue struct {
|
||||||
|
Index uint8
|
||||||
|
IsLocal bool
|
||||||
|
}
|
||||||
|
@ -55,6 +55,7 @@ const (
|
|||||||
LEFT_PAREN // (
|
LEFT_PAREN // (
|
||||||
RIGHT_PAREN // )
|
RIGHT_PAREN // )
|
||||||
COMMA // ,
|
COMMA // ,
|
||||||
|
ELLIPSIS // ...
|
||||||
)
|
)
|
||||||
|
|
||||||
// String returns the string representation of the token type
|
// String returns the string representation of the token type
|
||||||
@ -96,4 +97,5 @@ var tokenNames = [...]string{
|
|||||||
LEFT_PAREN: "LEFT_PAREN",
|
LEFT_PAREN: "LEFT_PAREN",
|
||||||
RIGHT_PAREN: "RIGHT_PAREN",
|
RIGHT_PAREN: "RIGHT_PAREN",
|
||||||
COMMA: "COMMA",
|
COMMA: "COMMA",
|
||||||
|
ELLIPSIS: "ELLIPSIS",
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ const (
|
|||||||
STRING_TYPE
|
STRING_TYPE
|
||||||
FUNCTION_TYPE
|
FUNCTION_TYPE
|
||||||
TABLE_TYPE
|
TABLE_TYPE
|
||||||
|
CLOSURE_TYPE
|
||||||
)
|
)
|
||||||
|
|
||||||
// Value interface represents any value in the language at runtime
|
// Value interface represents any value in the language at runtime
|
||||||
@ -104,3 +105,18 @@ func (t TableValue) Type() ValueType {
|
|||||||
func (t TableValue) String() string {
|
func (t TableValue) String() string {
|
||||||
return fmt.Sprintf("<table: %p>", &t)
|
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