2#ifndef CEL_PARSER_LOOKUP_HPP
3#define CEL_PARSER_LOOKUP_HPP
6#include <cel/parser/diagnostic.hpp>
7#include <cel/runtime.hpp>
16#include <unordered_map>
28namespace parser_detail {
29enum class lookup_selector;
30enum class scope_selection;
42 std::function<bool(std::string_view, dyn_segment&, std::size_t,
source_span)>;
51namespace parser_detail {
54 using is_transparent = void;
57 std::size_t operator()(std::string_view name)
const noexcept {
58 return std::hash<std::string_view>{}(name);
82 friend struct parser_detail::lookup_access;
85 std::vector<value_type> inputs;
90 struct function_binding {
96 using names = std::unordered_map<std::string, T, parser_detail::name_hash, std::equal_to<>>;
97 names<value_type> types_;
98 names<std::vector<operation>> operations_;
99 names<std::vector<operation>> structural_;
100 names<std::vector<operation>> builtins_;
101 names<function_binding> functions_;
102 std::unordered_map<std::type_index, std::string> marker_names_;
103 std::vector<scope_callback> libraries_;
104 std::vector<scope_callback> scopes_;
109 static void insert(names<std::vector<operation>>& destination,
110 std::string_view name,
111 std::span<const value_type> inputs,
117 static bool emit_match(
const names<std::vector<operation>>& registrations,
118 std::string_view name,
119 dyn_segment& builder,
124 bool scope_match(std::string_view name,
125 dyn_segment& builder,
128 parser_detail::scope_selection selection)
const;
131 bool direct_match(std::string_view name,
132 dyn_segment& builder,
135 parser_detail::scope_selection selection)
const;
137 void install_builtins();
139 template <
class R,
class... A,
class F>
140 void builtin(std::string_view name, F&& callback) {
141 const std::array<value_type,
sizeof...(A)> inputs{native_type<A>()...};
142 insert(builtins_, name, inputs, native_type<R>(),
143 [callback = std::forward<F>(callback)](dyn_segment& builder,
source_span) {
144 builder.template op<R, A...>(callback);
149 void insert_type(std::string_view name, value_type type);
154 void insert_function(std::string_view name, value_type marker,
operation_emitter emit);
170 std::vector<scope_callback> isolate_scopes();
175 void restore_scopes(std::vector<scope_callback> saved);
190 void apply(std::string_view name,
191 dyn_segment& builder,
194 parser_detail::lookup_selector selector,
195 parser_detail::scope_selection selection)
const;
201 void apply_cast(std::string_view target, dyn_segment& builder,
source_span span)
const;
207 std::optional<value_type>
find_type(std::string_view name)
const;
229 if constexpr (!detail::native_leaf<T>) {
230 throw std::invalid_argument(
"named leaf registration requires an opaque leaf");
232 auto type = value_type::leaf<T>();
233 if (!type.compatible_with(native_type<T>()))
234 throw std::invalid_argument(
"named leaf registration requires an opaque leaf");
235 insert_type(name, std::move(type));
253 std::span<const value_type> inputs,
261 std::span<const value_type> inputs,
274 template <
class R,
class... A,
class F>
275 requires(!std::is_void_v<R> &&
requires(dyn_segment & b, F&& callback) {
276 b.template op<R, A...>(std::forward<F>(callback));
278 const std::array<value_type,
sizeof...(A)> inputs{native_type<A>()...};
279 auto owned = std::make_shared<const std::decay_t<F>>(std::forward<F>(callback));
281 [owned = std::move(owned)](dyn_segment& builder, source_span) {
282 builder.template op<R, A...>([owned](A&&... arguments) -> R {
283 return std::invoke(*owned, std::move(arguments)...);
297 using marker_type = std::decay_t<M>;
298 if constexpr (!detail::native_leaf<marker_type>) {
299 throw std::invalid_argument(
"function markers require an opaque leaf");
301 const auto type = value_type::leaf<marker_type>();
302 auto owned = value::from<marker_type>(std::forward<M>(marker));
303 if (!type.compatible_with(owned.type()))
304 throw std::invalid_argument(
"function markers require an opaque leaf");
305 insert_function(name, type,
306 [owned = std::move(owned)](dyn_segment& builder,
source_span) {
op_lookup(op_lookup &&) noexcept=default
Transfers owned registration and scope state.
void register_type(std::string_view name)
Registers an opaque trivially-copyable leaf under an owned nonempty name. Throws std::invalid_argumen...
Definition lookup.hpp:228
op_lookup & operator=(const op_lookup &)=delete
Disallows copy assignment of this registry.
std::optional< value_type > find_type(std::string_view name) const
Returns a retained descriptor for extension signatures, or nullopt for an unknown name....
void push_library_scope(scope_callback callback)
Owns a persistent LIFO library scope visible in independent closure bodies. Precondition: no transien...
void register_record(std::string_view name, std::span< const record_field > fields)
Registers an owned complete nominal record schema, never a guessed native layout. Throws invalid_argu...
op_lookup(const op_lookup &)=delete
Disallows copying this registry.
void register_structural_op(std::string_view name, std::span< const value_type > inputs, value_type result, operation_emitter emit)
Registers a lower-priority structural signature with complete recursive identities....
void register_op(std::string_view name, F &&callback)
Registers an owned const-invocable callback with exactly the declared result type....
Definition lookup.hpp:277
void register_function(std::string_view name, M &&marker)
Binds an ordinary name to its first owned trivially-copyable marker. Repeated installers may use anot...
Definition lookup.hpp:296
op_lookup()
Creates only core operators, casts, and the persistent full-range constructor. Standard-library funct...
void register_operation(std::string_view name, std::span< const value_type > inputs, value_type result, operation_emitter emit)
Registers one exact complete operation; a return type never distinguishes overloads....
std::function< void(dyn_segment &, source_span)> operation_emitter
Owns a checked emitter whose successful effect consumes its declared inputs and adds one result....
Definition lookup.hpp:48
std::function< bool(std::string_view, dyn_segment &, std::size_t, source_span)> scope_callback
Owns a copyable resolver called with a borrowed name, builder, operand count, and source span....
Definition lookup.hpp:41
Provides checked CEL compilation, extension libraries, and owned results.
Definition compiler.hpp:10
Identifies a half-open UTF-8 byte interval; begin never exceeds end. Example: source_span{0,...
Definition diagnostic.hpp:15