oxilean_codegen/php_backend/
phpexpr_traits.rs1use super::functions::format_param;
12use super::types::PHPExpr;
13use std::fmt;
14
15impl fmt::Display for PHPExpr {
16 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
17 match self {
18 PHPExpr::Lit(s) => write!(f, "{}", s),
19 PHPExpr::Var(name) => write!(f, "${}", name),
20 PHPExpr::BinOp(lhs, op, rhs) => write!(f, "({} {} {})", lhs, op, rhs),
21 PHPExpr::UnaryOp(op, operand) => write!(f, "({}{})", op, operand),
22 PHPExpr::FuncCall(name, args) => {
23 let args_s: Vec<std::string::String> =
24 args.iter().map(|a| format!("{}", a)).collect();
25 write!(f, "{}({})", name, args_s.join(", "))
26 }
27 PHPExpr::ArrayLit(elems) => {
28 let s: Vec<std::string::String> = elems.iter().map(|e| format!("{}", e)).collect();
29 write!(f, "[{}]", s.join(", "))
30 }
31 PHPExpr::ArrayMap(pairs) => {
32 let s: Vec<std::string::String> = pairs
33 .iter()
34 .map(|(k, v)| format!("{} => {}", k, v))
35 .collect();
36 write!(f, "[{}]", s.join(", "))
37 }
38 PHPExpr::New(class, args) => {
39 let args_s: Vec<std::string::String> =
40 args.iter().map(|a| format!("{}", a)).collect();
41 write!(f, "new {}({})", class, args_s.join(", "))
42 }
43 PHPExpr::Arrow(obj, prop) => {
44 write!(
45 f,
46 "{}->{}",
47 if matches!(obj.as_ref(), PHPExpr::Var(_)) {
48 format!("{}", obj)
49 } else {
50 format!("({})", obj)
51 },
52 prop
53 )
54 }
55 PHPExpr::NullSafe(obj, prop) => {
56 write!(
57 f,
58 "{}?->{}",
59 if matches!(obj.as_ref(), PHPExpr::Var(_)) {
60 format!("{}", obj)
61 } else {
62 format!("({})", obj)
63 },
64 prop
65 )
66 }
67 PHPExpr::StaticAccess(class, member) => write!(f, "{}::{}", class, member),
68 PHPExpr::Index(arr, idx) => write!(f, "{}[{}]", arr, idx),
69 PHPExpr::Ternary(cond, then, else_) => {
70 write!(f, "({} ? {} : {})", cond, then, else_)
71 }
72 PHPExpr::NullCoalesce(a, b) => write!(f, "({} ?? {})", a, b),
73 PHPExpr::Closure {
74 params,
75 use_vars,
76 return_type,
77 body,
78 } => {
79 let params_s: Vec<std::string::String> = params.iter().map(format_param).collect();
80 let use_s = if use_vars.is_empty() {
81 std::string::String::new()
82 } else {
83 format!(
84 " use ({})",
85 use_vars
86 .iter()
87 .map(|v| format!("${}", v))
88 .collect::<Vec<_>>()
89 .join(", ")
90 )
91 };
92 let ret_s = return_type
93 .as_ref()
94 .map(|t| format!(": {}", t))
95 .unwrap_or_default();
96 let body_s = body.join("\n ");
97 write!(
98 f,
99 "function({}){}{} {{\n {}\n }}",
100 params_s.join(", "),
101 use_s,
102 ret_s,
103 body_s
104 )
105 }
106 PHPExpr::ArrowFn {
107 params,
108 return_type,
109 body,
110 } => {
111 let params_s: Vec<std::string::String> = params.iter().map(format_param).collect();
112 let ret_s = return_type
113 .as_ref()
114 .map(|t| format!(": {}", t))
115 .unwrap_or_default();
116 write!(f, "fn({}){} => {}", params_s.join(", "), ret_s, body)
117 }
118 PHPExpr::Match {
119 subject,
120 arms,
121 default,
122 } => {
123 let arms_s: Vec<std::string::String> = arms
124 .iter()
125 .map(|(pat, val)| format!(" {} => {}", pat, val))
126 .collect();
127 let default_s = default
128 .as_ref()
129 .map(|d| format!(",\n default => {}", d))
130 .unwrap_or_default();
131 write!(
132 f,
133 "match ({}) {{\n{}{}\n}}",
134 subject,
135 arms_s.join(",\n"),
136 default_s
137 )
138 }
139 PHPExpr::NamedArg(name, val) => write!(f, "{}: {}", name, val),
140 PHPExpr::Spread(expr) => write!(f, "...{}", expr),
141 PHPExpr::Cast(ty, expr) => write!(f, "({}) {}", ty, expr),
142 PHPExpr::Isset(expr) => write!(f, "isset({})", expr),
143 PHPExpr::Empty(expr) => write!(f, "empty({})", expr),
144 }
145 }
146}