mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-04-30 03:40:34 +02:00
* module/language/ecmascript/parse.scm (parse-ecmascript): And update the function declaration forms for the new var syntax. * module/language/ecmascript/compile-ghil.scm (comp): Support foo["bar"] in addition to foo.bar. * module/language/ecmascript/impl.scm (pget, pput): Some fixes for when we get non-symbols -- it can happen, yo. I suppose we should allow for non-string keys too..
335 lines
18 KiB
Scheme
335 lines
18 KiB
Scheme
;;; 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 *eof-object*
|
|
(call-with-input-string "" read-char))
|
|
|
|
(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*) -> *eof-object*)
|
|
|
|
;;
|
|
;; Verily, here we define statements. Expressions are defined
|
|
;; afterwards.
|
|
;;
|
|
|
|
(SourceElement (Statement) -> $1
|
|
(FunctionDeclaration) -> $1)
|
|
|
|
(FunctionDeclaration (function Identifier lparen rparen lbrace FunctionBody rbrace) -> `(var (,$2 (lambda () ,$6)))
|
|
(function Identifier lparen FormalParameterList rparen lbrace FunctionBody rbrace) -> `(var (,$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) -> $2)
|
|
(InitialiserNoIn (= AssignmentExpressionNoIn) -> $2)
|
|
|
|
(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 ,@$2)
|
|
(lbracket ElementList rbracket) -> `(array ,@$2)
|
|
(lbracket ElementList comma rbracket) -> `(array ,@$2)
|
|
(lbracket ElementList comma Elision rbracket) -> `(array ,@$2))
|
|
(ElementList (AssignmentExpression) -> `(,$1)
|
|
(Elision AssignmentExpression) -> `(,@$1 ,$2)
|
|
(ElementList comma AssignmentExpression) -> `(,@$1 ,$3)
|
|
(ElementList comma Elision AssignmentExpression) -> `(,@$1 ,@$3 ,$4))
|
|
(Elision (comma) -> '((number 0))
|
|
(Elision comma) -> `(,@$1 (number 0)))
|
|
|
|
(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) -> $1
|
|
(StringLiteral) -> (string->symbol $1)
|
|
(NumericLiteral) -> $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))))
|