Commit 161f3c30e491d88576e7feb64a8a58a052d1c996

Thomas de Grivel 2024-03-27T11:39:14

if then else

diff --git a/.ic3_history b/.ic3_history
index 389ecfc..aa532ae 100644
--- a/.ic3_history
+++ b/.ic3_history
@@ -1,24 +1,3 @@
-def 1 = 1
-def a = 1
-def 1 = 1
-def a = 1
-a
-def a = 1
-a
-def a = fn (x) do x * 2 end
-a
-List.reverse
-license
-def reverse = fn (x) { List.reverse(x) }
-reverse([1, 2, 3])
-def reverse = fn (x) { [:reversed | List.reverse(x)] }
-reverse([1, 2, 3])
-def reverse = fn (x) { List.reverse(x) }
-reverse([1, 2, 3])
-def reverse = fn (x) { [:reversed | List.reverse(x)] }
-reverse([1, 2, 3])
-def reverse = fn (x) { List.reverse(x) }
-reverse([1, 2, 3])
 def reverse = fn (x) { List.reverse(x) }
 C3.reverse
 def dt = macro (x) do
@@ -97,3 +76,24 @@ b = ^ a
 b = a
 a = ^ b
 a = ^ c
+a = ^ b
+b = 1
+a = ^ b
+a = c
+fib(10)
+fib(20)
+def fib = fn { (0) { 1 } (1) { 1 } (x) { if x < 0 then 1 else fib(x - 2) + fib(x - 1) end } }
+def fib = fn (x) { if x < 0 then 1 else fib(x - 2) + fib(x - 1) end }
+def fib = fn (x) { if x < 0 then
+1
+else
+fib(x - 2) + fib(x - 1)
+end
+}
+if true then 1 else 2 end
+if true 1 else 2 end
+def fib = fn (x) { if x < 0 1 else fib(x - 2) + fib(x - 1) end }
+fib(-1)
+def fib = fn (x) { if x < 0 0 else fib(x - 2) + fib(x - 1) end }
+def fib = fn (x) { if x < 0 then 0 else fib(x - 2) + fib(x - 1) end }
+def fib = fn { (0) { 1 } (1) { 1 } (x) { if x < 0 then 0 else fib(x - 2) + fib(x - 1) end }}
diff --git a/lib/c3/0.1/c3.facts b/lib/c3/0.1/c3.facts
index 3f7ca8d..1909fb9 100644
--- a/lib/c3/0.1/c3.facts
+++ b/lib/c3/0.1/c3.facts
@@ -206,7 +206,7 @@ add {C3, :symbol, C3.fib}
 replace {C3.fib, :symbol_value, fn {
   (0) { 1 }
   (1) { 1 }
-  (x) { fib(x - 1) + fib(x - 2) }
+  (x) { if x < 0 then 0 else fib(x - 1) + fib(x - 2) end }
 }}
 add {C3, :symbol, C3.if_then_else}
 replace {C3.if_then_else, :arity, 3}
diff --git a/libc3/buf_parse.c b/libc3/buf_parse.c
index 194bb8c..9d554f7 100644
--- a/libc3/buf_parse.c
+++ b/libc3/buf_parse.c
@@ -1710,6 +1710,12 @@ sw buf_parse_if (s_buf *buf, s_call *dest)
   if ((r = buf_parse_tag(buf, condition)) <= 0)
     goto restore;
   result += r;
+  if ((r = buf_parse_comments(buf)) < 0)
+    goto restore;
+  result += r;
+  if ((r = buf_ignore_spaces(buf)) < 0)
+    goto restore;
+  result += r;
   args_last = &(*args_last)->next.data.list;
   *args_last = list_new(NULL);
   then = &(*args_last)->tag;
@@ -1754,6 +1760,9 @@ sw buf_parse_if_then (s_buf *buf, s_tag *dest, bool *has_else)
   s_buf_save save;
   s_block tmp;
   buf_save_init(buf, &save);
+  if ((r = buf_read_sym(buf, &g_sym_then)) < 0)
+    goto restore;
+  result += r;
   i = &list;
   *i = NULL;
   while (1) {
diff --git a/libc3/env.c b/libc3/env.c
index de65e0e..3f9af42 100644
--- a/libc3/env.c
+++ b/libc3/env.c
@@ -474,8 +474,8 @@ bool env_eval_equal_tag (s_env *env, bool macro, const s_tag *a,
     err_inspect_ident(&a->data.ident);
     err_write_1(" = ");
     err_inspect_ident(&b->data.ident);
-    err_write_1(".\nTo assign a variable an existing variable, use"
-                " the pin operator on the\nexisting variable: ");
+    err_write_1(".\nTo match an existing variable please use the"
+                " pin operator, e.g.: ");
     err_inspect_ident(&a->data.ident);
     err_write_1(" = ^ ");
     err_inspect_ident(&b->data.ident);
diff --git a/libc3/sym.c b/libc3/sym.c
index f970687..f25bbd4 100644
--- a/libc3/sym.c
+++ b/libc3/sym.c
@@ -99,6 +99,7 @@ const s_sym g_sym_special_operator =
 const s_sym g_sym_struct_type     = {{{NULL}, 11, {"struct_type"}}};
 const s_sym g_sym_symbol          = {{{NULL},  6, {"symbol"}}};
 const s_sym g_sym_symbol_value    = {{{NULL}, 12, {"symbol_value"}}};
+const s_sym g_sym_then            = {{{NULL},  4, {"then"}}};
 const s_sym g_sym_w               = {{{NULL},  1, {"w"}}};
 const s_sym g_sym_wx              = {{{NULL},  2, {"wx"}}};
 const s_sym g_sym_x               = {{{NULL},  1, {"x"}}};
@@ -355,6 +356,7 @@ void sym_init_g_sym (void)
   sym_register(&g_sym_struct_type, NULL);
   sym_register(&g_sym_symbol, NULL);
   sym_register(&g_sym_symbol_value, NULL);
+  sym_register(&g_sym_then, NULL);
   sym_register(&g_sym_w, NULL);
   sym_register(&g_sym_wx, NULL);
   sym_register(&g_sym_x, NULL);
diff --git a/libc3/sym.h b/libc3/sym.h
index 2d8b173..4f8cf97 100644
--- a/libc3/sym.h
+++ b/libc3/sym.h
@@ -101,6 +101,7 @@ extern const s_sym g_sym_special_operator;
 extern const s_sym g_sym_struct_type;
 extern const s_sym g_sym_symbol;
 extern const s_sym g_sym_symbol_value;
+extern const s_sym g_sym_then;
 extern const s_sym g_sym_w;
 extern const s_sym g_sym_wx;
 extern const s_sym g_sym_x;