diff --git a/go/asm/asm.go b/go/asm/asm.go index 99d5b64..b13d6a7 100644 --- a/go/asm/asm.go +++ b/go/asm/asm.go @@ -294,6 +294,24 @@ func parseSized(op vm.Opcode, arg Arg, w io.Writer) (int, error) { return rn, err } +func parseNoarg(op vm.Opcode, arg Arg, w io.Writer) (int, error) { + var rn int + + b := bytes.NewBuffer(nil) + + n, err := writeOpcode(op, b) + rn += n + if err != nil { + return rn, err + } + if w != nil { + rn, err = w.Write(b.Bytes()) + } else { + rn = 0 + } + return rn, err +} + func Parse(s string, w io.Writer) (int, error) { rd := strings.NewReader(s) ast, err := asmParser.Parse("file", rd) @@ -334,6 +352,15 @@ func Parse(s string, w io.Writer) (int, error) { rn += n continue } + n, err = parseNoarg(op, v.OpArg, w) + if err != nil { + return n, err + } + if n > 0 { + rn += n + continue + } + } return rn, err } diff --git a/go/asm/asm_test.go b/go/asm/asm_test.go index af36c92..0380624 100644 --- a/go/asm/asm_test.go +++ b/go/asm/asm_test.go @@ -110,3 +110,49 @@ func TestParseSingle(t *testing.T) { t.Fatalf("expected %x, got %x", expect, rb) } } + +func TestParseNoarg(t *testing.T) { + var b []byte + b = vm.NewLine(b, vm.HALT, nil, nil, nil) + 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 != 2 { + t.Fatalf("expected 8 byte write count, got %v", n) + } + rb := r.Bytes() + expect := []byte{0x00, vm.HALT} + if !bytes.Equal(rb, expect) { + t.Fatalf("expected %x, got %x", expect, rb) + } +} + +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.LOAD, []string{"foo"}, []byte{42}, nil) + b = vm.NewLine(b, vm.MOUT, []string{"bar", "barbarbaz"}, nil, nil) + 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) + } + n_expect := 2 // halt + n_expect += 2 + 6 + 2 + 1 // catch + n_expect += 2 + 5 + 6 // incmp + n_expect += 2 + 4 + 2 // load + n_expect += 2 + 4 + 10 // mout + if n != n_expect { + t.Fatalf("expected total %v bytes output, got %v", n_expect, n) + } +}