Merge remote-tracking branch 'origin/stable-2.0'
[bpt/guile.git] / module / language / ecmascript / parse.scm
CommitLineData
5dcd3e48
AW
1;;; ECMAScript for Guile
2
0ecd70a2 3;; Copyright (C) 2009, 2010 Free Software Foundation, Inc.
5dcd3e48 4
53befeb7
NJ
5;;;; This library is free software; you can redistribute it and/or
6;;;; modify it under the terms of the GNU Lesser General Public
7;;;; License as published by the Free Software Foundation; either
8;;;; version 3 of the License, or (at your option) any later version.
9;;;;
10;;;; This library is distributed in the hope that it will be useful,
11;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
12;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13;;;; Lesser General Public License for more details.
14;;;;
15;;;; You should have received a copy of the GNU Lesser General Public
16;;;; License along with this library; if not, write to the Free Software
17;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
5dcd3e48
AW
18
19;;; Code:
20
21(define-module (language ecmascript parse)
0ecd70a2 22 #:use-module (system base lalr)
5dcd3e48 23 #:use-module (language ecmascript tokenize)
0ecd70a2 24 #:export (read-ecmascript read-ecmascript/1 make-parser))
5dcd3e48 25
96fa6896
AW
26(define* (syntax-error message #:optional token)
27 (if (lexical-token? token)
28 (throw 'syntax-error #f message
29 (and=> (lexical-token-source token)
30 source-location->source-properties)
31 (or (lexical-token-value token)
32 (lexical-token-category token))
33 #f)
34 (throw 'syntax-error #f message #f token #f)))
0b229e81 35
5dcd3e48 36(define (read-ecmascript port)
0ecd70a2
LC
37 (let ((parse (make-parser)))
38 (parse (make-tokenizer port) syntax-error)))
5dcd3e48
AW
39
40(define (read-ecmascript/1 port)
0ecd70a2
LC
41 (let ((parse (make-parser)))
42 (parse (make-tokenizer/1 port) syntax-error)))
5dcd3e48 43
131f7d6c
AW
44(define *eof-object*
45 (call-with-input-string "" read-char))
46
0ecd70a2
LC
47(define (make-parser)
48 ;; Return a fresh ECMAScript parser. Parsers produced by `lalr-scm' are now
49 ;; stateful (e.g., they won't invoke the tokenizer any more once it has
50 ;; returned `*eoi*'), hence the need to instantiate new parsers.
51
5dcd3e48
AW
52 (lalr-parser
53 ;; terminal (i.e. input) token types
54 (lbrace rbrace lparen rparen lbracket rbracket dot semicolon comma <
55 > <= >= == != === !== + - * % ++ -- << >> >>> & bor ^ ! ~ && or ?
56 colon = += -= *= %= <<= >>= >>>= &= bor= ^= / /=
57
58 break else new var case finally return void catch for switch while
59 continue function this with default if throw delete in try do
60 instanceof typeof null true false
61
62 Identifier StringLiteral NumericLiteral RegexpLiteral)
63
64
0ecd70a2
LC
65 (Program (SourceElements) : $1
66 (*eoi*) : *eof-object*)
5dcd3e48
AW
67
68 ;;
69 ;; Verily, here we define statements. Expressions are defined
70 ;; afterwards.
71 ;;
72
0ecd70a2
LC
73 (SourceElement (Statement) : $1
74 (FunctionDeclaration) : $1)
75
76 (FunctionDeclaration (function Identifier lparen rparen lbrace FunctionBody rbrace) : `(var (,$2 (lambda () ,$6)))
77 (function Identifier lparen FormalParameterList rparen lbrace FunctionBody rbrace) : `(var (,$2 (lambda ,$4 ,$7))))
78 (FunctionExpression (function lparen rparen lbrace FunctionBody rbrace) : `(lambda () ,$5)
79 (function Identifier lparen rparen lbrace FunctionBody rbrace) : `(lambda () ,$6)
80 (function lparen FormalParameterList rparen lbrace FunctionBody rbrace) : `(lambda ,$3 ,$6)
81 (function Identifier lparen FormalParameterList rparen lbrace FunctionBody rbrace) : `(lambda ,$4 ,$7))
82 (FormalParameterList (Identifier) : `(,$1)
83 (FormalParameterList comma Identifier) : `(,@$1 ,$3))
84 (SourceElements (SourceElement) : $1
85 (SourceElements SourceElement) : (if (and (pair? $1) (eq? (car $1) 'begin))
5dcd3e48
AW
86 `(begin ,@(cdr $1) ,$2)
87 `(begin ,$1 ,$2)))
eacbe346
NL
88 (FunctionBody (SourceElements) : $1
89 () : '(begin))
0ecd70a2
LC
90
91 (Statement (Block) : $1
92 (VariableStatement) : $1
93 (EmptyStatement) : $1
94 (ExpressionStatement) : $1
95 (IfStatement) : $1
96 (IterationStatement) : $1
97 (ContinueStatement) : $1
98 (BreakStatement) : $1
99 (ReturnStatement) : $1
100 (WithStatement) : $1
101 (LabelledStatement) : $1
102 (SwitchStatement) : $1
103 (ThrowStatement) : $1
104 (TryStatement) : $1)
105
106 (Block (lbrace StatementList rbrace) : `(block ,$2))
107 (StatementList (Statement) : $1
108 (StatementList Statement) : (if (and (pair? $1) (eq? (car $1) 'begin))
5dcd3e48
AW
109 `(begin ,@(cdr $1) ,$2)
110 `(begin ,$1 ,$2)))
111
0ecd70a2
LC
112 (VariableStatement (var VariableDeclarationList) : `(var ,@$2))
113 (VariableDeclarationList (VariableDeclaration) : `(,$1)
114 (VariableDeclarationList comma VariableDeclaration) : `(,@$1 ,$2))
115 (VariableDeclarationListNoIn (VariableDeclarationNoIn) : `(,$1)
116 (VariableDeclarationListNoIn comma VariableDeclarationNoIn) : `(,@$1 ,$2))
117 (VariableDeclaration (Identifier) : `(,$1)
118 (Identifier Initialiser) : `(,$1 ,$2))
119 (VariableDeclarationNoIn (Identifier) : `(,$1)
120 (Identifier Initialiser) : `(,$1 ,$2))
121 (Initialiser (= AssignmentExpression) : $2)
122 (InitialiserNoIn (= AssignmentExpressionNoIn) : $2)
5dcd3e48 123
0ecd70a2 124 (EmptyStatement (semicolon) : '(begin))
5dcd3e48 125
0ecd70a2 126 (ExpressionStatement (Expression semicolon) : $1)
5dcd3e48 127
0ecd70a2
LC
128 (IfStatement (if lparen Expression rparen Statement else Statement) : `(if ,$3 ,$5 ,$7)
129 (if lparen Expression rparen Statement) : `(if ,$3 ,$5))
5dcd3e48 130
0ecd70a2 131 (IterationStatement (do Statement while lparen Expression rparen semicolon) : `(do ,$2 ,$5)
5dcd3e48 132
0ecd70a2 133 (while lparen Expression rparen Statement) : `(while ,$3 ,$5)
5dcd3e48 134
0ecd70a2
LC
135 (for lparen semicolon semicolon rparen Statement) : `(for #f #f #f ,$6)
136 (for lparen semicolon semicolon Expression rparen Statement) : `(for #f #f ,$5 ,$7)
137 (for lparen semicolon Expression semicolon rparen Statement) : `(for #f ,$4 #f ,$7)
138 (for lparen semicolon Expression semicolon Expression rparen Statement) : `(for #f ,$4 ,$6 ,$8)
5dcd3e48 139
0ecd70a2
LC
140 (for lparen ExpressionNoIn semicolon semicolon rparen Statement) : `(for ,$3 #f #f ,$7)
141 (for lparen ExpressionNoIn semicolon semicolon Expression rparen Statement) : `(for ,$3 #f ,$6 ,$8)
142 (for lparen ExpressionNoIn semicolon Expression semicolon rparen Statement) : `(for ,$3 ,$5 #f ,$8)
143 (for lparen ExpressionNoIn semicolon Expression semicolon Expression rparen Statement) : `(for ,$3 ,$5 ,$7 ,$9)
5dcd3e48 144
0ecd70a2
LC
145 (for lparen var VariableDeclarationListNoIn semicolon semicolon rparen Statement) : `(for (var ,@$4) #f #f ,$8)
146 (for lparen var VariableDeclarationListNoIn semicolon semicolon Expression rparen Statement) : `(for (var ,@$4) #f ,$7 ,$9)
147 (for lparen var VariableDeclarationListNoIn semicolon Expression semicolon rparen Statement) : `(for (var ,@$4) ,$6 #f ,$9)
148 (for lparen var VariableDeclarationListNoIn semicolon Expression semicolon Expression rparen Statement) : `(for (var ,@$4) ,$6 ,$8 ,$10)
5dcd3e48 149
0ecd70a2
LC
150 (for lparen LeftHandSideExpression in Expression rparen Statement) : `(for-in ,$3 ,$5 ,$7)
151 (for lparen var VariableDeclarationNoIn in Expression rparen Statement) : `(begin (var ,$4) (for-in (ref ,@$4) ,$6 ,$8)))
5dcd3e48 152
0ecd70a2
LC
153 (ContinueStatement (continue Identifier semicolon) : `(continue ,$2)
154 (continue semicolon) : `(continue))
5dcd3e48 155
0ecd70a2
LC
156 (BreakStatement (break Identifier semicolon) : `(break ,$2)
157 (break semicolon) : `(break))
5dcd3e48 158
0ecd70a2
LC
159 (ReturnStatement (return Expression semicolon) : `(return ,$2)
160 (return semicolon) : `(return))
5dcd3e48 161
0ecd70a2 162 (WithStatement (with lparen Expression rparen Statement) : `(with ,$3 ,$5))
5dcd3e48 163
0ecd70a2
LC
164 (SwitchStatement (switch lparen Expression rparen CaseBlock) : `(switch ,$3 ,@$5))
165 (CaseBlock (lbrace rbrace) : '()
166 (lbrace CaseClauses rbrace) : $2
167 (lbrace CaseClauses DefaultClause rbrace) : `(,@$2 ,@$3)
168 (lbrace DefaultClause rbrace) : `(,$2)
169 (lbrace DefaultClause CaseClauses rbrace) : `(,@$2 ,@$3))
170 (CaseClauses (CaseClause) : `(,$1)
171 (CaseClauses CaseClause) : `(,@$1 ,$2))
172 (CaseClause (case Expression colon) : `(case ,$2)
173 (case Expression colon StatementList) : `(case ,$2 ,$4))
174 (DefaultClause (default colon) : `(default)
175 (default colon StatementList) : `(default ,$3))
5dcd3e48 176
0ecd70a2 177 (LabelledStatement (Identifier colon Statement) : `(label ,$1 ,$3))
5dcd3e48 178
0ecd70a2 179 (ThrowStatement (throw Expression semicolon) : `(throw ,$2))
5dcd3e48 180
0ecd70a2
LC
181 (TryStatement (try Block Catch) : `(try ,$2 ,$3 #f)
182 (try Block Finally) : `(try ,$2 #f ,$3)
183 (try Block Catch Finally) : `(try ,$2 ,$3 ,$4))
184 (Catch (catch lparen Identifier rparen Block) : `(catch ,$3 ,$5))
185 (Finally (finally Block) : `(finally ,$2))
5dcd3e48
AW
186
187 ;;
188 ;; As promised, expressions. We build up to Expression bottom-up, so
189 ;; as to get operator precedence right.
190 ;;
191
0ecd70a2
LC
192 (PrimaryExpression (this) : 'this
193 (null) : 'null
194 (true) : 'true
195 (false) : 'false
196 (Identifier) : `(ref ,$1)
197 (StringLiteral) : `(string ,$1)
198 (RegexpLiteral) : `(regexp ,$1)
199 (NumericLiteral) : `(number ,$1)
84816b3a 200 (dot NumericLiteral) : `(number ,(string->number (string-append "." (number->string $2))))
0ecd70a2
LC
201 (ArrayLiteral) : $1
202 (ObjectLiteral) : $1
203 (lparen Expression rparen) : $2)
204
205 (ArrayLiteral (lbracket rbracket) : '(array)
206 (lbracket Elision rbracket) : '(array ,@$2)
207 (lbracket ElementList rbracket) : `(array ,@$2)
208 (lbracket ElementList comma rbracket) : `(array ,@$2)
209 (lbracket ElementList comma Elision rbracket) : `(array ,@$2))
210 (ElementList (AssignmentExpression) : `(,$1)
211 (Elision AssignmentExpression) : `(,@$1 ,$2)
212 (ElementList comma AssignmentExpression) : `(,@$1 ,$3)
213 (ElementList comma Elision AssignmentExpression) : `(,@$1 ,@$3 ,$4))
214 (Elision (comma) : '((number 0))
215 (Elision comma) : `(,@$1 (number 0)))
216
217 (ObjectLiteral (lbrace rbrace) : `(object)
218 (lbrace PropertyNameAndValueList rbrace) : `(object ,@$2))
219 (PropertyNameAndValueList (PropertyName colon AssignmentExpression) : `((,$1 ,$3))
220 (PropertyNameAndValueList comma PropertyName colon AssignmentExpression) : `(,@$1 (,$3 ,$5)))
221 (PropertyName (Identifier) : $1
222 (StringLiteral) : (string->symbol $1)
223 (NumericLiteral) : $1)
224
225 (MemberExpression (PrimaryExpression) : $1
226 (FunctionExpression) : $1
227 (MemberExpression lbracket Expression rbracket) : `(aref ,$1 ,$3)
228 (MemberExpression dot Identifier) : `(pref ,$1 ,$3)
229 (new MemberExpression Arguments) : `(new ,$2 ,$3))
230
231 (NewExpression (MemberExpression) : $1
232 (new NewExpression) : `(new ,$2 ()))
233
234 (CallExpression (MemberExpression Arguments) : `(call ,$1 ,$2)
235 (CallExpression Arguments) : `(call ,$1 ,$2)
236 (CallExpression lbracket Expression rbracket) : `(aref ,$1 ,$3)
237 (CallExpression dot Identifier) : `(pref ,$1 ,$3))
238 (Arguments (lparen rparen) : '()
239 (lparen ArgumentList rparen) : $2)
240 (ArgumentList (AssignmentExpression) : `(,$1)
241 (ArgumentList comma AssignmentExpression) : `(,@$1 ,$3))
242
243 (LeftHandSideExpression (NewExpression) : $1
244 (CallExpression) : $1)
245
246 (PostfixExpression (LeftHandSideExpression) : $1
247 (LeftHandSideExpression ++) : `(postinc ,$1)
248 (LeftHandSideExpression --) : `(postdec ,$1))
249
250 (UnaryExpression (PostfixExpression) : $1
251 (delete UnaryExpression) : `(delete ,$2)
252 (void UnaryExpression) : `(void ,$2)
253 (typeof UnaryExpression) : `(typeof ,$2)
254 (++ UnaryExpression) : `(preinc ,$2)
255 (-- UnaryExpression) : `(predec ,$2)
256 (+ UnaryExpression) : `(+ ,$2)
257 (- UnaryExpression) : `(- ,$2)
258 (~ UnaryExpression) : `(~ ,$2)
259 (! UnaryExpression) : `(! ,$2))
260
261 (MultiplicativeExpression (UnaryExpression) : $1
262 (MultiplicativeExpression * UnaryExpression) : `(* ,$1 ,$3)
263 (MultiplicativeExpression / UnaryExpression) : `(/ ,$1 ,$3)
264 (MultiplicativeExpression % UnaryExpression) : `(% ,$1 ,$3))
265
266 (AdditiveExpression (MultiplicativeExpression) : $1
267 (AdditiveExpression + MultiplicativeExpression) : `(+ ,$1 ,$3)
268 (AdditiveExpression - MultiplicativeExpression) : `(- ,$1 ,$3))
269
270 (ShiftExpression (AdditiveExpression) : $1
271 (ShiftExpression << MultiplicativeExpression) : `(<< ,$1 ,$3)
272 (ShiftExpression >> MultiplicativeExpression) : `(>> ,$1 ,$3)
273 (ShiftExpression >>> MultiplicativeExpression) : `(>>> ,$1 ,$3))
274
275 (RelationalExpression (ShiftExpression) : $1
276 (RelationalExpression < ShiftExpression) : `(< ,$1 ,$3)
277 (RelationalExpression > ShiftExpression) : `(> ,$1 ,$3)
278 (RelationalExpression <= ShiftExpression) : `(<= ,$1 ,$3)
279 (RelationalExpression >= ShiftExpression) : `(>= ,$1 ,$3)
280 (RelationalExpression instanceof ShiftExpression) : `(instanceof ,$1 ,$3)
281 (RelationalExpression in ShiftExpression) : `(in ,$1 ,$3))
282
283 (RelationalExpressionNoIn (ShiftExpression) : $1
284 (RelationalExpressionNoIn < ShiftExpression) : `(< ,$1 ,$3)
285 (RelationalExpressionNoIn > ShiftExpression) : `(> ,$1 ,$3)
286 (RelationalExpressionNoIn <= ShiftExpression) : `(<= ,$1 ,$3)
287 (RelationalExpressionNoIn >= ShiftExpression) : `(>= ,$1 ,$3)
288 (RelationalExpressionNoIn instanceof ShiftExpression) : `(instanceof ,$1 ,$3))
289
290 (EqualityExpression (RelationalExpression) : $1
291 (EqualityExpression == RelationalExpression) : `(== ,$1 ,$3)
292 (EqualityExpression != RelationalExpression) : `(!= ,$1 ,$3)
293 (EqualityExpression === RelationalExpression) : `(=== ,$1 ,$3)
294 (EqualityExpression !== RelationalExpression) : `(!== ,$1 ,$3))
295
296 (EqualityExpressionNoIn (RelationalExpressionNoIn) : $1
297 (EqualityExpressionNoIn == RelationalExpressionNoIn) : `(== ,$1 ,$3)
298 (EqualityExpressionNoIn != RelationalExpressionNoIn) : `(!= ,$1 ,$3)
299 (EqualityExpressionNoIn === RelationalExpressionNoIn) : `(=== ,$1 ,$3)
300 (EqualityExpressionNoIn !== RelationalExpressionNoIn) : `(!== ,$1 ,$3))
301
302 (BitwiseANDExpression (EqualityExpression) : $1
303 (BitwiseANDExpression & EqualityExpression) : `(& ,$1 ,$3))
304 (BitwiseANDExpressionNoIn (EqualityExpressionNoIn) : $1
305 (BitwiseANDExpressionNoIn & EqualityExpressionNoIn) : `(& ,$1 ,$3))
306
307 (BitwiseXORExpression (BitwiseANDExpression) : $1
308 (BitwiseXORExpression ^ BitwiseANDExpression) : `(^ ,$1 ,$3))
309 (BitwiseXORExpressionNoIn (BitwiseANDExpressionNoIn) : $1
310 (BitwiseXORExpressionNoIn ^ BitwiseANDExpressionNoIn) : `(^ ,$1 ,$3))
311
312 (BitwiseORExpression (BitwiseXORExpression) : $1
313 (BitwiseORExpression bor BitwiseXORExpression) : `(bor ,$1 ,$3))
314 (BitwiseORExpressionNoIn (BitwiseXORExpressionNoIn) : $1
315 (BitwiseORExpressionNoIn bor BitwiseXORExpressionNoIn) : `(bor ,$1 ,$3))
316
317 (LogicalANDExpression (BitwiseORExpression) : $1
318 (LogicalANDExpression && BitwiseORExpression) : `(and ,$1 ,$3))
319 (LogicalANDExpressionNoIn (BitwiseORExpressionNoIn) : $1
320 (LogicalANDExpressionNoIn && BitwiseORExpressionNoIn) : `(and ,$1 ,$3))
321
322 (LogicalORExpression (LogicalANDExpression) : $1
323 (LogicalORExpression or LogicalANDExpression) : `(or ,$1 ,$3))
324 (LogicalORExpressionNoIn (LogicalANDExpressionNoIn) : $1
325 (LogicalORExpressionNoIn or LogicalANDExpressionNoIn) : `(or ,$1 ,$3))
326
327 (ConditionalExpression (LogicalORExpression) : $1
328 (LogicalORExpression ? AssignmentExpression colon AssignmentExpression) : `(if ,$1 ,$3 ,$5))
329 (ConditionalExpressionNoIn (LogicalORExpressionNoIn) : $1
330 (LogicalORExpressionNoIn ? AssignmentExpressionNoIn colon AssignmentExpressionNoIn) : `(if ,$1 ,$3 ,$5))
331
332 (AssignmentExpression (ConditionalExpression) : $1
333 (LeftHandSideExpression AssignmentOperator AssignmentExpression) : `(,$2 ,$1 ,$3))
334 (AssignmentExpressionNoIn (ConditionalExpressionNoIn) : $1
335 (LeftHandSideExpression AssignmentOperator AssignmentExpressionNoIn) : `(,$2 ,$1 ,$3))
336 (AssignmentOperator (=) : '=
337 (*=) : '*=
338 (/=) : '/=
339 (%=) : '%=
340 (+=) : '+=
341 (-=) : '-=
342 (<<=) : '<<=
343 (>>=) : '>>=
344 (>>>=) : '>>>=
345 (&=) : '&=
346 (^=) : '^=
347 (bor=) : 'bor=)
348
349 (Expression (AssignmentExpression) : $1
350 (Expression comma AssignmentExpression) : `(begin ,$1 ,$3))
351 (ExpressionNoIn (AssignmentExpressionNoIn) : $1
352 (ExpressionNoIn comma AssignmentExpressionNoIn) : `(begin ,$1 ,$3))))