commit bc11d230ec4342dc8997eb367d6aaf89d0391c02
parent 7cfeb32417607210301aad01b7b31f5b294a9fa2
Author: Andres Navarro <canavarro82@gmail.com>
Date: Sun, 20 Nov 2011 21:43:15 -0300
Completed the major structure of the new interpreter, still missing the actual functionality thou.
Diffstat:
M | src/klisp.c | | | 157 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------- |
M | src/klisp.h | | | 6 | ++++++ |
2 files changed, 143 insertions(+), 20 deletions(-)
diff --git a/src/klisp.c b/src/klisp.c
@@ -35,7 +35,8 @@
static const char *progname = KLISP_PROGNAME;
-static void print_usage (void) {
+static void print_usage (void)
+{
fprintf(stderr,
"usage: %s [options] [script [args]].\n"
"Available options are:\n"
@@ -51,31 +52,102 @@ static void print_usage (void) {
fflush(stderr);
}
-static void k_message (const char *pname, const char *msg) {
+static void k_message (const char *pname, const char *msg)
+{
if (pname)
fprintf(stderr, "%s: ", pname);
fprintf(stderr, "%s\n", msg);
fflush(stderr);
}
+static void print_version (void)
+{
+ k_message(NULL, KLISP_RELEASE " " KLISP_COPYRIGHT);
+}
+
+/* check that argument has no extra characters at the end */
+#define notail(x) {if ((x)[2] != '\0') return -1;}
+
+static int collectargs (char **argv, bool *pi, bool *pv, bool *pe)
+{
+ int i;
+ for (i = 1; argv[i] != NULL; i++) {
+ if (argv[i][0] != '-') /* not an option? */
+ return i;
+ switch (argv[i][1]) { /* option */
+ case '-':
+ notail(argv[i]);
+ return (argv[i+1] != NULL ? i+1 : 0);
+ case '\0':
+ return i;
+ case 'i':
+ notail(argv[i]);
+ *pi = true; /* go through */
+ case 'v':
+ notail(argv[i]);
+ *pv = true;
+ break;
+ case 'e':
+ *pe = true; /* go through */
+// case 'l': /* No library for now */
+ if (argv[i][2] == '\0') {
+ i++;
+ if (argv[i] == NULL)
+ return -1;
+ }
+ break;
+ default:
+ return -1; /* invalid option */
+ }
+ }
+ return 0;
+}
+
+static int runargs (klisp_State *K, char **argv, int n)
+{
+ for (int i = 1; i < n; i++) {
+ if (argv[i] == NULL)
+ continue;
+
+ klisp_assert(argv[i][0] == '-');
+
+ switch (argv[i][1]) { /* option */
+ case 'e': {
+ const char *chunk = argv[i] + 2;
+ if (*chunk == '\0')
+ chunk = argv[++i];
+ klisp_assert(chunk != NULL);
+
+ /* TODO do string */
+ UNUSED(K);
+// if (dostring(L, chunk, "=(command line)") != 0)
+// return 1;
+ break;
+ }
+// case 'l': /* no libraries for now */
+ default:
+ break;
+ }
+ }
+ return 0;
+}
+
+/* This is weird but was done to follow lua scheme */
struct Smain {
- int argc;
- char **argv;
- int status;
+ int argc;
+ char **argv;
+ int status;
};
-int main(int argc, char *argv[])
+static int pmain (klisp_State *K)
{
+ /* This is weird but was done to follow lua scheme */
+ struct Smain *s = (struct Smain *) pvalue(K->next_obj);
+ char **argv = s->argv;
+
if (argv[0] && argv[0][0])
progname = argv[0];
- klisp_State *K = klispL_newstate();
-
- if (K == NULL) {
- k_message(argv[0], "cannot create state: not enough memory");
- return EXIT_FAILURE;
- }
-
/* TODO Here we should load libraries, however we don't have any
non native bindings in the ground environment yet */
/* RATIONALE I wanted to write all bindings in c, so that I can later on
@@ -83,14 +155,59 @@ int main(int argc, char *argv[])
Also by writing all in c it's easy to be consistent, especially with
error messages */
- /* XXX Fix REPL, Fix Script */
+ /* TODO do init */
+ bool has_i = false, has_v = false, has_e = false;
+ int script = collectargs(argv, &has_i, &has_v, &has_e);
- // klispS_run(K); /* XXX Now this does nothing */
- int exit_code = EXIT_FAILURE; // K->script_exit_code;
- klisp_close(K);
+ if (script < 0) { /* invalid args? */
+ print_usage();
+ s->status = 1;
+ return 0;
+ }
+
+ if (has_v)
+ print_version();
+
+ s->status = runargs(K, argv, (script > 0) ? script : s->argc);
+
+ if (s->status != 0)
+ return 0;
+
+ if (script > 0) /* XXX FIX script */
+ s->status = 0;
+
+ if (s->status != 0)
+ return 0;
+
+ if (has_i) /* TODO FIX REPL */
+ s->status = 0;
+ else if (script == 0 && !has_e && !has_v) {
+ print_version();
+ s->status = 0; /* TODO FIX REPL */
+ } else
+ s->status = 0; /* TODO do FILE */
+
+ return 0;
+}
- /* TEMP */
- print_usage();
+int main(int argc, char *argv[])
+{
+ int status;
+ struct Smain s;
+ klisp_State *K = klispL_newstate();
+
+ if (K == NULL) {
+ k_message(argv[0], "cannot create state: not enough memory");
+ return EXIT_FAILURE;
+ }
+
+ /* This is weird but was done to follow lua scheme */
+ s.argc = argc;
+ s.argv = argv;
+ K->next_obj = p2tv(&s);
+ status = pmain(K);
+
+ klisp_close(K);
- return exit_code;
+ return (status || s.status)? EXIT_FAILURE : EXIT_SUCCESS;
}
diff --git a/src/klisp.h b/src/klisp.h
@@ -16,6 +16,12 @@
** SOURCE NOTE: This is mostly from Lua.
*/
+#define KLISP_VERSION "klisp 0.2"
+#define KLISP_RELEASE "klisp 0.2"
+#define KLISP_VERSION_NUM 02
+#define KLISP_COPYRIGHT "Copyright (C) 2011 Andres Navarro, Oto Havle"
+#define KLISP_AUTHORS "Andres Navarro, Oto Havle"
+
typedef struct klisp_State klisp_State;
/*