functions now capture variables :D
This commit is contained in:
parent
43e450c207
commit
d315a53fbd
5 changed files with 49 additions and 11 deletions
|
|
@ -587,6 +587,7 @@ func (c *Compiler) compile(tree Node) error {
|
||||||
n.yield,
|
n.yield,
|
||||||
c.Chunk,
|
c.Chunk,
|
||||||
nil,
|
nil,
|
||||||
|
nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
// restore old chunk and ip
|
// restore old chunk and ip
|
||||||
|
|
@ -958,6 +959,13 @@ func (c *Compiler) deduceSignature(tree Node) (TypeSignature, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, c.error(fmt.Sprintf("unimplemented result type deduction for unary %s", n.UnaryOperation), n)
|
return nil, c.error(fmt.Sprintf("unimplemented result type deduction for unary %s", n.UnaryOperation), n)
|
||||||
|
case BlockNodeType:
|
||||||
|
n := tree.(*BlockNode)
|
||||||
|
if len(n.statements) == 0 {
|
||||||
|
return &NilSignature{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.deduceSignature(n.statements[len(n.statements)-1])
|
||||||
default:
|
default:
|
||||||
return nil, c.error(fmt.Sprintf("impossible to deduce signature of %s", tree.Type()), tree)
|
return nil, c.error(fmt.Sprintf("impossible to deduce signature of %s", tree.Type()), tree)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1387,9 +1387,15 @@ func (p *Parser) parseSignature() (TypeSignature, error) {
|
||||||
in = append(in, sig)
|
in = append(in, sig)
|
||||||
}
|
}
|
||||||
|
|
||||||
out, err := p.parseSignature()
|
var out TypeSignature
|
||||||
if err != nil {
|
var err error
|
||||||
return nil, err
|
if p.accept(TokenArrow) {
|
||||||
|
out, err = p.parseSignature()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
out = &NilSignature{}
|
||||||
}
|
}
|
||||||
|
|
||||||
s = &FunctionSignature{
|
s = &FunctionSignature{
|
||||||
|
|
|
||||||
|
|
@ -603,6 +603,7 @@ type FunctionValue struct {
|
||||||
Yield TypeSignature
|
Yield TypeSignature
|
||||||
Chunk *Chunk
|
Chunk *Chunk
|
||||||
Parent Value
|
Parent Value
|
||||||
|
Scope *Scope
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *FunctionValue) Type() ValueType {
|
func (v *FunctionValue) Type() ValueType {
|
||||||
|
|
@ -633,6 +634,7 @@ func (v *FunctionValue) Clone() Value {
|
||||||
v.Yield,
|
v.Yield,
|
||||||
v.Chunk,
|
v.Chunk,
|
||||||
v.Parent,
|
v.Parent,
|
||||||
|
v.Scope,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
20
core/vm.go
20
core/vm.go
|
|
@ -698,7 +698,13 @@ func (vm *VM) Next() bool {
|
||||||
vm.stack.Pop()
|
vm.stack.Pop()
|
||||||
|
|
||||||
case InstructionConstant:
|
case InstructionConstant:
|
||||||
vm.stack.Push(vm.ReadConstant())
|
c := vm.ReadConstant()
|
||||||
|
|
||||||
|
if c, ok := c.(*FunctionValue); ok {
|
||||||
|
c.Scope = vm.scope
|
||||||
|
}
|
||||||
|
|
||||||
|
vm.stack.Push(c)
|
||||||
|
|
||||||
case InstructionAddFloat:
|
case InstructionAddFloat:
|
||||||
r := vm.stack.Pop().(*FloatValue).Number
|
r := vm.stack.Pop().(*FloatValue).Number
|
||||||
|
|
@ -840,6 +846,7 @@ func (vm *VM) Next() bool {
|
||||||
scope: vm.scope,
|
scope: vm.scope,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
vm.scope = f.Scope
|
||||||
vm.descend()
|
vm.descend()
|
||||||
|
|
||||||
for i := len(f.Params) - 1; i >= 0; i-- {
|
for i := len(f.Params) - 1; i >= 0; i-- {
|
||||||
|
|
@ -993,6 +1000,15 @@ func (vm *VM) Next() bool {
|
||||||
vm.stack.Push(member)
|
vm.stack.Push(member)
|
||||||
|
|
||||||
case InstructionBreakpoint:
|
case InstructionBreakpoint:
|
||||||
|
/*
|
||||||
|
// I'm keeping this
|
||||||
|
s := vm.scope
|
||||||
|
log.Printf("breakpoint %d", vm.ip)
|
||||||
|
for s != nil {
|
||||||
|
log.Printf("%s", s.current)
|
||||||
|
s = s.parent
|
||||||
|
}
|
||||||
|
*/
|
||||||
vm.stack.Push(&NilValue{})
|
vm.stack.Push(&NilValue{})
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
@ -1122,7 +1138,7 @@ func (vm *VM) HasNext() bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (vm *VM) GetConstant(id Bytecode) Value {
|
func (vm *VM) GetConstant(id Bytecode) Value {
|
||||||
return vm.chunk.Constants[id]
|
return vm.chunk.Constants[id].Clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (vm *VM) ReadConstant() Value {
|
func (vm *VM) ReadConstant() Value {
|
||||||
|
|
|
||||||
18
era3.ang
18
era3.ang
|
|
@ -1,10 +1,16 @@
|
||||||
|
fn counter() -> (fn() -> int) {
|
||||||
|
i := 0
|
||||||
|
|
||||||
fn double(a: int) -> int {
|
fn() -> int {
|
||||||
2*a
|
i = i + 1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
a := 1
|
next := counter()
|
||||||
|
other := counter()
|
||||||
|
|
||||||
a = 2
|
println(next())
|
||||||
|
println(next())
|
||||||
println(double(2) == 4)
|
println(other())
|
||||||
|
println(other())
|
||||||
|
println(next())
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue