Update examples to use StreamNode and Series with lookback

The `PipelineNode` has been refactored into `StreamNode`. This commit
updates the example files to reflect this change and also updates the
`series` constructor to accept a lookback parameter.

The `PipelineNode` was an artifact of a previous implementation and is
no longer needed. The `StreamNode` is the appropriate type for
representing the output of a pipe operation.

The `series` function now requires a `lookback` argument to specify the
maximum number of items to store. This makes the behavior of series more
explicit and prevents accidental unbounded memory growth.
This commit is contained in:
Michael Schimmel
2026-03-07 23:48:09 +01:00
parent d08fab4f73
commit 595bcf09e5
15 changed files with 108 additions and 233 deletions
+1 -12
View File
@@ -387,9 +387,6 @@ impl VM {
} else if let Some(sn) = obj.as_any().downcast_ref::<crate::ast::rtl::streams::StreamNode>() {
let mapped = crate::ast::rtl::streams::build_map_stream(sn.inner.clone(), *field);
return Ok(Value::Object(Rc::new(mapped)));
} else if let Some(pn) = obj.as_any().downcast_ref::<crate::ast::rtl::streams::PipelineNode>() {
let mapped = crate::ast::rtl::streams::build_map_stream(pn.stream.clone(), *field);
return Ok(Value::Object(Rc::new(mapped)));
}
// Fallback if it's another type of object that is not a RecordSeries.
@@ -431,7 +428,7 @@ impl VM {
lambda,
out_type,
} => {
use crate::ast::rtl::streams::{PipelineNode, StreamNode};
use crate::ast::rtl::streams::StreamNode;
let mut obs_streams = Vec::new();
for input in inputs {
@@ -439,8 +436,6 @@ impl VM {
if let Value::Object(obj) = val {
if let Some(s) = obj.as_any().downcast_ref::<StreamNode>() {
obs_streams.push(s.inner.clone());
} else if let Some(p) = obj.as_any().downcast_ref::<PipelineNode>() {
obs_streams.push(p.stream.clone());
} else {
return Err(format!(
"Pipe input must be a stream, found {}",
@@ -565,9 +560,6 @@ impl VM {
} else if let Some(sn) = obj.as_any().downcast_ref::<crate::ast::rtl::streams::StreamNode>() {
let mapped = crate::ast::rtl::streams::build_map_stream(sn.inner.clone(), k);
return Ok(Value::Object(Rc::new(mapped)));
} else if let Some(pn) = obj.as_any().downcast_ref::<crate::ast::rtl::streams::PipelineNode>() {
let mapped = crate::ast::rtl::streams::build_map_stream(pn.stream.clone(), k);
return Ok(Value::Object(Rc::new(mapped)));
}
return Err(format!(
"Field accessor .{} expects a record, RecordSeries or Stream, got {}",
@@ -637,9 +629,6 @@ impl VM {
} else if let Some(sn) = obj.as_any().downcast_ref::<crate::ast::rtl::streams::StreamNode>() {
let mapped = crate::ast::rtl::streams::build_map_stream(sn.inner.clone(), *k);
Ok(Value::Object(Rc::new(mapped)))
} else if let Some(pn) = obj.as_any().downcast_ref::<crate::ast::rtl::streams::PipelineNode>() {
let mapped = crate::ast::rtl::streams::build_map_stream(pn.stream.clone(), *k);
Ok(Value::Object(Rc::new(mapped)))
} else {
Err(format!(
"Field accessor .{} expects a record, RecordSeries or Stream, got {}",