mirror of
https://github.com/justinethier/cyclone.git
synced 2025-07-16 17:27:33 +02:00
Parse numbers
This commit is contained in:
parent
685a90c9a4
commit
ab293fccb9
1 changed files with 62 additions and 27 deletions
89
runtime.c
89
runtime.c
|
@ -5923,6 +5923,58 @@ int _read_is_numeric(const char *tok)
|
||||||
((len > 1) && (tok[1] == '.' || isdigit(tok[1])) && (tok[0] == '-' || tok[0] == '+'))));
|
((len > 1) && (tok[1] == '.' || isdigit(tok[1])) && (tok[0] == '-' || tok[0] == '+'))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int _read_is_hex_digit(char c)
|
||||||
|
{
|
||||||
|
return (c >= 'a' && c <= 'f') ||
|
||||||
|
(c >= 'A' && c <= 'F');
|
||||||
|
}
|
||||||
|
|
||||||
|
void _read_return_number(void *data, port_type *p, int base, int exact)
|
||||||
|
{
|
||||||
|
// TODO: validation?
|
||||||
|
p->tok_buf[p->tok_end] = '\0'; // TODO: what if buffer is full?
|
||||||
|
p->tok_end = 0; // Reset for next atom
|
||||||
|
make_empty_vector(vec);
|
||||||
|
make_string(str, p->tok_buf);
|
||||||
|
vec.num_elements = 2;
|
||||||
|
vec.elements = (object *) alloca(sizeof(object) * vec.num_elements);
|
||||||
|
vec.elements[0] = &str;
|
||||||
|
vec.elements[1] = obj_int2obj(base);
|
||||||
|
// TODO: need to pass exact or inexact
|
||||||
|
return_thread_runnable(data, &vec);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _read_number(void *data, port_type *p, int base, int exact)
|
||||||
|
{
|
||||||
|
char c;
|
||||||
|
while(1) {
|
||||||
|
// Read more data into buffer, if needed
|
||||||
|
if (p->buf_idx == p->mem_buf_len) {
|
||||||
|
if (!read_from_port(p)){
|
||||||
|
_read_return_number(data, p, base, exact);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c = p->mem_buf[p->buf_idx++];
|
||||||
|
p->col_num++;
|
||||||
|
|
||||||
|
if (isdigit(c)) {
|
||||||
|
if ((base == 2 && c > '1') ||
|
||||||
|
(base == 8 && c > '7')) {
|
||||||
|
_read_error(data, p, "Illegal digit");
|
||||||
|
}
|
||||||
|
_read_add_to_tok_buf(p, c);
|
||||||
|
} else if (c == '+' || c == '-' || c == '.') {
|
||||||
|
_read_add_to_tok_buf(p, c);
|
||||||
|
} else if (base == 16 && _read_is_hex_digit(c)) {
|
||||||
|
_read_add_to_tok_buf(p, c);
|
||||||
|
} else {
|
||||||
|
p->buf_idx--;
|
||||||
|
p->col_num--;
|
||||||
|
_read_return_number(data, p, base, exact);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void _read_return_atom(void *data, object cont, port_type *p)
|
void _read_return_atom(void *data, object cont, port_type *p)
|
||||||
{
|
{
|
||||||
object sym;
|
object sym;
|
||||||
|
@ -5937,17 +5989,11 @@ void _read_return_atom(void *data, object cont, port_type *p)
|
||||||
if (_read_is_numeric(p->tok_buf)) {
|
if (_read_is_numeric(p->tok_buf)) {
|
||||||
make_empty_vector(vec);
|
make_empty_vector(vec);
|
||||||
make_string(str, p->tok_buf);
|
make_string(str, p->tok_buf);
|
||||||
|
|
||||||
vec.num_elements = 2;
|
vec.num_elements = 2;
|
||||||
vec.elements = (object *) alloca(sizeof(object) * vec.num_elements);
|
vec.elements = (object *) alloca(sizeof(object) * vec.num_elements);
|
||||||
vec.elements[0] = &str;
|
vec.elements[0] = &str;
|
||||||
vec.elements[1] = obj_int2obj(10);
|
vec.elements[1] = obj_int2obj(10);
|
||||||
return_thread_runnable(data, &vec);
|
return_thread_runnable(data, &vec);
|
||||||
|
|
||||||
//Cyc_string2number_(data, cont, &str);
|
|
||||||
// TODO: can't do that, need to return_thread_runnable
|
|
||||||
// for now could cheat (just like with errors): return a specially-marked
|
|
||||||
// vector and call string->number on buf from there
|
|
||||||
} else if (strncmp("+inf.0", p->tok_buf, 6) == 0 ||
|
} else if (strncmp("+inf.0", p->tok_buf, 6) == 0 ||
|
||||||
strncmp("-inf.0", p->tok_buf, 6) == 0) {
|
strncmp("-inf.0", p->tok_buf, 6) == 0) {
|
||||||
make_double(d, pow(2.0, 1000000));
|
make_double(d, pow(2.0, 1000000));
|
||||||
|
@ -6045,27 +6091,16 @@ void Cyc_io_read_token(void *data, object cont, object port)
|
||||||
return_thread_runnable(data, boolean_f);
|
return_thread_runnable(data, boolean_f);
|
||||||
// TODO: character
|
// TODO: character
|
||||||
// TODO: numbers
|
// TODO: numbers
|
||||||
/*
|
} else if (c == 'e') {
|
||||||
((eq? #\e next-c)
|
_read_number(data, p, 10, 1);
|
||||||
(parse-number fp toks all? parens ptbl
|
} else if (c == 'i') {
|
||||||
10 (lambda (num)
|
_read_number(data, p, 10, 0);
|
||||||
(exact
|
} else if (c == 'b') {
|
||||||
(string->number (list->string num))))))
|
_read_number(data, p, 2, 1);
|
||||||
((eq? #\i next-c)
|
} else if (c == 'o') {
|
||||||
(parse-number fp toks all? parens ptbl
|
_read_number(data, p, 8, 1);
|
||||||
10 (lambda (num)
|
} else if (c == 'x') {
|
||||||
(inexact
|
_read_number(data, p, 16, 1);
|
||||||
(string->number (list->string num))))))
|
|
||||||
((eq? #\b next-c)
|
|
||||||
(parse-number fp toks all? parens ptbl
|
|
||||||
2 (lambda (num) (string->number (list->string num) 2))))
|
|
||||||
((eq? #\o next-c)
|
|
||||||
(parse-number fp toks all? parens ptbl
|
|
||||||
8 (lambda (num) (string->number (list->string num) 8))))
|
|
||||||
((eq? #\x next-c)
|
|
||||||
(parse-number fp toks all? parens ptbl
|
|
||||||
16 (lambda (num) (string->number (list->string num) 16))))
|
|
||||||
*/
|
|
||||||
} else if (c == '(') { // Vector
|
} else if (c == '(') { // Vector
|
||||||
make_empty_vector(vec);
|
make_empty_vector(vec);
|
||||||
return_thread_runnable(data, &vec);
|
return_thread_runnable(data, &vec);
|
||||||
|
|
Loading…
Add table
Reference in a new issue