Enum values are auto-filled
This commit is contained in:
parent
2669a04857
commit
500184c4ab
@ -22,6 +22,7 @@ type Argument interface {
|
||||
ToString (indent int) (output string)
|
||||
Equals (value any) (equal bool)
|
||||
Value () (value any)
|
||||
Resolve () (constant Argument, err error)
|
||||
canBePassedAs (what Type) (allowed bool)
|
||||
}
|
||||
|
||||
|
@ -69,6 +69,9 @@ func (analyzer analysisOperation) analyzeEnumSection () (
|
||||
outputSection.what, err = analyzer.analyzeType(inputSection.Type())
|
||||
if err != nil { return }
|
||||
|
||||
// if the inherited type is a single number, we take note of that here
|
||||
// because it will allow us to do things like automatically fill in
|
||||
// member values if they are not specified.
|
||||
isNumeric :=
|
||||
outputSection.what.isNumeric() &&
|
||||
outputSection.what.isSingular()
|
||||
@ -94,8 +97,14 @@ func (analyzer analysisOperation) analyzeEnumSection () (
|
||||
outputMember.argument,
|
||||
err = analyzer.analyzeArgument(inputMember.Argument())
|
||||
if err != nil { return }
|
||||
|
||||
// attempt to resolve the argument to a single constant
|
||||
// literal
|
||||
outputMember.argument, err =
|
||||
outputMember.argument.Resolve()
|
||||
if err != nil { return }
|
||||
|
||||
// type check default value
|
||||
// type check value
|
||||
err = analyzer.typeCheck (
|
||||
outputMember.argument,
|
||||
outputSection.what)
|
||||
@ -117,7 +126,8 @@ func (analyzer analysisOperation) analyzeEnumSection () (
|
||||
return
|
||||
}
|
||||
|
||||
if outputMember.argument == nil { continue }
|
||||
if outputMember.argument == nil { continue }
|
||||
if compareMember.argument == nil { continue }
|
||||
|
||||
if compareMember.argument.Equals (
|
||||
outputMember.argument.Value(),
|
||||
@ -134,8 +144,55 @@ func (analyzer analysisOperation) analyzeEnumSection () (
|
||||
outputMember)
|
||||
}
|
||||
|
||||
// TODO: fill in members that do not have values with incrementing
|
||||
// values. take care to not duplicate them.
|
||||
// fill in members that do not have values
|
||||
if isNumeric {
|
||||
for index, fillInMember := range outputSection.members {
|
||||
if fillInMember.argument != nil { continue }
|
||||
|
||||
max := uint64(0)
|
||||
for _, compareMember := range outputSection.members {
|
||||
|
||||
compareValue := compareMember.argument
|
||||
switch compareValue.(type) {
|
||||
case IntLiteral:
|
||||
number := uint64 (
|
||||
compareValue.(IntLiteral).value)
|
||||
if number > max {
|
||||
max = number
|
||||
}
|
||||
case UIntLiteral:
|
||||
number := uint64 (
|
||||
compareValue.(UIntLiteral).value)
|
||||
if number > max {
|
||||
max = number
|
||||
}
|
||||
case FloatLiteral:
|
||||
number := uint64 (
|
||||
compareValue.(FloatLiteral).value)
|
||||
if number > max {
|
||||
max = number
|
||||
}
|
||||
case nil:
|
||||
// do nothing
|
||||
default:
|
||||
panic (
|
||||
"invalid state: illegal " +
|
||||
"argument type while " +
|
||||
"attempting to fill in enum " +
|
||||
"member value for " +
|
||||
fillInMember.name + " in " +
|
||||
outputSection.location.Describe())
|
||||
}
|
||||
}
|
||||
|
||||
// fill in
|
||||
fillInMember.argument = UIntLiteral {
|
||||
locatable: fillInMember.locatable,
|
||||
value: max + 1,
|
||||
}
|
||||
outputSection.members[index] = fillInMember
|
||||
}
|
||||
}
|
||||
|
||||
outputSection.complete = true
|
||||
return
|
||||
|
@ -51,6 +51,13 @@ func (literal IntLiteral) Value () (value any) {
|
||||
return
|
||||
}
|
||||
|
||||
// Resolve resolves the argument to a constant literal, which in this case is
|
||||
// trivial because the literal is already constant.
|
||||
func (literal IntLiteral) Resolve () (constant Argument, err error) {
|
||||
constant = literal
|
||||
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) {
|
||||
@ -97,6 +104,13 @@ func (literal UIntLiteral) canBePassedAs (what Type) (allowed bool) {
|
||||
return
|
||||
}
|
||||
|
||||
// Resolve resolves the argument to a constant literal, which in this case is
|
||||
// trivial because the literal is already constant.
|
||||
func (literal UIntLiteral) Resolve () (constant Argument, err error) {
|
||||
constant = literal
|
||||
return
|
||||
}
|
||||
|
||||
// What returns the type of the argument
|
||||
func (literal FloatLiteral) What () (what Type) {
|
||||
what.actual = &PrimitiveF64
|
||||
@ -122,6 +136,13 @@ func (literal FloatLiteral) Value () (value any) {
|
||||
return
|
||||
}
|
||||
|
||||
// Resolve resolves the argument to a constant literal, which in this case is
|
||||
// trivial because the literal is already constant.
|
||||
func (literal FloatLiteral) Resolve () (constant Argument, err error) {
|
||||
constant = literal
|
||||
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) {
|
||||
@ -165,6 +186,13 @@ func (literal StringLiteral) Value () (value any) {
|
||||
return
|
||||
}
|
||||
|
||||
// Resolve resolves the argument to a constant literal, which in this case is
|
||||
// trivial because the literal is already constant.
|
||||
func (literal StringLiteral) Resolve () (constant Argument, err error) {
|
||||
constant = literal
|
||||
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) {
|
||||
|
@ -5,7 +5,7 @@ require '../typeSection'
|
||||
enum ro aWeekday:Int
|
||||
- sunday
|
||||
- monday
|
||||
- tuesday
|
||||
- tuesday 3
|
||||
- wednesday
|
||||
- thursday
|
||||
- friday
|
||||
@ -13,7 +13,7 @@ enum ro aWeekday:Int
|
||||
|
||||
type ro bColor:U32
|
||||
|
||||
# enum ro cNamedColor:bColor
|
||||
# - red 0xFF0000
|
||||
# - green 0x00FF00
|
||||
# - blue 0x0000FF
|
||||
enum ro cNamedColor:bColor
|
||||
- red 0xFF0000
|
||||
- green 0x00FF00
|
||||
- blue 0x0000FF
|
||||
|
Reference in New Issue
Block a user