Update series syntax and binder scope handling

Refine the BNF for `series` to explicitly include the `lookback_limit`
and `schema`.
Introduce scope management within the `bind` function for `if/else`
branches to ensure correct context handling during compilation.
Add `Again` and `GetField` node kinds to the `Specializer`.
Improve lexer to ignore invisible characters within identifiers,
demonstrated by a new test case.
This commit is contained in:
2026-03-26 16:04:45 +01:00
parent 6d0882dd4a
commit 903c77a665
4 changed files with 38 additions and 1 deletions
+5
View File
@@ -243,11 +243,16 @@ impl Binder {
else_br,
} => {
let cond = self.bind(cond.as_ref(), ExprContext::Expression, diag);
self.functions.last_mut().unwrap().push_scope();
let then_br = self.bind(then_br.as_ref(), ctx, diag);
self.functions.last_mut().unwrap().pop_scope();
let mut else_br_bound = None;
if let Some(e) = else_br {
self.functions.last_mut().unwrap().push_scope();
else_br_bound = Some(Rc::new(self.bind(e, ctx, diag)));
self.functions.last_mut().unwrap().pop_scope();
}
self.make_node(
+8
View File
@@ -143,6 +143,14 @@ impl Specializer {
node.ty.clone(),
)
}
NodeKind::Again { args } => {
let args = Rc::new(self.visit_node(args.as_ref().clone()));
(NodeKind::Again { args }, node.ty.clone())
}
NodeKind::GetField { rec, field } => {
let rec = Rc::new(self.visit_node(rec.as_ref().clone()));
(NodeKind::GetField { rec, field }, node.ty.clone())
}
k => (k, node.ty.clone()),
};
+23
View File
@@ -235,6 +235,11 @@ impl<'a> Lexer<'a> {
{
let mut s = String::new();
while let Some(&c) = self.peek() {
if is_invisible(c) {
self.input.next();
self.col += 1;
continue;
}
if predicate(c) {
s.push(self.input.next().unwrap());
self.col += 1;
@@ -296,3 +301,21 @@ fn is_invisible(c: char) -> bool {
_ => false,
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_lex_invisible_chars() {
// U+200B Zero Width Space should be ignored inside identifiers
let source = "ab";
let mut lexer = Lexer::new(source);
let token = lexer.next_token().unwrap();
if let TokenKind::Identifier(id) = token.kind {
assert_eq!(id.as_ref(), "ab");
} else {
panic!("Expected identifier, got {:?}", token.kind);
}
}
}