Skip to content

Commit 1c6512e

Browse files
committed
fix: add some basics
1 parent 560ba2d commit 1c6512e

31 files changed

+4656
-1
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,4 @@
1919

2020
# Go workspace file
2121
go.work
22+
.monkey/main.go

.ignore-inspiration/ast/ast.go

Lines changed: 339 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,339 @@
1+
package ast
2+
3+
import (
4+
"bytes"
5+
"monkey/token"
6+
"strings"
7+
)
8+
9+
// The base Node interface
10+
type Node interface {
11+
TokenLiteral() string
12+
String() string
13+
}
14+
15+
// All statement nodes implement this
16+
type Statement interface {
17+
Node
18+
statementNode()
19+
}
20+
21+
// All expression nodes implement this
22+
type Expression interface {
23+
Node
24+
expressionNode()
25+
}
26+
27+
type Program struct {
28+
Statements []Statement
29+
}
30+
31+
func (p *Program) TokenLiteral() string {
32+
if len(p.Statements) > 0 {
33+
return p.Statements[0].TokenLiteral()
34+
} else {
35+
return ""
36+
}
37+
}
38+
39+
func (p *Program) String() string {
40+
var out bytes.Buffer
41+
42+
for _, s := range p.Statements {
43+
out.WriteString(s.String())
44+
}
45+
46+
return out.String()
47+
}
48+
49+
// Statements
50+
type LetStatement struct {
51+
Token token.Token // the token.LET token
52+
Name *Identifier
53+
Value Expression
54+
}
55+
56+
func (ls *LetStatement) statementNode() {}
57+
func (ls *LetStatement) TokenLiteral() string { return ls.Token.Literal }
58+
func (ls *LetStatement) String() string {
59+
var out bytes.Buffer
60+
61+
out.WriteString(ls.TokenLiteral() + " ")
62+
out.WriteString(ls.Name.String())
63+
out.WriteString(" = ")
64+
65+
if ls.Value != nil {
66+
out.WriteString(ls.Value.String())
67+
}
68+
69+
out.WriteString(";")
70+
71+
return out.String()
72+
}
73+
74+
type ReturnStatement struct {
75+
Token token.Token // the 'return' token
76+
ReturnValue Expression
77+
}
78+
79+
func (rs *ReturnStatement) statementNode() {}
80+
func (rs *ReturnStatement) TokenLiteral() string { return rs.Token.Literal }
81+
func (rs *ReturnStatement) String() string {
82+
var out bytes.Buffer
83+
84+
out.WriteString(rs.TokenLiteral() + " ")
85+
86+
if rs.ReturnValue != nil {
87+
out.WriteString(rs.ReturnValue.String())
88+
}
89+
90+
out.WriteString(";")
91+
92+
return out.String()
93+
}
94+
95+
type ExpressionStatement struct {
96+
Token token.Token // the first token of the expression
97+
Expression Expression
98+
}
99+
100+
func (es *ExpressionStatement) statementNode() {}
101+
func (es *ExpressionStatement) TokenLiteral() string { return es.Token.Literal }
102+
func (es *ExpressionStatement) String() string {
103+
if es.Expression != nil {
104+
return es.Expression.String()
105+
}
106+
return ""
107+
}
108+
109+
type BlockStatement struct {
110+
Token token.Token // the { token
111+
Statements []Statement
112+
}
113+
114+
func (bs *BlockStatement) statementNode() {}
115+
func (bs *BlockStatement) TokenLiteral() string { return bs.Token.Literal }
116+
func (bs *BlockStatement) String() string {
117+
var out bytes.Buffer
118+
119+
for _, s := range bs.Statements {
120+
out.WriteString(s.String())
121+
}
122+
123+
return out.String()
124+
}
125+
126+
// Expressions
127+
type Identifier struct {
128+
Token token.Token // the token.IDENT token
129+
Value string
130+
}
131+
132+
func (i *Identifier) expressionNode() {}
133+
func (i *Identifier) TokenLiteral() string { return i.Token.Literal }
134+
func (i *Identifier) String() string { return i.Value }
135+
136+
type Boolean struct {
137+
Token token.Token
138+
Value bool
139+
}
140+
141+
func (b *Boolean) expressionNode() {}
142+
func (b *Boolean) TokenLiteral() string { return b.Token.Literal }
143+
func (b *Boolean) String() string { return b.Token.Literal }
144+
145+
type IntegerLiteral struct {
146+
Token token.Token
147+
Value int64
148+
}
149+
150+
func (il *IntegerLiteral) expressionNode() {}
151+
func (il *IntegerLiteral) TokenLiteral() string { return il.Token.Literal }
152+
func (il *IntegerLiteral) String() string { return il.Token.Literal }
153+
154+
type PrefixExpression struct {
155+
Token token.Token // The prefix token, e.g. !
156+
Operator string
157+
Right Expression
158+
}
159+
160+
func (pe *PrefixExpression) expressionNode() {}
161+
func (pe *PrefixExpression) TokenLiteral() string { return pe.Token.Literal }
162+
func (pe *PrefixExpression) String() string {
163+
var out bytes.Buffer
164+
165+
out.WriteString("(")
166+
out.WriteString(pe.Operator)
167+
out.WriteString(pe.Right.String())
168+
out.WriteString(")")
169+
170+
return out.String()
171+
}
172+
173+
type InfixExpression struct {
174+
Token token.Token // The operator token, e.g. +
175+
Left Expression
176+
Operator string
177+
Right Expression
178+
}
179+
180+
func (ie *InfixExpression) expressionNode() {}
181+
func (ie *InfixExpression) TokenLiteral() string { return ie.Token.Literal }
182+
func (ie *InfixExpression) String() string {
183+
var out bytes.Buffer
184+
185+
out.WriteString("(")
186+
out.WriteString(ie.Left.String())
187+
out.WriteString(" " + ie.Operator + " ")
188+
out.WriteString(ie.Right.String())
189+
out.WriteString(")")
190+
191+
return out.String()
192+
}
193+
194+
type IfExpression struct {
195+
Token token.Token // The 'if' token
196+
Condition Expression
197+
Consequence *BlockStatement
198+
Alternative *BlockStatement
199+
}
200+
201+
func (ie *IfExpression) expressionNode() {}
202+
func (ie *IfExpression) TokenLiteral() string { return ie.Token.Literal }
203+
func (ie *IfExpression) String() string {
204+
var out bytes.Buffer
205+
206+
out.WriteString("if")
207+
out.WriteString(ie.Condition.String())
208+
out.WriteString(" ")
209+
out.WriteString(ie.Consequence.String())
210+
211+
if ie.Alternative != nil {
212+
out.WriteString("else ")
213+
out.WriteString(ie.Alternative.String())
214+
}
215+
216+
return out.String()
217+
}
218+
219+
type FunctionLiteral struct {
220+
Token token.Token // The 'fn' token
221+
Parameters []*Identifier
222+
Body *BlockStatement
223+
}
224+
225+
func (fl *FunctionLiteral) expressionNode() {}
226+
func (fl *FunctionLiteral) TokenLiteral() string { return fl.Token.Literal }
227+
func (fl *FunctionLiteral) String() string {
228+
var out bytes.Buffer
229+
230+
params := []string{}
231+
for _, p := range fl.Parameters {
232+
params = append(params, p.String())
233+
}
234+
235+
out.WriteString(fl.TokenLiteral())
236+
out.WriteString("(")
237+
out.WriteString(strings.Join(params, ", "))
238+
out.WriteString(") ")
239+
out.WriteString(fl.Body.String())
240+
241+
return out.String()
242+
}
243+
244+
type CallExpression struct {
245+
Token token.Token // The '(' token
246+
Function Expression // Identifier or FunctionLiteral
247+
Arguments []Expression
248+
}
249+
250+
func (ce *CallExpression) expressionNode() {}
251+
func (ce *CallExpression) TokenLiteral() string { return ce.Token.Literal }
252+
func (ce *CallExpression) String() string {
253+
var out bytes.Buffer
254+
255+
args := []string{}
256+
for _, a := range ce.Arguments {
257+
args = append(args, a.String())
258+
}
259+
260+
out.WriteString(ce.Function.String())
261+
out.WriteString("(")
262+
out.WriteString(strings.Join(args, ", "))
263+
out.WriteString(")")
264+
265+
return out.String()
266+
}
267+
268+
type StringLiteral struct {
269+
Token token.Token
270+
Value string
271+
}
272+
273+
func (sl *StringLiteral) expressionNode() {}
274+
func (sl *StringLiteral) TokenLiteral() string { return sl.Token.Literal }
275+
func (sl *StringLiteral) String() string { return sl.Token.Literal }
276+
277+
type ArrayLiteral struct {
278+
Token token.Token // the '[' token
279+
Elements []Expression
280+
}
281+
282+
func (al *ArrayLiteral) expressionNode() {}
283+
func (al *ArrayLiteral) TokenLiteral() string { return al.Token.Literal }
284+
func (al *ArrayLiteral) String() string {
285+
var out bytes.Buffer
286+
287+
elements := []string{}
288+
for _, el := range al.Elements {
289+
elements = append(elements, el.String())
290+
}
291+
292+
out.WriteString("[")
293+
out.WriteString(strings.Join(elements, ", "))
294+
out.WriteString("]")
295+
296+
return out.String()
297+
}
298+
299+
type IndexExpression struct {
300+
Token token.Token // The [ token
301+
Left Expression
302+
Index Expression
303+
}
304+
305+
func (ie *IndexExpression) expressionNode() {}
306+
func (ie *IndexExpression) TokenLiteral() string { return ie.Token.Literal }
307+
func (ie *IndexExpression) String() string {
308+
var out bytes.Buffer
309+
310+
out.WriteString("(")
311+
out.WriteString(ie.Left.String())
312+
out.WriteString("[")
313+
out.WriteString(ie.Index.String())
314+
out.WriteString("])")
315+
316+
return out.String()
317+
}
318+
319+
type HashLiteral struct {
320+
Token token.Token // the '{' token
321+
Pairs map[Expression]Expression
322+
}
323+
324+
func (hl *HashLiteral) expressionNode() {}
325+
func (hl *HashLiteral) TokenLiteral() string { return hl.Token.Literal }
326+
func (hl *HashLiteral) String() string {
327+
var out bytes.Buffer
328+
329+
pairs := []string{}
330+
for key, value := range hl.Pairs {
331+
pairs = append(pairs, key.String()+":"+value.String())
332+
}
333+
334+
out.WriteString("{")
335+
out.WriteString(strings.Join(pairs, ", "))
336+
out.WriteString("}")
337+
338+
return out.String()
339+
}

.ignore-inspiration/ast/ast_test.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package ast
2+
3+
import (
4+
"monkey/token"
5+
"testing"
6+
)
7+
8+
func TestString(t *testing.T) {
9+
program := &Program{
10+
Statements: []Statement{
11+
&LetStatement{
12+
Token: token.Token{Type: token.LET, Literal: "let"},
13+
Name: &Identifier{
14+
Token: token.Token{Type: token.IDENT, Literal: "myVar"},
15+
Value: "myVar",
16+
},
17+
Value: &Identifier{
18+
Token: token.Token{Type: token.IDENT, Literal: "anotherVar"},
19+
Value: "anotherVar",
20+
},
21+
},
22+
},
23+
}
24+
25+
if program.String() != "let myVar = anotherVar;" {
26+
t.Errorf("program.String() wrong. got=%q", program.String())
27+
}
28+
}

0 commit comments

Comments
 (0)