Untested enum analysis
This commit is contained in:
parent
c047a1438a
commit
a1faf68cce
@ -111,7 +111,7 @@ func (analyzer *analysisOperation) fetchSection (
|
|||||||
analyzer.currentTree = previousTree
|
analyzer.currentTree = previousTree
|
||||||
} ()
|
} ()
|
||||||
|
|
||||||
// TODO: analyze section. have analysis methods work on currentPosition
|
// analyze section. have analysis methods work on currentPosition
|
||||||
// and currentSection.
|
// and currentSection.
|
||||||
//
|
//
|
||||||
// while building an analyzed section, add it to the section
|
// while building an analyzed section, add it to the section
|
||||||
@ -123,6 +123,8 @@ func (analyzer *analysisOperation) fetchSection (
|
|||||||
section, err = analyzer.analyzeTypeSection()
|
section, err = analyzer.analyzeTypeSection()
|
||||||
if err != nil { return}
|
if err != nil { return}
|
||||||
case parser.EnumSection:
|
case parser.EnumSection:
|
||||||
|
section, err = analyzer.analyzeEnumSection()
|
||||||
|
if err != nil { return}
|
||||||
case parser.FaceSection:
|
case parser.FaceSection:
|
||||||
case parser.DataSection:
|
case parser.DataSection:
|
||||||
case parser.FuncSection:
|
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 {
|
type TypeSection struct {
|
||||||
sectionBase
|
sectionBase
|
||||||
what Type
|
what Type
|
||||||
complete bool
|
|
||||||
argument Argument
|
argument Argument
|
||||||
members []ObjectMember
|
members []ObjectMember
|
||||||
}
|
}
|
||||||
@ -19,10 +18,6 @@ type ObjectMember struct {
|
|||||||
locatable
|
locatable
|
||||||
name string
|
name string
|
||||||
bitWidth uint64
|
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
|
permission types.Permission
|
||||||
|
|
||||||
what Type
|
what Type
|
||||||
@ -126,6 +121,7 @@ func (analyzer analysisOperation) analyzeTypeSection () (
|
|||||||
|
|
||||||
outputSection.permission = inputSection.Permission()
|
outputSection.permission = inputSection.Permission()
|
||||||
|
|
||||||
|
// get inherited type
|
||||||
outputSection.what, err = analyzer.analyzeType(inputSection.Type())
|
outputSection.what, err = analyzer.analyzeType(inputSection.Type())
|
||||||
if err != nil { return }
|
if err != nil { return }
|
||||||
|
|
||||||
@ -173,6 +169,8 @@ func (analyzer analysisOperation) analyzeTypeSection () (
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// analyzeObjectMembers analyzes object members from a parser type section into
|
||||||
|
// a semantic type section.
|
||||||
func (analyzer *analysisOperation) analyzeObjectMembers (
|
func (analyzer *analysisOperation) analyzeObjectMembers (
|
||||||
into *TypeSection,
|
into *TypeSection,
|
||||||
from parser.TypeSection,
|
from parser.TypeSection,
|
||||||
|
@ -87,7 +87,8 @@ func (parser *parsingOperation) parseEnumMember () (
|
|||||||
err = parser.nextToken()
|
err = parser.nextToken()
|
||||||
if err != nil { return }
|
if err != nil { return }
|
||||||
if parser.token.Is(lexer.TokenKindNewline) {
|
if parser.token.Is(lexer.TokenKindNewline) {
|
||||||
parser.nextToken()
|
err = parser.nextToken()
|
||||||
|
if err != nil { return }
|
||||||
// if we have exited the member, return
|
// if we have exited the member, return
|
||||||
if !parser.token.Is(lexer.TokenKindIndent) { return }
|
if !parser.token.Is(lexer.TokenKindIndent) { return }
|
||||||
if parser.token.Value().(int) != 2 { 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