aboutsummaryrefslogtreecommitdiffstats
path: root/pkg
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2018-03-02 11:49:19 +0100
committerDmitry Vyukov <dvyukov@google.com>2018-03-05 12:10:27 +0100
commit5110ff445ddb5a09a13e17b187c06d2dc3a7d52a (patch)
tree4a482d23c3e284e996539a1677dee246e9e7b0a5 /pkg
parentdb01d57e9144125b368d14815d08e897ff496604 (diff)
pkg/compiler: switch attributes from Ident to Type
This allows parametrized attributes like size[10]. But this is not used for now.
Diffstat (limited to 'pkg')
-rw-r--r--pkg/ast/ast.go2
-rw-r--r--pkg/ast/clone.go4
-rw-r--r--pkg/ast/format.go13
-rw-r--r--pkg/ast/parser.go4
-rw-r--r--pkg/ast/testdata/all.txt4
-rw-r--r--pkg/compiler/check.go6
-rw-r--r--pkg/compiler/compiler.go22
-rw-r--r--pkg/compiler/testdata/errors.txt12
8 files changed, 48 insertions, 19 deletions
diff --git a/pkg/ast/ast.go b/pkg/ast/ast.go
index f7d5b8b32..723d6d9c4 100644
--- a/pkg/ast/ast.go
+++ b/pkg/ast/ast.go
@@ -102,7 +102,7 @@ type Struct struct {
Pos Pos
Name *Ident
Fields []*Field
- Attrs []*Ident
+ Attrs []*Type
Comments []*Comment
IsUnion bool
}
diff --git a/pkg/ast/clone.go b/pkg/ast/clone.go
index b754b7650..4c938b807 100644
--- a/pkg/ast/clone.go
+++ b/pkg/ast/clone.go
@@ -105,9 +105,9 @@ func (n *Struct) Clone() Node {
for _, f := range n.Fields {
fields = append(fields, f.Clone().(*Field))
}
- var attrs []*Ident
+ var attrs []*Type
for _, a := range n.Attrs {
- attrs = append(attrs, a.Clone().(*Ident))
+ attrs = append(attrs, a.Clone().(*Type))
}
var comments []*Comment
for _, c := range n.Comments {
diff --git a/pkg/ast/format.go b/pkg/ast/format.go
index a7e0f568f..cf7edf975 100644
--- a/pkg/ast/format.go
+++ b/pkg/ast/format.go
@@ -68,7 +68,7 @@ func (res *Resource) serialize(w io.Writer) {
}
func (typedef *TypeDef) serialize(w io.Writer) {
- fmt.Fprintf(w, "type %v%v", typedef.Name.Name, fmtIdentList(typedef.Args, false))
+ fmt.Fprintf(w, "type %v%v", typedef.Name.Name, fmtIdentList(typedef.Args))
if typedef.Type != nil {
fmt.Fprintf(w, " %v\n", fmtType(typedef.Type))
}
@@ -120,7 +120,11 @@ func (str *Struct) serialize(w io.Writer) {
for _, com := range str.Comments {
fmt.Fprintf(w, "#%v\n", com.Text)
}
- fmt.Fprintf(w, "%c%v\n", closing, fmtIdentList(str.Attrs, true))
+ fmt.Fprintf(w, "%c", closing)
+ if attrs := fmtTypeList(str.Attrs); attrs != "" {
+ fmt.Fprintf(w, " %v", attrs)
+ }
+ fmt.Fprintf(w, "\n")
}
func (flags *IntFlags) serialize(w io.Writer) {
@@ -182,14 +186,11 @@ func fmtTypeList(args []*Type) string {
return w.String()
}
-func fmtIdentList(args []*Ident, space bool) string {
+func fmtIdentList(args []*Ident) string {
if len(args) == 0 {
return ""
}
w := new(bytes.Buffer)
- if space {
- fmt.Fprintf(w, " ")
- }
fmt.Fprintf(w, "[")
for i, arg := range args {
fmt.Fprintf(w, "%v%v", comma(i, ""), arg.Name)
diff --git a/pkg/ast/parser.go b/pkg/ast/parser.go
index a7cfdbf02..b28658de8 100644
--- a/pkg/ast/parser.go
+++ b/pkg/ast/parser.go
@@ -376,9 +376,9 @@ func (p *parser) parseStruct(name *Ident) *Struct {
p.consume(tokNewLine)
}
if p.tryConsume(tokLBrack) {
- str.Attrs = append(str.Attrs, p.parseIdent())
+ str.Attrs = append(str.Attrs, p.parseType())
for p.tryConsume(tokComma) {
- str.Attrs = append(str.Attrs, p.parseIdent())
+ str.Attrs = append(str.Attrs, p.parseType())
}
p.consume(tokRBrack)
}
diff --git a/pkg/ast/testdata/all.txt b/pkg/ast/testdata/all.txt
index ede11a88a..7e1db7309 100644
--- a/pkg/ast/testdata/all.txt
+++ b/pkg/ast/testdata/all.txt
@@ -46,6 +46,10 @@ s2 {
}
+s3 {
+ f1 int8
+} [attribute[1, "foo"], another[and[another]]]
+
type mybool8 int8
type net_port proc[1, 2, int16be]
type mybool16 ### unexpected '\n', expecting '[', identifier
diff --git a/pkg/compiler/check.go b/pkg/compiler/check.go
index 57ef5b995..58738fa3e 100644
--- a/pkg/compiler/check.go
+++ b/pkg/compiler/check.go
@@ -535,6 +535,12 @@ func (comp *compiler) checkStruct(ctx checkCtx, n *ast.Struct) {
for _, f := range n.Fields {
comp.checkType(ctx, f.Type, flags)
}
+ for _, attr := range n.Attrs {
+ if attr.Ident == "" || attr.HasColon {
+ comp.error(attr.Pos, "bad struct/union attribute")
+ return
+ }
+ }
if n.IsUnion {
comp.parseUnionAttrs(n)
} else {
diff --git a/pkg/compiler/compiler.go b/pkg/compiler/compiler.go
index 918d25136..8e20a4e67 100644
--- a/pkg/compiler/compiler.go
+++ b/pkg/compiler/compiler.go
@@ -138,12 +138,15 @@ func (comp *compiler) warning(pos ast.Pos, msg string, args ...interface{}) {
func (comp *compiler) parseUnionAttrs(n *ast.Struct) (varlen bool) {
for _, attr := range n.Attrs {
- switch attr.Name {
+ switch attr.Ident {
case "varlen":
varlen = true
default:
comp.error(attr.Pos, "unknown union %v attribute %v",
- n.Name.Name, attr.Name)
+ n.Name.Name, attr.Ident)
+ }
+ if len(attr.Args) != 0 {
+ comp.error(attr.Pos, "%v attribute had args", attr.Ident)
}
}
return
@@ -152,15 +155,15 @@ func (comp *compiler) parseUnionAttrs(n *ast.Struct) (varlen bool) {
func (comp *compiler) parseStructAttrs(n *ast.Struct) (packed bool, align uint64) {
for _, attr := range n.Attrs {
switch {
- case attr.Name == "packed":
+ case attr.Ident == "packed":
packed = true
- case attr.Name == "align_ptr":
+ case attr.Ident == "align_ptr":
align = comp.ptrSize
- case strings.HasPrefix(attr.Name, "align_"):
- a, err := strconv.ParseUint(attr.Name[6:], 10, 64)
+ case strings.HasPrefix(attr.Ident, "align_"):
+ a, err := strconv.ParseUint(attr.Ident[6:], 10, 64)
if err != nil {
comp.error(attr.Pos, "bad struct %v alignment %v",
- n.Name.Name, attr.Name[6:])
+ n.Name.Name, attr.Ident[6:])
continue
}
if a&(a-1) != 0 || a == 0 || a > 1<<30 {
@@ -170,7 +173,10 @@ func (comp *compiler) parseStructAttrs(n *ast.Struct) (packed bool, align uint64
align = a
default:
comp.error(attr.Pos, "unknown struct %v attribute %v",
- n.Name.Name, attr.Name)
+ n.Name.Name, attr.Ident)
+ }
+ if len(attr.Args) != 0 {
+ comp.error(attr.Pos, "%v attribute had args", attr.Ident)
}
}
return
diff --git a/pkg/compiler/testdata/errors.txt b/pkg/compiler/testdata/errors.txt
index 8ea03bc7b..2b3a7539f 100644
--- a/pkg/compiler/testdata/errors.txt
+++ b/pkg/compiler/testdata/errors.txt
@@ -160,6 +160,18 @@ s7 {
f1 ptr64[in, int32]
}
+s8 {
+ f1 int8
+} [unknown] ### unknown struct s8 attribute unknown
+
+s9 {
+ f1 int8
+} ["foo"[0]] ### bad struct/union attribute
+
+s10 {
+ f1 int8
+} [packed[0]] ### packed attribute had args
+
u3 [
f1 int8
f2 int32