mpc_result_t r;
lex_tok_t* p_tok = NULL;
char* text = scanner_read(p_lexer->scanner);
- if (mpc_parse("<stdin>", text, p_lexer->lexrule, &r)) {
- mpc_ast_print(((mpc_ast_t*)r.output)->children[1]);
- p_tok = lexer_translate( ((mpc_ast_t*)r.output)->children[1] );
- mpc_ast_delete(r.output);
- } else {
- mpc_err_print(r.error);
- mpc_err_delete(r.error);
+ if (NULL != text) {
+ if (mpc_parse("<stdin>", text, p_lexer->lexrule, &r)) {
+ mpc_ast_print(((mpc_ast_t*)r.output)->children[1]);
+ p_tok = lexer_translate( ((mpc_ast_t*)r.output)->children[1] );
+ mpc_ast_delete(r.output);
+ } else {
+ mpc_err_print(r.error);
+ mpc_err_delete(r.error);
+ }
+ free(text);
}
- free(text);
return p_tok;
}
typedef enum {
END, STRING, CHAR, INT, FLOAT, BOOL, LBRACE, RBRACE, LBRACK, RBRACK, LPAR,
- RPAR, COMMA, VAR
+ RPAR, COMMA, VAR, END_FILE
} lex_tok_type_t;
typedef struct {
lex_tok_t* p_tok;
} parser_t;
+lex_tok_t tok_eof = { END_FILE, NULL, 0, 0, NULL };
+
parser_t* parser_new(char* p_prompt, FILE* input)
{
parser_t* p_parser = (parser_t*)malloc(sizeof(parser_t));
void parser_fetch(parser_t* p_parser)
{
p_parser->p_tok = lexer_read(p_parser->p_lexer);
+ if (NULL == p_parser->p_tok)
+ p_parser->p_tok = &tok_eof;
}
lex_tok_t* parser_peek(parser_t* p_parser)
return p_parser->p_tok;
}
+bool parser_eof(parser_t* p_parser) {
+ return (parser_peek(p_parser)->type == END_FILE);
+}
+
void parser_error(parser_t* p_parser, const char* p_text)
{
(void)p_parser;
*****************************************************************************/
/* TODO:
- * Gracefully handle EOF
* Formalize grammar for parser
* Paren for function application must be on same line as variable in REPL
* "end" and ';' must be equivalent
(void)argc;
(void)argv;
- //scanner_t* p_scanner = scanner_new(":> ", stdin);
- //while(!scanner_eof(p_scanner)) {
- // printf("TOK: '%s'\n", scanner_read(p_scanner) );
- // puts("OK.");
- //}
-
parser_t* p_parser = parser_new(":> ", stdin);
- while(true) {
+ while(!parser_eof(p_parser)) {
parser_toplevel(p_parser);
puts("OK.");
}
/* If we haven't read a line yet, read one now */
if (NULL == p_scanner->p_line)
scanner_getline(p_scanner);
- while('\0' == scanner_current(p_scanner) || scanner_oneof(p_scanner, " \t\r\n")) {
- if ('\0' == scanner_current(p_scanner) && !scanner_eof(p_scanner)) {
+ /* Fast forward past whitespace and read a newline if necessary */
+ while(!scanner_eof(p_scanner)) {
+ if ('\0' == scanner_current(p_scanner)) {
scanner_getline(p_scanner);
- } else {
+ } else if (scanner_oneof(p_scanner, " \t\r\n")) {
p_scanner->index++;
+ } else {
+ break;
}
}
}