Skip to content

Commit

Permalink
Added InstructionNode (Stringer only)
Browse files Browse the repository at this point in the history
  • Loading branch information
RealA10N committed Aug 2, 2024
1 parent 2e7e739 commit 1893059
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 0 deletions.
33 changes: 33 additions & 0 deletions parse/caller_argument.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package parse

import (
"usm/lex"
"usm/source"
)

// TODO: this should be a tagged union.
// The supported caller arguments are registers, globals, immediates (and labales?)

type CallerArgumentNode struct {
source.UnmanagedSourceView
}

func (n CallerArgumentNode) View() source.UnmanagedSourceView {
return n.UnmanagedSourceView
}

func (n CallerArgumentNode) String(ctx source.SourceContext) string {
return string(n.UnmanagedSourceView.Raw(ctx))
}

type CallerArgumentParser struct{}

func (CallerArgumentParser) Parse(v *TokenView) (node CallerArgumentNode, err ParsingError) {
tkn, err := ConsumeToken(v, lex.OprToken)
if err != nil {
return
}

node = CallerArgumentNode{tkn.View}
return
}
56 changes: 56 additions & 0 deletions parse/instruction.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package parse

import (
"usm/source"
)

type InstructionNode struct {
Operation source.UnmanagedSourceView
Arguments []CallerArgumentNode
Targets []RegisterNode
}

func (n InstructionNode) View() source.UnmanagedSourceView {
first := n.Operation
last := n.Operation

if len(n.Targets) > 0 {
first = n.Targets[0].View()
}

if len(n.Arguments) > 0 {
last = n.Arguments[len(n.Arguments)-1].View()
}

return first.Merge(last)
}

func (n InstructionNode) stringArguments(ctx source.SourceContext) (s string) {
if len(n.Arguments) == 0 {
return
}

for _, arg := range n.Arguments {
s += " " + arg.String(ctx)
}

return
}

func (n InstructionNode) stringTargets(ctx source.SourceContext) (s string) {
if len(n.Targets) == 0 {
return
}

for _, tgt := range n.Targets {
s += tgt.String(ctx) + " "
}

s += "= "
return
}

func (n InstructionNode) String(ctx source.SourceContext) string {
op := string(n.Operation.Raw(ctx))
return n.stringTargets(ctx) + op + n.stringArguments(ctx)
}
28 changes: 28 additions & 0 deletions parse/instruction_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package parse_test

import (
"testing"
"usm/parse"
"usm/source"

"github.com/stretchr/testify/assert"
)

func TestInstructionStringer(t *testing.T) {
inst := "%div %mod = divmod %x %y"
v, ctx := source.NewSourceView(inst).Detach()

node := parse.InstructionNode{
Operation: v.Subview(12, 18),
Arguments: []parse.CallerArgumentNode{
parse.CallerArgumentNode{v.Subview(19, 21)},
parse.CallerArgumentNode{v.Subview(22, 24)},
},
Targets: []parse.RegisterNode{
parse.RegisterNode{v.Subview(0, 4)},
parse.RegisterNode{v.Subview(5, 9)},
},
}

assert.Equal(t, inst, node.String(ctx))
}

0 comments on commit 1893059

Please sign in to comment.