basic for loop + examples -> era3
This commit is contained in:
parent
dd7af341a3
commit
0bc8b2ef55
24 changed files with 222 additions and 201 deletions
|
|
@ -153,6 +153,7 @@ func (c *Compiler) add(instruction Bytecode) {
|
|||
c.advance(1)
|
||||
}
|
||||
|
||||
// addConstant add both a constant (if it is not already defined), and add the index of it to the bytecode
|
||||
func (c *Compiler) addConstant(value Value) {
|
||||
chunk := c.Chunk
|
||||
for i := 0; i < len(chunk.Constants); i++ {
|
||||
|
|
@ -165,6 +166,10 @@ func (c *Compiler) addConstant(value Value) {
|
|||
|
||||
chunk.Constants = append(chunk.Constants, value)
|
||||
|
||||
if len(chunk.Constants) > 256 {
|
||||
panic("too many constants (>256)")
|
||||
}
|
||||
|
||||
c.add(Bytecode(len(chunk.Constants) - 1))
|
||||
}
|
||||
|
||||
|
|
@ -472,7 +477,6 @@ func (c *Compiler) compile(tree Node) (TypeSignature, error) {
|
|||
c.add(InstructionJumpFalse)
|
||||
jumpValuePos = c.ip
|
||||
c.advance(2)
|
||||
|
||||
}
|
||||
|
||||
c.add(InstructionPop)
|
||||
|
|
@ -492,6 +496,74 @@ func (c *Compiler) compile(tree Node) (TypeSignature, error) {
|
|||
|
||||
return &CompositeSignature{dt, &NilSignature{}}, nil
|
||||
|
||||
case ForNodeType:
|
||||
n := tree.(*ForNode)
|
||||
|
||||
is, err := c.compile(n.iterator)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
iteratorSignature := &FunctionSignature{
|
||||
[]TypeSignature{},
|
||||
&TupleSignature{
|
||||
[]TypeSignature{
|
||||
&AnySignature{},
|
||||
&BooleanSignature{},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if !iteratorSignature.Contains(is) {
|
||||
return nil, c.error(fmt.Sprintf("cannot iterate with non-iterator %s (must be %s)", is, iteratorSignature), n.iterator)
|
||||
}
|
||||
|
||||
outputSig := is.(*FunctionSignature).Out.(*TupleSignature).Contents[0]
|
||||
ipos := c.ip
|
||||
|
||||
c.addDescend()
|
||||
c.add(InstructionDuplicate)
|
||||
c.add(InstructionCall)
|
||||
c.add(InstructionDestructureTuple)
|
||||
|
||||
// if no more items; jump to end
|
||||
c.add(InstructionJumpFalse)
|
||||
jmpValuePos := c.ip
|
||||
c.advance(2)
|
||||
|
||||
if n.counter.Type() != ReferenceNodeType {
|
||||
return nil, c.error("cannot use non-variable as a counter", n.counter)
|
||||
}
|
||||
|
||||
name := n.counter.(*ReferenceNode).name
|
||||
|
||||
c.add(InstructionDeclareLocal)
|
||||
c.addConstant(&StringValue{
|
||||
name,
|
||||
})
|
||||
c.add(InstructionPop)
|
||||
c.registerVar(name, outputSig)
|
||||
|
||||
_, err = c.compile(n.logic)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c.add(InstructionPop)
|
||||
|
||||
c.addAscend()
|
||||
|
||||
c.add(InstructionLoop)
|
||||
c.addU16(uint16(c.ip - ipos + 2))
|
||||
|
||||
// end of loop
|
||||
c.putU16(jmpValuePos, uint16(c.ip-jmpValuePos-2))
|
||||
|
||||
c.add(InstructionPop)
|
||||
c.add(InstructionPop)
|
||||
c.add(InstructionNil)
|
||||
|
||||
return &NilSignature{}, nil
|
||||
|
||||
case AssignNodeType:
|
||||
n := tree.(*AssignNode)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue