The section kind specific maps are gone

I've REPLACED IT with the unified sections map. Interfaces, baby!
This commit is contained in:
Sasha Koshka 2022-09-04 19:30:59 -04:00
parent 9269161138
commit f3c72f8f30
5 changed files with 53 additions and 94 deletions

View File

@ -11,73 +11,43 @@ func (parser *ParsingOperation) parseBody () (err error) {
err = parser.expect(lexer.TokenKindName)
if err != nil { return }
sectionType := parser.token.Value().(string)
switch sectionType {
case "data":
var section *DataSection
section, err = parser.parseDataSection()
if parser.tree.dataSections == nil {
parser.tree.dataSections =
make(map[string] *DataSection)
}
parser.tree.dataSections[section.name] = section
parser.tree.sections[section.name] = section
if err != nil { return }
section, parseErr := parser.parseDataSection()
err = parser.tree.addSection(section)
if err != nil { return }
if parseErr != nil { return }
case "type":
var section *TypeSection
section, err = parser.parseTypeSection()
if parser.tree.typeSections == nil {
parser.tree.typeSections =
make(map[string] *TypeSection)
}
parser.tree.typeSections[section.name] = section
parser.tree.sections[section.name] = section
if err != nil { return }
section, parseErr := parser.parseTypeSection()
err = parser.tree.addSection(section)
if err != nil { return }
if parseErr != nil { return }
case "objt":
var section *ObjtSection
section, err = parser.parseObjtSection()
if parser.tree.objtSections == nil {
parser.tree.objtSections =
make(map[string] *ObjtSection)
}
parser.tree.objtSections[section.name] = section
parser.tree.sections[section.name] = section
if err != nil { return }
section, parseErr := parser.parseObjtSection()
err = parser.tree.addSection(section)
if err != nil { return }
if parseErr != nil { return }
case "face":
var section *FaceSection
section, err = parser.parseFaceSection()
if parser.tree.faceSections == nil {
parser.tree.faceSections =
make(map[string] *FaceSection)
}
parser.tree.faceSections[section.name] = section
parser.tree.sections[section.name] = section
if err != nil { return }
section, parseErr := parser.parseFaceSection()
err = parser.tree.addSection(section)
if err != nil { return }
if parseErr != nil { return }
case "enum":
var section *EnumSection
section, err = parser.parseEnumSection()
if parser.tree.enumSections == nil {
parser.tree.enumSections =
make(map[string] *EnumSection)
}
parser.tree.enumSections[section.name] = section
parser.tree.sections[section.name] = section
if err != nil { return }
section, parseErr := parser.parseEnumSection()
err = parser.tree.addSection(section)
if err != nil { return }
if parseErr != nil { return }
case "func":
var section *FuncSection
section, err = parser.parseFuncSection()
if parser.tree.funcSections == nil {
parser.tree.funcSections =
make(map[string] *FuncSection)
}
parser.tree.funcSections[section.name] = section
parser.tree.sections[section.name] = section
if err != nil { return }
section, parseErr := parser.parseFuncSection()
err = parser.tree.addSection(section)
if err != nil { return }
if parseErr != nil { return }
default:
err = parser.token.NewError (
@ -87,3 +57,18 @@ func (parser *ParsingOperation) parseBody () (err error) {
}
}
}
// addSection adds a section to the tree, ensuring it has a unique name within
// the module.
func (tree *SyntaxTree) addSection (section Section) (err error) {
_, exists := tree.sections[section.Name()]
if exists {
err = section.NewError (
"cannot have multiple sections with the same name",
infoerr.ErrorKindError)
return
}
tree.sections[section.Name()] = section
return
}

View File

@ -20,7 +20,7 @@ func (trait locatable) NewError (
message string,
kind infoerr.ErrorKind,
) (
err infoerr.Error,
err error,
) {
err = infoerr.NewError(trait.location, message, kind)
return

View File

@ -20,7 +20,12 @@ type ParsingOperation struct {
// Parse reads the files located in the module specified by modulePath, and
// converts them into an abstract syntax tree.
func Parse (modulePath string) (tree *SyntaxTree, err error) {
parser := ParsingOperation { modulePath: modulePath }
parser := ParsingOperation {
modulePath: modulePath,
tree: &SyntaxTree {
sections: make(map[string] Section),
},
}
if parser.modulePath[len(parser.modulePath) - 1] != '/' {
parser.modulePath += "/"
@ -54,9 +59,6 @@ func (parser *ParsingOperation) parse (sourceFile *file.File) (err error) {
if err != nil { return }
// reset the parser
if parser.tree == nil {
parser.tree = &SyntaxTree { }
}
if len(tokens) == 0 { return }
parser.tokens = tokens
parser.token = tokens[0]

View File

@ -47,35 +47,11 @@ func (tree *SyntaxTree) ToString (indent int) (output string) {
output += doIndent(indent, "---\n")
typeSectionKeys := sortMapKeysAlphabetically(tree.typeSections)
for _, name := range typeSectionKeys {
output += tree.typeSections[name].ToString(indent)
sectionKeys := sortMapKeysAlphabetically(tree.sections)
for _, name := range sectionKeys {
output += tree.sections[name].ToString(indent)
}
objtSectionKeys := sortMapKeysAlphabetically(tree.objtSections)
for _, name := range objtSectionKeys {
output += tree.objtSections[name].ToString(indent)
}
enumSectionKeys := sortMapKeysAlphabetically(tree.enumSections)
for _, name := range enumSectionKeys {
output += tree.enumSections[name].ToString(indent)
}
faceSectionKeys := sortMapKeysAlphabetically(tree.faceSections)
for _, name := range faceSectionKeys {
output += tree.faceSections[name].ToString(indent)
}
dataSectionKeys := sortMapKeysAlphabetically(tree.dataSections)
for _, name := range dataSectionKeys {
output += tree.dataSections[name].ToString(indent)
}
funcSectionKeys := sortMapKeysAlphabetically(tree.funcSections)
for _, name := range funcSectionKeys {
output += tree.funcSections[name].ToString(indent)
}
return
}

View File

@ -2,6 +2,7 @@ package parser
import "git.tebibyte.media/arf/arf/file"
import "git.tebibyte.media/arf/arf/types"
import "git.tebibyte.media/arf/arf/infoerr"
// SyntaxTree represents an abstract syntax tree. It covers an entire module. It
// can be expected to be syntactically correct, but it might not be semantically
@ -12,13 +13,6 @@ type SyntaxTree struct {
requires []string
sections map[string] Section
typeSections map[string] *TypeSection
objtSections map[string] *ObjtSection
enumSections map[string] *EnumSection
faceSections map[string] *FaceSection
dataSections map[string] *DataSection
funcSections map[string] *FuncSection
}
// SectionKind differentiates Section interfaces.
@ -40,6 +34,8 @@ type Section interface {
Kind () (kind SectionKind)
Permission () (permission types.Permission)
Name () (name string)
NewError (message string, kind infoerr.ErrorKind) (err error)
ToString (indent int) (output string)
}
// Identifier represents a chain of arguments separated by a dot.