Skip to content
This repository was archived by the owner on Jan 8, 2024. It is now read-only.

Commit f9a4b78

Browse files
Merge pull request #29 from Chia-Network/20220524-fix-fe-opt
20220524 fix fe opt
2 parents 6adba57 + bbc8e41 commit f9a4b78

File tree

5 files changed

+96
-22
lines changed

5 files changed

+96
-22
lines changed

src/compiler/codegen.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -987,7 +987,8 @@ fn start_codegen(
987987
let updated_opts = opts
988988
.set_compiler(use_compiler.clone())
989989
.set_in_defun(false)
990-
.set_stdenv(false);
990+
.set_stdenv(false)
991+
.set_frontend_opt(false);
991992

992993
updated_opts
993994
.compile_program(

src/compiler/compiler.rs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use crate::compiler::codegen::codegen;
1616
use crate::compiler::comptypes::{
1717
BodyForm, CompileErr, CompileForm, CompilerOpts, HelperForm, PrimaryCodegen,
1818
};
19-
use crate::compiler::evaluate::Evaluator;
19+
use crate::compiler::evaluate::{build_reflex_captures, Evaluator};
2020
use crate::compiler::frontend::frontend;
2121
use crate::compiler::prims;
2222
use crate::compiler::runtypes::RunFailure;
@@ -124,13 +124,10 @@ fn fe_opt(
124124
for h in compiler_helpers.iter() {
125125
match h {
126126
HelperForm::Defun(loc, name, inline, args, body) => {
127-
let body_rc = evaluator.shrink_bodyform(
128-
allocator,
129-
Rc::new(SExp::Nil(compileform.args.loc())),
130-
&HashMap::new(),
131-
body.clone(),
132-
true,
133-
)?;
127+
let mut env = HashMap::new();
128+
build_reflex_captures(&mut env, args.clone());
129+
let body_rc =
130+
evaluator.shrink_bodyform(allocator, args.clone(), &env, body.clone(), true)?;
134131
let new_helper = HelperForm::Defun(
135132
loc.clone(),
136133
name.clone(),

src/compiler/evaluate.rs

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,13 @@ fn synthesize_args(
313313
}
314314
}
315315

316+
fn reflex_capture(name: &Vec<u8>, capture: Rc<BodyForm>) -> bool {
317+
match capture.borrow() {
318+
BodyForm::Value(SExp::Atom(_, n)) => n == name,
319+
_ => false,
320+
}
321+
}
322+
316323
impl Evaluator {
317324
pub fn new(
318325
opts: Rc<dyn CompilerOpts>,
@@ -350,6 +357,7 @@ impl Evaluator {
350357
self.expand_macro(allocator, l.clone(), program.clone(), macro_args)?;
351358

352359
let input_sexp = dequote(call_loc.clone(), macro_expansion)?;
360+
353361
let frontend_macro_input = Rc::new(SExp::Cons(
354362
l.clone(),
355363
Rc::new(SExp::atom_from_string(l.clone(), &"mod".to_string())),
@@ -620,13 +628,17 @@ impl Evaluator {
620628
} else {
621629
env.get(name)
622630
.map(|x| {
623-
self.shrink_bodyform(
624-
allocator,
625-
prog_args.clone(),
626-
env,
627-
x.clone(),
628-
only_inline,
629-
)
631+
if reflex_capture(name, x.clone()) {
632+
Ok(x.clone())
633+
} else {
634+
self.shrink_bodyform(
635+
allocator,
636+
prog_args.clone(),
637+
env,
638+
x.clone(),
639+
only_inline,
640+
)
641+
}
630642
})
631643
.unwrap_or_else(|| {
632644
self.get_constant(name)
@@ -774,7 +786,11 @@ impl Evaluator {
774786
// Com takes place in the current environment.
775787
// We can only reduce com if all bindings are
776788
// primitive.
777-
let updated_opts = self.opts.set_stdenv(!in_defun).set_in_defun(in_defun);
789+
let updated_opts = self
790+
.opts
791+
.set_stdenv(!in_defun)
792+
.set_in_defun(in_defun)
793+
.set_frontend_opt(false);
778794

779795
let com_result = updated_opts.compile_program(
780796
allocator,

src/tests/compiler/compiler.rs

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ fn run_test_3() {
173173

174174
#[test]
175175
fn run_test_3_opt() {
176-
// run_test_3_maybe_opt(true);
176+
run_test_3_maybe_opt(true);
177177
}
178178

179179
fn run_test_4_maybe_opt(opt: bool) {
@@ -193,7 +193,7 @@ fn run_test_4() {
193193

194194
#[test]
195195
fn run_test_4_opt() {
196-
// run_test_4_maybe_opt(true);
196+
run_test_4_maybe_opt(true);
197197
}
198198

199199
fn run_test_5_maybe_opt(opt: bool) {
@@ -209,7 +209,7 @@ fn run_test_5() {
209209

210210
#[test]
211211
fn run_test_5_opt() {
212-
// run_test_5_maybe_opt(true);
212+
run_test_5_maybe_opt(true);
213213
}
214214

215215
fn run_test_6_maybe_opt(opt: bool) {
@@ -229,7 +229,7 @@ fn run_test_6() {
229229

230230
#[test]
231231
fn run_test_6_opt() {
232-
// run_test_6_maybe_opt(true);
232+
run_test_6_maybe_opt(true);
233233
}
234234

235235
fn run_test_7_maybe_opt(opt: bool) {
@@ -252,7 +252,7 @@ fn run_test_7() {
252252

253253
#[test]
254254
fn run_test_7_opt() {
255-
// run_test_7_maybe_opt(true);
255+
run_test_7_maybe_opt(true);
256256
}
257257

258258
fn run_test_8_maybe_opt(opt: bool) {
@@ -597,3 +597,39 @@ fn cant_redefine_defun_with_defun() {
597597
assert!(result.is_err());
598598
}
599599
}
600+
601+
fn test_collatz_maybe_opt(opt: bool) {
602+
let result = run_string_maybe_opt(
603+
&indoc! {"
604+
(mod (A)
605+
(include *standard-cl-22*)
606+
(defun-inline odd (X) (logand X 1))
607+
(defun collatz (N X)
608+
(if (= X 1)
609+
N
610+
(let ((incN (+ N 1)))
611+
(if (odd X)
612+
(collatz incN (+ 1 (* 3 X)))
613+
(collatz incN (/ X 2))
614+
)
615+
)
616+
)
617+
)
618+
(collatz 0 A)
619+
)
620+
"}
621+
.to_string(),
622+
&"(4)".to_string(),
623+
opt,
624+
)
625+
.unwrap();
626+
assert_eq!(result.to_string(), "(q . 2)");
627+
}
628+
629+
fn test_collatz() {
630+
test_collatz_maybe_opt(false);
631+
}
632+
633+
fn test_collatz_opt() {
634+
test_collatz_maybe_opt(true);
635+
}

src/tests/compiler/repl.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,3 +139,27 @@ fn test_last_of_pwcoin_2() {
139139
"(q (51 3735928559 1))"
140140
);
141141
}
142+
143+
#[test]
144+
fn test_collatz() {
145+
assert_eq!(
146+
test_repl_outcome(vec![
147+
"(defun-inline odd (X) (logand X 1))",
148+
"(defun collatz (N X)",
149+
" (if (= X 1)",
150+
" N",
151+
" (let ((incN (+ N 1)))",
152+
" (if (odd X)",
153+
" (collatz incN (+ 1 (* 3 X)))",
154+
" (collatz incN (/ X 2))",
155+
" )",
156+
" )",
157+
" )",
158+
" )",
159+
"(collatz 0 3)"
160+
])
161+
.unwrap()
162+
.unwrap(),
163+
"(q . 7)"
164+
);
165+
}

0 commit comments

Comments
 (0)