[svn] r7569: nemerle/trunk: macros/io.n ncc/testsuite/negative.cmd ncc/testsuite/positive.cmd ncc/testsuit...

VladD2 svnadmin at nemerle.org
Mon Apr 2 06:40:08 CEST 2007


Log:
Improve $-string. At now it support ..$(...) notation for print sequence (all which implement SCG.IEnumerable[T]).
Syntax: ..$seq
where 'seq' is a sequence.
Or: ..$(seq; separatorStringEppression)
Or: ..$(seq; separatorStringEppression; elementConvertionFunction)
Examples in ncc/testsuite/positive/printf.n

Author: VladD2
Date: Mon Apr  2 06:40:05 2007
New Revision: 7569

Modified:
   nemerle/trunk/macros/io.n
   nemerle/trunk/ncc/testsuite/negative.cmd
   nemerle/trunk/ncc/testsuite/positive.cmd
   nemerle/trunk/ncc/testsuite/positive/printf.n

Modified: nemerle/trunk/macros/io.n
==============================================================================
--- nemerle/trunk/macros/io.n	(original)
+++ nemerle/trunk/macros/io.n	Mon Apr  2 06:40:05 2007
@@ -345,8 +345,7 @@
       iter_through (parse_format (format), parms.Length, []);
     }
 
-
-    /** for $(..) expressions:
+    /** for $(...) and ..$(...) expressions:
         - first evaluate expressions
         - store intermediate results in variables
         - return list of evaluators and reference variables in reverse order
@@ -379,53 +378,126 @@
           }
       }
 
-      def loop (res, idx) {
+      def indexOfDollar(idx)
+      {
+        def str = str;
+        if (idx >= str.Length) -1
+        else if (char.IsWhiteSpace(str[idx])) indexOfDollar(idx + 1)
+        else if (str[idx] == '$') idx
+        else -1
+      }
+
+      mutable nestLevel = 0;
+
+      def loop (res, idx)
+      {
+        def str = str;
+        nestLevel++;
+        Diagnostics.Trace.Assert(nestLevel < 200);
+
         if (idx < 0 || idx >= str.Length)
           res
-        else if (str[idx] == '$') {
+        else if (str[idx] == '.') // try recognize pattern '..$x'
+        {
+          if (idx + 3 < str.Length && str[idx + 1] == '.' && indexOfDollar(idx + 2) >= 0)
+            parceSpliceEx(res, indexOfDollar(idx + 2), false);  // found pattern '..$'
+          else
+            loop (<[$("." : string)]> :: res, idx + 1)
+        }
+        else if (str[idx] == '$')
+          parceSpliceEx(res, idx, true)
+        else
+        {
+          def str = str;
+          def get(index) { if (index < 0 || index >= str.Length) '\0' else str[index] }
+          def getElipseIndex(index)
+          { // If '..' prefix exists return it index. Otherwise return initial index.
+            def ch = get(index - 1);
+            
+            if (char.IsWhiteSpace(ch)) getElipseIndex(index - 1)
+            else if (get(index - 1) == '.' && get(index - 2) == '.') index - 2
+            else -1
+          }
+          def nextIdx   = str.IndexOf('$', idx);
+          def elipseIdx = getElipseIndex(nextIdx);
+          def nextIdx   = if (elipseIdx >= 0) elipseIdx else nextIdx;
+          def next_str  = if (nextIdx == -1) str.Substring (idx)
+                          else str.Substring (idx, nextIdx - idx);
+          loop (<[ $(next_str : string) ]> :: res, nextIdx)
+        }
+      }
+      and parceSpliceEx(res, idx, isSimple)
+      {
+        def str = str;
+
           when (idx + 1 >= str.Length)
-            Message.FatalError ("lone `$' at the end of the format string");
-          if (str[idx + 1] == '(') {
+        {
+          //Diagnostics.Trace.Assert(false);
+          Message.Error ("lone `$' at the end of the format string");
+          Nemerle.Imperative.Return ([<[ "$" ]>]);
+        }
+          
+        def nextIndex = idx + 1;
+          
+        if (str[nextIndex] == '(')
+        {
             def end = find_end (1, idx + 2);
             def expr = str.Substring (idx + 2, end - idx - 2);
             def expr =
-              if (expr == "" || expr == "_" || 
-                  seen_non_alnum || 
-                  System.Char.IsDigit (expr [0])) {
+            if (expr == "" || expr == "_" || seen_non_alnum || char.IsDigit(expr[0]))
+            {
                 _env.Manager.MacroColors.PushUseSiteColor ();
-                def expr = MainParser.ParseExpr (_env, expr);
-                _env.Manager.MacroColors.PopColor ();
-                <[ Convert.ToString ($expr) ]>
+              try
+              {
+                def pExpr = MainParser.ParseExpr (_env, expr);
+                def makeSeqExpr(pExpr)
+                {
+                  def makeSeqExpr(seqExpr, sepExpr, cnvFuncExpr)
+                  {
+                    <[ string.Join($sepExpr, NCollectionsUtils.MapToArray($seqExpr, $cnvFuncExpr)) ]>
+                  }
+                  match (pExpr)
+                  {
+                    | <[ $seqExpr; $sepExpr; $cnvFuncExpr; ]> => makeSeqExpr(seqExpr, sepExpr, cnvFuncExpr)
+                    | <[ $seqExpr; $sepExpr; ]> => makeSeqExpr(seqExpr, sepExpr, <[ Convert.ToString(_) ]>)
+                    | _ => makeSeqExpr(pExpr, <[ ", " ]>, <[ Convert.ToString(_) ]>)
+                  }
+                }
+                
+                if (isSimple) <[ Convert.ToString ($pExpr) ]> else makeSeqExpr(pExpr)
+              }
+              finally { _env.Manager.MacroColors.PopColor (); }
               } else if (expr == "this")
-                <[ Convert.ToString (this) ]>
-              else
-                <[ Convert.ToString ($(expr : usesite)) ]>;
+              if (isSimple) <[ Convert.ToString (this) ]>
+              else <[ string.Join(", ", NCollectionsUtils.MapToArray(this, Convert.ToString(_))) ]>
+            else if (isSimple) <[ Convert.ToString ($(expr : usesite)) ]>;
+            else <[ string.Join(", ", NCollectionsUtils.MapToArray($(expr : usesite), Convert.ToString(_))) ]>;
             loop (expr :: res, end + 1)
           }
-          else if (str[idx + 1] == '$')
+        else if (str[nextIndex] == '$')
             loop (<[$("$" : string)]> :: res, idx + 2)
-          else {
-            def end = find_end_normal (idx + 1);
-            def variable_name = str.Substring (idx + 1, end - idx - 1);
+        else
+        {
+          def end = find_end_normal (nextIndex);
+          def variable_name = str.Substring (nextIndex, end - idx - 1);
             
-            if (variable_name == "") {
+          if (variable_name == "")
+          {
               Message.Warning ("expected variable name or expression enclosed with (..) after $ in splice string");
-              loop (<[$("$" : string)]> :: res, idx + 1)
+            loop (<[$("$" : string)]> :: res, nextIndex)
             }
-            else {
+          else
+          {
               def expr =
-                if (variable_name == "this") <[ Convert.ToString (this) ]>
-                else <[ Convert.ToString ($(variable_name : usesite)) ]>;
+              if (variable_name == "this") 
+                if (isSimple) <[ Convert.ToString (this) ]>
+                else <[ string.Join(", ", NCollectionsUtils.MapToArray(this, Convert.ToString(_))) ]>
+              else if (isSimple)
+                <[ Convert.ToString ($(variable_name : usesite)) ]>
+              else <[ string.Join(", ", NCollectionsUtils.MapToArray($(variable_name : usesite), Convert.ToString(_))) ]>;
               loop (expr :: res, end)
             }
           }
-        } else {
-          def next_idx = str.IndexOf ('$', idx);
-          def next_str =
-            if (next_idx == -1) str.Substring (idx)
-            else str.Substring (idx, next_idx - idx);
-          loop (<[ $(next_str : string) ]> :: res, next_idx)
-        }
       }
 
       loop ([], 0)

Modified: nemerle/trunk/ncc/testsuite/negative.cmd
==============================================================================
--- nemerle/trunk/ncc/testsuite/negative.cmd	(original)
+++ nemerle/trunk/ncc/testsuite/negative.cmd	Mon Apr  2 06:40:05 2007
@@ -1,5 +1,6 @@
 IF exist negative.results del negative.results
-tests.exe -d:negative -p "-nowarn:10003 -def:RUNTIME_MS" -s > negative.results
-type negative.results
+tests.exe -d:negative -p "-nowarn:10003 -def:RUNTIME_MS" -s
+rem > negative.results
+rem type negative.results
 echo ----------------------------------------
 pause
\ No newline at end of file

Modified: nemerle/trunk/ncc/testsuite/positive.cmd
==============================================================================
--- nemerle/trunk/ncc/testsuite/positive.cmd	(original)
+++ nemerle/trunk/ncc/testsuite/positive.cmd	Mon Apr  2 06:40:05 2007
@@ -1,5 +1,6 @@
 IF exist positive.results del positive.results
-tests.exe -d:positive -p "-nowarn:10003 -def:RUNTIME_MS" -s > positive.results
-type positive.results
+tests.exe -d:positive -p "-nowarn:10003 -def:RUNTIME_MS" -s
+rem  > positive.results
+rem  type positive.results
 echo ----------------------------------------
 pause
\ No newline at end of file

Modified: nemerle/trunk/ncc/testsuite/positive/printf.n
==============================================================================
--- nemerle/trunk/ncc/testsuite/positive/printf.n	(original)
+++ nemerle/trunk/ncc/testsuite/positive/printf.n	Mon Apr  2 06:40:05 2007
@@ -1,4 +1,5 @@
 using Nemerle.IO;
+using System.Console;
 using System.IO;
 
 class T {
@@ -117,6 +118,14 @@
     def mux' = 42;
     print ("$quxx' $(T().a()) $(mux')\n");
     print ("wrong ${1} splicing\n"); // W: expected variable name or expression.* after
+
+    def x = 1;
+    def lst = [1, 2, 3, 52];
+    def cnv = x => "0x" + x.ToString("X");
+    WriteLine ($@"lst = ..$(lst; ""; "");");
+    WriteLine ($@"x = $x; lst = ..  $(lst; ""; ""; cnv);");
+    WriteLine ($".$x;");
+    WriteLine ($"lst = '..$(lst)';");
   }
 }
 
@@ -147,5 +156,9 @@
 bla 2 bal
 3' some T 42
 wrong ${1} splicing
+lst = 1; 2; 3; 52;
+x = 1; lst = 0x1; 0x2; 0x3; 0x34;
+.1;
+lst = '1, 2, 3, 52';
 END-OUTPUT
 */



More information about the svn mailing list