From: Michael D. Lowis Date: Thu, 8 May 2014 02:42:04 +0000 (-0400) Subject: CP: half finished implementation of strtol for number parsing X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=faa3afe76d162fc7292843673b778c3c0e7fdd74;p=proto%2Fsclpl.git CP: half finished implementation of strtol for number parsing --- diff --git a/source/slvm/kernel/parser.c b/source/slvm/kernel/parser.c index 94d1eac..b69c707 100644 --- a/source/slvm/kernel/parser.c +++ b/source/slvm/kernel/parser.c @@ -8,7 +8,9 @@ #include "pal.h" #include #include -#include +//#include + +long strtol(char* p_str, char** p_end); /* Fetching Tokens *****************************************************************************/ @@ -160,10 +162,10 @@ TokenType_T parse_token(char* str, val_t* p_val) static bool is_integer(char* p_str, val_t* p_val) { - //char* end; - //*(p_val) = (val_t)strtol(p_str,&end,0); - //return (end == &(p_str[pal_strlen(p_str)])); - return false; + char* end; + *(p_val) = (val_t)strtol(p_str,&end); + return (end == &(p_str[pal_strlen(p_str)])); + //return false; } static bool is_float(char* p_str, val_t* p_val) @@ -234,3 +236,72 @@ static bool is_char(char* p_str, val_t* p_val) return res; } +/* Parsing Numbers + *****************************************************************************/ +static bool is_ws(char c) +{ + return (c == ' ' || c == '\t' || c == '\n' || c == '\r'); +} + +long strtol(char* p_str, char** p_p_end) +{ + int ch; + int sign = 1; + int base = 10; + long value = 0; + + /* Skip any leading whitespace */ + do { + ch = *(p_str); + p_str++; + } while (is_ws(ch)); + + /* Detect leading sign */ + if (ch == '-') + { + sign = -1; + ch = *p_str; + p_str++; + } + else if (ch == '+') + { + ch = *p_str; + p_str++; + } + + /* Detect the base of the number being parsed */ + if((ch == '0') && (*p_str == 'x' || *p_str == 'X')) + { + base = 16; + ch = p_str[1]; + p_str += 2; + } + else if((ch == '0') && (*p_str == 'b' || *p_str == 'B')) + { + base = 2; + ch = p_str[1]; + p_str += 2; + } + + /* Accumulate the digits in the appropriate base */ + for (value = 0;; ch = *p_str++) + { + /* Determine the value of the current digit */ + if (ch >= '0' && ch <= '9') + ch -= '0'; + else if ((ch >= 'A' && ch <= 'F') || (ch >= 'a' && ch <= 'f')) + ch -= (ch >= 'A' && ch <= 'F') ? 'A'-10 : 'a'-10; + else + break; + + /* if the base digit is invalid for the selected base then quit */ + if (ch >= base) break; + + /* Shift the value be the base and add in the digit */ + value *= base; + value += ch; + } + + *p_p_end = p_str-1; + return sign * value; +}