aboutsummaryrefslogtreecommitdiff
path: root/environment.c
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2024-08-19 13:23:02 -0400
committerBruce Hill <bruce@bruce-hill.com>2024-08-19 13:23:02 -0400
commit4e732a718dc57f3c06af5ca9e43e4744b87ba72d (patch)
tree878cce5dfcb2a7c53df0dcbafdac2727ed29c052 /environment.c
parent3ddaf9250586db0cf0d3e40106c836bb7ec33add (diff)
Restructure things so that DSL constructors do proper escaping
Diffstat (limited to 'environment.c')
-rw-r--r--environment.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/environment.c b/environment.c
index 4345770d..250e3153 100644
--- a/environment.c
+++ b/environment.c
@@ -531,6 +531,27 @@ binding_t *get_namespace_binding(env_t *env, ast_t *self, const char *name)
return NULL;
}
+binding_t *get_lang_escape_function(env_t *env, const char *lang_name, type_t *type_to_escape)
+{
+ binding_t *typeinfo = get_binding(env, lang_name);
+ assert(typeinfo && typeinfo->type->tag == TypeInfoType);
+ env_t *lang_env = Match(typeinfo->type, TypeInfoType)->env;
+ for (int64_t i = 1; i <= Table$length(*lang_env->locals); i++) {
+ struct {const char *name; binding_t *b; } *entry = Table$entry(*lang_env->locals, i);
+ if (entry->b->type->tag != FunctionType) continue;
+ if (!(streq(entry->name, "escape") || strncmp(entry->name, "escape_", strlen("escape_")) == 0))
+ continue;
+ auto fn = Match(entry->b->type, FunctionType);
+ if (!fn->args || fn->args->next) continue;
+ if (fn->ret->tag != TextType || !streq(Match(fn->ret, TextType)->lang, lang_name))
+ continue;
+ if (!can_promote(type_to_escape, fn->args->type))
+ continue;
+ return entry->b;
+ }
+ return NULL;
+}
+
void set_binding(env_t *env, const char *name, binding_t *binding)
{
if (name && binding)