Enum member names and values must be unique
This commit is contained in:
parent
dd29f69213
commit
2669a04857
@ -20,6 +20,8 @@ type Argument interface {
|
||||
Location () (location file.Location)
|
||||
NewError (message string, kind infoerr.ErrorKind) (err error)
|
||||
ToString (indent int) (output string)
|
||||
Equals (value any) (equal bool)
|
||||
Value () (value any)
|
||||
canBePassedAs (what Type) (allowed bool)
|
||||
}
|
||||
|
||||
|
@ -69,6 +69,10 @@ func (analyzer analysisOperation) analyzeEnumSection () (
|
||||
outputSection.what, err = analyzer.analyzeType(inputSection.Type())
|
||||
if err != nil { return }
|
||||
|
||||
isNumeric :=
|
||||
outputSection.what.isNumeric() &&
|
||||
outputSection.what.isSingular()
|
||||
|
||||
// enum sections are only allowed to inherit from type sections
|
||||
_, inheritsFromTypeSection := outputSection.what.actual.(*TypeSection)
|
||||
if !inheritsFromTypeSection {
|
||||
@ -96,6 +100,33 @@ func (analyzer analysisOperation) analyzeEnumSection () (
|
||||
outputMember.argument,
|
||||
outputSection.what)
|
||||
if err != nil { return }
|
||||
} else if !isNumeric {
|
||||
// non-numeric enums must have filled in values
|
||||
err = inputMember.NewError (
|
||||
"member value must be specified manually for " +
|
||||
"non-numeric enums",
|
||||
infoerr.ErrorKindError)
|
||||
return
|
||||
}
|
||||
|
||||
for _, compareMember := range outputSection.members {
|
||||
if compareMember.name == outputMember.name {
|
||||
err = inputMember.NewError (
|
||||
"enum member names must be unique",
|
||||
infoerr.ErrorKindError)
|
||||
return
|
||||
}
|
||||
|
||||
if outputMember.argument == nil { continue }
|
||||
|
||||
if compareMember.argument.Equals (
|
||||
outputMember.argument.Value(),
|
||||
) {
|
||||
err = inputMember.NewError (
|
||||
"enum member values must be unique",
|
||||
infoerr.ErrorKindError)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
outputSection.members = append (
|
||||
|
@ -39,6 +39,18 @@ func (literal IntLiteral) What () (what Type) {
|
||||
return
|
||||
}
|
||||
|
||||
// Equals returns whether the literal is equal to the specified value.
|
||||
func (literal IntLiteral) Equals (value any) (equal bool) {
|
||||
equal = literal.value == value
|
||||
return
|
||||
}
|
||||
|
||||
// Value returns the literal's value
|
||||
func (literal IntLiteral) Value () (value any) {
|
||||
value = literal.value
|
||||
return
|
||||
}
|
||||
|
||||
// canBePassedAs returns true if this literal can be implicitly cast to the
|
||||
// specified type, and false if it can't.
|
||||
func (literal IntLiteral) canBePassedAs (what Type) (allowed bool) {
|
||||
@ -63,6 +75,18 @@ func (literal UIntLiteral) What () (what Type) {
|
||||
return
|
||||
}
|
||||
|
||||
// Equals returns whether the literal is equal to the specified value.
|
||||
func (literal UIntLiteral) Equals (value any) (equal bool) {
|
||||
equal = literal.value == value
|
||||
return
|
||||
}
|
||||
|
||||
// Value returns the literal's value
|
||||
func (literal UIntLiteral) Value () (value any) {
|
||||
value = literal.value
|
||||
return
|
||||
}
|
||||
|
||||
// canBePassedAs returns true if this literal can be implicitly cast to the
|
||||
// specified type, and false if it can't.
|
||||
func (literal UIntLiteral) canBePassedAs (what Type) (allowed bool) {
|
||||
@ -86,6 +110,18 @@ func (literal FloatLiteral) ToString (indent int) (output string) {
|
||||
return
|
||||
}
|
||||
|
||||
// Equals returns whether the literal is equal to the specified value.
|
||||
func (literal FloatLiteral) Equals (value any) (equal bool) {
|
||||
equal = literal.value == value
|
||||
return
|
||||
}
|
||||
|
||||
// Value returns the literal's value
|
||||
func (literal FloatLiteral) Value () (value any) {
|
||||
value = literal.value
|
||||
return
|
||||
}
|
||||
|
||||
// canBePassedAs returns true if this literal can be implicitly cast to the
|
||||
// specified type, and false if it can't.
|
||||
func (literal FloatLiteral) canBePassedAs (what Type) (allowed bool) {
|
||||
@ -117,6 +153,18 @@ func (literal StringLiteral) ToString (indent int) (output string) {
|
||||
return
|
||||
}
|
||||
|
||||
// Equals returns whether the literal is equal to the specified value.
|
||||
func (literal StringLiteral) Equals (value any) (equal bool) {
|
||||
equal = literal.value == value
|
||||
return
|
||||
}
|
||||
|
||||
// Value returns the literal's value
|
||||
func (literal StringLiteral) Value () (value any) {
|
||||
value = literal.value
|
||||
return
|
||||
}
|
||||
|
||||
// canBePassedAs returns true if this literal can be implicitly cast to the
|
||||
// specified type, and false if it can't.
|
||||
func (literal StringLiteral) canBePassedAs (what Type) (allowed bool) {
|
||||
|
@ -47,3 +47,7 @@ func (location Location) Describe () (description string) {
|
||||
" column ", location.column + 1,
|
||||
" width ", location.width)
|
||||
}
|
||||
|
||||
// TODO: add extend method that extends that takes in another location, and
|
||||
// returns a new location that spans the two. then, use it in the parser to
|
||||
// properly locate an entire tree node.
|
||||
|
@ -1,4 +1,5 @@
|
||||
:arf
|
||||
require '../typeSection'
|
||||
---
|
||||
|
||||
enum ro aWeekday:Int
|
||||
@ -12,9 +13,7 @@ enum ro aWeekday:Int
|
||||
|
||||
type ro bColor:U32
|
||||
|
||||
enum ro cNamedColor:bColor
|
||||
- red 0xFF0000
|
||||
- green 0x00FF00
|
||||
- blue 0x0000FF
|
||||
|
||||
type ro X:cNamedColor
|
||||
# enum ro cNamedColor:bColor
|
||||
# - red 0xFF0000
|
||||
# - green 0x00FF00
|
||||
# - blue 0x0000FF
|
||||
|
Reference in New Issue
Block a user