Skip to main content

patch_prolog_frontend/parser/
operators.rs

1//! Operator table DATA — token → operator-name mappings grouped by ISO
2//! precedence level, kept separate from the precedence-climbing logic in
3//! [`super::term`].
4//!
5//! This is deliberately pure data (plus trivial lookups over it) so the M2
6//! runtime's minimal goal parser can share the same table without dragging in
7//! the full parser. Each `&str` here is the atom name the operator interns to.
8
9use crate::tokenizer::TokenKind;
10
11/// Precedence-700 non-associative operators (`is`, `=`, comparisons, term
12/// ordering). Maps a fixed-kind token to its operator atom name. The
13/// "word" operators that arrive as `Atom(..)` tokens (`@<`, `=..`, ...) are
14/// handled by [`word_op_700`].
15pub fn op_700(kind: &TokenKind) -> Option<&'static str> {
16    Some(match kind {
17        TokenKind::Is => "is",
18        TokenKind::Equals => "=",
19        TokenKind::NotEquals => "\\=",
20        TokenKind::Lt => "<",
21        TokenKind::Gt => ">",
22        TokenKind::Lte => "=<",
23        TokenKind::Gte => ">=",
24        TokenKind::ArithEq => "=:=",
25        TokenKind::ArithNeq => "=\\=",
26        TokenKind::TermEq => "==",
27        TokenKind::TermNeq => "\\==",
28        _ => return None,
29    })
30}
31
32/// Precedence-700 operators that the tokenizer emits as bare atoms
33/// (`@<`, `@>`, `@=<`, `@>=`, `=..`). Returns the canonical name when `s`
34/// is one of them.
35pub fn word_op_700(s: &str) -> Option<&'static str> {
36    match s {
37        "@<" => Some("@<"),
38        "@>" => Some("@>"),
39        "@=<" => Some("@=<"),
40        "@>=" => Some("@>="),
41        "=.." => Some("=.."),
42        _ => None,
43    }
44}
45
46/// Precedence-500 left-associative (`yfx`) operators: `+ - /\ \/ xor`.
47pub fn op_500(kind: &TokenKind) -> Option<&'static str> {
48    Some(match kind {
49        TokenKind::Plus => "+",
50        TokenKind::Minus => "-",
51        TokenKind::BitAnd => "/\\",
52        TokenKind::BitOr => "\\/",
53        TokenKind::Xor => "xor",
54        _ => return None,
55    })
56}
57
58/// Precedence-400 left-associative (`yfx`) operators:
59/// `* / // mod rem div << >>`.
60pub fn op_400(kind: &TokenKind) -> Option<&'static str> {
61    Some(match kind {
62        TokenKind::Star => "*",
63        TokenKind::Slash => "/",
64        TokenKind::IntDiv => "//",
65        TokenKind::Mod => "mod",
66        TokenKind::Rem => "rem",
67        TokenKind::Div => "div",
68        TokenKind::ShiftLeft => "<<",
69        TokenKind::ShiftRight => ">>",
70        _ => return None,
71    })
72}
73
74/// Operator name for an operator token appearing in *atom* position
75/// (issue #19): `p(+)`, `[<, >]`, `X = (mod)`, `=..` round-trips, etc.
76/// This is the superset of all infix/prefix operator spellings.
77pub fn op_as_atom(kind: &TokenKind) -> Option<&'static str> {
78    Some(match kind {
79        TokenKind::Plus => "+",
80        TokenKind::Minus => "-",
81        TokenKind::Star => "*",
82        TokenKind::Slash => "/",
83        TokenKind::IntDiv => "//",
84        TokenKind::Lt => "<",
85        TokenKind::Gt => ">",
86        TokenKind::Lte => "=<",
87        TokenKind::Gte => ">=",
88        TokenKind::Equals => "=",
89        TokenKind::NotEquals => "\\=",
90        TokenKind::TermEq => "==",
91        TokenKind::TermNeq => "\\==",
92        TokenKind::ArithEq => "=:=",
93        TokenKind::ArithNeq => "=\\=",
94        TokenKind::Is => "is",
95        TokenKind::Mod => "mod",
96        TokenKind::Rem => "rem",
97        TokenKind::Not => "\\+",
98        TokenKind::Backslash => "\\",
99        TokenKind::Arrow => "->",
100        TokenKind::Semicolon => ";",
101        TokenKind::Pow => "**",
102        TokenKind::Caret => "^",
103        TokenKind::Colon => ":",
104        TokenKind::ShiftLeft => "<<",
105        TokenKind::ShiftRight => ">>",
106        TokenKind::Div => "div",
107        TokenKind::BitAnd => "/\\",
108        TokenKind::BitOr => "\\/",
109        TokenKind::Xor => "xor",
110        _ => return None,
111    })
112}