Added useful utilities for resolving identidfiers

This commit is contained in:
Sasha Koshka 2022-09-19 12:17:12 -04:00
parent cf18af1995
commit 92ac258dbe
2 changed files with 55 additions and 1 deletions

View File

@ -5,7 +5,7 @@ import "fmt"
import "path/filepath"
// import "git.tebibyte.media/arf/arf/types"
import "git.tebibyte.media/arf/arf/parser"
// import "git.tebibyte.media/arf/arf/infoerr"
import "git.tebibyte.media/arf/arf/infoerr"
// AnalysisOperation holds information about an ongoing analysis operation.
type AnalysisOperation struct {
@ -14,6 +14,7 @@ type AnalysisOperation struct {
currentPosition locator
currentSection parser.Section
currentTree parser.SyntaxTree
}
// Analyze performs a semantic analyisys on the module specified by path, and
@ -82,12 +83,15 @@ func (analyzer *AnalysisOperation) fetchSection (
previousPosition := analyzer.currentPosition
previousSection := analyzer.currentSection
previousTree := analyzer.currentTree
analyzer.currentPosition = where
analyzer.currentSection = parsedSection
analyzer.currentTree = tree
defer func () {
analyzer.currentPosition = previousPosition
analyzer.currentSection = previousSection
analyzer.currentTree = previousTree
} ()
// TODO: analyze section. have analysis methods work on currentPosition
@ -110,6 +114,49 @@ func (analyzer *AnalysisOperation) fetchSection (
return
}
// fetchSectionFromIdentifier is like fetchSection, but takes in an identifier
// referring to a section and returns the section. This works within the context
// of whatever module is currently being analyzed. The identifier in question
// may have more items than 1 or 2, but those will be ignored. This method
// "consumes" items from the identifier, it will return an identifier without
// those items.
func (analyzer *AnalysisOperation) fetchSectionFromIdentifier (
which parser.Identifier,
) (
section Section,
bitten parser.Identifier,
err error,
) {
bitten = which
item := bitten.Bite()
path, exists := analyzer.currentTree.ResolveRequire(item)
if exists {
// we have our module path, so get the section name
item = bitten.Bite()
} else {
// that wasn't a module name, so the module path must be the our
// current one
path = analyzer.currentPosition.modulePath
}
section, err = analyzer.fetchSection (locator {
name: item,
modulePath: path,
})
if err != nil { return }
if section == nil {
err = which.NewError (
"section \"" + item + "\" does not exist",
infoerr.ErrorKindError,
)
return
}
return
}
func doIndent (indent int, input ...any) (output string) {
for index := 0; index < indent; index ++ {
output += "\t"

View File

@ -65,6 +65,13 @@ func (identifier Identifier) Item (index int) (item string) {
return
}
// Bite removes the first item from the identifier and returns it.
func (identifier *Identifier) Bite () (item string) {
item = identifier.trail[0]
identifier.trail = identifier.trail[1:]
return
}
// Kind returns the type's kind.
func (what Type) Kind () (kind TypeKind) {
kind = what.kind