oxdock_parser/constants.rs
1//! Language-level constants: the module separator, system module names,
2//! and reserved keywords.
3//!
4//! Single source of truth shared by the grammar lowerer (`parser.rs`), the
5//! macro token walker (`macro_input.rs`), and the runtime registry
6//! (`oxdock-core`). Changing any of these must update exactly one
7//! definition here; `dsl.pest` carries the same spellings by necessity (a
8//! grammar file cannot reference Rust constants) and the bidirectional
9//! keyword conformance test locks the two together.
10
11/// Separator between module and function name (`STD::GLOB`).
12pub const MODULE_SEPARATOR: &str = "::";
13
14/// Module holding the compiled-in builtins.
15pub const STD_MODULE_NAME: &str = "STD";
16
17/// Module holding in-script `FUNC` definitions.
18pub const SCRIPT_MODULE_NAME: &str = "SCRIPT";
19
20/// Bare-word statement starters parsed by PEG rules rather than command
21/// lowering. Each is referenced by [`crate::STRUCTURAL_KEYWORDS`]; spelling
22/// lives here exactly once.
23pub const KEYWORD_LET: &str = "LET";
24pub const KEYWORD_FOR: &str = "FOR";
25pub const KEYWORD_IF: &str = "IF";
26pub const KEYWORD_ELSE: &str = "ELSE";
27pub const KEYWORD_ASYNC: &str = "ASYNC";
28pub const KEYWORD_AWAIT: &str = "AWAIT";
29pub const KEYWORD_CANCEL: &str = "CANCEL";
30pub const KEYWORD_FUNC: &str = "FUNC";
31pub const KEYWORD_RETURN: &str = "RETURN";
32pub const KEYWORD_WHILE: &str = "WHILE";
33pub const KEYWORD_BREAK: &str = "BREAK";
34pub const KEYWORD_CONTINUE: &str = "CONTINUE";
35
36/// Variable inspection: a dedicated AST node, never a registry entry, so it
37/// needs no import and accepts no qualifier.
38pub const KEYWORD_INSPECT: &str = "INSPECT";
39
40/// Bare-call scope directive (a lowering directive, not a runtime step).
41pub const KEYWORD_IMPORT: &str = "IMPORT";
42
43/// Reserved for future script-module support; rejected at lowering.
44pub const KEYWORD_EXPORT: &str = "EXPORT";
45
46/// Canonical qualified form: `MODULE::BASE`.
47pub fn qualify(module: &str, base: &str) -> String {
48 format!("{module}{MODULE_SEPARATOR}{base}")
49}
50
51/// Split `MODULE::BASE` into its parts; `None` for bare names.
52pub fn split_qualified(name: &str) -> Option<(&str, &str)> {
53 name.split_once(MODULE_SEPARATOR)
54}
55
56/// Base of `MODULE::BASE`, or the name itself when bare. Used for
57/// human-facing step errors; listings (`FUNCTIONS()`, `DESCRIBE`) keep the
58/// qualified form.
59pub fn base_name(qualified: &str) -> &str {
60 split_qualified(qualified)
61 .map(|(_, base)| base)
62 .unwrap_or(qualified)
63}