From fd9b1b3d11c385756fd7eb17aa6082185f8c712e Mon Sep 17 00:00:00 2001 From: Sasha Koshka Date: Mon, 17 Oct 2022 15:41:26 -0400 Subject: [PATCH] wip --- analyzer/analyzer.go | 68 +++++++++++++++++++++++++++++++++++--------- analyzer/list.go | 4 +-- analyzer/type.go | 39 ++++--------------------- 3 files changed, 62 insertions(+), 49 deletions(-) diff --git a/analyzer/analyzer.go b/analyzer/analyzer.go index 4125756..3e40016 100644 --- a/analyzer/analyzer.go +++ b/analyzer/analyzer.go @@ -14,6 +14,7 @@ package analyzer import "os" 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" @@ -135,23 +136,42 @@ 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. If the section comes from a different module (and permissions -// should therefore be respected), external will be set to true. -func (analyzer *analysisOperation) fetchSectionFromIdentifier ( +// TODO: make this method a generalized "get this from an identifier in context +// of the current scope" method. have it return various things like sections, +// variables, functions, members, methods, etc. have it return an any. +// if no node could be found, return an error saying entity not found. if a node +// is found, but other identifier items describe members of that node that do +// not exist, return an error saying nonexistent member. if the node is private, +// also return an error. +// +// when new things are defined, they should not be allowed to shadow anything +// else in above scopes. nevertheless, the method should search in this order: +// +// 1. search scopes starting with closest -> farthest +// 2. if first part of identifier is a require, get section from other module +// 3. search for section in current module +// +// look into making a unified structure for data sections and variables, and +// having data section variables be part of a "root" scope at the base of every +// module. + +// fetchNodeFromIdentifier is like fetchSection, but takes in an identifier +// referring to any node accessible within the current scope and returns it. +// This method works within the current scope and current module. This method +// consumes the entire identifier, and will produce an error if there are +// identifier items left unconsumed. +func (analyzer *analysisOperation) fetchNodeFromIdentifier ( which parser.Identifier, ) ( - section Section, - external bool, - bitten parser.Identifier, - err error, + node any, + err error, ) { item, bitten := which.Bite() + // TODO: search scopes for variables + + // the identifier must be referring to a section + var external bool path, exists := analyzer.currentTree.ResolveRequire(item) if exists { // we have our module path, so get the section name @@ -163,19 +183,39 @@ func (analyzer *analysisOperation) fetchSectionFromIdentifier ( path = analyzer.currentPosition.modulePath } + // attempt to get section + var section Section section, err = analyzer.fetchSection (locator { name: item, modulePath: path, }) + node = section if err != nil { return } - if section == nil { + // return error if nothing mentioned in the identifier is accessible + if node == nil { err = which.NewError ( - "section \"" + item + "\" does not exist", + "can't find anything called \"" + item + "\" within " + + "current scope", infoerr.ErrorKindError, ) return } + + // return error if the section is private + if external && section.Permission() == types.PermissionPrivate { + err = which.NewError( + "this section is private, and cannot be used " + + "outside of its module", + infoerr.ErrorKindError) + return + } + + // see if we can do member selection on the section + // TODO: at this point, we are gonna return an argument. + if bitten.Length > 0 { + switch + } return } diff --git a/analyzer/list.go b/analyzer/list.go index 1453077..9b94ed2 100644 --- a/analyzer/list.go +++ b/analyzer/list.go @@ -12,11 +12,11 @@ type List struct { func (list List) ToString (indent int) (output string) { // TODO panic("TODO") - return + // return } func (list List) canBePassedAs (what Type) (allowed bool) { // TODO panic("TODO") - return + // return } diff --git a/analyzer/type.go b/analyzer/type.go index dfc794d..8b4049f 100644 --- a/analyzer/type.go +++ b/analyzer/type.go @@ -1,7 +1,6 @@ package analyzer import "fmt" -import "git.tebibyte.media/arf/arf/types" import "git.tebibyte.media/arf/arf/parser" import "git.tebibyte.media/arf/arf/infoerr" @@ -292,48 +291,22 @@ func (analyzer analysisOperation) analyzeType ( outputType.points = &points } else { // analyze the type section this type uses - var bitten parser.Identifier - var external bool - var actual Section + var node any - actual, - external, - bitten, - err = analyzer.fetchSectionFromIdentifier(inputType.Name()) + node, err = analyzer.fetchNodeFromIdentifier(inputType.Name()) if err != nil { return } - if actual == nil { - err = inputType.NewError ( - "this type does not exist", - infoerr.ErrorKindError) - return - } - - switch actual.(type) { + switch node.(type) { // TODO: uncomment once these sections are implemented case *TypeSection, *EnumSection /* , *FaceSection */: - outputType.actual = actual + outputType.actual = node.(Section) + default: - err = inputType.NewError ( + err = inputType.Name().NewError ( "this must refer to a type, interface, or enum", infoerr.ErrorKindError) return } - - if external && actual.Permission() == types.PermissionPrivate { - err = bitten.NewError( - "this type is private, and cannot be used " + - "outside of its module", - infoerr.ErrorKindError) - return - } - - if bitten.Length() > 0 { - err = bitten.NewError( - "cannot use member selection in this context", - infoerr.ErrorKindError) - return - } } return