Commit ca0a0ffa0e4d6833fbf285a019d119573d5aa24f

Thomas de Grivel 2024-07-16T15:35:29

env: move --load to ikc3.c and kc3s.c, wrote kc3_puts

diff --git a/.gitignore b/.gitignore
index 3f2b273..2e64bed 100644
--- a/.gitignore
+++ b/.gitignore
@@ -79,6 +79,10 @@ libkc3_window/sdl2/demo/macos/kc3_window_sdl2_demo_debug.app/
 *.lo
 macos/kc3-v*
 *.o
+test/ekc3/*.diff
+test/ekc3/*.err
+test/ekc3/*.out
+test/ekc3/*.ret
 test/facts_test_dump_file.facts
 test/facts_test_log_add.facts
 test/facts_test_log_remove.facts
diff --git a/Makefile b/Makefile
index 3cb2358..962d3a2 100644
--- a/Makefile
+++ b/Makefile
@@ -219,10 +219,23 @@ test_debug:
 	${MAKE} -C ikc3 debug
 	${MAKE} -C test test_debug
 
+test_ekc3: build
+	${MAKE} -C test test_ekc3
+
+test_ekc3_asan: asan
+	${MAKE} -C test test_ekc3_asan
+
+test_ekc3_cov: cov
+	${MAKE} -C test test_ekc3_cov
+
+test_ekc3_debug: debug
+	${MAKE} -C test test_ekc3_debug
+
 test_gcovr:
 	${MAKE} clean_cov
 	${MAKE} test_libkc3_cov
 	${MAKE} test_ikc3_cov
+	${MAKE} test_ekc3_cov
 	${MAKE} gcovr
 
 test_ikc3: build
diff --git a/ikc3/ikc3.c b/ikc3/ikc3.c
index f882a81..29ec996 100644
--- a/ikc3/ikc3.c
+++ b/ikc3/ikc3.c
@@ -94,16 +94,13 @@ int main (int argc, char **argv)
   s_tag input;
   char o[BUF_SIZE];
   s_buf out;
+  s_str path;
   sw r;
   s_tag result;
   if (argc < 1)
     return usage(argv[0]);
   if (! kc3_init(NULL, &argc, &argv))
     return 1;
-  if (argv && ! strcmp("--quit", argv[0])) {
-    kc3_clean(NULL);
-    return 0;
-  }
   buf_init(&in, false, sizeof(i), i);
 #if HAVE_WINEDITLINE
   buf_wineditline_open_r(&in, "ikc3> ", ".ikc3_history");
@@ -113,6 +110,32 @@ int main (int argc, char **argv)
   in.line = 0;
   buf_init(&out, false, sizeof(o), o);
   buf_file_open_w(&out, stdout);
+  while (argc) {
+    if (! strncmp("--load", *argv, 6) ||
+        ! strncmp("-l", *argv, 2)) {
+      if (argc < 2) {
+        err_write_1("ikc3: ");
+        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;
+        goto clean;
+      }
+      argc -= 2;
+      argv += 2;
+    }
+    else if (argc == 1 && ! strcmp("--quit", *argv)) {
+      r = 0;
+      goto clean;
+    }
+    else
+      break;
+  }
   while ((r = ikc3_buf_ignore_spaces(&out, &in)) >= 0) {
     if ((r = buf_parse_tag(&in, &input)) > 0) {
       if (! eval_tag(&input, &result)) {
@@ -135,6 +158,8 @@ int main (int argc, char **argv)
          (r = buf_ignore_character(&in)) <= 0))
       break;
   }
+  r = 0;
+ clean:
 #if HAVE_WINEDITLINE
   buf_wineditline_close(&in, ".ikc3_history");
 #else
@@ -142,7 +167,7 @@ int main (int argc, char **argv)
 #endif
   buf_file_close(&out);
   kc3_clean(NULL);
-  return 0;
+  return r;
 }
 
 int usage (char *argv0)
diff --git a/kc3s/kc3s.c b/kc3s/kc3s.c
index 32ad311..f366534 100644
--- a/kc3s/kc3s.c
+++ b/kc3s/kc3s.c
@@ -65,20 +65,43 @@ int main (int argc, char **argv)
   s_tag input;
   char o[BUF_SIZE];
   s_buf out;
+  s_str path;
   sw r;
   s_tag result;
   if (argc < 1)
     return usage(argv[0]);
   if (! kc3_init(NULL, &argc, &argv))
     return 1;
-  if (argv && ! strcmp("--quit", argv[0])) {
-    kc3_clean(NULL);
-    return 0;
-  }
   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);
+  while (argc) {
+    if (! strncmp("--load", *argv, 6) ||
+        ! strncmp("-l", *argv, 2)) {
+      if (argc < 2) {
+        err_write_1("ikc3: ");
+        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;
+        goto clean;
+      }
+      argc -= 2;
+      argv += 2;
+    }
+    else if (argc == 1 && ! strcmp("--quit", *argv)) {
+      r = 0;
+      goto clean;
+    }
+    else
+      break;
+  }
   while ((r = buf_ignore_spaces(&in)) >= 0) {
     if ((r = buf_parse_tag(&in, &input)) > 0) {
       if (! eval_tag(&input, &result)) {
@@ -101,10 +124,12 @@ int main (int argc, char **argv)
          (r = buf_ignore_character(&in)) <= 0))
       break;
   }
+  r = 0;
+ clean:
   buf_readline_close(&in);
   buf_file_close(&out);
   kc3_clean(NULL);
-  return 0;
+  return r;
 }
 
 int usage (char *argv0)
diff --git a/lib/kc3/0.1/kc3.facts b/lib/kc3/0.1/kc3.facts
index a80ab8e..fa30580 100644
--- a/lib/kc3/0.1/kc3.facts
+++ b/lib/kc3/0.1/kc3.facts
@@ -250,6 +250,6 @@ replace {KC3.let, :arity, 2}
 replace {KC3.let, :is_a, :special_operator}
 replace {KC3.let, :symbol_value, cfn Tag "kc3_let" (Tag, Block, Result)}
 add {KC3, :symbol, KC3.puts}
-replace {KC3.puts, :symbol_value, cfn Sw "io_inspect_tag" (Tag)}
+replace {KC3.puts, :symbol_value, cfn Sw "kc3_puts" (Tag)}
 add {KC3, :symbol, KC3.load}
 replace {KC3.load, :symbol_value, cfn Bool "kc3_load" (Str)}
diff --git a/libkc3/env.c b/libkc3/env.c
index c1fdcf5..6896e84 100644
--- a/libkc3/env.c
+++ b/libkc3/env.c
@@ -1979,30 +1979,6 @@ s_env * env_init (s_env *env, int *argc, char ***argv)
     env_clean(env);
     return NULL;
   }
-  if (argc) {
-    while (*argc) {
-      if (! strcmp("--load", **argv) ||
-          ! strcmp("-l", **argv)) {
-        if (*argc < 2) {
-          err_write_1("env_init: ");
-          err_write_1(**argv);
-          err_write_1(" without an argument\n");
-          assert(! "env_init: -l or --load without an argument");
-          env_clean(env);
-          return NULL;
-        }
-        str_init_1(&path, NULL, (*argv)[1]);
-        if (! env_load(env, &path)) {
-          env_clean(env);
-          return NULL;
-        }
-        *argc -= 2;
-        *argv += 2;
-      }
-      else
-        break;
-    }
-  }
   return env;
 }
 
diff --git a/libkc3/io.c b/libkc3/io.c
index cf98b1a..56ebd27 100644
--- a/libkc3/io.c
+++ b/libkc3/io.c
@@ -74,6 +74,14 @@ sw err_write_1 (const char *x)
   return r;
 }
 
+sw err_write_str (const s_str *x)
+{
+  sw r;
+  if ((r = buf_write_str(&g_kc3_env.err, x)) > 0)
+    buf_flush(&g_kc3_env.err);
+  return r;
+}
+
 sw io_inspect (const s_tag *x)
 {
   sw r;
@@ -115,6 +123,14 @@ sw io_write_1 (const char *x)
   return r;
 }
 
+sw io_write_str (const s_str *x)
+{
+  sw r;
+  if ((r = buf_write_str(&g_kc3_env.out, x)) > 0)
+    buf_flush(&g_kc3_env.out);
+  return r;
+}
+
 DEF_ERR_IO_INSPECT(array,      const s_array *)
 DEF_ERR_IO_INSPECT(call,       const s_call *)
 DEF_ERR_IO_INSPECT(character,  const character *)
diff --git a/libkc3/io.h b/libkc3/io.h
index 53c0a1d..8d6489d 100644
--- a/libkc3/io.h
+++ b/libkc3/io.h
@@ -29,11 +29,13 @@
 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_inspect (const s_tag *x);
 sw io_puts (const char *x);
 sw io_write_1 (const char *x);
+sw io_write_str (const s_str *x);
 
 PROTOTYPES_ERR_IO_INSPECT(array,      const s_array *);
 PROTOTYPES_ERR_IO_INSPECT(bool,       const bool *);
diff --git a/libkc3/kc3.c b/libkc3/kc3.c
index 8bad2a5..b711935 100644
--- a/libkc3/kc3.c
+++ b/libkc3/kc3.c
@@ -202,6 +202,25 @@ s_tag * kc3_pin (const s_tag *a, s_tag *dest)
   return dest;
 }
 
+sw kc3_puts (const s_tag *tag)
+{
+  sw r;
+  sw result = 0;
+  if (tag->type == TAG_STR) {
+    if ((r = io_write_str(&tag->data.str)) < 0)
+      return r;
+  }
+  else {
+    if ((r = io_inspect_tag(tag)) < 0)
+      return r;
+  }
+  result += r;
+  if ((r = io_write_1("\n")) < 0)
+    return r;
+  result += r;
+  return result;
+}
+
 s_list ** kc3_search_modules (s_list **dest)
 {
   return env_search_modules(&g_kc3_env, dest);
diff --git a/libkc3/kc3_main.h b/libkc3/kc3_main.h
index 042c1b2..f48d1f0 100644
--- a/libkc3/kc3_main.h
+++ b/libkc3/kc3_main.h
@@ -34,6 +34,7 @@ uw *           kc3_facts_next_id (uw *dest);
 s_str *        kc3_getenv (const s_str *name, s_str *dest);
 void           kc3_license (void);
 const s_sym ** kc3_module (const s_sym **dest);
+sw             kc3_puts (const s_tag *tag);
 
 /* Operators. */
 s_tag * kc3_access (const s_tag *tag, const s_sym * const *sym,
diff --git a/test/Makefile b/test/Makefile
index 36dee53..f8bb43a 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -76,18 +76,34 @@ lldb_test: debug
 test: libkc3_test
 	time ./libkc3_test
 	IKC3=${SRC_TOP}/ikc3/ikc3 time ./ikc3_test
+	KC3S=${SRC_TOP}/kc3s/kc3s time ./ekc3_test
 
 test_asan: libkc3_test_asan
 	time ./libkc3_test_asan
 	IKC3=${SRC_TOP}/ikc3/ikc3_asan time ./ikc3_test
+	KC3S=${SRC_TOP}/kc3s/kc3s_asan time ./ekc3_test
 
 test_cov:
 	time ./libkc3_test_cov
 	IKC3=${SRC_TOP}/ikc3/ikc3_cov time ./ikc3_test
+	KC3S=${SRC_TOP}/kc3s/kc3s_cov time ./ekc3_test
 
 test_debug: libkc3_test_debug
 	time ./libkc3_test_debug
 	IKC3=${SRC_TOP}/ikc3/ikc3_debug time ./ikc3_test
+	KC3S=${SRC_TOP}/kc3s/kc3s_debug time ./ekc3_test
+
+test_ekc3:
+	KC3S=${SRC_TOP}/kc3s/kc3s time ./ekc3_test
+
+test_ekc3_asan:
+	KC3S=${SRC_TOP}/kc3s/kc3s_asan time ./ekc3_test
+
+test_ekc3_cov:
+	KC3S=${SRC_TOP}/kc3s/kc3s_cov time ./ekc3_test
+
+test_ekc3_debug:
+	KC3S=${SRC_TOP}/kc3s/kc3s_debug time ./ekc3_test
 
 test_ikc3:
 	IKC3=${SRC_TOP}/ikc3/ikc3 time ./ikc3_test
diff --git a/test/ekc3/title.kc3 b/test/ekc3/title.kc3
index 4a422c6..b95124b 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"})
+puts(EKC3.render(__DIR__ + "/title.html.ekc3",
+      %{title: "EKC3 test title"}))
diff --git a/test/ikc3/puts.in b/test/ikc3/puts.in
new file mode 100644
index 0000000..8a8fe27
--- /dev/null
+++ b/test/ikc3/puts.in
@@ -0,0 +1,4 @@
+quote puts("Test")
+puts("Test")
+quote puts(%{hello: "World !"})
+puts(%{hello: "World !"})
diff --git a/test/ikc3/puts.out.expected b/test/ikc3/puts.out.expected
new file mode 100644
index 0000000..3a24fa1
--- /dev/null
+++ b/test/ikc3/puts.out.expected
@@ -0,0 +1,6 @@
+puts("Test")
+Test
+5
+puts(%{hello: "World !"})
+%{hello: "World !"}
+20
diff --git a/test/ikc3/puts.ret.expected b/test/ikc3/puts.ret.expected
new file mode 100644
index 0000000..573541a
--- /dev/null
+++ b/test/ikc3/puts.ret.expected
@@ -0,0 +1 @@
+0