From: MORIOKA Tomohiko Date: Thu, 18 Apr 2013 02:19:28 +0000 (+0900) Subject: (cos_skip_space): New function. X-Git-Url: http://git.chise.org/gitweb/?a=commitdiff_plain;h=0d250fa6fd2825c3cc5a2057b1fb1a7c5bda2b61;p=chise%2Fconcord.git (cos_skip_space): New function. (cos_read_int): Fix to support separator. (cos_read_list0): New function. (cos_read_list): New function. (cos_read_object): New function. --- diff --git a/read.c b/read.c index f8d0eb2..2e2f7fe 100644 --- a/read.c +++ b/read.c @@ -20,6 +20,19 @@ #include #include "cos-read.h" +int +cos_skip_space (unsigned char *str, size_t len, size_t start, size_t* endp) +{ + int i = start; + + while ( ( i < len ) && isspace (str[i]) ) + { + i++; + } + *endp = i; + return i; +} + COS_object cos_read_int (unsigned char *str, size_t len, size_t start, size_t* endp) { @@ -57,7 +70,12 @@ 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) ) + else if ( isspace (c) + || ( c == '(' ) + || ( c == ')' ) + || ( c == '[' ) + || ( c == ']' ) + || ( c == '"' ) ) { *endp = i; return cos_make_int ( negative_flag ? - dest : dest ); @@ -174,3 +192,109 @@ cos_read_string (unsigned char *str, size_t len, size_t start, size_t* endp) } return NULL; } + + +static COS_Cons +cos_read_list0 (unsigned char *str, size_t len, size_t start, size_t* endp) +{ + size_t i = start; + + i = cos_skip_space (str, len, i, endp); + if ( len >= start + 1 ) + { + COS_object car = cos_read_object (str, len, i, endp); + + if ( car == NULL ) + return NULL; + i = *endp; + + i = cos_skip_space (str, len, i, endp); + if ( str[i] == ')' ) + { + *endp = i + 1; + return cos_cons (car, cos_Qnil); + } + else if ( str[i] == '.' ) + { + COS_object cdr; + + i++; + if ( isspace (str[i]) + || ( str[i] == '"' ) + || ( str[i] == '[' ) + || ( str[i] == '(' ) ) + { + cdr = cos_read_object (str, len, i, endp); + if ( cdr == NULL ) + return NULL; + i = *endp; + i = cos_skip_space (str, len, i, endp); + if ( str[i] == ')' ) + { + *endp = i + 1; + return cos_cons (car, cdr); + } + cos_release_object (car); + cos_release_object (cdr); + return NULL; + } + else + { + cos_release_object (car); + return NULL; + } + } + else + { + COS_object rest; + + rest = cos_read_list0 (str, len, i, endp); + if ( rest == NULL ) + return NULL; + return cos_cons (car, rest); + } + } + return NULL; +} + +COS_Cons +cos_read_list (unsigned char *str, size_t len, size_t start, size_t* endp) +{ + size_t i = start; + + i = cos_skip_space (str, len, i, endp); + if ( (len >= start + 2) && (str[i++] == '(') ) + { + return cos_read_list0 (str, len, i, endp); + } + return NULL; +} + + +COS_object +cos_read_object (unsigned char *str, size_t len, size_t start, size_t* endp) +{ + COS_object val_obj; + int val_cid; + COS_String val_str; + + start = cos_skip_space (str, len, start, endp); + + val_obj = cos_read_int (str, len, start, endp); + if ( val_obj != NULL ) + return val_obj; + + val_cid = cos_read_char (str, len, start, endp); + if ( val_cid >= 0 ) + return cos_make_char (val_cid); + + val_str = cos_read_string (str, len, start, endp); + if ( val_str != NULL ) + return val_str; + + val_obj = cos_read_list (str, len, start, endp); + if ( val_obj != NULL ) + return val_obj; + + return NULL; +}