Skip to content

Commit

Permalink
More merges
Browse files Browse the repository at this point in the history
  • Loading branch information
prozacchiwawa committed May 8, 2024
1 parent 3b7f851 commit b413e5c
Show file tree
Hide file tree
Showing 15 changed files with 507 additions and 265 deletions.
14 changes: 7 additions & 7 deletions src/compiler/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1009,7 +1009,7 @@ fn generate_let_defun(
// binary size, when permitted. Sometimes the user will signal a
// preference.
should_inline_let(inline_hint),
DefunData {
Box::new(DefunData {
loc: l.clone(),
nl: l,
kw: kwl,
Expand All @@ -1019,7 +1019,7 @@ fn generate_let_defun(
body,
synthetic: Some(SyntheticType::NoInlinePreference),
ty: None,
},
}),
)
}

Expand Down Expand Up @@ -1313,7 +1313,7 @@ pub fn hoist_body_let_binding(
let new_expr = lambda_codegen(&new_function_name, letdata)?;
let function = HelperForm::Defun(
false,
DefunData {
Box::new(DefunData {
loc: letdata.loc.clone(),
name: new_function_name,
kw: letdata.kw.clone(),
Expand All @@ -1323,7 +1323,7 @@ pub fn hoist_body_let_binding(
body: new_body,
synthetic: Some(SyntheticType::WantNonInline),
ty: None,
},
}),
);
new_helpers_from_body.push(function);
Ok((new_helpers_from_body, Rc::new(new_expr)))
Expand Down Expand Up @@ -1355,11 +1355,11 @@ pub fn process_helper_let_bindings(helpers: &[HelperForm]) -> Result<Vec<HelperF

result[i] = HelperForm::Defun(
inline,
DefunData {
Box::new(DefunData {
body: hoisted_body,
ty: defun.ty.clone(),
..defun.clone()
},
..*defun.clone()
}),
);

i += 1;
Expand Down
22 changes: 17 additions & 5 deletions src/compiler/compiler.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use num_bigint::ToBigInt;
use std::borrow::Borrow;
use std::collections::HashMap;
use std::collections::{HashMap, HashSet};
use std::fs;
use std::path::PathBuf;
use std::rc::Rc;
Expand Down Expand Up @@ -31,6 +31,8 @@ use crate::compiler::srcloc::Srcloc;
use crate::compiler::{BasicCompileContext, CompileContextWrapper};
use crate::util::Number;

pub const FUZZ_TEST_PRE_CSE_MERGE_FIX_FLAG: usize = 1;

lazy_static! {
pub static ref STANDARD_MACROS: String = {
indoc! {"(
Expand Down Expand Up @@ -119,6 +121,7 @@ pub struct DefaultCompilerOpts {
pub start_env: Option<Rc<SExp>>,
pub disassembly_ver: Option<usize>,
pub prim_map: Rc<HashMap<Vec<u8>, Rc<SExp>>>,
pub diag_flags: Rc<HashSet<usize>>,
pub dialect: AcceptedDialect,
}

Expand Down Expand Up @@ -464,7 +467,7 @@ pub fn compile_module(
)));
program.helpers.push(HelperForm::Defun(
false,
DefunData {
Box::new(DefunData {
loc: dd.loc.clone(),
kw: None,
nl: dd.nl.clone(),
Expand All @@ -474,7 +477,7 @@ pub fn compile_module(
body: form_hash_expression(make_hash_of),
synthetic: Some(SyntheticType::WantNonInline),
ty: None,
},
}),
));
} else if let Some(HelperForm::Defconstant(dc)) = &exported {
let mut new_name = fun_name.clone();
Expand All @@ -501,7 +504,7 @@ pub fn compile_module(

program.helpers.push(HelperForm::Defun(
true,
DefunData {
Box::new(DefunData {
loc: dc.loc.clone(),
nl: dc.nl.clone(),
kw: None,
Expand All @@ -511,7 +514,7 @@ pub fn compile_module(
body: Rc::new(BodyForm::Value(SExp::Atom(dc.loc.clone(), new_name))),
synthetic: Some(SyntheticType::NoInlinePreference),
ty: None,
},
}),
));
} else {
return Err(CompileErr(
Expand Down Expand Up @@ -660,6 +663,9 @@ impl CompilerOpts for DefaultCompilerOpts {
fn get_search_paths(&self) -> Vec<String> {
self.include_dirs.clone()
}
fn diag_flags(&self) -> Rc<HashSet<usize>> {
self.diag_flags.clone()
}

fn set_dialect(&self, dialect: AcceptedDialect) -> Rc<dyn CompilerOpts> {
let mut copy = self.clone();
Expand Down Expand Up @@ -717,6 +723,11 @@ impl CompilerOpts for DefaultCompilerOpts {
Rc::new(copy)
}

fn set_diag_flags(&self, flags: Rc<HashSet<usize>>) -> Rc<dyn CompilerOpts> {
let mut copy = self.clone();
copy.diag_flags = flags;
Rc::new(copy)
}
fn read_new_file(
&self,
inc_from: String,
Expand Down Expand Up @@ -792,6 +803,7 @@ impl DefaultCompilerOpts {
dialect: AcceptedDialect::default(),
prim_map: create_prim_map(),
disassembly_ver: None,
diag_flags: Rc::new(HashSet::default()),
}
}
}
Expand Down
218 changes: 217 additions & 1 deletion src/compiler/comptypes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -754,7 +754,7 @@ pub enum HelperForm {
/// A macro definition (see DefmacData).
Defmacro(DefmacData),
/// A function definition (see DefunData).
Defun(bool, DefunData),
Defun(bool, Box<DefunData>),
}

#[test]
Expand Down Expand Up @@ -952,6 +952,9 @@ pub trait CompilerOpts {
fn prim_map(&self) -> Rc<HashMap<Vec<u8>, Rc<SExp>>>;
/// Specifies the search paths we're carrying.
fn get_search_paths(&self) -> Vec<String>;
/// Specifies flags that were passed down to various consumers. This is
/// open ended for various purposes, such as diagnostics.
fn diag_flags(&self) -> Rc<HashSet<usize>>;

/// Set the dialect.
fn set_dialect(&self, dialect: AcceptedDialect) -> Rc<dyn CompilerOpts>;
Expand All @@ -976,6 +979,8 @@ pub trait CompilerOpts {
fn set_start_env(&self, start_env: Option<Rc<SExp>>) -> Rc<dyn CompilerOpts>;
/// Set the primitive map in use so we can add custom primitives.
fn set_prim_map(&self, new_map: Rc<HashMap<Vec<u8>, Rc<SExp>>>) -> Rc<dyn CompilerOpts>;
/// Set the flags this CompilerOpts holds. Consumers can examine these.
fn set_diag_flags(&self, new_flags: Rc<HashSet<usize>>) -> Rc<dyn CompilerOpts>;

/// Using the search paths list we have, try to read a file by name,
/// Returning the expanded path to the file and its content.
Expand All @@ -997,6 +1002,217 @@ pub trait CompilerOpts {
) -> Result<CompilerOutput, CompileErr>;
}

/// A trait that simplifies implementing one's own CompilerOpts personality.
/// This specifies to a CompilerOptsDelegator that this object contains a
/// CompilerOpts that it uses for most of what it does, allowing end users
/// to opt into a default implementation of all the methods via
/// CompilerOptsDelegator and override only what's desired.
pub trait HasCompilerOptsDelegation {
/// Get this object's inner CompilerOpts.
fn compiler_opts(&self) -> Rc<dyn CompilerOpts>;
/// Call a function that updates this object's CompilerOpts and use the
/// update our own object with the result. Return the new wrapper.
fn update_compiler_opts<F: FnOnce(Rc<dyn CompilerOpts>) -> Rc<dyn CompilerOpts>>(
&self,
f: F,
) -> Rc<dyn CompilerOpts>;

// Defaults.
fn override_filename(&self) -> String {
self.compiler_opts().filename()
}
fn override_code_generator(&self) -> Option<PrimaryCodegen> {
self.compiler_opts().code_generator()
}
fn override_dialect(&self) -> AcceptedDialect {
self.compiler_opts().dialect()
}
fn override_disassembly_ver(&self) -> Option<usize> {
self.compiler_opts().disassembly_ver()
}
fn override_in_defun(&self) -> bool {
self.compiler_opts().in_defun()
}
fn override_stdenv(&self) -> bool {
self.compiler_opts().stdenv()
}
fn override_optimize(&self) -> bool {
self.compiler_opts().optimize()
}
fn override_frontend_opt(&self) -> bool {
self.compiler_opts().frontend_opt()
}
fn override_frontend_check_live(&self) -> bool {
self.compiler_opts().frontend_check_live()
}
fn override_start_env(&self) -> Option<Rc<SExp>> {
self.compiler_opts().start_env()
}
fn override_prim_map(&self) -> Rc<HashMap<Vec<u8>, Rc<SExp>>> {
self.compiler_opts().prim_map()
}
fn override_get_search_paths(&self) -> Vec<String> {
self.compiler_opts().get_search_paths()
}
fn override_diag_flags(&self) -> Rc<HashSet<usize>> {
self.compiler_opts().diag_flags()
}

fn override_set_dialect(&self, dialect: AcceptedDialect) -> Rc<dyn CompilerOpts> {
self.update_compiler_opts(|o| o.set_dialect(dialect))
}
fn override_set_search_paths(&self, dirs: &[String]) -> Rc<dyn CompilerOpts> {
self.update_compiler_opts(|o| o.set_search_paths(dirs))
}
fn override_set_disassembly_ver(&self, ver: Option<usize>) -> Rc<dyn CompilerOpts> {
self.update_compiler_opts(|o| o.set_disassembly_ver(ver))
}
fn override_set_in_defun(&self, new_in_defun: bool) -> Rc<dyn CompilerOpts> {
self.update_compiler_opts(|o| o.set_in_defun(new_in_defun))
}
fn override_set_stdenv(&self, new_stdenv: bool) -> Rc<dyn CompilerOpts> {
self.update_compiler_opts(|o| o.set_stdenv(new_stdenv))
}
fn override_set_optimize(&self, opt: bool) -> Rc<dyn CompilerOpts> {
self.update_compiler_opts(|o| o.set_optimize(opt))
}
fn override_set_frontend_opt(&self, opt: bool) -> Rc<dyn CompilerOpts> {
self.update_compiler_opts(|o| o.set_frontend_opt(opt))
}
fn override_set_frontend_check_live(&self, check: bool) -> Rc<dyn CompilerOpts> {
self.update_compiler_opts(|o| o.set_frontend_check_live(check))
}
fn override_set_code_generator(&self, new_compiler: PrimaryCodegen) -> Rc<dyn CompilerOpts> {
self.update_compiler_opts(|o| o.set_code_generator(new_compiler))
}
fn override_set_start_env(&self, start_env: Option<Rc<SExp>>) -> Rc<dyn CompilerOpts> {
self.update_compiler_opts(|o| o.set_start_env(start_env))
}
fn override_set_diag_flags(&self, flags: Rc<HashSet<usize>>) -> Rc<dyn CompilerOpts> {
self.update_compiler_opts(|o| o.set_diag_flags(flags))
}
fn override_set_prim_map(
&self,
new_map: Rc<HashMap<Vec<u8>, Rc<SExp>>>,
) -> Rc<dyn CompilerOpts> {
self.update_compiler_opts(|o| o.set_prim_map(new_map))
}
fn override_read_new_file(
&self,
inc_from: String,
filename: String,
) -> Result<(String, Vec<u8>), CompileErr> {
self.compiler_opts().read_new_file(inc_from, filename)
}
fn override_write_new_file(&self, target_path: &str, content: &[u8]) -> Result<(), CompileErr> {
self.compiler_opts().write_new_file(target_path, content)
}
fn override_compile_program(
&self,
context: &mut BasicCompileContext,
sexp: Rc<SExp>,
) -> Result<CompilerOutput, CompileErr> {
self.compiler_opts().compile_program(context, sexp)
}
}

impl<T: HasCompilerOptsDelegation> CompilerOpts for T {
// Defaults.
fn filename(&self) -> String {
self.override_filename()
}
fn code_generator(&self) -> Option<PrimaryCodegen> {
self.override_code_generator()
}
fn dialect(&self) -> AcceptedDialect {
self.override_dialect()
}
fn disassembly_ver(&self) -> Option<usize> {
self.override_disassembly_ver()
}
fn in_defun(&self) -> bool {
self.override_in_defun()
}
fn stdenv(&self) -> bool {
self.override_stdenv()
}
fn optimize(&self) -> bool {
self.override_optimize()
}
fn frontend_opt(&self) -> bool {
self.override_frontend_opt()
}
fn frontend_check_live(&self) -> bool {
self.override_frontend_check_live()
}
fn start_env(&self) -> Option<Rc<SExp>> {
self.override_start_env()
}
fn prim_map(&self) -> Rc<HashMap<Vec<u8>, Rc<SExp>>> {
self.override_prim_map()
}
fn get_search_paths(&self) -> Vec<String> {
self.override_get_search_paths()
}
fn diag_flags(&self) -> Rc<HashSet<usize>> {
self.override_diag_flags()
}

fn set_dialect(&self, dialect: AcceptedDialect) -> Rc<dyn CompilerOpts> {
self.override_set_dialect(dialect)
}
fn set_search_paths(&self, dirs: &[String]) -> Rc<dyn CompilerOpts> {
self.override_set_search_paths(dirs)
}
fn set_disassembly_ver(&self, ver: Option<usize>) -> Rc<dyn CompilerOpts> {
self.override_set_disassembly_ver(ver)
}
fn set_in_defun(&self, new_in_defun: bool) -> Rc<dyn CompilerOpts> {
self.override_set_in_defun(new_in_defun)
}
fn set_stdenv(&self, new_stdenv: bool) -> Rc<dyn CompilerOpts> {
self.override_set_stdenv(new_stdenv)
}
fn set_optimize(&self, opt: bool) -> Rc<dyn CompilerOpts> {
self.override_set_optimize(opt)
}
fn set_frontend_opt(&self, opt: bool) -> Rc<dyn CompilerOpts> {
self.override_set_frontend_opt(opt)
}
fn set_frontend_check_live(&self, check: bool) -> Rc<dyn CompilerOpts> {
self.override_set_frontend_check_live(check)
}
fn set_code_generator(&self, new_compiler: PrimaryCodegen) -> Rc<dyn CompilerOpts> {
self.override_set_code_generator(new_compiler)
}
fn set_start_env(&self, start_env: Option<Rc<SExp>>) -> Rc<dyn CompilerOpts> {
self.override_set_start_env(start_env)
}
fn set_prim_map(&self, new_map: Rc<HashMap<Vec<u8>, Rc<SExp>>>) -> Rc<dyn CompilerOpts> {
self.override_set_prim_map(new_map)
}
fn set_diag_flags(&self, new_flags: Rc<HashSet<usize>>) -> Rc<dyn CompilerOpts> {
self.override_set_diag_flags(new_flags)
}
fn read_new_file(
&self,
inc_from: String,
filename: String,
) -> Result<(String, Vec<u8>), CompileErr> {
self.override_read_new_file(inc_from, filename)
}
fn compile_program(
&self,
context: &mut BasicCompileContext,
sexp: Rc<SExp>,
) -> Result<CompilerOutput, CompileErr> {
self.override_compile_program(context, sexp)
}
fn write_new_file(&self, target_path: &str, content: &[u8]) -> Result<(), CompileErr> {
self.override_write_new_file(target_path, content)
}
}

/// Frontend uses this to accumulate frontend forms, used internally.
#[derive(Debug, Clone)]
pub struct ModAccum {
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/evaluate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1299,7 +1299,7 @@ impl<'info> Evaluator {
for h in self.helpers.iter() {
if let HelperForm::Defun(false, dd) = &h {
if name == h.name() {
return Some(Box::new(dd.clone()));
return Some(dd.clone());
}
}
}
Expand Down

0 comments on commit b413e5c

Please sign in to comment.