diff --git a/montyc_core/src/ast.rs b/montyc_core/src/ast.rs deleted file mode 100644 index 36e1150..0000000 --- a/montyc_core/src/ast.rs +++ /dev/null @@ -1,4 +0,0 @@ -derive_everything! { - #[repr(transparent)] - pub struct AstNodeId(pub u32); -} diff --git a/montyc_core/src/lib.rs b/montyc_core/src/lib.rs index 931d587..93c2597 100644 --- a/montyc_core/src/lib.rs +++ b/montyc_core/src/lib.rs @@ -37,7 +37,6 @@ pub(crate) mod macros { } } -pub mod ast; pub mod codegen; pub mod dict; pub mod error; @@ -52,6 +51,4 @@ pub type Qualname = Vec; // TODO: turn this into some cheap u64 ID type. pub type MapT = ahash::AHashMap; -pub type Rib = ahash::AHashMap; - pub use {error::*, func::*, module::*, span::*, typing::*, value::*}; diff --git a/montyc_driver/src/typeck/cfg_reducer.rs b/montyc_driver/src/cfg_reducer.rs similarity index 97% rename from montyc_driver/src/typeck/cfg_reducer.rs rename to montyc_driver/src/cfg_reducer.rs index 7ff6d4e..bb0ccc0 100644 --- a/montyc_driver/src/typeck/cfg_reducer.rs +++ b/montyc_driver/src/cfg_reducer.rs @@ -1,6 +1,6 @@ use montyc_core::MontyResult; -use crate::global_context::SessionContext; +use crate::session_context::SessionContext; pub trait GraphLike { fn n_nodes(&self) -> usize; diff --git a/montyc_driver/src/import.rs b/montyc_driver/src/import.rs index 79dc949..eecdb4c 100644 --- a/montyc_driver/src/import.rs +++ b/montyc_driver/src/import.rs @@ -12,7 +12,7 @@ use montyc_hlirt::{ ObjectId, ObjectSpace, PyException, PyResult, PyResultExt, }; -use crate::global_context::SessionContext; +use crate::session_context::SessionContext; // -- ModuleSpec diff --git a/montyc_driver/src/lib.rs b/montyc_driver/src/lib.rs index 1544b76..91aba2a 100644 --- a/montyc_driver/src/lib.rs +++ b/montyc_driver/src/lib.rs @@ -1,9 +1,11 @@ #![warn(warnings)] pub(crate) mod import; -pub(crate) mod pretty_printer; pub(crate) mod typeck; pub(crate) mod value_store; -mod global_context; -pub use global_context::{SessionContext, SessionMode, SessionOpts, UninitializedSession}; +pub mod cfg_reducer; +pub mod session_request; + +pub mod session_context; +pub use session_context::{SessionContext, SessionMode, SessionOpts, UninitializedSession}; diff --git a/montyc_driver/src/pretty_printer.rs b/montyc_driver/src/pretty_printer.rs deleted file mode 100644 index eb9e809..0000000 --- a/montyc_driver/src/pretty_printer.rs +++ /dev/null @@ -1,46 +0,0 @@ -// use montyc_hlirt::{glue::HostGlue, typing::PythonType, Function}; - -// use crate::prelude::GlobalContext; - -// pub fn func(gcx: &mut GlobalContext, f: &Function) -> String { -// let module = gcx.get_module(f.mref).unwrap(); -// let debug_info = format!("{:#?}", module.data) -// .lines() -// .map(|line| format!("# {}\n", line)) -// .collect::(); - -// let func_display = { -// let name = gcx.spanref_to_str(f.name); -// let (params, ret) = { -// let tcx = gcx.tcx().borrow(); - -// if let PythonType::Callable { args, ret } = tcx.get_python_type_of(f.type_id).unwrap() { -// let args = args.unwrap_or_default(); -// let args = args -// .iter() -// .map(|arg| tcx.display_type(arg.clone()).unwrap()) -// .collect::>(); - -// let ret = tcx.display_type(ret).unwrap(); - -// (args.join(", "), ret) -// } else { -// todo!(); -// } -// }; - -// let body = { -// let mut lines = Vec::with_capacity(f.code.inst().len()); - -// for inst in &f.code { -// lines.push(format!(" %{} {}", inst.value, inst.op)); -// } - -// lines.join("\n") -// }; - -// format!("def {}({}) -> {} {{\n{}\n}}", name, params, ret, body) -// }; - -// format!("{}{}", debug_info, func_display) -// } diff --git a/montyc_driver/src/global_context/host.rs b/montyc_driver/src/session_context/host.rs similarity index 100% rename from montyc_driver/src/global_context/host.rs rename to montyc_driver/src/session_context/host.rs diff --git a/montyc_driver/src/global_context/mod.rs b/montyc_driver/src/session_context/mod.rs similarity index 99% rename from montyc_driver/src/global_context/mod.rs rename to montyc_driver/src/session_context/mod.rs index 98fb558..82bdabd 100644 --- a/montyc_driver/src/global_context/mod.rs +++ b/montyc_driver/src/session_context/mod.rs @@ -536,7 +536,7 @@ impl SessionContext { UninitializedSession(this) } - /// Initialize the interpreter runtime, setting . + /// Initialize the interpreter runtime fn initialize_hlirt( &mut self, _monty: &ModuleData, diff --git a/montyc_driver/src/global_context/query.rs b/montyc_driver/src/session_context/query.rs similarity index 96% rename from montyc_driver/src/global_context/query.rs rename to montyc_driver/src/session_context/query.rs index 7a52af2..8786f32 100644 --- a/montyc_driver/src/global_context/query.rs +++ b/montyc_driver/src/session_context/query.rs @@ -94,21 +94,6 @@ impl Queries for SessionContext { Ok(modules.get(mref).unwrap().as_ref().clone()) } - fn get_qualname_of( - &self, - _func: TaggedValueId<{ montyc_core::FUNCTION }>, - ) -> montyc_core::Qualname { - todo!() - } - - fn get_value(&self, _value_id: ValueId) -> Option { - todo!() - } - - fn get_rib_of<'a>(&'a self, _value_id: ValueId) -> Option<&'a montyc_core::Rib> { - todo!() - } - fn get_module_flatcode(&self, mref: ModuleRef) -> MontyResult { fn ast_to_flatcode(mref: ModuleRef, ast: &T, span: Span) -> FlatCode { let mut code = montyc_flatcode::FlatCode::new((mref.clone(), span.clone())); @@ -263,10 +248,6 @@ impl Queries for SessionContext { Ok(func) } - fn spanref_to_value(&self, _sref: SpanRef) -> MontyResult { - todo!() - } - fn spanref_to_str(&self, sref: SpanRef) -> MontyResult { self.resolve_sref_as_str(sref) .ok_or_else(|| MontyError::None) diff --git a/montyc_driver/src/session_request.rs b/montyc_driver/src/session_request.rs new file mode 100644 index 0000000..6e9e23f --- /dev/null +++ b/montyc_driver/src/session_request.rs @@ -0,0 +1,126 @@ +//! A request is used to create a session, to parse, type-check, consteval and compile Python code. +//! + +use std::path::PathBuf; + +/// A builder for creating a `Request` instance with various options. +/// +/// A `Request` is used to create a session, to parse, type-check, consteval and compile Python code. +/// +/// # Examples +/// +/// ``` +/// let request = RequestBuilder::default() +/// .entry("__main__:main".to_string()) +/// .libstd("libstd/".into()) +/// .input("input.mt".into()) +/// .output("output".into()) +/// .build(); +/// ``` +#[derive(Debug, Default)] +pub struct SessionRequestBuilder { + entry: Option, + libstd: Option, + input: Option, + output: Option, + show_ir: Option, + cc: Option, + ld: Option, + cranelift_settings: Option>, +} + +impl SessionRequestBuilder { + /// Sets the path to the entry function. + /// + /// The default value is `__main__:main`. + pub fn entry(mut self, entry: &str) -> Self { + self.entry.replace(entry.to_owned()); + self + } + + /// Sets the path to a monty compatible stdlib. + /// + /// The default value is `libstd/`. + pub fn libstd(mut self, libstd: PathBuf) -> Self { + self.libstd.replace(libstd); + self + } + + /// Sets the input file to compile. + pub fn input(mut self, input: PathBuf) -> Self { + self.input.replace(input); + self + } + + /// Sets the name of the output binary. + /// + /// The default value is the input file's name. + pub fn output(mut self, output: PathBuf) -> Self { + self.output.replace(output); + self + } + + /// Shows the Cranelift IR for the specified function. + pub fn show_ir(mut self, show_ir: Option) -> Self { + self.show_ir = show_ir; + self + } + + /// Sets the C compiler to use. + pub fn cc(mut self, cc: Option) -> Self { + self.cc = cc; + self + } + + /// Sets the linker to use. + pub fn ld(mut self, ld: Option) -> Self { + self.ld = ld; + self + } + + /// Sets low level codegen settings to pass to Cranelift. + pub fn cranelift_settings(mut self, cranelift_settings: Vec) -> Self { + self.cranelift_settings = Some(cranelift_settings); + self + } + + /// Builds a `Request` instance with the configured options. + pub fn build(self) -> SessionRequest { + SessionRequest { + entry: self.entry.unwrap_or("__main__:main".to_string()), + libstd: self.libstd.unwrap_or(PathBuf::from("libstd/")), + input: self.input.unwrap_or(PathBuf::from("main.py")), + output: self.output.unwrap_or(PathBuf::from("main")), + show_ir: self.show_ir, + cc: self.cc, + ld: self.ld, + cranelift_settings: self.cranelift_settings.unwrap_or_default(), + } + } +} + +#[derive(Debug)] +pub struct SessionRequest { + /// The path to the entry function, for instance `main` in a `__main__.py` would be `__main__:main` (and is the default.) + pub entry: String, + /// The path to a monty compatible stdlib. + pub libstd: PathBuf, + /// The input file to compile. + pub input: PathBuf, + // The name of the output binary, defaults to the input file's name. + pub output: PathBuf, + /// Show the Cranelift IR for the specified function. + pub show_ir: Option, + /// The C compiler to use. + pub cc: Option, + /// The linker to use. + pub ld: Option, + /// Low level codegen settings to pass to Cranelift. + pub cranelift_settings: Vec, +} + +impl SessionRequest { + pub fn new() -> SessionRequestBuilder { + SessionRequestBuilder::default() + } +} diff --git a/montyc_driver/src/typeck/block_cfg.rs b/montyc_driver/src/typeck/block_cfg.rs index b2b34ab..65ad2ad 100644 --- a/montyc_driver/src/typeck/block_cfg.rs +++ b/montyc_driver/src/typeck/block_cfg.rs @@ -1,12 +1,11 @@ -use crate::global_context::SessionContext; +use crate::session_context::SessionContext; -use super::cfg_reducer::GraphLike; use super::variable_flowgraph::VariableFlowGraph; use super::{FlatInst, NodeIndex, RawInst}; pub(crate) type BlockCFG = petgraph::graph::Graph, BlockCFGEdge>; -impl GraphLike for BlockCFG { +impl crate::cfg_reducer::GraphLike for BlockCFG { fn n_nodes(&self) -> usize { self.raw_nodes().len() } diff --git a/montyc_driver/src/typeck/mod.rs b/montyc_driver/src/typeck/mod.rs index 6bddd17..86b4539 100644 --- a/montyc_driver/src/typeck/mod.rs +++ b/montyc_driver/src/typeck/mod.rs @@ -13,16 +13,15 @@ use montyc_parser::ast::{AstNode, Constant}; use montyc_query::Queries; use petgraph::{data::DataMap, graph::NodeIndex, EdgeDirection}; -use crate::global_context::SessionContext; -use crate::global_context::SessionMode; +use crate::cfg_reducer::CFGReducer; +use crate::session_context::SessionContext; +use crate::session_context::SessionMode; mod block_cfg; -mod cfg_reducer; mod typing_machine; mod variable_flowgraph; use block_cfg::BlockCFG; -use cfg_reducer::CFGReducer; use typing_machine::TypingMachine; /// run through a sequence of instructions and group linear sequences of instructions into "blocks" diff --git a/montyc_driver/src/typeck/typing_machine.rs b/montyc_driver/src/typeck/typing_machine.rs index dabdc85..fc7040d 100644 --- a/montyc_driver/src/typeck/typing_machine.rs +++ b/montyc_driver/src/typeck/typing_machine.rs @@ -7,10 +7,10 @@ use montyc_query::Queries; use petgraph::graph::NodeIndex; use petgraph::visit::EdgeRef; -use crate::global_context::SessionContext; +use crate::session_context::SessionContext; +use super::block_cfg::BlockCFGBuilder; use super::*; -use super::{block_cfg::BlockCFGBuilder, cfg_reducer::CFGReducer}; /// Akin to Pytype's VM this is a virtual machine for abstract interpretation of code. #[derive(Debug)] @@ -595,7 +595,7 @@ impl TypingMachine { } } -impl CFGReducer for TypingMachine { +impl crate::cfg_reducer::CFGReducer for TypingMachine { type InputGraphT = BlockCFG; type OutputT = montyc_core::codegen::CgBlockCFG; type IndexT = NodeIndex; diff --git a/montyc_driver/src/typeck/variable_flowgraph.rs b/montyc_driver/src/typeck/variable_flowgraph.rs index d11cc26..2ee5ca5 100644 --- a/montyc_driver/src/typeck/variable_flowgraph.rs +++ b/montyc_driver/src/typeck/variable_flowgraph.rs @@ -2,9 +2,11 @@ use montyc_core::MontyResult; use montyc_flatcode::raw_inst::RawInst; use petgraph::{graph::NodeIndex, visit::EdgeRef, EdgeDirection}; -use crate::{global_context::SessionContext, typeck::block_cfg::BlockCFGBuilder}; +use crate::{ + cfg_reducer::CFGReducer, session_context::SessionContext, typeck::block_cfg::BlockCFGBuilder, +}; -use super::{block_cfg::BlockCFG, cfg_reducer::CFGReducer}; +use super::block_cfg::BlockCFG; #[derive(Debug, Clone)] pub enum DefPlace { @@ -25,7 +27,7 @@ struct VFGBuilder { inp: BlockCFGBuilder, } -impl CFGReducer for VFGBuilder { +impl crate::cfg_reducer::CFGReducer for VFGBuilder { type IndexT = NodeIndex; type InputGraphT = BlockCFG; @@ -50,7 +52,7 @@ impl CFGReducer for VFGBuilder { fn visit_block( &mut self, - cx: &crate::global_context::SessionContext, + cx: &crate::session_context::SessionContext, output: &mut Self::OutputT, ix: Self::IndexT, _errors: &mut Vec, diff --git a/montyc_query/src/lib.rs b/montyc_query/src/lib.rs index 6854b45..2a2e372 100644 --- a/montyc_query/src/lib.rs +++ b/montyc_query/src/lib.rs @@ -3,11 +3,9 @@ use std::{alloc::Layout, fmt}; -use montyc_core::{ - span::SpanRef, - value::{TaggedValueId, ValueId}, - Function, ModuleData, ModuleRef, MontyError, Qualname, TypeId, TypingContext, Value, FUNCTION, -}; +use montyc_core::span::SpanRef; +use montyc_core::value::{TaggedValueId, ValueId}; +use montyc_core::{Function, ModuleData, ModuleRef, MontyError, TypeId, TypingContext, FUNCTION}; use montyc_flatcode::{FlatCode, FlatSeq}; use montyc_parser::ast::Constant; @@ -34,15 +32,6 @@ pub trait Queries { /// Given a `ModuleRef` try and get its associated module data. fn get_module_data(&self, mref: ModuleRef) -> MontyResult; - /// get the fully qualified name for this function. - fn get_qualname_of(&self, func: TaggedValueId) -> Qualname; - - /// get the value from its value_id. - fn get_value(&self, value_id: ValueId) -> Option; - - /// get the associated namespace rib of a value. - fn get_rib_of<'a>(&'a self, value_id: ValueId) -> Option<&'a montyc_core::Rib>; - /// Get specified modules flatcode. fn get_module_flatcode(&self, mref: ModuleRef) -> MontyResult; @@ -58,9 +47,6 @@ pub trait Queries { /// Get the associated function for this value. fn get_function(&self, value_id: ValueId) -> MontyResult; - /// Get the computed value produced and assigned to a distinct ident spanref. - fn spanref_to_value(&self, sref: SpanRef) -> MontyResult; - /// Given a `SpanRef` try and resolve it to its corresponding string slice. fn spanref_to_str(&self, sref: SpanRef) -> MontyResult;