support multi-line input in REPL
This commit is contained in:
parent
458ac6b9ab
commit
1a6c8a3cca
|
@ -61,7 +61,7 @@ bool pic_eq_p(pic_state *, pic_value, pic_value);
|
||||||
|
|
||||||
pic_value pic_intern_cstr(pic_state *, const char *);
|
pic_value pic_intern_cstr(pic_state *, const char *);
|
||||||
|
|
||||||
pic_value pic_parse(pic_state *, const char *);
|
bool pic_parse(pic_state *, const char *, pic_value *);
|
||||||
|
|
||||||
pic_value pic_eval(pic_state *, pic_value, struct pic_env *);
|
pic_value pic_eval(pic_state *, pic_value, struct pic_env *);
|
||||||
pic_value pic_run(pic_state *, struct pic_proc *, pic_value);
|
pic_value pic_run(pic_state *, struct pic_proc *, pic_value);
|
||||||
|
|
30
src/main.c
30
src/main.c
|
@ -31,17 +31,20 @@ test_object_creation(pic_state *pic)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define CODE_MAX_LENGTH 1024
|
||||||
#define LINE_MAX_LENGTH 256
|
#define LINE_MAX_LENGTH 256
|
||||||
|
|
||||||
int
|
int
|
||||||
main()
|
main()
|
||||||
{
|
{
|
||||||
pic_state *pic;
|
pic_state *pic;
|
||||||
char line[LINE_MAX_LENGTH], last_char, *read_line;
|
char code[CODE_MAX_LENGTH] = "", line[LINE_MAX_LENGTH];
|
||||||
|
char last_char, *read_line, *prompt;
|
||||||
int char_index;
|
int char_index;
|
||||||
pic_value v;
|
pic_value v;
|
||||||
struct pic_proc *proc;
|
struct pic_proc *proc;
|
||||||
int ai;
|
int ai;
|
||||||
|
bool r;
|
||||||
|
|
||||||
pic = pic_open();
|
pic = pic_open();
|
||||||
|
|
||||||
|
@ -52,9 +55,10 @@ main()
|
||||||
ai = pic_gc_arena_preserve(pic);
|
ai = pic_gc_arena_preserve(pic);
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
|
prompt = code[0] == '\0' ? "> " : "* ";
|
||||||
|
|
||||||
#if PIC_ENABLE_READLINE
|
#if PIC_ENABLE_READLINE
|
||||||
read_line = readline("> ");
|
read_line = readline(prompt);
|
||||||
if (read_line == NULL) {
|
if (read_line == NULL) {
|
||||||
line[0] = '\0';
|
line[0] = '\0';
|
||||||
}
|
}
|
||||||
|
@ -64,7 +68,7 @@ main()
|
||||||
free(read_line);
|
free(read_line);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
printf("> ");
|
printf(prompt);
|
||||||
|
|
||||||
char_index = 0;
|
char_index = 0;
|
||||||
while ((last_char = getchar()) != '\n') {
|
while ((last_char = getchar()) != '\n') {
|
||||||
|
@ -77,8 +81,21 @@ main()
|
||||||
line[char_index] = '\0';
|
line[char_index] = '\0';
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (strlen(code) + strlen(line) >= CODE_MAX_LENGTH)
|
||||||
|
goto overflow;
|
||||||
|
strcat(code, line);
|
||||||
|
|
||||||
/* read */
|
/* read */
|
||||||
v = pic_parse(pic, line);
|
r = pic_parse(pic, code, &v);
|
||||||
|
if (! r) { /* wait for more input */
|
||||||
|
pic_gc_arena_restore(pic, ai);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
code[0] = '\0';
|
||||||
|
if (pic_undef_p(v)) { /* parse error */
|
||||||
|
pic_gc_arena_restore(pic, ai);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
printf("[read: ");
|
printf("[read: ");
|
||||||
|
@ -86,11 +103,6 @@ main()
|
||||||
printf("]\n");
|
printf("]\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (pic_undef_p(v)) {
|
|
||||||
pic_gc_arena_restore(pic, ai);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* eval */
|
/* eval */
|
||||||
proc = pic_codegen(pic, v, pic->global_env);
|
proc = pic_codegen(pic, v, pic->global_env);
|
||||||
v = pic_run(pic, proc, pic_nil_value());
|
v = pic_run(pic, proc, pic_nil_value());
|
||||||
|
|
30
src/parse.y
30
src/parse.y
|
@ -9,6 +9,7 @@
|
||||||
struct parser_control {
|
struct parser_control {
|
||||||
pic_state *pic;
|
pic_state *pic;
|
||||||
pic_value value;
|
pic_value value;
|
||||||
|
bool incomp;
|
||||||
};
|
};
|
||||||
|
|
||||||
%}
|
%}
|
||||||
|
@ -31,12 +32,17 @@ struct parser_control {
|
||||||
program
|
program
|
||||||
:
|
:
|
||||||
{
|
{
|
||||||
p->value = pic_undef_value(p->pic);
|
p->value = pic_undef_value();
|
||||||
}
|
}
|
||||||
| datum
|
| datum
|
||||||
{
|
{
|
||||||
p->value = $1;
|
p->value = $1;
|
||||||
}
|
}
|
||||||
|
| incomplete_datum
|
||||||
|
{
|
||||||
|
p->incomp = true;
|
||||||
|
p->value = pic_undef_value();
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
datum
|
datum
|
||||||
|
@ -91,6 +97,18 @@ list_data
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
incomplete_datum
|
||||||
|
: tLPAREN incomplete_data
|
||||||
|
;
|
||||||
|
|
||||||
|
incomplete_data
|
||||||
|
: /* none */
|
||||||
|
| datum tDOT
|
||||||
|
| datum incomplete_datum
|
||||||
|
| datum tDOT incomplete_datum
|
||||||
|
| datum incomplete_data
|
||||||
|
;
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -99,12 +117,13 @@ yyerror(struct parser_control *p, const char *msg)
|
||||||
puts(msg);
|
puts(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
pic_value
|
bool
|
||||||
pic_parse(pic_state *pic, const char *str)
|
pic_parse(pic_state *pic, const char *str, pic_value *v)
|
||||||
{
|
{
|
||||||
struct parser_control p;
|
struct parser_control p;
|
||||||
|
|
||||||
p.pic = pic;
|
p.pic = pic;
|
||||||
|
p.incomp = false;
|
||||||
|
|
||||||
yy_scan_string(str);
|
yy_scan_string(str);
|
||||||
yyparse(&p);
|
yyparse(&p);
|
||||||
|
@ -114,5 +133,8 @@ pic_parse(pic_state *pic, const char *str)
|
||||||
p.value = pic_undef_value();
|
p.value = pic_undef_value();
|
||||||
}
|
}
|
||||||
|
|
||||||
return p.value;
|
if (! p.incomp) {
|
||||||
|
*v = p.value;
|
||||||
|
}
|
||||||
|
return ! p.incomp;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue