From f9786216734a020f5f1c08c20c386331cad7055d Mon Sep 17 00:00:00 2001 From: Sasha Koshka Date: Tue, 16 Aug 2022 10:44:02 -0400 Subject: [PATCH] Parse basic information about data sections (name, type) --- parser/data.go | 104 ++++++++++++++++++++++++++++++++++++++++++++++++- parser/tree.go | 4 +- 2 files changed, 105 insertions(+), 3 deletions(-) diff --git a/parser/data.go b/parser/data.go index a1348f4..c9a9da4 100644 --- a/parser/data.go +++ b/parser/data.go @@ -1,9 +1,111 @@ package parser -// parseData parses a data section +import "git.tebibyte.media/sashakoshka/arf/file" +import "git.tebibyte.media/sashakoshka/arf/types" +import "git.tebibyte.media/sashakoshka/arf/lexer" + +// parseData parses a data section. func (parser *ParsingOperation) parseDataSection () ( section *DataSection, err error, ) { + err = parser.expect(lexer.TokenKindName) + if err != nil { return } + + section = &DataSection { location: parser.token.Location() } + + err = parser.nextToken(lexer.TokenKindPermission) + if err != nil { return } + section.permission = parser.token.Value().(types.Permission) + + err = parser.nextToken(lexer.TokenKindName) + if err != nil { return } + section.name = parser.token.Value().(string) + + err = parser.nextToken(lexer.TokenKindColon) + if err != nil { return } + section.what, err = parser.parseType() + if err != nil { return } + + return +} + +// parseType parses a type notation of the form Name, {Name}, etc. +func (parser *ParsingOperation) parseType () (what Type, err error) { + err = parser.nextToken(lexer.TokenKindName, lexer.TokenKindLBrace) + if err != nil { return } + what.location = parser.token.Location() + + if parser.token.Is(lexer.TokenKindLBrace) { + what.kind = TypeKindPointer + + var points Type + points, err = parser.parseType() + if err != nil { return } + what.points = &points + + err = parser.nextToken ( + lexer.TokenKindUInt, + lexer.TokenKindRBrace) + if err != nil { return } + + if parser.token.Is(lexer.TokenKindUInt) { + what.kind = TypeKindArray + + what.length = parser.token.Value().(uint64) + + err = parser.nextToken ( + lexer.TokenKindUInt, + lexer.TokenKindRBrace) + if err != nil { return } + } + } else { + what.name, err = parser.parseIdentifier() + if err != nil { return } + } + + err = parser.nextToken() + + if parser.token.Is(lexer.TokenKindColon) { + err = parser.nextToken(lexer.TokenKindName) + if err != nil { return } + + qualifier := parser.token.Value().(string) + switch qualifier { + case "mut": + what.mutable = true + default: + err = parser.token.NewError ( + "unknown type qualifier \"" + qualifier + "\"", + file.ErrorKindError) + return + } + } + + return +} + +// parseIdentifier parses an identifier made out of dot separated names. +func (parser *ParsingOperation) parseIdentifier () ( + identifier Identifier, + err error, +) { + err = parser.expect(lexer.TokenKindName) + if err != nil { return } + identifier.location = parser.token.Location() + + for { + if !parser.token.Is(lexer.TokenKindName) { break } + + identifier.trail = append ( + identifier.trail, + parser.token.Value().(string)) + + err = parser.nextToken() + if err != nil { return } + + if !parser.token.Is(lexer.TokenKindDot) { break } + } + return } diff --git a/parser/tree.go b/parser/tree.go index 08e61eb..830c466 100644 --- a/parser/tree.go +++ b/parser/tree.go @@ -42,9 +42,9 @@ type Type struct { mutable bool kind TypeKind - // only applicable for arrays. a value of nil means it has an + // only applicable for arrays. a value of zero means it has an // undefined/dynamic length. - length *Argument + length uint64 // only applicable for basic. name Identifier