parser returns multiple expressions in a call

This commit is contained in:
Yuichi Nishiwaki 2013-10-30 17:06:01 +09:00
parent 6fcce1cd23
commit 98a41314fe
4 changed files with 66 additions and 59 deletions

View File

@ -90,8 +90,8 @@ pic_value pic_str_new_cstr(pic_state *, const char *);
struct pic_vector *pic_vec_new(pic_state *, size_t); struct pic_vector *pic_vec_new(pic_state *, size_t);
struct pic_vector *pic_vec_new_from_list(pic_state *, pic_value); struct pic_vector *pic_vec_new_from_list(pic_state *, pic_value);
bool pic_parse_file(pic_state *, FILE *file, pic_value *); int pic_parse_file(pic_state *, FILE *file, pic_value *);
bool pic_parse_cstr(pic_state *, const char *, pic_value *); int pic_parse_cstr(pic_state *, const char *, pic_value *);
pic_value pic_apply(pic_state *pic, struct pic_proc *, pic_value); pic_value pic_apply(pic_state *pic, struct pic_proc *, pic_value);
pic_value pic_apply_argv(pic_state *pic, struct pic_proc *, size_t, ...); pic_value pic_apply_argv(pic_state *pic, struct pic_proc *, size_t, ...);

View File

@ -2,6 +2,7 @@
#include <stdlib.h> #include <stdlib.h>
#include "picrin.h" #include "picrin.h"
#include "picrin/pair.h"
void pic_init_pair(pic_state *); void pic_init_pair(pic_state *);
void pic_init_port(pic_state *); void pic_init_port(pic_state *);
@ -17,8 +18,8 @@ pic_load_stdlib(pic_state *pic)
{ {
static const char *fn = "piclib/built-in.scm"; static const char *fn = "piclib/built-in.scm";
FILE *file; FILE *file;
bool r; int n, i;
pic_value v; pic_value v, vs;
struct pic_proc *proc; struct pic_proc *proc;
file = fopen(fn, "r"); file = fopen(fn, "r");
@ -27,24 +28,28 @@ pic_load_stdlib(pic_state *pic)
abort(); abort();
} }
r = pic_parse_file(pic, file, &v); n = pic_parse_file(pic, file, &vs);
if (! r) { if (n <= 0) {
fputs("fatal error: built-in.scm broken", stderr); fputs("fatal error: built-in.scm broken", stderr);
abort(); abort();
} }
proc = pic_codegen(pic, v); for (i = 0; i < n; ++i, vs = pic_cdr(pic, vs)) {
if (proc == NULL) { v = pic_car(pic, vs);
fputs(pic->errmsg, stderr);
fputs("fatal error: built-in.scm compilation failure", stderr);
abort();
}
v = pic_apply(pic, proc, pic_nil_value()); proc = pic_codegen(pic, v);
if (pic_undef_p(v)) { if (proc == NULL) {
fputs(pic->errmsg, stderr); fputs(pic->errmsg, stderr);
fputs("fatal error: built-in.scm evaluation failure", stderr); fputs("fatal error: built-in.scm compilation failure", stderr);
abort(); abort();
}
v = pic_apply(pic, proc, pic_nil_value());
if (pic_undef_p(v)) {
fputs(pic->errmsg, stderr);
fputs("fatal error: built-in.scm evaluation failure", stderr);
abort();
}
} }
#if DEBUG #if DEBUG

View File

@ -52,14 +52,7 @@ void yylex_destroy();
program program
: program_data : program_data
{ {
/* if single? */ p->value = $1;
if (pic_eq_p(p->pic, pic_cdr(p->pic, $1), pic_nil_value())) {
p->value = pic_car(p->pic, $1);
}
/* if multiple? */
else {
p->value = pic_cons(p->pic, pic_symbol_value(p->pic->sBEGIN), $1);
}
} }
| incomplete_program_data | incomplete_program_data
{ {
@ -218,7 +211,7 @@ yylex(YYSTYPE *yylvalp, struct parser_control *p)
return yylex_(yylvalp, p->yyscanner); return yylex_(yylvalp, p->yyscanner);
} }
bool int
pic_parse_file(pic_state *pic, FILE *file, pic_value *v) pic_parse_file(pic_state *pic, FILE *file, pic_value *v)
{ {
struct parser_control p; struct parser_control p;
@ -234,15 +227,17 @@ pic_parse_file(pic_state *pic, FILE *file, pic_value *v)
if (p.yynerrs > 0) { if (p.yynerrs > 0) {
p.value = pic_undef_value(); p.value = pic_undef_value();
return -1;
}
if (p.incomp) {
return 0;
} }
if (! p.incomp) { *v = p.value;
*v = p.value; return pic_length(pic, p.value);
}
return ! p.incomp;
} }
bool int
pic_parse_cstr(pic_state *pic, const char *str, pic_value *v) pic_parse_cstr(pic_state *pic, const char *str, pic_value *v)
{ {
struct parser_control p; struct parser_control p;
@ -257,11 +252,12 @@ pic_parse_cstr(pic_state *pic, const char *str, pic_value *v)
yylex_destroy(p.yyscanner); yylex_destroy(p.yyscanner);
if (p.yynerrs > 0) { if (p.yynerrs > 0) {
p.value = pic_undef_value(); return -1;
}
if (p.incomp) {
return 0;
} }
if (! p.incomp) { *v = p.value;
*v = p.value; return pic_length(pic, p.value);
}
return ! p.incomp;
} }

View File

@ -2,6 +2,7 @@
#include <unistd.h> #include <unistd.h>
#include "picrin.h" #include "picrin.h"
#include "picrin/pair.h"
#if PIC_ENABLE_READLINE #if PIC_ENABLE_READLINE
# include <string.h> # include <string.h>
@ -58,10 +59,9 @@ repl(pic_state *pic)
{ {
char code[CODE_MAX_LENGTH] = "", line[LINE_MAX_LENGTH]; char code[CODE_MAX_LENGTH] = "", line[LINE_MAX_LENGTH];
char *read_line, *prompt; char *read_line, *prompt;
pic_value v; pic_value v, vs;
struct pic_proc *proc; struct pic_proc *proc;
int ai; int ai, n, i;
bool r;
#if ! PIC_ENABLE_READLINE #if ! PIC_ENABLE_READLINE
char last_char; char last_char;
@ -102,39 +102,45 @@ repl(pic_state *pic)
strcat(code, line); strcat(code, line);
/* read */ /* read */
r = pic_parse_cstr(pic, code, &v); n = pic_parse_cstr(pic, code, &vs);
if (! r) { /* wait for more input */ if (n == 0) { /* wait for more input */
goto next; goto next;
} }
code[0] = '\0'; code[0] = '\0';
if (pic_undef_p(v)) { /* parse error */ if (n == -1) { /* parse error */
goto next; goto next;
} }
for (i = 0; i < n; ++i) {
v = pic_car(pic, vs);
#if DEBUG #if DEBUG
printf("[read: "); printf("[read: ");
pic_debug(pic, v); pic_debug(pic, v);
printf("]\n"); printf("]\n");
#endif #endif
/* eval */ /* eval */
proc = pic_codegen(pic, v); proc = pic_codegen(pic, v);
if (proc == NULL) { if (proc == NULL) {
printf("compilation error: %s\n", pic->errmsg); printf("compilation error: %s\n", pic->errmsg);
pic->errmsg = NULL; pic->errmsg = NULL;
goto next; goto next;
} }
v = pic_apply(pic, proc, pic_nil_value()); v = pic_apply(pic, proc, pic_nil_value());
if (pic_undef_p(v)) { if (pic_undef_p(v)) {
printf("runtime error: %s\n", pic->errmsg); printf("runtime error: %s\n", pic->errmsg);
pic->errmsg = NULL; pic->errmsg = NULL;
goto next; goto next;
} }
/* print */ /* print */
printf("=> "); printf("=> ");
pic_debug(pic, v); pic_debug(pic, v);
printf("\n"); printf("\n");
vs = pic_cdr(pic, vs);
}
next: next:
pic_gc_arena_restore(pic, ai); pic_gc_arena_restore(pic, ai);