Add now() built-in function

This commit introduces the `now()` built-in function, which returns the
current timestamp in milliseconds. It also includes an integration test
to ensure that `now()` is not constant-folded during AST dumping,
verifying its non-deterministic nature.
This commit is contained in:
Michael Schimmel
2026-02-22 08:44:49 +01:00
parent f35606616b
commit 589c13896f
2 changed files with 31 additions and 0 deletions
+10
View File
@@ -27,4 +27,14 @@ pub fn register(env: &Environment) {
}
Value::Void
});
let now_ty = StaticType::Function(Box::new(Signature {
params: StaticType::Tuple(vec![]),
ret: StaticType::DateTime,
}));
env.register_native("now", now_ty, Purity::SideEffectFree, |_| {
let ts = chrono::Utc::now().timestamp_millis();
Value::DateTime(ts)
});
}
+21
View File
@@ -169,6 +169,27 @@ mod tests {
assert_eq!(format!("{}", env.run_script("NaN").unwrap()), "NaN");
}
#[test]
fn test_now_function_not_folded() {
let env = Environment::new();
let source = "(now)";
// 1. Check result type and value plausibility
let result = env.run_script(source).expect("Failed to run script");
if let Value::DateTime(ts) = result {
let current = chrono::Utc::now().timestamp_millis();
assert!(ts > 0);
assert!(ts <= current);
} else {
panic!("Expected DateTime, got {:?}", result);
}
// 2. Verify it's NOT constant folded in the AST dump
let dump = env.dump_ast(source).expect("Failed to dump AST");
assert!(dump.contains("Call"), "now() should remain a Call, not a Constant. Dump: \n{}", dump);
assert!(!dump.contains("Constant: #"), "now() should NOT be folded into a specific timestamp constant. Dump: \n{}", dump);
}
#[test]
fn test_date_parsing() {
let env = Environment::new();