aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPřemysl Janouch <p.janouch@gmail.com>2017-05-17 23:34:58 +0200
committerPřemysl Janouch <p.janouch@gmail.com>2017-05-21 13:19:45 +0200
commit795cb42cc5534702c86ebb28750e63b166fc80c9 (patch)
tree965fccb936079e02a2139d864b43471f72515163
parentf7bce11c70c0315ef05ad063894bdb5ce949d48c (diff)
downloadell-795cb42cc5534702c86ebb28750e63b166fc80c9.tar.gz
ell-795cb42cc5534702c86ebb28750e63b166fc80c9.tar.xz
ell-795cb42cc5534702c86ebb28750e63b166fc80c9.zip
Make sure the lexer works
-rwxr-xr-xell.c57
1 files changed, 36 insertions, 21 deletions
diff --git a/ell.c b/ell.c
index 0d0e3dd..38b88da 100755
--- a/ell.c
+++ b/ell.c
@@ -252,11 +252,7 @@ token_name (enum token token) {
struct lexer {
const char *p; ///< Current position in input
size_t len; ///< How many bytes of input are left
-
- unsigned line; ///< Current line
- unsigned column; ///< Current column
-
- int64_t integer; ///< Parsed boolean or integer value
+ unsigned line, column; ///< Current line and column
struct buffer string; ///< Parsed string value
};
@@ -273,7 +269,8 @@ lexer_free (struct lexer *self) {
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
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",
self->line + 1, self->column + 1, description);
+ // TODO: see above, we should be able to indicate error without allocation
+ if (!*e)
+ abort ();
+
free (description);
}
@@ -426,9 +427,27 @@ lexer_next (struct lexer *self, char **e) {
// --- Parsing -----------------------------------------------------------------
+// TODO: parse "s" into a tree, including all the syntax sugar
static struct item *
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;
}
@@ -645,14 +664,19 @@ free_runtime_library (void) {
// --- Main --------------------------------------------------------------------
-static void
-process_message (const char *msg) {
- // Finally parse and execute the macro
+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
+ const char *program = "print 'hello world\n'";
+
const char *error = NULL;
- struct item *script = parse (msg, &error);
+ struct item *script = parse (program, &error);
if (error) {
printf ("%s: %s\r\n", "parse error", error);
- return;
+ return 1;
}
struct context ctx;
@@ -669,15 +693,6 @@ process_message (const char *msg) {
if (failure)
printf ("%s: %s\r\n", "runtime error", failure);
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 ();
return 0;