Switch statement analysis passes tests

This commit is contained in:
Sasha Koshka 2024-03-25 19:50:54 -04:00
parent f3bdfef5c5
commit 4931f97496
2 changed files with 31 additions and 6 deletions

View File

@ -475,7 +475,7 @@ func isNumeric (ty entity.Type) bool {
} }
} }
// isInteger returns whether or not the specified type is an integer. // isInteger returns whether or not the specified type is an integer or word.
func isInteger (ty entity.Type) bool { func isInteger (ty entity.Type) bool {
switch ReduceToBase(ty).(type) { switch ReduceToBase(ty).(type) {
case *entity.TypeInt, *entity.TypeWord: return true case *entity.TypeInt, *entity.TypeWord: return true
@ -483,6 +483,14 @@ func isInteger (ty entity.Type) bool {
} }
} }
// isWord returns whether or not the specified type is a word.
func isWord (ty entity.Type) bool {
switch ReduceToBase(ty).(type) {
case *entity.TypeWord: return true
default: return false
}
}
// isPointer returns whether or not the specified type is a pointer. // isPointer returns whether or not the specified type is a pointer.
func isPointer (ty entity.Type) bool { func isPointer (ty entity.Type) bool {
switch ReduceToBase(ty).(type) { switch ReduceToBase(ty).(type) {

View File

@ -815,7 +815,8 @@ func (this *Tree) analyzeSwitch (
if err != nil { return nil, err } if err != nil { return nil, err }
switc.Value = value switc.Value = value
width, integerOk := integerWidth(value.Type()) width, integerOk := integerWidth(value.Type())
if !integerOk { wordOk := isWord(value.Type())
if !integerOk && !wordOk {
return nil, errors.Errorf ( return nil, errors.Errorf (
value.Position(), "cannot switch on type %v", value.Position(), "cannot switch on type %v",
value.Type()) value.Type())
@ -843,6 +844,14 @@ func (this *Tree) analyzeSwitch (
case *entity.LiteralInt: case *entity.LiteralInt:
keyInt = int64(key.Value) keyInt = int64(key.Value)
case *entity.LiteralString: case *entity.LiteralString:
if !integerOk {
return nil, errors.Errorf (
key.Position(),
"cannot use string literal when " +
"switching on %v",
value.Type())
}
switch { switch {
case width >= 32: case width >= 32:
keyInt = int64(key.ValueUTF32[0]) keyInt = int64(key.ValueUTF32[0])
@ -852,9 +861,17 @@ func (this *Tree) analyzeSwitch (
keyInt = int64(key.ValueUTF8[0]) keyInt = int64(key.ValueUTF8[0])
} }
default: default:
return nil, errors.Errorf ( return nil, errors.Errorf (
key.Position(), "%v cannot represent a constant integer", key.Position(),
key) "%v cannot represent a constant integer",
key)
}
if previous, exists := switc.CaseMap[keyInt]; exists {
return nil, errors.Errorf (
cas.Key.Position(),
"%v already listed in match at %v",
keyInt, previous.Position())
} }
switc.Cases[index] = cas switc.Cases[index] = cas
@ -873,7 +890,7 @@ func (this *Tree) analyzeSwitch (
switc.Default.Expression = expression switc.Default.Expression = expression
} }
if into != nil && switc.Default != nil { if into != nil && switc.Default == nil {
return nil, errors.Errorf ( return nil, errors.Errorf (
switc.Position(), switc.Position(),
"switch must have a default case") "switch must have a default case")