Skip to content

Commit

Permalink
Add SETY instruction. Add more tests for SETX.
Browse files Browse the repository at this point in the history
  • Loading branch information
aleury committed Jan 15, 2024
1 parent d7485a4 commit b7dcbef
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 2 deletions.
8 changes: 6 additions & 2 deletions gmachine.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ const (
OpMOVA
OpSETA
OpSETX
OpSETY
OpPSHA
OpPOPA
OpJUMP
Expand Down Expand Up @@ -70,6 +71,7 @@ var opcodes = map[string]Word{
"MOVA": OpMOVA,
"SETA": OpSETA,
"SETX": OpSETX,
"SETY": OpSETY,
"PSHA": OpPSHA,
"POPA": OpPOPA,
"JUMP": OpJUMP,
Expand Down Expand Up @@ -153,6 +155,8 @@ func (g *Machine) Run() {
g.A = g.Next()
case OpSETX:
g.X = g.Next()
case OpSETY:
g.Y = g.Next()
case OpPSHA:
g.Memory[g.S] = g.A
g.S++
Expand Down Expand Up @@ -293,12 +297,12 @@ func assembleOpcodeStatement(stmt *ast.OpcodeStatement, program []Word, refs []R
refs = append(refs, ref)
program = append(program, Word(0))
case *ast.IntegerLiteral:
if !slices.Contains([]Word{OpSETA, OpSETX, OpJUMP}, opcode) {
if !slices.Contains([]Word{OpSETA, OpSETX, OpSETY, OpJUMP}, opcode) {
return nil, nil, fmt.Errorf("%w: %s at line %d", ErrInvalidOperand, stmt.TokenLiteral(), stmt.Token.Line)
}
program = append(program, Word(operand.Value))
case *ast.CharacterLiteral:
if opcode != OpSETA {
if !slices.Contains([]Word{OpSETA, OpSETX, OpSETY}, opcode) {
return nil, nil, fmt.Errorf("%w: %s at line %d", ErrInvalidOperand, stmt.TokenLiteral(), stmt.Token.Line)
}
program = append(program, Word(operand.Value))
Expand Down
67 changes: 67 additions & 0 deletions gmachine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,19 @@ func TestSETX(t *testing.T) {
}
}

func TestSETY(t *testing.T) {
t.Parallel()
g := gmachine.New(nil)
var wantY gmachine.Word = 5
err := assembleAndRunFromString(g, "SETY 5")
if err != nil {
t.Fatal("didn't expect an error", err)
}
if wantY != g.Y {
t.Errorf("want Y value %d, got %d", wantY, g.Y)
}
}

func TestAssemble(t *testing.T) {
t.Parallel()
want := []gmachine.Word{gmachine.OpINCA, gmachine.OpHALT}
Expand Down Expand Up @@ -217,6 +230,32 @@ func TestSETA_ReturnsErrorForInvalidNumber(t *testing.T) {
}
}

func TestSETX_ReturnsErrorForInvalidNumber(t *testing.T) {
t.Parallel()
g := gmachine.New(nil)
err := assembleAndRunFromString(g, "SETX 2a")
wantErr := parser.ErrInvalidIntegerLiteral
if err == nil {
t.Fatal("expected an error to be returned for invalid argument to SETA")
}
if !errors.Is(err, wantErr) {
t.Errorf("wanted error %v, got %v", wantErr, err)
}
}

func TestSETY_ReturnsErrorForInvalidNumber(t *testing.T) {
t.Parallel()
g := gmachine.New(nil)
err := assembleAndRunFromString(g, "SETY 2a")
wantErr := parser.ErrInvalidIntegerLiteral
if err == nil {
t.Fatal("expected an error to be returned for invalid argument to SETA")
}
if !errors.Is(err, wantErr) {
t.Errorf("wanted error %v, got %v", wantErr, err)
}
}

func TestSETA_AcceptsCharacterLiteral(t *testing.T) {
t.Parallel()
g := gmachine.New(nil)
Expand All @@ -231,6 +270,34 @@ func TestSETA_AcceptsCharacterLiteral(t *testing.T) {
}
}

func TestSETX_AcceptsCharacterLiteral(t *testing.T) {
t.Parallel()
g := gmachine.New(nil)
err := assembleAndRunFromString(g, "SETX 'h'")
if err != nil {
t.Fatal("didn't expect an error:", err)
}
wantX := 'h'
gotX := rune(g.X)
if wantX != gotX {
t.Errorf("want X %d, got %d", wantX, gotX)
}
}

func TestSETY_AcceptsCharacterLiteral(t *testing.T) {
t.Parallel()
g := gmachine.New(nil)
err := assembleAndRunFromString(g, "SETY 'h'")
if err != nil {
t.Fatal("didn't expect an error:", err)
}
wantY := 'h'
gotY := rune(g.Y)
if wantY != gotY {
t.Errorf("want Y %d, got %d", wantY, gotY)
}
}

func TestOUTA_SerializesValueAsBytesInBigEndianOrder(t *testing.T) {
t.Parallel()

Expand Down
1 change: 1 addition & 0 deletions token/token.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ var opcodes = map[string]TokenType{
"MOVA": OPCODE,
"SETA": OPCODE,
"SETX": OPCODE,
"SETY": OPCODE,
"PSHA": OPCODE,
"POPA": OPCODE,
"JUMP": OPCODE,
Expand Down
2 changes: 2 additions & 0 deletions token/token_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ func TestLookupIdent(t *testing.T) {
{"MULA", token.OPCODE},
{"MOVA", token.OPCODE},
{"SETA", token.OPCODE},
{"SETX", token.OPCODE},
{"SETY", token.OPCODE},
{"PSHA", token.OPCODE},
{"POPA", token.OPCODE},
{"JUMP", token.OPCODE},
Expand Down

0 comments on commit b7dcbef

Please sign in to comment.