From 7e972e213225754fe8118bb99261c84cfcb9ef6d Mon Sep 17 00:00:00 2001 From: Sasha Koshka Date: Wed, 7 Sep 2022 17:12:46 -0400 Subject: [PATCH] Syntax tree now stores map of require names -> full paths --- parser/accessors.go | 8 ++++++++ parser/meta.go | 29 ++++++++++++++++++++++++++++- parser/meta_test.go | 8 ++++++-- parser/parser.go | 1 + parser/tree.go | 4 +--- tests/parser/meta/meta.arf | 5 +++-- 6 files changed, 47 insertions(+), 8 deletions(-) diff --git a/parser/accessors.go b/parser/accessors.go index 776a387..bdfcd72 100644 --- a/parser/accessors.go +++ b/parser/accessors.go @@ -15,6 +15,14 @@ func (tree SyntaxTree) Sections () (iterator types.Iterator[Section]) { return } +// ResolveRequire returns the full path, from the filesystem root, of an import. +// This method will return false for exists if the module has not been +// imported. +func (tree SyntaxTree) ResolveRequire (name string) (path string, exists bool) { + path, exists = tree.requires[name] + return +} + // Kind returns the section's kind (SectionKindType). func (section TypeSection) Kind () (kind SectionKind) { kind = SectionKindType diff --git a/parser/meta.go b/parser/meta.go index dbf2278..6d15a2b 100644 --- a/parser/meta.go +++ b/parser/meta.go @@ -1,10 +1,14 @@ package parser +import "os" +import "path/filepath" import "git.tebibyte.media/arf/arf/lexer" import "git.tebibyte.media/arf/arf/infoerr" // parseMeta parsese the metadata header at the top of an arf file. func (parser *ParsingOperation) parseMeta () (err error) { + cwd, _ := os.Getwd() + for { err = parser.expect ( lexer.TokenKindName, @@ -31,7 +35,30 @@ func (parser *ParsingOperation) parseMeta () (err error) { case "license": parser.tree.license = value case "require": - parser.tree.requires = append(parser.tree.requires, value) + // if import path is relative, get absolute path. + if value[0] == '.' { + value = filepath.Join(cwd, value) + } else if value[0] != '/' { + // TODO: get arf import path from an env + // variable, and default to this if not found. + // then, search all paths. + value = filepath.Join ( + "/usr/local/include/arf/", + value) + } + + basename := filepath.Base(value) + _, exists := parser.tree.requires[basename] + + if exists { + err = parser.token.NewError ( + "cannot require \"" + basename + + "\" multiple times", + infoerr.ErrorKindError) + return + } + + parser.tree.requires[basename] = value default: parser.token.NewError ( "unrecognized metadata field: " + field, diff --git a/parser/meta_test.go b/parser/meta_test.go index 6e6466f..26af856 100644 --- a/parser/meta_test.go +++ b/parser/meta_test.go @@ -1,14 +1,18 @@ package parser +import "os" import "testing" +import "path/filepath" func TestMeta (test *testing.T) { + cwd, _ := os.Getwd() checkTree ("../tests/parser/meta", false, `:arf author "Sasha Koshka" license "GPLv3" -require "someModule" -require "otherModule" +require "` + filepath.Join(cwd, "./some/local/module") + `" +require "/some/absolute/path/to/someModule" +require "/usr/include/arf/someLibraryInstalledInStandardLocation" --- `, test) } diff --git a/parser/parser.go b/parser/parser.go index 068f150..2520af9 100644 --- a/parser/parser.go +++ b/parser/parser.go @@ -38,6 +38,7 @@ func Fetch (modulePath string, skim bool) (tree SyntaxTree, err error) { modulePath: modulePath, skimming: skim, tree: SyntaxTree { + requires: make(map[string] string), sections: make(map[string] Section), }, } diff --git a/parser/tree.go b/parser/tree.go index 2f1aad9..a1be9dd 100644 --- a/parser/tree.go +++ b/parser/tree.go @@ -4,8 +4,6 @@ import "git.tebibyte.media/arf/arf/file" import "git.tebibyte.media/arf/arf/types" import "git.tebibyte.media/arf/arf/infoerr" -// TODO: implement table of import names -> full paths from /. perhaps replace -// requires[] with this, and build it when parsing the meta section. // 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 // correct (because it has not been analyzed yet.) @@ -13,7 +11,7 @@ type SyntaxTree struct { license string author string - requires []string + requires map[string] string sections map[string] Section } diff --git a/tests/parser/meta/meta.arf b/tests/parser/meta/meta.arf index b59a53a..8ea66e1 100644 --- a/tests/parser/meta/meta.arf +++ b/tests/parser/meta/meta.arf @@ -1,6 +1,7 @@ :arf author "Sasha Koshka" license "GPLv3" -require "someModule" -require "otherModule" +require "./some/local/module" +require "/some/absolute/path/to/someModule" +require "someLibraryInstalledInStandardLocation" ---