From 4eac5c67aa471a624d400eae8b0668d869624bf8 Mon Sep 17 00:00:00 2001 From: Sasha Koshka Date: Tue, 23 Aug 2022 15:13:00 -0400 Subject: [PATCH] Added untested interface section parsing --- parser/face.go | 130 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 parser/face.go diff --git a/parser/face.go b/parser/face.go new file mode 100644 index 0000000..a6b96eb --- /dev/null +++ b/parser/face.go @@ -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 +}