summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann Pedersen <ssp@redhat.com>2012-06-14 19:13:08 -0400
committerSøren Sandmann Pedersen <ssp@redhat.com>2012-06-14 19:13:08 -0400
commit0e3b4a4c09cbf63cd6399f58e849c8a5f07fdcc0 (patch)
tree313784f93a727aa8a553b9c8edee53928081ff53
parentf6fbd9f90f311cf8ba4ef7a9bfec218ae27c7e87 (diff)
Some refactoring
-rw-r--r--Makefile1
-rw-r--r--ast.h11
-rw-r--r--internal-tests.c334
-rw-r--r--main.c363
4 files changed, 365 insertions, 344 deletions
diff --git a/Makefile b/Makefile
index d0d2309..e06fc6a 100644
--- a/Makefile
+++ b/Makefile
@@ -21,6 +21,7 @@ OBJS= \
return-check.o \
util.o \
gc.o \
+ internal-tests.o \
interpret.o
BINARY=nn
diff --git a/ast.h b/ast.h
index 9b8a6b8..0cd08ff 100644
--- a/ast.h
+++ b/ast.h
@@ -1469,8 +1469,15 @@ gboolean return_check (ast_t *ast);
gboolean offsets (ast_t *ast);
void interpret (ast_t *ast);
+/* Driver */
+ast_t * compile (const char *input,
+ gboolean do_optimize);
+
/* Debug spew */
void dump_program (ast_program_t *program);
void dump_type_spec (ast_type_spec_t *type_spec);
-void dump_tokens (token_t *tokens);
-void dump_graph (ast_program_t *program);
+void dump_tokens (token_t *tokens);
+void dump_graph (ast_program_t *program);
+
+/* Internal testing */
+void run_internal_tests (void);
diff --git a/internal-tests.c b/internal-tests.c
new file mode 100644
index 0000000..e91de00
--- /dev/null
+++ b/internal-tests.c
@@ -0,0 +1,334 @@
+/* Ninja
+ * Copyright 2007, Soren Sandmann Pedersen
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <stdio.h>
+#include <glib.h>
+#include "ast.h"
+
+static void
+interp (const char *data)
+{
+ ast_t *ast;
+
+ if ((ast = compile (data, TRUE)))
+ interpret (ast);
+}
+
+static void
+dump (const char *data)
+{
+ ast_t *ast;
+
+ if ((ast = compile (data, TRUE)))
+ dump_program (&ast->program);
+}
+
+void
+run_internal_tests (void)
+{
+ token_t *tokens;
+
+ tokens = scan ("\"fro\\\\\"ot\"\"if//8\nwhile 8\nprint /* bir///*nan */100\n + //1\n00\n888.; fish();");
+ dump_tokens (tokens);
+
+ interp (
+ "gcd (m, n: int32, b, t: bool) -> int32 "
+ "{ "
+ " while (m != 0) "
+ " { "
+ " t: int32; "
+ " "
+ " t = m; "
+ " m = n % m; "
+ " n = t; "
+ " } "
+ " "
+ " return n; "
+ "} "
+ "print gcd (13 * 19 * 77 * 12, 77 * 3 * 13, true, false);");
+
+ dump ("{ x: double; { 10 + x; } }");
+ dump ("{ x, y: double; { 10 + y; } y + x; } 10 + x; x: int32;");
+ dump ("a, b, c, d, e, f: int32; a ? b : c ? d : e;");
+ dump ("print 100 + -100;");
+ dump ("while (100 > 10) { print 100 > 3 ; } print 100 > 3;");
+ dump ("print 100 * 100 + -100;");
+ dump ("print 100 * 100 + 100 * 12000;");
+ dump ("print 100 * 100 + - + + - 100 * 12000;");
+ dump ("print 100 + 10 * 100 + 100;");
+ dump ("print (100 + 10 > !10) * !100 % !-!100;");
+ dump ("print 100 + 100? 800 : 200;");
+ dump ("print -(100 + 100)? 3 = 100 + 100? 23423 + 100 : 100 + 10 : 100;");
+ dump ("print (100) + 100 + fish * fish * fish; 234 = 234; 1234 * !100 + 324;");
+ dump ("100 ? 10 = 10 ? 50 = 50 : 20 = 20 : 30 = 30;");
+ dump ("x, y: int32; 100 ? 10 + 10 > true + x : y;");
+ dump ("{ x, y: int32; 10 + y; } 10 + x;");
+ dump ("{ x, y: int32; 10 + y; } 10 + x;");
+ dump ("{ x, y: int32; { 10 + y; } y + x; } 10 + x; x: int32;");
+
+ dump ("x: int32; x = 50; true;");
+ dump ("x: int32; x = true; true;");
+
+ dump ("x: int32; while (x < 100) { print x; x = x + 1; }");
+ dump ("x: int32; while (++x < 100) { print x; x = x + 1; }");
+ dump ("x: int32; while (++x < --100) { print x; x = x + 1; }");
+ dump ("x: int32; while (++x < 100) { print x; x = x + 1; }");
+ dump ("x: bool; while (x) { x = true; }");
+
+ dump (
+ "m, n: int32; if (m > n) { print m; } else { print n; }");
+
+ dump ("m, n: int32; if (n >= m) if (n > m) print n; else print m ; else print n;");
+
+ dump ("m, n: int32; if (n > m) print n;");
+
+ dump ("print (100 + 100 * 100) / 100 ;\n");
+
+ dump ("print ((100 << 2 + 1) -100 * 100) / 100 ;\n");
+ dump ("print 100 == 100;");
+ dump ("print 100 != 100;");
+ dump ("print 100 == 99;");
+ dump ("print 100 != 99;");
+
+ dump ("print 100 % 7;");
+
+ dump ("x, y, z: int32; { x, y: int32; { z: int32; } } { x, y, z: int32; }");
+
+ dump ("x: int32; { y: int32; } { q, w: int32; }");
+ dump ("x: int32; if (x > 0) { y: int32; } else { q, w: int32; }");
+ dump ("x: int32; if (x > 0) { y, a, b: int32; } else { q, w: int32; }");
+
+ interp (
+ "m, n: int32; "
+ " "
+ "m = 21; "
+ "n = 35; "
+ " "
+ "while (m != 0) "
+ "{ "
+ " t: int32; "
+ " "
+ " t = m; "
+ " m = n % m; "
+ " n = t; "
+ "} "
+ " "
+ "print n; ");
+
+ interp (
+ "m, n: int32; "
+ " "
+ "m = 21; "
+ "n = 35; "
+ " "
+ "while (m != 0) "
+ "{ "
+ " t: int32; "
+ " "
+ " t = m; "
+ " m = n % m; "
+ " n = t; "
+ "} "
+ " "
+ "print n; ");
+
+ interp (
+ "i, j: int32; "
+ " "
+ "i = 5; "
+ "while (i > 0) "
+ "{ "
+ " print i--; "
+ "} ");
+
+ interp ("i: int32; i = 100;");
+
+ interp (
+ "i, j: int32; "
+ "j = 32;"
+ "if (i > 100) "
+ " print i; "
+ "else "
+ " print j; "
+ "");
+
+ interp (
+ "j: int32; "
+ "j = 32;"
+ "if (true) "
+ " print j; "
+ "");
+
+ interp (
+ "i, j: int32; i = 100; j = 100; { i, j: int32; i = j; }");
+
+ interp (
+ "i, j: int32; "
+ "for (i = 0; i < 5; ++i)"
+ "{ "
+ " j = 0; "
+ " while (j < 2) "
+ " {"
+ " print i + j; "
+ " ++j;"
+ " }"
+ "}");
+
+ interp (
+ "i, j: int32; "
+ "for (i = 0; i < 3; )"
+ "{ "
+ " j = 0; "
+ " while (j < 2) "
+ " {"
+ " print i + j; "
+ " ++j;"
+ " ++i;"
+ " }"
+ "}");
+
+ interp (
+ "a, b, c: int32; a = b = c = 0; a *= 100;");
+
+ interp (
+ "a, b, c: int32; a = b = c = 0; a -= 100;");
+
+ interp (
+ "a, b, c: int32; a = b = c = 0; a += 100;");
+
+ interp (
+ "a, b, c: int32; a = b = c = 0; a %= 100;");
+
+ interp (
+ "gcd (m, n: int32, b, t: bool) "
+ "{ "
+ " while (m != 0) "
+ " { "
+ " t: int32; "
+ " "
+ " t = m; "
+ " m = n % m; "
+ " n = t; "
+ " } "
+ " "
+ " print n; "
+ " return n + 100; "
+ "} "
+ "print gcd (13 * 19 * 77 * 12, 77 * 3 * 13, true, false);");
+
+ interp (
+ "gcd (m, n: int32, b, t: bool) -> int32 "
+ "{ "
+ " while (m != 0) "
+ " { "
+ " t: int32; "
+ " "
+ " t = m; "
+ " m = n % m; "
+ " n = t; "
+ " } "
+ " "
+ " return n; "
+ "} "
+ "print gcd (13 * 19 * 77 * 12, 77 * 3 * 13, true, false);");
+
+ interp (
+ "recurse (m: int32) -> int32 "
+ "{ "
+ " if (m == 1) "
+ " return m; "
+ " else "
+ " return 1 + recurse (m - 1); "
+ "} "
+ " "
+ "print recurse (5000); ");
+
+ interp (
+ "gcd (m : int32, n : int32, ) { "
+ "(m = 21); (n = 35); { "
+ "while ((m != 0)) { { t : int32; (t = m); "
+ "(m = (n % m)); (n = t); } } } print n; } print n; ");
+
+ interp (
+ "fun1 (m: int32) -> int32 "
+ "{ "
+ " if (m % 100 == 0 || m % 100 == 1) "
+ " print 1; "
+ " "
+ " if (m == 1) "
+ " return m; "
+ " else "
+ " return 1 + fun2 (m - 1); "
+ "} "
+ " "
+ "fun2 (m: int32) -> int32 "
+ "{ "
+ " if (m % 100 == 0 || m % 100 == 1) "
+ " print 2; "
+ " "
+ " if (m == 1) "
+ " return m; "
+ " else "
+ " return 1 + fun1 (m - 1); "
+ "} "
+ " "
+ "print fun1 (500); ");
+
+ interp (
+ "bar () "
+ "{ "
+ " m: int32; "
+ " m = 100; "
+ " "
+ " while (--m != 0) "
+ " if (m == 20) "
+ " { "
+ " print m; "
+ " return; "
+ " } "
+ " print 100000; /* we should never see this */ "
+ "} "
+ " "
+ "bar(); ");
+
+ interp (
+ "foo, blah: int32; "
+ " "
+ "bar () "
+ "{ "
+ " m: int32; "
+ " m = 100; "
+ " foo = 10; "
+ " blah = 10; "
+ " "
+ " while (--m != 0) "
+ " if (m == 20) "
+ " { "
+ " print m; "
+ " return; "
+ " } "
+ " print 100000; /* If we see this, blah may "
+ " incorrectly alias m */ "
+ "} "
+ " "
+ "bar(); ");
+
+ interp (
+ "100 == 100 & 10 > 10;");
+}
+
diff --git a/main.c b/main.c
index 1e91b6f..449557f 100644
--- a/main.c
+++ b/main.c
@@ -20,372 +20,49 @@
#include <glib.h>
#include "ast.h"
-static void
-real_dump (const char *input, gboolean interp)
+ast_t *
+compile (const char *input, gboolean do_optimize)
{
token_t *tokens;
ast_t *ast;
- tokens = scan (input);
- if (!tokens)
- return;
-
- g_print ("----------- begin compiling ----------\n");
+ if (!(tokens = scan (input)))
+ return NULL;
if (!(ast = parse (tokens)))
- return;
-
- dump_program (&ast->program);
- g_print ("\n");
+ return NULL;
if (!prepare (ast))
- return;
+ return NULL;
if (!symbol (ast))
- return;
+ return NULL;
if (!type_check (ast))
- return;
+ return NULL;
if (!mark_constants (ast))
- return;
+ return NULL;
if (!switch_check (ast))
- return;
+ return NULL;
if (!graph (ast))
- return;
-
- dump_graph (&ast->program);
+ return NULL;
if (!init_check (ast))
- return;
+ return NULL;
if (!return_check (ast))
- return;
-
-#if 0
- if (!optimize (ast))
- return;
-#endif
+ return NULL;
- dump_graph (&ast->program);
+ if (do_optimize && !optimize (ast))
+ return NULL;
if (!offsets (ast))
- return;
-
- if (interp)
- {
- g_print ("-=-=-=- result of interpreting -=-=-=-\n");
-
- interpret (ast);
- }
-}
-
-static void
-dump (const char *input)
-{
- return real_dump (input, FALSE);
-}
-
-static void
-interp (const char *input)
-{
- return real_dump (input, TRUE);
-}
-
-static void
-run_tests (void)
-{
- token_t *tokens;
-
- tokens = scan ("\"fro\\\\\"ot\"\"if//8\nwhile 8\nprint /* bir///*nan */100\n + //1\n00\n888.; fish();");
- dump_tokens (tokens);
-
- interp (
- "gcd (m, n: int32, b, t: bool) -> int32 "
- "{ "
- " while (m != 0) "
- " { "
- " t: int32; "
- " "
- " t = m; "
- " m = n % m; "
- " n = t; "
- " } "
- " "
- " return n; "
- "} "
- "print gcd (13 * 19 * 77 * 12, 77 * 3 * 13, true, false);");
-
- dump ("{ x: double; { 10 + x; } }");
- dump ("{ x, y: double; { 10 + y; } y + x; } 10 + x; x: int32;");
- dump ("a, b, c, d, e, f: int32; a ? b : c ? d : e;");
- dump ("print 100 + -100;");
- dump ("while (100 > 10) { print 100 > 3 ; } print 100 > 3;");
- dump ("print 100 * 100 + -100;");
- dump ("print 100 * 100 + 100 * 12000;");
- dump ("print 100 * 100 + - + + - 100 * 12000;");
- dump ("print 100 + 10 * 100 + 100;");
- dump ("print (100 + 10 > !10) * !100 % !-!100;");
- dump ("print 100 + 100? 800 : 200;");
- dump ("print -(100 + 100)? 3 = 100 + 100? 23423 + 100 : 100 + 10 : 100;");
- dump ("print (100) + 100 + fish * fish * fish; 234 = 234; 1234 * !100 + 324;");
- dump ("100 ? 10 = 10 ? 50 = 50 : 20 = 20 : 30 = 30;");
- dump ("x, y: int32; 100 ? 10 + 10 > true + x : y;");
- dump ("{ x, y: int32; 10 + y; } 10 + x;");
- dump ("{ x, y: int32; 10 + y; } 10 + x;");
- dump ("{ x, y: int32; { 10 + y; } y + x; } 10 + x; x: int32;");
-
- dump ("x: int32; x = 50; true;");
- dump ("x: int32; x = true; true;");
-
- dump ("x: int32; while (x < 100) { print x; x = x + 1; }");
- dump ("x: int32; while (++x < 100) { print x; x = x + 1; }");
- dump ("x: int32; while (++x < --100) { print x; x = x + 1; }");
- dump ("x: int32; while (++x < 100) { print x; x = x + 1; }");
- dump ("x: bool; while (x) { x = true; }");
-
- dump (
- "m, n: int32; if (m > n) { print m; } else { print n; }");
-
- dump ("m, n: int32; if (n >= m) if (n > m) print n; else print m ; else print n;");
-
- dump ("m, n: int32; if (n > m) print n;");
-
- dump ("print (100 + 100 * 100) / 100 ;\n");
-
- dump ("print ((100 << 2 + 1) -100 * 100) / 100 ;\n");
- dump ("print 100 == 100;");
- dump ("print 100 != 100;");
- dump ("print 100 == 99;");
- dump ("print 100 != 99;");
-
- dump ("print 100 % 7;");
-
- dump ("x, y, z: int32; { x, y: int32; { z: int32; } } { x, y, z: int32; }");
-
- dump ("x: int32; { y: int32; } { q, w: int32; }");
- dump ("x: int32; if (x > 0) { y: int32; } else { q, w: int32; }");
- dump ("x: int32; if (x > 0) { y, a, b: int32; } else { q, w: int32; }");
-
- interp (
- "m, n: int32; "
- " "
- "m = 21; "
- "n = 35; "
- " "
- "while (m != 0) "
- "{ "
- " t: int32; "
- " "
- " t = m; "
- " m = n % m; "
- " n = t; "
- "} "
- " "
- "print n; ");
-
- interp (
- "m, n: int32; "
- " "
- "m = 21; "
- "n = 35; "
- " "
- "while (m != 0) "
- "{ "
- " t: int32; "
- " "
- " t = m; "
- " m = n % m; "
- " n = t; "
- "} "
- " "
- "print n; ");
-
- interp (
- "i, j: int32; "
- " "
- "i = 5; "
- "while (i > 0) "
- "{ "
- " print i--; "
- "} ");
-
- interp ("i: int32; i = 100;");
-
- interp (
- "i, j: int32; "
- "j = 32;"
- "if (i > 100) "
- " print i; "
- "else "
- " print j; "
- "");
-
- interp (
- "j: int32; "
- "j = 32;"
- "if (true) "
- " print j; "
- "");
-
- interp (
- "i, j: int32; i = 100; j = 100; { i, j: int32; i = j; }");
-
- interp (
- "i, j: int32; "
- "for (i = 0; i < 5; ++i)"
- "{ "
- " j = 0; "
- " while (j < 2) "
- " {"
- " print i + j; "
- " ++j;"
- " }"
- "}");
-
- interp (
- "i, j: int32; "
- "for (i = 0; i < 3; )"
- "{ "
- " j = 0; "
- " while (j < 2) "
- " {"
- " print i + j; "
- " ++j;"
- " ++i;"
- " }"
- "}");
-
- interp (
- "a, b, c: int32; a = b = c = 0; a *= 100;");
-
- interp (
- "a, b, c: int32; a = b = c = 0; a -= 100;");
-
- interp (
- "a, b, c: int32; a = b = c = 0; a += 100;");
-
- interp (
- "a, b, c: int32; a = b = c = 0; a %= 100;");
-
- interp (
- "gcd (m, n: int32, b, t: bool) "
- "{ "
- " while (m != 0) "
- " { "
- " t: int32; "
- " "
- " t = m; "
- " m = n % m; "
- " n = t; "
- " } "
- " "
- " print n; "
- " return n + 100; "
- "} "
- "print gcd (13 * 19 * 77 * 12, 77 * 3 * 13, true, false);");
-
- interp (
- "gcd (m, n: int32, b, t: bool) -> int32 "
- "{ "
- " while (m != 0) "
- " { "
- " t: int32; "
- " "
- " t = m; "
- " m = n % m; "
- " n = t; "
- " } "
- " "
- " return n; "
- "} "
- "print gcd (13 * 19 * 77 * 12, 77 * 3 * 13, true, false);");
-
- interp (
- "recurse (m: int32) -> int32 "
- "{ "
- " if (m == 1) "
- " return m; "
- " else "
- " return 1 + recurse (m - 1); "
- "} "
- " "
- "print recurse (5000); ");
-
- interp (
- "gcd (m : int32, n : int32, ) { "
- "(m = 21); (n = 35); { "
- "while ((m != 0)) { { t : int32; (t = m); "
- "(m = (n % m)); (n = t); } } } print n; } print n; ");
-
- interp (
- "fun1 (m: int32) -> int32 "
- "{ "
- " if (m % 100 == 0 || m % 100 == 1) "
- " print 1; "
- " "
- " if (m == 1) "
- " return m; "
- " else "
- " return 1 + fun2 (m - 1); "
- "} "
- " "
- "fun2 (m: int32) -> int32 "
- "{ "
- " if (m % 100 == 0 || m % 100 == 1) "
- " print 2; "
- " "
- " if (m == 1) "
- " return m; "
- " else "
- " return 1 + fun1 (m - 1); "
- "} "
- " "
- "print fun1 (500); ");
-
- interp (
- "bar () "
- "{ "
- " m: int32; "
- " m = 100; "
- " "
- " while (--m != 0) "
- " if (m == 20) "
- " { "
- " print m; "
- " return; "
- " } "
- " print 100000; /* we should never see this */ "
- "} "
- " "
- "bar(); ");
-
- interp (
- "foo, blah: int32; "
- " "
- "bar () "
- "{ "
- " m: int32; "
- " m = 100; "
- " foo = 10; "
- " blah = 10; "
- " "
- " while (--m != 0) "
- " if (m == 20) "
- " { "
- " print m; "
- " return; "
- " } "
- " print 100000; /* If we see this, blah may "
- " incorrectly alias m */ "
- "} "
- " "
- "bar(); ");
+ return NULL;
- interp (
- "100 == 100 & 10 > 10;");
+ return ast;
}
int
@@ -393,12 +70,13 @@ main (int argc, char **argv)
{
if (argc == 1)
{
- run_tests ();
+ run_internal_tests ();
}
else if (argc == 2)
{
gsize size;
gchar *content;
+ ast_t *ast;
if (!g_file_get_contents (argv[1], &content, &size, NULL))
{
@@ -406,7 +84,8 @@ main (int argc, char **argv)
return -1;
}
- interp (content);
+ if ((ast = compile (content, FALSE)))
+ interpret (ast);
}
else
{