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_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_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
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
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;
|
||||
pic_value v;
|
||||
struct pic_proc *proc;
|
||||
int ai;
|
||||
bool r;
|
||||
|
||||
pic = pic_open();
|
||||
|
||||
|
@ -52,9 +55,10 @@ main()
|
|||
ai = pic_gc_arena_preserve(pic);
|
||||
|
||||
while (1) {
|
||||
prompt = code[0] == '\0' ? "> " : "* ";
|
||||
|
||||
#if PIC_ENABLE_READLINE
|
||||
read_line = readline("> ");
|
||||
read_line = readline(prompt);
|
||||
if (read_line == NULL) {
|
||||
line[0] = '\0';
|
||||
}
|
||||
|
@ -64,7 +68,7 @@ main()
|
|||
free(read_line);
|
||||
}
|
||||
#else
|
||||
printf("> ");
|
||||
printf(prompt);
|
||||
|
||||
char_index = 0;
|
||||
while ((last_char = getchar()) != '\n') {
|
||||
|
@ -77,8 +81,21 @@ main()
|
|||
line[char_index] = '\0';
|
||||
#endif
|
||||
|
||||
if (strlen(code) + strlen(line) >= CODE_MAX_LENGTH)
|
||||
goto overflow;
|
||||
strcat(code, line);
|
||||
|
||||
/* 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
|
||||
printf("[read: ");
|
||||
|
@ -86,11 +103,6 @@ main()
|
|||
printf("]\n");
|
||||
#endif
|
||||
|
||||
if (pic_undef_p(v)) {
|
||||
pic_gc_arena_restore(pic, ai);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* eval */
|
||||
proc = pic_codegen(pic, v, pic->global_env);
|
||||
v = pic_run(pic, proc, pic_nil_value());
|
||||
|
|
30
src/parse.y
30
src/parse.y
|
@ -9,6 +9,7 @@
|
|||
struct parser_control {
|
||||
pic_state *pic;
|
||||
pic_value value;
|
||||
bool incomp;
|
||||
};
|
||||
|
||||
%}
|
||||
|
@ -31,12 +32,17 @@ struct parser_control {
|
|||
program
|
||||
:
|
||||
{
|
||||
p->value = pic_undef_value(p->pic);
|
||||
p->value = pic_undef_value();
|
||||
}
|
||||
| datum
|
||||
{
|
||||
p->value = $1;
|
||||
}
|
||||
| incomplete_datum
|
||||
{
|
||||
p->incomp = true;
|
||||
p->value = pic_undef_value();
|
||||
}
|
||||
;
|
||||
|
||||
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
|
||||
|
@ -99,12 +117,13 @@ yyerror(struct parser_control *p, const char *msg)
|
|||
puts(msg);
|
||||
}
|
||||
|
||||
pic_value
|
||||
pic_parse(pic_state *pic, const char *str)
|
||||
bool
|
||||
pic_parse(pic_state *pic, const char *str, pic_value *v)
|
||||
{
|
||||
struct parser_control p;
|
||||
|
||||
p.pic = pic;
|
||||
p.incomp = false;
|
||||
|
||||
yy_scan_string(str);
|
||||
yyparse(&p);
|
||||
|
@ -114,5 +133,8 @@ pic_parse(pic_state *pic, const char *str)
|
|||
p.value = pic_undef_value();
|
||||
}
|
||||
|
||||
return p.value;
|
||||
if (! p.incomp) {
|
||||
*v = p.value;
|
||||
}
|
||||
return ! p.incomp;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue