Initial Dever 0.0.1
This commit is contained in:
commit
81233d098c
1479 files changed
+163782
No files matched your search
@@ -0,0 +1,95 @@
|
||||
use dever::{
|
||||
compiler::{build, check, model::Program},
|
||||
syntax::{diagnostic::Diagnostic, source::Source},
|
||||
};
|
||||
|
||||
fn linked(text: &str) -> Result<Program, Diagnostic> {
|
||||
let inputs = [
|
||||
("main", text),
|
||||
("dever.time", include_str!("../../../lib/dever/time.dever")),
|
||||
(
|
||||
"dever.time",
|
||||
include_str!("../../../lib/dever/time/calendar.dever"),
|
||||
),
|
||||
(
|
||||
"dever.time",
|
||||
include_str!("../../../lib/dever/time/operations.dever"),
|
||||
),
|
||||
(
|
||||
"dever.time",
|
||||
include_str!("../../../lib/dever/time/clock.dever"),
|
||||
),
|
||||
];
|
||||
let modules = inputs
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(index, (_, text))| {
|
||||
dever::syntax::parse(&Source::new(
|
||||
index,
|
||||
if index == 0 {
|
||||
"main.dever".into()
|
||||
} else {
|
||||
format!("library{index}.dever")
|
||||
},
|
||||
(*text).into(),
|
||||
))
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
check::check(
|
||||
modules,
|
||||
&inputs
|
||||
.iter()
|
||||
.map(|(package, _)| (*package).into())
|
||||
.collect::<Vec<_>>(),
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn calendar_types_are_distinct_and_only_clock_reads_have_effects() {
|
||||
let program = linked("main() (answer: Text) pure { instant = dever.time.parseDatetime(\"1970-01-01T00:00:00Z\")\n answer = dever.time.formatDatetime(dever.time.add(instant, dever.time.duration(1))) }").unwrap();
|
||||
let main = program
|
||||
.functions
|
||||
.iter()
|
||||
.position(|function| function.signature.name == "main")
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
program.functions[main].signature.effects,
|
||||
Default::default()
|
||||
);
|
||||
assert_eq!(
|
||||
build::runtime_features(&program, &program.reachable([main])),
|
||||
["calendar"]
|
||||
);
|
||||
let clocks = linked("main() (value: Int) { value = dever.time.unixMillis() }").unwrap();
|
||||
let main = clocks
|
||||
.functions
|
||||
.iter()
|
||||
.position(|function| function.signature.name == "main")
|
||||
.unwrap();
|
||||
assert!(clocks.functions[main].signature.effects.clock);
|
||||
assert!(!clocks.functions[main].signature.effects.timer);
|
||||
assert!(!clocks.functions[main].signature.effects.suspend);
|
||||
assert!(build::runtime_features(&clocks, &clocks.reachable([main])).is_empty());
|
||||
for (source, code) in [
|
||||
("main() (value: DateTime) { value = 0 }", "C005"),
|
||||
(
|
||||
"main(value: DateTime) (answer: DateTime) { answer = dever.time.add(value, 1) }",
|
||||
"C005",
|
||||
),
|
||||
(
|
||||
"main(value: DateTime) (answer: Bool) { answer = value < value }",
|
||||
"C005",
|
||||
),
|
||||
(
|
||||
"main() (value: DateTime) pure { value = dever.time.now() }",
|
||||
"C013",
|
||||
),
|
||||
("main() () { value = dever.system.timeDuration(1) }", "C006"),
|
||||
(
|
||||
"main() () { lost = result(dever.time.parseDate(\"bad\")) }",
|
||||
"C012",
|
||||
),
|
||||
] {
|
||||
assert_eq!(linked(source).unwrap_err().code, code, "{source}");
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user