Skip to content

Commit

Permalink
hacking
Browse files Browse the repository at this point in the history
  • Loading branch information
Grant Wuerker committed Dec 20, 2022
1 parent 25218d4 commit a76549b
Show file tree
Hide file tree
Showing 7 changed files with 356 additions and 2 deletions.
16 changes: 16 additions & 0 deletions crates/analyzer/src/namespace/items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,7 @@ pub struct Ingot {
// pub version: SmolStr,
pub mode: IngotMode,
pub src_dir: SmolStr,
pub test_file: SmolStr,
}

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, Clone)]
Expand Down Expand Up @@ -337,6 +338,7 @@ impl IngotId {
name: name.into(),
mode,
src_dir: file_path_prefix.as_str().into(),
test_file: file_path_prefix.parent().unwrap().join("tests.fe").into(),
}));

// Intern the source files
Expand Down Expand Up @@ -676,6 +678,20 @@ impl ModuleId {
.collect::<Vec<_>>()
}

/// All functions, including from submodules and including duplicates
pub fn all_functions(&self, db: &dyn AnalyzerDb) -> Vec<FunctionId> {
self.items(db)
.iter()
.filter_map(|(_, item)| {
if let Item::Function(function) = item {
Some(*function)
} else {
None
}
})
.collect()
}

/// Returns the map of ingot deps, built-ins, and the ingot itself as
/// "ingot".
pub fn global_items(&self, db: &dyn AnalyzerDb) -> IndexMap<SmolStr, Item> {
Expand Down
1 change: 1 addition & 0 deletions crates/codegen/src/yul/isel/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ use crate::{
},
};

// here
pub fn lower_function(
db: &dyn CodegenDb,
ctx: &mut Context,
Expand Down
2 changes: 2 additions & 0 deletions crates/codegen/src/yul/isel/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ pub mod context;
mod contract;
mod function;
mod inst_order;
mod test;

pub use contract::{lower_contract, lower_contract_deployable};
pub use test::lower_test;
pub use function::lower_function;
70 changes: 70 additions & 0 deletions crates/codegen/src/yul/isel/test.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
use super::context::Context;
use fe_analyzer::namespace::items::FunctionId;
use yultsur::{yul, *};
use crate::{
db::CodegenDb,
};

pub fn lower_test(db: &dyn CodegenDb, test: FunctionId) -> yul::Object {
let mut context = Context::default();
let test = db.mir_lowered_func_signature(test);
context.function_dependency.insert(test);

let dep_constants = context.resolve_constant_dependency(db);
let dep_functions: Vec<_> = context
.resolve_function_dependency(db)
.into_iter()
.map(yul::Statement::FunctionDefinition)
.collect();
let runtime_funcs: Vec<_> = context
.runtime
.collect_definitions()
.into_iter()
.map(yul::Statement::FunctionDefinition)
.collect();
let test_func_name = identifier! { (db.codegen_function_symbol_name(test)) };
let call = expression! {[test_func_name]()};

let code = code! {
[dep_functions...]
[runtime_funcs...]
};

let name = identifier! { test };
let object = yul::Object {
name,
code,
objects: vec![],
data: dep_constants,
};

normalize_object(object)

}

fn normalize_object(obj: yul::Object) -> yul::Object {
let data = obj
.data
.into_iter()
.map(|data| yul::Data {
name: data.name,
value: data
.value
.replace('\\', "\\\\\\\\")
.replace('\n', "\\\\n")
.replace('"', "\\\\\"")
.replace('\r', "\\\\r")
.replace('\t', "\\\\t"),
})
.collect::<Vec<_>>();
yul::Object {
name: obj.name,
code: obj.code,
objects: obj
.objects
.into_iter()
.map(normalize_object)
.collect::<Vec<_>>(),
data,
}
}
30 changes: 28 additions & 2 deletions crates/driver/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
pub use fe_codegen::db::{CodegenDb, Db};
//use fe_codegen::yul::runtime::RuntimeProvider;

use fe_analyzer::namespace::items::{IngotId, IngotMode, ModuleId};
use fe_analyzer::namespace::items::{IngotId, IngotMode, ModuleId, FunctionId};
use fe_analyzer::AnalyzerDb;
use fe_analyzer::{context::Analysis, namespace::items::ContractId};
use fe_common::db::Upcast;
Expand All @@ -22,6 +22,7 @@ pub struct CompiledModule {
pub src_ast: String,
pub lowered_ast: String,
pub contracts: IndexMap<String, CompiledContract>,
pub tests: IndexMap<String, String>,
}

/// The artifacts of a compiled contract.
Expand Down Expand Up @@ -57,6 +58,24 @@ pub fn compile_single_file(
}
}

pub fn compile_test_file(
db: &mut Db,
path: &str,
src: &str,
optimize: bool,
) -> Result<Vec<String>, CompileError> {
let module = ModuleId::new_standalone(db, path, src);
let diags = module.diagnostics(db);

if diags.is_empty() {
let test = compile_test_to_yul(db, module.all_functions(db)[0]);
compile_to_evm("test", &test, optimize);
Err(CompileError(diags))
} else {
Err(CompileError(diags))
}
}

// Run analysis with ingot
// Return vector error,waring...
pub fn check_ingot(
Expand Down Expand Up @@ -108,7 +127,8 @@ pub fn compile_ingot(
let main_module = ingot
.root_module(db)
.expect("missing root module, with no diagnostic");
compile_module_id(db, main_module, with_bytecode, optimize)
let mut module = compile_module_id(db, main_module, with_bytecode, optimize)?;
Ok(module)
}

/// Returns graphviz string.
Expand Down Expand Up @@ -160,6 +180,7 @@ fn compile_module_id(
src_ast: format!("{:#?}", module_id.ast(db)),
lowered_ast: format!("{:#?}", module_id.ast(db)),
contracts,
tests: IndexMap::new(),
})
}

Expand Down Expand Up @@ -197,6 +218,11 @@ fn compile_to_yul(db: &mut Db, contract: ContractId) -> String {
yul_contract.to_string().replace('"', "\\\"")
}

fn compile_test_to_yul(db: &mut Db, test: FunctionId) -> String {
let yul_test = fe_codegen::yul::isel::lower_test(db, test);
yul_test.to_string().replace('"', "\\\"")
}

#[cfg(feature = "solc-backend")]
fn compile_to_evm(name: &str, yul_object: &str, optimize: bool) -> String {
match fe_yulc::compile_single_contract(name, yul_object, optimize) {
Expand Down
Loading

0 comments on commit a76549b

Please sign in to comment.