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)
|
Location () (location file.Location)
|
||||||
NewError (message string, kind infoerr.ErrorKind) (err error)
|
NewError (message string, kind infoerr.ErrorKind) (err error)
|
||||||
ToString (indent int) (output string)
|
ToString (indent int) (output string)
|
||||||
|
Equals (value any) (equal bool)
|
||||||
|
Value () (value any)
|
||||||
canBePassedAs (what Type) (allowed bool)
|
canBePassedAs (what Type) (allowed bool)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,6 +69,10 @@ func (analyzer analysisOperation) analyzeEnumSection () (
|
|||||||
outputSection.what, err = analyzer.analyzeType(inputSection.Type())
|
outputSection.what, err = analyzer.analyzeType(inputSection.Type())
|
||||||
if err != nil { return }
|
if err != nil { return }
|
||||||
|
|
||||||
|
isNumeric :=
|
||||||
|
outputSection.what.isNumeric() &&
|
||||||
|
outputSection.what.isSingular()
|
||||||
|
|
||||||
// enum sections are only allowed to inherit from type sections
|
// enum sections are only allowed to inherit from type sections
|
||||||
_, inheritsFromTypeSection := outputSection.what.actual.(*TypeSection)
|
_, inheritsFromTypeSection := outputSection.what.actual.(*TypeSection)
|
||||||
if !inheritsFromTypeSection {
|
if !inheritsFromTypeSection {
|
||||||
@ -96,6 +100,33 @@ func (analyzer analysisOperation) analyzeEnumSection () (
|
|||||||
outputMember.argument,
|
outputMember.argument,
|
||||||
outputSection.what)
|
outputSection.what)
|
||||||
if err != nil { return }
|
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 (
|
outputSection.members = append (
|
||||||
|
@ -39,6 +39,18 @@ func (literal IntLiteral) What () (what Type) {
|
|||||||
return
|
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
|
// canBePassedAs returns true if this literal can be implicitly cast to the
|
||||||
// specified type, and false if it can't.
|
// specified type, and false if it can't.
|
||||||
func (literal IntLiteral) canBePassedAs (what Type) (allowed bool) {
|
func (literal IntLiteral) canBePassedAs (what Type) (allowed bool) {
|
||||||
@ -63,6 +75,18 @@ func (literal UIntLiteral) What () (what Type) {
|
|||||||
return
|
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
|
// canBePassedAs returns true if this literal can be implicitly cast to the
|
||||||
// specified type, and false if it can't.
|
// specified type, and false if it can't.
|
||||||
func (literal UIntLiteral) canBePassedAs (what Type) (allowed bool) {
|
func (literal UIntLiteral) canBePassedAs (what Type) (allowed bool) {
|
||||||
@ -86,6 +110,18 @@ func (literal FloatLiteral) ToString (indent int) (output string) {
|
|||||||
return
|
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
|
// canBePassedAs returns true if this literal can be implicitly cast to the
|
||||||
// specified type, and false if it can't.
|
// specified type, and false if it can't.
|
||||||
func (literal FloatLiteral) canBePassedAs (what Type) (allowed bool) {
|
func (literal FloatLiteral) canBePassedAs (what Type) (allowed bool) {
|
||||||
@ -117,6 +153,18 @@ func (literal StringLiteral) ToString (indent int) (output string) {
|
|||||||
return
|
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
|
// canBePassedAs returns true if this literal can be implicitly cast to the
|
||||||
// specified type, and false if it can't.
|
// specified type, and false if it can't.
|
||||||
func (literal StringLiteral) canBePassedAs (what Type) (allowed bool) {
|
func (literal StringLiteral) canBePassedAs (what Type) (allowed bool) {
|
||||||
|
@ -47,3 +47,7 @@ func (location Location) Describe () (description string) {
|
|||||||
" column ", location.column + 1,
|
" column ", location.column + 1,
|
||||||
" width ", location.width)
|
" 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
|
:arf
|
||||||
|
require '../typeSection'
|
||||||
---
|
---
|
||||||
|
|
||||||
enum ro aWeekday:Int
|
enum ro aWeekday:Int
|
||||||
@ -12,9 +13,7 @@ enum ro aWeekday:Int
|
|||||||
|
|
||||||
type ro bColor:U32
|
type ro bColor:U32
|
||||||
|
|
||||||
enum ro cNamedColor:bColor
|
# enum ro cNamedColor:bColor
|
||||||
- red 0xFF0000
|
# - red 0xFF0000
|
||||||
- green 0x00FF00
|
# - green 0x00FF00
|
||||||
- blue 0x0000FF
|
# - blue 0x0000FF
|
||||||
|
|
||||||
type ro X:cNamedColor
|
|
||||||
|
Reference in New Issue
Block a user