2021-06-29 21:19:22 +00:00
|
|
|
use crate::*;
|
2021-06-28 14:35:45 +00:00
|
|
|
use crate::syntax::block::Item;
|
2021-06-29 20:32:35 +00:00
|
|
|
use crate::syntax::block::constructors::*;
|
2021-06-29 21:19:22 +00:00
|
|
|
use crate::gen::schema::*;
|
2021-06-28 14:35:45 +00:00
|
|
|
|
2021-06-30 14:07:49 +00:00
|
|
|
use convert_case::{Case, Casing};
|
|
|
|
|
|
|
|
use lazy_static::lazy_static;
|
|
|
|
|
2021-06-30 07:53:32 +00:00
|
|
|
use preserves::value::Map;
|
2021-06-30 14:07:49 +00:00
|
|
|
use preserves::value::NestedValue;
|
|
|
|
use preserves::value::Value;
|
2021-06-30 07:53:32 +00:00
|
|
|
|
2021-06-29 20:32:35 +00:00
|
|
|
use super::CompilerConfig;
|
2021-06-30 13:55:42 +00:00
|
|
|
use super::names;
|
2021-06-28 14:35:45 +00:00
|
|
|
use super::types;
|
|
|
|
|
2021-07-02 05:48:52 +00:00
|
|
|
#[derive(Clone, Copy)]
|
|
|
|
pub enum ModuleContextMode {
|
|
|
|
TargetIOValue,
|
|
|
|
TargetAny,
|
|
|
|
}
|
|
|
|
|
2021-06-29 20:32:35 +00:00
|
|
|
pub struct ModuleContext<'m> {
|
|
|
|
pub config: &'m CompilerConfig,
|
2021-06-30 07:53:32 +00:00
|
|
|
pub literals: Map<_Any, String>,
|
2021-06-28 14:35:45 +00:00
|
|
|
pub typedefs: Vec<Item>,
|
|
|
|
pub functiondefs: Vec<Item>,
|
2021-07-02 05:48:52 +00:00
|
|
|
pub mode: ModuleContextMode,
|
2021-06-28 14:35:45 +00:00
|
|
|
}
|
|
|
|
|
2021-06-29 20:32:35 +00:00
|
|
|
pub struct FunctionContext<'a, 'm> {
|
|
|
|
pub m: &'a mut ModuleContext<'m>,
|
2021-06-28 14:35:45 +00:00
|
|
|
pub temp_counter: usize,
|
|
|
|
pub captures: Vec<Capture>,
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct Capture {
|
|
|
|
pub field_name: String,
|
2021-06-28 15:26:41 +00:00
|
|
|
pub ty: types::TField,
|
2021-06-28 14:35:45 +00:00
|
|
|
pub source_expr: String,
|
|
|
|
}
|
|
|
|
|
2021-06-30 14:07:49 +00:00
|
|
|
lazy_static! {
|
|
|
|
static ref ID_RE: regex::Regex = regex::Regex::new(r"^[a-zA-Z][a-zA-Z_0-9]*$").unwrap();
|
|
|
|
}
|
|
|
|
|
2021-06-29 20:32:35 +00:00
|
|
|
impl<'m> ModuleContext<'m> {
|
|
|
|
pub fn new(config: &'m CompilerConfig) -> Self {
|
2021-06-28 14:35:45 +00:00
|
|
|
ModuleContext {
|
2021-06-29 20:32:35 +00:00
|
|
|
config: config,
|
2021-06-28 14:35:45 +00:00
|
|
|
literals: Map::new(),
|
|
|
|
typedefs: Vec::new(),
|
|
|
|
functiondefs: Vec::new(),
|
2021-07-02 05:48:52 +00:00
|
|
|
mode: ModuleContextMode::TargetIOValue,
|
2021-06-28 14:35:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-06-30 07:53:32 +00:00
|
|
|
pub fn define_literal(&mut self, v: &_Any) -> String {
|
2021-06-30 14:07:49 +00:00
|
|
|
let prefix = format!("LIT_{}", self.literals.len());
|
|
|
|
let next_id = match v.value() {
|
|
|
|
Value::Boolean(b) => prefix + "_" + &b.to_string(),
|
|
|
|
Value::Symbol(s) => if ID_RE.is_match(&s) { prefix + "_" + s } else { prefix },
|
|
|
|
Value::String(s) => if ID_RE.is_match(&s) { prefix + "_" + s } else { prefix },
|
|
|
|
Value::SignedInteger(n) => prefix + "_" + &n.to_string(),
|
|
|
|
_ => prefix
|
|
|
|
};
|
|
|
|
let next_id = next_id.to_case(Case::UpperSnake);
|
2021-07-02 05:48:52 +00:00
|
|
|
"&*".to_owned() + self.target_prefix() + "::" + self.literals.entry(v.clone()).or_insert(next_id)
|
2021-06-28 14:35:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn define_type(&mut self, i: Item) {
|
|
|
|
self.typedefs.push(i)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn define_function<F: FnOnce(FunctionContext) -> Item>(&mut self, f: F) {
|
|
|
|
let i = f(FunctionContext::new(self));
|
|
|
|
self.functiondefs.push(i)
|
|
|
|
}
|
2021-06-29 20:32:35 +00:00
|
|
|
|
2021-06-29 21:19:22 +00:00
|
|
|
pub fn render_ref(&self, r: &Ref) -> Item {
|
|
|
|
match self.config.module_aliases.get(&r.module.0) {
|
|
|
|
None =>
|
|
|
|
if r.module.0.is_empty() {
|
|
|
|
item(r.name.to_owned())
|
|
|
|
} else {
|
|
|
|
let mut items = Vec::new();
|
|
|
|
items.push(item(self.config.fully_qualified_module_prefix.to_owned()));
|
2021-06-30 13:55:42 +00:00
|
|
|
for p in &r.module.0 { items.push(item(names::render_modname(p))) }
|
2021-06-29 21:19:22 +00:00
|
|
|
items.push(item(r.name.to_owned()));
|
|
|
|
item(name(items))
|
|
|
|
}
|
|
|
|
Some(s) =>
|
|
|
|
item(name![s.to_owned(), r.name.to_owned()])
|
2021-06-29 20:32:35 +00:00
|
|
|
}
|
|
|
|
}
|
2021-07-02 05:48:52 +00:00
|
|
|
|
|
|
|
pub fn target(&self) -> &'static str {
|
|
|
|
match self.mode {
|
|
|
|
ModuleContextMode::TargetIOValue => "preserves::value::IOValue",
|
|
|
|
ModuleContextMode::TargetAny => "_Any",
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn target_prefix(&self) -> &'static str {
|
|
|
|
match self.mode {
|
|
|
|
ModuleContextMode::TargetIOValue => "_io_",
|
|
|
|
ModuleContextMode::TargetAny => "_any_",
|
|
|
|
}
|
|
|
|
}
|
2021-06-28 14:35:45 +00:00
|
|
|
}
|
|
|
|
|
2021-06-29 20:32:35 +00:00
|
|
|
impl<'a, 'm> FunctionContext<'a, 'm> {
|
|
|
|
pub fn new(m: &'a mut ModuleContext<'m>) -> Self {
|
2021-06-28 14:35:45 +00:00
|
|
|
FunctionContext {
|
|
|
|
m: m,
|
|
|
|
temp_counter: 0,
|
|
|
|
captures: Vec::new(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-06-28 15:26:41 +00:00
|
|
|
pub fn capture(&mut self, field_name: String, ty: types::TField, source_expr: String) {
|
2021-06-28 14:35:45 +00:00
|
|
|
self.captures.push(Capture {
|
2021-06-28 15:26:41 +00:00
|
|
|
field_name: field_name,
|
|
|
|
ty: ty,
|
|
|
|
source_expr: source_expr,
|
2021-06-28 14:35:45 +00:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2021-06-29 14:54:29 +00:00
|
|
|
pub fn lookup_capture(&self, field_name: &str) -> &Capture {
|
|
|
|
for c in &self.captures {
|
|
|
|
if c.field_name == field_name {
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
panic!("No capture for field {:?} available", field_name)
|
|
|
|
}
|
|
|
|
|
2021-06-28 14:35:45 +00:00
|
|
|
pub fn gentempname(&mut self) -> String {
|
|
|
|
let i = self.temp_counter;
|
|
|
|
self.temp_counter += 1;
|
|
|
|
format!("_tmp{}", i)
|
|
|
|
}
|
2021-06-29 14:54:29 +00:00
|
|
|
|
|
|
|
pub fn branch<R, F: FnOnce(&mut Self) -> R>(&mut self, f: F) -> R {
|
|
|
|
let saved_temp_counter = self.temp_counter;
|
|
|
|
let saved_capture_count = self.captures.len();
|
|
|
|
let result = f(self);
|
|
|
|
self.temp_counter = saved_temp_counter;
|
|
|
|
self.captures.truncate(saved_capture_count);
|
|
|
|
result
|
|
|
|
}
|
2021-06-28 14:35:45 +00:00
|
|
|
}
|