summaryrefslogtreecommitdiff
path: root/module/language/ecmascript/parse.scm
diff options
context:
space:
mode:
Diffstat (limited to 'module/language/ecmascript/parse.scm')
-rw-r--r--module/language/ecmascript/parse.scm332
1 files changed, 332 insertions, 0 deletions
diff --git a/module/language/ecmascript/parse.scm b/module/language/ecmascript/parse.scm
new file mode 100644
index 000000000..ebc7eaae8
--- /dev/null
+++ b/module/language/ecmascript/parse.scm
@@ -0,0 +1,332 @@
+;;; ECMAScript for Guile
+
+;; Copyright (C) 2009 Free Software Foundation, Inc.
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program; see the file COPYING. If not, write to
+;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Code:
+
+(define-module (language ecmascript parse)
+ #:use-module (language ecmascript parse-lalr)
+ #:use-module (language ecmascript tokenize)
+ #:export (read-ecmascript read-ecmascript/1 parse-ecmascript))
+
+(define (read-ecmascript port)
+ (parse-ecmascript (make-tokenizer port) pk))
+
+(define (read-ecmascript/1 port)
+ (parse-ecmascript (make-tokenizer/1 port) pk))
+
+(define parse-ecmascript
+ (lalr-parser
+ ;; terminal (i.e. input) token types
+ (lbrace rbrace lparen rparen lbracket rbracket dot semicolon comma <
+ > <= >= == != === !== + - * % ++ -- << >> >>> & bor ^ ! ~ && or ?
+ colon = += -= *= %= <<= >>= >>>= &= bor= ^= / /=
+
+ break else new var case finally return void catch for switch while
+ continue function this with default if throw delete in try do
+ instanceof typeof null true false
+
+ Identifier StringLiteral NumericLiteral RegexpLiteral)
+
+
+ (Program (SourceElements) -> $1
+ (*eoi*) -> (call-with-input-string "" read-char))
+
+ ;;
+ ;; Verily, here we define statements. Expressions are defined
+ ;; afterwards.
+ ;;
+
+ (SourceElement (Statement) -> $1
+ (FunctionDeclaration) -> $1)
+
+ (FunctionDeclaration (function Identifier lparen rparen lbrace FunctionBody rbrace) -> `(define ,$2 (lambda () ,@$6))
+ (function Identifier lparen FormalParameterList rparen lbrace FunctionBody rbrace) -> `(define ,$2 (lambda ,$4 ,@$7)))
+ (FunctionExpression (function lparen rparen lbrace FunctionBody rbrace) -> `(lambda () ,@$5)
+ (function Identifier lparen rparen lbrace FunctionBody rbrace) -> `(lambda () ,@$6)
+ (function lparen FormalParameterList rparen lbrace FunctionBody rbrace) -> `(lambda ,$3 ,@$6)
+ (function Identifier lparen FormalParameterList rparen lbrace FunctionBody rbrace) -> `(lambda ,$4 ,@$7))
+ (FormalParameterList (Identifier) -> `(,$1)
+ (FormalParameterList comma Identifier) -> `(,@$1 ,$3))
+ (SourceElements (SourceElement) -> $1
+ (SourceElements SourceElement) -> (if (and (pair? $1) (eq? (car $1) 'begin))
+ `(begin ,@(cdr $1) ,$2)
+ `(begin ,$1 ,$2)))
+ (FunctionBody (SourceElements) -> $1)
+
+ (Statement (Block) -> $1
+ (VariableStatement) -> $1
+ (EmptyStatement) -> $1
+ (ExpressionStatement) -> $1
+ (IfStatement) -> $1
+ (IterationStatement) -> $1
+ (ContinueStatement) -> $1
+ (BreakStatement) -> $1
+ (ReturnStatement) -> $1
+ (WithStatement) -> $1
+ (LabelledStatement) -> $1
+ (SwitchStatement) -> $1
+ (ThrowStatement) -> $1
+ (TryStatement) -> $1)
+
+ (Block (lbrace StatementList rbrace) -> `(block ,$2))
+ (StatementList (Statement) -> $1
+ (StatementList Statement) -> (if (and (pair? $1) (eq? (car $1) 'begin))
+ `(begin ,@(cdr $1) ,$2)
+ `(begin ,$1 ,$2)))
+
+ (VariableStatement (var VariableDeclarationList) -> `(var ,@$2))
+ (VariableDeclarationList (VariableDeclaration) -> `(,$1)
+ (VariableDeclarationList comma VariableDeclaration) -> `(,@$1 ,$2))
+ (VariableDeclarationListNoIn (VariableDeclarationNoIn) -> `(,$1)
+ (VariableDeclarationListNoIn comma VariableDeclarationNoIn) -> `(,@$1 ,$2))
+ (VariableDeclaration (Identifier) -> `(,$1)
+ (Identifier Initialiser) -> `(,$1 ,$2))
+ (VariableDeclarationNoIn (Identifier) -> `(,$1)
+ (Identifier Initialiser) -> `(,$1 ,$2))
+ (Initialiser (= AssignmentExpression) -> $1)
+ (InitialiserNoIn (= AssignmentExpressionNoIn) -> $1)
+
+ (EmptyStatement (semicolon) -> '(begin))
+
+ (ExpressionStatement (Expression semicolon) -> $1)
+
+ (IfStatement (if lparen Expression rparen Statement else Statement) -> `(if ,$3 ,$5 ,$7)
+ (if lparen Expression rparen Statement) -> `(if ,$3 ,$5))
+
+ (IterationStatement (do Statement while lparen Expression rparen semicolon) -> `(do ,$2 ,$5)
+
+ (while lparen Expression rparen Statement) -> `(while ,$3 ,$5)
+
+ (for lparen semicolon semicolon rparen Statement) -> `(for #f #f #f ,$6)
+ (for lparen semicolon semicolon Expression rparen Statement) -> `(for #f #f ,$5 ,$7)
+ (for lparen semicolon Expression semicolon rparen Statement) -> `(for #f ,$4 #f ,$7)
+ (for lparen semicolon Expression semicolon Expression rparen Statement) -> `(for #f ,$4 ,$6 ,$8)
+
+ (for lparen ExpressionNoIn semicolon semicolon rparen Statement) -> `(for ,$3 #f #f ,$7)
+ (for lparen ExpressionNoIn semicolon semicolon Expression rparen Statement) -> `(for ,$3 #f ,$6 ,$8)
+ (for lparen ExpressionNoIn semicolon Expression semicolon rparen Statement) -> `(for ,$3 ,$5 #f ,$8)
+ (for lparen ExpressionNoIn semicolon Expression semicolon Expression rparen Statement) -> `(for ,$3 ,$5 ,$7 ,$9)
+
+ (for lparen var VariableDeclarationListNoIn semicolon semicolon rparen Statement) -> `(for (var ,$4) #f #f ,$8)
+ (for lparen var VariableDeclarationListNoIn semicolon semicolon Expression rparen Statement) -> `(for (var ,$4) #f ,$7 ,$9)
+ (for lparen var VariableDeclarationListNoIn semicolon Expression semicolon rparen Statement) -> `(for (var ,$4) ,$6 #f ,$9)
+ (for lparen var VariableDeclarationListNoIn semicolon Expression semicolon Expression rparen Statement) -> `(for (var ,$4) ,$6 ,$8 ,$10)
+
+ (for lparen LeftHandSideExpression in Expression rparen Statement) -> `(for-in ,$3 ,$5 ,$7)
+ (for lparen var VariableDeclarationNoIn in Expression rparen Statement) -> `(for-in ,$4 ,$6 ,$8))
+
+ (ContinueStatement (continue Identifier semicolon) -> `(continue ,$2)
+ (continue semicolon) -> `(continue))
+
+ (BreakStatement (break Identifier semicolon) -> `(break ,$2)
+ (break semicolon) -> `(break))
+
+ (ReturnStatement (return Expression semicolon) -> `(return ,$2)
+ (return semicolon) -> `(return))
+
+ (WithStatement (with lparen Expression rparen Statement) -> `(with ,$3 ,$5))
+
+ (SwitchStatement (switch lparen Expression rparen CaseBlock) -> `(switch ,$3 ,@$5))
+ (CaseBlock (lbrace rbrace) -> '()
+ (lbrace CaseClauses rbrace) -> $2
+ (lbrace CaseClauses DefaultClause rbrace) -> `(,@$2 ,@$3)
+ (lbrace DefaultClause rbrace) -> `(,$2)
+ (lbrace DefaultClause CaseClauses rbrace) -> `(,@$2 ,@$3))
+ (CaseClauses (CaseClause) -> `(,$1)
+ (CaseClauses CaseClause) -> `(,@$1 ,$2))
+ (CaseClause (case Expression colon) -> `(case ,$2)
+ (case Expression colon StatementList) -> `(case ,$2 ,$4))
+ (DefaultClause (default colon) -> `(default)
+ (default colon StatementList) -> `(default ,$3))
+
+ (LabelledStatement (Identifier colon Statement) -> `(label ,$1 ,$3))
+
+ (ThrowStatement (throw Expression semicolon) -> `(throw ,$2))
+
+ (TryStatement (try Block Catch) -> `(try ,$2 ,$3 #f)
+ (try Block Finally) -> `(try ,$2 #f ,$3)
+ (try Block Catch Finally) -> `(try ,$2 ,$3 ,$4))
+ (Catch (catch lparen Identifier rparen Block) -> `(catch ,$3 ,$5))
+ (Finally (finally Block) -> `(finally ,$2))
+
+ ;;
+ ;; As promised, expressions. We build up to Expression bottom-up, so
+ ;; as to get operator precedence right.
+ ;;
+
+ (PrimaryExpression (this) -> '(this)
+ (null) -> 'null
+ (true) -> #t
+ (false) -> #f
+ (Identifier) -> `(ref ,$1)
+ (StringLiteral) -> `(string ,$1)
+ (RegexpLiteral) -> `(regexp ,$1)
+ (NumericLiteral) -> `(number ,$1)
+ (ArrayLiteral) -> $1
+ (ObjectLiteral) -> $1
+ (lparen Expression rparen) -> $2)
+
+ (ArrayLiteral (lbracket rbracket) -> '(array)
+ (lbracket Elision rbracket) -> '(array)
+ (lbracket ElementList rbracket) -> `(array ,@$2)
+ (lbracket ElementList comma rbracket) -> `(array ,@$2)
+ (lbracket ElementList comma Elision rbracket) -> `(array ,@$2))
+ (ElementList (AssignmentExpression) -> `(,$1)
+ (Elision AssignmentExpression) -> `(,$2)
+ (ElementList comma AssignmentExpression) -> `(,@$1 ,$3)
+ (ElementList comma Elision AssignmentExpression) -> `(,@$1 ,$4))
+ (Elision (comma) -> #f
+ (Elision comma) -> #f)
+
+ (ObjectLiteral (lbrace rbrace) -> `(object)
+ (lbrace PropertyNameAndValueList rbrace) -> `(object ,@$2))
+ (PropertyNameAndValueList (PropertyName colon AssignmentExpression) -> `((,$1 . ,$3))
+ (PropertyNameAndValueList comma PropertyName colon AssignmentExpression) -> `(,@$1 (,$3 . ,$5)))
+ (PropertyName (Identifier) -> `(ref ,$1)
+ (StringLiteral) -> `(string ,$1)
+ (NumericLiteral) -> `(number ,$1))
+
+ (MemberExpression (PrimaryExpression) -> $1
+ (FunctionExpression) -> $1
+ (MemberExpression lbracket Expression rbracket) -> `(aref ,$1 ,$3)
+ (MemberExpression dot Identifier) -> `(pref ,$1 ,$3)
+ (new MemberExpression Arguments) -> `(new ,$2 ,$3))
+
+ (NewExpression (MemberExpression) -> $1
+ (new NewExpression) -> `(new ,$2))
+
+ (CallExpression (MemberExpression Arguments) -> `(call ,$1 ,$2)
+ (CallExpression Arguments) -> `(call ,$1 ,$2)
+ (CallExpression lbracket Expression rbracket) -> `(aref ,$1 ,$3)
+ (CallExpression dot Identifier) -> `(pref ,$1 ,$3))
+ (Arguments (lparen rparen) -> '()
+ (lparen ArgumentList rparen) -> $2)
+ (ArgumentList (AssignmentExpression) -> `(,$1)
+ (ArgumentList comma AssignmentExpression) -> `(,@$1 ,$3))
+
+ (LeftHandSideExpression (NewExpression) -> $1
+ (CallExpression) -> $1)
+
+ (PostfixExpression (LeftHandSideExpression) -> $1
+ (LeftHandSideExpression ++) -> `(postinc ,$1)
+ (LeftHandSideExpression --) -> `(postdec ,$1))
+
+ (UnaryExpression (PostfixExpression) -> $1
+ (delete UnaryExpression) -> `(delete ,$2)
+ (void UnaryExpression) -> `(void ,$2)
+ (typeof UnaryExpression) -> `(typeof ,$2)
+ (++ UnaryExpression) -> `(preinc ,$2)
+ (-- UnaryExpression) -> `(predec ,$2)
+ (+ UnaryExpression) -> `(+ ,$2)
+ (- UnaryExpression) -> `(- ,$2)
+ (~ UnaryExpression) -> `(~ ,$2)
+ (! UnaryExpression) -> `(! ,$2))
+
+ (MultiplicativeExpression (UnaryExpression) -> $1
+ (MultiplicativeExpression * UnaryExpression) -> `(* ,$1 ,$3)
+ (MultiplicativeExpression / UnaryExpression) -> `(/ ,$1 ,$3)
+ (MultiplicativeExpression % UnaryExpression) -> `(% ,$1 ,$3))
+
+ (AdditiveExpression (MultiplicativeExpression) -> $1
+ (AdditiveExpression + MultiplicativeExpression) -> `(+ ,$1 ,$3)
+ (AdditiveExpression - MultiplicativeExpression) -> `(- ,$1 ,$3))
+
+ (ShiftExpression (AdditiveExpression) -> $1
+ (ShiftExpression << MultiplicativeExpression) -> `(<< ,$1 ,$3)
+ (ShiftExpression >> MultiplicativeExpression) -> `(>> ,$1 ,$3)
+ (ShiftExpression >>> MultiplicativeExpression) -> `(>>> ,$1 ,$3))
+
+ (RelationalExpression (ShiftExpression) -> $1
+ (RelationalExpression < ShiftExpression) -> `(< ,$1 ,$3)
+ (RelationalExpression > ShiftExpression) -> `(> ,$1 ,$3)
+ (RelationalExpression <= ShiftExpression) -> `(<= ,$1 ,$3)
+ (RelationalExpression >= ShiftExpression) -> `(>= ,$1 ,$3)
+ (RelationalExpression instanceof ShiftExpression) -> `(instanceof ,$1 ,$3)
+ (RelationalExpression in ShiftExpression) -> `(in ,$1 ,$3))
+
+ (RelationalExpressionNoIn (ShiftExpression) -> $1
+ (RelationalExpressionNoIn < ShiftExpression) -> `(< ,$1 ,$3)
+ (RelationalExpressionNoIn > ShiftExpression) -> `(> ,$1 ,$3)
+ (RelationalExpressionNoIn <= ShiftExpression) -> `(<= ,$1 ,$3)
+ (RelationalExpressionNoIn >= ShiftExpression) -> `(>= ,$1 ,$3)
+ (RelationalExpressionNoIn instanceof ShiftExpression) -> `(instanceof ,$1 ,$3))
+
+ (EqualityExpression (RelationalExpression) -> $1
+ (EqualityExpression == RelationalExpression) -> `(== ,$1 ,$3)
+ (EqualityExpression != RelationalExpression) -> `(!= ,$1 ,$3)
+ (EqualityExpression === RelationalExpression) -> `(=== ,$1 ,$3)
+ (EqualityExpression !== RelationalExpression) -> `(!== ,$1 ,$3))
+
+ (EqualityExpressionNoIn (RelationalExpressionNoIn) -> $1
+ (EqualityExpressionNoIn == RelationalExpressionNoIn) -> `(== ,$1 ,$3)
+ (EqualityExpressionNoIn != RelationalExpressionNoIn) -> `(!= ,$1 ,$3)
+ (EqualityExpressionNoIn === RelationalExpressionNoIn) -> `(=== ,$1 ,$3)
+ (EqualityExpressionNoIn !== RelationalExpressionNoIn) -> `(!== ,$1 ,$3))
+
+ (BitwiseANDExpression (EqualityExpression) -> $1
+ (BitwiseANDExpression & EqualityExpression) -> `(& ,$1 ,$3))
+ (BitwiseANDExpressionNoIn (EqualityExpressionNoIn) -> $1
+ (BitwiseANDExpressionNoIn & EqualityExpressionNoIn) -> `(& ,$1 ,$3))
+
+ (BitwiseXORExpression (BitwiseANDExpression) -> $1
+ (BitwiseXORExpression ^ BitwiseANDExpression) -> `(^ ,$1 ,$3))
+ (BitwiseXORExpressionNoIn (BitwiseANDExpressionNoIn) -> $1
+ (BitwiseXORExpressionNoIn ^ BitwiseANDExpressionNoIn) -> `(^ ,$1 ,$3))
+
+ (BitwiseORExpression (BitwiseXORExpression) -> $1
+ (BitwiseORExpression bor BitwiseXORExpression) -> `(bor ,$1 ,$3))
+ (BitwiseORExpressionNoIn (BitwiseXORExpressionNoIn) -> $1
+ (BitwiseORExpressionNoIn bor BitwiseXORExpressionNoIn) -> `(bor ,$1 ,$3))
+
+ (LogicalANDExpression (BitwiseORExpression) -> $1
+ (LogicalANDExpression && BitwiseORExpression) -> `(and ,$1 ,$3))
+ (LogicalANDExpressionNoIn (BitwiseORExpressionNoIn) -> $1
+ (LogicalANDExpressionNoIn && BitwiseORExpressionNoIn) -> `(and ,$1 ,$3))
+
+ (LogicalORExpression (LogicalANDExpression) -> $1
+ (LogicalORExpression or LogicalANDExpression) -> `(or ,$1 ,$3))
+ (LogicalORExpressionNoIn (LogicalANDExpressionNoIn) -> $1
+ (LogicalORExpressionNoIn or LogicalANDExpressionNoIn) -> `(or ,$1 ,$3))
+
+ (ConditionalExpression (LogicalORExpression) -> $1
+ (LogicalORExpression ? AssignmentExpression colon AssignmentExpression) -> `(if ,$1 ,$3 ,$5))
+ (ConditionalExpressionNoIn (LogicalORExpressionNoIn) -> $1
+ (LogicalORExpressionNoIn ? AssignmentExpressionNoIn colon AssignmentExpressionNoIn) -> `(if ,$1 ,$3 ,$5))
+
+ (AssignmentExpression (ConditionalExpression) -> $1
+ (LeftHandSideExpression AssignmentOperator AssignmentExpression) -> `(,$2 ,$1 ,$3))
+ (AssignmentExpressionNoIn (ConditionalExpressionNoIn) -> $1
+ (LeftHandSideExpression AssignmentOperator AssignmentExpressionNoIn) -> `(,$2 ,$1 ,$3))
+ (AssignmentOperator (=) -> '=
+ (*=) -> '=
+ (/=) -> '/=
+ (%=) -> '%=
+ (+=) -> '+=
+ (-=) -> '-=
+ (<<=) -> '<<=
+ (>>=) -> '>>=
+ (>>>=) -> '>>>=
+ (&=) -> '&=
+ (^=) -> '^=
+ (bor=) -> 'bor=)
+
+ (Expression (AssignmentExpression) -> $1
+ (Expression comma AssignmentExpression) -> `(begin ,$1 ,$3))
+ (ExpressionNoIn (AssignmentExpressionNoIn) -> $1
+ (ExpressionNoIn comma AssignmentExpressionNoIn) -> `(begin ,$1 ,$3))))