Skip to content

Commit

Permalink
Add exposing renaming
Browse files Browse the repository at this point in the history
  • Loading branch information
prozacchiwawa committed Jan 19, 2024
1 parent 091267c commit 74c770e
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 44 deletions.
4 changes: 4 additions & 0 deletions resources/tests/module/test_factorial_renamed.clsp
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
(include *standard-cl-23*)
(import std.factorial exposing (! as factorial))

(export (X) (factorial X))
77 changes: 75 additions & 2 deletions src/compiler/comptypes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,31 @@ pub struct QualifiedModuleInfo {
pub struct ModuleImportListedName {
pub nl: Srcloc,
pub name: Vec<u8>,
pub alias: Option<Vec<u8>>,
}

impl ModuleImportListedName {
pub fn to_sexp(&self) -> Rc<SExp> {
let as_atom = Rc::new(SExp::Atom(self.nl.clone(), b"as".to_vec()));
let name_atom = Rc::new(SExp::Atom(self.nl.clone(), self.name.clone()));
if let Some(alias) = self.alias.as_ref() {
Rc::new(SExp::Cons(
self.nl.clone(),
name_atom,
Rc::new(SExp::Cons(
self.nl.clone(),
as_atom.clone(),
Rc::new(SExp::Cons(
self.nl.clone(),
Rc::new(SExp::Atom(self.nl.clone(), alias.clone())),
Rc::new(SExp::Nil(self.nl.clone())),
)),
)),
))
} else {
name_atom
}
}
}

/// Specification of how to name imported items from the target namespace.
Expand All @@ -478,6 +503,45 @@ pub enum ModuleImportSpec {
Hiding(Srcloc, Vec<ModuleImportListedName>),
}

pub fn match_as_named(lst: &[SExp], offset: usize) -> Option<(Srcloc, Vec<u8>, Option<Vec<u8>>)> {
let name_offset = offset;
let small = 1 + offset;
let as_kw = 1 + offset;
let as_name_offset = 2 + offset;
let large = 3 + offset;

if lst.len() != small && lst.len() != large {
return None;
}

let export_name = if lst.len() == large {
if let SExp::Atom(_, as_atom) = lst[as_kw].borrow() {
// Not 'as'
if as_atom != b"as" {
return None;
}
} else {
return None;
}

if let SExp::Atom(_, as_name) = lst[as_name_offset].borrow() {
Some(as_name.clone())
} else {
return None;
}
} else {
None
};

let from_name = if let SExp::Atom(_, from_name) = lst[name_offset].borrow() {
from_name.clone()
} else {
return None;
};

Some((lst[name_offset].loc(), from_name, export_name))
}

impl ModuleImportSpec {
pub fn name_loc(&self) -> Srcloc {
match self {
Expand Down Expand Up @@ -571,10 +635,19 @@ impl ModuleImportSpec {
if let SExp::Atom(kw_loc, kw) = &forms[skip] {
let mut words = vec![];
for atom in forms.iter().skip(skip + 1) {
if let SExp::Atom(name_loc, name) = atom {
if let Some((import_name_loc, import_name, export_name)) =
atom.proper_list().and_then(|lst| match_as_named(&lst, 0))
{
words.push(ModuleImportListedName {
nl: import_name_loc,
name: import_name,
alias: export_name,
});
} else if let SExp::Atom(name_loc, name) = atom {
words.push(ModuleImportListedName {
nl: name_loc.clone(),
name: name.clone(),
alias: None,
});
} else {
return Err(CompileErr(
Expand Down Expand Up @@ -620,7 +693,7 @@ impl ModuleImportSpec {
result_vec.extend(
exposed_names
.iter()
.map(|e| Rc::new(SExp::Atom(e.nl.clone(), e.name.clone())))
.map(|e| e.to_sexp())
.collect::<Vec<Rc<SExp>>>(),
);
Rc::new(enlist(kl.clone(), &result_vec))
Expand Down
45 changes: 6 additions & 39 deletions src/compiler/frontend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ use num_bigint::ToBigInt;

use crate::classic::clvm::__type_compatibility__::{bi_one, bi_zero};
use crate::compiler::comptypes::{
list_to_cons, ArgsAndTail, Binding, BindingPattern, BodyForm, ChiaType, CompileErr,
CompileForm, CompilerOpts, ConstantKind, DefconstData, DefmacData, DeftypeData, DefunData,
Export, FrontendOutput, HelperForm, ImportLongName, IncludeDesc, LetData, LetFormInlineHint,
LetFormKind, LongNameTranslation, ModAccum, ModuleImportSpec, NamespaceData, NamespaceRefData,
StructDef, StructMember, SyntheticType, TypeAnnoKind,
list_to_cons, match_as_named, ArgsAndTail, Binding, BindingPattern, BodyForm, ChiaType,
CompileErr, CompileForm, CompilerOpts, ConstantKind, DefconstData, DefmacData, DeftypeData,
DefunData, Export, FrontendOutput, HelperForm, ImportLongName, IncludeDesc, LetData,
LetFormInlineHint, LetFormKind, LongNameTranslation, ModAccum, ModuleImportSpec, NamespaceData,
NamespaceRefData, StructDef, StructMember, SyntheticType, TypeAnnoKind,
};
use crate::compiler::lambda::handle_lambda;
use crate::compiler::preprocessor::{
Expand Down Expand Up @@ -1147,39 +1147,6 @@ fn parse_chia_type(v: Vec<SExp>) -> Result<ChiaType, CompileErr> {
))
}

pub fn match_export_named(lst: &[SExp]) -> Option<(Vec<u8>, Option<Vec<u8>>)> {
if lst.len() != 2 && lst.len() != 4 {
return None;
}

let export_name = if lst.len() == 4 {
if let SExp::Atom(_, as_atom) = lst[2].borrow() {
// Not 'as'
if as_atom != b"as" {
return None;
}
} else {
return None;
}

if let SExp::Atom(_, as_name) = lst[3].borrow() {
Some(as_name.clone())
} else {
return None;
}
} else {
None
};

let from_name = if let SExp::Atom(_, from_name) = lst[1].borrow() {
from_name.clone()
} else {
return None;
};

Some((from_name, export_name))
}

pub fn match_export_form(
opts: Rc<dyn CompilerOpts>,
form: Rc<SExp>,
Expand All @@ -1200,7 +1167,7 @@ pub fn match_export_form(
return Ok(None);
}

if let Some((fun_name, export_name)) = match_export_named(&lst) {
if let Some((_, fun_name, export_name)) = match_as_named(&lst, 1) {
return Ok(Some(Export::Function(fun_name, export_name)));
}

Expand Down
14 changes: 11 additions & 3 deletions src/compiler/resolve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::compiler::compiler::is_at_capture;
use crate::compiler::comptypes::{
map_m, Binding, BindingPattern, BodyForm, CompileErr, CompileForm, CompilerOpts, DefconstData,
DefmacData, DefunData, HelperForm, ImportLongName, LambdaData, LetData, LetFormKind,
LongNameTranslation, ModuleImportSpec, NamespaceData,
LongNameTranslation, ModuleImportListedName, ModuleImportSpec, NamespaceData,
};
use crate::compiler::frontend::{generate_type_helpers, HelperFormResult};
use crate::compiler::rename::rename_args_helperform;
Expand Down Expand Up @@ -150,6 +150,14 @@ pub fn rename_args_named_helper(
Ok((pair.0.clone(), rename_args_helperform(&pair.1)?))
}

fn exposed_name_matches(exposed: &ModuleImportListedName, orig_name: &[u8]) -> bool {
if let Some(alias) = exposed.alias.as_ref() {
orig_name == alias
} else {
orig_name == &exposed.name
}
}

pub fn find_helper_target(
opts: Rc<dyn CompilerOpts>,
helpers: &[HelperForm],
Expand Down Expand Up @@ -252,8 +260,8 @@ pub fn find_helper_target(
}

for exposed in x.iter() {
if exposed.name == orig_name {
let target_name = ns_spec.longname.with_child(&child);
if exposed_name_matches(exposed, orig_name) {
let target_name = ns_spec.longname.with_child(exposed.name);
if let Some(helper) = find_helper_target(
opts.clone(),
helpers,
Expand Down
17 changes: 17 additions & 0 deletions src/tests/compiler/modules.rs
Original file line number Diff line number Diff line change
Expand Up @@ -540,3 +540,20 @@ fn test_export_foreign_constant() {
}],
);
}

#[test]
fn test_import_renamed() {
let filename = "resources/tests/module/test_factorial_renamed.clsp";
let content = fs::read_to_string(filename).expect("file should exist");
let hex_filename = "resources/tests/module/test_factorial_renamed.hex";

test_compile_and_run_program_with_modules(
filename,
&content,
&[HexArgumentOutcome {
hexfile: hex_filename,
argument: "(5)",
outcome: Some("120"),
}],
);
}

0 comments on commit 74c770e

Please sign in to comment.