summaryrefslogtreecommitdiff
path: root/src/helper.c
diff options
context:
space:
mode:
authorJSDurand <mmemmew@gmail.com>2023-07-08 12:30:21 +0800
committerJSDurand <mmemmew@gmail.com>2023-07-08 12:31:13 +0800
commit9a317e56f8a6126583f7d0c431bf878d9b1fe7b1 (patch)
tree7bb6004196b38446a5ab0cb3a0ab642d35f113e9 /src/helper.c
parent691f969eb104fa3d4c2a1667693fd0382eb9d6b5 (diff)
Finished the Emacs binding.
Now the binding part is finished. What remains is a bug encountered when planting a fragment to the forest which intersects a packed node, which would lead to invalid forests. This will also cause problem when planting a packed fragment, but until now my testing grammars do not produce packed fragments, so this problem is not encountered yet. I am still figuring out efficient ways to solve this problem.
Diffstat (limited to 'src/helper.c')
-rw-r--r--src/helper.c73
1 files changed, 73 insertions, 0 deletions
diff --git a/src/helper.c b/src/helper.c
new file mode 100644
index 0000000..5d7e9f8
--- /dev/null
+++ b/src/helper.c
@@ -0,0 +1,73 @@
+#include "helper.h"
+
+struct Label
+read_label(unsigned char *ptr)
+{
+ struct Label label = { 0 };
+
+ switch (*ptr) {
+ case Plain:
+ label.status = Plain;
+ break;
+ case Packed:
+ label.status = Packed;
+ break;
+ default:
+ label.status = Clone;
+ label.clone_index = from_big_endian(ptr+1);
+ break;
+ }
+
+ label.start = from_big_endian(ptr+9);
+ label.end = from_big_endian(ptr+17);
+
+ switch (*(ptr+25)) {
+ case Terminal:
+ label.variant = Terminal;
+ break;
+ case Nonterminal:
+ label.variant = Nonterminal;
+ break;
+ default:
+ label.variant = Rule;
+ break;
+ }
+
+ label.content = from_big_endian(ptr+26);
+
+ return label;
+}
+
+void
+print_label(struct Label label)
+{
+ switch (label.status) {
+ case Plain:
+ printf("a plain node ");
+ break;
+ case Packed:
+ printf("a packed node ");
+ break;
+ default:
+ printf("a cloned node with index %llu ", label.clone_index);
+ break;
+ }
+
+ printf("spanning (%llu, %llu) ", label.start, label.end);
+
+ printf("labelled as a ");
+
+ switch (label.variant) {
+ case Terminal:
+ printf("terminal ");
+ break;
+ case Nonterminal:
+ printf("non-terminal ");
+ break;
+ default:
+ printf("rule ");
+ break;
+ }
+
+ printf("%llu\n", label.content);
+}