Skip to content

Commit

Permalink
Added ArgumentParser
Browse files Browse the repository at this point in the history
  • Loading branch information
RealA10N committed Aug 2, 2024
1 parent ad730c2 commit f2fef9f
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 7 deletions.
60 changes: 60 additions & 0 deletions parse/argument.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package parse

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

type ArgumentNode struct {
Node
Type lex.Token
Register lex.Token
}

type ArgumentNodeParser struct{}

func ConsumeToken(v *TokenView, typ lex.TokenType) (tkn lex.Token, perr ParsingError) {
tknView, restView := v.Partition(1)
tkn, err := tknView.At(0)

if err != nil {
perr = EofError{Expected: lex.TypToken}
return
}

if tkn.Type != typ {
perr = UnexpectedTokenError{Expected: typ, Got: tkn}
return
}

*v = restView
return tkn, nil
}

func NewNodeFromBoundaryTokens(first, last lex.Token) Node {
return Node{
View: source.UnmanagedSourceView{
Start: first.View.Start,
End: last.View.End},
}
}

func (p ArgumentNodeParser) Parse(v *TokenView) (node ArgumentNode, err ParsingError) {
typ, err := ConsumeToken(v, lex.TypToken)
if err != nil {
return
}

reg, err := ConsumeToken(v, lex.RegToken)
if err != nil {
return
}

node = ArgumentNode{
Node: NewNodeFromBoundaryTokens(typ, reg),
Type: typ,
Register: reg,
}

return node, nil
}
36 changes: 36 additions & 0 deletions parse/argument_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package parse_test

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

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

func TestArgumentNodeParserSimpleCase(t *testing.T) {
p := parse.ArgumentNodeParser{}
v, ctx := source.NewSourceView("$i32 %0 .entry").Detach()

typView := v.Subview(0, 4)
regView := v.Subview(5, 7)
lblView := v.Subview(8, 14)
typTkn := lex.Token{Type: lex.TypToken, View: typView}
regTkn := lex.Token{Type: lex.RegToken, View: regView}
lblTkn := lex.Token{Type: lex.LblToken, View: lblView}
tkns := view.NewView[lex.Token, uint32]([]lex.Token{typTkn, regTkn, lblTkn})
expectedSubview := tkns.Subview(2, 3)

node, err := p.Parse(&tkns)
assert.Nil(t, err)
assert.Equal(t, expectedSubview, tkns)

assert.EqualValues(t, 0, node.View.Start)
assert.EqualValues(t, 7, node.View.End)
assert.Equal(t, "$i32 %0", string(node.View.Raw(ctx)))

assert.Equal(t, typTkn, node.Type)
assert.Equal(t, regTkn, node.Register)
}
7 changes: 0 additions & 7 deletions parse/base/node.go

This file was deleted.

28 changes: 28 additions & 0 deletions parse/error.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package parse

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

type ParsingError interface {
Error(source.SourceContext) string
}

type UnexpectedTokenError struct {
Expected lex.TokenType
Got lex.Token
}

func (err UnexpectedTokenError) Error(ctx source.SourceContext) string {
return fmt.Sprintf("expected %s token, but got %s", err.Expected.String(), err.Got.String(ctx))
}

type EofError struct {
Expected lex.TokenType
}

func (err EofError) Error(source.SourceContext) string {
return fmt.Sprintf("expected %s token, but file ended", err.Expected.String())
}
20 changes: 20 additions & 0 deletions parse/node.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package parse

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

"github.com/RealA10N/view"
)

type TokenView = view.View[lex.Token, uint32]
type UnmanagedTokenView = view.UnmanagedView[lex.Token, uint32]
type TokenViewContext = view.ViewContext[lex.Token]

type Node struct {
View source.UnmanagedSourceView
}

type NodeParser[T any] interface {
Parse(view TokenView) (T, error)
}

0 comments on commit f2fef9f

Please sign in to comment.