Skip to content

Commit c3e88c4

Browse files
committed
Added draft CLI interface with autocompletion
1 parent da3139b commit c3e88c4

File tree

3 files changed

+229
-242
lines changed

3 files changed

+229
-242
lines changed

transform/isa.go

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
package transform
2+
3+
import (
4+
"strings"
5+
6+
"alon.kr/x/faststringmap"
7+
"alon.kr/x/usm/gen"
8+
)
9+
10+
type InstructionSet struct {
11+
Name string
12+
Aliases []string
13+
Description string
14+
Extensions []string
15+
16+
GenerationContext gen.GenerationContext
17+
18+
Transformations TransformationCollection
19+
}
20+
21+
type InstructionSetCollection struct {
22+
InstructionSets []*InstructionSet
23+
NameToInstructionSet faststringmap.Map[*InstructionSet]
24+
}
25+
26+
func NewIsaCollection(
27+
instructionSets ...*InstructionSet,
28+
) *InstructionSetCollection {
29+
entries := []faststringmap.MapEntry[*InstructionSet]{}
30+
for _, set := range instructionSets {
31+
entries = append(entries, faststringmap.MapEntry[*InstructionSet]{
32+
Key: set.Name,
33+
Value: set,
34+
})
35+
36+
for _, alias := range set.Aliases {
37+
entries = append(entries, faststringmap.MapEntry[*InstructionSet]{
38+
Key: alias,
39+
Value: set,
40+
})
41+
}
42+
}
43+
44+
return &InstructionSetCollection{
45+
InstructionSets: instructionSets,
46+
NameToInstructionSet: faststringmap.NewMap(entries),
47+
}
48+
}
49+
50+
func (c *InstructionSetCollection) TransformationNames() []string {
51+
names := []string{}
52+
for _, set := range c.InstructionSets {
53+
names = append(names, set.Transformations.Names()...)
54+
}
55+
return names
56+
}
57+
58+
func (c *InstructionSetCollection) Traverse(
59+
start *InstructionSet,
60+
transformations []string,
61+
) *InstructionSet {
62+
isa := start
63+
for _, transName := range transformations {
64+
trans, ok := isa.Transformations.NameToTransformation.LookupString(transName)
65+
if !ok {
66+
return nil
67+
}
68+
69+
isaName := trans.Target
70+
isa, ok = c.NameToInstructionSet.LookupString(isaName)
71+
if !ok {
72+
return nil
73+
}
74+
}
75+
76+
return isa
77+
}
78+
79+
// Infer the instruction set from the filename extension.
80+
// Returns nil if no matching instruction set is found.
81+
// If multiple instruction sets match the filename, the one that matches with
82+
// the longest prefix is returned.
83+
func (c *InstructionSetCollection) FilenameToInstructionSet(
84+
filename string,
85+
) *InstructionSet {
86+
// TODO: this can be implemented in linear time with, for example, a trie of
87+
// reversed prefixes, and traversal of the filename from the end. (faststringmap)
88+
89+
longest := 0
90+
var longestSet *InstructionSet
91+
92+
for _, set := range c.InstructionSets {
93+
for _, ext := range set.Extensions {
94+
if strings.HasSuffix(filename, ext) {
95+
if len(ext) > longest {
96+
longest = len(ext)
97+
longestSet = set
98+
}
99+
}
100+
}
101+
}
102+
103+
return longestSet
104+
}

transform/transformation.go

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package transform
2+
3+
import (
4+
"alon.kr/x/faststringmap"
5+
"alon.kr/x/usm/core"
6+
"alon.kr/x/usm/gen"
7+
)
8+
9+
type Transformation struct {
10+
Name string
11+
Aliases []string
12+
Description string
13+
14+
// The name of the target ISA of this transformation.
15+
Target string
16+
17+
// Transform takes a file in the input ISA, and returns a file in the
18+
// output ISA.
19+
//
20+
// The transformation may modify, and possibly invalidate the input
21+
// structure.
22+
Transform func(*gen.FileInfo) (*gen.FileInfo, core.ResultList)
23+
}
24+
25+
type TransformationCollection struct {
26+
Transformations []*Transformation
27+
NameToTransformation faststringmap.Map[*Transformation]
28+
}
29+
30+
func (c *TransformationCollection) Names() []string {
31+
names := []string{}
32+
for _, t := range c.Transformations {
33+
names = append(names, t.Name)
34+
names = append(names, t.Aliases...)
35+
}
36+
return names
37+
}
38+
39+
func NewTransformationCollection(transformations ...*Transformation) *TransformationCollection {
40+
entries := []faststringmap.MapEntry[*Transformation]{}
41+
for _, t := range transformations {
42+
entries = append(entries, faststringmap.MapEntry[*Transformation]{
43+
Key: t.Name,
44+
Value: t,
45+
})
46+
for _, alias := range t.Aliases {
47+
entries = append(entries, faststringmap.MapEntry[*Transformation]{
48+
Key: alias,
49+
Value: t,
50+
})
51+
}
52+
}
53+
54+
return &TransformationCollection{
55+
Transformations: transformations,
56+
NameToTransformation: faststringmap.NewMap(entries),
57+
}
58+
}

0 commit comments

Comments
 (0)