Revision: 3779
          http://vexi.svn.sourceforge.net/vexi/?rev=3779&view=rev
Author:   mkpg2
Date:     2010-01-15 19:28:18 +0000 (Fri, 15 Jan 2010)

Log Message:
-----------
Feature. Safe navigation operators '?.' and '?['

Modified Paths:
--------------
    trunk/core/org.ibex.js/src/org/ibex/js/parse/Lexer.jpp
    trunk/core/org.ibex.js/src/org/ibex/js/parse/Parser.java
    trunk/core/org.ibex.js/src/org/ibex/js/parse/Tokens.java

Added Paths:
-----------
    trunk/core/org.ibex.js/src_junit/test/js/exec/general/safe_navigation.js

Modified: trunk/core/org.ibex.js/src/org/ibex/js/parse/Lexer.jpp
===================================================================
--- trunk/core/org.ibex.js/src/org/ibex/js/parse/Lexer.jpp      2010-01-15 
18:28:57 UTC (rev 3778)
+++ trunk/core/org.ibex.js/src/org/ibex/js/parse/Lexer.jpp      2010-01-15 
19:28:18 UTC (rev 3779)
@@ -271,7 +271,7 @@
         case '(': return LP;
         case ')': return RP;
         case ',': return COMMA;
-        case '?': return HOOK;
+        case '?': return in.match('.') ? HOOK_DOT : (in.match('[')?HOOK_LB: 
HOOK);
         case ':': return !in.match(':') ? COLON : in.match('=') ? GRAMMAR : 
le(":: is not a valid token");
         case '.': return DOT;
         case '|': return in.match('|') ? OR : (in.match('=') ? ASSIGN_BITOR : 
BITOR);

Modified: trunk/core/org.ibex.js/src/org/ibex/js/parse/Parser.java
===================================================================
--- trunk/core/org.ibex.js/src/org/ibex/js/parse/Parser.java    2010-01-15 
18:28:57 UTC (rev 3778)
+++ trunk/core/org.ibex.js/src/org/ibex/js/parse/Parser.java    2010-01-15 
19:28:18 UTC (rev 3779)
@@ -135,11 +135,9 @@
         precedence[ADD] = precedence[SUB] = 12;
         precedence[MUL] = precedence[DIV] = precedence[MOD] = 13;
         precedence[BITNOT] =  precedence[BANG] = precedence[TYPEOF] = 
precedence[KEYSOF] = 14;
-        precedence[LB] = precedence[LP] =  precedence[INC] = precedence[DEC] = 
15;
+        precedence[HOOK_LB] = precedence[LB] = precedence[LP] =  
precedence[INC] = precedence[DEC] = 15;
         precedence[NEW] = 16;  // REMARK (added by mike who is not sure if 
this is this right to spec)
-        precedence[DOT] =  17; // used to be 15
-        
-        
+        precedence[HOOK_DOT] = precedence[DOT] =  17; // used to be 15
     }
 
     protected Parser(Reader r, String sourceName, int line) throws IOException 
{ super(r, sourceName, line); }
@@ -662,6 +660,24 @@
             b.set(size - 1, integer(b.size - size));                           
    // write the target of the short-circuit jump
             break;
         }
+        // safe navigation
+        case HOOK_LB:
+        case HOOK_DOT: {
+            b.add(parserLine, DUP);                              
+            b.add(parserLine, JF, integer(0));                       // jump 
to the end
+            int jump = b.size;
+            if(tok==HOOK_DOT){
+                consume(NAME);
+                b.add(parserLine, LITERAL, string(string));
+            }else{
+                startExpr(b, -1);
+                consume(RB);
+            }
+            continueExprAfterAssignable(b,minPrecedence,null);
+            b.set(jump - 1, integer(b.size - jump + 1));   // now we know 
where the target of the jump is
+            // the top item of the stack is either the object before the ? or 
+            break;
+        }
         case DOT: {
             // support foo..bar syntax for foo[""].bar
             if (peekToken() == DOT) {
@@ -1291,12 +1307,12 @@
 
     
     // ParserException 
//////////////////////////////////////////////////////////////////////
-    private IOException pe(String s) { return new ParserException(s, 
sourceName, line); }
+    private IOException pe(String s) { return new ParserException(s, 
sourceName, line, col); }
     
     static class ParserException extends SourceException{
 
-               public ParserException(String message, String sourceName, int 
line) {
-                       super(message, sourceName, line);
+               public ParserException(String message, String sourceName, int 
line, int col) {
+                       super(message, sourceName, line, col);
                }
        public String getMessageSig() {
                return "[Parsing Error]";

Modified: trunk/core/org.ibex.js/src/org/ibex/js/parse/Tokens.java
===================================================================
--- trunk/core/org.ibex.js/src/org/ibex/js/parse/Tokens.java    2010-01-15 
18:28:57 UTC (rev 3778)
+++ trunk/core/org.ibex.js/src/org/ibex/js/parse/Tokens.java    2010-01-15 
19:28:18 UTC (rev 3779)
@@ -104,8 +104,10 @@
     public static final int NEW           = 83;  // new
     public static final int INSTANCEOF    = 84;  // instanceof
     public static final int CONST         = 85;  // const
-    
-    public static final int MAX_TOKEN = CONST;
+    public static final int HOOK_DOT      = 86;  // ?.
+    public static final int HOOK_LB       = 87;  // ?[
+      
+    public static final int MAX_TOKEN = HOOK_LB;
 
     public final static String[] codeToString = new String[] {
         "BITOR", "ASSIGN_BITOR", "BITXOR", "ASSIGN_BITXOR", "BITAND",
@@ -120,7 +122,7 @@
         "HOOK", "COLON", "INC", "DEC", "DOT", "FUNCTION", "IF",
         "ELSE", "SWITCH", "CASE", "DEFAULT", "WHILE", "DO", "FOR",
         "VAR", "WITH", "CATCH", "FINALLY", "RESERVED", "GRAMMAR",
-        "ADD_TRAP", "DEL_TRAP", "CASCADE", "KEYSOF", "NEW", "INSTANCEOF", 
"CONST"
+        "ADD_TRAP", "DEL_TRAP", "CASCADE", "KEYSOF", "NEW", "INSTANCEOF", 
"CONST", "HOOK_DOT", "HOOK_LB"
     };
 
 }

Added: trunk/core/org.ibex.js/src_junit/test/js/exec/general/safe_navigation.js
===================================================================
--- trunk/core/org.ibex.js/src_junit/test/js/exec/general/safe_navigation.js    
                        (rev 0)
+++ trunk/core/org.ibex.js/src_junit/test/js/exec/general/safe_navigation.js    
2010-01-15 19:28:18 UTC (rev 3779)
@@ -0,0 +1,25 @@
+
+var o = null;
+o?.a = 1;
+assert((o?.a)==null);
+assert(o?.a==null);
+assert(o?.a?.b==null);
+
+o?["a"] = 2;
+assert((o?["a"])==null);
+assert(o?["a"]==null);
+assert(o?["a"]?["b"]==null);
+
+o = {};
+o?.a = 3;
+assert((o?.a)==3);
+assert(o?.a==3);
+assert(o?.a?.b==null);
+
+
+o?["a"] = 4;
+assert((o?["a"])==4);
+assert(o?["a"]==4);
+assert(o?["a"]?["b"]==null);
+
+


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

------------------------------------------------------------------------------
Throughout its 18-year history, RSA Conference consistently attracts the
world's best and brightest in the field, creating opportunities for Conference
attendees to learn about information security's most important issues through
interactions with peers, luminaries and emerging and established companies.
http://p.sf.net/sfu/rsaconf-dev2dev
_______________________________________________
Vexi-svn mailing list
Vexi-svn@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/vexi-svn

Reply via email to