| 239 | raise StackError(f"Dropping live value '{var.name}'") |
| 240 | |
| 241 | def pop(self, var: StackItem, out: CWriter) -> Local: |
| 242 | if self.variables: |
| 243 | top = self.variables[-1] |
| 244 | if var.is_array() != top.is_array() or top.size != var.size: |
| 245 | # Mismatch in variables |
| 246 | self.clear(out) |
| 247 | self.logical_sp = self.logical_sp.pop(var) |
| 248 | indirect = "&" if var.is_array() else "" |
| 249 | if self.variables: |
| 250 | popped = self.variables.pop() |
| 251 | assert var.is_array() == popped.is_array() and popped.size == var.size |
| 252 | if not var.used: |
| 253 | return popped |
| 254 | if popped.name != var.name: |
| 255 | rename = f"{var.name} = {popped.name};\n" |
| 256 | popped.item = var |
| 257 | else: |
| 258 | rename = "" |
| 259 | if not popped.in_local: |
| 260 | if popped.memory_offset is None: |
| 261 | popped.memory_offset = self.logical_sp |
| 262 | assert popped.memory_offset == self.logical_sp, (popped, self.as_comment()) |
| 263 | offset = popped.memory_offset - self.physical_sp |
| 264 | if var.is_array(): |
| 265 | defn = f"{var.name} = &stack_pointer[{offset.to_c()}];\n" |
| 266 | else: |
| 267 | defn = f"{var.name} = stack_pointer[{offset.to_c()}];\n" |
| 268 | popped.in_local = True |
| 269 | else: |
| 270 | defn = rename |
| 271 | out.emit(defn) |
| 272 | return popped |
| 273 | self.base_offset = self.logical_sp |
| 274 | if var.name in UNUSED or not var.used: |
| 275 | return Local.unused(var, self.base_offset) |
| 276 | c_offset = (self.base_offset - self.physical_sp).to_c() |
| 277 | assign = f"{var.name} = {indirect}stack_pointer[{c_offset}];\n" |
| 278 | out.emit(assign) |
| 279 | self._print(out) |
| 280 | return Local.from_memory(var, self.base_offset) |
| 281 | |
| 282 | def clear(self, out: CWriter) -> None: |
| 283 | "Flush to memory and clear variables stack" |