commit d6a03141321e3a1ea18510d2427a0255ef238423
parent 13bf7309e7048723e9a9d7eabcc7b69dc32c672c
Author: lash <dev@holbrook.no>
Date: Thu, 6 Apr 2023 08:38:30 +0100
Proper catch of CATCH and INCMP
Diffstat:
3 files changed, 88 insertions(+), 32 deletions(-)
diff --git a/go/asm/asm.go b/go/asm/asm.go
@@ -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,13 +47,17 @@ func parseDescType(b *bytes.Buffer, arg Arg) (int, error) {
selector = *arg.Selector
}
- n, err := writeSym(b, *arg.Sym)
- rn += n
- if err != nil {
- return rn, err
+ 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 selector != "" {
+ if arg.Sym != nil {
n, err := writeSym(b, *arg.Sym)
rn += n
if err != nil {
@@ -60,7 +65,15 @@ func parseDescType(b *bytes.Buffer, arg Arg) (int, error) {
}
}
- n, err = writeSym(b, *arg.Desc)
+ if selector != "" {
+ n, err := writeSym(b, *arg.Selector)
+ rn += n
+ if err != nil {
+ return rn, err
+ }
+ }
+
+ 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)
diff --git a/go/asm/asm_test.go b/go/asm/asm_test.go
@@ -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)
diff --git a/go/testdata/foo.fst b/go/testdata/foo.fst
@@ -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"