diff --git a/.ic3_history b/.ic3_history
index 0f61e21..522676e 100644
--- a/.ic3_history
+++ b/.ic3_history
@@ -1,24 +1,3 @@
-U8[]
-U8[1]
-(U8[]) { 1, 2, 3 }
-(U8[]) {1, 2, 3}
-(U8[]) {0}
-(U8[]) {1, 2, 3}
-dlopen
-dlopen("libc3/window/sdl2/.libs/libc3_window_sdl2.so.0.0", 0)
-dlopen("libc3/window/sdl2/.libs/libc3_window_sdl2.so.0.0", (U32) 0)
-dlopen("libc3/window/sdl2/.libs/libc3_window_sdl2.so.0.0", (U32) 1)
-dlopen("libc3/window/sdl2/.libs/libc3_window_sdl2.so.0.0", (U32) 2)
-dlopen("libc3/window/sdl2/.libs/libc3_window_sdl2.so.0.0", (U32) 0)
-dlopen("libc3/window/.libs/libc3_window.so.0.0", (U32) 0)
-dlopen("libc3/window/.libs/libc3_window.so.0.0", (U32) 4)
-dlopen("libc3/window/.libs/libc3_window.so.0.0", (U32) 1)
-dlopen("libc3/window/.libs/libc3_window.so.0.0", (U32) 2)
-dlopen("libc3/window/.libs/libc3_window.so.0.0", (U32) 4)
-dlopen("libc3/window/.libs/libc3_window.so.0.0", (U32) 8)
-dlopen("libc3/window/.libs/libc3_window.so.0.0", (U32) 16)
-dlopen("libc3/window/.libs/libc3_window.so.0.0", (U32) 32)
-dlopen("libc3/window/.libs/libc3_window.so.0.0", (U32) 0)
dlopen("/home/dx/c/thodg/c3-lang/c3/libc3/window/.libs/libc3_window.so.0.0", (U32) 0)
getenv("_")
getenv("SHELL")
@@ -97,3 +76,24 @@ m("plop")
m = macro (x) { quote 1 + unquote x }
plop = 2
m(plop)
+name = "Thomas"
+m = macro (x) { quote 1 + unquote x }
+m(name)
+name
+name = "Thomas"
+m = macro (x) { quote 1 + unquote x }
+m(name)
+name = "Thomas"
+m = macro (x) { quote 1 + unquote x }
+m(name)
+name = "Thomas"
+m = macro (x) { quote 1 + unquote x }
+m(name)
+name
+^a = ^a
+^a = ^1
+^ a = ^ 1
+^ a = 1
+a = 1
+^ a = 1
+^ a
diff --git a/ic3/.ic3_history b/ic3/.ic3_history
index 3163cff..81326ad 100644
--- a/ic3/.ic3_history
+++ b/ic3/.ic3_history
@@ -1,47 +1,3 @@
-1.231229999999997e+2
-1.231229999999996e+2
-1.231229999999995e+2
-123.123
-1234567.0f
-1.234f
-%GL.Point2D{}
-GL.Point2D
-type(GL.Point2D)
-quote %GL.Point2D{}
-GL.Point2D{
-GL.Point2D{}
-GL.Point2D{}}
-GL.Point2D{}
-GL.Point2D
-{}
-facts_next_id
-facts_next_id()
-4 * 27
-24 * 7
-4.0/1920.0
-4.0 / 1920.0
-4.0f / 1920.0f
-4.0f / 1200.0f
-U8[]
-D
-U8[]
-U8[1]
-(U8[]) { 1, 2, 3 }
-(U8[]) {1, 2, 3}
-(U8[]) {0}
-(U8[]) {1, 2, 3}
-dlopen
-dlopen("libc3/window/sdl2/.libs/libc3_window_sdl2.so.0.0", 0)
-dlopen("libc3/window/sdl2/.libs/libc3_window_sdl2.so.0.0", (U32) 0)
-dlopen("libc3/window/sdl2/.libs/libc3_window_sdl2.so.0.0", (U32) 1)
-dlopen("libc3/window/sdl2/.libs/libc3_window_sdl2.so.0.0", (U32) 2)
-dlopen("libc3/window/sdl2/.libs/libc3_window_sdl2.so.0.0", (U32) 0)
-dlopen("libc3/window/.libs/libc3_window.so.0.0", (U32) 0)
-dlopen("libc3/window/.libs/libc3_window.so.0.0", (U32) 4)
-dlopen("libc3/window/.libs/libc3_window.so.0.0", (U32) 1)
-dlopen("libc3/window/.libs/libc3_window.so.0.0", (U32) 2)
-dlopen("libc3/window/.libs/libc3_window.so.0.0", (U32) 4)
-dlopen("libc3/window/.libs/libc3_window.so.0.0", (U32) 8)
dlopen("libc3/window/.libs/libc3_window.so.0.0", (U32) 16)
dlopen("libc3/window/.libs/libc3_window.so.0.0", (U32) 32)
dlopen("libc3/window/.libs/libc3_window.so.0.0", (U32) 0)
@@ -97,3 +53,47 @@ dlopen("../libc3/window/sdl2/.libs/libc3_window_sdl2_debug.so.0.0")
%GL.Object{}
quote %GL.Object{}
quote %GL.Sphere{}
+^1
+name = "Thomas"
+^name
+^name = "Thomas"
+^1
+name = "Plop"
+^name
+^name = 1
+^name = plop
+plop
+name
+^name = ^plop
+^name = 1
+^name = a
+^name = plop
+name = "Plop"
+^name = plop
+name = "Plop"
+^name = plop
+name = ^plop
+^name = plop
+(^name) = plop
+^name = ^plop
+plop = "Plop"
+name = "Plop"
+^name = ^plop
+!1 = plop
+! 1 = plop
+^ 1 = plop
+^ 1 = ^ plop
+1 = ^ plop
+name = "Plop"
+^ name = plop
+plop
+^ name
+name
+^ name
+name = "Plop"
+^ name
+^ name = 1
+^ name = "abc"
+^ name = "Plop"
+^ name = plop
+plop
diff --git a/lib/c3/0.1/c3.facts b/lib/c3/0.1/c3.facts
index b975f07..7de6335 100644
--- a/lib/c3/0.1/c3.facts
+++ b/lib/c3/0.1/c3.facts
@@ -15,6 +15,13 @@ replace {C3.operator01, :arity, 2}
replace {C3.operator01, :cfn, cfn Tag "tag_brackets" (Tag, Tag, Result)}
replace {C3.operator01, :operator_precedence, 13}
replace {C3.operator01, :operator_associativity, :left}
+add {C3, :operator, C3.operator_pin}
+replace {C3.operator_pin, :is_a, :operator}
+replace {C3.operator_pin, :symbol, :^}
+replace {C3.operator_pin, :arity, 1}
+replace {C3.operator_pin, :cfn, cfn Tag "c3_pin" (Tag, Result)}
+replace {C3.operator_pin, :operator_precedence, 12}
+replace {C3.operator_pin, :operator_associativity, :right}
add {C3, :operator, C3.operator02}
replace {C3.operator02, :is_a, :operator}
replace {C3.operator02, :symbol, :!}
diff --git a/libc3/c3.c b/libc3/c3.c
index 52c2f8f..c3b5930 100644
--- a/libc3/c3.c
+++ b/libc3/c3.c
@@ -88,3 +88,10 @@ void c3_license (void)
buf_write_1(&g_c3_env.out, g_c3_license);
buf_flush(&g_c3_env.out);
}
+
+s_tag * c3_pin (const s_tag *a, s_tag *dest)
+{
+ if (! env_eval_tag(&g_c3_env, a, dest))
+ return NULL;
+ return dest;
+}
diff --git a/libc3/env.c b/libc3/env.c
index 33725df..cbc1d42 100644
--- a/libc3/env.c
+++ b/libc3/env.c
@@ -397,9 +397,11 @@ bool env_eval_equal_tag (s_env *env, const s_tag *a, const s_tag *b,
is_unbound_a = a->type == TAG_IDENT;
is_unbound_b = b->type == TAG_IDENT;
if (is_unbound_a && is_unbound_b) {
- warnx("unbound equal on both sides: %s = %s",
- a->data.ident.sym->str.ptr.pchar,
- b->data.ident.sym->str.ptr.pchar);
+ err_write_1("env_eval_equal_tag: unbound equal on both sides: ");
+ err_inspect_ident(&a->data.ident),
+ err_write_1(" = ");
+ err_inspect_ident(&b->data.ident);
+ err_write_1("\n");
return false;
}
if (is_unbound_a) {
@@ -412,6 +414,30 @@ bool env_eval_equal_tag (s_env *env, const s_tag *a, const s_tag *b,
frame_binding_new(env->frame, b->data.ident.sym, dest);
return true;
}
+ if (a->type == TAG_CALL &&
+ //a->data.call.ident.module == &g_sym_C3 &&
+ a->data.call.ident.sym == &g_sym_operator_pin) {
+ if (! env_eval_tag(env, &a->data.call.arguments->tag, &tmp_a))
+ return false;
+ if (! env_eval_equal_tag(env, &tmp_a, b, dest)) {
+ tag_clean(&tmp_a);
+ return false;
+ }
+ tag_clean(&tmp_a);
+ return true;
+ }
+ if (b->type == TAG_CALL &&
+ //b->data.call.ident.module == &g_sym_C3 &&
+ b->data.call.ident.sym == &g_sym_operator_pin) {
+ if (! env_eval_tag(env, &b->data.call.arguments->tag, &tmp_b))
+ return false;
+ if (! env_eval_equal_tag(env, a, &tmp_b, dest)) {
+ tag_clean(&tmp_b);
+ return false;
+ }
+ tag_clean(&tmp_b);
+ return true;
+ }
switch (a->type) {
case TAG_F32:
case TAG_F64:
@@ -618,7 +644,7 @@ bool env_eval_ident_is_bound (s_env *env, const s_ident *ident)
s_tag tmp;
assert(env);
assert(ident);
- if (frame_get(env->frame, tmp_ident.sym))
+ if (frame_get(env->frame, ident->sym))
return true;
ident_init_copy(&tmp_ident, ident);
ident_resolve_module(&tmp_ident, env);
diff --git a/libc3/io.c b/libc3/io.c
index 8f495b1..ed1aa53 100644
--- a/libc3/io.c
+++ b/libc3/io.c
@@ -110,7 +110,8 @@ DEF_ERR_IO_INSPECT(character, const character *)
DEF_ERR_IO_INSPECT(f32, const f32 *)
DEF_ERR_IO_INSPECT(fact, const s_fact *)
DEF_ERR_IO_INSPECT(fn_pattern, const s_list *)
-DEF_ERR_IO_INSPECT(list, const s_list **)
+DEF_ERR_IO_INSPECT(ident, const s_ident *)
+DEF_ERR_IO_INSPECT(list, const s_list * const *)
DEF_ERR_IO_INSPECT(map, const s_map *)
DEF_ERR_IO_INSPECT(s8, const s8 *)
DEF_ERR_IO_INSPECT(s16, const s16 *)
@@ -118,7 +119,7 @@ DEF_ERR_IO_INSPECT(s32, const s32 *)
DEF_ERR_IO_INSPECT(s64, const s64 *)
DEF_ERR_IO_INSPECT(str, const s_str *)
DEF_ERR_IO_INSPECT(sw, const sw *)
-DEF_ERR_IO_INSPECT(sym, const s_sym **)
+DEF_ERR_IO_INSPECT(sym, const s_sym * const *)
DEF_ERR_IO_INSPECT(tag, const s_tag *)
DEF_ERR_IO_INSPECT(tuple, const s_tuple *)
DEF_ERR_IO_INSPECT(u8, const u8 *)
diff --git a/libc3/io.h b/libc3/io.h
index 41b0da7..063d465 100644
--- a/libc3/io.h
+++ b/libc3/io.h
@@ -48,7 +48,7 @@ PROTOTYPES_ERR_IO_INSPECT(fn, const s_fn *);
PROTOTYPES_ERR_IO_INSPECT(fn_pattern, const s_list *);
PROTOTYPES_ERR_IO_INSPECT(ident, const s_ident *);
PROTOTYPES_ERR_IO_INSPECT(integer, const s_integer *);
-PROTOTYPES_ERR_IO_INSPECT(list, const s_list **);
+PROTOTYPES_ERR_IO_INSPECT(list, const s_list * const *);
PROTOTYPES_ERR_IO_INSPECT(map, const s_map *);
PROTOTYPES_ERR_IO_INSPECT(s8, const s8 *);
PROTOTYPES_ERR_IO_INSPECT(s16, const s16 *);
@@ -56,7 +56,7 @@ PROTOTYPES_ERR_IO_INSPECT(s32, const s32 *);
PROTOTYPES_ERR_IO_INSPECT(s64, const s64 *);
PROTOTYPES_ERR_IO_INSPECT(str, const s_str *);
PROTOTYPES_ERR_IO_INSPECT(sw, const sw *);
-PROTOTYPES_ERR_IO_INSPECT(sym, const s_sym **);
+PROTOTYPES_ERR_IO_INSPECT(sym, const s_sym * const *);
PROTOTYPES_ERR_IO_INSPECT(tag, const s_tag *);
PROTOTYPES_ERR_IO_INSPECT(tuple, const s_tuple *);
PROTOTYPES_ERR_IO_INSPECT(u8, const u8 *);
diff --git a/libc3/sym.c b/libc3/sym.c
index 2ba94a8..0fd8a53 100644
--- a/libc3/sym.c
+++ b/libc3/sym.c
@@ -14,64 +14,65 @@
#include <string.h>
#include "c3.h"
-const s_sym g_sym__brackets = {{{NULL}, 2, {"[]"}}};
-const s_sym g_sym__paren = {{{NULL}, 2, {"()"}}};
-const s_sym g_sym__plus = {{{NULL}, 1, {"+"}}};
-const s_sym g_sym_Array = {{{NULL}, 5, {"Array"}}};
-const s_sym g_sym_Block = {{{NULL}, 5, {"Block"}}};
-const s_sym g_sym_Bool = {{{NULL}, 4, {"Bool"}}};
-const s_sym g_sym_C3 = {{{NULL}, 2, {"C3"}}};
-const s_sym g_sym_Call = {{{NULL}, 4, {"Call"}}};
-const s_sym g_sym_Cfn = {{{NULL}, 3, {"Cfn"}}};
-const s_sym g_sym_Character = {{{NULL}, 9, {"Character"}}};
-const s_sym g_sym_Char__star = {{{NULL}, 5, {"Char*"}}};
-const s_sym g_sym_F32 = {{{NULL}, 3, {"F32"}}};
-const s_sym g_sym_F64 = {{{NULL}, 3, {"F64"}}};
-const s_sym g_sym_F128 = {{{NULL}, 3, {"F128"}}};
-const s_sym g_sym_Fact = {{{NULL}, 4, {"Fact"}}};
-const s_sym g_sym_Fn = {{{NULL}, 2, {"Fn"}}};
-const s_sym g_sym_Ident = {{{NULL}, 5, {"Ident"}}};
-const s_sym g_sym_Integer = {{{NULL}, 7, {"Integer"}}};
-const s_sym g_sym_List = {{{NULL}, 4, {"List"}}};
-const s_sym g_sym_Map = {{{NULL}, 3, {"Map"}}};
-const s_sym g_sym_Ptag = {{{NULL}, 4, {"Ptag"}}};
-const s_sym g_sym_Ptr = {{{NULL}, 3, {"Ptr"}}};
-const s_sym g_sym_PtrFree = {{{NULL}, 7, {"PtrFree"}}};
-const s_sym g_sym_Quote = {{{NULL}, 5, {"Quote"}}};
-const s_sym g_sym_Unquote = {{{NULL}, 7, {"Unquote"}}};
-const s_sym g_sym_Result = {{{NULL}, 6, {"Result"}}};
-const s_sym g_sym_S8 = {{{NULL}, 2, {"S8"}}};
-const s_sym g_sym_S16 = {{{NULL}, 3, {"S16"}}};
-const s_sym g_sym_S32 = {{{NULL}, 3, {"S32"}}};
-const s_sym g_sym_S64 = {{{NULL}, 3, {"S64"}}};
-const s_sym g_sym_Str = {{{NULL}, 3, {"Str"}}};
-const s_sym g_sym_Struct = {{{NULL}, 6, {"Struct"}}};
-const s_sym g_sym_StructType = {{{NULL}, 10, {"StructType"}}};
-const s_sym g_sym_Sw = {{{NULL}, 2, {"Sw"}}};
-const s_sym g_sym_Sym = {{{NULL}, 3, {"Sym"}}};
-const s_sym g_sym_Tag = {{{NULL}, 3, {"Tag"}}};
-const s_sym g_sym_Tuple = {{{NULL}, 5, {"Tuple"}}};
-const s_sym g_sym_U8 = {{{NULL}, 2, {"U8"}}};
-const s_sym g_sym_U16 = {{{NULL}, 3, {"U16"}}};
-const s_sym g_sym_U32 = {{{NULL}, 3, {"U32"}}};
-const s_sym g_sym_U64 = {{{NULL}, 3, {"U64"}}};
-const s_sym g_sym_Uw = {{{NULL}, 2, {"Uw"}}};
-const s_sym g_sym_Uw_brackets = {{{NULL}, 4, {"Uw[]"}}};
-const s_sym g_sym_Var = {{{NULL}, 3, {"Var"}}};
-const s_sym g_sym_Void = {{{NULL}, 4, {"Void"}}};
-const s_sym g_sym_cast = {{{NULL}, 4, {"cast"}}};
-const s_sym g_sym_defstruct = {{{NULL}, 9, {"defstruct"}}};
-const s_sym g_sym_do = {{{NULL}, 2, {"do"}}};
-const s_sym g_sym_end = {{{NULL}, 3, {"end"}}};
-const s_sym g_sym_load_time = {{{NULL}, 9, {"load_time"}}};
-const s_sym g_sym_r = {{{NULL}, 1, {"r"}}};
-const s_sym g_sym_rw = {{{NULL}, 2, {"rw"}}};
-const s_sym g_sym_rwx = {{{NULL}, 3, {"rwx"}}};
-const s_sym g_sym_rx = {{{NULL}, 2, {"rx"}}};
-const s_sym g_sym_struct_type = {{{NULL}, 11, {"struct_type"}}};
-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"}}};
+const s_sym g_sym__brackets = {{{NULL}, 2, {"[]"}}};
+const s_sym g_sym__paren = {{{NULL}, 2, {"()"}}};
+const s_sym g_sym__plus = {{{NULL}, 1, {"+"}}};
+const s_sym g_sym_Array = {{{NULL}, 5, {"Array"}}};
+const s_sym g_sym_Block = {{{NULL}, 5, {"Block"}}};
+const s_sym g_sym_Bool = {{{NULL}, 4, {"Bool"}}};
+const s_sym g_sym_C3 = {{{NULL}, 2, {"C3"}}};
+const s_sym g_sym_Call = {{{NULL}, 4, {"Call"}}};
+const s_sym g_sym_Cfn = {{{NULL}, 3, {"Cfn"}}};
+const s_sym g_sym_Character = {{{NULL}, 9, {"Character"}}};
+const s_sym g_sym_Char__star = {{{NULL}, 5, {"Char*"}}};
+const s_sym g_sym_F32 = {{{NULL}, 3, {"F32"}}};
+const s_sym g_sym_F64 = {{{NULL}, 3, {"F64"}}};
+const s_sym g_sym_F128 = {{{NULL}, 3, {"F128"}}};
+const s_sym g_sym_Fact = {{{NULL}, 4, {"Fact"}}};
+const s_sym g_sym_Fn = {{{NULL}, 2, {"Fn"}}};
+const s_sym g_sym_Ident = {{{NULL}, 5, {"Ident"}}};
+const s_sym g_sym_Integer = {{{NULL}, 7, {"Integer"}}};
+const s_sym g_sym_List = {{{NULL}, 4, {"List"}}};
+const s_sym g_sym_Map = {{{NULL}, 3, {"Map"}}};
+const s_sym g_sym_Ptag = {{{NULL}, 4, {"Ptag"}}};
+const s_sym g_sym_Ptr = {{{NULL}, 3, {"Ptr"}}};
+const s_sym g_sym_PtrFree = {{{NULL}, 7, {"PtrFree"}}};
+const s_sym g_sym_Quote = {{{NULL}, 5, {"Quote"}}};
+const s_sym g_sym_Unquote = {{{NULL}, 7, {"Unquote"}}};
+const s_sym g_sym_Result = {{{NULL}, 6, {"Result"}}};
+const s_sym g_sym_S8 = {{{NULL}, 2, {"S8"}}};
+const s_sym g_sym_S16 = {{{NULL}, 3, {"S16"}}};
+const s_sym g_sym_S32 = {{{NULL}, 3, {"S32"}}};
+const s_sym g_sym_S64 = {{{NULL}, 3, {"S64"}}};
+const s_sym g_sym_Str = {{{NULL}, 3, {"Str"}}};
+const s_sym g_sym_Struct = {{{NULL}, 6, {"Struct"}}};
+const s_sym g_sym_StructType = {{{NULL}, 10, {"StructType"}}};
+const s_sym g_sym_Sw = {{{NULL}, 2, {"Sw"}}};
+const s_sym g_sym_Sym = {{{NULL}, 3, {"Sym"}}};
+const s_sym g_sym_Tag = {{{NULL}, 3, {"Tag"}}};
+const s_sym g_sym_Tuple = {{{NULL}, 5, {"Tuple"}}};
+const s_sym g_sym_U8 = {{{NULL}, 2, {"U8"}}};
+const s_sym g_sym_U16 = {{{NULL}, 3, {"U16"}}};
+const s_sym g_sym_U32 = {{{NULL}, 3, {"U32"}}};
+const s_sym g_sym_U64 = {{{NULL}, 3, {"U64"}}};
+const s_sym g_sym_Uw = {{{NULL}, 2, {"Uw"}}};
+const s_sym g_sym_Uw_brackets = {{{NULL}, 4, {"Uw[]"}}};
+const s_sym g_sym_Var = {{{NULL}, 3, {"Var"}}};
+const s_sym g_sym_Void = {{{NULL}, 4, {"Void"}}};
+const s_sym g_sym_cast = {{{NULL}, 4, {"cast"}}};
+const s_sym g_sym_defstruct = {{{NULL}, 9, {"defstruct"}}};
+const s_sym g_sym_do = {{{NULL}, 2, {"do"}}};
+const s_sym g_sym_end = {{{NULL}, 3, {"end"}}};
+const s_sym g_sym_load_time = {{{NULL}, 9, {"load_time"}}};
+const s_sym g_sym_operator_pin = {{{NULL}, 12, {"operator_pin"}}};
+const s_sym g_sym_r = {{{NULL}, 1, {"r"}}};
+const s_sym g_sym_rw = {{{NULL}, 2, {"rw"}}};
+const s_sym g_sym_rwx = {{{NULL}, 3, {"rwx"}}};
+const s_sym g_sym_rx = {{{NULL}, 2, {"rx"}}};
+const s_sym g_sym_struct_type = {{{NULL}, 11, {"struct_type"}}};
+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"}}};
static s_sym_list * g_sym_list = NULL;
@@ -300,6 +301,7 @@ void sym_init_g_sym (void)
sym_intern(&g_sym_do, NULL);
sym_intern(&g_sym_end, NULL);
sym_intern(&g_sym_load_time, NULL);
+ sym_intern(&g_sym_operator_pin, NULL);
sym_intern(&g_sym_r, NULL);
sym_intern(&g_sym_rw, NULL);
sym_intern(&g_sym_rwx, NULL);
diff --git a/libc3/sym.h b/libc3/sym.h
index d86194e..5063fc2 100644
--- a/libc3/sym.h
+++ b/libc3/sym.h
@@ -76,6 +76,7 @@ extern const s_sym g_sym_defstruct;
extern const s_sym g_sym_do;
extern const s_sym g_sym_end;
extern const s_sym g_sym_load_time;
+extern const s_sym g_sym_operator_pin;
extern const s_sym g_sym_r;
extern const s_sym g_sym_rw;
extern const s_sym g_sym_rwx;
diff --git a/test/ic3/equal.in b/test/ic3/equal.in
index 34b3260..c3a29e2 100644
--- a/test/ic3/equal.in
+++ b/test/ic3/equal.in
@@ -1,4 +1,4 @@
a = 1
b = 1
-a = 2
-[a, b] = [1, 2]
+c = 2
+[d, e] = [1, 2]