Skip to content
Open
4 changes: 2 additions & 2 deletions bitcoind-tests/tests/common/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ type FnWitness = fn([u8; 32]) -> simplicityhl::WitnessValues;

pub struct TestCase<'a> {
pub name: &'static str,
template: Option<simplicityhl::TemplateProgram>,
template: Option<simplicityhl::TemplateAst>,
compiled: Option<simplicityhl::CompiledProgram>,
witness: FnWitness,
lock_time: elements::LockTime,
Expand Down Expand Up @@ -67,7 +67,7 @@ impl<'a> TestCase<'a> {
pub fn template_path<P: AsRef<std::path::Path>>(mut self, path: P) -> Self {
let text = std::fs::read_to_string(path).expect("path should be readable");
let template =
simplicityhl::TemplateProgram::new(text.as_str(), Box::new(ElementsJetHinter::new()))
simplicityhl::TemplateAst::new(text.as_str(), Box::new(ElementsJetHinter::new()))
.expect("program should compile");
self.template = Some(template);
self
Expand Down
6 changes: 3 additions & 3 deletions external-jet-lib-example/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@ unsafe {

### 4. Pass `ExternalJetHinter` to the compiler

`ExternalJetHinter` implements `JetHinter` and delegates `parse_jet` / `construct_verify` to the loaded library. Pass it when constructing a `TemplateProgram`:
`ExternalJetHinter` implements `JetHinter` and delegates `parse_jet` / `construct_verify` to the loaded library. Pass it when constructing a `TemplateAst`:

```rust
use simplicityhl::{jet::external::ExternalJetHinter, TemplateProgram};
use simplicityhl::{jet::external::ExternalJetHinter, TemplateAst};

let program = TemplateProgram::new(simf_code, Box::new(ExternalJetHinter::new()))
let program = TemplateAst::new(simf_code, Box::new(ExternalJetHinter::new()))
.expect("compilation failed");
```

Expand Down
4 changes: 2 additions & 2 deletions external-jet-lib-example/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
//! loads and runs native code from the given path. Only point it at libraries
//! you trust.

use simplicityhl::{jet::external::ExternalJetHinter, TemplateProgram};
use simplicityhl::{jet::external::ExternalJetHinter, TemplateAst};

/// Loads the external jet library named on the command line and compiles a tiny
/// SimplicityHL program against it.
Expand All @@ -45,7 +45,7 @@ fn main() {
// (`parse_jet`, `construct_verify`, `conjure`) to the loaded library; here
// `assert!(true)` is lowered via `construct_verify` to the library's
// `verify` jet.
let _ = TemplateProgram::new(code, Box::new(ExternalJetHinter::new()))
let _ = TemplateAst::new(code, Box::new(ExternalJetHinter::new()))
.expect("failed to compile code with external jets");

println!("External jets were successfully used to compile:\n{}", code);
Expand Down
11 changes: 8 additions & 3 deletions fuzz/fuzz_targets/compile_parse_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ fn do_test(data: &[u8]) {
use arbitrary::Arbitrary;
use simplicityhl::ast::ElementsJetHinter;

use simplicityhl::{ast, named, parse, ArbitraryOfType, Arguments};
use simplicityhl::{ast, named, parse, ArbitraryOfType, Arguments, WitnessNameToValueMap as _};

let mut u = arbitrary::Unstructured::new(data);
let parse_program = match parse::Program::arbitrary(&mut u) {
Expand All @@ -22,8 +22,13 @@ fn do_test(data: &[u8]) {
Err(..) => return,
};
let simplicity_named_construct = ast_program
.compile(arguments, false, Box::new(ElementsJetHinter::new()))
.expect("AST should compile with given arguments");
.compile(
arguments.shallow_clone(),
false,
Box::new(ElementsJetHinter::new()),
)
.expect("AST should compile with given arguments")
.instantiate(arguments);
let _simplicity_commit = named::forget_names(&simplicity_named_construct);
}

Expand Down
12 changes: 5 additions & 7 deletions fuzz/fuzz_targets/compile_text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,11 @@ fn do_test(data: &[u8]) -> libfuzzer_sys::Corpus {
if slow_input(&program_text) {
return Corpus::Reject;
}
let template = match simplicityhl::TemplateProgram::new(
program_text,
Box::new(ElementsJetHinter::new()),
) {
Ok(x) => x,
Err(..) => return Corpus::Keep,
};
let template =
match simplicityhl::TemplateAst::new(program_text, Box::new(ElementsJetHinter::new())) {
Ok(x) => x,
Err(..) => return Corpus::Keep,
};
let arguments = match Arguments::arbitrary_of_type(&mut u, template.parameters()) {
Ok(arguments) => arguments,
Err(..) => return Corpus::Reject,
Expand Down
65 changes: 37 additions & 28 deletions src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,14 @@ use crate::jet::{source_type, target_type, JetHL};
use crate::num::{NonZeroPow2Usize, Pow2Usize};
use crate::parse::{MatchPattern, UseDecl, Visibility};
use crate::pattern::Pattern;
use crate::str::{AliasName, FunctionName, Identifier, ModuleName, SymbolName, WitnessName};
use crate::str::{AliasName, FunctionName, Identifier, ModuleName, SymbolName};
use crate::types::{
AliasedType, EnumInfo, EnumVariantInfo, ResolvedType, StructuralType, TypeConstructible,
TypeDeconstructible, TypeInner, UIntType,
};
use crate::value::{UIntValue, Value};
use crate::witness::{Parameters, WitnessTypes};
use crate::TemplateProgramWitness;
use crate::{impl_eq_hash, parse};

/// A program consists of the main function.
Expand Down Expand Up @@ -227,9 +228,9 @@ pub enum SingleExpressionInner {
/// Constant value.
Constant(Value),
/// Witness value.
Witness(WitnessName),
Witness(TemplateProgramWitness),
/// Parameter value.
Parameter(WitnessName),
Parameter(TemplateProgramWitness),
/// Variable that has been assigned a value.
Variable(Identifier),
/// Expression in parentheses.
Expand Down Expand Up @@ -725,8 +726,8 @@ struct Scope {

/// Block-level variable scopes. Push on block enter, pop on block exit.
variables: Vec<HashMap<Identifier, ResolvedType>>,
parameters: HashMap<WitnessName, ResolvedType>,
witnesses: HashMap<WitnessName, ResolvedType>,
parameters: HashMap<TemplateProgramWitness, ResolvedType>,
witnesses: HashMap<TemplateProgramWitness, ResolvedType>,
/// Allow enum constructions to name an enum by its declared name even
/// when that name is not an alias in scope. Enabled only for value
/// parsing (witness and argument files), which runs without a scope.
Expand Down Expand Up @@ -878,7 +879,7 @@ impl Scope {
/// * May also return errors propagated from item collection and insertion, such as [`Error::PrivateItem`] or [`Error::RedefinedItem`].
pub fn resolve_use(&mut self, use_decl: &UseDecl) -> Result<(), Error> {
let path = use_decl.path();
if path.first().map(|id| id.as_inner()) != Some(CRATE_STR) {
if path.first().map(|id| id.as_str()) != Some(CRATE_STR) {
return Err(Error::MissingCrateKeyword);
}

Expand All @@ -898,13 +899,13 @@ impl Scope {
.module_path
.iter()
.zip(&path[1..])
.take_while(|(curr, nav)| curr.as_inner() == nav.as_inner())
.take_while(|(curr, nav)| curr.as_str() == nav.as_str())
.count();

let mut target_scope = &self.root;

for (ind, segment) in path[1..].iter().enumerate() {
let name = ModuleName::from_str_unchecked(segment.as_inner());
let name = ModuleName::from_ident(segment);

let (inner, visibility) = target_scope
.submodules
Expand All @@ -920,7 +921,7 @@ impl Scope {

let mut collected = Vec::with_capacity(use_decl_items.len());
for (name, aliased) in use_decl_items {
if aliased.as_ref().is_some_and(|a| a.as_inner() == MAIN_STR) {
if aliased.as_ref().is_some_and(|a| a == MAIN_STR) {
return Err(Error::MainCannotBeAlias);
}

Expand Down Expand Up @@ -1127,7 +1128,7 @@ impl Scope {
) -> Result<(), Error> {
self.check_alias_free(&name)?;

let info = EnumInfo::new(Arc::from(name.as_inner()), variants);
let info = EnumInfo::new(Arc::clone(name.as_inner()), variants);
let resolved = ResolvedType::enumeration(info);

self.current_module_mut()
Expand All @@ -1142,7 +1143,11 @@ impl Scope {
/// ## Errors
///
/// * [`Error::ExpressionTypeMismatch`] A parameter of the same name has already been defined as a different type.
pub fn insert_parameter(&mut self, name: WitnessName, ty: ResolvedType) -> Result<(), Error> {
pub fn insert_parameter(
&mut self,
name: TemplateProgramWitness,
ty: ResolvedType,
) -> Result<(), Error> {
match self.parameters.entry(name.clone()) {
Entry::Occupied(entry) if entry.get() == &ty => Ok(()),
Entry::Occupied(entry) => Err(Error::ExpressionTypeMismatch {
Expand All @@ -1162,7 +1167,11 @@ impl Scope {
///
/// * [`Error::WitnessOutsideMain`] The current scope is not inside the main function.
/// * [`Error::WitnessReused`] A witness with the same name has already been defined.
pub fn insert_witness(&mut self, name: WitnessName, ty: ResolvedType) -> Result<(), Error> {
pub fn insert_witness(
&mut self,
name: TemplateProgramWitness,
ty: ResolvedType,
) -> Result<(), Error> {
if !self.is_main {
return Err(Error::WitnessOutsideMain);
}
Expand Down Expand Up @@ -1402,7 +1411,7 @@ impl AbstractSyntaxTree for Function {
"Variables live only inside the function"
);

if from.name().as_inner() != MAIN_STR {
if from.name() != MAIN_STR {
let params = from
.params()
.iter()
Expand Down Expand Up @@ -1554,7 +1563,7 @@ fn analyze_enum_construction(
let written = construction.enum_path_string();
let names_expected_enum = match construction.enum_path() {
[single] => {
let alias = AliasName::from_str_unchecked(single.as_inner());
let alias = AliasName::from_ident(single);
match scope.get_alias(&alias) {
Ok(resolved) if &resolved == ty => true,
Ok(resolved) => {
Expand All @@ -1578,7 +1587,7 @@ fn analyze_enum_construction(

let (variant_index, variant) = info
.variant(construction.variant())
.ok_or_else(|| enum_variant_error(construction.variant().as_inner(), info))
.ok_or_else(|| enum_variant_error(construction.variant().as_str(), info))
.with_span(span)?;
if construction.args().len() != variant.payload().len() {
return Err(Error::Grammar {
Expand Down Expand Up @@ -1904,7 +1913,7 @@ impl AbstractSyntaxTree for EnumMatch {
})
.with_span(span);
};
let alias = AliasName::from_str_unchecked(single.as_inner());
let alias = AliasName::from_ident(single);
let enum_ty = scope.get_alias(&alias).with_span(span)?;
let info = match enum_ty.as_enum() {
Some(info) => info.clone(),
Expand Down Expand Up @@ -2977,9 +2986,9 @@ mod module_tests {
"main.simf",
"
pub fn global_func() {}
mod inner {
use crate::global_func;
pub fn call_it() { global_func(); }
mod inner {
use crate::global_func;
pub fn call_it() { global_func(); }
}
fn main() {}
",
Expand Down Expand Up @@ -3021,11 +3030,11 @@ mod module_tests {
let result = analyze_multifile(vec![(
"main.simf",
"
mod brother {
mod brother {
fn secret_toy() {} // Missing 'pub'
}
mod sister {
use crate::brother::secret_toy;
mod sister {
use crate::brother::secret_toy;
}
fn main() {}
",
Expand All @@ -3041,8 +3050,8 @@ mod module_tests {
let result = analyze_multifile(vec![(
"main.simf",
"
mod child {
fn hidden() {}
mod child {
fn hidden() {}
}
use crate::child::hidden;
fn main() {}
Expand Down Expand Up @@ -3080,10 +3089,10 @@ mod module_tests {
#[cfg(test)]
mod enum_tests {
use crate::ast::ElementsJetHinter;
use crate::{TemplateProgram, UnstableFeatures};
use crate::{TemplateAst, UnstableFeatures};

fn analyze(src: &str) -> Result<(), String> {
TemplateProgram::new_with_unstable(
TemplateAst::new_with_unstable(
src,
&UnstableFeatures::all(),
Box::new(ElementsJetHinter::new()),
Expand Down Expand Up @@ -3541,7 +3550,7 @@ mod enum_tests {
fn alias_named_after_pattern_stays_valid_without_enums() {
// Stable programs may alias pattern names; the enums feature must
// not retroactively reject them.
let result = TemplateProgram::new_with_unstable(
let result = TemplateAst::new_with_unstable(
"type Left = u32;\nfn main() { let _x: Left = 1; }",
&UnstableFeatures::none(),
Box::new(ElementsJetHinter::new()),
Expand Down Expand Up @@ -3596,7 +3605,7 @@ mod enum_tests {

#[test]
fn enum_requires_unstable_feature() {
let result = TemplateProgram::new_with_unstable(
let result = TemplateAst::new_with_unstable(
"enum Color { Red, Green }\nfn main() {}",
&UnstableFeatures::none(),
Box::new(ElementsJetHinter::new()),
Expand Down
18 changes: 7 additions & 11 deletions src/compile/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,10 @@ use crate::error::{Diagnostic, Error, Span, WithSpan};
use crate::named::{self, CoreExt, PairBuilder};
use crate::num::{NonZeroPow2Usize, Pow2Usize};
use crate::pattern::{BasePattern, Pattern};
use crate::str::WitnessName;
use crate::template_program::{TemplateProgram, TemplateProgramWitness};
use crate::types::{StructuralType, TypeDeconstructible};
use crate::value::StructuralValue;
use crate::witness::Arguments;
use crate::Value;
use crate::value::{StructuralValue, Value};
use crate::witness::{Arguments, WitnessNameToValueMap as _};

type ProgNode<'brand> = Arc<named::ConstructNode<'brand>>;

Expand Down Expand Up @@ -217,7 +216,7 @@ impl<'brand> Scope<'brand> {
}
}

pub fn get_argument(&self, name: &WitnessName) -> &Value {
pub fn get_argument(&self, name: &TemplateProgramWitness) -> &Value {
self.arguments
.get(name)
.expect("Precondition: Arguments are consistent with parameters")
Expand Down Expand Up @@ -266,7 +265,7 @@ impl Program {
arguments: Arguments,
include_debug_symbols: bool,
jet_hinter: Box<dyn JetHinter>,
) -> Result<Arc<named::CommitNode>, Diagnostic> {
) -> Result<TemplateProgram, Diagnostic> {
types::Context::with_context(|ctx| {
let mut scope = Scope::new(
ctx,
Expand All @@ -276,11 +275,8 @@ impl Program {
jet_hinter,
);

let main = self.main();
let construct = main.compile(&mut scope).map(PairBuilder::build)?;
// SimplicityHL types should be correct by construction. If not, assign the
// whole main function as the span for them, which is as sensible as anything.
named::finalize_types(&construct).with_span(main)
let construct = self.main().compile(&mut scope).map(PairBuilder::build)?;
Ok(TemplateProgram::from_construct_node(&construct))
})
}
}
Expand Down
Loading
Loading