%%
-Tok* gettoken(Parser* ctx)
-{
- Tok* tok = NULL;
- int type = yylex();
- if (type != T_END_FILE) {
- tok = emalloc(sizeof(Tok));
- tok->type = type;
+void gettoken(Parser* ctx, Tok* tok) {
+ tok->type = yylex();
+ if (tok->type != T_END_FILE)
memcpy(&(tok->value), &Value, sizeof(Value));
- }
- return tok;
}
void fetchline(Parser* ctx)
/* Driver Modes
*****************************************************************************/
static int emit_tokens(void) {
- Tok* token = NULL;
+ Tok token = { 0 };
Parser* ctx = parser_new(NULL, stdin);
- while(NULL != (token = gettoken(ctx)))
- pprint_token(stdout, token, true);
+ while (1) {
+ gettoken(ctx, &token);
+ if (token.type == T_END_FILE)
+ break;
+ else
+ pprint_token(stdout, &token, true);
+ }
return 0;
}
{
AST* ret = NULL;
if (!match(p, T_END_FILE)) {
- if (accept(p, T_REQUIRE))
- ret = require(p);
- else if (accept(p, T_DEF))
+ if (accept(p, T_DEF))
ret = definition(p);
else
- error(p, "expressions are not allowed at the toplevel");
+ error(p, "only definitions are allowed at the toplevel");
}
return ret;
}
Parser* parser_new(char* prompt, FILE* input)
{
Parser* parser = emalloc(sizeof(Parser));
- parser->line = NULL;
- parser->index = 0;
- parser->lineno = 0;
+ memset(parser, 0, sizeof(Parser));
parser->input = input;
parser->prompt = prompt;
- parser->tok = NULL;
return parser;
}
static void fetch(Parser* parser)
{
- parser->tok = gettoken(parser);
- if (NULL == parser->tok)
- parser->tok = &tok_eof;
+ gettoken(parser, &(parser->tok));
}
static Tok* peek(Parser* parser)
{
- if (NULL == parser->tok)
+ if (T_NONE == parser->tok.type)
fetch(parser);
- return parser->tok;
+ return &(parser->tok);
}
static bool parser_eof(Parser* parser)
static void parser_resume(Parser* parser)
{
- if ((NULL != parser->tok) && (&tok_eof != parser->tok))
- parser->tok = NULL;
+ if ((T_NONE != parser->tok.type) && (T_END_FILE != parser->tok.type))
+ parser->tok.type = T_NONE;
/* We ignore the rest of the current line and attempt to start parsing
* again on the next line */
fetchline(parser);
static Tok* accept(Parser* parser, TokType type)
{
Tok* tok = peek(parser);
- if (tok->type == type) {
- parser->tok = NULL;
- return tok;
- }
- return NULL;
+ if (tok->type == type)
+ parser->tok.type = T_NONE;
+ return tok;
}
static Tok* expect(Parser* parser, TokType type)
/* Token Types
*****************************************************************************/
typedef enum {
- T_ID, T_CHAR, T_INT, T_FLOAT, T_BOOL, T_STRING, T_LBRACE, T_RBRACE, T_LBRACK,
- T_RBRACK, T_LPAR, T_RPAR, T_COMMA, T_SQUOTE, T_DQUOTE, T_END, T_COLON, T_AMP,
- T_REQUIRE, T_DEF, T_IF, T_FN, T_THEN, T_ELSE, T_END_FILE
+ T_NONE, T_ID, T_CHAR, T_INT, T_FLOAT, T_BOOL, T_STRING, T_LBRACE, T_RBRACE,
+ T_LBRACK, T_RBRACK, T_LPAR, T_RPAR, T_COMMA, T_SQUOTE, T_DQUOTE, T_END,
+ T_COLON, T_AMP, T_REQUIRE, T_DEF, T_IF, T_FN, T_THEN, T_ELSE, T_END_FILE
} TokType;
typedef struct {
size_t lineno;
FILE* input;
char* prompt;
- Tok* tok;
+ Tok tok;
} Parser;
// Lexer routines
-Tok* gettoken(Parser* ctx);
+void gettoken(Parser* ctx, Tok* tok);
void fetchline(Parser* ctx);
// Parser routines