Skip to content

Commit

Permalink
Mark unbox calls as tail calls when in tail position (#299)
Browse files Browse the repository at this point in the history
* mark unbox calls as tail calls when in tail position

* remove the command line as a dependencny
  • Loading branch information
mattwparas authored Jan 1, 2025
1 parent 01d4637 commit 9b2ada5
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 1 deletion.
2 changes: 1 addition & 1 deletion cogs/installer/cog.scm
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
(define package-name 'installer)
(define version "0.1.0")

(define dependencies '((#:name steel/command-line #:path "../command-line")))
(define dependencies '())

;; Create bin directory for entrypoints, and then
;; copy this file to that location, installing a
Expand Down
50 changes: 50 additions & 0 deletions crates/steel-core/src/compiler/passes/analysis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1161,6 +1161,11 @@ impl<'a> VisitorMutUnitRef<'a> for AnalysisPass<'a> {
CallSiteInformation::new(call_site_kind, span),
);
}
} else {
self.info.call_info.insert(
l.syntax_object_id,
CallSiteInformation::new(call_site_kind, l.location),
);
}
}
}
Expand Down Expand Up @@ -5496,6 +5501,51 @@ mod analysis_pass_tests {
}
}

#[test]
fn tail_call_eligible_test_with_let_local() {
let script = r#"
(define loop
(λ ()
(%plain-let ((##captured3 123) (##foo3 123))
(%plain-let ((####captured34 (#%box ##captured3))
(####foo34 (#%box ##foo3)))
(%plain-let ((##_____captured04 (list))
(##_____foo14 (λ ()
(begin
(cons 10 (#%unbox ####captured34))
((#%unbox ####foo34))))))
(begin
(#%set-box! ####captured34 ##_____captured04)
(#%set-box! ####foo34 ##_____foo14)
((#%unbox ####foo34))))))))
"#;

let mut exprs = Parser::parse(script).unwrap();
let mut analysis = SemanticAnalysis::new(&mut exprs);
analysis.populate_captures();

let tail_calls = analysis
.analysis
.call_info
.values()
.filter(|x| matches!(x.kind, CallKind::TailCall))
.collect::<Vec<_>>();

assert_eq!(tail_calls.len(), 2);

for var in tail_calls {
println!("{var:?}");

crate::rerrs::report_info(
ErrorKind::FreeIdentifier.to_error_code(),
"input.rkt",
script,
"tail call".to_string(),
var.span,
);
}
}

#[test]
fn tail_call_eligible_test_with_let() {
let script = r#"
Expand Down

0 comments on commit 9b2ada5

Please sign in to comment.