summaryrefslogtreecommitdiffstats
path: root/src/point.cpp
diff options
context:
space:
mode:
authors-ol <s-ol@users.noreply.github.com>2019-11-28 15:04:24 +0000
committers-ol <s-ol@users.noreply.github.com>2019-11-28 15:04:24 +0000
commit7d82e09523ddc023da8df7bb6a0504f10c26cb92 (patch)
tree4594d8fc710fcf5162fb7fc0640cee12edfb0720 /src/point.cpp
parentinitial prototype (diff)
downloadjanet-2geom-7d82e09523ddc023da8df7bb6a0504f10c26cb92.tar.gz
janet-2geom-7d82e09523ddc023da8df7bb6a0504f10c26cb92.zip
make compile as a janet module
Diffstat (limited to 'src/point.cpp')
-rw-r--r--src/point.cpp106
1 files changed, 106 insertions, 0 deletions
diff --git a/src/point.cpp b/src/point.cpp
new file mode 100644
index 0000000..70a4888
--- /dev/null
+++ b/src/point.cpp
@@ -0,0 +1,106 @@
+#include "point.h"
+
+#include <sstream>
+
+extern "C" Janet geom_point_get(void *p, Janet key);
+
+extern "C" void geom_point_tostring(void *p, JanetBuffer *buffer) {
+ std::stringstream stream;
+ stream << "<2geom/point " << *static_cast<Geom::Point *>(p) << ">";
+ janet_buffer_push_cstring(buffer, stream.str().c_str());
+}
+
+
+const JanetAbstractType geom_point_type = {
+ "2geom/point",
+ NULL,
+ NULL,
+ geom_point_get,
+ NULL,
+ NULL,
+ NULL,
+ geom_point_tostring
+};
+
+
+Janet janet_wrap_point(Geom::Point const &x) {
+ Geom::Point *box = (Geom::Point *)janet_abstract(&geom_point_type, sizeof(Geom::Point));
+ *box = (Geom::Point)x;
+ return janet_wrap_abstract(box);
+}
+
+
+Geom::Point janet_unwrap_point(Janet x) {
+ if (janet_checktype(x, JANET_ABSTRACT)) {
+ void *abst = janet_unwrap_abstract(x);
+ if (janet_abstract_type(abst) == &geom_point_type)
+ return *(Geom::Point *)abst;
+ }
+
+ janet_panic("not a point");
+ return Geom::Point();
+}
+
+
+extern "C" Janet cfun_geom_point_new(int32_t argc, Janet *argv) {
+ janet_fixarity(argc, 2);
+ double x = janet_getnumber(argv, 0);
+ double y = janet_getnumber(argv, 1);
+ return janet_wrap_point(Geom::Point(x, y));
+}
+
+const JanetReg it_cfuns[] = {
+ {
+ "point", cfun_geom_point_new,
+ "(geom/point x y)\n\nCreate a Point from x/y coordinate values."
+ },
+ {NULL, NULL, NULL}
+};
+
+
+#define OPMETHOD(name, oper) \
+static Janet cfun_geom_point_##name(int32_t argc, Janet *argv) { \
+ janet_arity(argc, 2, -1); \
+ Geom::Point *box = (Geom::Point *)janet_abstract(&geom_point_type, sizeof(Geom::Point)); \
+ *box = janet_unwrap_point(argv[0]); \
+ for (int i = 1; i < argc; i++) \
+ *box oper##= janet_unwrap_point(argv[i]); \
+ return janet_wrap_abstract(box); \
+} \
+ \
+static Janet cfun_geom_point_##name##_mut(int32_t argc, Janet *argv) { \
+ janet_arity(argc, 2, -1); \
+ Geom::Point *box = (Geom::Point *)janet_abstract(&geom_point_type, sizeof(Geom::Point)); \
+ for (int i = 1; i < argc; i++) \
+ *box oper##= janet_unwrap_point(argv[i]); \
+ return janet_wrap_abstract(box); \
+}
+
+OPMETHOD(add, +)
+OPMETHOD(sub, -)
+
+static JanetMethod geom_point_methods[] = {
+ {"+", cfun_geom_point_add},
+ {"-", cfun_geom_point_sub},
+ {NULL, NULL}
+};
+
+extern "C" Janet geom_point_get(void *p, Janet key) {
+ Geom::Point *box = (Geom::Point *)p;
+ if (!janet_checktype(key, JANET_KEYWORD))
+ janet_panicf("expected keyword, got %v", key);
+
+ uint8_t const *keystr = janet_unwrap_keyword(key);
+ if (janet_string_equal(keystr, janet_cstring("x"))) {
+ return janet_wrap_number(box->x());
+ } else if (janet_string_equal(keystr, janet_cstring("y"))) {
+ return janet_wrap_number(box->y());
+ } else {
+ return janet_getmethod(keystr, geom_point_methods);
+ }
+}
+
+extern "C" void janet_lib_geom_point(JanetTable *env) {
+ janet_cfuns(env, NULL, it_cfuns);
+ janet_register_abstract_type(&geom_point_type);
+}