elenchus_compiler/
data.rs1use crate::error::CompileError;
3use crate::ir::PortBinding;
4use crate::resolver::parse_tagged;
5use alloc::string::{String, ToString};
6use alloc::vec::Vec;
7use elenchus_parser::Statement;
8
9pub fn read_data_source(file: &str, src: &str) -> Result<Vec<(String, bool)>, CompileError> {
14 let program = parse_tagged(file, src)?;
15 let mut out = Vec::new();
16 for stmt in &program.statements {
17 match stmt {
18 Statement::Provide { atom, value } => {
19 let a = &atom.data;
23 let mut key = String::new();
24 if let Some(d) = a.domain {
25 key.push_str(d);
26 key.push('.');
27 }
28 key.push_str(a.subject);
29 if let Some(p) = a.predicate {
30 key.push(' ');
31 key.push_str(p);
32 }
33 if let Some(o) = a.object {
34 key.push(' ');
35 key.push_str(o);
36 }
37 out.push((key, *value));
38 }
39 Statement::Domain(_) => {}
40 other => {
41 return Err(CompileError::DataFileStatement {
42 file: file.to_string(),
43 line: statement_line(other),
44 });
45 }
46 }
47 }
48 Ok(out)
49}
50
51pub fn read_data_bindings(
56 file: &str,
57 src: &str,
58) -> Result<Vec<(String, PortBinding)>, CompileError> {
59 Ok(read_data_source(file, src)?
60 .into_iter()
61 .map(|(name, value)| {
62 (
63 name,
64 PortBinding {
65 value,
66 origin: alloc::format!("data:{file}"),
67 },
68 )
69 })
70 .collect())
71}
72
73fn statement_line(s: &Statement) -> u32 {
75 match s {
76 Statement::Domain(n) => n.span.location_line(),
77 Statement::Import { path, .. } => path.span.location_line(),
78 Statement::Fact(a) | Statement::Negation(a) => a.span.location_line(),
79 Statement::Assume(l) => l.span.location_line(),
80 Statement::Set { name, .. } => name.span.location_line(),
81 Statement::Close { relation, .. } => relation.span.location_line(),
82 Statement::Var { name, .. } => name.span.location_line(),
83 Statement::Provide { atom, .. } => atom.span.location_line(),
84 Statement::Premise { name, .. } | Statement::Rule { name, .. } => name.span.location_line(),
85 Statement::Check { subject, .. } => subject
86 .as_ref()
87 .map(|s| s.span.location_line())
88 .unwrap_or(0),
89 }
90}