diff --git a/ic3/.ic3_history b/ic3/.ic3_history
index af224cc..003515e 100644
--- a/ic3/.ic3_history
+++ b/ic3/.ic3_history
@@ -1,5 +1,3 @@
-dt(200)
-def dt = macro (x) do
quote do
x = unquote x
def dt = macro (x) do
@@ -97,3 +95,5 @@ do end
defmodule Plop do end
quote Plop
quote_cfn Plop
+(Sym) "Abc"
+defmodule Plop do end
diff --git a/lib/c3/0.1/c3.facts b/lib/c3/0.1/c3.facts
index dddf44d..626d62a 100644
--- a/lib/c3/0.1/c3.facts
+++ b/lib/c3/0.1/c3.facts
@@ -219,7 +219,7 @@ replace {C3.hash, :symbol_value, cfn Uw "tag_hash_uw" (Tag)}
add {C3, :symbol, C3.defmodule}
replace {C3.defmodule, :arity, 2}
replace {C3.defmodule, :is_a, :special_operator}
-replace {C3.defmodule, :symbol_value, cfn Tag "c3_defmodule" (Sym, Block, Result)}
+replace {C3.defmodule, :symbol_value, cfn Sym "c3_defmodule" (Sym, Block, Result)}
add {C3, :symbol, C3.def}
replace {C3.def, :arity, 1}
replace {C3.def, :is_a, :special_operator}
diff --git a/libc3/c3.c b/libc3/c3.c
index 0c1da99..ba65158 100644
--- a/libc3/c3.c
+++ b/libc3/c3.c
@@ -50,7 +50,8 @@ s_tag * c3_def (const s_call *call, s_tag *dest)
return env_def(&g_c3_env, call, dest);
}
-s_tag * c3_defmodule (const s_sym *name, const s_block *block, s_tag *dest)
+const s_sym ** c3_defmodule (const s_sym **name, const s_block *block,
+ const s_sym **dest)
{
return env_defmodule(&g_c3_env, name, block, dest);
}
diff --git a/libc3/c3_main.h b/libc3/c3_main.h
index 401ed34..f78bd1d 100644
--- a/libc3/c3_main.h
+++ b/libc3/c3_main.h
@@ -35,9 +35,12 @@ s_str * c3_getenv (const s_str *name, s_str *dest);
void c3_license (void);
/* Operators. */
-void ** c3_dlopen (const s_str *path, void **dest);
-void c3_exit (sw code);
-s_tag * c3_pin (const s_tag *a, s_tag *dest);
+s_tag * c3_def (const s_call *call, s_tag *dest);
+const s_sym ** c3_defmodule (const s_sym **name, const s_block *block,
+ const s_sym **dest);
+void ** c3_dlopen (const s_str *path, void **dest);
+void c3_exit (sw code);
+s_tag * c3_pin (const s_tag *a, s_tag *dest);
/* Special operators. */
s_tag * c3_if_then_else (const s_tag *cond, const s_tag *then,
diff --git a/libc3/env.c b/libc3/env.c
index bb08fcd..a9fb724 100644
--- a/libc3/env.c
+++ b/libc3/env.c
@@ -106,24 +106,27 @@ s_tag * env_def (s_env *env, const s_call *call, s_tag *dest)
return dest;
}
-s_tag * env_defmodule (s_env *env, const s_sym *name,
- const s_block *block, s_tag *dest)
+const s_sym ** env_defmodule (s_env *env, const s_sym **name,
+ const s_block *block, const s_sym **dest)
{
const s_sym *module;
- s_tag *result = NULL;
+ const s_sym **result = NULL;
s_tag tmp;
assert(env);
assert(name);
+ assert(*name);
assert(block);
assert(dest);
module = env->current_module;
- env->current_module = name;
+ env_module_is_loading_set(env, *name, true);
+ env->current_module = *name;
if (env_eval_block(env, block, &tmp)) {
- dest->type = TAG_SYM;
- dest->data.sym = name;
+ *dest = *name;
result = dest;
}
env->current_module = module;
+ env_module_is_loading_set(env, *name, false);
+ tag_clean(&tmp);
return result;
}
@@ -1441,7 +1444,7 @@ bool env_module_is_loading (s_env *env, const s_sym *module)
true : false;
}
-void env_module_is_loading_set (s_env *env, const s_sym *module,
+bool env_module_is_loading_set (s_env *env, const s_sym *module,
bool is_loading)
{
s_tag tag_module;
@@ -1452,12 +1455,16 @@ void env_module_is_loading_set (s_env *env, const s_sym *module,
tag_init_sym(&tag_module, module);
tag_init_sym(&tag_is_loading, &g_sym_is_loading);
tag_init_bool(&tag_true, true);
- if (is_loading)
- facts_replace_tags(&env->facts, &tag_module, &tag_is_loading,
- &tag_true);
+ if (is_loading) {
+ if (! facts_replace_tags(&env->facts, &tag_module, &tag_is_loading,
+ &tag_true))
+ return false;
+ }
else
- facts_remove_fact_tags(&env->facts, &tag_module, &tag_is_loading,
- &tag_true);
+ if (! facts_remove_fact_tags(&env->facts, &tag_module,
+ &tag_is_loading, &tag_true))
+ return false;
+ return true;
}
bool env_module_load (s_env *env, const s_sym *module, s_facts *facts)
@@ -1473,10 +1480,10 @@ bool env_module_load (s_env *env, const s_sym *module, s_facts *facts)
assert(env);
assert(module);
assert(facts);
- if (env_module_is_loading(env, module)) {
+ if (env_module_is_loading(env, module))
return true;
- }
- env_module_is_loading_set(env, module, true);
+ if (! env_module_is_loading_set(env, module, true))
+ return false;
if (! module_path(module, &env->module_path, &path)) {
err_write_1("env_module_load: ");
err_write_1(module->str.ptr.pchar);
diff --git a/libc3/env.h b/libc3/env.h
index 3ee4106..7fa3e3c 100644
--- a/libc3/env.h
+++ b/libc3/env.h
@@ -27,119 +27,121 @@ void env_ident_resolve_module (const s_env *env,
s_ident *ident);
/* Operators. */
-s_tag * env_def (s_env *env, const s_call *call, s_tag *dest);
-s_tag * env_defmodule (s_env *env, const s_sym *name,
- const s_block *block, s_tag *dest);
-bool env_eval_array (s_env *env, const s_array *array,
- s_array *dest);
-bool env_eval_array_tag (s_env *env, const s_array *array,
- s_tag *dest);
-bool env_eval_block (s_env *env, const s_block *block,
+s_tag * env_def (s_env *env, const s_call *call, s_tag *dest);
+const s_sym ** env_defmodule (s_env *env, const s_sym **name,
+ const s_block *block, const s_sym **dest);
+bool env_eval_array (s_env *env, const s_array *array,
+ s_array *dest);
+bool env_eval_array_tag (s_env *env, const s_array *array,
+ s_tag *dest);
+bool env_eval_block (s_env *env, const s_block *block,
+ s_tag *dest);
+bool env_eval_call (s_env *env, const s_call *call,
s_tag *dest);
-bool env_eval_call (s_env *env, const s_call *call,
- s_tag *dest);
-bool env_eval_call_arguments (s_env *env, const s_list *args,
- s_list **dest);
-bool env_eval_call_cfn (s_env *env, const s_call *call,
- s_tag *dest);
-bool env_eval_call_fn (s_env *env, const s_call *call,
- s_tag *dest);
-bool env_eval_call_resolve (s_env *env, s_call *call);
-bool env_eval_complex (s_env *env, const s_complex *c,
- s_tag *dest);
-bool env_eval_equal_block (s_env *env, bool macro,
- const s_block *a, const s_block *b,
- s_block *dest);
-bool env_eval_equal_list (s_env *env, bool macro,
- const s_list *a, const s_list *b,
- s_list **dest);
-bool env_eval_equal_struct (s_env *env, bool macro,
- const s_struct *a,
- const s_struct *b,
- s_struct *dest);
-bool env_eval_equal_tag (s_env *env, bool macro,
- const s_tag *a, const s_tag *b,
+bool env_eval_call_arguments (s_env *env, const s_list *args,
+ s_list **dest);
+bool env_eval_call_cfn (s_env *env, const s_call *call,
s_tag *dest);
-bool env_eval_equal_tuple (s_env *env, bool macro,
- const s_tuple *a, const s_tuple *b,
- s_tuple *dest);
-bool env_eval_fn (s_env *env, const s_fn *fn, s_tag *dest);
-bool env_eval_fn_call (s_env *env, const s_fn *fn,
- const s_list *arguments, s_tag *dest);
-bool env_eval_ident (s_env *env, const s_ident *ident,
+bool env_eval_call_fn (s_env *env, const s_call *call,
+ s_tag *dest);
+bool env_eval_call_resolve (s_env *env, s_call *call);
+bool env_eval_complex (s_env *env, const s_complex *c,
+ s_tag *dest);
+bool env_eval_equal_block (s_env *env, bool macro,
+ const s_block *a, const s_block *b,
+ s_block *dest);
+bool env_eval_equal_list (s_env *env, bool macro,
+ const s_list *a, const s_list *b,
+ s_list **dest);
+bool env_eval_equal_struct (s_env *env, bool macro,
+ const s_struct *a,
+ const s_struct *b,
+ s_struct *dest);
+bool env_eval_equal_tag (s_env *env, bool macro,
+ const s_tag *a, const s_tag *b,
+ s_tag *dest);
+bool env_eval_equal_tuple (s_env *env, bool macro,
+ const s_tuple *a, const s_tuple *b,
+ s_tuple *dest);
+bool env_eval_fn (s_env *env, const s_fn *fn, s_tag *dest);
+bool env_eval_fn_call (s_env *env, const s_fn *fn,
+ const s_list *arguments, s_tag *dest);
+bool env_eval_ident (s_env *env, const s_ident *ident,
+ s_tag *dest);
+bool env_eval_ident_is_bound (s_env *env,
+ const s_ident *ident);
+bool env_eval_list (s_env *env, const s_list *list,
s_tag *dest);
-bool env_eval_ident_is_bound (s_env *env, const s_ident *ident);
-bool env_eval_list (s_env *env, const s_list *list,
+bool env_eval_map (s_env *env, const s_map *map,
s_tag *dest);
-bool env_eval_map (s_env *env, const s_map *map,
- s_tag *dest);
-bool env_eval_progn (s_env *env, const s_list *program,
- s_tag *dest);
-bool env_eval_quote (s_env *env, const s_quote *quote,
- s_tag *dest);
-bool env_eval_quote_array (s_env *env, const s_array *array,
+bool env_eval_progn (s_env *env, const s_list *program,
+ s_tag *dest);
+bool env_eval_quote (s_env *env, const s_quote *quote,
+ s_tag *dest);
+bool env_eval_quote_array (s_env *env, const s_array *array,
+ s_tag *dest);
+bool env_eval_quote_block (s_env *env, const s_block *block,
+ s_tag *dest);
+bool env_eval_quote_call (s_env *env, const s_call *call,
s_tag *dest);
-bool env_eval_quote_block (s_env *env, const s_block *block,
+bool env_eval_quote_list (s_env *env, const s_list *list,
s_tag *dest);
-bool env_eval_quote_call (s_env *env, const s_call *call,
+bool env_eval_quote_map (s_env *env, const s_map *map,
s_tag *dest);
-bool env_eval_quote_list (s_env *env, const s_list *list,
- s_tag *dest);
-bool env_eval_quote_map (s_env *env, const s_map *map,
- s_tag *dest);
-bool env_eval_quote_quote (s_env *env, const s_quote *quote,
- s_tag *dest);
-bool env_eval_quote_struct (s_env *env, const s_struct *s,
+bool env_eval_quote_quote (s_env *env, const s_quote *quote,
s_tag *dest);
-bool env_eval_quote_tag (s_env *env, const s_tag *tag,
- s_tag *dest);
-bool env_eval_quote_tuple (s_env *env, const s_tuple *tuple,
- s_tag *dest);
-bool env_eval_quote_unquote (s_env *env, const s_unquote *unquote,
+bool env_eval_quote_struct (s_env *env, const s_struct *s,
s_tag *dest);
-bool env_eval_struct (s_env *env, const s_struct *s,
+bool env_eval_quote_tag (s_env *env, const s_tag *tag,
+ s_tag *dest);
+bool env_eval_quote_tuple (s_env *env, const s_tuple *tuple,
+ s_tag *dest);
+bool env_eval_quote_unquote (s_env *env,
+ const s_unquote *unquote,
+ s_tag *dest);
+bool env_eval_struct (s_env *env, const s_struct *s,
+ s_tag *dest);
+bool env_eval_tag (s_env *env, const s_tag *tag,
+ s_tag *dest);
+bool env_eval_tuple (s_env *env, const s_tuple *tuple,
s_tag *dest);
-bool env_eval_tag (s_env *env, const s_tag *tag,
- s_tag *dest);
-bool env_eval_tuple (s_env *env, const s_tuple *tuple,
- s_tag *dest);
-bool env_eval_void (s_env *env, const void *_, s_tag *dest);
-bool env_ident_is_special_operator (s_env *env,
- const s_ident *ident);
-bool env_module_is_loading (s_env *env, const s_sym *module);
-void env_module_is_loading_set (s_env *env,
- const s_sym *module,
- bool value);
-bool env_module_load (s_env *env, const s_sym *module,
- s_facts *facts);
-bool env_module_maybe_reload (s_env *env,
- const s_sym *module,
- s_facts *facts);
-s8 env_operator_arity (s_env *env, const s_ident *op);
-bool env_operator_find (s_env *env, const s_ident *op);
-s_ident * env_operator_ident (s_env *env, const s_ident *op,
- s_ident *dest);
-bool env_eval_integer (s_env *env, const s_integer *integer,
- s_integer *dest);
-bool env_operator_is_right_associative (s_env *env,
- const s_ident *op);
-s8 env_operator_precedence (s_env *env, const s_ident *op);
-s_ident * env_operator_resolve (s_env *env, const s_ident *op,
- u8 arity, s_ident *dest);
-const s_sym * env_operator_symbol (s_env *env, const s_ident *op);
-u8 env_special_operator_arity (s_env *env,
- const s_ident *ident);
-bool env_struct_type_exists (s_env *env,
- const s_sym *module);
+bool env_eval_void (s_env *env, const void *_, s_tag *dest);
+bool env_ident_is_special_operator (s_env *env,
+ const s_ident *ident);
+bool env_module_is_loading (s_env *env, const s_sym *module);
+bool env_module_is_loading_set (s_env *env,
+ const s_sym *module,
+ bool value);
+bool env_module_load (s_env *env, const s_sym *module,
+ s_facts *facts);
+bool env_module_maybe_reload (s_env *env,
+ const s_sym *module,
+ s_facts *facts);
+s8 env_operator_arity (s_env *env, const s_ident *op);
+bool env_operator_find (s_env *env, const s_ident *op);
+s_ident * env_operator_ident (s_env *env, const s_ident *op,
+ s_ident *dest);
+bool env_eval_integer (s_env *env, const s_integer *integer,
+ s_integer *dest);
+bool env_operator_is_right_associative (s_env *env,
+ const s_ident *op);
+s8 env_operator_precedence (s_env *env, const s_ident *op);
+s_ident * env_operator_resolve (s_env *env, const s_ident *op,
+ u8 arity, s_ident *dest);
+const s_sym * env_operator_symbol (s_env *env, const s_ident *op);
+u8 env_special_operator_arity (s_env *env,
+ const s_ident *ident);
+bool env_struct_type_exists (s_env *env,
+ const s_sym *module);
const s_struct_type *
- env_struct_type_find (s_env *env, const s_sym *module);
-f_clean env_struct_type_get_clean (s_env *env,
- const s_sym *module);
-s_list ** env_struct_type_get_spec (s_env *env, const s_sym *module,
- s_list **dest);
-bool env_tag_ident_is_bound (const s_env *env,
- const s_tag *tag,
- s_facts *facts);
+ env_struct_type_find (s_env *env, const s_sym *module);
+f_clean env_struct_type_get_clean (s_env *env,
+ const s_sym *module);
+s_list ** env_struct_type_get_spec (s_env *env, const s_sym *module,
+ s_list **dest);
+bool env_tag_ident_is_bound (const s_env *env,
+ const s_tag *tag,
+ s_facts *facts);
/* Control structures. */
void env_error_f (s_env *env, const char *fmt, ...);
diff --git a/libc3/module.c b/libc3/module.c
index 64225eb..fc913c4 100644
--- a/libc3/module.c
+++ b/libc3/module.c
@@ -30,6 +30,8 @@ bool module_ensure_loaded (const s_sym *module, s_facts *facts)
s_tag tag_module_name;
s_tag tag_is_a;
s_tag tag_module;
+ if (module_is_loading(module))
+ return true;
tag_init_sym(&tag_module_name, module);
tag_init_sym(&tag_is_a, &g_sym_is_a);
tag_init_sym(&tag_module, &g_sym_module);
@@ -50,6 +52,11 @@ bool module_ensure_loaded (const s_sym *module, s_facts *facts)
return module_maybe_reload(module, facts);
}
+bool module_is_loading (const s_sym *module)
+{
+ return env_module_is_loading(&g_c3_env, module);
+}
+
bool module_load (const s_sym *module, s_facts *facts)
{
return env_module_load(&g_c3_env, module, facts);
diff --git a/libc3/module.h b/libc3/module.h
index 33adb6f..676ce48 100644
--- a/libc3/module.h
+++ b/libc3/module.h
@@ -28,6 +28,7 @@ bool module_load (const s_sym *module, s_facts *facts);
bool module_maybe_reload (const s_sym *module, s_facts *facts);
/* Observers */
+bool module_is_loading (const s_sym *module);
s_tag * module_load_time (const s_sym *module, s_facts *facts,
s_tag *dest);
s_str * module_path (const s_sym *module, const s_str *prefix,
diff --git a/libc3/tag.c b/libc3/tag.c
index f307717..0232347 100644
--- a/libc3/tag.c
+++ b/libc3/tag.c
@@ -730,7 +730,7 @@ bool tag_to_const_pointer (const s_tag *tag, const s_sym *type,
case TAG_STR: *dest = &tag->data.str; return true;
case TAG_STRUCT: *dest = &tag->data.struct_; return true;
case TAG_STRUCT_TYPE: *dest = &tag->data.struct_type; return true;
- case TAG_SYM: *dest = tag->data.sym; return true;
+ case TAG_SYM: *dest = &tag->data.sym; return true;
case TAG_TUPLE: *dest = &tag->data.tuple; return true;
case TAG_UNQUOTE: *dest = &tag->data.unquote; return true;
case TAG_VAR: *dest = tag; return true;
@@ -976,7 +976,7 @@ bool tag_to_ffi_pointer (s_tag *tag, const s_sym *type, void **dest)
goto invalid_cast;
case TAG_SYM:
if (type == &g_sym_Sym) {
- *dest = (void *) tag->data.sym;
+ *dest = (void *) &tag->data.sym;
return true;
}
if (type == &g_sym_Str) {
diff --git a/test/ic3/cast.in b/test/ic3/cast.in
index e9b3683..3ddc0fe 100644
--- a/test/ic3/cast.in
+++ b/test/ic3/cast.in
@@ -24,3 +24,7 @@ quote (Integer) 18446744073709551616
(Integer) 18446744073709551616
quote (Integer) 340282366920938463463374607431768211455
(Integer) 340282366920938463463374607431768211455
+quote (Sym) "Abc"
+(Sym) "Abc"
+quote (Sym) "abc"
+(Sym) "abc"
diff --git a/test/ic3/cast.out.expected b/test/ic3/cast.out.expected
index bcf07a7..175550b 100644
--- a/test/ic3/cast.out.expected
+++ b/test/ic3/cast.out.expected
@@ -24,3 +24,7 @@
18446744073709551616
(Integer) 340282366920938463463374607431768211455
340282366920938463463374607431768211455
+(Sym) "Abc"
+Abc
+(Sym) "abc"
+:abc