Added untested interface section parsing
This commit is contained in:
parent
441b036a1c
commit
4eac5c67aa
130
parser/face.go
Normal file
130
parser/face.go
Normal file
@ -0,0 +1,130 @@
|
||||
package parser
|
||||
|
||||
import "git.tebibyte.media/sashakoshka/arf/types"
|
||||
import "git.tebibyte.media/sashakoshka/arf/lexer"
|
||||
import "git.tebibyte.media/sashakoshka/arf/infoerr"
|
||||
|
||||
// parseFaceSection parses an interface section.
|
||||
func (parser *ParsingOperation) parseFaceSection () (
|
||||
section *FaceSection,
|
||||
err error,
|
||||
) {
|
||||
err = parser.expect(lexer.TokenKindName)
|
||||
if err != nil { return }
|
||||
|
||||
section = &FaceSection {
|
||||
location: parser.token.Location(),
|
||||
behaviors: make(map[string] FaceBehavior),
|
||||
}
|
||||
|
||||
// get permission
|
||||
err = parser.nextToken(lexer.TokenKindPermission)
|
||||
if err != nil { return }
|
||||
section.permission = parser.token.Value().(types.Permission)
|
||||
|
||||
// get name
|
||||
err = parser.nextToken(lexer.TokenKindName)
|
||||
if err != nil { return }
|
||||
section.name = parser.token.Value().(string)
|
||||
|
||||
// parse inherited interface
|
||||
err = parser.nextToken(lexer.TokenKindColon)
|
||||
if err != nil { return }
|
||||
err = parser.nextToken(lexer.TokenKindName)
|
||||
if err != nil { return }
|
||||
section.inherits = parser.token.Value().(string)
|
||||
if err != nil { return }
|
||||
err = parser.expect(lexer.TokenKindNewline)
|
||||
if err != nil { return }
|
||||
err = parser.nextToken()
|
||||
if err != nil { return }
|
||||
|
||||
// parse members
|
||||
for {
|
||||
// if we've left the block, stop parsing
|
||||
if !parser.token.Is(lexer.TokenKindIndent) { return }
|
||||
if parser.token.Value().(int) != 1 { return }
|
||||
|
||||
// parse behavior
|
||||
err = parser.nextToken(lexer.TokenKindName)
|
||||
if err != nil { return }
|
||||
behaviorBeginning := parser.token.Location()
|
||||
var behavior FaceBehavior
|
||||
behavior, err = parser.parseFaceBehavior()
|
||||
|
||||
// add to section
|
||||
_, exists := section.behaviors[behavior.name]
|
||||
if exists {
|
||||
err = infoerr.NewError (
|
||||
behaviorBeginning,
|
||||
"multiple behaviors named " + behavior.name +
|
||||
" in this interface",
|
||||
infoerr.ErrorKindError)
|
||||
return
|
||||
}
|
||||
|
||||
if err != nil { return }
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// parseFaceBehavior parses a single interface behavior. Indentation level is
|
||||
// assumed.
|
||||
func (parser *ParsingOperation) parseFaceBehavior () (
|
||||
behavior FaceBehavior,
|
||||
err error,
|
||||
) {
|
||||
// get name
|
||||
err = parser.nextToken(lexer.TokenKindName)
|
||||
if err != nil { return }
|
||||
behavior.name = parser.token.Value().(string)
|
||||
|
||||
for {
|
||||
err = parser.nextToken(lexer.TokenKindNewline)
|
||||
if err != nil { return }
|
||||
|
||||
// if we've left the block, stop parsing
|
||||
err = parser.nextToken()
|
||||
if err != nil { return }
|
||||
if !parser.token.Is(lexer.TokenKindIndent) { return }
|
||||
if parser.token.Value().(int) != 2 { return }
|
||||
|
||||
// get preceding symbol
|
||||
err = parser.nextToken (
|
||||
lexer.TokenKindGreaterThan,
|
||||
lexer.TokenKindLessThan)
|
||||
if err != nil { return }
|
||||
kind := parser.token.Kind()
|
||||
|
||||
var declaration Declaration
|
||||
|
||||
// get name
|
||||
err = parser.nextToken(lexer.TokenKindName)
|
||||
if err != nil { return }
|
||||
declaration.name = parser.token.Value().(string)
|
||||
|
||||
// parse inherited type
|
||||
err = parser.nextToken(lexer.TokenKindColon)
|
||||
if err != nil { return }
|
||||
err = parser.nextToken()
|
||||
if err != nil { return }
|
||||
declaration.what, err = parser.parseType()
|
||||
if err != nil { return }
|
||||
err = parser.expect(lexer.TokenKindNewline)
|
||||
if err != nil { return }
|
||||
err = parser.nextToken()
|
||||
if err != nil { return }
|
||||
|
||||
if kind == lexer.TokenKindGreaterThan {
|
||||
behavior.inputs = append (
|
||||
behavior.inputs,
|
||||
declaration)
|
||||
} else {
|
||||
behavior.inputs = append (
|
||||
behavior.inputs,
|
||||
declaration)
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
Reference in New Issue
Block a user