fix if result typing + fix indexing
This commit is contained in:
parent
0bc8b2ef55
commit
7cb2be8415
2 changed files with 38 additions and 15 deletions
|
|
@ -437,8 +437,10 @@ func (c *Compiler) compile(tree Node) (TypeSignature, error) {
|
||||||
|
|
||||||
c.putU16(jumpOverElse, uint16(c.ip-jumpOverElse-2))
|
c.putU16(jumpOverElse, uint16(c.ip-jumpOverElse-2))
|
||||||
|
|
||||||
if dot.Equal(ot) {
|
if dot.Contains(ot) {
|
||||||
return dot, nil
|
return dot, nil
|
||||||
|
} else if ot.Contains(dot) {
|
||||||
|
return ot, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return &CompositeSignature{
|
return &CompositeSignature{
|
||||||
|
|
@ -745,6 +747,15 @@ func (c *Compiler) compile(tree Node) (TypeSignature, error) {
|
||||||
|
|
||||||
st = c.resolveType(st)
|
st = c.resolveType(st)
|
||||||
|
|
||||||
|
it, err := c.compile(n.index)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if it.Type() != TypeInteger {
|
||||||
|
return nil, c.error(fmt.Sprintf("can only index with integers (got %s, nice try)", it), n.index)
|
||||||
|
}
|
||||||
|
|
||||||
var output TypeSignature
|
var output TypeSignature
|
||||||
switch st.Type() {
|
switch st.Type() {
|
||||||
case TypeList:
|
case TypeList:
|
||||||
|
|
@ -762,7 +773,7 @@ func (c *Compiler) compile(tree Node) (TypeSignature, error) {
|
||||||
in := n.index.(*IntegerNode)
|
in := n.index.(*IntegerNode)
|
||||||
|
|
||||||
i := in.value.Int64()
|
i := in.value.Int64()
|
||||||
if i < 0 || i >= int64(len(sig.Contents)) {
|
if i < 0 || int64(len(sig.Contents)) <= i {
|
||||||
return nil, c.error(fmt.Sprintf("cannot index outside of tuple (%d items)", len(sig.Contents)), n.source)
|
return nil, c.error(fmt.Sprintf("cannot index outside of tuple (%d items)", len(sig.Contents)), n.source)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -780,19 +791,15 @@ func (c *Compiler) compile(tree Node) (TypeSignature, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c.add(InstructionIndexTuple)
|
||||||
|
case TypeString:
|
||||||
|
output = &StringSignature{}
|
||||||
|
c.add(InstructionIndexString)
|
||||||
default:
|
default:
|
||||||
return nil, c.error(fmt.Sprintf("cannot index into value of type %s", st), n.source)
|
return nil, c.error(fmt.Sprintf("cannot index into value of type %s", st), n.source)
|
||||||
}
|
}
|
||||||
|
|
||||||
it, err := c.compile(n.index)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if it.Type() != TypeInteger {
|
|
||||||
return nil, c.error(fmt.Sprintf("can only index with integers (got %s, nice try)", it), n.index)
|
|
||||||
}
|
|
||||||
|
|
||||||
return output, nil
|
return output, nil
|
||||||
|
|
||||||
case BreakpointNodeType:
|
case BreakpointNodeType:
|
||||||
|
|
|
||||||
24
core/vm.go
24
core/vm.go
|
|
@ -143,6 +143,10 @@ const (
|
||||||
// InstructionIndexTuple index into a tuple. The lower item is the container, and the top item
|
// InstructionIndexTuple index into a tuple. The lower item is the container, and the top item
|
||||||
// is the index. [..., container, index] -> [..., item]
|
// is the index. [..., container, index] -> [..., item]
|
||||||
InstructionIndexTuple
|
InstructionIndexTuple
|
||||||
|
// InstructionIndexString index into a string. The lower item is the container, and the top item
|
||||||
|
// is the index. [..., container, index] -> [..., item]. Produces a new string with the character
|
||||||
|
// at the position
|
||||||
|
InstructionIndexString
|
||||||
|
|
||||||
// InstructionBreakpoint for debugging purposes
|
// InstructionBreakpoint for debugging purposes
|
||||||
InstructionBreakpoint
|
InstructionBreakpoint
|
||||||
|
|
@ -1070,7 +1074,7 @@ func (vm *VM) Next() bool {
|
||||||
|
|
||||||
n := int(i.Number.Int64())
|
n := int(i.Number.Int64())
|
||||||
|
|
||||||
if 0 < n || n >= 10 {
|
if n < 0 || len(l.Items) <= n {
|
||||||
vm.error(fmt.Sprintf("index %d out of bounds", n))
|
vm.error(fmt.Sprintf("index %d out of bounds", n))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1078,15 +1082,27 @@ func (vm *VM) Next() bool {
|
||||||
|
|
||||||
case InstructionIndexTuple:
|
case InstructionIndexTuple:
|
||||||
i := vm.Stack.Pop().(*IntegerValue)
|
i := vm.Stack.Pop().(*IntegerValue)
|
||||||
l := vm.Stack.Pop().(*TupleValue)
|
t := vm.Stack.Pop().(*TupleValue)
|
||||||
|
|
||||||
n := int(i.Number.Int64())
|
n := int(i.Number.Int64())
|
||||||
|
|
||||||
if 0 < n || n >= len(l.Items) {
|
if n < 0 || len(t.Items) <= n {
|
||||||
vm.error(fmt.Sprintf("index %d out of bounds", n))
|
vm.error(fmt.Sprintf("index %d out of bounds", n))
|
||||||
}
|
}
|
||||||
|
|
||||||
vm.Stack.Push(l.Items[n].Clone())
|
vm.Stack.Push(t.Items[n].Clone())
|
||||||
|
|
||||||
|
case InstructionIndexString:
|
||||||
|
i := vm.Stack.Pop().(*IntegerValue)
|
||||||
|
s := vm.Stack.Pop().(*StringValue)
|
||||||
|
|
||||||
|
n := int(i.Number.Int64())
|
||||||
|
|
||||||
|
if n < 0 || len(s.Text) <= n {
|
||||||
|
vm.error(fmt.Sprintf("index %d out of bounds", n))
|
||||||
|
}
|
||||||
|
|
||||||
|
vm.Stack.Push(&StringValue{string(s.Text[n])})
|
||||||
|
|
||||||
case InstructionBreakpoint:
|
case InstructionBreakpoint:
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue