diff --git a/.ikc3_history b/.ikc3_history
index 4364d90..2b46967 100644
--- a/.ikc3_history
+++ b/.ikc3_history
@@ -1,42 +1,3 @@
-defmodule Plop do def a = 1; def double = fn (x) { x * 2 } end
-Plop.a
-Plop.double
-Plop.double(21)
-def a = 1
-a
-def double = fn (x) { x * 2 }
-double(42)
-defmodule Tiyon do
- def a = 1
- def double = fn (x) { x * 2 }
- def double_tuple = macro (x) do {x, x} end
- def double_list = macro (x) do [x, x] end
-end
-Tiyon.a
-Tiyon.double(21)
-Tiyon.double_tuple(21)
-Tiyon.double_tuple(21 + 21)
-Tiyon.double_list(21 + 21)
-[42, x] = Tiyon.double_list(21 + 21)
-[42, x] = [42, 42]
-x
-Tiyon.double_list(21 + 21) = [42, y]
-def last = fn (x) do
- [y | _] = List.reverse(x)
- y
-end
-def last = fn (x) do
- [y | _] = List.reverse(x)
- y
-end
-def List.last = fn (x) do
- [y | _] = List.reverse(x)
- y
-end
-List.last([1, 2, 3, 4])
-def List.last = fn (x) do
- [y | z] = List.reverse(x)
- y
end
List.last([1, 2, 3, 4])
[x, y | z] = List.reverse([1, 2, 3])
@@ -97,4 +58,42 @@ x = %C3.Operator{sym: 1}
x = %C3.Operator{sym: (Sym) "1"}
x = %C3.Operator{sym: :1}
x = %KC3.Operator{sym: :1}
-
+s = Socket.listen("localhost", 8000)
+(s8) -128
+(S8) -128
+type(-128)
+type(-127)
+128*128
+128 * 128
+256 * 256 - 1
+type(256 * 256 - 1)
+type(-256 * 256 - 1)
+type(-256 * 256 + 1)
+-256 * 256 + 1
+type(-65536 * 65536 + 1)
+type(-65536 * 65536 - 1)
+type(-65536 * 65536 + 1)
+-256 * 256 + 1
+type(-256 * 256 + 1)
+type(-256 * 256 / 8 + 1)
+type(-256 * 256 / 2 + 1)
+type(-256 * 128 + 1)
+type(-256 * 128 + 2)
+type(-256 * 256 / 2 + 1)
+type(-128 * 128 / 2 + 1)
+type(-255 * 256 / 2 + 1)
+type(-255 * 256 + 1)
+-255 * 256 + 1
+-255 * 256
+-256 * 256 / 2
+-256 * 256 / 2 + 1
+type(-32767)
+type(-256 * 256 / 2 + 1)
+-32767
+type(-32767)
+(S16) -32767
+i = type(-32767)
+-32768 * 65536
+-32768 * 65536 + 1
+-2147483648 * 65536 * 65536 + 1
+q
diff --git a/kc3_http/socket.c b/kc3_http/socket.c
index 19e6ace..271c7ce 100644
--- a/kc3_http/socket.c
+++ b/kc3_http/socket.c
@@ -19,19 +19,43 @@
#include <libkc3/kc3.h>
#include "socket.h"
-void socket_clean (p_socket s)
+void socket_close (p_socket s)
{
assert(s);
close(*s);
*s = 0;
}
+p_socket socket_init_accept (p_socket s, p_socket listening)
+{
+ struct sockaddr *addr;
+ struct sockaddr_storage addr_storage = {0};
+ socklen_t addr_len;
+ sw e;
+ t_socket tmp;
+ assert(s);
+ assert(listening);
+ addr = (struct sockaddr *) &addr_storage;
+ addr_len = sizeof(addr_storage);
+ tmp = accept(*listening, addr, &addr_len);
+ if (tmp < 0) {
+ e = errno;
+ err_write_1("socket_init_accept: accept: ");
+ err_puts(strerror(e));
+ assert(! "socket_init_accept: accept");
+ return NULL;
+ }
+ *s = tmp;
+ return s;
+}
+
p_socket socket_init_listen (p_socket s, const s_str *host, u16 port)
{
- struct sockaddr *addr;
- struct sockaddr_in *addr_inet;
- struct sockaddr_in6 *addr_inet6;
- socklen_t addr_len;
+ struct sockaddr *addr;
+ struct sockaddr_in *addr_inet;
+ struct sockaddr_in6 *addr_inet6;
+ socklen_t addr_len;
+ struct sockaddr_storage addr_storage;
sw e;
struct hostent *hostent;
t_socket tmp;
@@ -44,13 +68,11 @@ p_socket socket_init_listen (p_socket s, const s_str *host, u16 port)
e = errno;
err_write_1("socket_init_listen: gethostbyname2: ");
err_puts(strerror(e));
- assert(!"socket_init_listen: gethostbyname2");
+ assert(! "socket_init_listen: gethostbyname2");
return NULL;
}
+ addr = (struct sockaddr *) &addr_storage;
addr_len = hostent->h_length;
- addr = alloc(addr_len);
- if (! addr)
- return NULL;
memcpy(addr, hostent->h_addr_list[0], addr_len);
switch (addr->sa_family) {
case AF_INET:
@@ -64,7 +86,6 @@ p_socket socket_init_listen (p_socket s, const s_str *host, u16 port)
default:
err_puts("socket_init_listen: unknown address family");
assert(! "socket_init_listen: unknown address family");
- free(addr);
return NULL;
}
tmp = socket(addr->sa_family, SOCK_STREAM, 0);
@@ -73,7 +94,6 @@ p_socket socket_init_listen (p_socket s, const s_str *host, u16 port)
err_write_1("socket_init_listen: socket: ");
err_puts(strerror(e));
assert(! "socket_init_listen: socket");
- free(addr);
return NULL;
}
if (bind(tmp, addr, addr_len) < 0) {
@@ -82,10 +102,8 @@ p_socket socket_init_listen (p_socket s, const s_str *host, u16 port)
err_puts(strerror(e));
assert(! "socket_init_listen: bind");
socket_clean(&tmp);
- free(addr);
return NULL;
}
- free(addr);
if (listen(tmp, SOMAXCONN) < 0) {
e = errno;
err_write_1("socket_init_listen: listen: ");
diff --git a/kc3_http/socket.h b/kc3_http/socket.h
index a0b4fc9..26a03fc 100644
--- a/kc3_http/socket.h
+++ b/kc3_http/socket.h
@@ -15,10 +15,11 @@
#include "types.h"
-/* Stack-allocation compatible functions, call socket_clean after
- use. */
-void socket_clean (p_socket s);
-p_socket socket_init_listen (p_socket s, const s_str *host, u16 port);
+/* Stack-allocation compatible functions. */
p_socket socket_init_accept (p_socket s, p_socket listening);
+p_socket socket_init_listen (p_socket s, const s_str *host, u16 port);
+
+/* Operators. */
+void socket_close (p_socket s);
#endif /* SOCKET_H */
diff --git a/lib/kc3/0.1/http.kc3 b/lib/kc3/0.1/http.kc3
new file mode 100644
index 0000000..042a51f
--- /dev/null
+++ b/lib/kc3/0.1/http.kc3
@@ -0,0 +1,13 @@
+defmodule Socket do
+
+ dlopen(__DIR__ + "http.so")
+
+ defstruct [fd: (S32) 0]
+
+ def accept = cfn Socket "socket_init_accept" (Result, Socket)
+
+ def close = cfn Void "socket_close" (Socket)
+
+ def listen = cfn Socket "socket_init_listen" (Result, Str, U16)
+
+end
diff --git a/lib/kc3/0.1/s16.kc3 b/lib/kc3/0.1/s16.kc3
new file mode 100644
index 0000000..93d15ab
--- /dev/null
+++ b/lib/kc3/0.1/s16.kc3
@@ -0,0 +1,5 @@
+defmodule S16 do
+
+ def cast = cfn S16 "s16_init_cast" (Result, Sym, Tag)
+
+end
diff --git a/lib/kc3/0.1/s32.facts b/lib/kc3/0.1/s32.facts
deleted file mode 100644
index c2e110f..0000000
--- a/lib/kc3/0.1/s32.facts
+++ /dev/null
@@ -1,5 +0,0 @@
-%{module: KC3.Facts.Dump,
- version: 1}
-replace {S32, :is_a, :module}
-replace {S32, :symbol, S32.cast}
-replace {S32.cast, :symbol_value, cfn S32 "s32_init_cast" (Result, Tag)}
diff --git a/lib/kc3/0.1/s32.kc3 b/lib/kc3/0.1/s32.kc3
new file mode 100644
index 0000000..2b66032
--- /dev/null
+++ b/lib/kc3/0.1/s32.kc3
@@ -0,0 +1,5 @@
+defmodule S32 do
+
+ def cast = cfn S32 "s32_init_cast" (Result, Sym, Tag)
+
+end
diff --git a/lib/kc3/0.1/s64.kc3 b/lib/kc3/0.1/s64.kc3
new file mode 100644
index 0000000..97f7a09
--- /dev/null
+++ b/lib/kc3/0.1/s64.kc3
@@ -0,0 +1,5 @@
+defmodule S64 do
+
+ def cast = cfn S64 "s64_init_cast" (Result, Sym, Tag)
+
+end
diff --git a/lib/kc3/0.1/s8.facts b/lib/kc3/0.1/s8.facts
deleted file mode 100644
index bb5b3cd..0000000
--- a/lib/kc3/0.1/s8.facts
+++ /dev/null
@@ -1,5 +0,0 @@
-%{module: KC3.Facts.Dump,
- version: 1}
-replace {S8, :is_a, :module}
-replace {S8, :symbol, S8.cast}
-replace {S8.cast, :symbol_value, cfn S8 "s8_init_cast" (Result, Tag)}
diff --git a/lib/kc3/0.1/s8.kc3 b/lib/kc3/0.1/s8.kc3
new file mode 100644
index 0000000..83b79f6
--- /dev/null
+++ b/lib/kc3/0.1/s8.kc3
@@ -0,0 +1,5 @@
+defmodule S8 do
+
+ def cast = cfn S8 "s8_init_cast" (Result, Sym, Tag)
+
+end
diff --git a/lib/kc3/0.1/socket.kc3 b/lib/kc3/0.1/socket.kc3
new file mode 100644
index 0000000..ad3a0c2
--- /dev/null
+++ b/lib/kc3/0.1/socket.kc3
@@ -0,0 +1,13 @@
+defmodule Socket do
+
+ defstruct [fd: (S32) -1]
+
+ dlopen(__DIR__ + "http.so")
+
+ def accept = cfn Socket "socket_init_accept" (Result, Socket)
+
+ def close = cfn Void "socket_close" (Socket)
+
+ def listen = cfn Socket "socket_init_listen" (Result, Str, U16)
+
+end
diff --git a/lib/kc3/0.1/sw.facts b/lib/kc3/0.1/sw.facts
deleted file mode 100644
index 986e73e..0000000
--- a/lib/kc3/0.1/sw.facts
+++ /dev/null
@@ -1,5 +0,0 @@
-%{module: KC3.Facts.Dump,
- version: 1}
-replace {Sw, :is_a, :module}
-replace {Sw, :symbol, Sw.cast}
-replace {Sw.cast, :symbol_value, cfn Sw "sw_init_cast" (Result, Tag)}
diff --git a/lib/kc3/0.1/sw.kc3 b/lib/kc3/0.1/sw.kc3
new file mode 100644
index 0000000..a880eb9
--- /dev/null
+++ b/lib/kc3/0.1/sw.kc3
@@ -0,0 +1,5 @@
+defmodule Sw do
+
+ def cast = cfn Sw "sw_init_cast" (Result, Sym, Tag)
+
+end
diff --git a/libkc3/cfn.c b/libkc3/cfn.c
index 17373b2..b3dfc7d 100644
--- a/libkc3/cfn.c
+++ b/libkc3/cfn.c
@@ -42,7 +42,9 @@ s_tag * cfn_apply (s_cfn *cfn, s_list *args, s_tag *dest)
num_args = list_length(args);
arity = cfn->arity - (cfn->arg_result ? 1 : 0);
if (arity != num_args) {
- err_write_1("cfn_apply: invalid number of arguments, expected ");
+ err_write_1("cfn_apply: ");
+ err_inspect_str(&cfn->name->str);
+ err_write_1(": invalid number of arguments, expected ");
err_inspect_u8(&arity);
err_write_1(", have ");
err_inspect_sw(&num_args);
diff --git a/libkc3/tag_add.c b/libkc3/tag_add.c
index 3b4b04a..5ab1cd0 100644
--- a/libkc3/tag_add.c
+++ b/libkc3/tag_add.c
@@ -675,8 +675,14 @@ s_tag * tag_add (const s_tag *a, const s_tag *b, s_tag *dest)
if (a->data.s32 < S32_MIN - b->data.s8 ||
a->data.s32 > S32_MAX - b->data.s8)
return tag_init_s64(dest, (s64) a->data.s32 + (s64) b->data.s8);
- else
+ else if (a->data.s32 < S16_MIN - b->data.s8 ||
+ a->data.s32 > S16_MAX - b->data.s8)
return tag_init_s32(dest, a->data.s32 + (s32) b->data.s8);
+ else if (a->data.s32 < S8_MIN - b->data.s8 ||
+ a->data.s32 > S8_MAX - b->data.s8)
+ return tag_init_s16(dest, a->data.s32 + (s32) b->data.s8);
+ else
+ return tag_init_s8(dest, a->data.s32 + (s32) b->data.s8);
case TAG_S16:
if (a->data.s32 < S32_MIN - b->data.s16 ||
a->data.s32 > S32_MAX - b->data.s16)
diff --git a/test/ikc3/cast.in b/test/ikc3/cast.in
index 3ddc0fe..786773f 100644
--- a/test/ikc3/cast.in
+++ b/test/ikc3/cast.in
@@ -1,3 +1,25 @@
+quote (S8) -1
+(S8) -1
+quote (S8) -127
+(S8) -127
+quote (S16) -127
+(S16) -127
+quote (S16) -128
+(S16) -128
+quote (S16) -32767
+(S16) -32767
+quote (S32) -32767
+(S32) -32767
+quote (S32) -32768
+(S32) -32768
+quote (S32) -2147483647
+(S32) -2147483647
+quote (S64) -2147483647
+(S64) -2147483647
+quote (S64) -2147483648
+(S64) -2147483648
+quote (S64) -9223372036854775807
+(S64) -9223372036854775807
quote (U8) 0
(U8) 0
quote (U8) 1
@@ -28,3 +50,7 @@ quote (Sym) "Abc"
(Sym) "Abc"
quote (Sym) "abc"
(Sym) "abc"
+quote (Str) Abc
+(Str) Abc
+quote (Str) :abc
+(Str) :abc
diff --git a/test/ikc3/cast.out.expected b/test/ikc3/cast.out.expected
index 175550b..6367734 100644
--- a/test/ikc3/cast.out.expected
+++ b/test/ikc3/cast.out.expected
@@ -1,3 +1,25 @@
+(S8) -1
+-1
+(S8) -127
+-127
+(S16) -127
+-127
+(S16) -128
+-128
+(S16) -32767
+-32767
+(S32) -32767
+-32767
+(S32) -32768
+-32768
+(S32) -2147483647
+-2147483647
+(S64) -2147483647
+-2147483647
+(S64) -2147483648
+-2147483648
+(S64) -9223372036854775807
+-9223372036854775807
(U8) 0
0
(U8) 1
@@ -28,3 +50,7 @@
Abc
(Sym) "abc"
:abc
+(Str) Abc
+"Abc"
+(Str) :abc
+"abc"
diff --git a/test/ikc3_test b/test/ikc3_test
index 564a79c..d2837c7 100755
--- a/test/ikc3_test
+++ b/test/ikc3_test
@@ -29,10 +29,10 @@ test_ok() {
}
if [ $# = 0 ]; then
- if [ "x${IKC3_TEST_TARGETS}" = "x" ]; then
+ if [ "x${IKC3_TEST}" = "x" ]; then
TARGETS="$(ls -1 *.in | sed -e 's/[.]in$//')"
else
- TARGETS="${IKC3_TEST_TARGETS}"
+ TARGETS="${IKC3_TEST}"
fi
else
TARGETS="$@"