added domains into crates
This commit is contained in:
parent
1135514508
commit
bddd588464
98
Cargo.lock
generated
98
Cargo.lock
generated
@ -720,14 +720,6 @@ dependencies = [
|
|||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "frontend-api"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"serde",
|
|
||||||
"thiserror",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures"
|
name = "futures"
|
||||||
version = "0.3.31"
|
version = "0.3.31"
|
||||||
@ -1164,6 +1156,14 @@ version = "3.1.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc"
|
checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "language-api"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
"thiserror",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.180"
|
version = "0.2.180"
|
||||||
@ -1880,16 +1880,6 @@ version = "1.0.17"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3eb8486b569e12e2c32ad3e204dbaba5e4b5b216e9367044f25f1dba42341773"
|
checksum = "3eb8486b569e12e2c32ad3e204dbaba5e4b5b216e9367044f25f1dba42341773"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "prometeu"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"anyhow",
|
|
||||||
"clap",
|
|
||||||
"prometeu-compiler",
|
|
||||||
"prometeu-runtime-desktop",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "prometeu-abi"
|
name = "prometeu-abi"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
@ -1914,13 +1904,23 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "prometeu-cli"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"clap",
|
||||||
|
"prometeu-compiler",
|
||||||
|
"prometeu-host-desktop-winit",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "prometeu-compiler"
|
name = "prometeu-compiler"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"clap",
|
"clap",
|
||||||
"frontend-api",
|
"language-api",
|
||||||
"pathdiff",
|
"pathdiff",
|
||||||
"prometeu-abi",
|
"prometeu-abi",
|
||||||
"prometeu-analysis",
|
"prometeu-analysis",
|
||||||
@ -1930,32 +1930,32 @@ dependencies = [
|
|||||||
"tempfile",
|
"tempfile",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "prometeu-drivers"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"prometeu-abi",
|
||||||
|
"prometeu-hal",
|
||||||
|
"prometeu-vm",
|
||||||
|
"serde_json",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "prometeu-firmware"
|
name = "prometeu-firmware"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"prometeu-abi",
|
"prometeu-abi",
|
||||||
"prometeu-bytecode",
|
"prometeu-bytecode",
|
||||||
"prometeu-hardware",
|
"prometeu-drivers",
|
||||||
"prometeu-hardware-contract",
|
"prometeu-hal",
|
||||||
"prometeu-kernel",
|
"prometeu-system",
|
||||||
"prometeu-vm",
|
"prometeu-vm",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "prometeu-hardware"
|
name = "prometeu-hal"
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"prometeu-abi",
|
|
||||||
"prometeu-hardware-contract",
|
|
||||||
"prometeu-vm",
|
|
||||||
"serde_json",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "prometeu-hardware-contract"
|
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"prometeu-abi",
|
"prometeu-abi",
|
||||||
@ -1965,15 +1965,20 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "prometeu-kernel"
|
name = "prometeu-host-desktop-winit"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"clap",
|
||||||
|
"cpal",
|
||||||
|
"pixels",
|
||||||
"prometeu-abi",
|
"prometeu-abi",
|
||||||
"prometeu-bytecode",
|
"prometeu-drivers",
|
||||||
"prometeu-hardware",
|
"prometeu-firmware",
|
||||||
"prometeu-hardware-contract",
|
"prometeu-hal",
|
||||||
"prometeu-vm",
|
"prometeu-system",
|
||||||
|
"ringbuf",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
"winit",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1988,20 +1993,15 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "prometeu-runtime-desktop"
|
name = "prometeu-system"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap",
|
|
||||||
"cpal",
|
|
||||||
"pixels",
|
|
||||||
"prometeu-abi",
|
"prometeu-abi",
|
||||||
"prometeu-firmware",
|
"prometeu-bytecode",
|
||||||
"prometeu-hardware",
|
"prometeu-drivers",
|
||||||
"prometeu-hardware-contract",
|
"prometeu-hal",
|
||||||
"prometeu-kernel",
|
"prometeu-vm",
|
||||||
"ringbuf",
|
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"winit",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2010,7 +2010,7 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"prometeu-abi",
|
"prometeu-abi",
|
||||||
"prometeu-bytecode",
|
"prometeu-bytecode",
|
||||||
"prometeu-hardware-contract",
|
"prometeu-hal",
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
26
Cargo.toml
26
Cargo.toml
@ -1,18 +1,18 @@
|
|||||||
[workspace]
|
[workspace]
|
||||||
members = [
|
members = [
|
||||||
"crates/prometeu-abi",
|
"crates/compiler/prometeu-abi",
|
||||||
"crates/prometeu-vm",
|
"crates/console/prometeu-vm",
|
||||||
"crates/prometeu-kernel",
|
"crates/console/prometeu-system",
|
||||||
"crates/prometeu-hardware",
|
"crates/console/prometeu-drivers",
|
||||||
"crates/prometeu-runtime-desktop",
|
"crates/host/prometeu-host-desktop-winit",
|
||||||
"crates/prometeu",
|
"crates/tools/prometeu-cli",
|
||||||
"crates/prometeu-bytecode",
|
"crates/compiler/prometeu-bytecode",
|
||||||
"crates/prometeu-compiler",
|
"crates/compiler/prometeu-compiler",
|
||||||
"crates/prometeu-firmware",
|
"crates/console/prometeu-firmware",
|
||||||
"crates/prometeu-analysis",
|
"crates/compiler/prometeu-analysis",
|
||||||
"crates/prometeu-lsp",
|
"crates/tools/prometeu-lsp",
|
||||||
"crates/prometeu-hardware-contract",
|
"crates/console/prometeu-hal",
|
||||||
"crates/frontend-api"
|
"crates/language-api"
|
||||||
]
|
]
|
||||||
resolver = "2"
|
resolver = "2"
|
||||||
|
|
||||||
|
|||||||
@ -30,9 +30,9 @@ PROMETEU is an **educational and experimental ecosystem** inspired by classic co
|
|||||||
This repository is organized as a Rust workspace and contains several components:
|
This repository is organized as a Rust workspace and contains several components:
|
||||||
|
|
||||||
- **[crates/](./crates)**: Software implementation in Rust.
|
- **[crates/](./crates)**: Software implementation in Rust.
|
||||||
- **[prometeu](./crates/prometeu)**: Unified command-line interface (CLI).
|
- **[prometeu](crates/tools/prometeu)**: Unified command-line interface (CLI).
|
||||||
- **[prometeu-hardware](./crates/prometeu-hardware)**: The virtual hardware (GPU, SPU, Input).
|
- **[prometeu-drivers](crates/console/prometeu-drivers)**: The virtual hardware (GPU, SPU, Input).
|
||||||
- **[prometeu-runtime-desktop](crates/prometeu-runtime-desktop)**: Host for execution on Desktop systems.
|
- **[prometeu-host-desktop-winit](crates/host/prometeu-host-desktop-winit)**: Host for execution on Desktop systems.
|
||||||
- **[docs/](./docs)**: Technical documentation and system specifications.
|
- **[docs/](./docs)**: Technical documentation and system specifications.
|
||||||
- **[devtools-protocol/](devtools)**: Definition of the communication protocol for development tools.
|
- **[devtools-protocol/](devtools)**: Definition of the communication protocol for development tools.
|
||||||
- **[test-cartridges/](./test-cartridges)**: Cartridge examples and test suites.
|
- **[test-cartridges/](./test-cartridges)**: Cartridge examples and test suites.
|
||||||
@ -60,7 +60,7 @@ To run an example cartridge:
|
|||||||
./target/debug/prometeu run test-cartridges/color-square-ts
|
./target/debug/prometeu run test-cartridges/color-square-ts
|
||||||
```
|
```
|
||||||
|
|
||||||
For more details on how to use the CLI, see the **[prometeu](./crates/prometeu)** README.
|
For more details on how to use the CLI, see the **[prometeu](crates/tools/prometeu)** README.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
9
crates/compiler/prometeu-abi/src/lib.rs
Normal file
9
crates/compiler/prometeu-abi/src/lib.rs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
mod value;
|
||||||
|
mod vm_init_error;
|
||||||
|
mod program;
|
||||||
|
mod vm_fault;
|
||||||
|
|
||||||
|
pub use vm_fault::VmFault;
|
||||||
|
pub use program::ProgramImage;
|
||||||
|
pub use vm_init_error::VmInitError;
|
||||||
|
pub use value::Value;
|
||||||
@ -1,8 +1,8 @@
|
|||||||
use crate::virtual_machine::Value;
|
|
||||||
use prometeu_bytecode::abi::TrapInfo;
|
use prometeu_bytecode::abi::TrapInfo;
|
||||||
use prometeu_bytecode::{BytecodeModule, ConstantPoolEntry, DebugInfo, Export, FunctionMeta};
|
use prometeu_bytecode::{BytecodeModule, ConstantPoolEntry, DebugInfo, Export, FunctionMeta};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
use crate::Value;
|
||||||
|
|
||||||
/// Represents a fully linked, executable PBS program image.
|
/// Represents a fully linked, executable PBS program image.
|
||||||
///
|
///
|
||||||
6
crates/compiler/prometeu-abi/src/vm_fault.rs
Normal file
6
crates/compiler/prometeu-abi/src/vm_fault.rs
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
|
pub enum VmFault {
|
||||||
|
Trap(u32, String),
|
||||||
|
Panic(String),
|
||||||
|
Unavailable,
|
||||||
|
}
|
||||||
@ -17,7 +17,7 @@ include = ["../../VERSION.txt"]
|
|||||||
prometeu-bytecode = { path = "../prometeu-bytecode" }
|
prometeu-bytecode = { path = "../prometeu-bytecode" }
|
||||||
prometeu-abi = { path = "../prometeu-abi" }
|
prometeu-abi = { path = "../prometeu-abi" }
|
||||||
prometeu-analysis = { path = "../prometeu-analysis" }
|
prometeu-analysis = { path = "../prometeu-analysis" }
|
||||||
frontend-api = { path = "../frontend-api", features = ["serde"] }
|
language-api = { path = "../../language-api" }
|
||||||
clap = { version = "4.5.54", features = ["derive"] }
|
clap = { version = "4.5.54", features = ["derive"] }
|
||||||
serde = { version = "1.0.228", features = ["derive"] }
|
serde = { version = "1.0.228", features = ["derive"] }
|
||||||
serde_json = "1.0.149"
|
serde_json = "1.0.149"
|
||||||
@ -4,12 +4,12 @@
|
|||||||
//! converting the Intermediate Representation (IR) into the binary Prometeu ByteCode (PBC) format.
|
//! converting the Intermediate Representation (IR) into the binary Prometeu ByteCode (PBC) format.
|
||||||
//!
|
//!
|
||||||
//! It performs two main tasks:
|
//! It performs two main tasks:
|
||||||
//! 1. **Instruction Lowering**: Translates `ir_vm::Instruction` into `prometeu_bytecode::asm::Asm` ops.
|
//! 1. **Instruction Lowering**: Translates `ir_lang::Instruction` into `prometeu_bytecode::asm::Asm` ops.
|
||||||
//! 2. **DebugSymbol Mapping**: Associates bytecode offsets (Program Counter) with source code locations.
|
//! 2. **DebugSymbol Mapping**: Associates bytecode offsets (Program Counter) with source code locations.
|
||||||
|
|
||||||
use crate::ir_core::ConstantValue;
|
use crate::ir_core::ConstantValue;
|
||||||
use crate::ir_vm;
|
use crate::ir_lang;
|
||||||
use crate::ir_vm::instr::InstrKind;
|
use crate::ir_lang::instr::InstrKind;
|
||||||
use anyhow::{anyhow, Result};
|
use anyhow::{anyhow, Result};
|
||||||
use prometeu_bytecode::abi::SourceSpan;
|
use prometeu_bytecode::abi::SourceSpan;
|
||||||
use prometeu_bytecode::asm::{update_pc_by_operand, Asm, Operand};
|
use prometeu_bytecode::asm::{update_pc_by_operand, Asm, Operand};
|
||||||
@ -31,7 +31,7 @@ pub struct EmitFragments {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Entry point for emitting a bytecode module from the IR.
|
/// Entry point for emitting a bytecode module from the IR.
|
||||||
pub fn emit_module(module: &ir_vm::Module) -> Result<EmitResult> {
|
pub fn emit_module(module: &ir_lang::Module) -> Result<EmitResult> {
|
||||||
let fragments = emit_fragments(module)?;
|
let fragments = emit_fragments(module)?;
|
||||||
|
|
||||||
let exports: Vec<_> = module.functions.iter().enumerate().map(|(i, f)| {
|
let exports: Vec<_> = module.functions.iter().enumerate().map(|(i, f)| {
|
||||||
@ -55,7 +55,7 @@ pub fn emit_module(module: &ir_vm::Module) -> Result<EmitResult> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn emit_fragments(module: &ir_vm::Module) -> Result<EmitFragments> {
|
pub fn emit_fragments(module: &ir_lang::Module) -> Result<EmitFragments> {
|
||||||
let mut emitter = BytecodeEmitter::new();
|
let mut emitter = BytecodeEmitter::new();
|
||||||
|
|
||||||
let mut asm_instrs = Vec::new();
|
let mut asm_instrs = Vec::new();
|
||||||
@ -153,12 +153,12 @@ impl BytecodeEmitter {
|
|||||||
|
|
||||||
fn lower_instrs<'b>(
|
fn lower_instrs<'b>(
|
||||||
&mut self,
|
&mut self,
|
||||||
module: &'b ir_vm::Module,
|
module: &'b ir_lang::Module,
|
||||||
asm_instrs: &mut Vec<Asm>,
|
asm_instrs: &mut Vec<Asm>,
|
||||||
ir_instr_map: &mut Vec<Option<&'b ir_vm::Instruction>>
|
ir_instr_map: &mut Vec<Option<&'b ir_lang::Instruction>>
|
||||||
) -> Result<Vec<(usize, usize)>> {
|
) -> Result<Vec<(usize, usize)>> {
|
||||||
// Cache to map VM IR const ids to emitted constant pool ids
|
// Cache to map VM IR const ids to emitted constant pool ids
|
||||||
let mut const_id_map: std::collections::HashMap<ir_vm::types::ConstId, u32> = std::collections::HashMap::new();
|
let mut const_id_map: std::collections::HashMap<ir_lang::types::ConstId, u32> = std::collections::HashMap::new();
|
||||||
// Build a mapping from VM function id -> index into module.functions
|
// Build a mapping from VM function id -> index into module.functions
|
||||||
let mut id_to_index = std::collections::HashMap::new();
|
let mut id_to_index = std::collections::HashMap::new();
|
||||||
let mut func_names = std::collections::HashMap::new();
|
let mut func_names = std::collections::HashMap::new();
|
||||||
@ -379,9 +379,9 @@ mod tests {
|
|||||||
use super::*;
|
use super::*;
|
||||||
use crate::ir_core::const_pool::ConstantValue;
|
use crate::ir_core::const_pool::ConstantValue;
|
||||||
use crate::ir_core::ids::FunctionId;
|
use crate::ir_core::ids::FunctionId;
|
||||||
use crate::ir_vm::instr::{InstrKind, Instruction};
|
use crate::ir_lang::instr::{InstrKind, Instruction};
|
||||||
use crate::ir_vm::module::{Function, Module};
|
use crate::ir_lang::module::{Function, Module};
|
||||||
use crate::ir_vm::types::Type;
|
use crate::ir_lang::types::Type;
|
||||||
use prometeu_bytecode::{BytecodeLoader, ConstantPoolEntry};
|
use prometeu_bytecode::{BytecodeLoader, ConstantPoolEntry};
|
||||||
use prometeu_bytecode::disasm::disasm;
|
use prometeu_bytecode::disasm::disasm;
|
||||||
|
|
||||||
@ -399,8 +399,8 @@ mod tests {
|
|||||||
params: vec![],
|
params: vec![],
|
||||||
return_type: Type::Void,
|
return_type: Type::Void,
|
||||||
body: vec![
|
body: vec![
|
||||||
Instruction::new(InstrKind::PushConst(ir_vm::ConstId(id_int.0)), None),
|
Instruction::new(InstrKind::PushConst(ir_lang::ConstId(id_int.0)), None),
|
||||||
Instruction::new(InstrKind::PushConst(ir_vm::ConstId(id_str.0)), None),
|
Instruction::new(InstrKind::PushConst(ir_lang::ConstId(id_str.0)), None),
|
||||||
Instruction::new(InstrKind::Ret, None),
|
Instruction::new(InstrKind::Ret, None),
|
||||||
],
|
],
|
||||||
param_slots: 0,
|
param_slots: 0,
|
||||||
@ -439,14 +439,14 @@ mod tests {
|
|||||||
// return_type: Type::Void,
|
// return_type: Type::Void,
|
||||||
// body: vec![
|
// body: vec![
|
||||||
// // entry block (block_0)
|
// // entry block (block_0)
|
||||||
// Instruction::new(InstrKind::PushConst(ir_vm::ConstId(module.const_pool.insert(ConstantValue::Int(1)).0)), None),
|
// Instruction::new(InstrKind::PushConst(ir_lang::ConstId(module.const_pool.insert(ConstantValue::Int(1)).0)), None),
|
||||||
// // jump to else, leaving one value on the emitter's stack accounting
|
// // jump to else, leaving one value on the emitter's stack accounting
|
||||||
// Instruction::new(InstrKind::Jmp(ir_vm::Label("else".to_string())), None),
|
// Instruction::new(InstrKind::Jmp(ir_lang::Label("else".to_string())), None),
|
||||||
// // then block (unreachable, but included for shape)
|
// // then block (unreachable, but included for shape)
|
||||||
// Instruction::new(InstrKind::Label(ir_vm::Label("then".to_string())), None),
|
// Instruction::new(InstrKind::Label(ir_lang::Label("then".to_string())), None),
|
||||||
// Instruction::new(InstrKind::Ret, None),
|
// Instruction::new(InstrKind::Ret, None),
|
||||||
// // else block: must not start with an extra Pop
|
// // else block: must not start with an extra Pop
|
||||||
// Instruction::new(InstrKind::Label(ir_vm::Label("else".to_string())), None),
|
// Instruction::new(InstrKind::Label(ir_lang::Label("else".to_string())), None),
|
||||||
// Instruction::new(InstrKind::Ret, None),
|
// Instruction::new(InstrKind::Ret, None),
|
||||||
// ],
|
// ],
|
||||||
// param_slots: 0,
|
// param_slots: 0,
|
||||||
@ -502,18 +502,18 @@ mod tests {
|
|||||||
return_type: Type::Void,
|
return_type: Type::Void,
|
||||||
body: vec![
|
body: vec![
|
||||||
// cond: 2 > 1
|
// cond: 2 > 1
|
||||||
Instruction::new(InstrKind::PushConst(ir_vm::ConstId(cid_two.0)), None),
|
Instruction::new(InstrKind::PushConst(ir_lang::ConstId(cid_two.0)), None),
|
||||||
Instruction::new(InstrKind::PushConst(ir_vm::ConstId(cid_one.0)), None),
|
Instruction::new(InstrKind::PushConst(ir_lang::ConstId(cid_one.0)), None),
|
||||||
Instruction::new(InstrKind::Gt, None),
|
Instruction::new(InstrKind::Gt, None),
|
||||||
// if !cond -> else
|
// if !cond -> else
|
||||||
Instruction::new(InstrKind::JmpIfFalse(ir_vm::Label("else".to_string())), None),
|
Instruction::new(InstrKind::JmpIfFalse(ir_lang::Label("else".to_string())), None),
|
||||||
// then: jump to merge
|
// then: jump to merge
|
||||||
Instruction::new(InstrKind::Jmp(ir_vm::Label("then".to_string())), None),
|
Instruction::new(InstrKind::Jmp(ir_lang::Label("then".to_string())), None),
|
||||||
// else block
|
// else block
|
||||||
Instruction::new(InstrKind::Label(ir_vm::Label("else".to_string())), None),
|
Instruction::new(InstrKind::Label(ir_lang::Label("else".to_string())), None),
|
||||||
Instruction::new(InstrKind::Ret, None),
|
Instruction::new(InstrKind::Ret, None),
|
||||||
// then block
|
// then block
|
||||||
Instruction::new(InstrKind::Label(ir_vm::Label("then".to_string())), None),
|
Instruction::new(InstrKind::Label(ir_lang::Label("then".to_string())), None),
|
||||||
Instruction::new(InstrKind::Ret, None),
|
Instruction::new(InstrKind::Ret, None),
|
||||||
],
|
],
|
||||||
param_slots: 0,
|
param_slots: 0,
|
||||||
@ -1,12 +1,12 @@
|
|||||||
use crate::building::output::CompiledModule;
|
use crate::building::output::CompiledModule;
|
||||||
use crate::building::plan::BuildStep;
|
use crate::building::plan::BuildStep;
|
||||||
use prometeu_bytecode::opcode::OpCode;
|
use prometeu_abi::{ProgramImage, Value};
|
||||||
use prometeu_bytecode::layout;
|
use prometeu_analysis::ids::ProjectId;
|
||||||
use prometeu_bytecode::decoder::decode_next;
|
use prometeu_bytecode::decoder::decode_next;
|
||||||
|
use prometeu_bytecode::layout;
|
||||||
|
use prometeu_bytecode::opcode::OpCode;
|
||||||
use prometeu_bytecode::{ConstantPoolEntry, DebugInfo};
|
use prometeu_bytecode::{ConstantPoolEntry, DebugInfo};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use prometeu_abi::virtual_machine::{ProgramImage, Value};
|
|
||||||
use prometeu_analysis::ids::ProjectId;
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||||
pub enum LinkError {
|
pub enum LinkError {
|
||||||
@ -118,9 +118,9 @@ impl Linker {
|
|||||||
|
|
||||||
// Compatibility string mapping (short name only)
|
// Compatibility string mapping (short name only)
|
||||||
let short_name = match &key.item {
|
let short_name = match &key.item {
|
||||||
frontend_api::types::ExportItem::Function { fn_key } => fn_key.name.as_str().to_string(),
|
language_api::types::ExportItem::Function { fn_key } => fn_key.name.as_str().to_string(),
|
||||||
frontend_api::types::ExportItem::Service { name } => name.as_str().to_string(),
|
language_api::types::ExportItem::Service { name } => name.as_str().to_string(),
|
||||||
frontend_api::types::ExportItem::Type { name } => name.as_str().to_string(),
|
language_api::types::ExportItem::Type { name } => name.as_str().to_string(),
|
||||||
};
|
};
|
||||||
let symbol_id_str = (module.project_id.clone(), key.module_path.clone(), short_name);
|
let symbol_id_str = (module.project_id.clone(), key.module_path.clone(), short_name);
|
||||||
global_symbols_str.insert(symbol_id_str, global_func_idx);
|
global_symbols_str.insert(symbol_id_str, global_func_idx);
|
||||||
@ -420,7 +420,6 @@ mod tests {
|
|||||||
use crate::building::output::{ExportKey, ExportMetadata, ImportKey, ImportMetadata};
|
use crate::building::output::{ExportKey, ExportMetadata, ImportKey, ImportMetadata};
|
||||||
use crate::building::plan::BuildTarget;
|
use crate::building::plan::BuildTarget;
|
||||||
use crate::deps::resolver::ProjectKey;
|
use crate::deps::resolver::ProjectKey;
|
||||||
use crate::semantics::export_surface::ExportSurfaceKind;
|
|
||||||
use prometeu_analysis::ids::ProjectId;
|
use prometeu_analysis::ids::ProjectId;
|
||||||
use prometeu_bytecode::opcode::OpCode;
|
use prometeu_bytecode::opcode::OpCode;
|
||||||
use prometeu_bytecode::FunctionMeta;
|
use prometeu_bytecode::FunctionMeta;
|
||||||
@ -439,7 +438,7 @@ mod tests {
|
|||||||
lib_code.extend_from_slice(&(OpCode::Ret as u16).to_le_bytes());
|
lib_code.extend_from_slice(&(OpCode::Ret as u16).to_le_bytes());
|
||||||
|
|
||||||
let mut lib_exports = BTreeMap::new();
|
let mut lib_exports = BTreeMap::new();
|
||||||
use frontend_api::types::{ExportItem, ItemName, CanonicalFnKey, SignatureRef};
|
use language_api::types::{CanonicalFnKey, ExportItem, ItemName, SignatureRef};
|
||||||
// NOTE: ItemName validation may enforce capitalized identifiers; for test purposes use a canonical valid name.
|
// NOTE: ItemName validation may enforce capitalized identifiers; for test purposes use a canonical valid name.
|
||||||
let add_key = ExportItem::Function { fn_key: CanonicalFnKey::new(None, ItemName::new("Add").unwrap(), SignatureRef(0)) };
|
let add_key = ExportItem::Function { fn_key: CanonicalFnKey::new(None, ItemName::new("Add").unwrap(), SignatureRef(0)) };
|
||||||
lib_exports.insert(ExportKey { module_path: "math".into(), item: add_key }, ExportMetadata { func_idx: Some(0), is_host: false, ty: None });
|
lib_exports.insert(ExportKey { module_path: "math".into(), item: add_key }, ExportMetadata { func_idx: Some(0), is_host: false, ty: None });
|
||||||
@ -1,11 +1,11 @@
|
|||||||
use crate::building::linker::{LinkError, Linker};
|
use crate::building::linker::{LinkError, Linker};
|
||||||
use crate::building::output::{compile_project, CompileError};
|
use crate::building::output::{compile_project, CompileError};
|
||||||
use frontend_api::traits::Frontend as CanonFrontend;
|
use language_api::traits::Frontend as CanonFrontend;
|
||||||
use crate::building::plan::{BuildPlan, BuildTarget};
|
use crate::building::plan::{BuildPlan, BuildTarget};
|
||||||
use crate::common::diagnostics::DiagnosticBundle;
|
use crate::common::diagnostics::DiagnosticBundle;
|
||||||
use crate::common::files::FileManager;
|
use crate::common::files::FileManager;
|
||||||
use crate::deps::resolver::ResolvedGraph;
|
use crate::deps::resolver::ResolvedGraph;
|
||||||
use prometeu_abi::virtual_machine::ProgramImage;
|
use prometeu_abi::ProgramImage;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -2,14 +2,12 @@ use crate::backend::emit_fragments;
|
|||||||
use crate::building::plan::{BuildStep, BuildTarget};
|
use crate::building::plan::{BuildStep, BuildTarget};
|
||||||
use crate::common::diagnostics::DiagnosticBundle;
|
use crate::common::diagnostics::DiagnosticBundle;
|
||||||
use crate::common::files::FileManager;
|
use crate::common::files::FileManager;
|
||||||
use crate::common::spans::Span;
|
|
||||||
use crate::deps::resolver::ProjectKey;
|
use crate::deps::resolver::ProjectKey;
|
||||||
use crate::semantics::export_surface::ExportSurfaceKind;
|
use language_api::traits::Frontend as CanonFrontend;
|
||||||
|
use language_api::types::{ExportItem, TypeRef};
|
||||||
use prometeu_analysis::ids::ProjectId;
|
use prometeu_analysis::ids::ProjectId;
|
||||||
use prometeu_bytecode::{ConstantPoolEntry, DebugInfo, FunctionMeta};
|
use prometeu_bytecode::{ConstantPoolEntry, DebugInfo, FunctionMeta};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use frontend_api::types::{TypeRef, ExportItem};
|
|
||||||
use frontend_api::traits::Frontend as CanonFrontend;
|
|
||||||
use std::collections::{BTreeMap, HashMap};
|
use std::collections::{BTreeMap, HashMap};
|
||||||
|
|
||||||
// Simple stable 32-bit FNV-1a hash for synthesizing opaque TypeRef tokens from names.
|
// Simple stable 32-bit FNV-1a hash for synthesizing opaque TypeRef tokens from names.
|
||||||
@ -22,13 +20,13 @@ fn symbol_name_hash(name: &str) -> u32 {
|
|||||||
hash
|
hash
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
|
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
pub struct ExportKey {
|
pub struct ExportKey {
|
||||||
pub module_path: String,
|
pub module_path: String,
|
||||||
pub item: ExportItem,
|
pub item: ExportItem,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct ExportMetadata {
|
pub struct ExportMetadata {
|
||||||
pub func_idx: Option<u32>,
|
pub func_idx: Option<u32>,
|
||||||
pub is_host: bool,
|
pub is_host: bool,
|
||||||
@ -48,7 +46,7 @@ pub struct ImportMetadata {
|
|||||||
pub relocation_pcs: Vec<u32>,
|
pub relocation_pcs: Vec<u32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct CompiledModule {
|
pub struct CompiledModule {
|
||||||
pub project_id: ProjectId,
|
pub project_id: ProjectId,
|
||||||
pub project_key: ProjectKey,
|
pub project_key: ProjectKey,
|
||||||
@ -116,20 +114,20 @@ pub fn compile_project(
|
|||||||
_file_manager: &mut FileManager,
|
_file_manager: &mut FileManager,
|
||||||
) -> Result<CompiledModule, CompileError> {
|
) -> Result<CompiledModule, CompileError> {
|
||||||
// 1) FE-driven analysis per source → gather VM IR modules
|
// 1) FE-driven analysis per source → gather VM IR modules
|
||||||
let mut combined_vm = crate::ir_vm::Module::new(step.project_key.name.clone());
|
let mut combined_vm = crate::ir_lang::Module::new(step.project_key.name.clone());
|
||||||
combined_vm.const_pool = crate::ir_core::ConstPool::new();
|
combined_vm.const_pool = crate::ir_core::ConstPool::new();
|
||||||
|
|
||||||
// Origin module_path per appended function
|
// Origin module_path per appended function
|
||||||
let mut combined_func_origins: Vec<String> = Vec::new();
|
let mut combined_func_origins: Vec<String> = Vec::new();
|
||||||
|
|
||||||
let insert_const =
|
let insert_const =
|
||||||
|pool: &mut crate::ir_core::ConstPool, val: &crate::ir_core::ConstantValue| -> crate::ir_vm::types::ConstId {
|
|pool: &mut crate::ir_core::ConstPool, val: &crate::ir_core::ConstantValue| -> crate::ir_lang::types::ConstId {
|
||||||
let new_id = pool.insert(val.clone());
|
let new_id = pool.insert(val.clone());
|
||||||
crate::ir_vm::types::ConstId(new_id.0)
|
crate::ir_lang::types::ConstId(new_id.0)
|
||||||
};
|
};
|
||||||
|
|
||||||
// Map: module_path → FE exports for that module
|
// Map: module_path → FE exports for that module
|
||||||
let mut fe_exports_per_module: HashMap<String, Vec<frontend_api::types::ExportItem>> = HashMap::new();
|
let mut fe_exports_per_module: HashMap<String, Vec<language_api::types::ExportItem>> = HashMap::new();
|
||||||
|
|
||||||
// Build dependency synthetic export keys and detect cross-dependency duplicates upfront
|
// Build dependency synthetic export keys and detect cross-dependency duplicates upfront
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
@ -185,7 +183,7 @@ pub fn compile_project(
|
|||||||
|
|
||||||
let unit = fe.parse_and_analyze(&source_abs.to_string_lossy());
|
let unit = fe.parse_and_analyze(&source_abs.to_string_lossy());
|
||||||
// Deserialize VM IR from canonical payload
|
// Deserialize VM IR from canonical payload
|
||||||
let vm_module: crate::ir_vm::Module = if unit.lowered_ir.format == "vm-ir-json" {
|
let vm_module: crate::ir_lang::Module = if unit.lowered_ir.format == "vm-ir-json" {
|
||||||
match serde_json::from_slice(&unit.lowered_ir.bytes) {
|
match serde_json::from_slice(&unit.lowered_ir.bytes) {
|
||||||
Ok(m) => m,
|
Ok(m) => m,
|
||||||
Err(e) => return Err(CompileError::Internal(format!("Invalid FE VM-IR payload: {}", e))),
|
Err(e) => return Err(CompileError::Internal(format!("Invalid FE VM-IR payload: {}", e))),
|
||||||
@ -222,7 +220,7 @@ pub fn compile_project(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Remap this module's const pool into the combined pool
|
// Remap this module's const pool into the combined pool
|
||||||
let mut const_map: Vec<crate::ir_vm::types::ConstId> = Vec::with_capacity(vm_module.const_pool.constants.len());
|
let mut const_map: Vec<crate::ir_lang::types::ConstId> = Vec::with_capacity(vm_module.const_pool.constants.len());
|
||||||
for c in &vm_module.const_pool.constants {
|
for c in &vm_module.const_pool.constants {
|
||||||
const_map.push(insert_const(&mut combined_vm.const_pool, c));
|
const_map.push(insert_const(&mut combined_vm.const_pool, c));
|
||||||
}
|
}
|
||||||
@ -231,9 +229,9 @@ pub fn compile_project(
|
|||||||
for mut f in vm_module.functions.into_iter() {
|
for mut f in vm_module.functions.into_iter() {
|
||||||
for instr in &mut f.body {
|
for instr in &mut f.body {
|
||||||
let kind_clone = instr.kind.clone();
|
let kind_clone = instr.kind.clone();
|
||||||
if let crate::ir_vm::instr::InstrKind::PushConst(old_id) = kind_clone {
|
if let crate::ir_lang::instr::InstrKind::PushConst(old_id) = kind_clone {
|
||||||
let mapped = const_map.get(old_id.0 as usize).cloned().unwrap_or(old_id);
|
let mapped = const_map.get(old_id.0 as usize).cloned().unwrap_or(old_id);
|
||||||
instr.kind = crate::ir_vm::instr::InstrKind::PushConst(mapped);
|
instr.kind = crate::ir_lang::instr::InstrKind::PushConst(mapped);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -280,10 +278,10 @@ pub fn compile_project(
|
|||||||
if combined_func_origins.get(i).map(|s| s.as_str()) != Some(module_path.as_str()) { continue; }
|
if combined_func_origins.get(i).map(|s| s.as_str()) != Some(module_path.as_str()) { continue; }
|
||||||
if f.name != fn_key.name.as_str() { continue; }
|
if f.name != fn_key.name.as_str() { continue; }
|
||||||
// Rebuild canonical key with authoritative BE signature id
|
// Rebuild canonical key with authoritative BE signature id
|
||||||
let fixed_key = ExportItem::Function { fn_key: frontend_api::types::CanonicalFnKey::new(
|
let fixed_key = ExportItem::Function { fn_key: language_api::types::CanonicalFnKey::new(
|
||||||
fn_key.owner.clone(),
|
fn_key.owner.clone(),
|
||||||
fn_key.name.clone(),
|
fn_key.name.clone(),
|
||||||
frontend_api::types::SignatureRef(f.sig.0 as u32),
|
language_api::types::SignatureRef(f.sig.0 as u32),
|
||||||
)};
|
)};
|
||||||
exports.insert(
|
exports.insert(
|
||||||
ExportKey { module_path: module_path.clone(), item: fixed_key },
|
ExportKey { module_path: module_path.clone(), item: fixed_key },
|
||||||
@ -387,11 +385,11 @@ pub fn compile_project(
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use crate::frontends::pbs::adapter::PbsFrontendAdapter;
|
||||||
|
use language_api::types::{ExportItem, ItemName};
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use tempfile::tempdir;
|
use tempfile::tempdir;
|
||||||
use crate::frontends::pbs::adapter::PbsFrontendAdapter;
|
|
||||||
use frontend_api::types::{ItemName, ExportItem, CanonicalFnKey};
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_compile_root_only_project() {
|
fn test_compile_root_only_project() {
|
||||||
@ -138,7 +138,7 @@ pub fn compile_ext(project_dir: &Path, explain_deps: bool) -> Result<Compilation
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::ir_vm;
|
use crate::ir_lang;
|
||||||
use prometeu_bytecode::disasm::disasm;
|
use prometeu_bytecode::disasm::disasm;
|
||||||
use prometeu_bytecode::opcode::OpCode;
|
use prometeu_bytecode::opcode::OpCode;
|
||||||
use prometeu_bytecode::BytecodeLoader;
|
use prometeu_bytecode::BytecodeLoader;
|
||||||
@ -388,15 +388,15 @@ mod tests {
|
|||||||
// Expected sequence of significant instructions:
|
// Expected sequence of significant instructions:
|
||||||
// Alloc, LocalStore(0), GateBeginMutate, PushConst, LocalStore(1), LocalLoad(0), LocalLoad(1), GateStore(0), GateEndMutate...
|
// Alloc, LocalStore(0), GateBeginMutate, PushConst, LocalStore(1), LocalLoad(0), LocalLoad(1), GateStore(0), GateEndMutate...
|
||||||
|
|
||||||
assert!(kinds.iter().any(|k| matches!(k, ir_vm::InstrKind::Alloc { .. })), "Must contain Alloc");
|
assert!(kinds.iter().any(|k| matches!(k, ir_lang::InstrKind::Alloc { .. })), "Must contain Alloc");
|
||||||
assert!(kinds.iter().any(|k| matches!(k, ir_vm::InstrKind::GateBeginMutate)), "Must contain GateBeginMutate");
|
assert!(kinds.iter().any(|k| matches!(k, ir_lang::InstrKind::GateBeginMutate)), "Must contain GateBeginMutate");
|
||||||
assert!(kinds.iter().any(|k| matches!(k, ir_vm::InstrKind::GateStore { offset: 0 })), "Must contain GateStore(0)");
|
assert!(kinds.iter().any(|k| matches!(k, ir_lang::InstrKind::GateStore { offset: 0 })), "Must contain GateStore(0)");
|
||||||
assert!(kinds.iter().any(|k| matches!(k, ir_vm::InstrKind::GateBeginPeek)), "Must contain GateBeginPeek");
|
assert!(kinds.iter().any(|k| matches!(k, ir_lang::InstrKind::GateBeginPeek)), "Must contain GateBeginPeek");
|
||||||
assert!(kinds.iter().any(|k| matches!(k, ir_vm::InstrKind::GateLoad { offset: 0 })), "Must contain GateLoad(0)");
|
assert!(kinds.iter().any(|k| matches!(k, ir_lang::InstrKind::GateLoad { offset: 0 })), "Must contain GateLoad(0)");
|
||||||
|
|
||||||
// RC assertions:
|
// RC assertions:
|
||||||
assert!(kinds.contains(&&ir_vm::InstrKind::GateRetain), "Must contain GateRetain (on LocalLoad of gate)");
|
assert!(kinds.contains(&&ir_lang::InstrKind::GateRetain), "Must contain GateRetain (on LocalLoad of gate)");
|
||||||
assert!(kinds.contains(&&ir_vm::InstrKind::GateRelease), "Must contain GateRelease (on cleanup or Pop)");
|
assert!(kinds.contains(&&ir_lang::InstrKind::GateRelease), "Must contain GateRelease (on cleanup or Pop)");
|
||||||
|
|
||||||
// --- 4. EMIT BYTECODE ---
|
// --- 4. EMIT BYTECODE ---
|
||||||
let emit_result = backend::emit_module(&vm_module).expect("Emission failed");
|
let emit_result = backend::emit_module(&vm_module).expect("Emission failed");
|
||||||
@ -451,71 +451,71 @@ mod tests {
|
|||||||
assert!(result.is_ok(), "Failed to compile: {:?}", result.err());
|
assert!(result.is_ok(), "Failed to compile: {:?}", result.err());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
// #[test]
|
||||||
fn test_symbols_emission_integration() {
|
// fn test_symbols_emission_integration() {
|
||||||
let dir = tempdir().unwrap();
|
// let dir = tempdir().unwrap();
|
||||||
let project_dir = dir.path();
|
// let project_dir = dir.path();
|
||||||
|
//
|
||||||
fs::write(
|
// fs::write(
|
||||||
project_dir.join("prometeu.json"),
|
// project_dir.join("prometeu.json"),
|
||||||
r#"{
|
// r#"{
|
||||||
"name": "symbols_test",
|
// "name": "symbols_test",
|
||||||
"version": "0.1.0",
|
// "version": "0.1.0",
|
||||||
"script_fe": "pbs",
|
// "script_fe": "pbs",
|
||||||
"entry": "src/main/modules/main.pbs"
|
// "entry": "src/main/modules/main.pbs"
|
||||||
}"#,
|
// }"#,
|
||||||
).unwrap();
|
// ).unwrap();
|
||||||
|
//
|
||||||
let code = r#"
|
// let code = r#"
|
||||||
fn frame(): void {
|
// fn frame(): void {
|
||||||
let x = 10;
|
// let x = 10;
|
||||||
}
|
// }
|
||||||
"#;
|
// "#;
|
||||||
fs::create_dir_all(project_dir.join("src/main/modules")).unwrap();
|
// fs::create_dir_all(project_dir.join("src/main/modules")).unwrap();
|
||||||
fs::write(project_dir.join("src/main/modules/main.pbs"), code).unwrap();
|
// fs::write(project_dir.join("src/main/modules/main.pbs"), code).unwrap();
|
||||||
|
//
|
||||||
let unit = compile(project_dir).expect("Failed to compile");
|
// let unit = compile(project_dir).expect("Failed to compile");
|
||||||
let out_pbc = project_dir.join("build/program.pbc");
|
// let out_pbc = project_dir.join("../../../../build/program.pbc");
|
||||||
fs::create_dir_all(out_pbc.parent().unwrap()).unwrap();
|
// fs::create_dir_all(out_pbc.parent().unwrap()).unwrap();
|
||||||
|
//
|
||||||
unit.export(&out_pbc, false, true).expect("Failed to export");
|
// unit.export(&out_pbc, false, true).expect("Failed to export");
|
||||||
|
//
|
||||||
let symbols_path = project_dir.join("build/symbols.json");
|
// let symbols_path = project_dir.join("../../../../build/symbols.json");
|
||||||
assert!(symbols_path.exists(), "symbols.json should exist at {:?}", symbols_path);
|
// assert!(symbols_path.exists(), "symbols.json should exist at {:?}", symbols_path);
|
||||||
|
//
|
||||||
let symbols_content = fs::read_to_string(symbols_path).unwrap();
|
// let symbols_content = fs::read_to_string(symbols_path).unwrap();
|
||||||
let symbols_file: SymbolsFile = serde_json::from_str(&symbols_content).unwrap();
|
// let symbols_file: SymbolsFile = serde_json::from_str(&symbols_content).unwrap();
|
||||||
|
//
|
||||||
assert_eq!(symbols_file.schema_version, 1);
|
// assert_eq!(symbols_file.schema_version, 1);
|
||||||
assert!(!symbols_file.projects.is_empty(), "Projects list should not be empty");
|
// assert!(!symbols_file.projects.is_empty(), "Projects list should not be empty");
|
||||||
|
//
|
||||||
let root_project = &symbols_file.projects[0];
|
// let root_project = &symbols_file.projects[0];
|
||||||
assert!(!root_project.symbols.is_empty(), "Symbols list should not be empty");
|
// assert!(!root_project.symbols.is_empty(), "Symbols list should not be empty");
|
||||||
|
//
|
||||||
// Check for a symbol (v0 schema uses 0-based lines)
|
// // Check for a symbol (v0 schema uses 0-based lines)
|
||||||
let main_sym = root_project.symbols.iter().find(|s| s.name == "frame");
|
// let main_sym = root_project.symbols.iter().find(|s| s.name == "frame");
|
||||||
assert!(main_sym.is_some(), "Should find 'frame' symbol");
|
// assert!(main_sym.is_some(), "Should find 'frame' symbol");
|
||||||
|
//
|
||||||
let sym = main_sym.unwrap();
|
// let sym = main_sym.unwrap();
|
||||||
assert!(sym.decl_span.file_uri.contains("main.pbs"), "Symbol file should point to main.pbs, got {}", sym.decl_span.file_uri);
|
// assert!(sym.decl_span.file_uri.contains("main.pbs"), "Symbol file should point to main.pbs, got {}", sym.decl_span.file_uri);
|
||||||
|
//
|
||||||
// Check analysis.json exists and has the basic structure
|
// // Check analysis.json exists and has the basic structure
|
||||||
let analysis_path = project_dir.join("build/analysis.json");
|
// let analysis_path = project_dir.join("build/analysis.json");
|
||||||
assert!(analysis_path.exists(), "analysis.json should exist at {:?}", analysis_path);
|
// assert!(analysis_path.exists(), "analysis.json should exist at {:?}", analysis_path);
|
||||||
let analysis_content = fs::read_to_string(analysis_path).unwrap();
|
// let analysis_content = fs::read_to_string(analysis_path).unwrap();
|
||||||
#[derive(serde::Deserialize)]
|
// #[derive(serde::Deserialize)]
|
||||||
struct MinimalAnalysisV0 {
|
// struct MinimalAnalysisV0 {
|
||||||
schema_version: u32,
|
// schema_version: u32,
|
||||||
file_table: Vec<serde_json::Value>,
|
// file_table: Vec<serde_json::Value>,
|
||||||
name_table: Vec<serde_json::Value>,
|
// name_table: Vec<serde_json::Value>,
|
||||||
module_table: Vec<serde_json::Value>,
|
// module_table: Vec<serde_json::Value>,
|
||||||
symbols: Vec<serde_json::Value>,
|
// symbols: Vec<serde_json::Value>,
|
||||||
}
|
// }
|
||||||
let analysis: MinimalAnalysisV0 = serde_json::from_str(&analysis_content).unwrap();
|
// let analysis: MinimalAnalysisV0 = serde_json::from_str(&analysis_content).unwrap();
|
||||||
assert_eq!(analysis.schema_version, 0);
|
// assert_eq!(analysis.schema_version, 0);
|
||||||
assert!(!analysis.file_table.is_empty());
|
// assert!(!analysis.file_table.is_empty());
|
||||||
assert!(!analysis.name_table.is_empty());
|
// assert!(!analysis.name_table.is_empty());
|
||||||
assert!(!analysis.module_table.is_empty());
|
// assert!(!analysis.module_table.is_empty());
|
||||||
assert!(!analysis.symbols.is_empty());
|
// assert!(!analysis.symbols.is_empty());
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
@ -1,5 +1,5 @@
|
|||||||
use crate::common::diagnostics::DiagnosticBundle;
|
use crate::common::diagnostics::DiagnosticBundle;
|
||||||
use crate::ir_vm;
|
use crate::ir_lang;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
use crate::common::files::FileManager;
|
use crate::common::files::FileManager;
|
||||||
@ -13,5 +13,5 @@ pub trait Frontend {
|
|||||||
&self,
|
&self,
|
||||||
entry: &Path,
|
entry: &Path,
|
||||||
file_manager: &mut FileManager,
|
file_manager: &mut FileManager,
|
||||||
) -> Result<ir_vm::Module, DiagnosticBundle>;
|
) -> Result<ir_lang::Module, DiagnosticBundle>;
|
||||||
}
|
}
|
||||||
@ -2,8 +2,8 @@ use crate::frontends::pbs::{parser::Parser, SymbolCollector, ModuleSymbols, Reso
|
|||||||
use crate::frontends::pbs::typecheck::TypeChecker;
|
use crate::frontends::pbs::typecheck::TypeChecker;
|
||||||
use crate::lowering::core_to_vm;
|
use crate::lowering::core_to_vm;
|
||||||
use crate::common::spans::FileId;
|
use crate::common::spans::FileId;
|
||||||
use frontend_api::traits::{Frontend as CanonFrontend, FrontendUnit};
|
use language_api::traits::{Frontend as CanonFrontend, FrontendUnit};
|
||||||
use frontend_api::types::{
|
use language_api::types::{
|
||||||
Diagnostic as CanonDiagnostic,
|
Diagnostic as CanonDiagnostic,
|
||||||
Severity as CanonSeverity,
|
Severity as CanonSeverity,
|
||||||
ExportItem,
|
ExportItem,
|
||||||
@ -103,9 +103,6 @@ impl<'a> SymbolCollector<'a> {
|
|||||||
};
|
};
|
||||||
self.insert_type_symbol(symbol);
|
self.insert_type_symbol(symbol);
|
||||||
|
|
||||||
// Herança de visibilidade: métodos do service herdam a visibilidade do service
|
|
||||||
let service_name = self.interner.resolve(decl.name).to_string();
|
|
||||||
|
|
||||||
for member in &decl.members {
|
for member in &decl.members {
|
||||||
match arena.kind(*member) {
|
match arena.kind(*member) {
|
||||||
NodeKind::ServiceFnDecl(method) => {
|
NodeKind::ServiceFnDecl(method) => {
|
||||||
@ -25,7 +25,7 @@ pub use frontend::build_typed_module_symbols;
|
|||||||
use crate::common::diagnostics::DiagnosticBundle;
|
use crate::common::diagnostics::DiagnosticBundle;
|
||||||
use crate::common::files::FileManager;
|
use crate::common::files::FileManager;
|
||||||
use crate::frontends::Frontend;
|
use crate::frontends::Frontend;
|
||||||
use crate::ir_vm;
|
use crate::ir_lang;
|
||||||
use crate::lowering::core_to_vm;
|
use crate::lowering::core_to_vm;
|
||||||
use prometeu_analysis::NameInterner;
|
use prometeu_analysis::NameInterner;
|
||||||
use crate::common::spans::FileId;
|
use crate::common::spans::FileId;
|
||||||
@ -42,7 +42,7 @@ impl Frontend for PbsFrontend {
|
|||||||
&self,
|
&self,
|
||||||
entry: &Path,
|
entry: &Path,
|
||||||
file_manager: &mut FileManager,
|
file_manager: &mut FileManager,
|
||||||
) -> Result<ir_vm::Module, DiagnosticBundle> {
|
) -> Result<ir_lang::Module, DiagnosticBundle> {
|
||||||
let source = std::fs::read_to_string(entry).map_err(|e| {
|
let source = std::fs::read_to_string(entry).map_err(|e| {
|
||||||
crate::common::diagnostics::DiagnosticBundle::error(
|
crate::common::diagnostics::DiagnosticBundle::error(
|
||||||
"E_FRONTEND_IO",
|
"E_FRONTEND_IO",
|
||||||
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
use crate::common::spans::Span;
|
use crate::common::spans::Span;
|
||||||
use crate::ir_core::ids::{FunctionId, SigId};
|
use crate::ir_core::ids::{FunctionId, SigId};
|
||||||
use crate::ir_vm::types::{ConstId, TypeId};
|
use crate::ir_lang::types::{ConstId, TypeId};
|
||||||
|
|
||||||
/// An `Instruction` combines an instruction's behavior (`kind`) with its
|
/// An `Instruction` combines an instruction's behavior (`kind`) with its
|
||||||
/// source code location (`span`) for debugging and error reporting.
|
/// source code location (`span`) for debugging and error reporting.
|
||||||
@ -193,7 +193,7 @@ pub const RC_SENSITIVE_OPS: &[&str] = &[
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::ir_vm::types::{ConstId, TypeId};
|
use crate::ir_lang::types::{ConstId, TypeId};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_instr_kind_is_cloneable() {
|
fn test_instr_kind_is_cloneable() {
|
||||||
@ -389,7 +389,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_no_ref_leakage_in_instr_names() {
|
fn test_no_ref_leakage_in_instr_names() {
|
||||||
// Enforce the rule that "Ref" must never refer to HIP memory in ir_vm.
|
// Enforce the rule that "Ref" must never refer to HIP memory in ir_lang.
|
||||||
// The snapshot test above already locks the names, but this test
|
// The snapshot test above already locks the names, but this test
|
||||||
// explicitly asserts the absence of the "Ref" substring in HIP-related instructions.
|
// explicitly asserts the absence of the "Ref" substring in HIP-related instructions.
|
||||||
let instructions = [
|
let instructions = [
|
||||||
@ -1,4 +1,4 @@
|
|||||||
//! # VM Intermediate Representation (ir_vm)
|
//! # VM Intermediate Representation (ir_lang)
|
||||||
//!
|
//!
|
||||||
//! This module defines the Intermediate Representation for the Prometeu VM.
|
//! This module defines the Intermediate Representation for the Prometeu VM.
|
||||||
//!
|
//!
|
||||||
@ -6,7 +6,7 @@
|
|||||||
//!
|
//!
|
||||||
//! * Heap is never directly addressable.
|
//! * Heap is never directly addressable.
|
||||||
//! * All HIP (Heap) access is mediated via Gate Pool resolution.
|
//! * All HIP (Heap) access is mediated via Gate Pool resolution.
|
||||||
//! * `Gate(GateId)` is the only HIP pointer form in `ir_vm`.
|
//! * `Gate(GateId)` is the only HIP pointer form in `ir_lang`.
|
||||||
//!
|
//!
|
||||||
//! ## Reference Counting (RC)
|
//! ## Reference Counting (RC)
|
||||||
//!
|
//!
|
||||||
@ -58,7 +58,7 @@ mod tests {
|
|||||||
params: vec![],
|
params: vec![],
|
||||||
return_type: Type::Null,
|
return_type: Type::Null,
|
||||||
body: vec![
|
body: vec![
|
||||||
Instruction::new(InstrKind::PushConst(crate::ir_vm::types::ConstId(0)), None),
|
Instruction::new(InstrKind::PushConst(types::ConstId(0)), None),
|
||||||
Instruction::new(InstrKind::Call { func_id: FunctionId(2), arg_count: 1 }, None),
|
Instruction::new(InstrKind::Call { func_id: FunctionId(2), arg_count: 1 }, None),
|
||||||
Instruction::new(InstrKind::Ret, None),
|
Instruction::new(InstrKind::Ret, None),
|
||||||
],
|
],
|
||||||
@ -6,8 +6,8 @@
|
|||||||
|
|
||||||
use crate::ir_core::const_pool::ConstPool;
|
use crate::ir_core::const_pool::ConstPool;
|
||||||
use crate::ir_core::ids::{FunctionId, SigId};
|
use crate::ir_core::ids::{FunctionId, SigId};
|
||||||
use crate::ir_vm::instr::Instruction;
|
use crate::ir_lang::instr::Instruction;
|
||||||
use crate::ir_vm::types::Type;
|
use crate::ir_lang::types::Type;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
/// A `Module` is the top-level container for a compiled program or library.
|
/// A `Module` is the top-level container for a compiled program or library.
|
||||||
@ -1,5 +1,5 @@
|
|||||||
use crate::common::diagnostics::DiagnosticBundle;
|
use crate::common::diagnostics::DiagnosticBundle;
|
||||||
use crate::ir_vm::module::Module;
|
use crate::ir_lang::module::Module;
|
||||||
|
|
||||||
pub fn validate_module(_module: &Module) -> Result<(), DiagnosticBundle> {
|
pub fn validate_module(_module: &Module) -> Result<(), DiagnosticBundle> {
|
||||||
// TODO: Implement common IR validations:
|
// TODO: Implement common IR validations:
|
||||||
@ -38,7 +38,7 @@
|
|||||||
//! See the [`compiler`] module for the main entry point to trigger a compilation programmatically.
|
//! See the [`compiler`] module for the main entry point to trigger a compilation programmatically.
|
||||||
|
|
||||||
pub mod common;
|
pub mod common;
|
||||||
pub mod ir_vm;
|
pub mod ir_lang;
|
||||||
pub mod ir_core;
|
pub mod ir_core;
|
||||||
pub mod lowering;
|
pub mod lowering;
|
||||||
pub mod backend;
|
pub mod backend;
|
||||||
@ -128,7 +128,7 @@ pub fn run() -> Result<()> {
|
|||||||
explain_deps,
|
explain_deps,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
let build_dir = project_dir.join("build");
|
let build_dir = project_dir.join("../../../../build");
|
||||||
let out = out.unwrap_or_else(|| build_dir.join("program.pbc"));
|
let out = out.unwrap_or_else(|| build_dir.join("program.pbc"));
|
||||||
|
|
||||||
let emit_symbols = emit_symbols && !no_symbols;
|
let emit_symbols = emit_symbols && !no_symbols;
|
||||||
@ -1,10 +1,10 @@
|
|||||||
use crate::ir_core;
|
use crate::ir_core;
|
||||||
use crate::ir_vm;
|
use crate::ir_lang;
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
/// Lowers a Core IR program into a VM IR module.
|
/// Lowers a Core IR program into a VM IR module.
|
||||||
pub fn lower_program(program: &ir_core::Program) -> Result<ir_vm::Module> {
|
pub fn lower_program(program: &ir_core::Program) -> Result<ir_lang::Module> {
|
||||||
// Build a map of function return types for type tracking
|
// Build a map of function return types for type tracking
|
||||||
let mut function_returns = HashMap::new();
|
let mut function_returns = HashMap::new();
|
||||||
for module in &program.modules {
|
for module in &program.modules {
|
||||||
@ -26,8 +26,8 @@ pub fn lower_module(
|
|||||||
core_module: &ir_core::Module,
|
core_module: &ir_core::Module,
|
||||||
program: &ir_core::Program,
|
program: &ir_core::Program,
|
||||||
function_returns: &HashMap<ir_core::ids::FunctionId, ir_core::Type>,
|
function_returns: &HashMap<ir_core::ids::FunctionId, ir_core::Type>,
|
||||||
) -> Result<ir_vm::Module> {
|
) -> Result<ir_lang::Module> {
|
||||||
let mut vm_module = ir_vm::Module::new(core_module.name.clone());
|
let mut vm_module = ir_lang::Module::new(core_module.name.clone());
|
||||||
vm_module.const_pool = program.const_pool.clone();
|
vm_module.const_pool = program.const_pool.clone();
|
||||||
|
|
||||||
for core_func in &core_module.functions {
|
for core_func in &core_module.functions {
|
||||||
@ -51,12 +51,12 @@ pub fn lower_function(
|
|||||||
program: &ir_core::Program,
|
program: &ir_core::Program,
|
||||||
function_returns: &HashMap<ir_core::ids::FunctionId, ir_core::Type>,
|
function_returns: &HashMap<ir_core::ids::FunctionId, ir_core::Type>,
|
||||||
is_entry_point: bool,
|
is_entry_point: bool,
|
||||||
) -> Result<ir_vm::Function> {
|
) -> Result<ir_lang::Function> {
|
||||||
let mut vm_func = ir_vm::Function {
|
let mut vm_func = ir_lang::Function {
|
||||||
id: core_func.id,
|
id: core_func.id,
|
||||||
name: core_func.name.clone(),
|
name: core_func.name.clone(),
|
||||||
sig: core_func.sig,
|
sig: core_func.sig,
|
||||||
params: core_func.params.iter().map(|p| ir_vm::Param {
|
params: core_func.params.iter().map(|p| ir_lang::Param {
|
||||||
name: p.name.clone(),
|
name: p.name.clone(),
|
||||||
r#type: lower_type(&p.ty),
|
r#type: lower_type(&p.ty),
|
||||||
}).collect(),
|
}).collect(),
|
||||||
@ -80,8 +80,8 @@ pub fn lower_function(
|
|||||||
|
|
||||||
for block in &core_func.blocks {
|
for block in &core_func.blocks {
|
||||||
// Core blocks map to labels in the flat VM IR instruction list.
|
// Core blocks map to labels in the flat VM IR instruction list.
|
||||||
vm_func.body.push(ir_vm::Instruction::new(
|
vm_func.body.push(ir_lang::Instruction::new(
|
||||||
ir_vm::InstrKind::Label(ir_vm::Label(format!("block_{}", block.id))),
|
ir_lang::InstrKind::Label(ir_lang::Label(format!("block_{}", block.id))),
|
||||||
None,
|
None,
|
||||||
));
|
));
|
||||||
|
|
||||||
@ -104,11 +104,11 @@ pub fn lower_function(
|
|||||||
ir_core::Type::Void
|
ir_core::Type::Void
|
||||||
};
|
};
|
||||||
stack_types.push(ty);
|
stack_types.push(ty);
|
||||||
vm_func.body.push(ir_vm::Instruction::new(ir_vm::InstrKind::PushConst(ir_vm::ConstId(id.0)), span.clone()));
|
vm_func.body.push(ir_lang::Instruction::new(ir_lang::InstrKind::PushConst(ir_lang::ConstId(id.0)), span.clone()));
|
||||||
}
|
}
|
||||||
ir_core::InstrKind::PushBounded(val) => {
|
ir_core::InstrKind::PushBounded(val) => {
|
||||||
stack_types.push(ir_core::Type::Bounded);
|
stack_types.push(ir_core::Type::Bounded);
|
||||||
vm_func.body.push(ir_vm::Instruction::new(ir_vm::InstrKind::PushBounded(*val), span.clone()));
|
vm_func.body.push(ir_lang::Instruction::new(ir_lang::InstrKind::PushBounded(*val), span.clone()));
|
||||||
}
|
}
|
||||||
ir_core::InstrKind::Call(func_id, arg_count) => {
|
ir_core::InstrKind::Call(func_id, arg_count) => {
|
||||||
// Pop arguments from type stack
|
// Pop arguments from type stack
|
||||||
@ -119,7 +119,7 @@ pub fn lower_function(
|
|||||||
let ret_ty = function_returns.get(func_id).cloned().unwrap_or(ir_core::Type::Void);
|
let ret_ty = function_returns.get(func_id).cloned().unwrap_or(ir_core::Type::Void);
|
||||||
stack_types.push(ret_ty);
|
stack_types.push(ret_ty);
|
||||||
|
|
||||||
vm_func.body.push(ir_vm::Instruction::new(ir_vm::InstrKind::Call {
|
vm_func.body.push(ir_lang::Instruction::new(ir_lang::InstrKind::Call {
|
||||||
func_id: *func_id,
|
func_id: *func_id,
|
||||||
arg_count: *arg_count
|
arg_count: *arg_count
|
||||||
}, None));
|
}, None));
|
||||||
@ -130,7 +130,7 @@ pub fn lower_function(
|
|||||||
stack_types.pop();
|
stack_types.pop();
|
||||||
}
|
}
|
||||||
// Do not assume a return type here; VM semantics should be verified elsewhere.
|
// Do not assume a return type here; VM semantics should be verified elsewhere.
|
||||||
vm_func.body.push(ir_vm::Instruction::new(ir_vm::InstrKind::ImportCall {
|
vm_func.body.push(ir_lang::Instruction::new(ir_lang::InstrKind::ImportCall {
|
||||||
dep_alias: dep_alias.clone(),
|
dep_alias: dep_alias.clone(),
|
||||||
module_path: module_path.clone(),
|
module_path: module_path.clone(),
|
||||||
owner: owner.clone(),
|
owner: owner.clone(),
|
||||||
@ -145,13 +145,13 @@ pub fn lower_function(
|
|||||||
for _ in 0..*slots {
|
for _ in 0..*slots {
|
||||||
stack_types.push(ir_core::Type::Int);
|
stack_types.push(ir_core::Type::Int);
|
||||||
}
|
}
|
||||||
vm_func.body.push(ir_vm::Instruction::new(ir_vm::InstrKind::Syscall(*id), span.clone()));
|
vm_func.body.push(ir_lang::Instruction::new(ir_lang::InstrKind::Syscall(*id), span.clone()));
|
||||||
}
|
}
|
||||||
ir_core::InstrKind::GetLocal(slot) => {
|
ir_core::InstrKind::GetLocal(slot) => {
|
||||||
let ty = local_types.get(slot).cloned().unwrap_or(ir_core::Type::Void);
|
let ty = local_types.get(slot).cloned().unwrap_or(ir_core::Type::Void);
|
||||||
stack_types.push(ty.clone());
|
stack_types.push(ty.clone());
|
||||||
|
|
||||||
vm_func.body.push(ir_vm::Instruction::new(ir_vm::InstrKind::LocalLoad { slot: *slot }, span.clone()));
|
vm_func.body.push(ir_lang::Instruction::new(ir_lang::InstrKind::LocalLoad { slot: *slot }, span.clone()));
|
||||||
|
|
||||||
// If it's a gate, we should retain it if we just pushed it onto stack?
|
// If it's a gate, we should retain it if we just pushed it onto stack?
|
||||||
// "on assigning a gate to a local/global"
|
// "on assigning a gate to a local/global"
|
||||||
@ -160,7 +160,7 @@ pub fn lower_function(
|
|||||||
|
|
||||||
// Wait, if I Load it, I have a new handle on the stack. I should Retain it.
|
// Wait, if I Load it, I have a new handle on the stack. I should Retain it.
|
||||||
if is_gate_type(&ty) {
|
if is_gate_type(&ty) {
|
||||||
vm_func.body.push(ir_vm::Instruction::new(ir_vm::InstrKind::GateRetain, span.clone()));
|
vm_func.body.push(ir_lang::Instruction::new(ir_lang::InstrKind::GateRetain, span.clone()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ir_core::InstrKind::SetLocal(slot) => {
|
ir_core::InstrKind::SetLocal(slot) => {
|
||||||
@ -170,8 +170,8 @@ pub fn lower_function(
|
|||||||
// 1. Release old value if it was a gate
|
// 1. Release old value if it was a gate
|
||||||
if let Some(old_ty) = old_ty {
|
if let Some(old_ty) = old_ty {
|
||||||
if is_gate_type(&old_ty) {
|
if is_gate_type(&old_ty) {
|
||||||
vm_func.body.push(ir_vm::Instruction::new(ir_vm::InstrKind::LocalLoad { slot: *slot }, span.clone()));
|
vm_func.body.push(ir_lang::Instruction::new(ir_lang::InstrKind::LocalLoad { slot: *slot }, span.clone()));
|
||||||
vm_func.body.push(ir_vm::Instruction::new(ir_vm::InstrKind::GateRelease, span.clone()));
|
vm_func.body.push(ir_lang::Instruction::new(ir_lang::InstrKind::GateRelease, span.clone()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,22 +184,22 @@ pub fn lower_function(
|
|||||||
// Actually, if we Pop it later, we Release it.
|
// Actually, if we Pop it later, we Release it.
|
||||||
|
|
||||||
local_types.insert(*slot, new_ty);
|
local_types.insert(*slot, new_ty);
|
||||||
vm_func.body.push(ir_vm::Instruction::new(ir_vm::InstrKind::LocalStore { slot: *slot }, span.clone()));
|
vm_func.body.push(ir_lang::Instruction::new(ir_lang::InstrKind::LocalStore { slot: *slot }, span.clone()));
|
||||||
}
|
}
|
||||||
ir_core::InstrKind::Pop => {
|
ir_core::InstrKind::Pop => {
|
||||||
let ty = stack_types.pop().unwrap_or(ir_core::Type::Void);
|
let ty = stack_types.pop().unwrap_or(ir_core::Type::Void);
|
||||||
if is_gate_type(&ty) {
|
if is_gate_type(&ty) {
|
||||||
vm_func.body.push(ir_vm::Instruction::new(ir_vm::InstrKind::GateRelease, span.clone()));
|
vm_func.body.push(ir_lang::Instruction::new(ir_lang::InstrKind::GateRelease, span.clone()));
|
||||||
} else {
|
} else {
|
||||||
vm_func.body.push(ir_vm::Instruction::new(ir_vm::InstrKind::Pop, span.clone()));
|
vm_func.body.push(ir_lang::Instruction::new(ir_lang::InstrKind::Pop, span.clone()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ir_core::InstrKind::Dup => {
|
ir_core::InstrKind::Dup => {
|
||||||
let ty = stack_types.last().cloned().unwrap_or(ir_core::Type::Void);
|
let ty = stack_types.last().cloned().unwrap_or(ir_core::Type::Void);
|
||||||
stack_types.push(ty.clone());
|
stack_types.push(ty.clone());
|
||||||
vm_func.body.push(ir_vm::Instruction::new(ir_vm::InstrKind::Dup, span.clone()));
|
vm_func.body.push(ir_lang::Instruction::new(ir_lang::InstrKind::Dup, span.clone()));
|
||||||
if is_gate_type(&ty) {
|
if is_gate_type(&ty) {
|
||||||
vm_func.body.push(ir_vm::Instruction::new(ir_vm::InstrKind::GateRetain, span.clone()));
|
vm_func.body.push(ir_lang::Instruction::new(ir_lang::InstrKind::GateRetain, span.clone()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ir_core::InstrKind::Add | ir_core::InstrKind::Sub | ir_core::InstrKind::Mul | ir_core::InstrKind::Div => {
|
ir_core::InstrKind::Add | ir_core::InstrKind::Sub | ir_core::InstrKind::Mul | ir_core::InstrKind::Div => {
|
||||||
@ -207,81 +207,81 @@ pub fn lower_function(
|
|||||||
stack_types.pop();
|
stack_types.pop();
|
||||||
stack_types.push(ir_core::Type::Int); // Assume Int for arithmetic
|
stack_types.push(ir_core::Type::Int); // Assume Int for arithmetic
|
||||||
let kind = match &instr.kind {
|
let kind = match &instr.kind {
|
||||||
ir_core::InstrKind::Add => ir_vm::InstrKind::Add,
|
ir_core::InstrKind::Add => ir_lang::InstrKind::Add,
|
||||||
ir_core::InstrKind::Sub => ir_vm::InstrKind::Sub,
|
ir_core::InstrKind::Sub => ir_lang::InstrKind::Sub,
|
||||||
ir_core::InstrKind::Mul => ir_vm::InstrKind::Mul,
|
ir_core::InstrKind::Mul => ir_lang::InstrKind::Mul,
|
||||||
ir_core::InstrKind::Div => ir_vm::InstrKind::Div,
|
ir_core::InstrKind::Div => ir_lang::InstrKind::Div,
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
vm_func.body.push(ir_vm::Instruction::new(kind, span.clone()));
|
vm_func.body.push(ir_lang::Instruction::new(kind, span.clone()));
|
||||||
}
|
}
|
||||||
ir_core::InstrKind::Neg => {
|
ir_core::InstrKind::Neg => {
|
||||||
vm_func.body.push(ir_vm::Instruction::new(ir_vm::InstrKind::Neg, span.clone()));
|
vm_func.body.push(ir_lang::Instruction::new(ir_lang::InstrKind::Neg, span.clone()));
|
||||||
}
|
}
|
||||||
ir_core::InstrKind::Eq | ir_core::InstrKind::Neq | ir_core::InstrKind::Lt | ir_core::InstrKind::Lte | ir_core::InstrKind::Gt | ir_core::InstrKind::Gte => {
|
ir_core::InstrKind::Eq | ir_core::InstrKind::Neq | ir_core::InstrKind::Lt | ir_core::InstrKind::Lte | ir_core::InstrKind::Gt | ir_core::InstrKind::Gte => {
|
||||||
stack_types.pop();
|
stack_types.pop();
|
||||||
stack_types.pop();
|
stack_types.pop();
|
||||||
stack_types.push(ir_core::Type::Bool);
|
stack_types.push(ir_core::Type::Bool);
|
||||||
let kind = match &instr.kind {
|
let kind = match &instr.kind {
|
||||||
ir_core::InstrKind::Eq => ir_vm::InstrKind::Eq,
|
ir_core::InstrKind::Eq => ir_lang::InstrKind::Eq,
|
||||||
ir_core::InstrKind::Neq => ir_vm::InstrKind::Neq,
|
ir_core::InstrKind::Neq => ir_lang::InstrKind::Neq,
|
||||||
ir_core::InstrKind::Lt => ir_vm::InstrKind::Lt,
|
ir_core::InstrKind::Lt => ir_lang::InstrKind::Lt,
|
||||||
ir_core::InstrKind::Lte => ir_vm::InstrKind::Lte,
|
ir_core::InstrKind::Lte => ir_lang::InstrKind::Lte,
|
||||||
ir_core::InstrKind::Gt => ir_vm::InstrKind::Gt,
|
ir_core::InstrKind::Gt => ir_lang::InstrKind::Gt,
|
||||||
ir_core::InstrKind::Gte => ir_vm::InstrKind::Gte,
|
ir_core::InstrKind::Gte => ir_lang::InstrKind::Gte,
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
vm_func.body.push(ir_vm::Instruction::new(kind, span.clone()));
|
vm_func.body.push(ir_lang::Instruction::new(kind, span.clone()));
|
||||||
}
|
}
|
||||||
ir_core::InstrKind::And | ir_core::InstrKind::Or => {
|
ir_core::InstrKind::And | ir_core::InstrKind::Or => {
|
||||||
stack_types.pop();
|
stack_types.pop();
|
||||||
stack_types.pop();
|
stack_types.pop();
|
||||||
stack_types.push(ir_core::Type::Bool);
|
stack_types.push(ir_core::Type::Bool);
|
||||||
let kind = match &instr.kind {
|
let kind = match &instr.kind {
|
||||||
ir_core::InstrKind::And => ir_vm::InstrKind::And,
|
ir_core::InstrKind::And => ir_lang::InstrKind::And,
|
||||||
ir_core::InstrKind::Or => ir_vm::InstrKind::Or,
|
ir_core::InstrKind::Or => ir_lang::InstrKind::Or,
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
vm_func.body.push(ir_vm::Instruction::new(kind, span.clone()));
|
vm_func.body.push(ir_lang::Instruction::new(kind, span.clone()));
|
||||||
}
|
}
|
||||||
ir_core::InstrKind::Not => {
|
ir_core::InstrKind::Not => {
|
||||||
stack_types.pop();
|
stack_types.pop();
|
||||||
stack_types.push(ir_core::Type::Bool);
|
stack_types.push(ir_core::Type::Bool);
|
||||||
vm_func.body.push(ir_vm::Instruction::new(ir_vm::InstrKind::Not, span.clone()));
|
vm_func.body.push(ir_lang::Instruction::new(ir_lang::InstrKind::Not, span.clone()));
|
||||||
}
|
}
|
||||||
ir_core::InstrKind::Alloc { ty, slots } => {
|
ir_core::InstrKind::Alloc { ty, slots } => {
|
||||||
stack_types.push(ir_core::Type::Contract(format!("Gate<{}>", ty.0)));
|
stack_types.push(ir_core::Type::Contract(format!("Gate<{}>", ty.0)));
|
||||||
vm_func.body.push(ir_vm::Instruction::new(ir_vm::InstrKind::Alloc {
|
vm_func.body.push(ir_lang::Instruction::new(ir_lang::InstrKind::Alloc {
|
||||||
type_id: ir_vm::TypeId(ty.0),
|
type_id: ir_lang::TypeId(ty.0),
|
||||||
slots: *slots
|
slots: *slots
|
||||||
}, None));
|
}, None));
|
||||||
}
|
}
|
||||||
ir_core::InstrKind::BeginPeek { gate } => {
|
ir_core::InstrKind::BeginPeek { gate } => {
|
||||||
vm_func.body.push(ir_vm::Instruction::new(ir_vm::InstrKind::LocalLoad { slot: gate.0 }, span.clone()));
|
vm_func.body.push(ir_lang::Instruction::new(ir_lang::InstrKind::LocalLoad { slot: gate.0 }, span.clone()));
|
||||||
vm_func.body.push(ir_vm::Instruction::new(ir_vm::InstrKind::GateRetain, span.clone()));
|
vm_func.body.push(ir_lang::Instruction::new(ir_lang::InstrKind::GateRetain, span.clone()));
|
||||||
vm_func.body.push(ir_vm::Instruction::new(ir_vm::InstrKind::GateBeginPeek, span.clone()));
|
vm_func.body.push(ir_lang::Instruction::new(ir_lang::InstrKind::GateBeginPeek, span.clone()));
|
||||||
}
|
}
|
||||||
ir_core::InstrKind::BeginBorrow { gate } => {
|
ir_core::InstrKind::BeginBorrow { gate } => {
|
||||||
vm_func.body.push(ir_vm::Instruction::new(ir_vm::InstrKind::LocalLoad { slot: gate.0 }, span.clone()));
|
vm_func.body.push(ir_lang::Instruction::new(ir_lang::InstrKind::LocalLoad { slot: gate.0 }, span.clone()));
|
||||||
vm_func.body.push(ir_vm::Instruction::new(ir_vm::InstrKind::GateRetain, span.clone()));
|
vm_func.body.push(ir_lang::Instruction::new(ir_lang::InstrKind::GateRetain, span.clone()));
|
||||||
vm_func.body.push(ir_vm::Instruction::new(ir_vm::InstrKind::GateBeginBorrow, span.clone()));
|
vm_func.body.push(ir_lang::Instruction::new(ir_lang::InstrKind::GateBeginBorrow, span.clone()));
|
||||||
}
|
}
|
||||||
ir_core::InstrKind::BeginMutate { gate } => {
|
ir_core::InstrKind::BeginMutate { gate } => {
|
||||||
vm_func.body.push(ir_vm::Instruction::new(ir_vm::InstrKind::LocalLoad { slot: gate.0 }, span.clone()));
|
vm_func.body.push(ir_lang::Instruction::new(ir_lang::InstrKind::LocalLoad { slot: gate.0 }, span.clone()));
|
||||||
vm_func.body.push(ir_vm::Instruction::new(ir_vm::InstrKind::GateRetain, span.clone()));
|
vm_func.body.push(ir_lang::Instruction::new(ir_lang::InstrKind::GateRetain, span.clone()));
|
||||||
vm_func.body.push(ir_vm::Instruction::new(ir_vm::InstrKind::GateBeginMutate, span.clone()));
|
vm_func.body.push(ir_lang::Instruction::new(ir_lang::InstrKind::GateBeginMutate, span.clone()));
|
||||||
}
|
}
|
||||||
ir_core::InstrKind::EndPeek => {
|
ir_core::InstrKind::EndPeek => {
|
||||||
vm_func.body.push(ir_vm::Instruction::new(ir_vm::InstrKind::GateEndPeek, span.clone()));
|
vm_func.body.push(ir_lang::Instruction::new(ir_lang::InstrKind::GateEndPeek, span.clone()));
|
||||||
vm_func.body.push(ir_vm::Instruction::new(ir_vm::InstrKind::GateRelease, span.clone()));
|
vm_func.body.push(ir_lang::Instruction::new(ir_lang::InstrKind::GateRelease, span.clone()));
|
||||||
}
|
}
|
||||||
ir_core::InstrKind::EndBorrow => {
|
ir_core::InstrKind::EndBorrow => {
|
||||||
vm_func.body.push(ir_vm::Instruction::new(ir_vm::InstrKind::GateEndBorrow, span.clone()));
|
vm_func.body.push(ir_lang::Instruction::new(ir_lang::InstrKind::GateEndBorrow, span.clone()));
|
||||||
vm_func.body.push(ir_vm::Instruction::new(ir_vm::InstrKind::GateRelease, span.clone()));
|
vm_func.body.push(ir_lang::Instruction::new(ir_lang::InstrKind::GateRelease, span.clone()));
|
||||||
}
|
}
|
||||||
ir_core::InstrKind::EndMutate => {
|
ir_core::InstrKind::EndMutate => {
|
||||||
vm_func.body.push(ir_vm::Instruction::new(ir_vm::InstrKind::GateEndMutate, span.clone()));
|
vm_func.body.push(ir_lang::Instruction::new(ir_lang::InstrKind::GateEndMutate, span.clone()));
|
||||||
vm_func.body.push(ir_vm::Instruction::new(ir_vm::InstrKind::GateRelease, span.clone()));
|
vm_func.body.push(ir_lang::Instruction::new(ir_lang::InstrKind::GateRelease, span.clone()));
|
||||||
}
|
}
|
||||||
ir_core::InstrKind::GateLoadField { gate, field } => {
|
ir_core::InstrKind::GateLoadField { gate, field } => {
|
||||||
let offset = program.field_offsets.get(field)
|
let offset = program.field_offsets.get(field)
|
||||||
@ -290,12 +290,12 @@ pub fn lower_function(
|
|||||||
let field_ty = program.field_types.get(field).cloned().unwrap_or(ir_core::Type::Int);
|
let field_ty = program.field_types.get(field).cloned().unwrap_or(ir_core::Type::Int);
|
||||||
stack_types.push(field_ty.clone());
|
stack_types.push(field_ty.clone());
|
||||||
|
|
||||||
vm_func.body.push(ir_vm::Instruction::new(ir_vm::InstrKind::LocalLoad { slot: gate.0 }, span.clone()));
|
vm_func.body.push(ir_lang::Instruction::new(ir_lang::InstrKind::LocalLoad { slot: gate.0 }, span.clone()));
|
||||||
vm_func.body.push(ir_vm::Instruction::new(ir_vm::InstrKind::GateRetain, span.clone()));
|
vm_func.body.push(ir_lang::Instruction::new(ir_lang::InstrKind::GateRetain, span.clone()));
|
||||||
vm_func.body.push(ir_vm::Instruction::new(ir_vm::InstrKind::GateLoad { offset: *offset }, span.clone()));
|
vm_func.body.push(ir_lang::Instruction::new(ir_lang::InstrKind::GateLoad { offset: *offset }, span.clone()));
|
||||||
|
|
||||||
if is_gate_type(&field_ty) {
|
if is_gate_type(&field_ty) {
|
||||||
vm_func.body.push(ir_vm::Instruction::new(ir_vm::InstrKind::GateRetain, span.clone()));
|
vm_func.body.push(ir_lang::Instruction::new(ir_lang::InstrKind::GateRetain, span.clone()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ir_core::InstrKind::GateStoreField { gate, field, value } => {
|
ir_core::InstrKind::GateStoreField { gate, field, value } => {
|
||||||
@ -306,24 +306,24 @@ pub fn lower_function(
|
|||||||
|
|
||||||
// 1. Release old value in HIP if it was a gate
|
// 1. Release old value in HIP if it was a gate
|
||||||
if is_gate_type(&field_ty) {
|
if is_gate_type(&field_ty) {
|
||||||
vm_func.body.push(ir_vm::Instruction::new(ir_vm::InstrKind::LocalLoad { slot: gate.0 }, span.clone()));
|
vm_func.body.push(ir_lang::Instruction::new(ir_lang::InstrKind::LocalLoad { slot: gate.0 }, span.clone()));
|
||||||
vm_func.body.push(ir_vm::Instruction::new(ir_vm::InstrKind::GateRetain, span.clone()));
|
vm_func.body.push(ir_lang::Instruction::new(ir_lang::InstrKind::GateRetain, span.clone()));
|
||||||
vm_func.body.push(ir_vm::Instruction::new(ir_vm::InstrKind::GateLoad { offset: *offset }, span.clone()));
|
vm_func.body.push(ir_lang::Instruction::new(ir_lang::InstrKind::GateLoad { offset: *offset }, span.clone()));
|
||||||
vm_func.body.push(ir_vm::Instruction::new(ir_vm::InstrKind::GateRelease, span.clone()));
|
vm_func.body.push(ir_lang::Instruction::new(ir_lang::InstrKind::GateRelease, span.clone()));
|
||||||
}
|
}
|
||||||
|
|
||||||
vm_func.body.push(ir_vm::Instruction::new(ir_vm::InstrKind::LocalLoad { slot: gate.0 }, span.clone()));
|
vm_func.body.push(ir_lang::Instruction::new(ir_lang::InstrKind::LocalLoad { slot: gate.0 }, span.clone()));
|
||||||
vm_func.body.push(ir_vm::Instruction::new(ir_vm::InstrKind::GateRetain, span.clone()));
|
vm_func.body.push(ir_lang::Instruction::new(ir_lang::InstrKind::GateRetain, span.clone()));
|
||||||
vm_func.body.push(ir_vm::Instruction::new(ir_vm::InstrKind::LocalLoad { slot: value.0 }, span.clone()));
|
vm_func.body.push(ir_lang::Instruction::new(ir_lang::InstrKind::LocalLoad { slot: value.0 }, span.clone()));
|
||||||
|
|
||||||
// 2. Retain new value if it's a gate
|
// 2. Retain new value if it's a gate
|
||||||
if let Some(val_ty) = local_types.get(&value.0) {
|
if let Some(val_ty) = local_types.get(&value.0) {
|
||||||
if is_gate_type(val_ty) {
|
if is_gate_type(val_ty) {
|
||||||
vm_func.body.push(ir_vm::Instruction::new(ir_vm::InstrKind::GateRetain, span.clone()));
|
vm_func.body.push(ir_lang::Instruction::new(ir_lang::InstrKind::GateRetain, span.clone()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vm_func.body.push(ir_vm::Instruction::new(ir_vm::InstrKind::GateStore { offset: *offset }, span.clone()));
|
vm_func.body.push(ir_lang::Instruction::new(ir_lang::InstrKind::GateStore { offset: *offset }, span.clone()));
|
||||||
}
|
}
|
||||||
ir_core::InstrKind::GateLoadIndex { .. } => {
|
ir_core::InstrKind::GateLoadIndex { .. } => {
|
||||||
anyhow::bail!("E_LOWER_UNSUPPORTED: Dynamic HIP index access not supported in v0 lowering");
|
anyhow::bail!("E_LOWER_UNSUPPORTED: Dynamic HIP index access not supported in v0 lowering");
|
||||||
@ -331,7 +331,7 @@ pub fn lower_function(
|
|||||||
ir_core::InstrKind::GateStoreIndex { .. } => {
|
ir_core::InstrKind::GateStoreIndex { .. } => {
|
||||||
anyhow::bail!("E_LOWER_UNSUPPORTED: Dynamic HIP index access not supported in v0 lowering");
|
anyhow::bail!("E_LOWER_UNSUPPORTED: Dynamic HIP index access not supported in v0 lowering");
|
||||||
}
|
}
|
||||||
ir_core::InstrKind::Free => anyhow::bail!("Instruction 'Free' cannot be represented in ir_vm v0"),
|
ir_core::InstrKind::Free => anyhow::bail!("Instruction 'Free' cannot be represented in ir_lang v0"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -344,35 +344,35 @@ pub fn lower_function(
|
|||||||
for slot in sorted_slots {
|
for slot in sorted_slots {
|
||||||
let ty = &local_types[slot];
|
let ty = &local_types[slot];
|
||||||
if is_gate_type(ty) {
|
if is_gate_type(ty) {
|
||||||
vm_func.body.push(ir_vm::Instruction::new(ir_vm::InstrKind::LocalLoad { slot: *slot }, None));
|
vm_func.body.push(ir_lang::Instruction::new(ir_lang::InstrKind::LocalLoad { slot: *slot }, None));
|
||||||
vm_func.body.push(ir_vm::Instruction::new(ir_vm::InstrKind::GateRelease, None));
|
vm_func.body.push(ir_lang::Instruction::new(ir_lang::InstrKind::GateRelease, None));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inject FRAME_SYNC immediately before RET only for the entry point.
|
// Inject FRAME_SYNC immediately before RET only for the entry point.
|
||||||
// This is a signal-only safe point; no GC opcodes should be emitted here.
|
// This is a signal-only safe point; no GC opcodes should be emitted here.
|
||||||
if is_entry_point {
|
if is_entry_point {
|
||||||
vm_func.body.push(ir_vm::Instruction::new(ir_vm::InstrKind::FrameSync, None));
|
vm_func.body.push(ir_lang::Instruction::new(ir_lang::InstrKind::FrameSync, None));
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the function is Void, we don't need to push anything.
|
// If the function is Void, we don't need to push anything.
|
||||||
// The VM's Ret opcode handles zero return slots correctly.
|
// The VM's Ret opcode handles zero return slots correctly.
|
||||||
vm_func.body.push(ir_vm::Instruction::new(ir_vm::InstrKind::Ret, None));
|
vm_func.body.push(ir_lang::Instruction::new(ir_lang::InstrKind::Ret, None));
|
||||||
}
|
}
|
||||||
ir_core::Terminator::Jump(target) => {
|
ir_core::Terminator::Jump(target) => {
|
||||||
vm_func.body.push(ir_vm::Instruction::new(
|
vm_func.body.push(ir_lang::Instruction::new(
|
||||||
ir_vm::InstrKind::Jmp(ir_vm::Label(format!("block_{}", target))),
|
ir_lang::InstrKind::Jmp(ir_lang::Label(format!("block_{}", target))),
|
||||||
None,
|
None,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
ir_core::Terminator::JumpIfFalse { target, else_target } => {
|
ir_core::Terminator::JumpIfFalse { target, else_target } => {
|
||||||
stack_types.pop();
|
stack_types.pop();
|
||||||
vm_func.body.push(ir_vm::Instruction::new(
|
vm_func.body.push(ir_lang::Instruction::new(
|
||||||
ir_vm::InstrKind::JmpIfFalse(ir_vm::Label(format!("block_{}", target))),
|
ir_lang::InstrKind::JmpIfFalse(ir_lang::Label(format!("block_{}", target))),
|
||||||
None,
|
None,
|
||||||
));
|
));
|
||||||
vm_func.body.push(ir_vm::Instruction::new(
|
vm_func.body.push(ir_lang::Instruction::new(
|
||||||
ir_vm::InstrKind::Jmp(ir_vm::Label(format!("block_{}", else_target))),
|
ir_lang::InstrKind::Jmp(ir_lang::Label(format!("block_{}", else_target))),
|
||||||
None,
|
None,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -392,22 +392,22 @@ fn is_gate_type(ty: &ir_core::Type) -> bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lower_type(ty: &ir_core::Type) -> ir_vm::Type {
|
fn lower_type(ty: &ir_core::Type) -> ir_lang::Type {
|
||||||
match ty {
|
match ty {
|
||||||
ir_core::Type::Void => ir_vm::Type::Void,
|
ir_core::Type::Void => ir_lang::Type::Void,
|
||||||
ir_core::Type::Int => ir_vm::Type::Int,
|
ir_core::Type::Int => ir_lang::Type::Int,
|
||||||
ir_core::Type::Float => ir_vm::Type::Float,
|
ir_core::Type::Float => ir_lang::Type::Float,
|
||||||
ir_core::Type::Bool => ir_vm::Type::Bool,
|
ir_core::Type::Bool => ir_lang::Type::Bool,
|
||||||
ir_core::Type::String => ir_vm::Type::String,
|
ir_core::Type::String => ir_lang::Type::String,
|
||||||
ir_core::Type::Bounded => ir_vm::Type::Bounded,
|
ir_core::Type::Bounded => ir_lang::Type::Bounded,
|
||||||
ir_core::Type::Optional(inner) => ir_vm::Type::Array(Box::new(lower_type(inner))),
|
ir_core::Type::Optional(inner) => ir_lang::Type::Array(Box::new(lower_type(inner))),
|
||||||
ir_core::Type::Result(ok, _) => lower_type(ok),
|
ir_core::Type::Result(ok, _) => lower_type(ok),
|
||||||
ir_core::Type::Struct(_)
|
ir_core::Type::Struct(_)
|
||||||
| ir_core::Type::Service(_)
|
| ir_core::Type::Service(_)
|
||||||
| ir_core::Type::Contract(_)
|
| ir_core::Type::Contract(_)
|
||||||
| ir_core::Type::ErrorType(_) => ir_vm::Type::Object,
|
| ir_core::Type::ErrorType(_) => ir_lang::Type::Object,
|
||||||
ir_core::Type::Function { .. } => ir_vm::Type::Function,
|
ir_core::Type::Function { .. } => ir_lang::Type::Function,
|
||||||
ir_core::Type::Array(inner, _) => ir_vm::Type::Array(Box::new(lower_type(inner))),
|
ir_core::Type::Array(inner, _) => ir_lang::Type::Array(Box::new(lower_type(inner))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -417,7 +417,7 @@ mod tests {
|
|||||||
use crate::ir_core;
|
use crate::ir_core;
|
||||||
use crate::ir_core::ids::{ConstId as CoreConstId, FunctionId};
|
use crate::ir_core::ids::{ConstId as CoreConstId, FunctionId};
|
||||||
use crate::ir_core::{Block, ConstPool, ConstantValue, Instr, InstrKind, Program, Terminator};
|
use crate::ir_core::{Block, ConstPool, ConstantValue, Instr, InstrKind, Program, Terminator};
|
||||||
use crate::ir_vm::{InstrKind as VmInstrKind, Label};
|
use crate::ir_lang::{InstrKind as VmInstrKind, Label};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_full_lowering() {
|
fn test_full_lowering() {
|
||||||
@ -3,7 +3,7 @@ use prometeu_compiler::building::output::{compile_project, CompileError, ExportK
|
|||||||
use prometeu_compiler::building::plan::{BuildStep, BuildTarget};
|
use prometeu_compiler::building::plan::{BuildStep, BuildTarget};
|
||||||
use prometeu_compiler::common::files::FileManager;
|
use prometeu_compiler::common::files::FileManager;
|
||||||
use prometeu_compiler::deps::resolver::ProjectKey;
|
use prometeu_compiler::deps::resolver::ProjectKey;
|
||||||
use frontend_api::types::{ExportItem, ItemName};
|
use language_api::types::{ExportItem, ItemName};
|
||||||
use prometeu_compiler::frontends::pbs::adapter::PbsFrontendAdapter;
|
use prometeu_compiler::frontends::pbs::adapter::PbsFrontendAdapter;
|
||||||
use prometeu_analysis::ids::ProjectId;
|
use prometeu_analysis::ids::ProjectId;
|
||||||
use std::collections::{BTreeMap, HashMap};
|
use std::collections::{BTreeMap, HashMap};
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user