Skip to content

Commit

Permalink
Convert to pass-by-reference instead of pass-by-value (#678)
Browse files Browse the repository at this point in the history
  • Loading branch information
dfellis authored Mar 17, 2024
1 parent 1426e65 commit a7f3342
Show file tree
Hide file tree
Showing 4 changed files with 243 additions and 171 deletions.
2 changes: 1 addition & 1 deletion src/lntors/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ pub fn generate(
// If it's a bound function, just call it with the argument, if there
// is one
let arg_str = match &handler_fn.microstatements[0] {
Microstatement::Arg { name, .. } => name.clone(),
Microstatement::Arg { name, .. } => format!("&{}", name).to_string(),
_ => "".to_string(),
};
out = format!("{} super::{}({});\n", out, b, arg_str);
Expand Down
35 changes: 29 additions & 6 deletions src/lntors/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,14 @@ pub fn from_microstatement(
mut out: OrderedHashMap<String, String>,
) -> Result<(String, OrderedHashMap<String, String>), Box<dyn std::error::Error>> {
match microstatement {
Microstatement::Arg { .. } => Ok(("".to_string(), out)), // Skip arg microstatements that are just used for discovery during generation
Microstatement::Arg { name, .. } => {
// TODO: Update the serialization logic to understand values vs references so we can
// eliminate this useless (and harmful for mutable references) clone
Ok((
format!("let {} = {}.clone()", name, name).to_string(),
out,
))
}
Microstatement::Assignment {
name,
value,
Expand All @@ -24,8 +31,8 @@ pub fn from_microstatement(
out = o;
Ok((
format!(
"let {} {} = {}",
if *mutable { "mut" } else { "" },
"let {}{} = {}",
if *mutable { "mut " } else { "" },
name,
val,
)
Expand Down Expand Up @@ -103,7 +110,15 @@ pub fn from_microstatement(
for arg in args {
let (a, o) = from_microstatement(arg, scope, program, out)?;
out = o;
argstrs.push(a);
// If the argument is itself a function, this is the only place in Rust
// where you can't pass by reference, so we check the type and change
// the argument output accordingly.
let arg_type = arg.get_type(scope, program)?;
if arg_type.as_str() == "function" {
argstrs.push(format!("{}", a));
} else {
argstrs.push(format!("&{}", a));
}
}
Ok((
format!("{}({})", rustname, argstrs.join(", ")).to_string(),
Expand All @@ -115,7 +130,15 @@ pub fn from_microstatement(
for arg in args {
let (a, o) = from_microstatement(arg, scope, program, out)?;
out = o;
argstrs.push(a);
// If the argument is itself a function, this is the only place in Rust
// where you can't pass by reference, so we check the type and change
// the argument output accordingly.
let arg_type = arg.get_type(scope, program)?;
if arg_type.as_str() == "function" {
argstrs.push(format!("{}", a));
} else {
argstrs.push(format!("&{}", a));
}
}
Ok((
format!("{}({})", rustname, argstrs.join(", ")).to_string(),
Expand Down Expand Up @@ -157,7 +180,7 @@ pub fn generate(
for arg in &function.args {
if let Some((t, s)) = program.resolve_type(scope, &arg.1) {
if let Ok(t_str) = typen::generate(t, s, program) {
arg_strs.push(format!("{}: {}", arg.0, t_str).to_string());
arg_strs.push(format!("{}: &{}", arg.0, t_str).to_string());
} else {
return Err(format!("Failed to convert Alan type {} to Rust", &arg.1).into());
}
Expand Down
4 changes: 2 additions & 2 deletions src/std/root.ln
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
// Integer-related bindings
export type i8 binds i8;
export type Result<i8> binds Result_i8;
export fn ok(i: i8): Result<i8> binds Ok;
export fn ok(i: i8): Result<i8> binds alan_ok;
export fn getOr(r: Result<i8>, default: i8): i8 binds get_or_i8;
export fn i8(i: i64): i8 binds i64toi8;
export fn add(a: i8, b: i8): Result<i8> binds addi8;
Expand Down Expand Up @@ -63,7 +63,7 @@ export fn min(a: i32, b: i32): i32 binds mini32;
export fn max(a: i32, b: i32): i32 binds maxi32;
export type i64 binds i64;
export type Result<i64> binds Result_i64;
export fn ok(i: i64): Result<i64> binds Ok;
export fn ok(i: i64): Result<i64> binds alan_ok;
export fn getOr(r: Result<i64>, default: i64): i64 binds get_or_i64;
export fn i64(i: i64): i64 = i;
export fn add(a: i64, b: i64): Result<i64> binds addi64;
Expand Down
Loading

0 comments on commit a7f3342

Please sign in to comment.