From 7cc0bbec040c9d95749636b93d69d017a76e6381 Mon Sep 17 00:00:00 2001 From: Amit Upadhyay Date: Sat, 7 Dec 2024 17:24:16 +0530 Subject: [PATCH] impl fastn_continuation::Continuation for fastn_compiler::Compiler --- v0.5/Cargo.lock | 1 + v0.5/fastn-compiler/Cargo.toml | 1 + v0.5/fastn-compiler/src/compiler.rs | 116 ++++++++++++------------ v0.5/fastn-compiler/src/lib.rs | 2 +- v0.5/fastn-continuation/src/lib.rs | 17 ++++ v0.5/fastn-unresolved/src/parser/mod.rs | 4 +- v0.5/fastn-unresolved/src/utils.rs | 1 + v0.5/fastn/src/commands/render.rs | 38 ++------ v0.5/fastn/src/commands/serve.rs | 1 - v0.5/fastn/src/lib.rs | 2 - v0.5/fastn/src/symbols.rs | 92 ++++++++----------- 11 files changed, 127 insertions(+), 148 deletions(-) diff --git a/v0.5/Cargo.lock b/v0.5/Cargo.lock index e942b04f7..e39fd6b9b 100644 --- a/v0.5/Cargo.lock +++ b/v0.5/Cargo.lock @@ -174,6 +174,7 @@ name = "fastn-compiler" version = "0.1.0" dependencies = [ "fastn-builtins", + "fastn-continuation", "fastn-resolved", "fastn-section", "fastn-unresolved", diff --git a/v0.5/fastn-compiler/Cargo.toml b/v0.5/fastn-compiler/Cargo.toml index c73afe015..4e49c66e2 100644 --- a/v0.5/fastn-compiler/Cargo.toml +++ b/v0.5/fastn-compiler/Cargo.toml @@ -11,6 +11,7 @@ homepage.workspace = true [dependencies] fastn-builtins.workspace = true fastn-resolved.workspace = true +fastn-continuation.workspace = true fastn-section.workspace = true fastn-unresolved.workspace = true indexmap.workspace = true diff --git a/v0.5/fastn-compiler/src/compiler.rs b/v0.5/fastn-compiler/src/compiler.rs index afc3ab43f..c5c05bc52 100644 --- a/v0.5/fastn-compiler/src/compiler.rs +++ b/v0.5/fastn-compiler/src/compiler.rs @@ -1,13 +1,5 @@ const ITERATION_THRESHOLD: usize = 100; -pub enum CompilerState { - StuckOnSymbols( - Box, - std::collections::HashSet, - ), - Done(Result), -} - // foo.ftd // -- import: foo as f (f => foo) // @@ -23,7 +15,7 @@ pub struct Compiler { /// checkout resolve_document for why this is an Option pub(crate) content: Option>, pub(crate) document: fastn_unresolved::Document, - pub global_aliases: fastn_unresolved::AliasesSimple, + // pub global_aliases: fastn_unresolved::AliasesSimple, iterations: usize, } @@ -32,14 +24,14 @@ impl Compiler { source: &str, package: &str, module: Option<&str>, - global_aliases: fastn_unresolved::AliasesSimple, + // global_aliases: fastn_unresolved::AliasesSimple, ) -> Self { let mut arena = fastn_unresolved::Arena::default(); let mut document = fastn_unresolved::parse( fastn_unresolved::Module::new(package, module, &mut arena), source, &mut arena, - &global_aliases, + // &global_aliases, ); let content = Some(document.content); document.content = vec![]; @@ -50,7 +42,7 @@ impl Compiler { modules: std::collections::HashMap::new(), content, document, - global_aliases, + // global_aliases, definitions_used: Default::default(), iterations: 0, } @@ -151,50 +143,6 @@ impl Compiler { stuck_on_symbols } - pub fn continue_with_definitions( - mut self, - definitions: Vec, - ) -> CompilerState { - self.iterations += 1; - if self.iterations > ITERATION_THRESHOLD { - panic!("iterations too high"); - } - - for definition in definitions { - // the following is only okay if our symbol store only returns unresolved definitions, - // some other store might return resolved definitions, and we need to handle that. - self.definitions.insert( - definition - .unresolved() - .unwrap() - .symbol - .clone() - .unwrap() - .string(&self.arena), - definition, - ); - } - - let unresolved_symbols = self.resolve_document(); - if unresolved_symbols.is_empty() { - return CompilerState::Done(self.finalise(false)); - } - - // this itself has to happen in a loop. we need a warning if we are not able to resolve all - // symbols in 10 attempts. - let mut r = ResolveSymbolsResult { - need_more_symbols: unresolved_symbols, - unresolvable: Default::default(), - }; - r = self.resolve_symbols(r.need_more_symbols); - - if r.need_more_symbols.is_empty() { - return CompilerState::Done(self.finalise(true)); - } - - CompilerState::StuckOnSymbols(Box::new(self), r.need_more_symbols) - } - fn finalise( self, some_symbols_are_unresolved: bool, @@ -236,11 +184,61 @@ pub fn compile( source: &str, package: &str, module: Option<&str>, - global_aliases: fastn_unresolved::AliasesSimple, -) -> CompilerState { - Compiler::new(source, package, module, global_aliases).continue_with_definitions(vec![]) +) -> fastn_continuation::Result { + use fastn_continuation::Continuation; + + Compiler::new(source, package, module).continue_after(vec![]) } +impl fastn_continuation::Continuation for Compiler { + type Output = Result; + type NeededInput = std::collections::HashSet; + type NeededOutput = Vec; + + fn continue_after( + mut self, + definitions: Self::NeededOutput, + ) -> fastn_continuation::Result { + self.iterations += 1; + if self.iterations > ITERATION_THRESHOLD { + panic!("iterations too high"); + } + + for definition in definitions { + // the following is only okay if our symbol store only returns unresolved definitions, + // some other store might return resolved definitions, and we need to handle that. + self.definitions.insert( + definition + .unresolved() + .unwrap() + .symbol + .clone() + .unwrap() + .string(&self.arena), + definition, + ); + } + + let unresolved_symbols = self.resolve_document(); + if unresolved_symbols.is_empty() { + return fastn_continuation::Result::Done(self.finalise(false)); + } + + // this itself has to happen in a loop. we need a warning if we are not able to resolve all + // symbols in 10 attempts. + let mut r = ResolveSymbolsResult { + need_more_symbols: unresolved_symbols, + unresolvable: Default::default(), + }; + r = self.resolve_symbols(r.need_more_symbols); + + if r.need_more_symbols.is_empty() { + return fastn_continuation::Result::Done(self.finalise(true)); + } + + fastn_continuation::Result::Stuck(Box::new(self), r.need_more_symbols) + } +} #[derive(Default)] struct ResolveSymbolsResult { need_more_symbols: std::collections::HashSet, diff --git a/v0.5/fastn-compiler/src/lib.rs b/v0.5/fastn-compiler/src/lib.rs index 316ddb648..93ddeb874 100644 --- a/v0.5/fastn-compiler/src/lib.rs +++ b/v0.5/fastn-compiler/src/lib.rs @@ -7,7 +7,7 @@ extern crate self as fastn_compiler; mod compiler; mod utils; -pub use compiler::{compile, Compiler, CompilerState}; +pub use compiler::{compile, Compiler}; pub use fastn_section::Result; #[derive(Debug)] diff --git a/v0.5/fastn-continuation/src/lib.rs b/v0.5/fastn-continuation/src/lib.rs index cd0bb1b0d..3dfd1882c 100644 --- a/v0.5/fastn-continuation/src/lib.rs +++ b/v0.5/fastn-continuation/src/lib.rs @@ -26,6 +26,23 @@ where } } +pub fn consume_with(mut c: Result, f: F) -> C::Output +where + F: Fn(&mut C, C::NeededInput) -> C::NeededOutput, +{ + loop { + match c { + Result::Stuck(mut ic, input) => { + let o = f(&mut ic, input); + c = ic.continue_after(o); + } + Result::Done(c) => { + return c; + } + } + } +} + pub async fn consume_async( mut c: Result, f: impl Fn(C::NeededInput) -> Fut, diff --git a/v0.5/fastn-unresolved/src/parser/mod.rs b/v0.5/fastn-unresolved/src/parser/mod.rs index 083a69d8a..053b8dfff 100644 --- a/v0.5/fastn-unresolved/src/parser/mod.rs +++ b/v0.5/fastn-unresolved/src/parser/mod.rs @@ -6,7 +6,7 @@ pub fn parse( module: fastn_unresolved::Module, source: &str, arena: &mut fastn_unresolved::Arena, - global_aliases: &fastn_unresolved::AliasesSimple, + // global_aliases: &fastn_unresolved::AliasesSimple, ) -> fastn_unresolved::Document { let (mut document, sections) = fastn_unresolved::Document::new( module, @@ -51,7 +51,7 @@ pub fn parse( } } - document.add_definitions_to_scope(arena, global_aliases); + // document.add_definitions_to_scope(arena, global_aliases); document } diff --git a/v0.5/fastn-unresolved/src/utils.rs b/v0.5/fastn-unresolved/src/utils.rs index 48c18eb52..0af3774e5 100644 --- a/v0.5/fastn-unresolved/src/utils.rs +++ b/v0.5/fastn-unresolved/src/utils.rs @@ -31,6 +31,7 @@ impl fastn_unresolved::Document { self.comments.extend(comments); } + #[expect(unused)] pub(crate) fn add_definitions_to_scope( &mut self, _arena: &mut fastn_unresolved::Arena, diff --git a/v0.5/fastn/src/commands/render.rs b/v0.5/fastn/src/commands/render.rs index 5b86b448a..413ad64a0 100644 --- a/v0.5/fastn/src/commands/render.rs +++ b/v0.5/fastn/src/commands/render.rs @@ -1,16 +1,12 @@ impl fastn::commands::Render { - pub async fn run(self, config: &mut fastn_package::Package, _router: fastn_router::Router) { + pub async fn run(self, _package: &mut fastn_package::Package, _router: fastn_router::Router) { let route = fastn_continuation::consume(fastn_router::Router::reader(), fastn::full_filler) .route("/", fastn_router::Method::Get, &[]); match route { fastn_router::Route::Document(path, data) => { - let html = fastn::commands::render::render_document( - config.auto_imports.clone(), - path.as_str(), - data, - self.strict, - ) - .await; + let html = + fastn::commands::render::render_document(path.as_str(), data, self.strict) + .await; std::fs::write(path.replace(".ftd", ".html"), html).unwrap(); } _ => todo!(), @@ -18,30 +14,14 @@ impl fastn::commands::Render { } } -pub async fn render_document( - global_aliases: Vec, - path: &str, - _data: serde_json::Value, - _strict: bool, -) -> String { +pub async fn render_document(path: &str, _data: serde_json::Value, _strict: bool) -> String { let source = std::fs::File::open(path) .and_then(std::io::read_to_string) .unwrap(); - let mut cs = fastn_compiler::compile(&source, "main", None, todo!()); - let mut symbol_store = fastn::Symbols {}; - - let o = loop { - match cs { - fastn_compiler::CompilerState::StuckOnSymbols(mut c, symbols) => { - let o = symbol_store.lookup(&mut c, &symbols).await; - cs = c.continue_with_definitions(o); - } - fastn_compiler::CompilerState::Done(c) => { - break c; - } - } - }; - + let o = fastn_continuation::consume_with( + fastn_compiler::compile(&source, "main", None), + fastn::symbols::lookup, + ); let h = fastn_runtime::HtmlData::from_cd(o.unwrap()); h.to_test_html() } diff --git a/v0.5/fastn/src/commands/serve.rs b/v0.5/fastn/src/commands/serve.rs index 512c4894c..18ef6acc6 100644 --- a/v0.5/fastn/src/commands/serve.rs +++ b/v0.5/fastn/src/commands/serve.rs @@ -49,7 +49,6 @@ async fn render( Ok(hyper::Response::new(http_body_util::Full::new( hyper::body::Bytes::from( fastn::commands::render::render_document( - todo!(), // global_aliases, "index.ftd", serde_json::Value::Null, diff --git a/v0.5/fastn/src/lib.rs b/v0.5/fastn/src/lib.rs index 099eedc85..1a2ef886c 100644 --- a/v0.5/fastn/src/lib.rs +++ b/v0.5/fastn/src/lib.rs @@ -12,8 +12,6 @@ use tokio as _; pub mod commands; mod symbols; -pub use symbols::Symbols; - pub enum Action { Read, Write, diff --git a/v0.5/fastn/src/symbols.rs b/v0.5/fastn/src/symbols.rs index 63ca7254b..57d58fdfc 100644 --- a/v0.5/fastn/src/symbols.rs +++ b/v0.5/fastn/src/symbols.rs @@ -1,62 +1,46 @@ -#[derive(Debug)] -pub struct Symbols {} +fn find_all_definitions_in_a_module( + compiler: &mut fastn_compiler::Compiler, + (file, module): (String, fastn_unresolved::Module), +) -> Vec { + // we need to fetch the symbol from the store + let source = match std::fs::File::open(file.as_str()).and_then(std::io::read_to_string) { + Ok(v) => v, + Err(e) => { + println!("failed to read file {}.ftd: {e:?}", file); + return vec![]; + } + }; -impl Symbols { - fn find_all_definitions_in_a_module( - &mut self, - compiler: &mut fastn_compiler::Compiler, - (file, module): (String, fastn_unresolved::Module), - ) -> Vec { - // we need to fetch the symbol from the store - let source = match std::fs::File::open(file.as_str()).and_then(std::io::read_to_string) { - Ok(v) => v, - Err(e) => { - println!("failed to read file {}.ftd: {e:?}", file); - return vec![]; - } - }; - - let d = fastn_unresolved::parse( - module.clone(), - &source, - &mut compiler.arena, - &Default::default(), // TODO - // compiler.global_aliases, - ); + let d = fastn_unresolved::parse(module.clone(), &source, &mut compiler.arena); - d.definitions - .into_iter() - .map(|d| match d { - fastn_unresolved::UR::UnResolved(mut v) => { - v.symbol = Some( - module.symbol(v.name.unresolved().unwrap().str(), &mut compiler.arena), - ); - fastn_unresolved::UR::UnResolved(v) - } - _ => { - unreachable!("fastn_unresolved::parse() only returns unresolved definitions") - } - }) - .collect::>() - } + d.definitions + .into_iter() + .map(|d| match d { + fastn_unresolved::UR::UnResolved(mut v) => { + v.symbol = + Some(module.symbol(v.name.unresolved().unwrap().str(), &mut compiler.arena)); + fastn_unresolved::UR::UnResolved(v) + } + _ => { + unreachable!("fastn_unresolved::parse() only returns unresolved definitions") + } + }) + .collect::>() } -impl Symbols { - pub async fn lookup( - &mut self, - compiler: &mut fastn_compiler::Compiler, - symbols: &std::collections::HashSet, - ) -> Vec { - let unique_modules = symbols - .iter() - .map(|s| file_for_symbol(s, &mut compiler.arena)) - .collect::>(); +pub fn lookup( + compiler: &mut fastn_compiler::Compiler, + symbols: std::collections::HashSet, +) -> Vec { + let unique_modules = symbols + .iter() + .map(|s| file_for_symbol(s, &mut compiler.arena)) + .collect::>(); - unique_modules - .into_iter() - .flat_map(|m| self.find_all_definitions_in_a_module(compiler, m)) - .collect() - } + unique_modules + .into_iter() + .flat_map(|m| find_all_definitions_in_a_module(compiler, m)) + .collect() } fn file_for_symbol(