diff --git a/assets/heatmap.png b/assets/heatmap.png index f7dd431..c0de76b 100644 Binary files a/assets/heatmap.png and b/assets/heatmap.png differ diff --git a/parser/cache.go b/parser/cache.go new file mode 100644 index 0000000..a07dbd6 --- /dev/null +++ b/parser/cache.go @@ -0,0 +1,11 @@ +package parser + +// cacheItem stores an item of the parser cache. +type cacheItem struct { + tree SyntaxTree + skimmed bool +} + +// cache stores all modules that have been parsed so far. They are indexed with +// their full path on the filesystem, starting with '/'. +var cache = make(map[string] cacheItem) diff --git a/parser/parser.go b/parser/parser.go index 215a679..43f344a 100644 --- a/parser/parser.go +++ b/parser/parser.go @@ -18,15 +18,28 @@ type ParsingOperation struct { } // TODO: -// - implement parser cache -// - have this try to hit the cache, and actually parse on miss -// - rename this to Fetch +// * implement parser cache +// * have this try to hit the cache, and actually parse on miss +// * rename this to Fetch // - add `skim bool` argument. when this is true, don't parse any code or data // section initialization values, just definitions and their default values. -// 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) { +// Fetch returns the parsed module located at the specified path, and returns an +// abstract syntax tree. If the module has not yet been parsed, it parses it +// first. +func Fetch (modulePath string, skim bool) (tree SyntaxTree, err error) { + if modulePath[0] != '/' { + panic("module path did not begin at filesystem root") + } + + // try to hit cache + cached, exists := cache[modulePath] + if exists && !(!skim && cached.skimmed){ + tree = cached.tree + return + } + + // miss, so parse the module. parser := ParsingOperation { modulePath: modulePath, tree: SyntaxTree { @@ -56,6 +69,13 @@ func Parse (modulePath string) (tree SyntaxTree, err error) { } tree = parser.tree + + // cache tree + cache[modulePath] = cacheItem { + tree: tree, + skimmed: false, + } + return } diff --git a/parser/test-common.go b/parser/test-common.go index 2784087..8a8e918 100644 --- a/parser/test-common.go +++ b/parser/test-common.go @@ -1,12 +1,16 @@ package parser import "io" +import "os" import "strings" import "testing" -// import "git.tebibyte.media/arf/arf/types" +import "path/filepath" func checkTree (modulePath string, correct string, test *testing.T) { - tree, err := Parse(modulePath) + cwd, _ := os.Getwd() + modulePath = filepath.Join(cwd, modulePath) + println(modulePath) + tree, err := Fetch(modulePath, false) treeString := tree.ToString(0) treeRunes := []rune(treeString)