Proper catch of CATCH and INCMP
This commit is contained in:
parent
13bf7309e7
commit
d6a0314132
@ -39,6 +39,7 @@ func flush(b *bytes.Buffer, w io.Writer) (int, error) {
|
||||
func parseDescType(b *bytes.Buffer, arg Arg) (int, error) {
|
||||
var rn int
|
||||
var err error
|
||||
|
||||
var selector string
|
||||
if arg.Flag != nil {
|
||||
selector = strconv.FormatUint(uint64(*arg.Flag), 10)
|
||||
@ -46,21 +47,33 @@ func parseDescType(b *bytes.Buffer, arg Arg) (int, error) {
|
||||
selector = *arg.Selector
|
||||
}
|
||||
|
||||
var size string
|
||||
if arg.Size != nil {
|
||||
size = strconv.FormatUint(uint64(*arg.Size), 10)
|
||||
n, err := writeSym(b, size)
|
||||
rn += n
|
||||
if err != nil {
|
||||
return rn, err
|
||||
}
|
||||
}
|
||||
|
||||
if arg.Sym != nil {
|
||||
n, err := writeSym(b, *arg.Sym)
|
||||
rn += n
|
||||
if err != nil {
|
||||
return rn, err
|
||||
}
|
||||
}
|
||||
|
||||
if selector != "" {
|
||||
n, err := writeSym(b, *arg.Sym)
|
||||
n, err := writeSym(b, *arg.Selector)
|
||||
rn += n
|
||||
if err != nil {
|
||||
return rn, err
|
||||
}
|
||||
}
|
||||
|
||||
n, err = writeSym(b, *arg.Desc)
|
||||
n, err := writeSym(b, *arg.Desc)
|
||||
rn += n
|
||||
if err != nil {
|
||||
return rn, err
|
||||
@ -72,13 +85,23 @@ func parseDescType(b *bytes.Buffer, arg Arg) (int, error) {
|
||||
func parseTwoSym(b *bytes.Buffer, arg Arg) (int, error) {
|
||||
var rn int
|
||||
|
||||
n, err := writeSym(b, *arg.Sym)
|
||||
var selector string
|
||||
var sym string
|
||||
if arg.Size != nil {
|
||||
selector = strconv.FormatUint(uint64(*arg.Size), 10)
|
||||
sym = *arg.Selector
|
||||
} else if arg.Selector != nil {
|
||||
sym = *arg.Sym
|
||||
selector = *arg.Selector
|
||||
}
|
||||
|
||||
n, err := writeSym(b, selector)
|
||||
rn += n
|
||||
if err != nil {
|
||||
return rn, err
|
||||
}
|
||||
|
||||
n, err = writeSym(b, *arg.Selector)
|
||||
n, err = writeSym(b, sym)
|
||||
rn += n
|
||||
if err != nil {
|
||||
return rn, err
|
||||
@ -142,10 +165,7 @@ func parseOne(op vm.Opcode, instruction *Instruction, w io.Writer) (int, error)
|
||||
return n_out, err
|
||||
}
|
||||
|
||||
if a.Sym == nil {
|
||||
return flush(b, w)
|
||||
}
|
||||
|
||||
// Catch MOUT
|
||||
if a.Desc != nil {
|
||||
n, err := parseDescType(b, a)
|
||||
n_buf += n
|
||||
@ -155,7 +175,9 @@ func parseOne(op vm.Opcode, instruction *Instruction, w io.Writer) (int, error)
|
||||
return flush(b, w)
|
||||
}
|
||||
|
||||
// Catch
|
||||
if a.Selector != nil {
|
||||
log.Printf("entering twosym for %v", op)
|
||||
n, err := parseTwoSym(b, a)
|
||||
n_buf += n
|
||||
if err != nil {
|
||||
@ -164,6 +186,7 @@ func parseOne(op vm.Opcode, instruction *Instruction, w io.Writer) (int, error)
|
||||
return flush(b, w)
|
||||
}
|
||||
|
||||
// Catch CATCH, LOAD
|
||||
if a.Size != nil {
|
||||
if a.Flag != nil {
|
||||
n, err := parseSig(b, a)
|
||||
@ -181,6 +204,11 @@ func parseOne(op vm.Opcode, instruction *Instruction, w io.Writer) (int, error)
|
||||
return flush(b, w)
|
||||
}
|
||||
|
||||
// Catch HALT
|
||||
if a.Sym == nil {
|
||||
return flush(b, w)
|
||||
}
|
||||
|
||||
n, err = writeSym(b, *a.Sym)
|
||||
n_buf += n
|
||||
return flush(b, w)
|
||||
@ -236,7 +264,7 @@ var (
|
||||
|
||||
func numSize(n uint32) int {
|
||||
v := math.Log2(float64(n))
|
||||
return int(((v - 1) / 8) + 1)
|
||||
return int((v / 8) + 1)
|
||||
}
|
||||
|
||||
func writeOpcode(w *bytes.Buffer, op vm.Opcode) (int, error) {
|
||||
@ -287,26 +315,31 @@ func NewBatcher(mp MenuProcessor) Batcher {
|
||||
}
|
||||
}
|
||||
|
||||
func(b *Batcher) MenuExit(w io.Writer) (int, error) {
|
||||
if !b.inMenu {
|
||||
func(bt *Batcher) MenuExit(w io.Writer) (int, error) {
|
||||
if !bt.inMenu {
|
||||
return 0, nil
|
||||
}
|
||||
b.inMenu = false
|
||||
return w.Write(b.menuProcessor.ToLines())
|
||||
bt.inMenu = false
|
||||
b := bt.menuProcessor.ToLines()
|
||||
log.Printf("tolines %v", b)
|
||||
return w.Write(b)
|
||||
}
|
||||
|
||||
func(b *Batcher) MenuAdd(w io.Writer, code string, arg Arg) (int, error) {
|
||||
b.inMenu = true
|
||||
selector := ""
|
||||
if arg.Selector != nil {
|
||||
func(bt *Batcher) MenuAdd(w io.Writer, code string, arg Arg) (int, error) {
|
||||
bt.inMenu = true
|
||||
var selector string
|
||||
if arg.Size != nil {
|
||||
selector = strconv.FormatUint(uint64(*arg.Size), 10)
|
||||
} else if arg.Selector != nil {
|
||||
selector = *arg.Selector
|
||||
}
|
||||
err := b.menuProcessor.Add(code, *arg.Sym, selector, *arg.Desc)
|
||||
log.Printf("menu processor add %v '%v' '%v' '%v'", code, *arg.Sym, selector, *arg.Desc)
|
||||
err := bt.menuProcessor.Add(code, *arg.Sym, selector, *arg.Desc)
|
||||
return 0, err
|
||||
}
|
||||
|
||||
func(b *Batcher) Exit(w io.Writer) (int, error) {
|
||||
return b.MenuExit(w)
|
||||
func(bt *Batcher) Exit(w io.Writer) (int, error) {
|
||||
return bt.MenuExit(w)
|
||||
}
|
||||
|
||||
func Parse(s string, w io.Writer) (int, error) {
|
||||
@ -341,6 +374,7 @@ func Parse(s string, w io.Writer) (int, error) {
|
||||
if err != nil {
|
||||
return rn, err
|
||||
}
|
||||
log.Printf("wrote %v bytes for %v", n, v.OpArg)
|
||||
}
|
||||
}
|
||||
n, err := batch.Exit(w)
|
||||
|
@ -73,7 +73,7 @@ func TestParseDisplay(t *testing.T) {
|
||||
|
||||
func TestParseDouble(t *testing.T) {
|
||||
var b []byte
|
||||
b = vm.NewLine(b, vm.INCMP, []string{"foo", "bar"}, nil, nil)
|
||||
b = vm.NewLine(b, vm.INCMP, []string{"bar", "foo"}, nil, nil)
|
||||
s, err := vm.ToString(b)
|
||||
log.Printf("parsing:\n%s\n", s)
|
||||
|
||||
@ -144,8 +144,7 @@ func TestParseSingle(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestParseSig(t *testing.T) {
|
||||
var b []byte
|
||||
b = vm.NewLine(b, vm.CATCH, []string{"plugh"}, []byte{0x02, 0x9a}, []uint8{0x2a})
|
||||
b := vm.NewLine(nil, vm.CATCH, []string{"plugh"}, []byte{0x02, 0x9a}, []uint8{0x2a})
|
||||
s, err := vm.ToString(b)
|
||||
log.Printf("parsing:\n%s\n", s)
|
||||
|
||||
@ -166,6 +165,28 @@ func TestParseSig(t *testing.T) {
|
||||
if !bytes.Equal(rb, expect) {
|
||||
t.Fatalf("expected %v, got %x", expect_hex, rb)
|
||||
}
|
||||
|
||||
b = vm.NewLine(nil, vm.CATCH, []string{"plugh"}, []byte{0x01}, []uint8{0x0})
|
||||
s, err = vm.ToString(b)
|
||||
log.Printf("parsing:\n%s\n", s)
|
||||
|
||||
r = bytes.NewBuffer(nil)
|
||||
n, err = Parse(s, r)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if n != 11 {
|
||||
t.Fatalf("expected 11 byte write count, got %v", n)
|
||||
}
|
||||
rb = r.Bytes()
|
||||
expect_hex = "000105706c756768010100"
|
||||
expect, err = hex.DecodeString(expect_hex)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(rb, expect) {
|
||||
t.Fatalf("expected %v, got %x", expect_hex, rb)
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseNoarg(t *testing.T) {
|
||||
@ -193,7 +214,7 @@ func TestParserWriteMultiple(t *testing.T) {
|
||||
var b []byte
|
||||
b = vm.NewLine(b, vm.HALT, nil, nil, nil)
|
||||
b = vm.NewLine(b, vm.CATCH, []string{"xyzzy"}, []byte{0x02, 0x9a}, []uint8{1})
|
||||
b = vm.NewLine(b, vm.INCMP, []string{"inky", "pinky"}, nil, nil)
|
||||
b = vm.NewLine(b, vm.INCMP, []string{"pinky", "inky"}, nil, nil)
|
||||
b = vm.NewLine(b, vm.LOAD, []string{"foo"}, []byte{42}, nil)
|
||||
b = vm.NewLine(b, vm.MOUT, []string{"bar", "bar barb az"}, nil, nil)
|
||||
s, err := vm.ToString(b)
|
||||
|
9
go/testdata/foo.fst
vendored
9
go/testdata/foo.fst
vendored
@ -1,7 +1,8 @@
|
||||
MOUT 0 "to foo"
|
||||
MOUT 1 "go bar"
|
||||
MOUT 1 "to foo"
|
||||
MOUT 2 "go bar"
|
||||
LOAD inky 20
|
||||
HALT
|
||||
INCMP 0 _
|
||||
INCMP 1 baz
|
||||
INCMP 1 _
|
||||
INCMP 2 baz
|
||||
CATCH _catch 1 1
|
||||
DOWN foofoo 1 "go to foo"
|
||||
|
Loading…
Reference in New Issue
Block a user