diff --git a/.ic3_history b/.ic3_history
index 70e9a0a..31d0774 100644
--- a/.ic3_history
+++ b/.ic3_history
@@ -1,23 +1,3 @@
-type(1 +i 2 +i 3 + 4)
-sq(1 +i 2 +i 3 + 4)
-sq = fn (x) { x * x }
-type(1 +i 2 +i 3 + 4)
-sq(1 +i 2 +i 3 + 4)
-1 +i 2 +i 3 + 4
-sq = fn (x) { x * x }
-sq(1 +i 2 +i 3 + 4)
-sq(1 +i 0)
-sq(1 +i 1)
-sq(0 +i 1)
-sq(1 +i 1)
-sq(1 +i 2)
-sq(1 +i 0)
-sq(1 +i 0.5)
-sq(1 +i 1/2)
-(Ratio) 1
-quote (Complex) 0
--1/-1
--1/-1 + 1
-1/-1 + 1/1
-1/-1
-1/1
@@ -97,3 +77,23 @@ defmodule Plop do
1 + 1
2 + 2
end
+defmodule Plop
+do
+ 1 + 1
+ 2 + 2
+end
+def
+123 = 123
+def
+def a = 1
+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
diff --git a/README.md b/README.md
index ab8b083..29521e7 100644
--- a/README.md
+++ b/README.md
@@ -417,8 +417,11 @@ Script interpreter. Works the same as ic3 but is not interactive.
- has_ident
- collect_idents
- modules
- - defmodule
+ - DONE defmodule
- def
+ - def double = 4
+ - def double = fn (x) do x * 2 end
+ - def double = macro (x) do {x, x} end
- defmacro
- defoperator
- defspecial_operator
diff --git a/ic3/.ic3_history b/ic3/.ic3_history
index 57d6470..31d0774 100644
--- a/ic3/.ic3_history
+++ b/ic3/.ic3_history
@@ -1,100 +1,99 @@
-"ab" + "cd" + "ef"
-"Bonjour " + name + " !"
-hello = fn (name) { "Hello, " + name + " !" }
-hello("Patrice")
-hello("Thomas")
-"Hello, " + "Tiyon" + " !"
-hello = fn (name) { "Hello, " + name + " !" }
-hello("Tiyon")
-hello("Patrice")
-"Hello, #{name} !"
-hello("Tiyon")
-hello = fn (name) { "Hello, " + name + " !" }
-hello("Tiyon")
-hello("Baptiste")
-"a"
-"abc"
-hello = fn (name) { "Hello, #{name} !" }
-hello("Thomas")
-hello = fn (name) { "Hello, #{name} !" }
-name("Thomas")
-hello("Thomas")
-hello = fn (name) { "Hello, #{name} !" }
-hello("Paul")
-quote hello("Paul")
-hello
-quote unquote 1
-quote quote unquote 1
-quote unquote 1
-quote quote unquote 1
-dlopen("libc3/window/.libs/libc3_window_debug.so.0.0")
-dlopen("libc3/window/sdl2/.libs/libc3_window_sdl2_debug.so.0.0")
-dlopen("libc3/window/.libs/libc3_window_debug.so.0.0")
-dlopen("libc3/window/.libs/libc3_window.so.0.0")
-dlopen("../libc3/window/.libs/libc3_window_debug.so.0.0")
-dlopen("../libc3/window/sdl2/.libs/libc3_window_sdl2_debug.so.0.0")
-dlopen("../libc3/window/.libs/libc3_window_debug.so.0.0")
-dlopen("../libc3/window/sdl2/.libs/libc3_window_sdl2_debug.so.0.0")
-%GL.Object{}
-type(%GL.Object{})
-%GL.Object{}
-dlopen("../libc3/window/.libs/libc3_window_debug.so.0.0")
-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
-n = "Plop"
-m = macro (name) { quote "Hello, " + (unquote name) + " !" }
-m(n)
-n = "Plop"
-m = macro (name) { quote "Hello, " + (unquote name) + " !" }
-m(n)
-if true 1 else 2 end
-quote if true 1 else 2 end
-quote if false 1 else 2 end
-if false 1 else 2 end
-
+-1/-1 + 1/1
+-1/-1
+-1/1
+sqrt(-1)
+sqrt(-1) * sqrt(-1)
+sqrt(-2) * sqrt(-2)
+sqrt(1)
+sqrt(2)
+sqrt(-2) * sqrt(-2)
+sqrt(-1) * sqrt(-1)
+sqrt(-1)
+sqrt(-2)
+sqrt(-1) * sqrt(-1)
+sqrt(-2) * sqrt(-2)
+1/3 +i 1/2
+1 +i 2
+1/2 +i 2/3
+(1/2 +i 2/3 +i 3/4) * 1/2
+(1/2 +i 2/3 +i 3/4) - 1/2
+1 - 1/2
+1/2 - 1
+1/2 - 3/4
+1 - 3/4
+1/2 * 3/4
+2/3 * 3/4
+2/3 / 3/4
+1 / sqrt(2)
+(1 +i 2) / 3
+(10 +i 20) / 3
+(10/1 +i 20/1) / 3
+(1/2 +i 2/3) / 2
+5 % 3
+5 mod 3
+15 mod 3
+-15 mod 3
+-15 mod -3
+-15 mod -2
+-15 mod -5
+-15 mod -6
+-15 mod 6
+3 mod sqrt(2)
+4 mod sqrt(2)
+2 mod sqrt(2)
+10 mod sqrt(2)
+1/2 + 2/3
+1/2 * 2/3
+1/2 / 2/3
+1/2 - 2/3
+1 +i 2
+(1 +i 2) + (2 +i 3)
+(1 +i 2) * (2 +i 3)
+ic3> (1 +i 2) + (2 +i 3)
+(1 +i 2) / (2 +i 3)
+(1/1 +i 2/1) / (2 +i 3)
+(Ratio) 0
+(Ratio) 1
+(Ratio) 1.2
+(Ratio) 42
+(Ratio) 42 / 3
+((Ratio) 42) / 3
+((Ratio) 42) / 5
+(Ratio) 42 / 5
+(Ratio) 42
+((Ratio) 42) / 5
+(Ratio) 42
+(Ratio) 42 / 5
+(Ratio) 42 / 6
+license()
+license(à
+)
+license()
+hash
+hash(1)
+hash(2)
+license()
+defmodule Plop do
+ 1 + 1
+ 2 + 2
+end
+defmodule Plop
+do
+ 1 + 1
+ 2 + 2
+end
+def
+123 = 123
+def
+def a = 1
+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
diff --git a/lib/c3/0.1/c3.facts b/lib/c3/0.1/c3.facts
index 3939469..3f7ca8d 100644
--- a/lib/c3/0.1/c3.facts
+++ b/lib/c3/0.1/c3.facts
@@ -176,14 +176,14 @@ replace {C3.operator22, :arity, 2}
replace {C3.operator22, :symbol_value, cfn Bool "tag_or" (Tag, Tag, Result)}
replace {C3.operator22, :operator_precedence, 2}
replace {C3.operator22, :operator_associativity, :left}
-add {C3, :operator, C3.operator23}
-replace {C3.operator23, :is_a, :operator}
-replace {C3.operator23, :arity, 2}
-add {C3.operator23, :is_a, :special_operator}
-replace {C3.operator23, :symbol, :=}
-replace {C3.operator23, :symbol_value, cfn Tag "tag_equal" (Tag, Tag, Result)}
-replace {C3.operator23, :operator_precedence, 1}
-replace {C3.operator23, :operator_associativity, :right}
+add {C3, :operator, C3.operator_equal}
+replace {C3.operator_equal, :is_a, :operator}
+replace {C3.operator_equal, :arity, 2}
+add {C3.operator_equal, :is_a, :special_operator}
+replace {C3.operator_equal, :symbol, :=}
+replace {C3.operator_equal, :symbol_value, cfn Tag "tag_equal" (Tag, Tag, Result)}
+replace {C3.operator_equal, :operator_precedence, 1}
+replace {C3.operator_equal, :operator_associativity, :right}
replace {C3.break, :symbol_value, cfn Void "c3_break" ()}
replace {C3, :symbol, C3.license}
replace {C3.license, :symbol_value, cfn Void "c3_license" ()}
@@ -220,3 +220,7 @@ 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)}
+add {C3, :symbol, C3.def}
+replace {C3.def, :arity, 1}
+replace {C3.def, :is_a, :special_operator}
+replace {C3.def, :symbol_value, cfn Tag "c3_def" (Call, Result)}
diff --git a/libc3/c3.c b/libc3/c3.c
index 07fe480..a051a17 100644
--- a/libc3/c3.c
+++ b/libc3/c3.c
@@ -45,6 +45,11 @@ void c3_clean (s_env *env)
sym_delete_all();
}
+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)
{
return env_defmodule(&g_c3_env, name, block, dest);
diff --git a/libc3/env.c b/libc3/env.c
index 7c8821c..6b8f017 100644
--- a/libc3/env.c
+++ b/libc3/env.c
@@ -54,6 +54,7 @@ static s_env * env_init_args (s_env *env, int argc, char **argv);
void env_clean (s_env *env)
{
assert(env);
+ facts_save_file(&env->facts, "debug.facts");
frame_delete_all(env->frame);
error_handler_delete_all(env->error_handler);
facts_clean(&env->facts);
@@ -68,6 +69,41 @@ void env_clean (s_env *env)
list_delete_all(env->path);
}
+s_tag * env_def (s_env *env, const s_call *call, s_tag *dest)
+{
+ s_tag *tag_ident;
+ s_tag tag_module;
+ s_tag tag_symbol;
+ s_tag tag_symbol_value;
+ s_tag *tag_value;
+ (void) env;
+ assert(env);
+ assert(call);
+ assert(dest);
+ if (call->ident.module != &g_sym_C3 ||
+ call->ident.sym != &g_sym_operator_equal ||
+ call->arguments->tag.type != TAG_IDENT ||
+ ! list_next(call->arguments) ||
+ list_next(list_next(call->arguments))) {
+ err_puts("env_def: invalid assignment: expected Ident = value");
+ assert(! "env_def: invalid assignment: expected Ident = value");
+ return NULL;
+ }
+ tag_init_sym(&tag_module, call->arguments->tag.data.ident.module);
+ tag_init_sym(&tag_symbol, &g_sym_symbol);
+ tag_ident = &call->arguments->tag;
+ tag_init_sym(&tag_symbol_value, &g_sym_symbol_value);
+ tag_value = &list_next(call->arguments)->tag;
+ if (! facts_add_tags(&env->facts, &tag_module, &tag_symbol,
+ tag_ident))
+ return NULL;
+ if (! facts_add_tags(&env->facts, tag_ident, &tag_symbol_value,
+ tag_value))
+ return NULL;
+ tag_init_ident(dest, &call->arguments->tag.data.ident);
+ return dest;
+}
+
s_tag * env_defmodule (s_env *env, const s_sym *name,
const s_block *block, s_tag *dest)
{
diff --git a/libc3/env.h b/libc3/env.h
index 396dc7c..3ee4106 100644
--- a/libc3/env.h
+++ b/libc3/env.h
@@ -27,6 +27,7 @@ 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,
diff --git a/libc3/sym.c b/libc3/sym.c
index 4ed9bee..f970687 100644
--- a/libc3/sym.c
+++ b/libc3/sym.c
@@ -22,6 +22,7 @@
#include "tag_type.h"
const s_sym g_sym__brackets = {{{NULL}, 2, {"[]"}}};
+const s_sym g_sym__equal = {{{NULL}, 1, {"="}}};
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"}}};
@@ -84,6 +85,7 @@ const s_sym g_sym_module = {{{NULL}, 6, {"module"}}};
const s_sym g_sym_operator = {{{NULL}, 8, {"operator"}}};
const s_sym g_sym_operator_associativity =
{{{NULL}, 22, {"operator_associativity"}}};
+const s_sym g_sym_operator_equal = {{{NULL}, 14, {"operator_equal"}}};
const s_sym g_sym_operator_pin = {{{NULL}, 12, {"operator_pin"}}};
const s_sym g_sym_operator_precedence =
{{{NULL}, 19, {"operator_precedence"}}};
@@ -279,6 +281,7 @@ const s_sym ** sym_init_copy (const s_sym **sym,
void sym_init_g_sym (void)
{
sym_register(&g_sym__brackets, NULL);
+ sym_register(&g_sym__equal, NULL);
sym_register(&g_sym__paren, NULL);
sym_register(&g_sym__plus, NULL);
sym_register(&g_sym_Array, NULL);
@@ -340,6 +343,7 @@ void sym_init_g_sym (void)
sym_register(&g_sym_module, NULL);
sym_register(&g_sym_operator, NULL);
sym_register(&g_sym_operator_associativity, NULL);
+ sym_register(&g_sym_operator_equal, NULL);
sym_register(&g_sym_operator_pin, NULL);
sym_register(&g_sym_operator_precedence, NULL);
sym_register(&g_sym_r, NULL);
@@ -653,6 +657,10 @@ bool sym_to_ffi_type (const s_sym *sym, ffi_type *result_type,
*dest = &ffi_type_uint8;
return true;
}
+ if (sym == &g_sym_Call) {
+ *dest = &ffi_type_pointer;
+ return true;
+ }
if (sym == &g_sym_Char__star) {
*dest = &ffi_type_pointer;
return true;
diff --git a/libc3/sym.h b/libc3/sym.h
index b610900..2d8b173 100644
--- a/libc3/sym.h
+++ b/libc3/sym.h
@@ -27,6 +27,7 @@
#define SYM_MAX 1024
extern const s_sym g_sym__brackets;
+extern const s_sym g_sym__equal;
extern const s_sym g_sym__paren;
extern const s_sym g_sym__plus;
extern const s_sym g_sym_Array;
@@ -88,6 +89,7 @@ extern const s_sym g_sym_macro;
extern const s_sym g_sym_module;
extern const s_sym g_sym_operator;
extern const s_sym g_sym_operator_associativity;
+extern const s_sym g_sym_operator_equal;
extern const s_sym g_sym_operator_pin;
extern const s_sym g_sym_operator_precedence;
extern const s_sym g_sym_r;