WIP fix sig case for uint
This commit is contained in:
parent
07555fee91
commit
be736c1ff6
125
go/asm/asm.go
125
go/asm/asm.go
@ -5,7 +5,9 @@ import (
|
|||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"log"
|
||||||
"math"
|
"math"
|
||||||
|
// "strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/alecthomas/participle/v2"
|
"github.com/alecthomas/participle/v2"
|
||||||
@ -22,25 +24,48 @@ type Asm struct {
|
|||||||
type Display struct {
|
type Display struct {
|
||||||
Sym string `@Sym Whitespace`
|
Sym string `@Sym Whitespace`
|
||||||
//Val string `Quote (@Desc @Whitespace?)+ Quote Whitespace`
|
//Val string `Quote (@Desc @Whitespace?)+ Quote Whitespace`
|
||||||
Val string `Quote (@Sym @Whitespace?)+ Quote Whitespace`
|
Val string `Quote (@Sym @Whitespace?)+ Quote Whitespace? EOL`
|
||||||
}
|
}
|
||||||
|
|
||||||
func(d Display) String() string {
|
func(d Display) String() string {
|
||||||
return fmt.Sprintf("Display: %v %v", d.Sym, d.Val)
|
return fmt.Sprintf("Display: %v %v", d.Sym, d.Val)
|
||||||
}
|
}
|
||||||
|
|
||||||
//type Sig struct {
|
type Sig struct {
|
||||||
// Sym string `@Sym Whitespace`
|
Sym string `@Sym Whitespace`
|
||||||
// Size uint32 `@Size Whitespace`
|
Size uint32 `@Size Whitespace`
|
||||||
// Val uint32 `@Size Whitespace`
|
Val uint8 `@Size Whitespace? EOL`
|
||||||
//}
|
}
|
||||||
//
|
//
|
||||||
//func(s Sig) String() string {
|
//func(s Sig) Capture(v []string) error {
|
||||||
// return fmt.Sprintf("Sig: %v %v %v", s.Sym, s.Size, s.Val)
|
// log.Printf("considering capture %v %v", v[0], len(v))
|
||||||
|
// if len(v) < 3 {
|
||||||
|
// return nil
|
||||||
|
// }
|
||||||
|
// s.Sym = v[0]
|
||||||
|
// r, err := strconv.Atoi(v[1])
|
||||||
|
// if err != nil {
|
||||||
|
// return err
|
||||||
|
// }
|
||||||
|
// s.Size = uint32(r)
|
||||||
|
// r, err = strconv.Atoi(v[2])
|
||||||
|
// if err != nil {
|
||||||
|
// return err
|
||||||
|
// }
|
||||||
|
// if r != 0 {
|
||||||
|
// r = 1
|
||||||
|
// }
|
||||||
|
// s.Val = uint8(r)
|
||||||
|
// log.Printf("after considering capture: %v", s)
|
||||||
|
// return nil
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
func(s Sig) String() string {
|
||||||
|
return fmt.Sprintf("Sig: %v %v %v", s.Sym, s.Size, s.Val)
|
||||||
|
}
|
||||||
|
|
||||||
type Single struct {
|
type Single struct {
|
||||||
One string `@Sym Whitespace`
|
One string `@Sym Whitespace? EOL`
|
||||||
}
|
}
|
||||||
|
|
||||||
func(s Single) String() string {
|
func(s Single) String() string {
|
||||||
@ -49,7 +74,7 @@ func(s Single) String() string {
|
|||||||
|
|
||||||
type Double struct {
|
type Double struct {
|
||||||
One string `@Sym Whitespace`
|
One string `@Sym Whitespace`
|
||||||
Two string `@Sym Whitespace`
|
Two string `@Sym Whitespace? EOL`
|
||||||
}
|
}
|
||||||
|
|
||||||
func(d Double) String() string {
|
func(d Double) String() string {
|
||||||
@ -58,8 +83,12 @@ func(d Double) String() string {
|
|||||||
|
|
||||||
type Sized struct {
|
type Sized struct {
|
||||||
Sym string `@Sym Whitespace`
|
Sym string `@Sym Whitespace`
|
||||||
Size uint32 `@Size Whitespace`
|
Size uint32 `@Size Whitespace? EOL`
|
||||||
X uint32 `(@Size Whitespace)?`
|
}
|
||||||
|
|
||||||
|
func(s Sized) Capture(v []Sized) error {
|
||||||
|
log.Printf("foofofofofo")
|
||||||
|
return fmt.Errorf("foo foo foo")
|
||||||
}
|
}
|
||||||
|
|
||||||
func(s Sized) String() string {
|
func(s Sized) String() string {
|
||||||
@ -67,9 +96,10 @@ func(s Sized) String() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Arg struct {
|
type Arg struct {
|
||||||
ArgNone string "Whitespace?"
|
ArgNone string "Discard?"
|
||||||
ArgDisplay *Display `@@?`
|
ArgDisplay *Display `@@?`
|
||||||
ArgSized *Sized `@@?`
|
ArgSized *Sized `@@?`
|
||||||
|
ArgSig *Sig `@@?`
|
||||||
ArgDouble *Double `@@?`
|
ArgDouble *Double `@@?`
|
||||||
ArgSingle *Single `@@?`
|
ArgSingle *Single `@@?`
|
||||||
}
|
}
|
||||||
@ -78,6 +108,9 @@ func (a Arg) String() string {
|
|||||||
if a.ArgDisplay != nil {
|
if a.ArgDisplay != nil {
|
||||||
return fmt.Sprintf("%s", a.ArgDisplay)
|
return fmt.Sprintf("%s", a.ArgDisplay)
|
||||||
}
|
}
|
||||||
|
if a.ArgSig != nil {
|
||||||
|
return fmt.Sprintf("%s", a.ArgSig)
|
||||||
|
}
|
||||||
if a.ArgSized != nil {
|
if a.ArgSized != nil {
|
||||||
return fmt.Sprintf("%s", a.ArgSized)
|
return fmt.Sprintf("%s", a.ArgSized)
|
||||||
}
|
}
|
||||||
@ -104,9 +137,12 @@ var (
|
|||||||
asmLexer = lexer.MustSimple([]lexer.SimpleRule{
|
asmLexer = lexer.MustSimple([]lexer.SimpleRule{
|
||||||
{"Comment", `(?:#)[^\n]*\n?`},
|
{"Comment", `(?:#)[^\n]*\n?`},
|
||||||
{"Ident", `^[A-Z]+`},
|
{"Ident", `^[A-Z]+`},
|
||||||
{"Sym", `[a-zA-Z0-9_]+`},
|
{"SizeSig", `[0-9]+\s+{?:[0-9]}`},
|
||||||
{"Size", `[0-9]+`},
|
{"Size", `[0-9]+`},
|
||||||
{"Whitespace", `[ \t\n\r]+`},
|
{"Sym", `[a-zA-Z_][a-zA-Z0-9_]+`},
|
||||||
|
{"Whitespace", `[ \t]+`},
|
||||||
|
{"Discard", `^\s+[\n\r]+$`},
|
||||||
|
{"EOL", `[\n\r]+`},
|
||||||
{"Quote", `["']`},
|
{"Quote", `["']`},
|
||||||
})
|
})
|
||||||
asmParser = participle.MustBuild[Asm](
|
asmParser = participle.MustBuild[Asm](
|
||||||
@ -155,7 +191,7 @@ func writeSize(n uint32, w *bytes.Buffer) (int, error) {
|
|||||||
w.Write([]byte{byte(sz)})
|
w.Write([]byte{byte(sz)})
|
||||||
binary.BigEndian.PutUint32(bn[:], n)
|
binary.BigEndian.PutUint32(bn[:], n)
|
||||||
c := 4-sz
|
c := 4-sz
|
||||||
return w.Write(bn[c:])
|
return w.Write(bn[c:])
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseSingle(op vm.Opcode, arg Arg, w io.Writer) (int, error) {
|
func parseSingle(op vm.Opcode, arg Arg, w io.Writer) (int, error) {
|
||||||
@ -294,6 +330,53 @@ func parseSized(op vm.Opcode, arg Arg, w io.Writer) (int, error) {
|
|||||||
return rn, err
|
return rn, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func parseSig(op vm.Opcode, arg Arg, w io.Writer) (int, error) {
|
||||||
|
var rn int
|
||||||
|
|
||||||
|
v := arg.ArgSig
|
||||||
|
if v == nil {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
b := bytes.NewBuffer(nil)
|
||||||
|
|
||||||
|
n, err := writeOpcode(op, b)
|
||||||
|
rn += n
|
||||||
|
if err != nil {
|
||||||
|
return rn, err
|
||||||
|
}
|
||||||
|
|
||||||
|
n, err = writeSym(v.Sym, b)
|
||||||
|
rn += n
|
||||||
|
if err != nil {
|
||||||
|
return rn, err
|
||||||
|
}
|
||||||
|
|
||||||
|
n, err = writeSize(v.Size, b)
|
||||||
|
rn += n
|
||||||
|
if err != nil {
|
||||||
|
return rn, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if v.Val == 0 {
|
||||||
|
n, err = b.Write([]byte{0x00})
|
||||||
|
} else {
|
||||||
|
n, err = b.Write([]byte{0x01})
|
||||||
|
}
|
||||||
|
rn += n
|
||||||
|
if err != nil {
|
||||||
|
return rn, err
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if w != nil {
|
||||||
|
rn, err = w.Write(b.Bytes())
|
||||||
|
} else {
|
||||||
|
rn = 0
|
||||||
|
}
|
||||||
|
return rn, err
|
||||||
|
}
|
||||||
|
|
||||||
func parseNoarg(op vm.Opcode, arg Arg, w io.Writer) (int, error) {
|
func parseNoarg(op vm.Opcode, arg Arg, w io.Writer) (int, error) {
|
||||||
var rn int
|
var rn int
|
||||||
|
|
||||||
@ -321,6 +404,7 @@ func Parse(s string, w io.Writer) (int, error) {
|
|||||||
|
|
||||||
var rn int
|
var rn int
|
||||||
for _, v := range ast.Instructions {
|
for _, v := range ast.Instructions {
|
||||||
|
log.Printf("parsing line %v: %v", v.OpCode, v.OpArg)
|
||||||
op := vm.OpcodeIndex[v.OpCode]
|
op := vm.OpcodeIndex[v.OpCode]
|
||||||
n, err := parseSized(op, v.OpArg, w)
|
n, err := parseSized(op, v.OpArg, w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -330,7 +414,6 @@ func Parse(s string, w io.Writer) (int, error) {
|
|||||||
rn += n
|
rn += n
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
n, err = parseDisplay(op, v.OpArg, w)
|
n, err = parseDisplay(op, v.OpArg, w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return n, err
|
return n, err
|
||||||
@ -339,6 +422,14 @@ func Parse(s string, w io.Writer) (int, error) {
|
|||||||
rn += n
|
rn += n
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
n, err = parseSig(op, v.OpArg, w)
|
||||||
|
if err != nil {
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
if n > 0 {
|
||||||
|
rn += n
|
||||||
|
continue
|
||||||
|
}
|
||||||
n, err = parseDouble(op, v.OpArg, w)
|
n, err = parseDouble(op, v.OpArg, w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return n, err
|
return n, err
|
||||||
|
@ -2,6 +2,7 @@ package asm
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"encoding/hex"
|
||||||
"log"
|
"log"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
@ -111,6 +112,31 @@ 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})
|
||||||
|
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 != 12 {
|
||||||
|
t.Fatalf("expected 12 byte write count, got %v", n)
|
||||||
|
}
|
||||||
|
rb := r.Bytes()
|
||||||
|
expect_hex := "000105706c75676802029a01"
|
||||||
|
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) {
|
func TestParseNoarg(t *testing.T) {
|
||||||
var b []byte
|
var b []byte
|
||||||
b = vm.NewLine(b, vm.HALT, nil, nil, nil)
|
b = vm.NewLine(b, vm.HALT, nil, nil, nil)
|
||||||
@ -138,7 +164,7 @@ func TestParserWriteMultiple(t *testing.T) {
|
|||||||
b = vm.NewLine(b, vm.CATCH, []string{"xyzzy"}, []byte{0x02, 0x9a}, []uint8{1})
|
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{"inky", "pinky"}, nil, nil)
|
||||||
b = vm.NewLine(b, vm.LOAD, []string{"foo"}, []byte{42}, nil)
|
b = vm.NewLine(b, vm.LOAD, []string{"foo"}, []byte{42}, nil)
|
||||||
b = vm.NewLine(b, vm.MOUT, []string{"bar", "barbarbaz"}, nil, nil)
|
b = vm.NewLine(b, vm.MOUT, []string{"bar", "bar barb az"}, nil, nil)
|
||||||
s, err := vm.ToString(b)
|
s, err := vm.ToString(b)
|
||||||
log.Printf("parsing:\n%s\n", s)
|
log.Printf("parsing:\n%s\n", s)
|
||||||
|
|
||||||
@ -148,11 +174,20 @@ func TestParserWriteMultiple(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
n_expect := 2 // halt
|
n_expect := 2 // halt
|
||||||
n_expect += 2 + 6 + 2 + 1 // catch
|
n_expect += 2 + 6 + 3 + 1 // catch
|
||||||
n_expect += 2 + 5 + 6 // incmp
|
n_expect += 2 + 5 + 6 // incmp
|
||||||
n_expect += 2 + 4 + 2 // load
|
n_expect += 2 + 4 + 2 // load
|
||||||
n_expect += 2 + 4 + 10 // mout
|
n_expect += 2 + 4 + 12 // mout
|
||||||
|
log.Printf("result %x", r.Bytes())
|
||||||
if n != n_expect {
|
if n != n_expect {
|
||||||
t.Fatalf("expected total %v bytes output, got %v", n_expect, n)
|
t.Fatalf("expected total %v bytes output, got %v", n_expect, n)
|
||||||
}
|
}
|
||||||
|
r_expect_hex := "000700010578797a7a7902029a000804696e6b790570696e6b79000303666f6f023432000a036261720b626172206261726220617a"
|
||||||
|
r_expect, err := hex.DecodeString(r_expect_hex)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if !bytes.Equal(r.Bytes(), r_expect) {
|
||||||
|
t.Fatalf("expected result %v, got %x", r_expect_hex, r.Bytes())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user