diff --git a/.ikc3_history b/.ikc3_history
index b28e400..0c6d479 100644
--- a/.ikc3_history
+++ b/.ikc3_history
@@ -1,18 +1,3 @@
-points[1]
-points[2]
-"#{(F128) 0.0}"
-"#{(F128) 0.1}"
-List.map([1, 2, 3], fn (x) { x * 8 })
-1 + 1
-1 + 1000000000000000000000000000000000000000000000000000000000
-type(1 + 1000000000000000000000000000000000000000000000000)
-type(1 + 1)
-type(255)
-type(256)
-type(255 + 1)
-F128.pi
-F128.cos(2 * F128.pi)
-F128
type(F128)
:F128
type(:F128)
@@ -97,3 +82,18 @@ git log | grep jeremy
9 +i 2 + 3 +i 5
Parse.tag("%Time{}")
Parse.tag("%Time{tv_sec: 1, tv_nsec: 2}")
+is_integer?(123)
+is_integer?(:a)
+Metric.hit("/plop"
+)
+Metric.hit("/plop"
+)
+Metric.hit("/plop")
+Metric.get("/plop")
+Metric.hit("/plop")
+Metric.get("/plop")
+10 + 1
+Metric.get("/plop")
+Metric.get("/plop") + 1
+Metric.get("/plop")
+Metric.hit("/plop")
diff --git a/lib/kc3/0.1/kc3.facts b/lib/kc3/0.1/kc3.facts
index 60ec745..8717fe1 100644
--- a/lib/kc3/0.1/kc3.facts
+++ b/lib/kc3/0.1/kc3.facts
@@ -383,3 +383,7 @@ add {KC3, :symbol, KC3.getpid}
replace {KC3.getpid, :symbol_value, cfn Sw "kc3_getpid" ()}
add {KC3, :symbol, KC3.getppid}
replace {KC3.getppid, :symbol_value, cfn Sw "kc3_getppid" ()}
+add {KC3, :symbol, KC3.killpg}
+replace {KC3.killpg, :symbol_value, cfn Bool "kc3_killpg" (Sw, Sym)}
+add {KC3, :symbol, KC3.is_integer?}
+replace {KC3.is_integer?, :symbol_value, cfn Bool "tag_is_integer" (Tag)}
diff --git a/lib/kc3/0.1/metric.kc3 b/lib/kc3/0.1/metric.kc3
new file mode 100644
index 0000000..f324857
--- /dev/null
+++ b/lib/kc3/0.1/metric.kc3
@@ -0,0 +1,19 @@
+defmodule Metric do
+
+ def get = fn (key) {
+ count = Facts.first_with_tags(Config.db, key, :metric_hits, count = ?,
+ fn (x) { count })
+ if is_integer?(count) do
+ count
+ else
+ 0
+ end
+ }
+
+ def hit = fn (key) {
+ count = Metric.get(key) + 1
+ Facts.replace_tags(Config.db, key, :metric_hits, count)
+ count
+ }
+
+end
diff --git a/libkc3/kc3.c b/libkc3/kc3.c
index e079a76..c849abe 100644
--- a/libkc3/kc3.c
+++ b/libkc3/kc3.c
@@ -13,6 +13,7 @@
#include <dlfcn.h>
#include <errno.h>
#include <pthread.h>
+#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -459,6 +460,92 @@ s_tag * kc3_integer_reduce (s_tag *tag, s_tag *dest)
return dest;
}
+bool kc3_killpg (sw process_group, const s_sym * const *signal)
+{
+ sw e;
+ s32 sig = -1;
+ if (*signal == sym_1("SIGHUP"))
+ sig = SIGHUP;
+ else if (*signal == sym_1("SIGINT"))
+ sig = SIGINT;
+ else if (*signal == sym_1("SIGQUIT"))
+ sig = SIGQUIT;
+ else if (*signal == sym_1("SIGILL"))
+ sig = SIGILL;
+ else if (*signal == sym_1("SIGTRAP"))
+ sig = SIGTRAP;
+ else if (*signal == sym_1("SIGABRT"))
+ sig = SIGABRT;
+ else if (*signal == sym_1("SIGEMT"))
+ sig = SIGEMT;
+ else if (*signal == sym_1("SIGFPE"))
+ sig = SIGFPE;
+ else if (*signal == sym_1("SIGKILL"))
+ sig = SIGKILL;
+ else if (*signal == sym_1("SIGBUS"))
+ sig = SIGBUS;
+ else if (*signal == sym_1("SIGSEGV"))
+ sig = SIGSEGV;
+ else if (*signal == sym_1("SIGSYS"))
+ sig = SIGSYS;
+ else if (*signal == sym_1("SIGPIPE"))
+ sig = SIGPIPE;
+ else if (*signal == sym_1("SIGALRM"))
+ sig = SIGALRM;
+ else if (*signal == sym_1("SIGTERM"))
+ sig = SIGTERM;
+ else if (*signal == sym_1("SIGURG"))
+ sig = SIGURG;
+ else if (*signal == sym_1("SIGSTOP"))
+ sig = SIGSTOP;
+ else if (*signal == sym_1("SIGTSTP"))
+ sig = SIGTSTP;
+ else if (*signal == sym_1("SIGCONT"))
+ sig = SIGCONT;
+ else if (*signal == sym_1("SIGCHLD"))
+ sig = SIGCHLD;
+ else if (*signal == sym_1("SIGTTIN"))
+ sig = SIGTTIN;
+ else if (*signal == sym_1("SIGTTOU"))
+ sig = SIGTTOU;
+ else if (*signal == sym_1("SIGIO"))
+ sig = SIGIO;
+ else if (*signal == sym_1("SIGXCPU"))
+ sig = SIGXCPU;
+ else if (*signal == sym_1("SIGXFSZ"))
+ sig = SIGXFSZ;
+ else if (*signal == sym_1("SIGVTALRM"))
+ sig = SIGVTALRM;
+ else if (*signal == sym_1("SIGPROF"))
+ sig = SIGPROF;
+ else if (*signal == sym_1("SIGWINCH"))
+ sig = SIGWINCH;
+ else if (*signal == sym_1("SIGINFO"))
+ sig = SIGINFO;
+ else if (*signal == sym_1("SIGUSR1"))
+ sig = SIGUSR1;
+ else if (*signal == sym_1("SIGUSR2"))
+ sig = SIGUSR2;
+ else if (*signal == sym_1("SIGTHR"))
+ sig = SIGTHR;
+ else {
+ err_write_1("kc3_killpg: unknown signal: ");
+ err_inspect_sym(signal);
+ err_write_1("\n");
+ assert(! "kc3_killpg: unknown signal");
+ return false;
+ }
+ if (killpg(process_group, sig)) {
+ e = errno;
+ err_write_1("kc3_killpg: killpg: ");
+ err_write_1(strerror(e));
+ err_write_1("\n");
+ assert(! "kc3_killpg: killpg");
+ return false;
+ }
+ return true;
+}
+
s_tag * kc3_let (s_tag *vars, s_tag *tag, s_tag *dest)
{
return env_let(g_kc3_env, vars, tag, dest);
diff --git a/libkc3/kc3_main.h b/libkc3/kc3_main.h
index d2ba40e..06a6d09 100644
--- a/libkc3/kc3_main.h
+++ b/libkc3/kc3_main.h
@@ -110,6 +110,7 @@ s_tag * kc3_facts_with_tags (s_facts *facts, s_tag *subject,
p_callable *callback, s_tag *dest);
s_tag * kc3_identity (s_tag *tag, s_tag *dest);
s_tag * kc3_integer_reduce (s_tag *tag, s_tag *dest);
+bool kc3_killpg (sw process_group, const s_sym * const *signal);
s_tag * kc3_let (s_tag *vars, s_tag *tag, s_tag *dest);
s_array * kc3_list_to_array (s_list **list,
const s_sym * const *array_type,
diff --git a/libkc3/tag.c b/libkc3/tag.c
index 7f719c9..fc79f1b 100644
--- a/libkc3/tag.c
+++ b/libkc3/tag.c
@@ -829,6 +829,61 @@ bool tag_is_cast (const s_tag *tag, const s_sym *type)
tag->data.call.ident.sym == &g_sym_cast);
}
+bool tag_is_integer (s_tag *tag)
+{
+ assert(tag);
+ tag = tag_resolve_cow(tag);
+ switch (tag->type) {
+ case TAG_VOID:
+ case TAG_ARRAY:
+ case TAG_BLOCK:
+ case TAG_BOOL:
+ case TAG_CALL:
+ case TAG_CALLABLE:
+ case TAG_CHARACTER:
+ case TAG_COMPLEX:
+ case TAG_F32:
+ case TAG_F64:
+ case TAG_F128:
+ case TAG_FACT:
+ case TAG_LIST:
+ case TAG_MAP:
+ case TAG_PTAG:
+ case TAG_PTR:
+ case TAG_PTR_FREE:
+ case TAG_QUOTE:
+ case TAG_RATIO:
+ case TAG_STR:
+ case TAG_STRUCT:
+ case TAG_STRUCT_TYPE:
+ case TAG_SYM:
+ case TAG_TIME:
+ case TAG_TUPLE:
+ case TAG_UNQUOTE:
+ case TAG_VAR:
+ case TAG_IDENT:
+ return false;
+ case TAG_INTEGER:
+ case TAG_SW:
+ case TAG_S64:
+ case TAG_S32:
+ case TAG_S16:
+ case TAG_S8:
+ case TAG_U8:
+ case TAG_U16:
+ case TAG_U32:
+ case TAG_U64:
+ case TAG_UW:
+ return true;
+ case TAG_COW:
+ break;
+ }
+ err_puts("tag_is_integer: invalid tag type");
+ assert(! "tag_is_integer: invalid tag type");
+ abort();
+ return false;
+}
+
bool tag_is_number (s_tag *tag)
{
assert(tag);
diff --git a/libkc3/tag.h b/libkc3/tag.h
index 046acdb..dc4c3bc 100644
--- a/libkc3/tag.h
+++ b/libkc3/tag.h
@@ -50,6 +50,7 @@ bool tag_ident_is_bound (const s_tag *tag);
bool tag_is_alist (const s_tag *tag);
bool tag_is_bound_var (const s_tag *tag);
bool tag_is_cast (const s_tag *tag, const s_sym *type);
+bool tag_is_integer (s_tag *tag);
bool tag_is_struct (const s_tag *tag, const s_sym *module);
bool * tag_is_unbound_var (const s_tag *tag, bool *dest);
bool tag_is_zero(const s_tag *tag);