Skip to content

Commit

Permalink
Merge pull request #53 from Chia-Network/20231101-empty-atom
Browse files Browse the repository at this point in the history
Handle empty atom as nil
  • Loading branch information
prozacchiwawa authored Nov 2, 2023
2 parents 9d9aa8e + 7a89033 commit a8bfff9
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 1 deletion.
8 changes: 8 additions & 0 deletions src/compiler/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -656,6 +656,14 @@ pub fn generate_expr_code(
l.clone(),
Rc::new(SExp::Integer(l.clone(), bi_one())),
))
} else if atom.is_empty() {
// Ensure that we handle empty atoms as nils.
generate_expr_code(
context,
opts,
compiler,
Rc::new(BodyForm::Value(SExp::Nil(l.clone()))),
)
} else {
// This is as a variable access, given that we've got
// a Value bodyform containing an Atom, so if a defun
Expand Down
48 changes: 47 additions & 1 deletion src/tests/compiler/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::rc::Rc;

use clvm_rs::allocator::Allocator;

use crate::classic::clvm::__type_compatibility__::bi_one;
use crate::classic::clvm_tools::stages::stage_0::DefaultProgramRunner;
use crate::compiler::clvm::run;
use crate::compiler::compiler::{compile_file, DefaultCompilerOpts};
Expand All @@ -11,7 +12,7 @@ use crate::compiler::dialect::AcceptedDialect;
use crate::compiler::frontend::{collect_used_names_sexp, frontend};
use crate::compiler::rename::rename_in_cons;
use crate::compiler::runtypes::RunFailure;
use crate::compiler::sexp::{decode_string, parse_sexp, SExp};
use crate::compiler::sexp::{decode_string, enlist, parse_sexp, SExp};
use crate::compiler::srcloc::Srcloc;

const TEST_TIMEOUT: usize = 1000000;
Expand Down Expand Up @@ -2304,3 +2305,48 @@ fn test_rename_in_compileform_simple() {
let renamed_helperform = squash_name_differences(helper_f[0].to_sexp()).expect("should rename");
assert_eq!(renamed_helperform.to_string(), desired_outcome);
}

#[test]
fn test_handle_explicit_empty_atom() {
let filename = "*empty-atom-test*";
let srcloc = Srcloc::start(filename);
let opts = Rc::new(DefaultCompilerOpts::new(filename)).set_dialect(AcceptedDialect {
stepping: Some(21),
strict: true,
});

let atom = |s: &str| Rc::new(SExp::Atom(srcloc.clone(), s.as_bytes().to_vec()));

let sublist = |l: &[Rc<SExp>]| Rc::new(enlist(srcloc.clone(), l));

let nil = Rc::new(SExp::Nil(srcloc.clone()));

let program = sublist(&[
atom("mod"),
nil.clone(),
sublist(&[atom("include"), atom("*strict-cl-21*")]),
sublist(&[
atom("+"),
atom(""),
Rc::new(SExp::Integer(srcloc.clone(), bi_one())),
]),
]);
let mut allocator = Allocator::new();
let mut symbols = HashMap::new();
let runner = Rc::new(DefaultProgramRunner::new());

let compiled = opts
.compile_program(&mut allocator, runner.clone(), program, &mut symbols)
.expect("should compile");
let outcome = run(
&mut allocator,
runner,
opts.prim_map(),
Rc::new(compiled),
nil,
None,
None,
)
.expect("should run");
assert_eq!(outcome.to_string(), "1");
}

0 comments on commit a8bfff9

Please sign in to comment.