Decompile an Ixon Expr to a Lean Expr with arena-based metadata restoration. Traverses the arena tree following child pointers. Share references are expanded with the same arena_idx (parent's child pointer already captures the correct metadata subtree). Mdata arena nodes are collected and applied as wrappers.
( expr: &Arc<Expr>, arena: &ExprMeta, arena_idx: u64, lvl_names: &[Name], cache: &mut BlockCache, stt: &CompileState, _dstt: &DecompileState, )
| 509 | let mut fields = Vec::with_capacity(count); |
| 510 | for _ in 0..count { |
| 511 | let field_addr = read_addr_bytes(buf)?; |
| 512 | let field = read_string(&field_addr, stt)?; |
| 513 | fields.push(field); |
| 514 | } |
| 515 | Ok(SyntaxPreresolved::Decl(name, fields)) |
| 516 | }, |
| 517 | _ => Err(DecompileError::BadConstantFormat { |
| 518 | msg: "preresolved: invalid tag".into(), |
| 519 | }), |
| 520 | } |
| 521 | } |
| 522 | |
| 523 | /// Deserialize a Syntax from bytes (mirrors compile-side serialize_syntax). |
| 524 | fn deserialize_syntax( |
| 525 | bytes: &[u8], |
| 526 | stt: &CompileState, |
| 527 | ) -> Result<Syntax, DecompileError> { |
| 528 | let mut buf = bytes; |
| 529 | deserialize_syntax_inner(&mut buf, stt) |
| 530 | } |
| 531 | |
| 532 | /// Recursive inner deserializer for Syntax. |
| 533 | fn deserialize_syntax_inner( |
| 534 | buf: &mut &[u8], |
| 535 | stt: &CompileState, |
| 536 | ) -> Result<Syntax, DecompileError> { |
| 537 | if buf.is_empty() { |
| 538 | return Err(DecompileError::BadConstantFormat { |
| 539 | msg: "syntax: empty".into(), |
| 540 | }); |
| 541 | } |
| 542 | let tag = buf[0]; |
| 543 | *buf = &buf[1..]; |
| 544 | match tag { |
| 545 | 0 => Ok(Syntax::Missing), |
| 546 | 1 => { |
| 547 | let info = deserialize_source_info(buf, stt)?; |
| 548 | let kind_addr = read_addr_bytes(buf)?; |
| 549 | let kind = decompile_name(&kind_addr, stt)?; |
| 550 | let arg_count = read_tag0(buf)? as usize; |
| 551 | let mut args = Vec::with_capacity(arg_count); |
| 552 | for _ in 0..arg_count { |
| 553 | args.push(deserialize_syntax_inner(buf, stt)?); |
| 554 | } |
| 555 | Ok(Syntax::Node(info, kind, args)) |
| 556 | }, |
| 557 | 2 => { |
| 558 | let info = deserialize_source_info(buf, stt)?; |
| 559 | let val_addr = read_addr_bytes(buf)?; |
| 560 | let val = read_string(&val_addr, stt)?; |
| 561 | Ok(Syntax::Atom(info, val)) |
| 562 | }, |
| 563 | 3 => { |
| 564 | let info = deserialize_source_info(buf, stt)?; |
| 565 | let raw_val = deserialize_substring(buf, stt)?; |
| 566 | let val_addr = read_addr_bytes(buf)?; |
| 567 | let val = decompile_name(&val_addr, stt)?; |
| 568 | let pr_count = read_tag0(buf)? as usize; |