From f57637d7fc4c3e9a475d007679d1ce675c892fb2 Mon Sep 17 00:00:00 2001 From: Sasha Koshka Date: Sun, 16 Oct 2022 02:53:37 -0400 Subject: [PATCH] Untested data section analysis --- analyzer/analyzer.go | 2 + analyzer/data-section.go | 81 +++++++++++++++++++++++++++++ analyzer/data-section_test.go | 9 ++++ tests/analyzer/dataSection/main.arf | 10 ++++ tests/analyzer/typeSection/main.arf | 2 + 5 files changed, 104 insertions(+) create mode 100644 analyzer/data-section.go create mode 100644 analyzer/data-section_test.go create mode 100644 tests/analyzer/dataSection/main.arf diff --git a/analyzer/analyzer.go b/analyzer/analyzer.go index dbcb11a..4125756 100644 --- a/analyzer/analyzer.go +++ b/analyzer/analyzer.go @@ -127,6 +127,8 @@ func (analyzer *analysisOperation) fetchSection ( if err != nil { return} case parser.FaceSection: case parser.DataSection: + section, err = analyzer.analyzeDataSection() + if err != nil { return} case parser.FuncSection: } diff --git a/analyzer/data-section.go b/analyzer/data-section.go new file mode 100644 index 0000000..23f66e6 --- /dev/null +++ b/analyzer/data-section.go @@ -0,0 +1,81 @@ +package analyzer + +import "git.tebibyte.media/arf/arf/types" +import "git.tebibyte.media/arf/arf/parser" +import "git.tebibyte.media/arf/arf/infoerr" + +// DataSection represents a global variable section. +type DataSection struct { + sectionBase + what Type + argument Argument +} + +// ToString returns all data stored within the data section, in string form. +func (section DataSection) ToString (indent int) (output string) { + output += doIndent(indent, "typeSection ") + output += section.permission.ToString() + " " + output += section.where.ToString() + output += "\n" + output += section.what.ToString(indent + 1) + if section.argument != nil { + output += section.argument.ToString(indent + 1) + } + return +} + +// analyzeDataSection analyzes a data section. +func (analyzer analysisOperation) analyzeDataSection () ( + section Section, + err error, +) { + outputSection := DataSection { } + outputSection.where = analyzer.currentPosition + + section = &outputSection + analyzer.addSection(section) + + inputSection := analyzer.currentSection.(parser.DataSection) + outputSection.location = analyzer.currentSection.Location() + + if inputSection.Permission() == types.PermissionReadWrite { + err = inputSection.NewError ( + "read-write (rw) permission not understood in this " + + "context, try read-only (ro)", + infoerr.ErrorKindError) + return + } + + outputSection.permission = inputSection.Permission() + + // get inherited type + outputSection.what, err = analyzer.analyzeType(inputSection.Type()) + if err != nil { return } + + // data sections are only allowed to inherit type, enum, and face sections + _, inheritsFromTypeSection := outputSection.what.actual.(*TypeSection) + _, inheritsFromEnumSection := outputSection.what.actual.(*EnumSection) + // _, inheritsFromFaceSection := outputSection.what.actual.(*FaceSection) + if !inheritsFromTypeSection && inheritsFromEnumSection { + err = inputSection.Type().NewError ( + "type sections can only inherit from type, enum, and " + + "face sections", + infoerr.ErrorKindError) + return + } + + if !inputSection.Argument().Nil() { + outputSection.argument, + err = analyzer.analyzeArgument(inputSection.Argument()) + if err != nil { return } + + // type check default value + err = analyzer.typeCheck ( + outputSection.argument, + outputSection.what) + if err != nil { return } + } + + outputSection.complete = true + return +} diff --git a/analyzer/data-section_test.go b/analyzer/data-section_test.go new file mode 100644 index 0000000..d5c4e9d --- /dev/null +++ b/analyzer/data-section_test.go @@ -0,0 +1,9 @@ +package analyzer + +import "testing" + +func TestDataSection (test *testing.T) { + checkTree ("../tests/analyzer/dataSection", false, +` +`, test) +} diff --git a/tests/analyzer/dataSection/main.arf b/tests/analyzer/dataSection/main.arf new file mode 100644 index 0000000..6f62c82 --- /dev/null +++ b/tests/analyzer/dataSection/main.arf @@ -0,0 +1,10 @@ +:arf +--- + +data ro aBasicInt:Int 5 + +data ro bRune:Int 'A' + +data ro cString:String 'A very large bird' + +data ro dCharBuffer:U8:32 'A very large bird\000' diff --git a/tests/analyzer/typeSection/main.arf b/tests/analyzer/typeSection/main.arf index 286db2a..3416a9b 100644 --- a/tests/analyzer/typeSection/main.arf +++ b/tests/analyzer/typeSection/main.arf @@ -18,3 +18,5 @@ type ro eInheritObject:cBasicObject type ro fInheritObjectFromOther:required.bBird ro wing 2 ro beak:Int 238 + +# TODO: test a type that has a member pointing to itself