implement numerical I/O

This commit is contained in:
Yuichi Nishiwaki 2014-04-02 00:06:38 +09:00
parent af064e384a
commit 28edfb5023
2 changed files with 57 additions and 1 deletions

View File

@ -122,7 +122,7 @@ Picrin is a lightweight scheme implementation intended to comply with full R7RS
| 6.2.4 Implementation extensions | yes | | | 6.2.4 Implementation extensions | yes | |
| 6.2.5 Syntax of numerical constants | yes | | | 6.2.5 Syntax of numerical constants | yes | |
| 6.2.6 Numerical operations | yes | `denominator`, `numerator`, and `rationalize` are not supported for now. Also, picrin does not provide complex library procedures. | | 6.2.6 Numerical operations | yes | `denominator`, `numerator`, and `rationalize` are not supported for now. Also, picrin does not provide complex library procedures. |
| 6.2.7 Numerical input and output | no | | | 6.2.7 Numerical input and output | incomplete | only partial support supplied. |
| 6.3 Booleans | yes | | | 6.3 Booleans | yes | |
| 6.4 Pairs and lists | yes | `list?` is safe for using against circular list. | | 6.4 Pairs and lists | yes | `list?` is safe for using against circular list. |
| 6.5 Symbols | yes | | | 6.5 Symbols | yes | |

View File

@ -7,6 +7,7 @@
#include <stdlib.h> #include <stdlib.h>
#include "picrin.h" #include "picrin.h"
#include "picrin/string.h"
static int static int
gcd(int a, int b) gcd(int a, int b)
@ -679,6 +680,57 @@ pic_number_exact(pic_state *pic)
return pic_int_value((int)round(f)); return pic_int_value((int)round(f));
} }
static pic_value
pic_number_number_to_string(pic_state *pic)
{
double f;
bool e;
int radix = 10;
pic_get_args(pic, "F|i", &f, &e, &radix);
if (e) {
char buf[snprintf(NULL, 0, "%d", (int)f) + 1];
snprintf(buf, sizeof buf, "%d", (int)f);
return pic_obj_value(pic_str_new(pic, buf, sizeof buf - 1));
}
else {
char buf[snprintf(NULL, 0, "%a", f) + 1];
snprintf(buf, sizeof buf, "%a", f);
return pic_obj_value(pic_str_new(pic, buf, sizeof buf - 1));
}
}
static pic_value
pic_number_string_to_number(pic_state *pic)
{
const char *str;
int radix = 10;
long num;
char *eptr;
double flo;
pic_get_args(pic, "z|i", &str, &radix);
num = strtol(str, &eptr, radix);
if (*eptr == '\0') {
return pic_valid_int(num)
? pic_int_value(num)
: pic_float_value(num);
}
flo = strtod(str, &eptr);
if (*eptr == '\0') {
return pic_float_value(flo);
}
pic_errorf(pic, "invalid string given: %s", str);
}
void void
pic_init_number(pic_state *pic) pic_init_number(pic_state *pic)
{ {
@ -745,6 +797,10 @@ pic_init_number(pic_state *pic)
pic_defun(pic, "exact", pic_number_exact); pic_defun(pic, "exact", pic_number_exact);
pic_gc_arena_restore(pic, ai); pic_gc_arena_restore(pic, ai);
pic_defun(pic, "number->string", pic_number_number_to_string);
pic_defun(pic, "string->number", pic_number_string_to_number);
pic_gc_arena_restore(pic, ai);
pic_deflibrary ("(scheme inexact)") { pic_deflibrary ("(scheme inexact)") {
pic_defun(pic, "finite?", pic_number_finite_p); pic_defun(pic, "finite?", pic_number_finite_p);
pic_defun(pic, "infinite?", pic_number_infinite_p); pic_defun(pic, "infinite?", pic_number_infinite_p);