Skip to content

Commit 7b75867

Browse files
authored
Merge pull request #3 from mgnsk/dev
Rewrite with more test coverage
2 parents 9c523cd + d989fac commit 7b75867

65 files changed

Lines changed: 8619 additions & 6024 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 101 additions & 211 deletions
Large diffs are not rendered by default.

ast/ast_test.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package ast_test
2+
3+
import (
4+
"testing"
5+
6+
"github.com/mgnsk/gong/internal/parser/lexer"
7+
"github.com/mgnsk/gong/internal/parser/parser"
8+
)
9+
10+
func parse(input string) (interface{}, error) {
11+
lex := lexer.NewLexer([]byte(input))
12+
p := parser.NewParser()
13+
return p.Parse(lex)
14+
}
15+
16+
func BenchmarkParser(b *testing.B) {
17+
lex := lexer.NewLexer([]byte(
18+
"[[[[[k*]/3].]$].8]))",
19+
))
20+
p := parser.NewParser()
21+
22+
b.ReportAllocs()
23+
b.ResetTimer()
24+
25+
for i := 0; i < b.N; i++ {
26+
lex.Reset()
27+
p.Reset()
28+
_, err := p.Parse(lex)
29+
if err != nil {
30+
b.Fatal(err)
31+
}
32+
}
33+
}

ast/bar.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package ast
2+
3+
import (
4+
"io"
5+
)
6+
7+
// Bar is a bar.
8+
type Bar struct {
9+
Name string
10+
DeclList NodeList
11+
}
12+
13+
func (b Bar) WriteTo(w io.Writer) (int64, error) {
14+
ew := newErrWriter(w)
15+
var n int
16+
17+
n += ew.WriteString(`bar "`)
18+
n += ew.WriteString(b.Name)
19+
n += ew.WriteString("\"\n")
20+
21+
for _, stmt := range b.DeclList {
22+
n += ew.WriteString("\t")
23+
n += ew.CopyFrom(stmt)
24+
n += ew.WriteString("\n")
25+
}
26+
27+
n += ew.WriteString("end")
28+
29+
return int64(n), ew.Flush()
30+
}
31+
32+
// NewBar creates a new bar.
33+
func NewBar(name string, declList NodeList) Bar {
34+
return Bar{Name: name, DeclList: declList}
35+
}

ast/bar_test.go

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package ast_test
2+
3+
import (
4+
"bytes"
5+
"fmt"
6+
"strings"
7+
"testing"
8+
9+
"github.com/mgnsk/gong/ast"
10+
. "github.com/onsi/gomega"
11+
)
12+
13+
func TestBar(t *testing.T) {
14+
g := NewGomegaWithT(t)
15+
16+
input1 := `
17+
18+
tempo 120
19+
timesig 1 4
20+
channel 1
21+
velocity 20
22+
program 1
23+
control 1 1
24+
assign c 60
25+
assign d 62
26+
bar "Bar 1"
27+
start
28+
c
29+
stop
30+
end
31+
play "Bar 1"
32+
33+
`
34+
35+
input2 := `
36+
tempo 120; timesig 1 4; channel 1; velocity 20;
37+
program 1; control 1 1
38+
assign c 60; assign d 62
39+
bar "Bar 1" start; c; stop; end
40+
play "Bar 1"
41+
`
42+
43+
res1, err := parse(input1)
44+
g.Expect(err).NotTo(HaveOccurred())
45+
g.Expect(res1).To(BeAssignableToTypeOf(ast.NodeList{}))
46+
47+
var buf1 bytes.Buffer
48+
res1.(ast.NodeList).WriteTo(&buf1)
49+
50+
g.Expect(buf1.String()).To(Equal(strings.Trim(input1, " \n")))
51+
52+
res2, err := parse(input2)
53+
g.Expect(err).NotTo(HaveOccurred())
54+
g.Expect(res2).To(BeAssignableToTypeOf(ast.NodeList{}))
55+
g.Expect(res2).To(Equal(res1))
56+
57+
var buf2 bytes.Buffer
58+
res2.(ast.NodeList).WriteTo(&buf2)
59+
g.Expect(buf2.String()).To(Equal(strings.Trim(input1, " \n")))
60+
}
61+
62+
func TestCommandsForbiddenInBar(t *testing.T) {
63+
for _, input := range []string{
64+
"assign c 60",
65+
`bar "Inner" start end`,
66+
`play "test"`,
67+
} {
68+
t.Run(input, func(t *testing.T) {
69+
g := NewGomegaWithT(t)
70+
71+
_, err := parse(fmt.Sprintf(`bar "Outer" %s; end`, input))
72+
g.Expect(err).To(HaveOccurred())
73+
g.Expect(err.Error()).To(ContainSubstring(`got:`))
74+
})
75+
}
76+
}
Lines changed: 154 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
package ast
22

33
import (
4+
"io"
45
"math"
56

6-
"github.com/mgnsk/gong/internal/constants"
7+
"github.com/mgnsk/gong/constants"
78
"github.com/mgnsk/gong/internal/parser/token"
89
)
910

@@ -13,6 +14,22 @@ type CmdAssign struct {
1314
Key uint8
1415
}
1516

17+
func (c CmdAssign) WriteTo(w io.Writer) (int64, error) {
18+
ew := newErrWriter(w)
19+
var n int
20+
21+
n += ew.WriteString("assign ")
22+
n += ew.WriteRune(c.Note)
23+
n += ew.WriteString(" ")
24+
n += ew.WriteInt(int(c.Key))
25+
26+
return int64(n), ew.Flush()
27+
}
28+
29+
// func (c CmdAssign) String() string {
30+
// return fmt.Sprintf("assign %c %d", c.Note, c.Key)
31+
// }
32+
1633
// NewCmdAssign creates a note assignment command.
1734
func NewCmdAssign(note, key *token.Token) (CmdAssign, error) {
1835
v, err := key.Int32Value()
@@ -31,6 +48,20 @@ func NewCmdAssign(note, key *token.Token) (CmdAssign, error) {
3148
// CmdTempo is a tempo command.
3249
type CmdTempo uint16
3350

51+
func (c CmdTempo) WriteTo(w io.Writer) (int64, error) {
52+
ew := newErrWriter(w)
53+
var n int
54+
55+
n += ew.WriteString("tempo ")
56+
n += ew.WriteInt(int(c))
57+
58+
return int64(n), ew.Flush()
59+
}
60+
61+
// func (c CmdTempo) String() string {
62+
// return fmt.Sprintf("tempo %d", c)
63+
// }
64+
3465
// NewCmdTempo creates a tempo command.
3566
func NewCmdTempo(bpm *token.Token) (CmdTempo, error) {
3667
v, err := bpm.Int32Value()
@@ -45,17 +76,33 @@ func NewCmdTempo(bpm *token.Token) (CmdTempo, error) {
4576

4677
// CmdTimeSig is a time signature change command.
4778
type CmdTimeSig struct {
48-
Beats uint8
49-
Value uint8
79+
Num uint8
80+
Denom uint8
81+
}
82+
83+
func (c CmdTimeSig) WriteTo(w io.Writer) (int64, error) {
84+
ew := newErrWriter(w)
85+
var n int
86+
87+
n += ew.WriteString("timesig ")
88+
n += ew.WriteInt(int(c.Num))
89+
n += ew.WriteString(" ")
90+
n += ew.WriteInt(int(c.Denom))
91+
92+
return int64(n), ew.Flush()
5093
}
5194

95+
// func (c CmdTimeSig) String() string {
96+
// return fmt.Sprintf("timesig %d %d", c.Num, c.Denom)
97+
// }
98+
5299
// NewCmdTimeSig creates a time signature change command.
53-
func NewCmdTimeSig(beats, value *token.Token) (CmdTimeSig, error) {
54-
b, err := beats.Int32Value()
100+
func NewCmdTimeSig(num, denom *token.Token) (CmdTimeSig, error) {
101+
b, err := num.Int32Value()
55102
if err != nil {
56103
return CmdTimeSig{}, err
57104
}
58-
v, err := value.Int32Value()
105+
v, err := denom.Int32Value()
59106
if err != nil {
60107
return CmdTimeSig{}, err
61108
}
@@ -66,14 +113,28 @@ func NewCmdTimeSig(beats, value *token.Token) (CmdTimeSig, error) {
66113
return CmdTimeSig{}, err
67114
}
68115
return CmdTimeSig{
69-
Beats: uint8(b),
70-
Value: uint8(v),
116+
Num: uint8(b),
117+
Denom: uint8(v),
71118
}, nil
72119
}
73120

74121
// CmdChannel is a channel change command.
75122
type CmdChannel uint8
76123

124+
func (c CmdChannel) WriteTo(w io.Writer) (int64, error) {
125+
ew := newErrWriter(w)
126+
var n int
127+
128+
n += ew.WriteString("channel ")
129+
n += ew.WriteInt(int(c))
130+
131+
return int64(n), ew.Flush()
132+
}
133+
134+
// func (c CmdChannel) String() string {
135+
// return fmt.Sprintf("channel %d", c)
136+
// }
137+
77138
// NewCmdChannel creates a channel change command.
78139
func NewCmdChannel(value *token.Token) (CmdChannel, error) {
79140
v, err := value.Int32Value()
@@ -89,6 +150,20 @@ func NewCmdChannel(value *token.Token) (CmdChannel, error) {
89150
// CmdVelocity is a velocity change command.
90151
type CmdVelocity uint8
91152

153+
func (c CmdVelocity) WriteTo(w io.Writer) (int64, error) {
154+
ew := newErrWriter(w)
155+
var n int
156+
157+
n += ew.WriteString("velocity ")
158+
n += ew.WriteInt(int(c))
159+
160+
return int64(n), ew.Flush()
161+
}
162+
163+
// func (c CmdVelocity) String() string {
164+
// return fmt.Sprintf("velocity %d", c)
165+
// }
166+
92167
// NewCmdVelocity creates a velocity change command.
93168
func NewCmdVelocity(value *token.Token) (CmdVelocity, error) {
94169
v, err := value.Int32Value()
@@ -104,6 +179,20 @@ func NewCmdVelocity(value *token.Token) (CmdVelocity, error) {
104179
// CmdProgram is a program change command.
105180
type CmdProgram uint8
106181

182+
func (c CmdProgram) WriteTo(w io.Writer) (int64, error) {
183+
ew := newErrWriter(w)
184+
var n int
185+
186+
n += ew.WriteString("program ")
187+
n += ew.WriteInt(int(c))
188+
189+
return int64(n), ew.Flush()
190+
}
191+
192+
// func (c CmdProgram) String() string {
193+
// return fmt.Sprintf("program %d", c)
194+
// }
195+
107196
// NewCmdProgram creates a program change command.
108197
func NewCmdProgram(value *token.Token) (CmdProgram, error) {
109198
v, err := value.Int32Value()
@@ -122,6 +211,22 @@ type CmdControl struct {
122211
Parameter uint8
123212
}
124213

214+
func (c CmdControl) WriteTo(w io.Writer) (int64, error) {
215+
ew := newErrWriter(w)
216+
var n int
217+
218+
n += ew.WriteString("control ")
219+
n += ew.WriteInt(int(c.Control))
220+
n += ew.WriteString(" ")
221+
n += ew.WriteInt(int(c.Parameter))
222+
223+
return int64(n), ew.Flush()
224+
}
225+
226+
// func (c CmdControl) String() string {
227+
// return fmt.Sprintf("control %d %d", c.Control, c.Parameter)
228+
// }
229+
125230
// NewCmdControl creates a control change command.
126231
func NewCmdControl(control, value *token.Token) (CmdControl, error) {
127232
c, err := control.Int32Value()
@@ -144,17 +249,52 @@ func NewCmdControl(control, value *token.Token) (CmdControl, error) {
144249
}, nil
145250
}
146251

147-
// CmdBar is a bar begin command.
148-
type CmdBar string
149-
150-
// CmdEnd is a bar end command.
151-
type CmdEnd struct{}
152-
153252
// CmdPlay is a bar play command.
154253
type CmdPlay string
155254

255+
func (c CmdPlay) WriteTo(w io.Writer) (int64, error) {
256+
ew := newErrWriter(w)
257+
var n int
258+
259+
n += ew.WriteString("play \"")
260+
n += ew.WriteString(string(c))
261+
n += ew.WriteString("\"")
262+
263+
return int64(n), ew.Flush()
264+
}
265+
266+
// func (c CmdPlay) String() string {
267+
// return fmt.Sprintf(`play "%s"`, string(c))
268+
// }
269+
156270
// CmdStart is a start commad.
157271
type CmdStart struct{}
158272

273+
func (c CmdStart) WriteTo(w io.Writer) (int64, error) {
274+
ew := newErrWriter(w)
275+
var n int
276+
277+
n += ew.WriteString("start")
278+
279+
return int64(n), ew.Flush()
280+
}
281+
282+
// func (c CmdStart) String() string {
283+
// return "start"
284+
// }
285+
159286
// CmdStop is a stop command.
160287
type CmdStop struct{}
288+
289+
func (c CmdStop) WriteTo(w io.Writer) (int64, error) {
290+
ew := newErrWriter(w)
291+
var n int
292+
293+
n += ew.WriteString("stop")
294+
295+
return int64(n), ew.Flush()
296+
}
297+
298+
// func (c CmdStop) String() string {
299+
// return "stop"
300+
// }

0 commit comments

Comments
 (0)