diff --git a/.ic3_history b/.ic3_history
deleted file mode 100644
index e107258..0000000
--- a/.ic3_history
+++ /dev/null
@@ -1,99 +0,0 @@
-Plop.a
-defmodule Plop do def a = 1; def double = fn (x) { x * 2 } end
-Plop.a
-Plop.double
-Plop.double(21)
-def a = 1
-a
-def double = fn (x) { x * 2 }
-double(42)
-defmodule Tiyon do
- def a = 1
- def double = fn (x) { x * 2 }
- def double_tuple = macro (x) do {x, x} end
- def double_list = macro (x) do [x, x] end
-end
-Tiyon.a
-Tiyon.double(21)
-Tiyon.double_tuple(21)
-Tiyon.double_tuple(21 + 21)
-Tiyon.double_list(21 + 21)
-[42, x] = Tiyon.double_list(21 + 21)
-[42, x] = [42, 42]
-x
-Tiyon.double_list(21 + 21) = [42, y]
-def last = fn (x) do
- [y | _] = List.reverse(x)
- y
-end
-def last = fn (x) do
- [y | _] = List.reverse(x)
- y
-end
-def List.last = fn (x) do
- [y | _] = List.reverse(x)
- y
-end
-List.last([1, 2, 3, 4])
-def List.last = fn (x) do
- [y | z] = List.reverse(x)
- y
-end
-List.last([1, 2, 3, 4])
-[x, y | z] = List.reverse([1, 2, 3])
-x
-y
-z
-[x, y | z] = List.reverse([1, 2, 3, 4])
-x
-y
-z
-if true then true end
-if 42 then true end
-if 0 then true end
-if 0 then true else false end
-List.map
-List.map([1, 2, 3], fn (x) { x * 2 })
-List.reverse
-List.reverse([1, 2, 3])
-List.reverse
-List.reverse([1, 2])
-def a = 1
-a
-module()
-defmodule Plop do
- def m = fn () { module() }
-end
-Plop.m()
-module()
-List.reverse([1, 2, 3])
-List.reverse([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
-(List) {1, 2}
-?
-cow 1
-(Tag) cow 1
-a = cow 1
-a
-a + 1
-cow 1
-type(cow 1)
-cow 1 + cow 1
-cow(1) + cow(1)
-quote [a: 1, b: 2]
-quote [{:a, 1}, {:b, 2}]
-%C3.Operator{}
-%GL.Vertex{}
-123.456
-abc.def
-%{a: 1}
-%{a: 1}.a
-x = %C3.Operator{}
-x.sym
-quote x.sym
-x = %C3.Operator{}
-x.sym
-x = %{
-x = %C3.Operator{sym: :-}
-x = %C3.Operator{sym: 1}
-x = %C3.Operator{sym: (Sym) "1"}
-x = %C3.Operator{sym: :1}
diff --git a/.ikc3_history b/.ikc3_history
new file mode 100644
index 0000000..4364d90
--- /dev/null
+++ b/.ikc3_history
@@ -0,0 +1,100 @@
+defmodule Plop do def a = 1; def double = fn (x) { x * 2 } end
+Plop.a
+Plop.double
+Plop.double(21)
+def a = 1
+a
+def double = fn (x) { x * 2 }
+double(42)
+defmodule Tiyon do
+ def a = 1
+ def double = fn (x) { x * 2 }
+ def double_tuple = macro (x) do {x, x} end
+ def double_list = macro (x) do [x, x] end
+end
+Tiyon.a
+Tiyon.double(21)
+Tiyon.double_tuple(21)
+Tiyon.double_tuple(21 + 21)
+Tiyon.double_list(21 + 21)
+[42, x] = Tiyon.double_list(21 + 21)
+[42, x] = [42, 42]
+x
+Tiyon.double_list(21 + 21) = [42, y]
+def last = fn (x) do
+ [y | _] = List.reverse(x)
+ y
+end
+def last = fn (x) do
+ [y | _] = List.reverse(x)
+ y
+end
+def List.last = fn (x) do
+ [y | _] = List.reverse(x)
+ y
+end
+List.last([1, 2, 3, 4])
+def List.last = fn (x) do
+ [y | z] = List.reverse(x)
+ y
+end
+List.last([1, 2, 3, 4])
+[x, y | z] = List.reverse([1, 2, 3])
+x
+y
+z
+[x, y | z] = List.reverse([1, 2, 3, 4])
+x
+y
+z
+if true then true end
+if 42 then true end
+if 0 then true end
+if 0 then true else false end
+List.map
+List.map([1, 2, 3], fn (x) { x * 2 })
+List.reverse
+List.reverse([1, 2, 3])
+List.reverse
+List.reverse([1, 2])
+def a = 1
+a
+module()
+defmodule Plop do
+ def m = fn () { module() }
+end
+Plop.m()
+module()
+List.reverse([1, 2, 3])
+List.reverse([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
+(List) {1, 2}
+?
+cow 1
+(Tag) cow 1
+a = cow 1
+a
+a + 1
+cow 1
+type(cow 1)
+cow 1 + cow 1
+cow(1) + cow(1)
+quote [a: 1, b: 2]
+quote [{:a, 1}, {:b, 2}]
+%C3.Operator{}
+%GL.Vertex{}
+123.456
+abc.def
+%{a: 1}
+%{a: 1}.a
+x = %C3.Operator{}
+x.sym
+quote x.sym
+x = %C3.Operator{}
+x.sym
+x = %{
+x = %C3.Operator{sym: :-}
+x = %C3.Operator{sym: 1}
+x = %C3.Operator{sym: (Sym) "1"}
+x = %C3.Operator{sym: :1}
+x = %KC3.Operator{sym: :1}
+
diff --git a/ikc3/.ic3_history b/ikc3/.ic3_history
deleted file mode 100644
index e107258..0000000
--- a/ikc3/.ic3_history
+++ /dev/null
@@ -1,99 +0,0 @@
-Plop.a
-defmodule Plop do def a = 1; def double = fn (x) { x * 2 } end
-Plop.a
-Plop.double
-Plop.double(21)
-def a = 1
-a
-def double = fn (x) { x * 2 }
-double(42)
-defmodule Tiyon do
- def a = 1
- def double = fn (x) { x * 2 }
- def double_tuple = macro (x) do {x, x} end
- def double_list = macro (x) do [x, x] end
-end
-Tiyon.a
-Tiyon.double(21)
-Tiyon.double_tuple(21)
-Tiyon.double_tuple(21 + 21)
-Tiyon.double_list(21 + 21)
-[42, x] = Tiyon.double_list(21 + 21)
-[42, x] = [42, 42]
-x
-Tiyon.double_list(21 + 21) = [42, y]
-def last = fn (x) do
- [y | _] = List.reverse(x)
- y
-end
-def last = fn (x) do
- [y | _] = List.reverse(x)
- y
-end
-def List.last = fn (x) do
- [y | _] = List.reverse(x)
- y
-end
-List.last([1, 2, 3, 4])
-def List.last = fn (x) do
- [y | z] = List.reverse(x)
- y
-end
-List.last([1, 2, 3, 4])
-[x, y | z] = List.reverse([1, 2, 3])
-x
-y
-z
-[x, y | z] = List.reverse([1, 2, 3, 4])
-x
-y
-z
-if true then true end
-if 42 then true end
-if 0 then true end
-if 0 then true else false end
-List.map
-List.map([1, 2, 3], fn (x) { x * 2 })
-List.reverse
-List.reverse([1, 2, 3])
-List.reverse
-List.reverse([1, 2])
-def a = 1
-a
-module()
-defmodule Plop do
- def m = fn () { module() }
-end
-Plop.m()
-module()
-List.reverse([1, 2, 3])
-List.reverse([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
-(List) {1, 2}
-?
-cow 1
-(Tag) cow 1
-a = cow 1
-a
-a + 1
-cow 1
-type(cow 1)
-cow 1 + cow 1
-cow(1) + cow(1)
-quote [a: 1, b: 2]
-quote [{:a, 1}, {:b, 2}]
-%C3.Operator{}
-%GL.Vertex{}
-123.456
-abc.def
-%{a: 1}
-%{a: 1}.a
-x = %C3.Operator{}
-x.sym
-quote x.sym
-x = %C3.Operator{}
-x.sym
-x = %{
-x = %C3.Operator{sym: :-}
-x = %C3.Operator{sym: 1}
-x = %C3.Operator{sym: (Sym) "1"}
-x = %C3.Operator{sym: :1}
diff --git a/ikc3/.ikc3_history b/ikc3/.ikc3_history
new file mode 100644
index 0000000..e107258
--- /dev/null
+++ b/ikc3/.ikc3_history
@@ -0,0 +1,99 @@
+Plop.a
+defmodule Plop do def a = 1; def double = fn (x) { x * 2 } end
+Plop.a
+Plop.double
+Plop.double(21)
+def a = 1
+a
+def double = fn (x) { x * 2 }
+double(42)
+defmodule Tiyon do
+ def a = 1
+ def double = fn (x) { x * 2 }
+ def double_tuple = macro (x) do {x, x} end
+ def double_list = macro (x) do [x, x] end
+end
+Tiyon.a
+Tiyon.double(21)
+Tiyon.double_tuple(21)
+Tiyon.double_tuple(21 + 21)
+Tiyon.double_list(21 + 21)
+[42, x] = Tiyon.double_list(21 + 21)
+[42, x] = [42, 42]
+x
+Tiyon.double_list(21 + 21) = [42, y]
+def last = fn (x) do
+ [y | _] = List.reverse(x)
+ y
+end
+def last = fn (x) do
+ [y | _] = List.reverse(x)
+ y
+end
+def List.last = fn (x) do
+ [y | _] = List.reverse(x)
+ y
+end
+List.last([1, 2, 3, 4])
+def List.last = fn (x) do
+ [y | z] = List.reverse(x)
+ y
+end
+List.last([1, 2, 3, 4])
+[x, y | z] = List.reverse([1, 2, 3])
+x
+y
+z
+[x, y | z] = List.reverse([1, 2, 3, 4])
+x
+y
+z
+if true then true end
+if 42 then true end
+if 0 then true end
+if 0 then true else false end
+List.map
+List.map([1, 2, 3], fn (x) { x * 2 })
+List.reverse
+List.reverse([1, 2, 3])
+List.reverse
+List.reverse([1, 2])
+def a = 1
+a
+module()
+defmodule Plop do
+ def m = fn () { module() }
+end
+Plop.m()
+module()
+List.reverse([1, 2, 3])
+List.reverse([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
+(List) {1, 2}
+?
+cow 1
+(Tag) cow 1
+a = cow 1
+a
+a + 1
+cow 1
+type(cow 1)
+cow 1 + cow 1
+cow(1) + cow(1)
+quote [a: 1, b: 2]
+quote [{:a, 1}, {:b, 2}]
+%C3.Operator{}
+%GL.Vertex{}
+123.456
+abc.def
+%{a: 1}
+%{a: 1}.a
+x = %C3.Operator{}
+x.sym
+quote x.sym
+x = %C3.Operator{}
+x.sym
+x = %{
+x = %C3.Operator{sym: :-}
+x = %C3.Operator{sym: 1}
+x = %C3.Operator{sym: (Sym) "1"}
+x = %C3.Operator{sym: :1}
diff --git a/ikc3/buf_linenoise.c b/ikc3/buf_linenoise.c
index 967d9f3..12f60ec 100644
--- a/ikc3/buf_linenoise.c
+++ b/ikc3/buf_linenoise.c
@@ -43,6 +43,7 @@ s_buf * buf_linenoise_open_r (s_buf *buf, const char *prompt,
{
s_buf_linenoise *buf_linenoise;
assert(buf);
+ buf->line = 0;
buf_linenoise = malloc(sizeof(s_buf_linenoise));
if (! buf_linenoise) {
err_puts("buf_linenoise_open_r: failed to allocate memory");
diff --git a/ikc3/buf_wineditline.c b/ikc3/buf_wineditline.c
index c7ab9a2..13eb06e 100644
--- a/ikc3/buf_wineditline.c
+++ b/ikc3/buf_wineditline.c
@@ -43,6 +43,7 @@ s_buf * buf_wineditline_open_r (s_buf *buf, const char *prompt,
{
s_buf_wineditline *buf_wineditline;
assert(buf);
+ buf->line = 0;
buf_wineditline = malloc(sizeof(s_buf_wineditline));
if (! buf_wineditline) {
err_puts("buf_wineditline_open_r: failed to allocate memory");
diff --git a/ikc3/ikc3.c b/ikc3/ikc3.c
index 29ec996..bd5b005 100644
--- a/ikc3/ikc3.c
+++ b/ikc3/ikc3.c
@@ -87,45 +87,72 @@ sw buf_xfer_spaces (s_buf *out, s_buf *in)
return size;
}
-int main (int argc, char **argv)
+sw ikc3_run (void)
{
- char i[BUF_SIZE];
- s_buf in;
s_tag input;
- char o[BUF_SIZE];
- s_buf out;
- s_str path;
sw r;
s_tag result;
+ while ((r = ikc3_buf_ignore_spaces(&g_kc3_env.out,
+ &g_kc3_env.in)) >= 0) {
+ if ((r = buf_parse_tag(&g_kc3_env.in, &input)) > 0) {
+ if (! eval_tag(&input, &result)) {
+ tag_clean(&input);
+ continue;
+ }
+ if (buf_inspect_tag(&g_kc3_env.out, &result) < 0) {
+ tag_clean(&input);
+ tag_clean(&result);
+ break;
+ }
+ tag_clean(&input);
+ tag_clean(&result);
+ }
+ if ((r = buf_write_1(&g_kc3_env.out, "\n")) < 0)
+ break;
+ if ((r = buf_flush(&g_kc3_env.out)) < 0)
+ break;
+ if (r < 0 ||
+ (r == 0 &&
+ (r = buf_ignore_character(&g_kc3_env.in)) <= 0))
+ break;
+ }
+ return 0;
+}
+
+int main (int argc, char **argv)
+{
+ FILE *fp = 0;
+ char in_data[BUF_SIZE];
+ s_buf in_original;
+ sw r;
if (argc < 1)
- return usage(argv[0]);
+ return usage("ikc3");
if (! kc3_init(NULL, &argc, &argv))
return 1;
- buf_init(&in, false, sizeof(i), i);
-#if HAVE_WINEDITLINE
- buf_wineditline_open_r(&in, "ikc3> ", ".ikc3_history");
-#else
- buf_linenoise_open_r(&in, "ikc3> ", ".ikc3_history");
-#endif
- in.line = 0;
- buf_init(&out, false, sizeof(o), o);
- buf_file_open_w(&out, stdout);
+ in_original = g_kc3_env.in;
+ buf_init(&g_kc3_env.in, false, sizeof(in_data), in_data);
while (argc) {
- if (! strncmp("--load", *argv, 6) ||
- ! strncmp("-l", *argv, 2)) {
+ if (! strcmp("--load", *argv) ||
+ ! strcmp("-l", *argv)) {
if (argc < 2) {
- err_write_1("ikc3: ");
+ err_write_1(g_kc3_env.argv[0]);
+ err_write_1(": ");
err_write_1(*argv);
err_write_1(" without an argument\n");
assert(! "env_init: -l or --load without an argument");
r = 1;
goto clean;
}
- str_init_1(&path, NULL, argv[1]);
- if (! env_load(&g_kc3_env, &path)) {
- r = 1;
+ fp = fopen(argv[1], "rb");
+ if (! buf_file_open_r(&g_kc3_env.in, fp)) {
+ r = -1;
goto clean;
}
+ r = ikc3_run();
+ buf_file_close(&g_kc3_env.in);
+ fclose(fp);
+ if (r)
+ goto clean;
argc -= 2;
argv += 2;
}
@@ -136,42 +163,25 @@ int main (int argc, char **argv)
else
break;
}
- while ((r = ikc3_buf_ignore_spaces(&out, &in)) >= 0) {
- if ((r = buf_parse_tag(&in, &input)) > 0) {
- if (! eval_tag(&input, &result)) {
- tag_clean(&input);
- continue;
- }
- if (buf_inspect_tag(&out, &result) < 0) {
- tag_clean(&input);
- tag_clean(&result);
- break;
- }
- tag_clean(&input);
- tag_clean(&result);
- buf_write_u8(&out, '\n');
- if ((r = buf_flush(&out)) < 0)
- break;
- }
- if (r < 0 ||
- (r == 0 &&
- (r = buf_ignore_character(&in)) <= 0))
- break;
- }
- r = 0;
+#if HAVE_WINEDITLINE
+ buf_wineditline_open_r(&g_kc3_env.in, "ikc3> ", ".ikc3_history");
+#else
+ buf_linenoise_open_r(&g_kc3_env.in, "ikc3> ", ".ikc3_history");
+#endif
+ r = ikc3_run();
clean:
#if HAVE_WINEDITLINE
- buf_wineditline_close(&in, ".ikc3_history");
+ buf_wineditline_close(&g_kc3_env.in, ".ikc3_history");
#else
- buf_linenoise_close(&in, ".ikc3_history");
+ buf_linenoise_close(&g_kc3_env.in, ".ikc3_history");
#endif
- buf_file_close(&out);
+ g_kc3_env.in = in_original;
kc3_clean(NULL);
return r;
}
int usage (char *argv0)
{
- printf("Usage: %s\n", argv0);
+ printf("Usage: %s [--load FILE] [--quit]\n", argv0);
return 1;
}
diff --git a/kc3s/kc3s.c b/kc3s/kc3s.c
index f366534..bac903d 100644
--- a/kc3s/kc3s.c
+++ b/kc3s/kc3s.c
@@ -58,40 +58,70 @@ sw buf_xfer_spaces (s_buf *out, s_buf *in)
return size;
}
-int main (int argc, char **argv)
+sw kc3s_run (void)
{
- char i[BUF_SIZE];
- s_buf in;
s_tag input;
- char o[BUF_SIZE];
- s_buf out;
- s_str path;
sw r;
s_tag result;
+ while ((r = buf_ignore_spaces(&g_kc3_env.in)) >= 0) {
+ if ((r = buf_parse_tag(&g_kc3_env.in, &input)) > 0) {
+ if (! eval_tag(&input, &result)) {
+ tag_clean(&input);
+ continue;
+ }
+ if (buf_inspect_tag(&g_kc3_env.out, &result) < 0) {
+ tag_clean(&input);
+ tag_clean(&result);
+ break;
+ }
+ tag_clean(&input);
+ tag_clean(&result);
+ buf_write_u8(&g_kc3_env.out, '\n');
+ if ((r = buf_flush(&g_kc3_env.out)) < 0)
+ break;
+ }
+ if (r < 0 ||
+ (r == 0 &&
+ (r = buf_ignore_character(&g_kc3_env.in)) <= 0))
+ break;
+ }
+ return 0;
+}
+
+int main (int argc, char **argv)
+{
+ FILE *fp;
+ char in_data[BUF_SIZE];
+ s_buf in_original;
+ sw r;
if (argc < 1)
return usage(argv[0]);
if (! kc3_init(NULL, &argc, &argv))
return 1;
- buf_init(&in, false, sizeof(i), i);
- buf_file_open_r(&in, stdin);
- buf_init(&out, false, sizeof(o), o);
- buf_file_open_w(&out, stdout);
+ in_original = g_kc3_env.in;
+ buf_init(&g_kc3_env.in, false, sizeof(in_data), in_data);
while (argc) {
- if (! strncmp("--load", *argv, 6) ||
- ! strncmp("-l", *argv, 2)) {
+ if (! strcmp("--load", *argv) ||
+ ! strcmp("-l", *argv)) {
if (argc < 2) {
- err_write_1("ikc3: ");
+ err_write_1(g_kc3_env.argv[0]);
+ err_write_1(": ");
err_write_1(*argv);
err_write_1(" without an argument\n");
assert(! "env_init: -l or --load without an argument");
r = 1;
goto clean;
}
- str_init_1(&path, NULL, argv[1]);
- if (! env_load(&g_kc3_env, &path)) {
- r = 1;
+ fp = fopen(argv[1], "rb");
+ if (! buf_file_open_r(&g_kc3_env.in, fp)) {
+ r = -1;
goto clean;
}
+ r = kc3s_run();
+ buf_file_close(&g_kc3_env.in);
+ fclose(fp);
+ if (r)
+ goto clean;
argc -= 2;
argv += 2;
}
@@ -102,32 +132,9 @@ int main (int argc, char **argv)
else
break;
}
- while ((r = buf_ignore_spaces(&in)) >= 0) {
- if ((r = buf_parse_tag(&in, &input)) > 0) {
- if (! eval_tag(&input, &result)) {
- tag_clean(&input);
- continue;
- }
- if (buf_inspect_tag(&out, &result) < 0) {
- tag_clean(&input);
- tag_clean(&result);
- break;
- }
- tag_clean(&input);
- tag_clean(&result);
- buf_write_u8(&out, '\n');
- if ((r = buf_flush(&out)) < 0)
- break;
- }
- if (r < 0 ||
- (r == 0 &&
- (r = buf_ignore_character(&in)) <= 0))
- break;
- }
- r = 0;
+ r = kc3s_run();
clean:
- buf_readline_close(&in);
- buf_file_close(&out);
+ g_kc3_env.in = in_original;
kc3_clean(NULL);
return r;
}
diff --git a/lib/kc3/0.1/ekc3.kc3 b/lib/kc3/0.1/ekc3.kc3
index 4d0feaa..fd4d79e 100644
--- a/lib/kc3/0.1/ekc3.kc3
+++ b/lib/kc3/0.1/ekc3.kc3
@@ -1,5 +1,7 @@
defmodule EKC3 do
- def render = cfn Str "ekc3_render" (Str, Tag)
+ dlopen(__DIR__ + "libekc3.so")
+
+ def render_file = cfn Str "ekc3_render_file" (Str)
end
diff --git a/libkc3/buf_file.c b/libkc3/buf_file.c
index e7cd9c5..12390fa 100644
--- a/libkc3/buf_file.c
+++ b/libkc3/buf_file.c
@@ -56,6 +56,7 @@ s_buf * buf_file_open_r (s_buf *buf, FILE *fp)
if (! buf_file)
return NULL;
buf_file->fp = fp;
+ buf->line = 0;
buf->refill = buf_file_open_r_refill;
buf->user_ptr = buf_file;
return buf;
diff --git a/libkc3/io.c b/libkc3/io.c
index 56ebd27..0e324ec 100644
--- a/libkc3/io.c
+++ b/libkc3/io.c
@@ -42,6 +42,11 @@
DEF_ERR_INSPECT(name, type) \
DEF_IO_INSPECT(name, type)
+sw err_flush (void)
+{
+ return buf_flush(&g_kc3_env.err);
+}
+
sw err_inspect (const s_tag *x)
{
return err_inspect_tag(x);
@@ -82,6 +87,11 @@ sw err_write_str (const s_str *x)
return r;
}
+sw io_flush (void)
+{
+ return buf_flush(&g_kc3_env.out);
+}
+
sw io_inspect (const s_tag *x)
{
sw r;
diff --git a/libkc3/io.h b/libkc3/io.h
index 8d6489d..62457f8 100644
--- a/libkc3/io.h
+++ b/libkc3/io.h
@@ -26,12 +26,14 @@
PROTOTYPE_IO_INSPECT(name, type)
/* error output */
+sw err_flush (void);
sw err_inspect (const s_tag *x);
sw err_puts (const char *x);
sw err_write_1 (const char *x);
sw err_write_str (const s_str *x);
/* standard output */
+sw io_flush (void);
sw io_inspect (const s_tag *x);
sw io_puts (const char *x);
sw io_write_1 (const char *x);
diff --git a/libkc3/kc3.c b/libkc3/kc3.c
index b711935..a2c718c 100644
--- a/libkc3/kc3.c
+++ b/libkc3/kc3.c
@@ -218,6 +218,8 @@ sw kc3_puts (const s_tag *tag)
if ((r = io_write_1("\n")) < 0)
return r;
result += r;
+ if ((r = io_flush()) < 0)
+ return r;
return result;
}
diff --git a/test/ekc3/title.kc3 b/test/ekc3/title.kc3
index b95124b..6547184 100644
--- a/test/ekc3/title.kc3
+++ b/test/ekc3/title.kc3
@@ -1,2 +1,2 @@
-puts(EKC3.render(__DIR__ + "/title.html.ekc3",
- %{title: "EKC3 test title"}))
+title = "EKC3 test title"
+puts(EKC3.render_file(__DIR__ + "/title.html.ekc3"))