diff --git a/parse/block.go b/parse/block.go index 68f6f62..de9d47e 100644 --- a/parse/block.go +++ b/parse/block.go @@ -37,7 +37,7 @@ func (p BlockParser[NodeT]) String() string { } func (p BlockParser[NodeT]) Parse(v *TokenView) (block BlockNode[NodeT], err ParsingError) { - leftCurly, err := v.ConsumeToken(lex.LeftCurlyBraceToken) + leftCurly, err := v.ConsumeTokenIgnoreSeparator(lex.LeftCurlyBraceToken) if err != nil { return @@ -46,7 +46,7 @@ func (p BlockParser[NodeT]) Parse(v *TokenView) (block BlockNode[NodeT], err Par block.Start = leftCurly.View.Start block.Nodes = ParseMany(p.Parser, v) - rightCurly, err := v.ConsumeToken(lex.RightCurlyBraceToken) + rightCurly, err := v.ConsumeTokenIgnoreSeparator(lex.RightCurlyBraceToken) if err != nil { return } diff --git a/parse/file_test.go b/parse/file_test.go index 8fa5463..407f927 100644 --- a/parse/file_test.go +++ b/parse/file_test.go @@ -76,39 +76,48 @@ func TestSingleFunction(t *testing.T) { } func TestFileParserTwoFunctionsNoExtraSeparator(t *testing.T) { - src := `function @first = - ret + src := `function @first = { ret } function @second = -ret` +{ +ret + }` - expected := `function @first = + expected := `function @first = { ret +} -function @second = +function @second = { ret +} ` testFormattedFile(t, src, expected) } func TestFileWithLabels(t *testing.T) { - src := `function $32 @fib $i32 %n = - jle %n $32 #1 .return + src := ` +function $32 @fib $i32 %n = +{ + + jle %n $32 #1 .return %n = dec %n %a = call @fib %n %n = dec %n - %b = call @fib %n + %b = call @fib %n %n = add %a %b -.return - ret %n` - expected := `function $32 @fib $i32 %n = +.return ret %n } +` + + expected := `function $32 @fib $i32 %n = { jle %n $32 #1 .return %n = dec %n %a = call @fib %n %n = dec %n %b = call @fib %n %n = add %a %b - .return ret %n +.return + ret %n +} ` testFormattedFile(t, src, expected) } diff --git a/parse/function.go b/parse/function.go index 456ab89..e911719 100644 --- a/parse/function.go +++ b/parse/function.go @@ -33,7 +33,7 @@ func (FunctionParser) String() string { } func (FunctionParser) parseFunctionKeyword(v *TokenView, node *FunctionNode) ParsingError { - kw, err := v.ConsumeToken(lex.FunctionKeywordToken) + kw, err := v.ConsumeTokenIgnoreSeparator(lex.FunctionKeywordToken) if err != nil { return err } diff --git a/parse/instruction.go b/parse/instruction.go index 59123d3..8e0873d 100644 --- a/parse/instruction.go +++ b/parse/instruction.go @@ -92,7 +92,6 @@ func (InstructionParser) parseOperator(v *TokenView, node *InstructionNode) Pars // // > Lbl* (Reg+ Eql)? Opr Arg+ !Arg func (p InstructionParser) Parse(v *TokenView) (node InstructionNode, err ParsingError) { - v.ConsumeManyTokens(lex.SeparatorToken) node.Labels, _ = ParseManyIgnoreSeparators(p.LabelParser, v) node.Targets = ParseMany(p.RegisterParser, v) @@ -107,6 +106,6 @@ func (p InstructionParser) Parse(v *TokenView) (node InstructionNode, err Parsin } node.Arguments = ParseMany(p.ArgumentParser, v) - err = v.ConsumeAtLeastTokens(1, lex.SeparatorToken) - return node, err + v.ConsumeManyTokens(lex.SeparatorToken) + return node, nil } diff --git a/parse/parser.go b/parse/parser.go index f8cb237..d4e1ddf 100644 --- a/parse/parser.go +++ b/parse/parser.go @@ -49,6 +49,7 @@ func ParseManyIgnoreSeparators[Node any]( p Parser[Node], v *TokenView, ) (nodes []Node, err ParsingError) { + v.ConsumeManyTokens(lex.SeparatorToken) for { var node Node node, err = p.Parse(v) diff --git a/parse/token_view.go b/parse/token_view.go index 401ec21..2d44092 100644 --- a/parse/token_view.go +++ b/parse/token_view.go @@ -51,6 +51,14 @@ func (v *TokenView) ConsumeManyTokens( } } +// Consume a token, but ignore any separator tokens that come before it. +func (v *TokenView) ConsumeTokenIgnoreSeparator( + expectedTypes ...lex.TokenType, +) (lex.Token, ParsingError) { + v.ConsumeManyTokens(lex.SeparatorToken) + return v.ConsumeToken(expectedTypes...) +} + // Consume as many tokens as possible greedly, until we recieve an error. // // If the number of tokens consumed is strictly less than the provided number,