From b79115c4c6593113c1c0dd2982c5c3b17a6debef Mon Sep 17 00:00:00 2001 From: Amit Upadhyay Date: Wed, 20 Nov 2024 23:24:47 +0530 Subject: [PATCH] some more design sketch --- fastn-resolved/src/js/mod.rs | 334 ++++++++++++++++--------------- v0.5/Cargo.lock | 1 + v0.5/fastn-compiler/Cargo.toml | 1 + v0.5/fastn-compiler/src/js.rs | 10 + v0.5/fastn-compiler/src/lib.rs | 1 + v0.5/fastn-compiler/src/utils.rs | 25 +++ 6 files changed, 206 insertions(+), 166 deletions(-) create mode 100644 v0.5/fastn-compiler/src/utils.rs diff --git a/fastn-resolved/src/js/mod.rs b/fastn-resolved/src/js/mod.rs index f4a2bf6ae..41c2c5e61 100644 --- a/fastn-resolved/src/js/mod.rs +++ b/fastn-resolved/src/js/mod.rs @@ -7,6 +7,7 @@ pub struct TDoc<'a> { type Map = std::collections::BTreeMap; type Result = std::result::Result; + pub const REFERENCE: &str = "$"; pub const CLONE: &str = "*$"; @@ -28,173 +29,174 @@ impl<'a> TDoc<'a> { pub fn get_record( &'a self, - name: &'a str, - line_number: usize, + _name: &'a str, + _line_number: usize, ) -> Result { - match self.get_thing(name, line_number)? { - fastn_resolved::Definition::Record(r) => Ok(r), - t => self.err( - format!("Expected Record, found: `{:?}`", t).as_str(), - name, - "get_record", - line_number, - ), - } + todo!() + // match self.get_thing(name, line_number)? { + // fastn_resolved::Definition::Record(r) => Ok(r), + // t => self.err( + // format!("Expected Record, found: `{:?}`", t).as_str(), + // name, + // "get_record", + // line_number, + // ), + // } } - pub fn get_thing( - &'a self, - name: &'a str, - line_number: usize, - ) -> Result { - let name = name - .strip_prefix(REFERENCE) - .or_else(|| name.strip_prefix(CLONE)) - .unwrap_or(name); - - let (initial_thing, remaining) = self.get_initial_thing(name, line_number)?; - - if let Some(remaining) = remaining { - return get_thing_(self, line_number, remaining.as_str(), &initial_thing); - } - return Ok(initial_thing); - - fn get_thing_( - doc: &TDoc, - line_number: usize, - name: &str, - thing: &fastn_resolved::Definition, - ) -> Result { - use ftd::interpreter::PropertyValueExt; - use itertools::Itertools; - - let (v, remaining) = ftd::interpreter::utils::split_at(name, "."); - let thing = match thing.clone() { - fastn_resolved::Definition::Variable(fastn_resolved::Variable { - name, - value, - mutable, - .. - }) => { - let value_kind = value.kind(); - let fields = match value.resolve(doc, line_number)?.inner() { - Some(fastn_resolved::Value::Record { fields, .. }) => fields, - Some(fastn_resolved::Value::Object { values }) => values, - Some(fastn_resolved::Value::KwArgs { arguments }) => arguments, - Some(fastn_resolved::Value::List { data, .. }) => data - .into_iter() - .enumerate() - .map(|(index, v)| (index.to_string(), v)) - .collect::>(), - None => { - let kind_name = match value_kind.get_record_name() { - Some(name) => name, - _ => { - return doc.err( - "not an record", - thing, - "get_thing", - line_number, - ); - } - }; - let kind_thing = doc.get_thing(kind_name, line_number)?; - let kind = match kind_thing - .record(doc.name, line_number)? - .fields - .iter() - .find(|f| f.name.eq(&v)) - .map(|v| v.kind.to_owned()) - { - Some(f) => f, - _ => { - return doc.err( - "not an record or or-type", - thing, - "get_thing", - line_number, - ); - } - }; - let thing = - ftd::interpreter::Thing::Variable(fastn_resolved::Variable { - name, - kind: kind.to_owned(), - mutable, - value: fastn_resolved::PropertyValue::Value { - value: fastn_resolved::Value::Optional { - data: Box::new(None), - kind, - }, - is_mutable: mutable, - line_number, - }, - conditional_value: vec![], - line_number, - is_static: !mutable, - }); - if let Some(remaining) = remaining { - return get_thing_(doc, line_number, &remaining, &thing); - } - return Ok(thing); - } - _ => return doc.err("not an record", thing, "get_thing", line_number), - }; - match fields.get(&v) { - Some(fastn_resolved::PropertyValue::Value { - value: val, - line_number, - is_mutable, - }) => ftd::interpreter::Thing::Variable(fastn_resolved::Variable { - name, - kind: fastn_resolved::KindData { - kind: val.kind(), - caption: false, - body: false, - }, - mutable: false, - value: fastn_resolved::PropertyValue::Value { - value: val.to_owned(), - line_number: *line_number, - is_mutable: *is_mutable, - }, - conditional_value: vec![], - line_number: *line_number, - is_static: !mutable, - }), - Some(fastn_resolved::PropertyValue::Reference { name, .. }) - | Some(fastn_resolved::PropertyValue::Clone { name, .. }) => { - let (initial_thing, name) = doc.get_initial_thing(name, line_number)?; - if let Some(remaining) = name { - get_thing_(doc, line_number, remaining.as_str(), &initial_thing)? - } else { - initial_thing - } - } - _ => thing.clone(), - } - } - ftd::interpreter::Thing::OrType(fastn_resolved::OrType { - name, variants, .. - }) => { - let variant = variants - .iter() - .find_or_first(|variant| variant.name().eq(&format!("{name}.{v}"))) - .ok_or(ftd::interpreter::Error::ParseError { - message: format!("Cant't find `{v}` variant in `{name}` or-type"), - doc_id: doc.name.to_string(), - line_number, - })?; - variant.to_thing(doc.name, line_number)? - } - _ => { - return doc.err("not an or-type", thing, "get_thing", line_number); - } - }; - if let Some(remaining) = remaining { - return get_thing_(doc, line_number, &remaining, &thing); - } - Ok(thing) - } - } + // pub fn get_thing( + // &'a self, + // name: &'a str, + // line_number: usize, + // ) -> Result { + // let name = name + // .strip_prefix(REFERENCE) + // .or_else(|| name.strip_prefix(CLONE)) + // .unwrap_or(name); + // + // let (initial_thing, remaining) = self.get_initial_thing(name, line_number)?; + // + // if let Some(remaining) = remaining { + // return get_thing_(self, line_number, remaining.as_str(), &initial_thing); + // } + // return Ok(initial_thing); + // + // fn get_thing_( + // doc: &TDoc, + // line_number: usize, + // name: &str, + // thing: &fastn_resolved::Definition, + // ) -> Result { + // use ftd::interpreter::PropertyValueExt; + // use itertools::Itertools; + // + // let (v, remaining) = ftd::interpreter::utils::split_at(name, "."); + // let thing = match thing.clone() { + // fastn_resolved::Definition::Variable(fastn_resolved::Variable { + // name, + // value, + // mutable, + // .. + // }) => { + // let value_kind = value.kind(); + // let fields = match value.resolve(doc, line_number)?.inner() { + // Some(fastn_resolved::Value::Record { fields, .. }) => fields, + // Some(fastn_resolved::Value::Object { values }) => values, + // Some(fastn_resolved::Value::KwArgs { arguments }) => arguments, + // Some(fastn_resolved::Value::List { data, .. }) => data + // .into_iter() + // .enumerate() + // .map(|(index, v)| (index.to_string(), v)) + // .collect::>(), + // None => { + // let kind_name = match value_kind.get_record_name() { + // Some(name) => name, + // _ => { + // return doc.err( + // "not an record", + // thing, + // "get_thing", + // line_number, + // ); + // } + // }; + // let kind_thing = doc.get_thing(kind_name, line_number)?; + // let kind = match kind_thing + // .record(doc.name, line_number)? + // .fields + // .iter() + // .find(|f| f.name.eq(&v)) + // .map(|v| v.kind.to_owned()) + // { + // Some(f) => f, + // _ => { + // return doc.err( + // "not an record or or-type", + // thing, + // "get_thing", + // line_number, + // ); + // } + // }; + // let thing = + // ftd::interpreter::Thing::Variable(fastn_resolved::Variable { + // name, + // kind: kind.to_owned(), + // mutable, + // value: fastn_resolved::PropertyValue::Value { + // value: fastn_resolved::Value::Optional { + // data: Box::new(None), + // kind, + // }, + // is_mutable: mutable, + // line_number, + // }, + // conditional_value: vec![], + // line_number, + // is_static: !mutable, + // }); + // if let Some(remaining) = remaining { + // return get_thing_(doc, line_number, &remaining, &thing); + // } + // return Ok(thing); + // } + // _ => return doc.err("not an record", thing, "get_thing", line_number), + // }; + // match fields.get(&v) { + // Some(fastn_resolved::PropertyValue::Value { + // value: val, + // line_number, + // is_mutable, + // }) => ftd::interpreter::Thing::Variable(fastn_resolved::Variable { + // name, + // kind: fastn_resolved::KindData { + // kind: val.kind(), + // caption: false, + // body: false, + // }, + // mutable: false, + // value: fastn_resolved::PropertyValue::Value { + // value: val.to_owned(), + // line_number: *line_number, + // is_mutable: *is_mutable, + // }, + // conditional_value: vec![], + // line_number: *line_number, + // is_static: !mutable, + // }), + // Some(fastn_resolved::PropertyValue::Reference { name, .. }) + // | Some(fastn_resolved::PropertyValue::Clone { name, .. }) => { + // let (initial_thing, name) = doc.get_initial_thing(name, line_number)?; + // if let Some(remaining) = name { + // get_thing_(doc, line_number, remaining.as_str(), &initial_thing)? + // } else { + // initial_thing + // } + // } + // _ => thing.clone(), + // } + // } + // ftd::interpreter::Thing::OrType(fastn_resolved::OrType { + // name, variants, .. + // }) => { + // let variant = variants + // .iter() + // .find_or_first(|variant| variant.name().eq(&format!("{name}.{v}"))) + // .ok_or(ftd::interpreter::Error::ParseError { + // message: format!("Cant't find `{v}` variant in `{name}` or-type"), + // doc_id: doc.name.to_string(), + // line_number, + // })?; + // variant.to_thing(doc.name, line_number)? + // } + // _ => { + // return doc.err("not an or-type", thing, "get_thing", line_number); + // } + // }; + // if let Some(remaining) = remaining { + // return get_thing_(doc, line_number, &remaining, &thing); + // } + // Ok(thing) + // } + // } } diff --git a/v0.5/Cargo.lock b/v0.5/Cargo.lock index 1ea8236de..bc2f3de17 100644 --- a/v0.5/Cargo.lock +++ b/v0.5/Cargo.lock @@ -117,6 +117,7 @@ dependencies = [ "fastn-resolved", "fastn-section", "fastn-unresolved", + "indexmap", "string-interner", ] diff --git a/v0.5/fastn-compiler/Cargo.toml b/v0.5/fastn-compiler/Cargo.toml index b73d90f63..763f5dccd 100644 --- a/v0.5/fastn-compiler/Cargo.toml +++ b/v0.5/fastn-compiler/Cargo.toml @@ -14,6 +14,7 @@ fastn-section.workspace = true fastn-resolved.workspace = true fastn-builtins.workspace = true fastn-unresolved.workspace = true +indexmap.workspace = true string-interner.workspace = true diff --git a/v0.5/fastn-compiler/src/js.rs b/v0.5/fastn-compiler/src/js.rs index ece9e71a6..8fe1afef3 100644 --- a/v0.5/fastn-compiler/src/js.rs +++ b/v0.5/fastn-compiler/src/js.rs @@ -1,5 +1,15 @@ impl fastn_compiler::Compiler { pub(crate) fn js(&self) -> String { + // this function should look a bit like ftd::js::document_into_js_ast(), we do not need + // to construct the Document object there, but will fetch all the fields as variables + + // self.content should be all UR::R now + let _resolved_content = self.resolved_content(); + // every symbol in self.symbol_used in the bag must be UR::R now + let needed_symbols = self.needed_symbols(); + let _js_files = self.external_js_files(&needed_symbols); + let _css_files = self.external_css_files(&needed_symbols); + todo!() } } diff --git a/v0.5/fastn-compiler/src/lib.rs b/v0.5/fastn-compiler/src/lib.rs index 5a0ad21df..9dc6a09b0 100644 --- a/v0.5/fastn-compiler/src/lib.rs +++ b/v0.5/fastn-compiler/src/lib.rs @@ -7,6 +7,7 @@ extern crate self as fastn_compiler; mod compiler; mod js; mod symbols; +mod utils; pub use compiler::compile; pub(crate) use compiler::Compiler; diff --git a/v0.5/fastn-compiler/src/utils.rs b/v0.5/fastn-compiler/src/utils.rs new file mode 100644 index 000000000..9600793a0 --- /dev/null +++ b/v0.5/fastn-compiler/src/utils.rs @@ -0,0 +1,25 @@ +impl fastn_compiler::Compiler { + pub(crate) fn resolved_content(&self) -> Vec { + // self.content should be all UR::R now + // every symbol in self.symbol_used in the bag must be UR::R now + todo!() + } + pub(crate) fn needed_symbols(&self) -> indexmap::IndexMap { + // go through self.symbols_used and get the resolved definitions + todo!() + } + pub(crate) fn external_js_files( + &self, + _needed_symbols: &indexmap::IndexMap, + ) -> Vec { + // go through needed_symbols and get the external js files + todo!() + } + pub(crate) fn external_css_files( + &self, + _needed_symbols: &indexmap::IndexMap, + ) -> Vec { + // go through needed_symbols and get the external css files + todo!() + } +}