unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
From: Sean Lynch <sean@seanplynch.com>
To: guile-devel@gnu.org
Cc: Sean Lynch <sean@seanplynch.com>
Subject: [PATCH 4/4] Fix some reserved word usages in ecmascript implementation
Date: Wed, 28 Oct 2020 00:03:35 -0400	[thread overview]
Message-ID: <20201028040330.22051-5-sean@seanplynch.com> (raw)
In-Reply-To: <20201028040330.22051-1-sean@seanplynch.com>

Reserved words are valid ecmascript in certain contexts, referred to
by the IdentifierName syntax rule. For example, while throw is a
keyword, using throw as a property accessor such as foo.throw is valid.
While this implementation isn't quite correct, it is an improvement. For
an example of how this might be incorrect, it will reject the expression
super.foo uncoditionally, however, that expression is valid inside a
member function of a class.

Further, the *keywords* alist is now updated to the that specified by
ECMAScript 2020, and *future-reserved-words* is merged into *keywords*
because in the end the only item that wouldn't be a keyword seems to be
enum.

* module/language/ecmascript/parse.scm: Add IdentifierName production
  that includes reserved word list.
* module/language/ecmascript/tokenize.scm: Update reserved word list and
  do not error upon encountering one. The parser will be responsible for
  rejecting an illegal usage of a reserved word.
---
 module/language/ecmascript/parse.scm    | 51 +++++++++++++--
 module/language/ecmascript/tokenize.scm | 84 +++++++++----------------
 2 files changed, 73 insertions(+), 62 deletions(-)

diff --git a/module/language/ecmascript/parse.scm b/module/language/ecmascript/parse.scm
index be41e4b9c..8fff96f54 100644
--- a/module/language/ecmascript/parse.scm
+++ b/module/language/ecmascript/parse.scm
@@ -55,9 +55,9 @@
     > <= >= == != === !== + - * % ++ -- << >> >>> & 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
+    await break case catch class const continue debugger default delete do else
+    enum export extends false finally for function if import in instanceof new
+    null return super switch this throw true try typeof var void while with yield
 
     Identifier StringLiteral NumericLiteral RegexpLiteral)
 
@@ -65,6 +65,45 @@
    (Program (SourceElements) : $1
             (*eoi*) : *eof-object*)
 
+   (IdentifierName (Identifier) : $1
+                   (await) : $1 
+                   (break) : $1
+                   (case) : $1
+                   (catch) : $1
+                   (class) : $1
+                   (const) : $1
+                   (continue) : $1
+                   (debugger) : $1
+                   (default) : $1
+                   (delete) : $1
+                   (do) : $1
+                   (else) : $1
+                   (enum) : $1
+                   (export) : $1
+                   (extends) : $1
+                   (false) : $1
+                   (finally) : $1
+                   (for) : $1
+                   (function) : $1
+                   (if) : $1
+                   (import) : $1
+                   (in) : $1
+                   (instanceof) : $1
+                   (new) : $1
+                   (null) : $1
+                   (return) : $1
+                   (super) : $1
+                   (switch) : $1
+                   (this) : $1
+                   (throw) : $1
+                   (true) : $1
+                   (try) : $1
+                   (typeof) : $1
+                   (var) : $1
+                   (void) : $1
+                   (while) : $1
+                   (with) : $1
+                   (yield) : $1)
    ;;
    ;; Verily, here we define statements. Expressions are defined
    ;; afterwards.
@@ -218,14 +257,14 @@
                   (lbrace PropertyNameAndValueList rbrace) : `(object ,@$2))
    (PropertyNameAndValueList (PropertyName colon AssignmentExpression) : `((,$1 ,$3))
                              (PropertyNameAndValueList comma PropertyName colon AssignmentExpression) : `(,@$1 (,$3 ,$5)))
-   (PropertyName (Identifier) : $1
+   (PropertyName (IdentifierName) : $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)
+                     (MemberExpression dot IdentifierName) : `(pref ,$1 ,$3)
                      (new MemberExpression Arguments) : `(new ,$2 ,$3))
 
    (NewExpression (MemberExpression) : $1
@@ -234,7 +273,7 @@
    (CallExpression (MemberExpression Arguments) : `(call ,$1 ,$2)
                    (CallExpression Arguments) : `(call ,$1 ,$2)
                    (CallExpression lbracket Expression rbracket) : `(aref ,$1 ,$3)
-                   (CallExpression dot Identifier) : `(pref ,$1 ,$3))
+                   (CallExpression dot IdentifierName) : `(pref ,$1 ,$3))
    (Arguments (lparen rparen) : '()
               (lparen ArgumentList rparen) : $2)
    (ArgumentList (AssignmentExpression) : `(,$1)
diff --git a/module/language/ecmascript/tokenize.scm b/module/language/ecmascript/tokenize.scm
index 8289b950c..cbae3bbe4 100644
--- a/module/language/ecmascript/tokenize.scm
+++ b/module/language/ecmascript/tokenize.scm
@@ -173,69 +173,44 @@
                           loc str))))))))
 
 (define *keywords*
-  '(("break" . break)
-    ("else" . else)
-    ("new" . new)
-    ("var" . var)
+  '(("await" . await) 
+    ("break" . break)
     ("case" . case)
-    ("finally" . finally)
-    ("return" . return)
-    ("void" . void)
     ("catch" . catch)
-    ("for" . for)
-    ("switch" . switch)
-    ("while" . while)
+    ("class" . class)
+    ("const" . const)
     ("continue" . continue)
-    ("function" . function)
-    ("this" . this)
-    ("with" . with)
+    ("debugger" . debugger)
     ("default" . default)
-    ("if" . if)
-    ("throw" . throw)
     ("delete" . delete)
-    ("in" . in)
-    ("try" . try)
     ("do" . do)
-    ("instanceof" . instanceof)
-    ("typeof" . typeof)
-
-    ;; these aren't exactly keywords, but hey
-    ("null" . null)
-    ("true" . true)
-    ("false" . false)))
-
-(define *future-reserved-words*
-  '(("abstract" . abstract)
+    ("else" . else)
     ("enum" . enum)
-    ("int" . int)
-    ("short" . short)
-    ("boolean" . boolean)
     ("export" . export)
-    ("interface" . interface)
-    ("static" . static)
-    ("byte" . byte)
     ("extends" . extends)
-    ("long" . long)
-    ("super" . super)
-    ("char" . char)
-    ("final" . final)
-    ("native" . native)
-    ("synchronized" . synchronized)
-    ("class" . class)
-    ("float" . float)
-    ("package" . package)
-    ("throws" . throws)
-    ("const" . const)
-    ("goto" . goto)
-    ("private" . private)
-    ("transient" . transient)
-    ("debugger" . debugger)
-    ("implements" . implements)
-    ("protected" . protected)
-    ("volatile" . volatile)
-    ("double" . double)
+    ("false" . false)
+    ("finally" . finally)
+    ("for" . for)
+    ("function" . function)
+    ("if" . if)
     ("import" . import)
-    ("public" . public)))
+    ("in" . in)
+    ("instanceof" . instanceof)
+    ("new" . new)
+    ("null" . null)
+    ("return" . return)
+    ("super" . super)
+    ("switch" . switch)
+    ("this" . this)
+    ("throw" . throw)
+    ("true" . true)
+    ("try" . try)
+    ("typeof" . typeof)
+    ("var" . var)
+    ("void" . void)
+    ("while" . while)
+    ("with" . with)
+    ("yield" . yield)))
 
 (define (read-identifier port loc)
   (let lp ((c (peek-char port)) (chars '()))
@@ -247,9 +222,6 @@
         (let ((word (list->string (reverse chars))))
           (cond ((assoc-ref *keywords* word)
                  => (lambda (x) (make-lexical-token x loc #f)))
-                ((assoc-ref *future-reserved-words* word)
-                 (syntax-error "word is reserved for the future, dude."
-                               loc word))
                 (else (make-lexical-token 'Identifier loc
                                           (string->symbol word)))))
         (begin (read-char port)
-- 
2.29.1




      parent reply	other threads:[~2020-10-28  4:03 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-10-28  4:03 [PATCH 0/4] Support ECMAScript Test262 Assertion Harness Sean Lynch
2020-10-28  4:03 ` [PATCH 1/4] Support ecmascript return operator with no operand Sean Lynch
2020-10-28  4:03 ` [PATCH 2/4] Implement ecmascript try/catch Sean Lynch
2020-10-28  4:03 ` [PATCH 3/4] Implement ecmascript function prototype Sean Lynch
2020-10-28  4:03 ` Sean Lynch [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/guile/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20201028040330.22051-5-sean@seanplynch.com \
    --to=sean@seanplynch.com \
    --cc=guile-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).