(is_delimiter): New function.
authorMORIOKA Tomohiko <tomo.git@chise.org>
Fri, 19 Apr 2013 05:12:16 +0000 (14:12 +0900)
committerMORIOKA Tomohiko <tomo.git@chise.org>
Fri, 19 Apr 2013 05:12:16 +0000 (14:12 +0900)
(cos_read_int): Use `is_delimiter'.
(cos_read_string): Fixed.
(cos_read_symbol): New function.
(cos_read_object): Use `cos_read_symbol' to support symbol.

read.c

diff --git a/read.c b/read.c
index 2e2f7fe..0991fe7 100644 (file)
--- a/read.c
+++ b/read.c
 #include <ctype.h>
 #include "cos-read.h"
 
-int
+static int
+is_delimiter (int ch)
+{
+  return isspace (ch)
+    || ( ch == '(' )
+    || ( ch == ')' )
+    || ( ch == '[' )
+    || ( ch == ']' )
+    || ( ch == '"' )
+    || ( ch == '#' )
+    || ( ch == ';' );
+}
+
+static int
 cos_skip_space (unsigned char *str, size_t len, size_t start, size_t* endp)
 {
   int i = start;
@@ -70,12 +83,7 @@ cos_read_int (unsigned char *str, size_t len, size_t start, size_t* endp)
                  dest = dest * 10 + c - '0';
                  i++;
                }
-             else if ( isspace (c)
-                       || ( c == '(' )
-                       || ( c == ')' )
-                       || ( c == '[' )
-                       || ( c == ']' )
-                       || ( c == '"' ) )
+             else if ( is_delimiter (c) )
                {
                  *endp = i;
                  return cos_make_int ( negative_flag ? - dest : dest );
@@ -180,7 +188,8 @@ cos_read_string (unsigned char *str, size_t len, size_t start, size_t* endp)
        {
          if ( c == '"' )
            {
-             return cos_make_string ((char*)&str[1], i - 2);
+             *endp = i;
+             return cos_make_string ((char*)&str[start + 1], i - 2 - start);
            }
          else if ( c == '\\' )
            {
@@ -194,6 +203,48 @@ cos_read_string (unsigned char *str, size_t len, size_t start, size_t* endp)
 }
 
 
+COS_Symbol
+cos_read_symbol (unsigned char *str, size_t len, size_t start, size_t* endp)
+{
+  size_t i = start;
+  int c;
+
+  if ( i < len )
+    {
+      while ( ( i < len )
+             && ( (c = cos_read_utf8 (str, len, i, &i)) >= 0 )
+             )
+       {
+         if ( is_delimiter (c) )
+           {
+             i--;
+             if ( i == start )
+               return NULL;
+             else
+               {
+                 *endp = i;
+                 return
+                   cos_intern (cos_make_string (&str[start], i - start));
+               }
+           }
+         else if ( c == '\\' )
+           {
+             i++;
+             if ( cos_read_utf8 (str, len, i, &i) < 0 )
+               return NULL;
+           }
+       }
+    }
+  if ( i == start )
+    return NULL;
+  else
+    {
+      *endp = i;
+      return cos_intern (cos_make_string (&str[start], i - start));
+    }
+}
+
+
 static COS_Cons
 cos_read_list0 (unsigned char *str, size_t len, size_t start, size_t* endp)
 {
@@ -280,6 +331,10 @@ cos_read_object (unsigned char *str, size_t len, size_t start, size_t* endp)
 
   start = cos_skip_space (str, len, start, endp);
 
+  val_obj = cos_read_list (str, len, start, endp);
+  if ( val_obj != NULL )
+    return val_obj;
+
   val_obj = cos_read_int (str, len, start, endp);
   if ( val_obj != NULL )
     return val_obj;
@@ -292,7 +347,7 @@ cos_read_object (unsigned char *str, size_t len, size_t start, size_t* endp)
   if ( val_str != NULL )
     return val_str;
 
-  val_obj = cos_read_list (str, len, start, endp);
+  val_obj = cos_read_symbol (str, len, start, endp);
   if ( val_obj != NULL )
     return val_obj;