picrin/tools/main.c

149 lines
2.5 KiB
C
Raw Normal View History

2013-10-09 03:58:35 -04:00
#include <stdio.h>
2013-10-24 06:06:31 -04:00
#include <unistd.h>
2013-10-09 03:58:35 -04:00
2013-10-10 03:15:41 -04:00
#include "picrin.h"
2013-10-17 04:08:33 -04:00
#if PIC_ENABLE_READLINE
2013-10-17 04:57:12 -04:00
# include <string.h>
# include <stdlib.h>
2013-10-17 04:08:33 -04:00
# include <readline/readline.h>
# include <readline/history.h>
#endif
2013-10-17 07:48:50 -04:00
#define CODE_MAX_LENGTH 1024
2013-10-09 04:14:48 -04:00
#define LINE_MAX_LENGTH 256
2013-10-24 06:06:31 -04:00
void
print_help(void)
{
const char *help =
"picrin scheme\n"
"\n"
"Usage: picrin [options]\n"
"\n"
"Options:\n"
" -h show this help";
puts(help);
}
void
parse_opt(int argc, char *argv[])
{
int r;
while (~(r = getopt(argc, argv, "h"))) {
switch (r) {
case 'h':
print_help();
exit(0);
}
}
}
2013-10-09 03:58:35 -04:00
int
2013-10-20 22:51:02 -04:00
main(int argc, char *argv[], char **envp)
2013-10-09 03:58:35 -04:00
{
2013-10-10 03:15:41 -04:00
pic_state *pic;
2013-10-17 07:48:50 -04:00
char code[CODE_MAX_LENGTH] = "", line[LINE_MAX_LENGTH];
2013-10-19 14:05:42 -04:00
char *read_line, *prompt;
2013-10-11 02:20:53 -04:00
pic_value v;
2013-10-11 23:55:05 -04:00
struct pic_proc *proc;
int ai;
2013-10-17 07:48:50 -04:00
bool r;
2013-10-19 14:05:42 -04:00
#if ! PIC_ENABLE_READLINE
char last_char;
int char_index;
#endif
2013-10-24 06:06:31 -04:00
parse_opt(argc, argv);
2013-10-20 22:51:02 -04:00
pic = pic_open(argc, argv, envp);
2013-10-10 03:15:41 -04:00
ai = pic_gc_arena_preserve(pic);
while (1) {
2013-10-17 07:48:50 -04:00
prompt = code[0] == '\0' ? "> " : "* ";
2013-10-17 04:08:33 -04:00
#if PIC_ENABLE_READLINE
2013-10-17 07:48:50 -04:00
read_line = readline(prompt);
2013-10-17 04:08:33 -04:00
if (read_line == NULL) {
2013-10-19 23:57:15 -04:00
goto eof;
2013-10-17 04:08:33 -04:00
}
else {
strncpy(line, read_line, LINE_MAX_LENGTH - 1);
add_history(read_line);
free(read_line);
}
#else
2013-10-17 07:48:50 -04:00
printf(prompt);
char_index = 0;
while ((last_char = getchar()) != '\n') {
if (last_char == EOF)
goto eof;
2013-10-09 04:14:48 -04:00
if (char_index == LINE_MAX_LENGTH)
goto overflow;
line[char_index++] = last_char;
}
line[char_index] = '\0';
2013-10-17 04:08:33 -04:00
#endif
2013-10-17 07:48:50 -04:00
if (strlen(code) + strlen(line) >= CODE_MAX_LENGTH)
goto overflow;
strcat(code, line);
2013-10-12 00:06:02 -04:00
/* read */
2013-10-27 05:38:41 -04:00
r = pic_parse_cstr(pic, code, &v);
2013-10-17 07:48:50 -04:00
if (! r) { /* wait for more input */
goto next;
2013-10-17 07:48:50 -04:00
}
code[0] = '\0';
if (pic_undef_p(v)) { /* parse error */
goto next;
2013-10-17 07:48:50 -04:00
}
2013-10-14 20:08:10 -04:00
#if DEBUG
printf("[read: ");
pic_debug(pic, v);
printf("]\n");
#endif
2013-10-12 00:06:02 -04:00
/* eval */
proc = pic_codegen(pic, v);
if (proc == NULL) {
printf("compilation error: %s\n", pic->errmsg);
pic->errmsg = NULL;
goto next;
}
v = pic_apply(pic, proc, pic_nil_value());
2013-10-20 10:30:01 -04:00
if (pic_undef_p(v)) {
printf("runtime error: %s\n", pic->errmsg);
pic->errmsg = NULL;
goto next;
}
2013-10-12 00:06:02 -04:00
/* print */
2013-10-15 06:12:33 -04:00
printf("=> ");
2013-10-11 23:55:05 -04:00
pic_debug(pic, v);
printf("\n");
next:
pic_gc_arena_restore(pic, ai);
}
eof:
puts("");
2013-10-09 04:14:48 -04:00
goto exit;
overflow:
puts("** [fatal] line input overflow");
goto exit;
2013-10-09 04:14:48 -04:00
exit:
2013-10-10 03:15:41 -04:00
pic_close(pic);
2013-10-09 03:58:35 -04:00
return 0;
}