pkg/compiler: switch attributes from Ident to Type

This allows parametrized attributes like size[10].
But this is not used for now.
This commit is contained in:
Dmitry Vyukov 2018-03-02 11:49:19 +01:00
parent db01d57e91
commit 5110ff445d
8 changed files with 48 additions and 19 deletions

View File

@ -102,7 +102,7 @@ type Struct struct {
Pos Pos
Name *Ident
Fields []*Field
Attrs []*Ident
Attrs []*Type
Comments []*Comment
IsUnion bool
}

View File

@ -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 {

View File

@ -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)

View File

@ -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)
}

View File

@ -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

View File

@ -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 {

View File

@ -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

View File

@ -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