Untested enum analysis

This commit is contained in:
Sasha Koshka 2022-10-13 18:02:35 -04:00
parent c047a1438a
commit a1faf68cce
6 changed files with 132 additions and 7 deletions

View File

@ -111,7 +111,7 @@ func (analyzer *analysisOperation) fetchSection (
analyzer.currentTree = previousTree
} ()
// TODO: analyze section. have analysis methods work on currentPosition
// analyze section. have analysis methods work on currentPosition
// and currentSection.
//
// while building an analyzed section, add it to the section
@ -123,6 +123,8 @@ func (analyzer *analysisOperation) fetchSection (
section, err = analyzer.analyzeTypeSection()
if err != nil { return}
case parser.EnumSection:
section, err = analyzer.analyzeEnumSection()
if err != nil { return}
case parser.FaceSection:
case parser.DataSection:
case parser.FuncSection:

104
analyzer/enum-section.go Normal file
View File

@ -0,0 +1,104 @@
package analyzer
import "git.tebibyte.media/arf/arf/types"
import "git.tebibyte.media/arf/arf/parser"
import "git.tebibyte.media/arf/arf/infoerr"
// EnumSection represents an enumerated type section.
type EnumSection struct {
sectionBase
what Type
members []EnumMember
}
// EnumMember is a member of an enumerated type.
type EnumMember struct {
locatable
name string
argument Argument
}
// ToString returns all data stored within the member, in string form.
func (member EnumMember) ToString (indent int) (output string) {
output += doIndent(indent, "member ", member.name, "\n")
if member.argument != nil {
output += member.argument.ToString(indent + 1)
}
return
}
// ToString returns all data stored within the type section, in string form.
func (section EnumSection) ToString (indent int) (output string) {
output += doIndent(indent, "enumSection ")
output += section.permission.ToString() + " "
output += section.where.ToString()
output += "\n"
output += section.what.ToString(indent + 1)
for _, member := range section.members {
output += member.ToString(indent + 1)
}
return
}
// analyzeEnumSection analyzes an enumerated type section.
func (analyzer analysisOperation) analyzeEnumSection () (
section Section,
err error,
) {
outputSection := EnumSection { }
outputSection.where = analyzer.currentPosition
section = &outputSection
analyzer.addSection(section)
inputSection := analyzer.currentSection.(parser.EnumSection)
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 }
// enum sections are only allowed to inherit from type sections
_, inheritsFromTypeSection := outputSection.what.actual.(*TypeSection)
if !inheritsFromTypeSection {
err = inputSection.Type().NewError (
"enum sections can only inherit from other type " +
"sections.",
infoerr.ErrorKindError)
return
}
// analyze members
for index := 0; index < inputSection.Length(); index ++ {
inputMember := inputSection.Item(index)
outputMember := EnumMember { }
outputMember.location = inputMember.Location()
outputMember.name = inputMember.Name()
if !inputMember.Argument().Nil() {
outputMember.argument,
err = analyzer.analyzeArgument(inputMember.Argument())
if err != nil { return }
// type check default value
err = analyzer.typeCheck (
outputMember.argument,
outputSection.what)
if err != nil { return }
}
}
outputSection.complete = true
return
}

View File

@ -0,0 +1,9 @@
package analyzer
import "testing"
func TestEnumSection (test *testing.T) {
checkTree ("../tests/analyzer/enumSection", false,
`
`, test)
}

View File

@ -9,7 +9,6 @@ import "git.tebibyte.media/arf/arf/infoerr"
type TypeSection struct {
sectionBase
what Type
complete bool
argument Argument
members []ObjectMember
}
@ -19,10 +18,6 @@ type ObjectMember struct {
locatable
name string
bitWidth uint64
// even if there is a private permission in another module, we still
// need to include it in the semantic analysis because we need to know
// what members objects have.
permission types.Permission
what Type
@ -126,6 +121,7 @@ func (analyzer analysisOperation) analyzeTypeSection () (
outputSection.permission = inputSection.Permission()
// get inherited type
outputSection.what, err = analyzer.analyzeType(inputSection.Type())
if err != nil { return }
@ -173,6 +169,8 @@ func (analyzer analysisOperation) analyzeTypeSection () (
return
}
// analyzeObjectMembers analyzes object members from a parser type section into
// a semantic type section.
func (analyzer *analysisOperation) analyzeObjectMembers (
into *TypeSection,
from parser.TypeSection,

View File

@ -87,7 +87,8 @@ func (parser *parsingOperation) parseEnumMember () (
err = parser.nextToken()
if err != nil { return }
if parser.token.Is(lexer.TokenKindNewline) {
parser.nextToken()
err = parser.nextToken()
if err != nil { return }
// if we have exited the member, return
if !parser.token.Is(lexer.TokenKindIndent) { return }
if parser.token.Value().(int) != 2 { return }

View File

@ -0,0 +1,11 @@
:arf
---
enum ro Weekday:Int
- sunday
- monday
- tuesday
- wednesday
- thursday
- friday
- saturday