include!("builtins/helpers.rs");
include!("builtins/member_access.rs");
include!("builtins/member_runtime.rs");
include!("builtins/member_syscalls.rs");
include!("builtins/member_storage.rs");
include!("builtins/member_neo.rs");
include!("builtins/member_nativecalls.rs");
include!("builtins/resolved.rs");
fn try_lower_builtin_call(
func: &Expression,
args: &[Expression],
ctx: &mut LoweringContext,
instructions: &mut Vec<Instruction>,
) -> Option<bool> {
if let Some(result) = try_lower_type_concat(func, args, ctx, instructions) {
return Some(result);
}
if let Some(result) = try_lower_member_builtin(func, args, ctx, instructions) {
return Some(result);
}
try_lower_resolved_builtin_call(func, args, ctx, instructions)
}
fn try_lower_type_concat(
func: &Expression,
args: &[Expression],
ctx: &mut LoweringContext,
instructions: &mut Vec<Instruction>,
) -> Option<bool> {
let Expression::MemberAccess(_, inner, member) = func else {
return None;
};
if member.name != "concat" {
return None;
}
let is_bytes_or_string = matches!(
inner.as_ref(),
Expression::Type(_, PtType::DynamicBytes | PtType::String)
);
if !is_bytes_or_string {
return None;
}
if args.is_empty() {
instructions.push(Instruction::PushLiteral(LiteralValue::ByteArray(vec![])));
return Some(true);
}
let mut success = true;
for arg in args {
if !lower_expression(arg, ctx, instructions) {
success = false;
continue;
}
}
if success {
instructions.push(Instruction::CallBuiltin {
builtin: BuiltinCall::BytesConcat,
arg_count: args.len(),
});
instructions.push(Instruction::Convert {
target: ConvertTarget::ByteArray,
});
}
Some(success)
}