test_compiler.rs
1 // Copyright (C) 2019-2025 ADnet Contributors 2 // This file is part of the ADL library. 3 4 // The ADL library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 9 // The ADL library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 14 // You should have received a copy of the GNU General Public License 15 // along with the ADL library. If not, see <https://www.gnu.org/licenses/>. 16 17 use adl_disassembler::disassemble_from_str; 18 use adl_errors::{AdlError, BufferEmitter, Handler}; 19 use adl_span::{Symbol, create_session_if_not_set_then}; 20 21 use snarkvm::{ 22 prelude::{Process, TestnetV0}, 23 synthesizer::program::ProgramCore, 24 }; 25 26 use indexmap::IndexMap; 27 use itertools::Itertools as _; 28 use serial_test::serial; 29 use std::str::FromStr; 30 31 fn run_test(test: &str, handler: &Handler) -> Result<String, ()> { 32 // Initialize a `Process`. This should always succeed. 33 let mut process = Process::<TestnetV0>::load().unwrap(); 34 35 let mut import_stubs = IndexMap::new(); 36 37 let mut bytecodes = Vec::<String>::new(); 38 39 // Compile each source file separately. 40 for source in test.split(super::test_utils::PROGRAM_DELIMITER) { 41 let (bytecode, program_name) = 42 handler.extend_if_error(super::test_utils::whole_compile(source, handler, import_stubs.clone()))?; 43 44 // Parse the bytecode as an Aleo program. 45 // Note that this function checks that the bytecode is well-formed. 46 let alpha_program = handler.extend_if_error(ProgramCore::from_str(&bytecode).map_err(AdlError::Anyhow))?; 47 48 // Add the program to the process. 49 // Note that this function performs an additional validity check on the bytecode. 50 handler.extend_if_error(process.add_program(&alpha_program).map_err(AdlError::Anyhow))?; 51 52 // Add the bytecode to the import stubs. 53 let stub = handler 54 .extend_if_error(disassemble_from_str::<TestnetV0>(&program_name, &bytecode).map_err(|err| err.into()))?; 55 import_stubs.insert(Symbol::intern(&program_name), stub); 56 57 // Only error out if there are errors. Warnings are okay but we still want to print them later. 58 if handler.err_count() != 0 { 59 return Err(()); 60 } 61 62 bytecodes.push(bytecode); 63 } 64 65 Ok(bytecodes.iter().format(&format!("{}\n", super::test_utils::PROGRAM_DELIMITER)).to_string()) 66 } 67 68 fn runner(source: &str) -> String { 69 let buf = BufferEmitter::new(); 70 let handler = Handler::new(buf.clone()); 71 72 create_session_if_not_set_then(|_| match run_test(source, &handler) { 73 Ok(x) => format!("{}{}", buf.extract_warnings(), x), 74 Err(()) => format!("{}{}", buf.extract_errs(), buf.extract_warnings()), 75 }) 76 } 77 78 #[test] 79 #[serial] 80 fn test_compiler() { 81 adl_test_framework::run_tests("compiler", runner); 82 }