Untested enum analysis
This commit is contained in:
parent
c047a1438a
commit
a1faf68cce
@ -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
104
analyzer/enum-section.go
Normal 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
|
||||
}
|
9
analyzer/enum-section_test.go
Normal file
9
analyzer/enum-section_test.go
Normal file
@ -0,0 +1,9 @@
|
||||
package analyzer
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestEnumSection (test *testing.T) {
|
||||
checkTree ("../tests/analyzer/enumSection", false,
|
||||
`
|
||||
`, test)
|
||||
}
|
@ -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,
|
||||
|
@ -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 }
|
||||
|
11
tests/analyzer/enumSection/main.arf
Normal file
11
tests/analyzer/enumSection/main.arf
Normal file
@ -0,0 +1,11 @@
|
||||
:arf
|
||||
---
|
||||
|
||||
enum ro Weekday:Int
|
||||
- sunday
|
||||
- monday
|
||||
- tuesday
|
||||
- wednesday
|
||||
- thursday
|
||||
- friday
|
||||
- saturday
|
Reference in New Issue
Block a user