aboutsummaryrefslogtreecommitdiffstats
path: root/pkg/compiler
diff options
context:
space:
mode:
authorPaul Chaignon <paul.chaignon@gmail.com>2024-09-08 11:37:59 +0200
committerAleksandr Nogikh <nogikh@google.com>2024-09-09 11:43:00 +0000
commite5005d1750564a41e2ae7fc840131133ded452d6 (patch)
tree87d4c0e0ab03d68d3c505f8ff477aea56097dfc3 /pkg/compiler
parent11cbc3b9349d6a8b0e2f98e4a877cfbf4f2774c4 (diff)
compiler: support constants in conditional fields
This commit adds support for using the value of constants in conditional fields in addition to integers and flags. Intuitively, this probably looks like it shouldn't be needed: constants are known so the condition can be resolved ahead of time. It is however useful in the case of templates (example in the next commit) where the type of a field may be interchangeably an integer or a constant: type example_t[TYPE] { f1 TYPE f2 int32 (if[value[f1] == 3]) } type example1 example_t[int64] type example2 example_t[const[0, int64]] Signed-off-by: Paul Chaignon <paul.chaignon@gmail.com>
Diffstat (limited to 'pkg/compiler')
-rw-r--r--pkg/compiler/check.go4
-rw-r--r--pkg/compiler/testdata/all.txt2
-rw-r--r--pkg/compiler/testdata/errors2.txt4
3 files changed, 6 insertions, 4 deletions
diff --git a/pkg/compiler/check.go b/pkg/compiler/check.go
index 5345e2e3f..3bda9cfe6 100644
--- a/pkg/compiler/check.go
+++ b/pkg/compiler/check.go
@@ -650,8 +650,8 @@ func (comp *compiler) checkPathField(target, t *ast.Type, field *ast.Field) bool
func (comp *compiler) checkExprLastField(target *ast.Type, field *ast.Field) {
_, desc := comp.derefPointers(field.Type)
- if desc != typeInt && desc != typeFlags {
- comp.error(target.Pos, "%v does not refer to an integer or a flag", field.Name.Name)
+ if desc != typeInt && desc != typeFlags && desc != typeConst {
+ comp.error(target.Pos, "%v does not refer to a constant, an integer, or a flag", field.Name.Name)
}
}
diff --git a/pkg/compiler/testdata/all.txt b/pkg/compiler/testdata/all.txt
index 68e85492d..098da4604 100644
--- a/pkg/compiler/testdata/all.txt
+++ b/pkg/compiler/testdata/all.txt
@@ -357,6 +357,8 @@ struct$conditional {
f1 int64 (if[value[f0] == 1])
f2 struct$conditional2
f3 union$conditional3
+ f4 const[0, int64]
+ f5 int64 (if[value[f4] == 0])
} [packed]
struct$conditional2 {
diff --git a/pkg/compiler/testdata/errors2.txt b/pkg/compiler/testdata/errors2.txt
index ffb2e5bc5..71e2aa5ad 100644
--- a/pkg/compiler/testdata/errors2.txt
+++ b/pkg/compiler/testdata/errors2.txt
@@ -470,11 +470,11 @@ conditional_fields {
f3 some_nested_flags
f4 int32 (if[value[f3:f1] != 0])
f5 int32 (if[value[f3:f2:f4] != 0]) ### value path f2 does not refer to a struct
- f6 int32 (if[value[f3:f4] != 0]) ### f4 does not refer to an integer or a flag
+ f6 int32 (if[value[f3:f4] != 0]) ### f4 does not refer to a constant, an integer, or a flag
f7 int32 (if[value[f3:some_field] != 0]) ### value target some_field does not exist in some_nested_flags
f8 int32 (if[value[f3:f5] != 0]) ### f5 has conditions, so value path cannot reference it
f9 int32 (if[value[parent:a] != 0]) ### value target a does not exist in conditional_fields
- f10 int32 (if[value[f3:f6] != 0]) ### f6 does not refer to an integer or a flag
+ f10 int32 (if[value[f3:f6] != 0]) ### f6 does not refer to a constant, an integer, or a flag
f11 len[f2, int32] ### f2 has conditions, so len path cannot reference it
f12 union_cond_fields
f13 int32:8 (if[1]) ### bitfields may not have conditions