summaryrefslogtreecommitdiff
path: root/src/runtime/swipl
diff options
context:
space:
mode:
authorkr.angelov <kr.angelov@gmail.com>2014-04-02 10:03:19 +0000
committerkr.angelov <kr.angelov@gmail.com>2014-04-02 10:03:19 +0000
commitb3ba3d3c1c12989d315a9ac3b6f7b7784e07f686 (patch)
treedc2771bede71e17c668a28a06f4676955736f53e /src/runtime/swipl
parentd4cbadb6addabd90813b1d8bc8947d5240f002dd (diff)
initial binding to Prolog for the C runtime
Diffstat (limited to 'src/runtime/swipl')
-rw-r--r--src/runtime/swipl/Makefile2
-rw-r--r--src/runtime/swipl/pgf.pl2
-rw-r--r--src/runtime/swipl/swipgf.c82
3 files changed, 86 insertions, 0 deletions
diff --git a/src/runtime/swipl/Makefile b/src/runtime/swipl/Makefile
new file mode 100644
index 000000000..929af540d
--- /dev/null
+++ b/src/runtime/swipl/Makefile
@@ -0,0 +1,2 @@
+all:
+ swipl-ld -cc-options,-std=c99 -lgu -lpgf -shared swipgf.c -o swipgf.so
diff --git a/src/runtime/swipl/pgf.pl b/src/runtime/swipl/pgf.pl
new file mode 100644
index 000000000..94b508365
--- /dev/null
+++ b/src/runtime/swipl/pgf.pl
@@ -0,0 +1,2 @@
+:- module(pgf, [ readPGF/2, language/3 ]).
+:- use_foreign_library(foreign('./swipgf.so')).
diff --git a/src/runtime/swipl/swipgf.c b/src/runtime/swipl/swipgf.c
new file mode 100644
index 000000000..39b683217
--- /dev/null
+++ b/src/runtime/swipl/swipgf.c
@@ -0,0 +1,82 @@
+#include <SWI-Prolog.h>
+#include <pgf/pgf.h>
+
+typedef struct {
+ GuPool* pool;
+ PgfPGF* pgf;
+} PlPGF;
+
+static PL_blob_t pgf_blob = {
+ PL_BLOB_MAGIC,
+ PL_BLOB_UNIQUE,
+ "PGF",
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+static foreign_t
+pl_readPGF(term_t a1, term_t a2)
+{
+ char *fpath;
+
+ if (!PL_get_atom_chars(a1, &fpath) )
+ PL_fail;
+
+ PlPGF pl_pgf;
+ pl_pgf.pool = gu_new_pool();
+
+ GuPool* tmp_pool = gu_local_pool();
+
+ // Create an exception frame that catches all errors.
+ GuExn* err = gu_new_exn(NULL, gu_kind(type), tmp_pool);
+
+ // Read the PGF grammar.
+ pl_pgf.pgf = pgf_read(fpath, pl_pgf.pool, err);
+ if (!gu_ok(err)) {
+ int res;
+ if (gu_exn_caught(err) == gu_type(GuErrno)) {
+ errno = *((GuErrno*) gu_exn_caught_data(err));
+ res = PL_existence_error("source_sink", a1);
+ } else {
+ res = PL_raise_exception(a1);
+ }
+ gu_pool_free(pl_pgf.pool);
+ gu_pool_free(tmp_pool);
+ return res;
+ }
+
+ gu_pool_free(tmp_pool);
+
+ if (!PL_unify_blob(a2, &pl_pgf, sizeof(pl_pgf), &pgf_blob)) {
+ gu_pool_free(pl_pgf.pool);
+ PL_fail;
+ }
+
+ PL_succeed;
+}
+
+static foreign_t
+pl_language(term_t a1, term_t a2, term_t a3, control_t handle)
+{
+ switch (PL_foreign_control(handle)) {
+ case PL_FIRST_CALL:
+ //ctxt = malloc(sizeof(struct context));
+ PL_retry_address(NULL/*ctxt*/);
+ case PL_REDO:
+ //ctxt = PL_foreign_context_address(handle);
+ PL_retry_address(NULL/*ctxt*/);
+ case PL_PRUNED:
+ //ctxt = PL_foreign_context_address(handle);
+ //free(ctxt);
+ PL_succeed;
+ }
+ PL_succeed;
+}
+
+install_t
+install_swipgf()
+{ PL_register_foreign("readPGF", 2, pl_readPGF, 0);
+ PL_register_foreign("language", 3, pl_language, PL_FA_NONDETERMINISTIC);
+}