Make sure the lexer works
This commit is contained in:
parent
f7bce11c70
commit
795cb42cc5
57
ell.c
57
ell.c
|
@ -252,11 +252,7 @@ token_name (enum token token) {
|
||||||
struct lexer {
|
struct lexer {
|
||||||
const char *p; ///< Current position in input
|
const char *p; ///< Current position in input
|
||||||
size_t len; ///< How many bytes of input are left
|
size_t len; ///< How many bytes of input are left
|
||||||
|
unsigned line, column; ///< Current line and column
|
||||||
unsigned line; ///< Current line
|
|
||||||
unsigned column; ///< Current column
|
|
||||||
|
|
||||||
int64_t integer; ///< Parsed boolean or integer value
|
|
||||||
struct buffer string; ///< Parsed string value
|
struct buffer string; ///< Parsed string value
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -273,7 +269,8 @@ lexer_free (struct lexer *self) {
|
||||||
free (self->string.s);
|
free (self->string.s);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool lexer_is_word_char (int c) { return !strchr ("()[]{}\n@#'", c); }
|
// FIXME: other isspace() stuff is missing
|
||||||
|
static bool lexer_is_word_char (int c) { return !strchr ("()[]{}\n@#' ", c); }
|
||||||
|
|
||||||
static int
|
static int
|
||||||
lexer_advance (struct lexer *self) {
|
lexer_advance (struct lexer *self) {
|
||||||
|
@ -302,6 +299,10 @@ lexer_error (struct lexer *self, char **e, const char *fmt, ...) {
|
||||||
*e = format ("near line %u, column %u: %s",
|
*e = format ("near line %u, column %u: %s",
|
||||||
self->line + 1, self->column + 1, description);
|
self->line + 1, self->column + 1, description);
|
||||||
|
|
||||||
|
// TODO: see above, we should be able to indicate error without allocation
|
||||||
|
if (!*e)
|
||||||
|
abort ();
|
||||||
|
|
||||||
free (description);
|
free (description);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -426,9 +427,27 @@ lexer_next (struct lexer *self, char **e) {
|
||||||
|
|
||||||
// --- Parsing -----------------------------------------------------------------
|
// --- Parsing -----------------------------------------------------------------
|
||||||
|
|
||||||
|
// TODO: parse "s" into a tree, including all the syntax sugar
|
||||||
static struct item *
|
static struct item *
|
||||||
parse (const char *s, const char **error) {
|
parse (const char *s, const char **error) {
|
||||||
// TODO
|
struct lexer lexer;
|
||||||
|
lexer_init (&lexer, s, strlen (s));
|
||||||
|
|
||||||
|
char *e = NULL;
|
||||||
|
enum token type;
|
||||||
|
while ((type = lexer_next (&lexer, &e)) != T_ABORT) {
|
||||||
|
printf ("%s", token_name (type));
|
||||||
|
if (type == T_STRING) {
|
||||||
|
buffer_append_c (&lexer.string, 0);
|
||||||
|
printf (" '%s'", lexer.string.s);
|
||||||
|
}
|
||||||
|
printf ("\n");
|
||||||
|
}
|
||||||
|
if (e) {
|
||||||
|
printf ("error: %s\n", e);
|
||||||
|
free (e);
|
||||||
|
}
|
||||||
|
lexer_free (&lexer);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -645,14 +664,19 @@ free_runtime_library (void) {
|
||||||
|
|
||||||
// --- Main --------------------------------------------------------------------
|
// --- Main --------------------------------------------------------------------
|
||||||
|
|
||||||
static void
|
int
|
||||||
process_message (const char *msg) {
|
main (int argc, char *argv[]) {
|
||||||
// Finally parse and execute the macro
|
if (!init_runtime_library ())
|
||||||
|
printf ("%s\n", "runtime library initialization failed");
|
||||||
|
|
||||||
|
// TODO: load the entirety of stdin and execute it
|
||||||
|
const char *program = "print 'hello world\n'";
|
||||||
|
|
||||||
const char *error = NULL;
|
const char *error = NULL;
|
||||||
struct item *script = parse (msg, &error);
|
struct item *script = parse (program, &error);
|
||||||
if (error) {
|
if (error) {
|
||||||
printf ("%s: %s\r\n", "parse error", error);
|
printf ("%s: %s\r\n", "parse error", error);
|
||||||
return;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct context ctx;
|
struct context ctx;
|
||||||
|
@ -669,15 +693,6 @@ process_message (const char *msg) {
|
||||||
if (failure)
|
if (failure)
|
||||||
printf ("%s: %s\r\n", "runtime error", failure);
|
printf ("%s: %s\r\n", "runtime error", failure);
|
||||||
context_free (&ctx);
|
context_free (&ctx);
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
main (int argc, char *argv[]) {
|
|
||||||
if (!init_runtime_library ())
|
|
||||||
printf ("%s\n", "runtime library initialization failed");
|
|
||||||
|
|
||||||
// TODO: load the entirety of stdin and execute it
|
|
||||||
process_message ("print 'hello world\n'");
|
|
||||||
|
|
||||||
free_runtime_library ();
|
free_runtime_library ();
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in New Issue