File tree Expand file tree Collapse file tree 3 files changed +52
-0
lines changed Expand file tree Collapse file tree 3 files changed +52
-0
lines changed Original file line number Diff line number Diff line change @@ -27,6 +27,7 @@ type Program struct {
27
27
Statements []Statement // A program is a list of statements
28
28
}
29
29
30
+ // TokenLiteral return the token literal of the first statement on ast
30
31
func (p * Program ) TokenLiteral () string {
31
32
if len (p .Statements ) > 0 {
32
33
return p .Statements [0 ].TokenLiteral ()
@@ -111,3 +112,12 @@ type Identifier struct {
111
112
func (i * Identifier ) expressionNode () {}
112
113
func (i * Identifier ) TokenLiteral () string { return i .Token .Literal }
113
114
func (i * Identifier ) String () string { return i .Value }
115
+
116
+ type IntegerLiteral struct {
117
+ Token token.Token // the token.INT token
118
+ Value int64
119
+ }
120
+
121
+ func (il * IntegerLiteral ) expressionNode () {}
122
+ func (il * IntegerLiteral ) TokenLiteral () string { return il .Token .Literal }
123
+ func (il * IntegerLiteral ) String () string { return il .Token .Literal }
Original file line number Diff line number Diff line change 5
5
"monkey/ast"
6
6
"monkey/lexer"
7
7
"monkey/token"
8
+ "strconv"
8
9
)
9
10
10
11
type Parser struct {
@@ -28,6 +29,7 @@ func New(l *lexer.Lexer) *Parser {
28
29
29
30
p .prefixParseFns = make (map [token.TokenType ]prefixParseFn )
30
31
p .registerPrefix (token .IDENT , p .parseIdentifier )
32
+ p .registerPrefix (token .INT , p .parseIntegerLiteral )
31
33
32
34
// Read two tokens, so curToken and peekToken are both set
33
35
p .nextToken ()
@@ -116,6 +118,18 @@ func (p *Parser) parseReturnStatement() *ast.ReturnStatement {
116
118
return stmt
117
119
}
118
120
121
+ func (p * Parser ) parseIntegerLiteral () ast.Expression {
122
+ lit := & ast.IntegerLiteral {Token : p .curToken }
123
+ value , err := strconv .ParseInt (p .curToken .Literal , 0 , 64 )
124
+ if err != nil {
125
+ msg := fmt .Sprintf ("could not parse %q as integer" , p .curToken .Literal )
126
+ p .errors = append (p .errors , msg )
127
+ return nil
128
+ }
129
+ lit .Value = value
130
+ return lit
131
+ }
132
+
119
133
func (p * Parser ) parseExpressionStatement () * ast.ExpressionStatement {
120
134
stmt := & ast.ExpressionStatement {Token : p .curToken }
121
135
Original file line number Diff line number Diff line change @@ -123,6 +123,34 @@ func TestIdentifierExpression(t *testing.T) {
123
123
}
124
124
}
125
125
126
+ func TestIntegerLiteralExpression (t * testing.T ) {
127
+ input := "5;"
128
+ l := lexer .New (input )
129
+ p := New (l )
130
+ program := p .ParseProgram ()
131
+ checkParserErrors (t , p )
132
+ if len (program .Statements ) != 1 {
133
+ t .Fatalf ("program has not enough statements. got=%d" ,
134
+ len (program .Statements ))
135
+ }
136
+ stmt , ok := program .Statements [0 ].(* ast.ExpressionStatement )
137
+ if ! ok {
138
+ t .Fatalf ("program.Statements[0] is not ast.ExpressionStatement. got=%T" ,
139
+ program .Statements [0 ])
140
+ }
141
+ literal , ok := stmt .Expression .(* ast.IntegerLiteral )
142
+ if ! ok {
143
+ t .Fatalf ("exp not *ast.IntegerLiteral. got=%T" , stmt .Expression )
144
+ }
145
+ if literal .Value != 5 {
146
+ t .Errorf ("literal.Value not %d. got=%d" , 5 , literal .Value )
147
+ }
148
+ if literal .TokenLiteral () != "5" {
149
+ t .Errorf ("literal.TokenLiteral not %s. got=%s" , "5" ,
150
+ literal .TokenLiteral ())
151
+ }
152
+ }
153
+
126
154
func checkParserErrors (t * testing.T , p * Parser ) {
127
155
errors := p .Errors ()
128
156
if len (errors ) == 0 {
You can’t perform that action at this time.
0 commit comments