From 4931f97496b1e2b2fcc65652f11499a98c158d61 Mon Sep 17 00:00:00 2001 From: Sasha Koshka Date: Mon, 25 Mar 2024 19:50:54 -0400 Subject: [PATCH] Switch statement analysis passes tests --- analyzer/assignment.go | 10 +++++++++- analyzer/expression.go | 27 ++++++++++++++++++++++----- 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/analyzer/assignment.go b/analyzer/assignment.go index 34ceba0..94fda08 100644 --- a/analyzer/assignment.go +++ b/analyzer/assignment.go @@ -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 { switch ReduceToBase(ty).(type) { 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. func isPointer (ty entity.Type) bool { switch ReduceToBase(ty).(type) { diff --git a/analyzer/expression.go b/analyzer/expression.go index fb671e2..88433e5 100644 --- a/analyzer/expression.go +++ b/analyzer/expression.go @@ -815,7 +815,8 @@ func (this *Tree) analyzeSwitch ( if err != nil { return nil, err } switc.Value = value width, integerOk := integerWidth(value.Type()) - if !integerOk { + wordOk := isWord(value.Type()) + if !integerOk && !wordOk { return nil, errors.Errorf ( value.Position(), "cannot switch on type %v", value.Type()) @@ -843,6 +844,14 @@ func (this *Tree) analyzeSwitch ( case *entity.LiteralInt: keyInt = int64(key.Value) case *entity.LiteralString: + if !integerOk { + return nil, errors.Errorf ( + key.Position(), + "cannot use string literal when " + + "switching on %v", + value.Type()) + } + switch { case width >= 32: keyInt = int64(key.ValueUTF32[0]) @@ -852,9 +861,17 @@ func (this *Tree) analyzeSwitch ( keyInt = int64(key.ValueUTF8[0]) } default: - return nil, errors.Errorf ( - key.Position(), "%v cannot represent a constant integer", - key) + return nil, errors.Errorf ( + key.Position(), + "%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 @@ -873,7 +890,7 @@ func (this *Tree) analyzeSwitch ( switc.Default.Expression = expression } - if into != nil && switc.Default != nil { + if into != nil && switc.Default == nil { return nil, errors.Errorf ( switc.Position(), "switch must have a default case")