1
2
3
4
5 package specexpr
6
7 import (
8 "fmt"
9 "strings"
10 )
11
12
13 const MinWidth = Int(128)
14
15 type Type interface {
16 isType()
17 String() string
18 }
19
20 type Basic struct {
21 Base string
22 Bits Int
23 }
24
25 var MakeBasic = MakeFunc2("Basic", func(base string, bits Int) (any, error) {
26
27 bits = max(8, bits)
28 return Basic{Base: base, Bits: bits}, nil
29 })
30
31 func (t Basic) isType() {}
32 func (t Basic) String() string {
33 if t.Bits == 0 {
34 return t.Base
35 }
36 return fmt.Sprintf("%s%d", t.Base, t.Bits)
37 }
38
39 type Vector struct {
40 Elem Basic
41 Width Num
42 }
43
44 var MakeVector = MakeFunc2("VectorW", func(elem Basic, w Num) (any, error) {
45 if !w.ValidWidth() {
46 return nil, fmt.Errorf("invalid width %s", w)
47 }
48 return Vector{Elem: elem, Width: w}, nil
49 })
50
51 var makeVectorL = MakeFunc2("VectorL", func(elem Basic, l Num) (any, error) {
52 w, _ := l.Mul(elem.Bits)
53 if w2, ok := w.(Int); ok {
54
55 w = max(MinWidth, w2)
56 }
57 if !w.ValidWidth() {
58 return nil, fmt.Errorf("invalid width %s", w)
59 }
60 return Vector{Elem: elem, Width: w}, nil
61 })
62
63 func (t Vector) isType() {}
64 func (t Vector) String() string {
65 var buf strings.Builder
66 if t.Elem.Base == "" {
67 buf.WriteString("<bad Elem>")
68 } else {
69 buf.WriteString(strings.ToTitle(t.Elem.Base[:1]))
70 buf.WriteString(t.Elem.Base[1:])
71 fmt.Fprintf(&buf, "%d", t.Elem.Bits)
72 }
73 if t.Scalable() {
74 buf.WriteString("s")
75 } else {
76 l, err := t.Width.Div(t.Elem.Bits)
77 if err == nil {
78 fmt.Fprintf(&buf, "x%d", l)
79 } else {
80
81 fmt.Fprintf(&buf, "w%s", t.Width)
82 }
83 }
84 return buf.String()
85 }
86 func (t Vector) Scalable() bool {
87 sw, ok := t.Width.(ScalableWidth)
88 return ok && sw.ValidWidth()
89 }
90
91 type Pointer struct {
92 Elem Type
93 }
94
95 var MakePointer = MakeFunc1("Pointer", func(elem Type) (any, error) {
96 return Pointer{elem}, nil
97 })
98
99 func (t Pointer) isType() {}
100 func (t Pointer) String() string {
101 return "*" + t.Elem.String()
102 }
103
104 type Array struct {
105 Elem Type
106 Len Int
107 }
108
109 var MakeArray = MakeFunc2("Array", func(elem Type, len Int) (any, error) {
110 return Array{elem, len}, nil
111 })
112
113 func (t Array) isType() {}
114 func (t Array) String() string {
115 return fmt.Sprintf("[%d]%s", t.Len, t.Elem)
116 }
117
118 type Slice struct {
119 Elem Type
120 }
121
122 var MakeSlice = MakeFunc1("Slice", func(elem Type) (any, error) {
123 return Slice{elem}, nil
124 })
125
126 func (t Slice) isType() {}
127 func (t Slice) String() string {
128 return "[]" + t.Elem.String()
129 }
130
View as plain text