Skip to content

Commit 6c554d6

Browse files
committed
pingpong poc
Signed-off-by: Jordan Rash <[email protected]>
1 parent 27fbf44 commit 6c554d6

File tree

6 files changed

+282
-67
lines changed

6 files changed

+282
-67
lines changed

Diff for: ast/type.go

+21-3
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,9 @@ func (t *InterfaceShape) shapeNode() {}
3232
func (t *InterfaceShape) TokenLiteral() string { return t.Token.Literal }
3333

3434
type WorldShape struct {
35-
Token token.Token
36-
Name *Identifier
37-
Value Expression
35+
Token token.Token
36+
Name *Identifier
37+
Children []Shape
3838
}
3939

4040
func (t *WorldShape) shapeNode() {}
@@ -106,3 +106,21 @@ type TupleShape struct {
106106

107107
func (t *TupleShape) shapeNode() {}
108108
func (t *TupleShape) TokenLiteral() string { return t.Token.Literal }
109+
110+
type ExportShape struct {
111+
Token token.Token
112+
Name *Identifier
113+
Value Expression
114+
}
115+
116+
func (t *ExportShape) shapeNode() {}
117+
func (t *ExportShape) TokenLiteral() string { return t.Token.Literal }
118+
119+
type FuncShape struct {
120+
Token token.Token
121+
Name *Identifier
122+
Value Expression
123+
}
124+
125+
func (t *FuncShape) shapeNode() {}
126+
func (t *FuncShape) TokenLiteral() string { return t.Token.Literal }

Diff for: cmd/main.go

+71-7
Original file line numberDiff line numberDiff line change
@@ -6,38 +6,102 @@ import (
66
"os"
77
"time"
88

9+
"github.com/jordan-rash/go-wit/ast"
910
"github.com/jordan-rash/go-wit/lexer"
1011
"github.com/jordan-rash/go-wit/parser"
1112
)
1213

1314
func main() {
14-
done := make(chan struct{}, 1)
15+
done := make(chan *ast.AST, 1)
1516

1617
ctxTimeout, cancel := context.WithTimeout(context.Background(), time.Second*3)
1718
defer cancel()
1819

1920
go parseWit(done)
2021

22+
var tree *ast.AST
23+
2124
select {
2225
case <-ctxTimeout.Done():
2326
panic(fmt.Errorf("time limit"))
24-
case <-done:
25-
fmt.Println("hit done")
27+
case tree = <-done:
28+
// fmt.Println("got tree")
29+
}
30+
31+
for _, s := range tree.Shapes {
32+
switch s.TokenLiteral() {
33+
case "package":
34+
tS, ok := s.(*ast.PackageShape)
35+
if !ok {
36+
// error
37+
}
38+
fmt.Println("Package: ", tS.Value)
39+
fmt.Println("Version: ", tS.Version)
40+
case "interface":
41+
tS, ok := s.(*ast.InterfaceShape)
42+
if !ok {
43+
// error
44+
}
45+
fmt.Println("Interface: ", tS.Name.Value)
46+
for _, c := range tS.Children {
47+
switch c.TokenLiteral() {
48+
case "type":
49+
tC, ok := c.(*ast.TypeStatement)
50+
if !ok {
51+
// error
52+
}
53+
fmt.Println("\t", tC.Name.TokenLiteral(), tC.Value.TokenLiteral())
54+
55+
case "use":
56+
tC, ok := c.(*ast.UseShape)
57+
if !ok {
58+
// error
59+
}
60+
fmt.Println("\t", tC.TokenLiteral(), tC.Value.TokenLiteral())
61+
default:
62+
// error
63+
}
64+
}
65+
case "world":
66+
tS, ok := s.(*ast.WorldShape)
67+
if !ok {
68+
// error
69+
}
70+
fmt.Println("World: ", tS.Name.Value)
71+
for _, c := range tS.Children {
72+
switch c.TokenLiteral() {
73+
case "export":
74+
tC, ok := c.(*ast.ExportShape)
75+
if !ok {
76+
// error
77+
}
78+
fmt.Println("\t", tC.Name.TokenLiteral(), tC.Value.TokenLiteral())
79+
80+
default:
81+
// error
82+
}
83+
}
84+
85+
default:
86+
// error
87+
}
2688
}
2789
}
2890

29-
func parseWit(done chan struct{}) {
30-
b, err := os.ReadFile("./core.wit")
91+
func parseWit(done chan *ast.AST) {
92+
b, err := os.ReadFile("./pingpong.wit")
3193
if err != nil {
3294
panic(err)
3395
}
3496

97+
fmt.Printf("Parsing the following file:\n\n```\n%s\n```\n\n", string(b))
98+
3599
p := parser.New(lexer.NewLexer(string(b)))
36-
p.Parse()
100+
t := p.Parse()
37101

38102
if p.Errors() != nil {
39103
panic(p.Errors())
40104
}
41105

42-
done <- struct{}{}
106+
done <- t
43107
}

Diff for: cmd/pingpong.wit

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package jordan-rash:pingpong@0.1.0
2+
3+
interface types {
4+
type pong = string
5+
}
6+
7+
interface pingpong {
8+
use types.{pong}
9+
ping: func() -> pong
10+
}
11+
12+
world ping-pong {
13+
export pingpong
14+
}

Diff for: parser/parser_test.go

+72-24
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ var (
5454
{"list<u16>", token.KEYWORD_TYPE, token.KEYWORD_U16},
5555
{"list<u32>", token.KEYWORD_TYPE, token.KEYWORD_U32},
5656
{"list<foo>", token.KEYWORD_TYPE, token.IDENTIFIER},
57-
// {"list<foo-bar>", token.KEYWORD_TYPE, token.IDENTIFIER},
57+
{"list<foo-bar>", token.KEYWORD_TYPE, token.IDENTIFIER},
5858
}
5959

6060
optionTests = tests{
@@ -72,7 +72,11 @@ var (
7272
{"option<u32>", token.KEYWORD_TYPE, token.KEYWORD_U32},
7373
{"option<u64>", token.KEYWORD_TYPE, token.KEYWORD_U64},
7474
{"option<foo>", token.KEYWORD_TYPE, token.IDENTIFIER},
75-
// {"option<foo-bar>", token.KEYWORD_TYPE, token.IDENTIFIER},
75+
{"option<foo-bar>", token.KEYWORD_TYPE, token.IDENTIFIER},
76+
}
77+
exportTests = tests{
78+
{"export derp", token.KEYWORD_EXPORT, token.IDENTIFIER},
79+
{"export foo-bar", token.KEYWORD_EXPORT, token.IDENTIFIER},
7680
}
7781
resultTests = []struct {
7882
input string
@@ -104,6 +108,37 @@ var (
104108
}
105109
)
106110

111+
func TestParsePingPong(t *testing.T) {
112+
input := `package jordan-rash:[email protected]
113+
114+
interface types {
115+
type pong = string
116+
}
117+
118+
interface pingpong {
119+
use types.{pong}
120+
ping: func() -> pong
121+
}
122+
123+
world ping-pong {
124+
export pingpong
125+
}
126+
`
127+
128+
// t.SkipNow()
129+
130+
p := New(lexer.NewLexer(input))
131+
ast := p.Parse()
132+
133+
assert.NoError(t, p.Errors())
134+
assert.NotNil(t, ast)
135+
136+
tokens := []string{token.KEYWORD_PACKAGE, token.KEYWORD_INTERFACE, token.KEYWORD_INTERFACE, token.KEYWORD_WORLD}
137+
for i, a := range ast.Shapes {
138+
assert.Equal(t, strings.ToLower(tokens[i]), a.TokenLiteral())
139+
}
140+
}
141+
107142
func TestRootShapes(t *testing.T) {
108143
tests := []struct {
109144
input string
@@ -150,6 +185,26 @@ func TestNestedInterfaceShapes(t *testing.T) {
150185
}
151186
}
152187

188+
func TestNestedWorldShapes(t *testing.T) {
189+
tmpl, err := template.New("test").Parse("world foo { {{ .Input }} }")
190+
assert.NoError(t, err)
191+
192+
for _, tt := range exportTests {
193+
sb := strings.Builder{}
194+
err = tmpl.Execute(&sb, tt)
195+
assert.NoError(t, err)
196+
197+
p := New(lexer.NewLexer(sb.String()))
198+
199+
tree := p.Parse()
200+
assert.NotNil(t, tree)
201+
assert.NoError(t, p.Errors())
202+
203+
assert.NotNil(t, tree)
204+
assert.Len(t, tree.Shapes, 1)
205+
}
206+
}
207+
153208
func TestTypeShape(t *testing.T) {
154209
for _, tt := range typeTests {
155210
p := New(lexer.NewLexer(tt.Input))
@@ -269,28 +324,21 @@ func TestTypePackageShape(t *testing.T) {
269324
}
270325
}
271326

272-
func TestParsePingPong(t *testing.T) {
273-
input := `package jordan-rash:[email protected]
274-
275-
interface types {
276-
type pong = string
277-
}
278-
279-
interface pingpong {
280-
use types.{pong}
281-
ping: func() -> pong
282-
}
283-
284-
world ping-pong {
285-
export pingpong
286-
}
287-
`
288-
289-
t.SkipNow()
327+
func TestExportShape(t *testing.T) {
328+
for _, tt := range exportTests {
329+
p := New(lexer.NewLexer(tt.Input))
290330

291-
p := New(lexer.NewLexer(input))
292-
ast := p.Parse()
331+
for p.peekToken.Type != token.END_OF_FILE {
332+
tempType := p.parseExportStatement()
333+
assert.NoError(t, p.Errors())
293334

294-
assert.NoError(t, p.Errors())
295-
assert.NotNil(t, ast)
335+
switch tT := tempType.Value.(type) {
336+
case *ast.Identifier:
337+
assert.Equal(t, tt.expectedType, string(tempType.Token.Type))
338+
assert.Equal(t, tt.expectedValueType, string(tT.Token.Type))
339+
case *ast.Child:
340+
assert.Equal(t, tt.expectedType, string(tempType.Token.Type))
341+
}
342+
}
343+
}
296344
}

0 commit comments

Comments
 (0)