diff --git a/.ic3_history b/.ic3_history
index aa532ae..af224cc 100644
--- a/.ic3_history
+++ b/.ic3_history
@@ -1,11 +1,3 @@
-def reverse = fn (x) { List.reverse(x) }
-C3.reverse
-def dt = macro (x) do
- quote do
- x = ^ x
- {x, x}
- end
-end
dt(200)
def dt = macro (x) do
quote do
@@ -97,3 +89,11 @@ 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 }}
+do end
+end
+do end
+end
+do end
+defmodule Plop do end
+quote Plop
+quote_cfn Plop
diff --git a/README.md b/README.md
index 29521e7..7673165 100644
--- a/README.md
+++ b/README.md
@@ -412,6 +412,9 @@ Script interpreter. Works the same as ic3 but is not interactive.
## TODO
- libc3
+ - pretty printer
+ - indent
+ - 80 columns (`\n`)
- tags
- height function `(TAG_VOID: 0, TAG_TUPLE: (1+ (max (height tuple->tags))))`
- has_ident
diff --git a/ic3/.ic3_history b/ic3/.ic3_history
index 31d0774..af224cc 100644
--- a/ic3/.ic3_history
+++ b/ic3/.ic3_history
@@ -1,99 +1,99 @@
--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)
+dt(200)
+def dt = macro (x) do
+ quote do
+ x = unquote x
+def dt = macro (x) do
+ quote do
+ x = unquote(x)
+ {x, x}
+ end
+end
+dt(200)
+dt(a)
+a = [1, 2, 3]
+dt(a)
+def dt = macro (x) do
+ quote do
+ x = ^ unquote(x)
+ {x, x}
+ end
+end
+dt(a)
+1 + 10000000000000000000000000000000000000000000
+def beaucoup = 1 + 10000000000000000000000000000000000000000000
+type(beaucoup)
+def beaucoup = 1 + 10000000000000000000000000000000000000000000
+type(beaucoup)
+beaucoup
+def beaucoup = (U8) beaucoup
+type(beaucoup)
+beacoup
+beaucoup
+1 / 4
+(Ratio) 1 / 4
+(Ratio) 1 / 4 * 2
+1/4 * 2
+type(1/4)
+1/4 / 13/12
+1/4 / 13/12 * 2
+(Complex) 1
+1 +i 2
+type(1 +i 2)
+1 +i 2 +i 3
+(1 +i 2) * (2 +i 3)
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
+def dt = macro (x) do
+ quote do
+ x = ^ unquote(x)
+ {x, x}
+ end
+end
+dt(200)
+dt(200 * 200)
+dt(sqrt(-1))
+def double = fn (x) { x * 2 }
+double(200)
+double(beaucoup)
+def beaucoup = 1 + 10000000000000000000000000000000000000000000
+double(beaucoup)
+dt
+double(3/4)
+1 / double(3/4)
+a = b
+a = 1
+b = a
+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 }}
+do end
end
-defmodule Plop
-do
- 1 + 1
- 2 + 2
+do end
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
+do end
+defmodule Plop do end
+quote Plop
+quote_cfn Plop
diff --git a/lib/c3/0.1/c3.facts b/lib/c3/0.1/c3.facts
index 1909fb9..dddf44d 100644
--- a/lib/c3/0.1/c3.facts
+++ b/lib/c3/0.1/c3.facts
@@ -224,3 +224,7 @@ 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)}
+add {C3, :symbol, C3.quote_cfn}
+replace {C3.quote_cfn, :arity, 1}
+replace {C3.quote_cfn, :is_a, :special_operator}
+replace {C3.quote_cfn, :symbol_value, cfn Tag "c3_quote_cfn" (Sym, Result)}
diff --git a/lib/c3/0.1/sym.facts b/lib/c3/0.1/sym.facts
new file mode 100644
index 0000000..30ba24d
--- /dev/null
+++ b/lib/c3/0.1/sym.facts
@@ -0,0 +1,5 @@
+%{module: C3.Facts.Dump,
+ version: 1}
+replace {Sym, :is_a, :module}
+replace {Sym, :symbol, Sym.cast}
+replace {Sym.cast, :symbol_value, cfn Sym "sym_init_cast" (Result, Tag)}
diff --git a/libc3/buf_parse.c b/libc3/buf_parse.c
index 9d554f7..143ae19 100644
--- a/libc3/buf_parse.c
+++ b/libc3/buf_parse.c
@@ -418,6 +418,12 @@ sw buf_parse_block (s_buf *buf, s_block *block)
goto clean;
}
result += r;
+ if ((r = buf_parse_comments(buf)) < 0)
+ goto restore;
+ result += r;
+ if ((r = buf_ignore_spaces(buf)) < 0)
+ goto restore;
+ result += r;
if ((r = buf_parse_block_inner(buf, short_form, block)) <= 0)
goto restore;
result += r;
@@ -445,12 +451,15 @@ sw buf_parse_block_inner (s_buf *buf, bool short_form, s_block *block)
i = &list;
*i = NULL;
while (1) {
- if ((r = buf_parse_comments(buf)) < 0)
- goto restore;
- result += r;
- if ((r = buf_ignore_spaces(buf)) < 0)
- goto restore;
- result += r;
+ if (short_form) {
+ if ((r = buf_read_1(buf, "}")) < 0)
+ goto restore;
+ }
+ else
+ if ((r = buf_read_sym(buf, &g_sym_end)) < 0)
+ goto restore;
+ if (r > 0)
+ goto ok;
*i = list_new(NULL);
if ((r = buf_parse_tag(buf, &(*i)->tag)) <= 0)
goto restore;
@@ -461,10 +470,13 @@ sw buf_parse_block_inner (s_buf *buf, bool short_form, s_block *block)
if ((r = buf_ignore_spaces_but_newline(buf)) < 0)
goto restore;
result += r;
- if ((r = buf_read_sym(buf, &g_sym_end)) < 0)
- goto restore;
- if (! r && (r = buf_read_1(buf, "}")) < 0)
- goto restore;
+ if (short_form) {
+ if ((r = buf_read_1(buf, "}")) < 0)
+ goto restore;
+ }
+ else
+ if ((r = buf_read_sym(buf, &g_sym_end)) < 0)
+ goto restore;
if (r > 0)
goto ok;
if ((r = buf_read_1(buf, "\n")) < 0 ||
@@ -477,12 +489,6 @@ sw buf_parse_block_inner (s_buf *buf, bool short_form, s_block *block)
if ((r = buf_ignore_spaces(buf)) < 0)
goto restore;
result += r;
- if ((r = buf_read_sym(buf, &g_sym_end)) < 0)
- goto restore;
- if (! r && (r = buf_read_1(buf, "}")) < 0)
- goto restore;
- if (r > 0)
- goto ok;
i = &(*i)->next.data.list;
}
r = 0;
diff --git a/libc3/c3.c b/libc3/c3.c
index a051a17..0c1da99 100644
--- a/libc3/c3.c
+++ b/libc3/c3.c
@@ -76,6 +76,11 @@ uw * c3_facts_next_id (uw *dest)
return dest;
}
+s_tag * c3_quote_cfn (const s_sym *sym, s_tag *dest)
+{
+ return tag_init_sym(dest, sym);
+}
+
s_str * c3_getenv (const s_str *name, s_str *dest)
{
char *p;
diff --git a/libc3/env.c b/libc3/env.c
index 3f9af42..bb08fcd 100644
--- a/libc3/env.c
+++ b/libc3/env.c
@@ -110,16 +110,21 @@ s_tag * env_defmodule (s_env *env, const s_sym *name,
const s_block *block, s_tag *dest)
{
const s_sym *module;
+ s_tag *result = NULL;
+ s_tag tmp;
assert(env);
assert(name);
assert(block);
assert(dest);
module = env->current_module;
env->current_module = name;
- if (! env_eval_block(env, block, dest))
- dest = NULL;
+ if (env_eval_block(env, block, &tmp)) {
+ dest->type = TAG_SYM;
+ dest->data.sym = name;
+ result = dest;
+ }
env->current_module = module;
- return dest;
+ return result;
}
void env_error_f (s_env *env, const char *fmt, ...)
diff --git a/libc3/tag.c b/libc3/tag.c
index 0232347..f307717 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/defmodule.in b/test/ic3/defmodule.in
new file mode 100644
index 0000000..26ea9a4
--- /dev/null
+++ b/test/ic3/defmodule.in
@@ -0,0 +1,8 @@
+quote defmodule Empty do end
+defmodule Empty do end
+quote defmodule Double do
+ def double = fn (x) { x * 2 }
+end
+defmodule Double do
+ def double = fn (x) { x * 2 }
+end
diff --git a/test/ic3/defmodule.out.expected b/test/ic3/defmodule.out.expected
new file mode 100644
index 0000000..27ea00b
--- /dev/null
+++ b/test/ic3/defmodule.out.expected
@@ -0,0 +1,6 @@
+defmodule Empty do end
+Empty
+defmodule Double do
+ def double = fn (x) { x * 2 }
+end
+Double
diff --git a/test/ic3/defmodule.ret.expected b/test/ic3/defmodule.ret.expected
new file mode 100644
index 0000000..573541a
--- /dev/null
+++ b/test/ic3/defmodule.ret.expected
@@ -0,0 +1 @@
+0