Merge pull request 'Add dereference parsing' (#17) from parse-dereferences into main

Reviewed-on: arf/arf#17
This commit is contained in:
Sasha Koshka 2022-10-11 17:37:40 +00:00
commit 942a52f7c6
6 changed files with 77 additions and 6 deletions

View File

@ -3,8 +3,6 @@ package parser
import "git.tebibyte.media/arf/arf/lexer"
import "git.tebibyte.media/arf/arf/infoerr"
// TODO: add support for dereferences and subscripts
var validArgumentStartTokens = []lexer.TokenKind {
lexer.TokenKindName,
@ -14,6 +12,7 @@ var validArgumentStartTokens = []lexer.TokenKind {
lexer.TokenKindString,
lexer.TokenKindLBracket,
lexer.TokenKindLBrace,
lexer.TokenKindLParen,
}
@ -78,9 +77,13 @@ func (parser *ParsingOperation) parseArgument () (argument Argument, err error)
parser.nextToken()
case lexer.TokenKindLBracket:
argument.kind = ArgumentKindPhrase
argument.kind = ArgumentKindPhrase
argument.value, err = parser.parseArgumentLevelPhrase()
case lexer.TokenKindLBrace:
argument.kind = ArgumentKindDereference
argument.value, err = parser.parseDereference()
case lexer.TokenKindLParen:
argument.kind = ArgumentKindList
argument.value, err = parser.parseList()

31
parser/dereference.go Normal file
View File

@ -0,0 +1,31 @@
package parser
import "git.tebibyte.media/arf/arf/lexer"
func (parser *ParsingOperation) parseDereference () (
dereference Dereference,
err error,
) {
err = parser.expect(lexer.TokenKindLBrace)
if err != nil { return }
dereference.location = parser.token.Location()
// parse the value we are dereferencing
err = parser.nextToken(validArgumentStartTokens...)
if err != nil { return }
dereference.argument, err = parser.parseArgument()
if err != nil { return }
// if there is an offset, parse it
err = parser.expect(lexer.TokenKindUInt, lexer.TokenKindRBrace)
if err != nil { return }
if parser.token.Is(lexer.TokenKindUInt) {
dereference.offset = parser.token.Value().(uint64)
}
err = parser.nextToken(lexer.TokenKindRBrace)
if err != nil { return }
err = parser.nextToken()
if err != nil { return }
return
}

View File

@ -105,5 +105,13 @@ func ro hDataInit
[= y:{Int} [loc x]]
[= z:Int:8 (398 9 2309 983 -2387 478 555 123)]
[= bird:Bird ((99999) 324)]
func ro iDereference
> x:{Int}
> y:{Int ..}
> z:Int:4
---
[= b:Int {x}]
[= c:Int {y 4}]
[= d:Int {z 3}]
`, test)
}

View File

@ -133,6 +133,9 @@ func (argument Argument) ToString (indent int, breakLine bool) (output string) {
case ArgumentKindList:
output += argument.value.(List).ToString(indent, breakLine)
case ArgumentKindDereference:
output += argument.value.(Dereference).ToString(indent)
case ArgumentKindIdentifier:
output += doIndent (
@ -276,6 +279,16 @@ func (behavior FaceBehavior) ToString (indent int) (output string) {
return
}
func (dereference Dereference) ToString (indent int) (output string) {
output += "{"
output += dereference.argument.ToString(indent, false)
if dereference.offset != 0 {
output += fmt.Sprint(" ", dereference.offset)
}
output += "}"
return
}
func (phrase Phrase) ToString (indent int, ownLine bool) (output string) {
if ownLine {
output += doIndent(indent)

View File

@ -97,10 +97,8 @@ const (
ArgumentKindList
// {name}
ArgumentKindDereference
// {name 23}
ArgumentKindSubscript
ArgumentKindDereference
// name.name
// name.name.name
@ -220,6 +218,15 @@ type FaceSection struct {
FaceBehavior
}
// Dereference represents a pointer dereference or array subscript.
type Dereference struct {
locatable
valuable
// if a simple dereference was parsed, this should just be zero.
offset uint64
}
// PhraseKind determines what semantic role a phrase plays.
type PhraseKind int

View File

@ -132,3 +132,12 @@ func ro hDataInit
= bird:Bird (
(99999)
324)
func ro iDereference
> x:{Int}
> y:{Int ..}
> z:Int:4
---
= b:Int {x}
= c:Int {y 4}
= d:Int {z 3}