This repository has been archived on 2024-02-27. You can view files and clone it, but cannot push or open issues or pull requests.
arf/analyzer/table.go

130 lines
3.2 KiB
Go

package analyzer
import "os"
import "sort"
import "path/filepath"
import "git.tebibyte.media/arf/arf/types"
// locator uniquely identifies a section in the section table.
type locator struct {
modulePath string
name string
}
func (where locator) ToString () (output string) {
cwd, _ := os.Getwd()
modulePath, err := filepath.Rel(cwd, where.modulePath)
if err != nil {
panic("cant get relative path: " + err.Error())
}
output += modulePath + "." + where.name
return
}
// SectionTable stores a list of semantically analized sections from one module,
// and all sections that it requires from other modules.
type SectionTable map[locator] Section
// ToString returns the data stored in the table as a string.
func (table SectionTable) ToString (indent int) (output string) {
sortedKeys := make(locatorArray, len(table))
index := 0
for key, _ := range table {
sortedKeys[index] = key
index ++
}
sort.Sort(sortedKeys)
for _, name := range sortedKeys {
section := table[name]
output += section.ToString(indent)
}
return
}
// locatorArray holds a sortable array of locators
type locatorArray []locator
// Len returns the length of the locator array
func (array locatorArray) Len () (length int) {
length = len(array)
return
}
// Less returns whether item at index left is less than item at index right.
func (array locatorArray) Less (left, right int) (less bool) {
leftLocator := array[left]
rightLocator := array[right]
less =
leftLocator.modulePath + leftLocator.name <
rightLocator.modulePath + rightLocator.name
return
}
// Swap swaps the elments at indices left and right.
func (array locatorArray) Swap (left, right int) {
temp := array[left]
array[left] = array[right]
array[right] = temp
}
// Section is a semantically analyzed section.
type Section interface {
// Provided by sectionBase
Name () (name string)
Complete () (complete bool)
ModulePath () (path string)
ModuleName () (path string)
Permission () (permission types.Permission)
locator () (where locator)
// Must be implemented by each individual section
ToString (indent int) (output string)
}
// sectionBase is a struct that all sections must embed.
type sectionBase struct {
where locator
complete bool
permission types.Permission
}
// Name returns the name of the section.
func (section sectionBase) Name () (name string) {
name = section.where.name
return
}
// ModulePath returns the full path of the module the section came from.
func (section sectionBase) ModulePath () (path string) {
path = section.where.modulePath
return
}
// ModuleName returns the name of the module where the section came from.
func (section sectionBase) ModuleName () (name string) {
name = filepath.Base(section.where.modulePath)
return
}
// Complete returns wether the section has been completed.
func (section sectionBase) Complete () (complete bool) {
complete = section.complete
return
}
// Permission returns the permission of the section.
func (section sectionBase) Permission () (permission types.Permission) {
permission = section.permission
return
}
// locator returns the module path and name of the section.
func (section sectionBase) locator () (where locator) {
where = section.where
return
}