aboutsummaryrefslogtreecommitdiffstats
path: root/src/mds-kbdc/compile-layout.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/mds-kbdc/compile-layout.c158
1 files changed, 158 insertions, 0 deletions
diff --git a/src/mds-kbdc/compile-layout.c b/src/mds-kbdc/compile-layout.c
new file mode 100644
index 0000000..84893a4
--- /dev/null
+++ b/src/mds-kbdc/compile-layout.c
@@ -0,0 +1,158 @@
+/**
+ * mds — A micro-display server
+ * Copyright © 2014 Mattias Andrée (maandree@member.fsf.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "compile-layout.h"
+
+#include "include-stack.h"
+
+
+
+/**
+ * Tree type constant shortener
+ */
+#define C(TYPE) MDS_KBDC_TREE_TYPE_##TYPE
+
+/**
+ * Add an error with “included from here”-notes to the error list
+ *
+ * @param NODE:const mds_kbdc_tree_t* The node the triggered the error
+ * @param PTR:size_t The number of “included from here”-notes
+ * @param SEVERITY:identifier * in `MDS_KBDC_PARSE_ERROR_*` to indicate severity
+ * @param ...:const char*, ... Error description format string and arguments
+ * @scope error:mds_kbdc_parse_error_t* Variable where the new error will be stored
+ */
+#define NEW_ERROR(NODE, PTR, SEVERITY, ...) \
+ NEW_ERROR_WITH_INCLUDES(NODE, PTR, SEVERITY, __VA_ARGS__)
+
+
+
+/**
+ * Variable whether the latest created error is stored
+ */
+static mds_kbdc_parse_error_t* error;
+
+/**
+ * The parameter of `compile_layout`
+ */
+static mds_kbdc_parsed_t* restrict result;
+
+
+
+/**
+ * Compile a subtree
+ *
+ * @param tree The tree to compile
+ * @return Zero on success, -1 on error
+ */
+static int compile_subtree(mds_kbdc_tree_t* restrict tree);
+
+
+
+/**
+ * Compile an include-statement
+ *
+ * @param tree The tree to compile
+ * @return Zero on success, -1 on error
+ */
+static int compile_include(mds_kbdc_tree_include_t* restrict tree)
+{
+ void* data;
+ int r;
+ if (mds_kbdc_include_stack_push(tree, &data))
+ return -1;
+ r = compile_subtree(tree->inner);
+ mds_kbdc_include_stack_pop(data);
+ return r;
+}
+
+
+/**
+ * Compile a subtree
+ *
+ * @param tree The tree to compile
+ * @return Zero on success, -1 on error
+ */
+static int compile_subtree(mds_kbdc_tree_t* restrict tree)
+{
+#define t(expr) if (r = (expr), r < 0) return r
+#define c(type) t (compile_##type(&(tree->type)))
+#define c_(type) t (compile_##type(&(tree->type##_)))
+ int r;
+ again:
+ if (tree == NULL)
+ return 0;
+
+ switch (tree->type)
+ {
+ case C(INFORMATION):
+ t (compile_subtree(tree->information.inner));
+ break;
+ case C(INFORMATION_LANGUAGE): break;
+ case C(INFORMATION_COUNTRY): break;
+ case C(INFORMATION_VARIANT): break;
+ case C(INCLUDE):
+ c(include);
+ break;
+ case C(FUNCTION): break;
+ case C(MACRO): break;
+ case C(ASSUMPTION):
+ t ((includes_ptr == 0) && compile_subtree(tree->assumption.inner));
+ break;
+ case C(ASSUMPTION_HAVE): break;
+ case C(ASSUMPTION_HAVE_CHARS): break;
+ case C(ASSUMPTION_HAVE_RANGE): break;
+ case C(FOR): break;
+ case C(IF): break;
+ case C(LET): break;
+ case C(MAP): break;
+ case C(MACRO_CALL): break;
+ case C(RETURN): break;
+ case C(BREAK): break;
+ case C(CONTINUE): break;
+ default:
+ break;
+ }
+
+ tree = tree->next;
+ goto again;
+ pfail:
+ return -1;
+#undef c_
+#undef c
+#undef t
+}
+
+
+/**
+ * Compile the layout code
+ *
+ * @param result_ `result` from `eliminate_dead_code`, will be updated
+ * @return -1 if an error occursed that cannot be stored in `result`, zero otherwise
+ */
+int compile_layout(mds_kbdc_parsed_t* restrict result_)
+{
+ int r;
+ mds_kbdc_include_stack_begin(result = result_);
+ r = compile_subtree(result_->tree);
+ return mds_kbdc_include_stack_end(), r;
+}
+
+
+
+#undef NEW_ERROR
+#undef C
+