diff --git a/parser/argument.go b/parser/argument.go index 1185ec0..2f83ecc 100644 --- a/parser/argument.go +++ b/parser/argument.go @@ -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() diff --git a/parser/dereference.go b/parser/dereference.go new file mode 100644 index 0000000..3d8d550 --- /dev/null +++ b/parser/dereference.go @@ -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 +} diff --git a/parser/func_test.go b/parser/func_test.go index 09c9e53..dabbf4e 100644 --- a/parser/func_test.go +++ b/parser/func_test.go @@ -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) } diff --git a/parser/tree-tostring.go b/parser/tree-tostring.go index 157e3ca..2db8f60 100644 --- a/parser/tree-tostring.go +++ b/parser/tree-tostring.go @@ -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) diff --git a/parser/tree.go b/parser/tree.go index 0b3f09f..64c4f01 100644 --- a/parser/tree.go +++ b/parser/tree.go @@ -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 diff --git a/tests/parser/func/main.arf b/tests/parser/func/main.arf index b8ed2d3..a800719 100644 --- a/tests/parser/func/main.arf +++ b/tests/parser/func/main.arf @@ -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}