summaryrefslogtreecommitdiff
path: root/source/luametatex/source/utilities/auxsparsearray.h
diff options
context:
space:
mode:
Diffstat (limited to 'source/luametatex/source/utilities/auxsparsearray.h')
-rw-r--r--source/luametatex/source/utilities/auxsparsearray.h212
1 files changed, 212 insertions, 0 deletions
diff --git a/source/luametatex/source/utilities/auxsparsearray.h b/source/luametatex/source/utilities/auxsparsearray.h
new file mode 100644
index 000000000..0a4ce20f1
--- /dev/null
+++ b/source/luametatex/source/utilities/auxsparsearray.h
@@ -0,0 +1,212 @@
+/*
+ See license.txt in the root of this project.
+*/
+
+# ifndef LMT_UTILITIES_SPARSEARRAY_H
+# define LMT_UTILITIES_SPARSEARRAY_H
+
+/*tex
+
+ This file originally was called |managed-sa| but becauss it kind of a library and also used in
+ \LUATEX\ it's better to use a different name. In this variant dumping is more sparse (resulting
+ in somewhat smaller format files). This might be backported but only after testing it here for a
+ long time. Of course the principles are the same, it's just extended.
+
+*/
+
+/*tex
+
+ The next two sets of three had better match up exactly, but using bare numbers is easier on the
+ \CCODE\ compiler. Here are some format sizes (for ConTeXt) with different values:
+
+ 64 : 17562942
+ 128 : 17548150 <= best value
+ 256 : 17681398
+
+*/
+
+# define LMT_SA_HIGHPART 128
+# define LMT_SA_MIDPART 128
+# define LMT_SA_LOWPART 128
+
+# define LMT_SA_H_PART(a) (((a)>>14)&127)
+# define LMT_SA_M_PART(a) (((a)>> 7)&127)
+# define LMT_SA_L_PART(a) ( (a) &127)
+
+/*tex
+
+ In the early days of \LUATEX\ we had just simple items, all 32 bit values. Then we put the
+ delcodes in trees too which saved memory and format size but it introduced 32 bit slack in all
+ the other code arrays. We then also had to dump selectively, but it was no big deal. Eventually,
+ once it became clear that the concepts would not change a variant was made for \LUAMETATEX: we
+ just use a two times larger lower array when we have delimiters. This saves some memory. The
+ price we pay is that a stack entry now has two values but that is not really an issue.
+
+ By packing the math code values we loose the option to store an active state but that's no big
+ deal.
+
+ todo: consider simple char array for catcodes.
+
+ The code here is somewhat messy because we generalized it a bit. Maybe I'll redo it some day.
+
+ */
+
+typedef struct sparse_state_info {
+ memory_data sparse_data;
+} sparse_state_info;
+
+extern sparse_state_info lmt_sparse_state;
+
+/*
+typedef struct sa_mathblob {
+ unsigned int character_value:21;
+ unsigned int class_value:3;
+ unsigned int family_value:8;
+} sa_mathblob;
+*/
+
+typedef struct sa_mathblob {
+ unsigned int class_value:math_class_bits;
+ unsigned int family_value:math_family_bits;
+ unsigned int character_value:math_character_bits;
+} sa_mathblob;
+
+typedef struct sa_mathspec {
+ unsigned short properties;
+ unsigned short group;
+ unsigned int index;
+} sa_mathspec;
+
+typedef struct packed_math_character {
+ union {
+ sa_mathblob sa_value;
+ unsigned ui_value;
+ };
+} packed_math_character;
+
+typedef union sa_tree_item {
+ unsigned int uint_value;
+ int int_value;
+ sa_mathblob math_code_value;
+ sa_mathspec math_spec_value;
+ unsigned short ushort_value[2];
+ unsigned char uchar_value[4];
+} sa_tree_item;
+
+typedef struct sa_stack_item {
+ int code;
+ int level;
+ sa_tree_item value_1;
+ sa_tree_item value_2;
+} sa_stack_item;
+
+typedef struct sa_tree_head {
+ int sa_stack_size; /*tex initial stack size */
+ int sa_stack_step; /*tex increment stack step */
+ int sa_stack_ptr; /*tex current stack point */
+ sa_tree_item dflt; /*tex default item value */
+ sa_tree_item ***tree; /*tex item tree head */
+ sa_stack_item *stack; /*tex stack tree head */
+ int bytes; /*tex the number of items per entry */
+ int padding;
+} sa_tree_head;
+
+typedef sa_tree_head *sa_tree;
+
+extern int sa_get_item_1 (const sa_tree head, int n);
+extern int sa_get_item_2 (const sa_tree head, int n);
+extern sa_tree_item sa_get_item_4 (const sa_tree head, int n);
+extern sa_tree_item sa_get_item_8 (const sa_tree head, int n, sa_tree_item * v2);
+extern void sa_set_item_1 (sa_tree head, int n, int v, int gl);
+extern void sa_set_item_2 (sa_tree head, int n, int v, int gl);
+extern void sa_set_item_4 (sa_tree head, int n, sa_tree_item v, int gl);
+extern void sa_set_item_8 (sa_tree head, int n, sa_tree_item v1, sa_tree_item v2, int gl);
+/* void sa_rawset_item_1 (sa_tree head, int n, sa_tree_item v); */
+/* void sa_rawset_item_2 (sa_tree head, int n, sa_tree_item v); */
+/* void sa_rawset_item_4 (sa_tree head, int n, sa_tree_item v); */
+/* void sa_rawset_item_8 (sa_tree head, int n, sa_tree_item v1, sa_tree_item v2); */
+extern sa_tree sa_new_tree (int size, int bytes, sa_tree_item dflt);
+extern sa_tree sa_copy_tree (sa_tree head);
+extern void sa_destroy_tree (sa_tree head);
+extern void sa_dump_tree (dumpstream f, sa_tree a);
+extern sa_tree sa_undump_tree (dumpstream f);
+extern void sa_restore_stack (sa_tree a, int gl);
+extern void sa_clear_stack (sa_tree a);
+
+extern void sa_set_item_n (const sa_tree head, int n, int v, int gl);
+extern int sa_get_item_n (const sa_tree head, int n);
+
+inline static halfword sa_return_item_1(sa_tree head, halfword n)
+{
+ if (head->tree) {
+ int hp = LMT_SA_H_PART(n);
+ if (head->tree[hp]) {
+ int mp = LMT_SA_M_PART(n);
+ if (head->tree[hp][mp]) {
+ return (halfword) head->tree[hp][mp][LMT_SA_L_PART(n)/4].uchar_value[n%4];
+ }
+ }
+ }
+ return (halfword) head->dflt.uchar_value[0];
+}
+
+inline static halfword sa_return_item_2(sa_tree head, halfword n)
+{
+ if (head->tree) {
+ int hp = LMT_SA_H_PART(n);
+ if (head->tree[hp]) {
+ int mp = LMT_SA_M_PART(n);
+ if (head->tree[hp][mp]) {
+ return (halfword) head->tree[hp][mp][LMT_SA_L_PART(n)/2].ushort_value[n%2];
+ }
+ }
+ }
+ return (halfword) head->dflt.ushort_value[0];
+}
+
+inline static halfword sa_return_item_4(sa_tree head, halfword n)
+{
+ if (head->tree) {
+ int hp = LMT_SA_H_PART(n);
+ if (head->tree[hp]) {
+ int mp = LMT_SA_M_PART(n);
+ if (head->tree[hp][mp]) {
+ return (halfword) head->tree[hp][mp][LMT_SA_L_PART(n)].int_value;
+ }
+ }
+ }
+ return (halfword) head->dflt.int_value;
+}
+
+inline static void sa_rawset_item_1(sa_tree head, halfword n, unsigned char v)
+{
+ head->tree[LMT_SA_H_PART(n)][LMT_SA_M_PART(n)][LMT_SA_L_PART(n)/4].uchar_value[n%4] = v;
+}
+
+inline static void sa_rawset_item_2(sa_tree head, halfword n, unsigned short v)
+{
+ head->tree[LMT_SA_H_PART(n)][LMT_SA_M_PART(n)][LMT_SA_L_PART(n)/2].ushort_value[n%2] = v;
+}
+
+inline static void sa_rawset_item_4(sa_tree head, halfword n, sa_tree_item v)
+{
+ head->tree[LMT_SA_H_PART(n)][LMT_SA_M_PART(n)][LMT_SA_L_PART(n)] = v;
+}
+
+inline static void sa_rawset_item_8(sa_tree head, halfword n, sa_tree_item v1, sa_tree_item v2)
+{
+ sa_tree_item *low = head->tree[LMT_SA_H_PART(n)][LMT_SA_M_PART(n)];
+ int l = 2*LMT_SA_L_PART(n);
+ low[l] = v1;
+ low[l+1] = v2;
+}
+
+// inline them
+
+extern void *sa_malloc_array (int recordsize, int size);
+extern void *sa_realloc_array (void *p, int recordsize, int size, int step);
+extern void *sa_calloc_array (int recordsize, int size);
+extern void *sa_free_array (void *p);
+extern void sa_wipe_array (void *head, int recordsize, int size);
+
+# endif