Skip to content

Commit

Permalink
Consolidate the Binds{T} and BindsGeneric{T, ...} into one ctype (#867)
Browse files Browse the repository at this point in the history
  • Loading branch information
dfellis authored Aug 27, 2024
1 parent 75b1230 commit fcac9c9
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 153 deletions.
82 changes: 4 additions & 78 deletions src/lntors/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ pub fn from_microstatement(
CType::Type(n, _) if n == "string" => {
Ok((format!("{}.to_string()", representation).to_string(), out))
}
CType::Binds(a) if a == "String" => {
CType::Binds(a, _) if a == "String" => {
Ok((format!("{}.to_string()", representation).to_string(), out))
}
CType::Function(..) => {
Expand Down Expand Up @@ -216,7 +216,7 @@ pub fn from_microstatement(
CType::Type(n, _) if n == "string" => {
Ok((format!("{}.to_string()", representation).to_string(), out))
}
CType::Binds(a) if a == "String" => {
CType::Binds(a, _) if a == "String" => {
Ok((format!("{}.to_string()", representation).to_string(), out))
}
_ => Ok((representation.clone(), out)),
Expand Down Expand Up @@ -850,81 +850,7 @@ pub fn from_microstatement(
out,
));
}
CType::Binds(n) if *n == enum_name => {
// Special-casing for Option and Result mapping. TODO:
// Make this more centralized
if ts.len() == 2 {
if let CType::Void = &ts[1] {
if let CType::Void = t {
return Ok(("None".to_string(), out));
} else {
return Ok((
format!(
"Some({})",
match argstrs[0]
.strip_prefix("&mut ")
{
Some(s) => s,
None => &argstrs[0],
}
),
out,
));
}
} else if let CType::Type(name, _) = &ts[1] {
if name == "Error" {
let okrustname =
typen::ctype_to_rtype(&ts[0], true)?;
let errrustname =
typen::ctype_to_rtype(&ts[1], true)?;
if let CType::Binds(..) = t {
return Ok((
format!(
"Err::<{}, {}>({})",
okrustname,
errrustname,
match argstrs[0]
.strip_prefix("&mut ")
{
Some(s) => s,
None => &argstrs[0],
}
),
out,
));
} else {
return Ok((
format!(
"Ok::<{}, {}>({})",
okrustname,
errrustname,
match argstrs[0]
.strip_prefix("&mut ")
{
Some(s) => s,
None => &argstrs[0],
}
),
out,
));
}
}
}
}
return Ok((
format!(
"{}::{}({})",
function.name,
enum_name,
match argstrs[0].strip_prefix("&mut ") {
Some(s) => s,
None => &argstrs[0],
},
),
out,
));
}
CType::BindsGeneric(n, ..) if *n == enum_name => {
CType::Binds(n, ..) if *n == enum_name => {
// Special-casing for Option and Result mapping. TODO:
// Make this more centralized
if ts.len() == 2 {
Expand Down Expand Up @@ -1075,7 +1001,7 @@ pub fn from_microstatement(
out,
));
}
CType::Binds(_) => {
CType::Binds(..) => {
return Ok((argstrs.join(", "), out));
}
otherwise => {
Expand Down
37 changes: 30 additions & 7 deletions src/lntors/typen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,18 +67,31 @@ pub fn ctype_to_rtype(
}
Ok(format!("({})", out.join(", ")))
}
CType::Binds(n) => Ok(n.clone()),
CType::Binds(name, args) => {
let mut out_args = Vec::new();
for arg in args {
out_args.push(ctype_to_rtype(arg, in_function_type)?);
}
if out_args.is_empty() {
Ok(name.clone())
} else {
Ok(format!("{}<{}>", name, out_args.join(", ")))
}
}
_ => Ok("".to_string()), // TODO: Is this correct?
}
}
CType::Generic(name, args, _) => Ok(format!("{}<{}>", name, args.join(", "))),
CType::Binds(name) => Ok(name.clone()),
CType::BindsGeneric(name, args) => {
CType::Binds(name, args) => {
let mut out_args = Vec::new();
for arg in args {
out_args.push(ctype_to_rtype(arg, in_function_type)?);
}
Ok(format!("{}<{}>", name, out_args.join(", ")))
if out_args.is_empty() {
Ok(name.clone())
} else {
Ok(format!("{}<{}>", name, out_args.join(", ")))
}
}
CType::IntrinsicGeneric(name, _) => Ok(name.clone()), // How would this even be reached?
CType::Int(i) => Ok(i.to_string()),
Expand Down Expand Up @@ -138,8 +151,8 @@ pub fn ctype_to_rtype(
if ts.len() == 2 {
match &ts[1] {
CType::Void => Ok(format!("Option<{}>", ctype_to_rtype(&ts[0], in_function_type)?)),
CType::Binds(rustname) if rustname == "AlanError" => Ok(format!("Result<{}, {}>", ctype_to_rtype(&ts[0], in_function_type)?, rustname)),
CType::Type(_, t) if matches!(&**t, CType::Binds(rustname) if rustname == "AlanError") => Ok(format!("Result<{}, {}>", ctype_to_rtype(&ts[0], in_function_type)?, "AlanError")),
CType::Binds(rustname, _) if rustname == "AlanError" => Ok(format!("Result<{}, {}>", ctype_to_rtype(&ts[0], in_function_type)?, rustname)),
CType::Type(_, t) if matches!(&**t, CType::Binds(rustname, _) if rustname == "AlanError") => Ok(format!("Result<{}, {}>", ctype_to_rtype(&ts[0], in_function_type)?, "AlanError")),
_ => Ok(CType::Either(ts.clone()).to_callable_string()),
}
} else {
Expand Down Expand Up @@ -172,7 +185,17 @@ pub fn generate(
// assuming no bugs in the standard library) so they do not alter the generated source
// output, while the `Structlike` type requires a new struct to be created and inserted
// into the source definition, potentially inserting inner types as needed
CType::Binds(rtype) => Ok((rtype.clone(), out)),
CType::Binds(n, ts) => {
let mut genargs = Vec::new();
for t in ts {
genargs.push(ctype_to_rtype(t, false)?);
}
if genargs.is_empty() {
Ok((n.clone(), out))
} else {
Ok((format!("{}<{}>", n, genargs.join(", ")), out))
}
}
// TODO: The complexity of this function indicates more fundamental issues in the type
// generation. This needs a rethink and rewrite.
CType::Type(name, t) => match &**t {
Expand Down
2 changes: 1 addition & 1 deletion src/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -965,7 +965,7 @@ named_and!(types: Types =>
test!(types =>
pass "type Foo = bar: string;";
pass "type Foo = Bar";
pass "type Result{T, Error} = BindsGeneric{'Result', T, Error};";
pass "type Result{T, Error} = Binds{'Result', T, Error};";
pass "type ExitCode = Binds{'std::process::ExitCode'};";
pass "type{Windows} Path = driveLetter: string, pathsegments: Array{string};";
);
Expand Down
Loading

0 comments on commit fcac9c9

Please sign in to comment.