picrin/src/read.c

708 lines
13 KiB
C
Raw Normal View History

2014-03-01 06:21:44 -05:00
/**
* See Copyright Notice in picrin.h
*/
2014-06-25 02:36:36 -04:00
#include <ctype.h>
#include <math.h>
2014-03-01 06:21:44 -05:00
#include "picrin.h"
2014-06-25 02:36:36 -04:00
#include "picrin/error.h"
2014-03-01 06:21:44 -05:00
#include "picrin/pair.h"
#include "picrin/string.h"
#include "picrin/vector.h"
#include "picrin/blob.h"
#include "picrin/port.h"
2014-06-25 02:36:36 -04:00
typedef pic_value (*read_func_t)(pic_state *, struct pic_port *, char);
2014-03-01 06:21:44 -05:00
2014-06-25 02:36:36 -04:00
static pic_value read(pic_state *pic, struct pic_port *port, char c);
static pic_value read_nullable(pic_state *pic, struct pic_port *port, char c);
2014-03-01 06:21:44 -05:00
2014-06-25 02:36:36 -04:00
static noreturn void
read_error(pic_state *pic, const char *msg)
{
2014-07-04 00:32:54 -04:00
pic_throw(pic, PIC_ERROR_READ, msg, pic_nil_value());
2014-06-25 02:36:36 -04:00
}
2014-03-01 06:21:44 -05:00
2014-06-25 02:36:36 -04:00
static char
skip(struct pic_port *port, char c)
2014-03-01 06:21:44 -05:00
{
2014-06-25 02:36:36 -04:00
while (isspace(c)) {
c = xfgetc(port->file);
}
return c;
2014-03-01 06:21:44 -05:00
}
2014-06-25 02:36:36 -04:00
static char
next(struct pic_port *port)
2014-03-01 06:21:44 -05:00
{
return xfgetc(port->file);
2014-06-25 02:36:36 -04:00
}
static char
peek(struct pic_port *port)
{
char c;
xungetc((c = xfgetc(port->file)), port->file);
return c;
2014-03-01 06:21:44 -05:00
}
2014-07-04 00:44:30 -04:00
static bool
expect(struct pic_port *port, const char *str)
{
char c;
while ((c = *str++) != 0) {
if (c != next(port))
return false;
}
return true;
}
2014-06-26 18:23:34 -04:00
static bool
isdelim(char c)
{
2014-06-26 18:28:46 -04:00
return c == EOF || strchr("();,|\" \t\n\r", c) != NULL; /* ignores "#", "'" */
2014-06-26 18:23:34 -04:00
}
2014-03-31 22:40:20 -04:00
static pic_value
2014-06-25 02:36:36 -04:00
read_comment(pic_state *pic, struct pic_port *port, char c)
2014-03-31 22:40:20 -04:00
{
UNUSED(pic);
2014-06-25 02:36:36 -04:00
do {
c = next(port);
} while (! (c == EOF || c == '\n'));
2014-03-31 22:40:20 -04:00
return pic_undef_value();
2014-06-25 02:36:36 -04:00
}
2014-03-31 22:40:20 -04:00
2014-06-25 02:36:36 -04:00
static pic_value
read_block_comment(pic_state *pic, struct pic_port *port, char c)
{
char x, y;
int i = 1;
2014-03-31 22:40:20 -04:00
UNUSED(pic);
2014-06-25 02:36:36 -04:00
UNUSED(c);
2014-03-31 22:40:20 -04:00
2014-06-25 02:36:36 -04:00
y = next(port);
2014-03-31 22:40:20 -04:00
while (y != EOF && i > 0) {
x = y;
y = next(port);
2014-06-25 08:38:11 -04:00
if (x == '|' && y == '#') {
i--;
}
if (x == '#' && y == '|') {
i++;
}
2014-06-25 02:36:36 -04:00
}
2014-03-31 22:40:20 -04:00
return pic_undef_value();
}
static pic_value
read_datum_comment(pic_state *pic, struct pic_port *port, char c)
{
UNUSED(c);
read(pic, port, next(port));
return pic_undef_value();
2014-06-25 02:36:36 -04:00
}
2014-03-31 22:40:20 -04:00
2014-06-25 02:36:36 -04:00
static pic_value
read_quote(pic_state *pic, struct pic_port *port, char c)
{
UNUSED(c);
2014-03-31 22:40:20 -04:00
2014-06-25 02:36:36 -04:00
return pic_list2(pic, pic_sym_value(pic->sQUOTE), read(pic, port, next(port)));
}
2014-03-31 22:40:20 -04:00
2014-06-25 02:36:36 -04:00
static pic_value
read_quasiquote(pic_state *pic, struct pic_port *port, char c)
{
UNUSED(c);
return pic_list2(pic, pic_sym_value(pic->sQUASIQUOTE), read(pic, port, next(port)));
}
static pic_value
read_comma(pic_state *pic, struct pic_port *port, char c)
{
c = next(port);
if (c == '@') {
return pic_list2(pic, pic_sym_value(pic->sUNQUOTE_SPLICING), read(pic, port, next(port)));
} else {
return pic_list2(pic, pic_sym_value(pic->sUNQUOTE), read(pic, port, c));
}
}
static pic_value
read_symbol(pic_state *pic, struct pic_port *port, char c)
{
size_t len;
char *buf;
pic_sym sym;
len = 0;
buf = NULL;
do {
if (len != 0) {
c = next(port);
2014-03-31 22:40:20 -04:00
}
2014-06-25 02:36:36 -04:00
len += 1;
2014-06-28 11:54:20 -04:00
buf = pic_realloc(pic, buf, len + 1);
2014-06-25 02:36:36 -04:00
buf[len - 1] = c;
2014-06-26 18:23:34 -04:00
} while (! isdelim(peek(port)));
2014-03-31 22:40:20 -04:00
2014-06-25 02:36:36 -04:00
buf[len] = '\0';
sym = pic_intern_cstr(pic, buf);
pic_free(pic, buf);
2014-03-31 22:40:20 -04:00
2014-06-25 02:36:36 -04:00
return pic_sym_value(sym);
}
2014-06-28 09:32:26 -04:00
static size_t
read_uinteger(pic_state *pic, struct pic_port *port, char c, char buf[])
2014-06-25 02:36:36 -04:00
{
2014-06-28 09:32:26 -04:00
size_t i = 0;
2014-06-25 02:36:36 -04:00
if (! isdigit(c)) {
read_error(pic, "expected one or more digits");
}
2014-06-28 09:32:26 -04:00
buf[i++] = c;
2014-06-25 02:36:36 -04:00
while (isdigit(c = peek(port))) {
2014-06-28 09:32:26 -04:00
buf[i++] = next(port);
2014-06-25 02:36:36 -04:00
}
2014-06-28 09:32:26 -04:00
buf[i] = '\0';
return i;
2014-06-25 02:36:36 -04:00
}
static pic_value
read_number(pic_state *pic, struct pic_port *port, char c)
{
2014-06-28 09:32:26 -04:00
char buf[256];
size_t i;
2014-07-11 09:44:44 -04:00
long n;
2014-06-25 02:36:36 -04:00
2014-06-28 09:32:26 -04:00
i = read_uinteger(pic, port, c, buf);
2014-06-25 02:36:36 -04:00
2014-07-11 09:44:44 -04:00
switch (peek(port)) {
case '.':
2014-06-28 08:41:35 -04:00
do {
2014-06-28 09:32:26 -04:00
buf[i++] = next(port);
2014-06-28 08:41:35 -04:00
} while (isdigit(peek(port)));
2014-06-28 09:32:26 -04:00
buf[i] = '\0';
2014-06-28 08:41:35 -04:00
return pic_float_value(atof(buf));
2014-07-11 09:44:44 -04:00
case '/':
n = atoi(buf);
next(port);
read_uinteger(pic, port, next(port), buf);
if (n == n / atoi(buf) * atoi(buf)) {
return pic_int_value(n / atoi(buf)); /* exact */
} else {
return pic_float_value(n / (double)atoi(buf));
}
2014-07-11 09:44:44 -04:00
default:
2014-06-28 09:32:26 -04:00
return pic_int_value(atoi(buf));
2014-06-25 02:36:36 -04:00
}
}
static pic_value
negate(pic_value n)
{
if (pic_int_p(n)) {
return pic_int_value(-pic_int(n));
} else {
return pic_float_value(-pic_float(n));
}
}
static pic_value
read_minus(pic_state *pic, struct pic_port *port, char c)
{
2014-06-26 19:54:32 -04:00
pic_value sym;
2014-06-25 02:36:36 -04:00
2014-06-26 18:23:19 -04:00
if (isdigit(peek(port))) {
2014-06-26 18:59:25 -04:00
return negate(read_number(pic, port, next(port)));
2014-06-25 02:36:36 -04:00
}
else {
2014-06-26 19:54:32 -04:00
sym = read_symbol(pic, port, c);
if (pic_eq_p(sym, pic_sym_value(pic_intern_cstr(pic, "-inf.0")))) {
return pic_float_value(-INFINITY);
}
if (pic_eq_p(sym, pic_sym_value(pic_intern_cstr(pic, "-nan.0")))) {
return pic_float_value(-NAN);
}
return sym;
2014-06-25 02:36:36 -04:00
}
}
static pic_value
read_plus(pic_state *pic, struct pic_port *port, char c)
{
2014-06-26 19:54:32 -04:00
pic_value sym;
2014-06-25 02:36:36 -04:00
2014-06-26 18:23:19 -04:00
if (isdigit(peek(port))) {
2014-06-25 02:36:36 -04:00
return read_number(pic, port, c);
}
else {
2014-06-26 19:54:32 -04:00
sym = read_symbol(pic, port, c);
if (pic_eq_p(sym, pic_sym_value(pic_intern_cstr(pic, "+inf.0")))) {
return pic_float_value(INFINITY);
}
if (pic_eq_p(sym, pic_sym_value(pic_intern_cstr(pic, "+nan.0")))) {
return pic_float_value(NAN);
}
2014-06-25 02:36:36 -04:00
return read_symbol(pic, port, c);
}
}
static pic_value
read_boolean(pic_state *pic, struct pic_port *port, char c)
{
UNUSED(pic);
UNUSED(port);
2014-07-04 00:44:30 -04:00
if (! isdelim(peek(port))) {
if (c == 't') {
if (! expect(port, "rue")) {
goto fail;
}
} else {
if (! expect(port, "alse")) {
goto fail;
}
}
}
2014-06-25 02:36:36 -04:00
if (c == 't') {
return pic_true_value();
} else {
return pic_false_value();
}
2014-07-04 00:44:30 -04:00
fail:
read_error(pic, "illegal character during reading boolean literal");
2014-06-25 02:36:36 -04:00
}
static pic_value
read_char(pic_state *pic, struct pic_port *port, char c)
{
2014-07-16 03:12:25 -04:00
c = next(port);
2014-06-25 02:36:36 -04:00
2014-07-16 03:12:25 -04:00
if (! isdelim(peek(port))) {
switch (c) {
default: read_error(pic, "unexpected character after char literal");
case 'a': c = '\a'; expect(port, "lerm"); break;
case 'b': c = '\b'; expect(port, "ackspace"); break;
case 'd': c = 0x7F; expect(port, "elete"); break;
case 'e': c = 0x1B; expect(port, "scape"); break;
case 'n': c = peek(port) == 'e' ? (expect(port, "ewline"), '\n') : (expect(port, "ull"), '\0'); break;
case 'r': c = '\r'; expect(port, "eturn"); break;
case 's': c = ' '; expect(port, "pace"); break;
case 't': c = '\t'; expect(port, "ab"); break;
}
}
2014-06-25 02:36:36 -04:00
2014-07-16 03:12:25 -04:00
return pic_char_value(c);
2014-06-25 02:36:36 -04:00
}
static pic_value
read_string(pic_state *pic, struct pic_port *port, char c)
{
char *buf;
size_t size, cnt;
pic_str *str;
size = 256;
buf = pic_alloc(pic, size);
cnt = 0;
/* TODO: intraline whitespaces */
while ((c = next(port)) != '"') {
if (c == '\\') {
switch (c = next(port)) {
case 'a': c = '\a'; break;
case 'b': c = '\b'; break;
case 't': c = '\t'; break;
case 'n': c = '\n'; break;
case 'r': c = '\r'; break;
}
}
buf[cnt++] = c;
if (cnt >= size) {
buf = pic_realloc(pic, buf, size *= 2);
2014-03-31 22:40:20 -04:00
}
}
2014-06-25 02:36:36 -04:00
buf[cnt] = '\0';
2014-06-28 06:47:45 -04:00
str = pic_str_new(pic, buf, cnt);
2014-06-25 02:36:36 -04:00
pic_free(pic, buf);
return pic_obj_value(str);
2014-03-31 22:40:20 -04:00
}
static pic_value
2014-06-25 02:36:36 -04:00
read_unsigned_blob(pic_state *pic, struct pic_port *port, char c)
2014-03-31 22:40:20 -04:00
{
2014-06-25 02:36:36 -04:00
int nbits, n;
size_t len;
2014-06-28 09:32:26 -04:00
char *dat, buf[256];
2014-06-25 02:36:36 -04:00
pic_blob *blob;
2014-03-31 22:40:20 -04:00
2014-06-25 02:36:36 -04:00
nbits = 0;
while (isdigit(c = next(port))) {
nbits = 10 * nbits + c - '0';
2014-03-31 22:40:20 -04:00
}
2014-06-25 02:36:36 -04:00
if (nbits != 8) {
read_error(pic, "unsupported bytevector bit width");
}
if (c != '(') {
read_error(pic, "expected '(' character");
}
len = 0;
2014-06-28 09:32:26 -04:00
dat = NULL;
2014-06-25 02:36:36 -04:00
c = next(port);
while ((c = skip(port, c)) != ')') {
2014-06-28 09:32:26 -04:00
read_uinteger(pic, port, c, buf);
n = atoi(buf);
2014-06-25 02:36:36 -04:00
if (n < 0 || (1 << nbits) <= n) {
read_error(pic, "invalid element in bytevector literal");
}
len += 1;
2014-06-28 09:32:26 -04:00
dat = pic_realloc(pic, dat, len);
dat[len - 1] = n;
2014-06-25 02:36:36 -04:00
c = next(port);
}
2014-06-28 09:32:26 -04:00
blob = pic_blob_new(pic, dat, len);
pic_free(pic, dat);
2014-06-25 02:36:36 -04:00
return pic_obj_value(blob);
2014-03-31 22:40:20 -04:00
}
2014-03-01 06:21:44 -05:00
static pic_value
2014-06-25 02:36:36 -04:00
read_pair(pic_state *pic, struct pic_port *port, char c)
2014-03-01 06:21:44 -05:00
{
2014-06-25 02:36:36 -04:00
char tOPEN = c, tCLOSE = (tOPEN == '(') ? ')' : ']';
2014-03-01 06:21:44 -05:00
pic_value car, cdr;
retry:
2014-06-25 02:36:36 -04:00
c = skip(port, ' ');
if (c == tCLOSE) {
2014-03-01 06:21:44 -05:00
return pic_nil_value();
}
2014-06-26 18:23:34 -04:00
if (c == '.' && isdelim(peek(port))) {
2014-06-25 02:36:36 -04:00
cdr = read(pic, port, next(port));
2014-03-01 06:21:44 -05:00
2014-06-28 07:02:13 -04:00
closing:
2014-06-25 02:36:36 -04:00
if ((c = skip(port, ' ')) != tCLOSE) {
2014-06-28 07:02:13 -04:00
if (pic_undef_p(read_nullable(pic, port, c))) {
goto closing;
}
2014-06-25 02:36:36 -04:00
read_error(pic, "unmatched parenthesis");
2014-03-01 06:21:44 -05:00
}
return cdr;
}
else {
car = read_nullable(pic, port, c);
if (pic_undef_p(car)) {
goto retry;
}
2014-06-25 02:36:36 -04:00
cdr = read_pair(pic, port, tOPEN); /* FIXME: don't use recursion */
2014-03-01 06:21:44 -05:00
return pic_cons(pic, car, cdr);
}
}
2014-06-25 02:36:36 -04:00
static pic_value
read_vector(pic_state *pic, struct pic_port *port, char c)
2014-03-01 06:21:44 -05:00
{
pic_value list;
2014-03-01 06:21:44 -05:00
list = read(pic, port, c);
2014-06-25 08:40:51 -04:00
return pic_obj_value(pic_vec_new_from_list(pic, list));
2014-03-01 06:21:44 -05:00
}
static pic_value
2014-06-25 02:36:36 -04:00
read_label_set(pic_state *pic, struct pic_port *port, int i)
2014-03-01 06:21:44 -05:00
{
pic_value val;
2014-06-25 02:36:36 -04:00
char c;
2014-03-01 06:21:44 -05:00
2014-06-25 02:36:36 -04:00
switch (c = skip(port, ' ')) {
case '(': case '[':
{
pic_value tmp;
2014-03-01 06:21:44 -05:00
2014-06-25 02:36:36 -04:00
val = pic_cons(pic, pic_none_value(), pic_none_value());
2014-03-01 06:21:44 -05:00
2014-06-25 02:36:36 -04:00
xh_put_int(&pic->rlabels, i, &val);
2014-03-01 06:21:44 -05:00
2014-06-25 02:36:36 -04:00
tmp = read(pic, port, c);
pic_pair_ptr(val)->car = pic_car(pic, tmp);
pic_pair_ptr(val)->cdr = pic_cdr(pic, tmp);
2014-03-01 06:21:44 -05:00
2014-06-25 02:36:36 -04:00
return val;
}
case '#':
{
bool vect;
2014-03-01 06:21:44 -05:00
2014-06-25 02:36:36 -04:00
if (peek(port) == '(') {
vect = true;
} else {
vect = false;
}
2014-06-25 02:36:36 -04:00
if (vect) {
pic_vec *tmp;
2014-03-01 06:21:44 -05:00
2014-06-25 02:36:36 -04:00
val = pic_obj_value(pic_vec_new(pic, 0));
2014-03-01 06:21:44 -05:00
2014-06-25 02:36:36 -04:00
xh_put_int(&pic->rlabels, i, &val);
2014-03-01 06:21:44 -05:00
2014-06-25 02:36:36 -04:00
tmp = pic_vec_ptr(read(pic, port, c));
SWAP(pic_value *, tmp->data, pic_vec_ptr(val)->data);
SWAP(size_t, tmp->len, pic_vec_ptr(val)->len);
2014-03-01 06:21:44 -05:00
2014-06-25 02:36:36 -04:00
return val;
}
2014-03-01 06:21:44 -05:00
2014-06-25 02:36:36 -04:00
FALLTHROUGH;
}
default:
{
val = read(pic, port, c);
2014-03-01 06:21:44 -05:00
2014-06-25 02:36:36 -04:00
xh_put_int(&pic->rlabels, i, &val);
2014-03-01 06:21:44 -05:00
2014-06-25 02:36:36 -04:00
return val;
}
}
}
2014-03-01 06:21:44 -05:00
2014-06-25 02:36:36 -04:00
static pic_value
read_label_ref(pic_state *pic, struct pic_port *port, int i)
{
xh_entry *e;
2014-03-01 06:21:44 -05:00
2014-06-25 02:36:36 -04:00
UNUSED(port);
2014-03-01 06:21:44 -05:00
2014-06-25 02:36:36 -04:00
e = xh_get_int(&pic->rlabels, i);
if (! e) {
read_error(pic, "label of given index not defined");
2014-03-01 06:21:44 -05:00
}
2014-06-25 02:36:36 -04:00
return xh_val(e, pic_value);
2014-03-01 06:21:44 -05:00
}
static pic_value
2014-06-25 02:36:36 -04:00
read_label(pic_state *pic, struct pic_port *port, char c)
2014-03-01 06:21:44 -05:00
{
2014-06-25 02:36:36 -04:00
int i;
2014-03-01 06:21:44 -05:00
2014-06-25 02:36:36 -04:00
i = 0;
do {
i = i * 10 + c;
} while (isdigit(c = next(port)));
2014-03-01 06:21:44 -05:00
2014-06-25 02:36:36 -04:00
if (c == '=') {
return read_label_set(pic, port, i);
}
if (c == '#') {
return read_label_ref(pic, port, i);
}
read_error(pic, "broken label expression");
2014-03-01 06:21:44 -05:00
}
2014-06-25 02:36:36 -04:00
static pic_value
read_dispatch(pic_state *pic, struct pic_port *port, char c)
2014-03-01 06:21:44 -05:00
{
2014-06-25 02:36:36 -04:00
c = next(port);
switch (c) {
case '!':
return read_comment(pic, port, c);
case '|':
return read_block_comment(pic, port, c);
case ';':
return read_datum_comment(pic, port, c);
case 't': case 'f':
return read_boolean(pic, port, c);
case '\\':
return read_char(pic, port, c);
case '(':
return read_vector(pic, port, c);
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
return read_label(pic, port, c);
case 'u':
return read_unsigned_blob(pic, port, c);
default:
read_error(pic, "unexpected dispatch character");
}
}
2014-03-01 06:21:44 -05:00
2014-06-25 02:36:36 -04:00
static pic_value
read_nullable(pic_state *pic, struct pic_port *port, char c)
2014-06-25 02:36:36 -04:00
{
c = skip(port, c);
if (c == EOF) {
read_error(pic, "unexpected EOF");
2014-03-01 06:21:44 -05:00
}
2014-06-25 02:36:36 -04:00
switch (c) {
case ';':
return read_comment(pic, port, c);
case '#':
return read_dispatch(pic, port, c);
case '\'':
return read_quote(pic, port, c);
case '`':
return read_quasiquote(pic, port, c);
case ',':
return read_comma(pic, port, c);
case '"':
return read_string(pic, port, c);
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
return read_number(pic, port, c);
case '+':
return read_plus(pic, port, c);
case '-':
return read_minus(pic, port, c);
case '(': case '[':
return read_pair(pic, port, c);
default:
return read_symbol(pic, port, c);
2014-03-01 06:21:44 -05:00
}
}
static pic_value
read(pic_state *pic, struct pic_port *port, char c)
2014-03-01 06:21:44 -05:00
{
pic_value val;
2014-03-01 06:21:44 -05:00
retry:
val = read_nullable(pic, port, c);
if (pic_undef_p(val)) {
c = next(port);
goto retry;
}
return val;
}
pic_value
pic_read(pic_state *pic, struct pic_port *port)
{
2014-06-25 08:40:18 -04:00
pic_value val;
char c = next(port);
2014-06-25 08:40:18 -04:00
retry:
c = skip(port, c);
2014-06-25 08:40:18 -04:00
if (c == EOF) {
return pic_eof_object();
}
val = read_nullable(pic, port, c);
if (pic_undef_p(val)) {
c = next(port);
goto retry;
}
return val;
2014-06-25 02:36:36 -04:00
}
2014-03-01 06:21:44 -05:00
pic_value
2014-06-25 02:36:36 -04:00
pic_read_cstr(pic_state *pic, const char *str)
2014-03-01 06:21:44 -05:00
{
2014-06-25 02:36:36 -04:00
struct pic_port *port;
2014-03-01 06:21:44 -05:00
2014-06-25 02:36:36 -04:00
port = pic_open_input_string(pic, str);
2014-03-01 06:21:44 -05:00
2014-06-25 02:36:36 -04:00
return pic_read(pic, port);
}
2014-03-01 06:21:44 -05:00
2014-06-25 02:36:36 -04:00
static pic_value
pic_parse(pic_state *pic, struct pic_port *port)
{
pic_value val, acc;
2014-03-01 06:21:44 -05:00
2014-06-25 02:36:36 -04:00
pic_try {
acc = pic_nil_value();
while (! pic_eof_p(val = pic_read(pic, port))) {
pic_push(pic, val, acc);
}
}
pic_catch {
return pic_undef_value();
}
return pic_reverse(pic, acc);
2014-03-01 06:21:44 -05:00
}
2014-03-01 06:54:02 -05:00
pic_list
pic_parse_file(pic_state *pic, FILE *file)
2014-03-01 06:21:44 -05:00
{
2014-06-25 02:36:36 -04:00
struct pic_port *port;
2014-03-01 06:21:44 -05:00
2014-06-25 02:36:36 -04:00
port = (struct pic_port *)pic_obj_alloc(pic, sizeof(struct pic_port *), PIC_TT_PORT);
port->file = xfpopen(file);
port->flags = PIC_PORT_OUT | PIC_PORT_TEXT;
port->status = PIC_PORT_OPEN;
2014-03-01 06:21:44 -05:00
2014-06-25 02:36:36 -04:00
return pic_parse(pic, port);
2014-03-01 06:21:44 -05:00
}
2014-03-01 06:54:02 -05:00
pic_list
2014-06-25 02:36:36 -04:00
pic_parse_cstr(pic_state *pic, const char *str)
2014-03-01 06:21:44 -05:00
{
2014-06-25 02:36:36 -04:00
struct pic_port *port;
2014-03-01 06:21:44 -05:00
2014-06-25 02:36:36 -04:00
port = pic_open_input_string(pic, str);
2014-03-01 06:21:44 -05:00
2014-06-25 02:36:36 -04:00
return pic_parse(pic, port);
2014-03-01 06:21:44 -05:00
}
2014-06-25 09:36:56 -04:00
static pic_value
pic_read_read(pic_state *pic)
{
struct pic_port *port = pic_stdin(pic);
pic_get_args(pic, "|p", &port);
return pic_read(pic, port);
}
void
pic_init_read(pic_state *pic)
{
pic_deflibrary ("(scheme read)") {
pic_defun(pic, "read", pic_read_read);
}
}