diff options
author | Mattias Andrée <maandree@operamail.com> | 2014-12-05 08:47:22 +0100 |
---|---|---|
committer | Mattias Andrée <maandree@operamail.com> | 2014-12-05 08:47:22 +0100 |
commit | 0d6bd3bbae6b60a3f16d2a831f063cfd4cd1bdfe (patch) | |
tree | 6120d9c1e56f1b0cece7f88b85e5481854e3c3c9 | |
parent | mds-kbdc: m + include stack for macro and check for redefinitions of macros (diff) | |
download | mds-0d6bd3bbae6b60a3f16d2a831f063cfd4cd1bdfe.tar.gz mds-0d6bd3bbae6b60a3f16d2a831f063cfd4cd1bdfe.tar.bz2 mds-0d6bd3bbae6b60a3f16d2a831f063cfd4cd1bdfe.tar.xz |
mds-kbdc: misc
Signed-off-by: Mattias Andrée <maandree@operamail.com>
Diffstat (limited to '')
-rw-r--r-- | Makefile | 4 | ||||
-rw-r--r-- | src/mds-kbdc/builtin-functions.c | 336 | ||||
-rw-r--r-- | src/mds-kbdc/builtin-functions.h (renamed from src/mds-kbdc/functions.h) | 28 | ||||
-rw-r--r-- | src/mds-kbdc/compile-layout.c | 139 | ||||
-rw-r--r-- | src/mds-kbdc/functions.c | 293 |
5 files changed, 456 insertions, 344 deletions
@@ -30,8 +30,8 @@ OBJ_mds-server_ = mds-server interception-condition client multicast \ OBJ_mds-registry_ = mds-registry util globals reexec registry signals \ slave -OBJ_mds-kbdc_ = mds-kbdc globals raw-data functions string tree \ - make-tree parse-error simplify-tree parsed \ +OBJ_mds-kbdc_ = mds-kbdc globals raw-data builtin-functions string \ + tree make-tree parse-error simplify-tree parsed \ process-includes validate-tree eliminate-dead-code \ paths include-stack compile-layout diff --git a/src/mds-kbdc/builtin-functions.c b/src/mds-kbdc/builtin-functions.c new file mode 100644 index 0000000..cfac8ac --- /dev/null +++ b/src/mds-kbdc/builtin-functions.c @@ -0,0 +1,336 @@ +/** + * 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 "builtin-functions.h" + +#include <stdlib.h> +#include <string.h> + + + +/** + * Define useful data for built-in function with 2 parameters + */ +#define define_2 \ + const char32_t* restrict a = *args++; \ + const char32_t* restrict b = *args++; \ + size_t an = string_length(a); \ + size_t bn = string_length(b); \ + size_t i, n = an > bn ? an : bn; \ + char32_t* restrict rc = malloc((n + 1) * sizeof(char32_t)); \ + if (rc == NULL) \ + return NULL; \ + rc[n] = -1 + +/** + * Define useful data for built-in function with 1 parameter + */ +#define define_1 \ + const char32_t* restrict a = *args++; \ + size_t i, n = string_length(a); \ + char32_t* restrict rc = malloc((n + 1) * sizeof(char32_t)); \ + if (rc == NULL) \ + return NULL; \ + rc[n] = -1 + + +/** + * Definition of the built-in function add/2 + * + * @param args The arguments passed to the function + * @return The return value of the function, `NULL` on error + */ +static char32_t* builtin_function_add_2(const char32_t** restrict args) +{ + define_2; + for (i = 0; i < n; i++) + rc[i] = a[i % an] + b[i % bn]; + return rc; +} + + +/** + * Definition of the built-in function sub/2 + * + * @param args The arguments passed to the function + * @return The return value of the function, `NULL` on error + */ +static char32_t* builtin_function_sub_2(const char32_t** restrict args) +{ + define_2; + for (i = 0; i < n; i++) + rc[i] = a[i % an] - b[i % bn]; + return rc; +} + + +/** + * Definition of the built-in function mul/2 + * + * @param args The arguments passed to the function + * @return The return value of the function, `NULL` on error + */ +static char32_t* builtin_function_mul_2(const char32_t** restrict args) +{ + define_2; + for (i = 0; i < n; i++) + rc[i] = a[i % an] * b[i % bn]; + return rc; +} + + +/** + * Definition of the built-in function div/2 + * + * @param args The arguments passed to the function + * @return The return value of the function, `NULL` on error + */ +static char32_t* builtin_function_div_2(const char32_t** restrict args) +{ + define_2; + for (i = 0; i < n; i++) + rc[i] = a[i % an] / b[i % bn]; + return rc; +} + + +/** + * Definition of the built-in function mod/2 + * + * @param args The arguments passed to the function + * @return The return value of the function, `NULL` on error + */ +static char32_t* builtin_function_mod_2(const char32_t** restrict args) +{ + define_2; + for (i = 0; i < n; i++) + rc[i] = a[i % an] % b[i % bn]; + return rc; +} + + +/** + * Definition of the built-in function rsh/2 + * + * @param args The arguments passed to the function + * @return The return value of the function, `NULL` on error + */ +static char32_t* builtin_function_rsh_2(const char32_t** restrict args) +{ + define_2; + for (i = 0; i < n; i++) + rc[i] = a[i % an] << b[i % bn]; + return rc; +} + + +/** + * Definition of the built-in function lsh/2 + * + * @param args The arguments passed to the function + * @return The return value of the function, `NULL` on error + */ +static char32_t* builtin_function_lsh_2(const char32_t** restrict args) +{ + define_2; + for (i = 0; i < n; i++) + rc[i] = a[i % an] >> b[i % bn]; + return rc; +} + + +/** + * Definition of the built-in function or/2 + * + * @param args The arguments passed to the function + * @return The return value of the function, `NULL` on error + */ +static char32_t* builtin_function_or_2(const char32_t** restrict args) +{ + define_2; + for (i = 0; i < n; i++) + rc[i] = a[i % an] | b[i % bn]; + return rc; +} + + +/** + * Definition of the built-in function and/2 + * + * @param args The arguments passed to the function + * @return The return value of the function, `NULL` on error + */ +static char32_t* builtin_function_and_2(const char32_t** restrict args) +{ + define_2; + for (i = 0; i < n; i++) + rc[i] = a[i % an] & b[i % bn]; + return rc; +} + + +/** + * Definition of the built-in function xor/2 + * + * @param args The arguments passed to the function + * @return The return value of the function, `NULL` on error + */ +static char32_t* builtin_function_xor_2(const char32_t** restrict args) +{ + define_2; + for (i = 0; i < n; i++) + rc[i] = a[i % an] ^ b[i % bn]; + return rc; +} + + +/** + * Definition of the built-in function not/1 + * + * @param args The arguments passed to the function + * @return The return value of the function, `NULL` on error + */ +static char32_t* builtin_function_not_1(const char32_t** restrict args) +{ + define_1; + for (i = 0; i < n; i++) + rc[i] = !a[i]; + return rc; +} + + +/** + * Definition of the built-in function equals/2 + * + * @param args The arguments passed to the function + * @return The return value of the function, `NULL` on error + */ +static char32_t* builtin_function_equals_2(const char32_t** restrict args) +{ + define_2; + for (i = 0; i < n; i++) + rc[i] = a[i % an] == b[i % bn]; + return rc; +} + + +/** + * Definition of the built-in function greater/2 + * + * @param args The arguments passed to the function + * @return The return value of the function, `NULL` on error + */ +static char32_t* builtin_function_greater_2(const char32_t** restrict args) +{ + define_2; + for (i = 0; i < n; i++) + rc[i] = a[i % an] > b[i % bn]; + return rc; +} + + +/** + * Definition of the built-in function less/2 + * + * @param args The arguments passed to the function + * @return The return value of the function, `NULL` on error + */ +static char32_t* builtin_function_less_2(const char32_t** restrict args) +{ + define_2; + for (i = 0; i < n; i++) + rc[i] = a[i % an] < b[i % bn]; + return rc; +} + + +/* static char32_t* builtin_function_set_3(const char32_t** restrict args); (variable index value) */ +/* static char32_t* builtin_function_get_2(const char32_t** restrict args); (variable index) */ + + +#undef define_1 +#undef define_2 + + +/** + * Check whether a function is a builtin function + * + * @param name The name of the function + * @param arg_count The number of arguments to pass to the function + * @return Whether the described function is a builtin function + */ +int builtin_function_defined(const char* restrict name, size_t arg_count) +{ + size_t i; + static const char* const BUILTIN_FUNCTIONS_2[] = + { + "add", "sub", "mul", "div", "mod", "rsh", "lsh", "or", + "and", "xor", "equals", "greater", "less", "get", NULL + }; + + if (arg_count == 3) + return !strcmp(name, "set"); + else if (arg_count == 1) + return !strcmp(name, "not"); + else if (arg_count == 2) + for (i = 0; BUILTIN_FUNCTIONS_2[i]; i++) + if (!strcmp(name, BUILTIN_FUNCTIONS_2[i])) + return 1; + + return 0; +} + + +/** + * Invoke a builtin function + * + * @param name The name of the function + * @param arg_count The number of arguments to pass to the function + * @param args The arguments to pass + * @return The return value of the function, `NULL` on error + */ +char32_t* builtin_function_invoke(const char* restrict name, size_t arg_count, const char32_t** restrict args) +{ + if (arg_count == 3) + if (!strcmp(name, "set")) + return NULL; /* TODO builtin_function_set_3(args) */ + + if (arg_count == 1) + if (!strcmp(name, "not")) + return builtin_function_not_1(args); + + if (arg_count != 2) + return NULL; + + if (!strcmp(name, "add")) return builtin_function_add_2(args); + if (!strcmp(name, "sub")) return builtin_function_sub_2(args); + if (!strcmp(name, "mul")) return builtin_function_mul_2(args); + if (!strcmp(name, "div")) return builtin_function_div_2(args); + if (!strcmp(name, "mod")) return builtin_function_mod_2(args); + if (!strcmp(name, "rsh")) return builtin_function_rsh_2(args); + if (!strcmp(name, "lsh")) return builtin_function_lsh_2(args); + if (!strcmp(name, "or")) return builtin_function_or_2(args); + if (!strcmp(name, "and")) return builtin_function_and_2(args); + if (!strcmp(name, "xor")) return builtin_function_xor_2(args); + if (!strcmp(name, "equals")) return builtin_function_equals_2(args); + if (!strcmp(name, "greater")) return builtin_function_greater_2(args); + if (!strcmp(name, "less")) return builtin_function_less_2(args); + if (!strcmp(name, "get")) return NULL; /* TODO builtin_function_get_2(args) */ + + return NULL; +} + diff --git a/src/mds-kbdc/functions.h b/src/mds-kbdc/builtin-functions.h index 158c0b1..ebe3935 100644 --- a/src/mds-kbdc/functions.h +++ b/src/mds-kbdc/builtin-functions.h @@ -15,8 +15,8 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef MDS_MDS_KBDC_FUNCTIONS_H -#define MDS_MDS_KBDC_FUNCTIONS_H +#ifndef MDS_MDS_KBDC_BUILTIN_FUNCTIONS_H +#define MDS_MDS_KBDC_BUILTIN_FUNCTIONS_H #include "string.h" @@ -25,26 +25,26 @@ #include <stdarg.h> + /** - * Check whether a function is defined. + * Check whether a function is a builtin function * - * @param name The name of the function. - * @param arg_count The number of arguments to pass to the function. - * @return Whether the function is defined for the selected number of arguments. + * @param name The name of the function + * @param arg_count The number of arguments to pass to the function + * @return Whether the described function is a builtin function */ -int function_check_defined(const char32_t* restrict name, size_t arg_count) __attribute__((nonnull)); +int builtin_function_defined(const char* restrict name, size_t arg_count) __attribute__((pure)); /** - * Invoke a function defined in the keyboard layout source code, or that is builtin. + * Invoke a builtin function * - * @param name The name of the function. - * @param arg_count The number of arguments to pass to the function. - * @param ...:char32_t* The arguments to pass, do not end with a sentinel. - * @return The return value of the function, `NULL` on error. + * @param name The name of the function + * @param arg_count The number of arguments to pass to the function + * @param args The arguments to pass + * @return The return value of the function, `NULL` on error */ -char32_t* function_invoke(const char32_t* restrict name, size_t arg_count, ...) __attribute__((nonnull)); +char32_t* builtin_function_invoke(const char* restrict name, size_t arg_count, const char32_t** restrict args); -/* TODO define functions, check if function is built in */ #endif diff --git a/src/mds-kbdc/compile-layout.c b/src/mds-kbdc/compile-layout.c index d6df226..e677c23 100644 --- a/src/mds-kbdc/compile-layout.c +++ b/src/mds-kbdc/compile-layout.c @@ -19,6 +19,7 @@ /* TODO add call stack */ #include "include-stack.h" +#include "builtin-functions.h" #include "string.h" #include <stdlib.h> @@ -150,8 +151,15 @@ static int pop_stack(void) return 0; /* TODO */ } -static int get_macro_lax(const char* restrict macro_name, - const mds_kbdc_tree_macro_t** restrict macro, +static int set_macro(const mds_kbdc_tree_macro_t* restrict macro, + mds_kbdc_include_stack_t* macro_include_stack) +{ + (void) macro; + (void) macro_include_stack; + return 0; /* TODO */ +} + +static int get_macro_lax(const char* restrict macro_name, const mds_kbdc_tree_macro_t** restrict macro, mds_kbdc_include_stack_t** restrict macro_include_stack) { (void) macro_name; @@ -174,6 +182,7 @@ static int get_macro(const mds_kbdc_tree_macro_call_t* restrict macro_call, } + /** * Compile an include-statement * @@ -604,26 +613,11 @@ static int check_function_calls(const mds_kbdc_tree_t* restrict tree) t (check_function_calls(tree->if_.otherwise)); break; - case C(LET): - t (check_function_calls(tree->let.value)); - break; - - case C(ARRAY): - t (check_function_calls(tree->array.elements)); - break; - - case C(KEYS): - t (check_function_calls_in_keys(&(tree->keys))); - break; - - case C(STRING): - t (check_function_calls_in_string(&(tree->string))); - break; - - case C(MAP): - t (check_function_calls(tree->map.sequence)); - break; - + case C(LET): t (check_function_calls(tree->let.value)); break; + case C(ARRAY): t (check_function_calls(tree->array.elements)); break; + case C(KEYS): t (check_function_calls_in_keys(&(tree->keys))); break; + case C(STRING): t (check_function_calls_in_string(&(tree->string))); break; + case C(MAP): t (check_function_calls(tree->map.sequence)); break; default: break; } @@ -691,11 +685,37 @@ static int check_name_suffix(struct mds_kbdc_tree_callable* restrict tree) static int compile_function(mds_kbdc_tree_function_t* restrict tree) { #define t(expr) fail_if ((r = (expr), r < 0)); if (r) tree->processed = PROCESS_LEVEL - int r; + const mds_kbdc_tree_function_t* function; + mds_kbdc_include_stack_t* function_include_stack; + mds_kbdc_include_stack_t* our_include_stack = NULL; + char* suffixless; + char* suffix_start; + size_t arg_count; + int r, saved_errno; t (check_name_suffix((struct mds_kbdc_tree_callable*)tree)); - /* TODO check for redefinition */ + suffixless = strdup(tree->name); + fail_if (suffixless == NULL); + suffix_start = strchr(suffixless, '/'); + *suffix_start++ = '\0'; + arg_count = (size_t)atoll(suffix_start); + + if (builtin_function_defined(suffixless, arg_count)) + { + NEW_ERROR(tree, ERROR, "function ‘%s’ is already defined as a builtin function", tree->name); + return 0; + } + /* TODO check for redefinition */ function = NULL, function_include_stack = NULL; + if (function) + { + NEW_ERROR(tree, ERROR, "function ‘%s’ is already defined", tree->name); + fail_if (mds_kbdc_include_stack_restore(function_include_stack)); + NEW_ERROR(function, NOTE, "previously defined here"); + fail_if (mds_kbdc_include_stack_restore(our_include_stack)); + mds_kbdc_include_stack_free(our_include_stack); + return 0; + } t (check_marco_calls(tree->inner)); t (check_function_calls(tree->inner)); @@ -703,8 +723,9 @@ static int compile_function(mds_kbdc_tree_function_t* restrict tree) /* TODO add definition */ return 0; - pfail: - return -1; + FAIL_BEGIN; + mds_kbdc_include_stack_free(our_include_stack); + FAIL_END; #undef t } @@ -723,13 +744,14 @@ static int compile_macro(mds_kbdc_tree_macro_t* restrict tree) mds_kbdc_include_stack_t* our_include_stack = NULL; int r, saved_errno; + fail_if ((our_include_stack = mds_kbdc_include_stack_save(), our_include_stack == NULL)); + t (check_name_suffix((struct mds_kbdc_tree_callable*)tree)); t (get_macro_lax(tree->name, ¯o, ¯o_include_stack)); if (macro) { NEW_ERROR(tree, ERROR, "macro ‘%s’ is already defined", tree->name); - fail_if ((our_include_stack = mds_kbdc_include_stack_save(), our_include_stack == NULL)); fail_if (mds_kbdc_include_stack_restore(macro_include_stack)); NEW_ERROR(macro, NOTE, "previously defined here"); fail_if (mds_kbdc_include_stack_restore(our_include_stack)); @@ -740,7 +762,7 @@ static int compile_macro(mds_kbdc_tree_macro_t* restrict tree) t (check_marco_calls(tree->inner)); t (check_function_calls(tree->inner)); - /* TODO add definition */ + t (set_macro(tree, our_include_stack)); return 0; FAIL_BEGIN; @@ -967,6 +989,38 @@ static int compile_array(mds_kbdc_tree_array_t* restrict tree) /** + * Check that a chain of strings and key-combinations + * does not contain NULL characters + * + * @param tree The tree to check + * @return Zero on success, -1 on error, 1 if any of + * the elements contain a NULL character + */ +static int check_nonnul(mds_kbdc_tree_t* restrict tree) +{ + const char* restrict string; + int rc = 0; + again: + if (tree == NULL) + return rc; + + for (string = tree->string.string; *string; string++) + if ((string[0] == (char)0xC0) && (string[1] == (char)0x80)) + { + NEW_ERROR(tree, ERROR, "NULL characters are not allowed in mappings"); + tree->processed = PROCESS_LEVEL; + rc = 1; + break; + } + + tree = tree->next; + goto again; + pfail: + return -1; +} + + +/** * Compile a mapping- or value-statement * * @param tree The tree to compile @@ -980,17 +1034,32 @@ static int compile_map(mds_kbdc_tree_map_t* restrict tree) int saved_errno; fail_if ((seq = mds_kbdc_tree_dup(tree->sequence), seq = NULL)); - fail_if ((res = mds_kbdc_tree_dup(tree->result), res = NULL)); - fail_if ((bad |= evaluate_element(seq), bad < 0)); - fail_if ((bad |= evaluate_element(res), bad < 0)); - if (bad) - return 0; - /* TODO */ + if (tree->result) + { + fail_if ((res = mds_kbdc_tree_dup(tree->result), res = NULL)); + fail_if ((bad |= evaluate_element(res), bad < 0)); + } - /* NUL-characters (0xC0 0x80) is only allowed in value-statements */ + if (bad) + goto done; + if (tree->result) + { + fail_if ((bad |= check_nonnul(seq), bad < 0)); + fail_if ((bad |= check_nonnul(res), bad < 0)); + if (bad) + goto done; + + /* TODO */ + } + else + { + /* TODO */ + } + + done: mds_kbdc_tree_free(seq); mds_kbdc_tree_free(res); return 0; diff --git a/src/mds-kbdc/functions.c b/src/mds-kbdc/functions.c deleted file mode 100644 index 33fa70d..0000000 --- a/src/mds-kbdc/functions.c +++ /dev/null @@ -1,293 +0,0 @@ -/** - * 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 "functions.h" - -#include <stdlib.h> - - - -/** - * Define useful data for built-in function with 2 parameters. - */ -#define define_2 \ - const char32_t* restrict a = va_arg(args, const char32_t*); \ - const char32_t* restrict b = va_arg(args, const char32_t*); \ - size_t an = string_length(a); \ - size_t bn = string_length(b); \ - size_t i, n = an > bn ? an : bn; \ - char32_t* restrict rc = malloc((n + 1) * sizeof(char32_t)); \ - if (rc == NULL) \ - return NULL; \ - rc[n] = -1 - -/** - * Define useful data for built-in function with 1 parameter. - */ -#define define_1 \ - const char32_t* restrict a = va_arg(args, const char32_t*); \ - size_t i, n = string_length(a); \ - char32_t* restrict rc = malloc((n + 1) * sizeof(char32_t)); \ - if (rc == NULL) \ - return NULL; \ - rc[n] = -1 - - -/** - * Definition of the built-in function add/2. - * - * @param args The arguments passed to the function. - * @return The return value of the function, `NULL` on error. - */ -static char32_t* function_builtin_add_2(va_list args) -{ - define_2; - for (i = 0; i < n; i++) - rc[i] = a[i % an] + b[i % bn]; - return rc; -} - - -/** - * Definition of the built-in function sub/2. - * - * @param args The arguments passed to the function. - * @return The return value of the function, `NULL` on error. - */ -static char32_t* function_builtin_sub_2(va_list args) -{ - define_2; - for (i = 0; i < n; i++) - rc[i] = a[i % an] - b[i % bn]; - return rc; -} - - -/** - * Definition of the built-in function mul/2. - * - * @param args The arguments passed to the function. - * @return The return value of the function, `NULL` on error. - */ -static char32_t* function_builtin_mul_2(va_list args) -{ - define_2; - for (i = 0; i < n; i++) - rc[i] = a[i % an] * b[i % bn]; - return rc; -} - - -/** - * Definition of the built-in function div/2. - * - * @param args The arguments passed to the function. - * @return The return value of the function, `NULL` on error. - */ -static char32_t* function_builtin_div_2(va_list args) -{ - define_2; - for (i = 0; i < n; i++) - rc[i] = a[i % an] / b[i % bn]; - return rc; -} - - -/** - * Definition of the built-in function mod/2. - * - * @param args The arguments passed to the function. - * @return The return value of the function, `NULL` on error. - */ -static char32_t* function_builtin_mod_2(va_list args) -{ - define_2; - for (i = 0; i < n; i++) - rc[i] = a[i % an] % b[i % bn]; - return rc; -} - - -/** - * Definition of the built-in function rsh/2. - * - * @param args The arguments passed to the function. - * @return The return value of the function, `NULL` on error. - */ -static char32_t* function_builtin_rsh_2(va_list args) -{ - define_2; - for (i = 0; i < n; i++) - rc[i] = a[i % an] << b[i % bn]; - return rc; -} - - -/** - * Definition of the built-in function lsh/2. - * - * @param args The arguments passed to the function. - * @return The return value of the function, `NULL` on error. - */ -static char32_t* function_builtin_lsh_2(va_list args) -{ - define_2; - for (i = 0; i < n; i++) - rc[i] = a[i % an] >> b[i % bn]; - return rc; -} - - -/** - * Definition of the built-in function or/2. - * - * @param args The arguments passed to the function. - * @return The return value of the function, `NULL` on error. - */ -static char32_t* function_builtin_or_2(va_list args) -{ - define_2; - for (i = 0; i < n; i++) - rc[i] = a[i % an] | b[i % bn]; - return rc; -} - - -/** - * Definition of the built-in function and/2. - * - * @param args The arguments passed to the function. - * @return The return value of the function, `NULL` on error. - */ -static char32_t* function_builtin_and_2(va_list args) -{ - define_2; - for (i = 0; i < n; i++) - rc[i] = a[i % an] & b[i % bn]; - return rc; -} - - -/** - * Definition of the built-in function xor/2. - * - * @param args The arguments passed to the function. - * @return The return value of the function, `NULL` on error. - */ -static char32_t* function_builtin_xor_2(va_list args) -{ - define_2; - for (i = 0; i < n; i++) - rc[i] = a[i % an] ^ b[i % bn]; - return rc; -} - - -/** - * Definition of the built-in function not/1. - * - * @param args The arguments passed to the function. - * @return The return value of the function, `NULL` on error. - */ -static char32_t* function_builtin_not_1(va_list args) -{ - define_1; - for (i = 0; i < n; i++) - rc[i] = !a[i]; - return rc; -} - - -/** - * Definition of the built-in function equals/2. - * - * @param args The arguments passed to the function. - * @return The return value of the function, `NULL` on error. - */ -static char32_t* function_builtin_equals_2(va_list args) -{ - define_2; - for (i = 0; i < n; i++) - rc[i] = a[i % an] == b[i % bn]; - return rc; -} - - -/** - * Definition of the built-in function greater/2. - * - * @param args The arguments passed to the function. - * @return The return value of the function, `NULL` on error. - */ -static char32_t* function_builtin_greater_2(va_list args) -{ - define_2; - for (i = 0; i < n; i++) - rc[i] = a[i % an] > b[i % bn]; - return rc; -} - - -/** - * Definition of the built-in function less/2. - * - * @param args The arguments passed to the function. - * @return The return value of the function, `NULL` on error. - */ -static char32_t* function_builtin_less_2(va_list args) -{ - define_2; - for (i = 0; i < n; i++) - rc[i] = a[i % an] < b[i % bn]; - return rc; -} - - -/* static char32_t* function_builtin_set_3(va_list args); (variable index value) */ -/* static char32_t* function_builtin_get_2(va_list args); (variable index) */ - - -#undef define_1 -#undef define_2 - - -/** - * Check whether a function is defined. - * - * @param name The name of the function. - * @param arg_count The number of arguments to pass to the function. - * @return Whether the function is defined for the selected number of arguments. - */ -int function_check_defined(const char32_t* restrict name, size_t arg_count) -{ - return 0; /* TODO */ -} - - -/** - * Invoke a function defined in the keyboard layout source code, or that is builtin. - * - * @param name The name of the function. - * @param arg_count The number of arguments to pass to the function. - * @param ...:char32_t* The arguments to pass, do not end with a sentinel. - * @return The return value of the function, `NULL` on error. - */ -char32_t* function_invoke(const char32_t* restrict name, size_t arg_count, ...) -{ - return NULL; /* TODO */ -} - |