bquarkz 565fc0e451 dev/pbs (#8)
Co-authored-by: Nilton Constantino <nilton.constantino@visma.com>
Reviewed-on: #8
2026-02-03 15:28:30 +00:00

156 lines
4.8 KiB
Rust

//! # Prometeu Compiler
//!
//! This crate provides the official compiler for the Prometeu ecosystem.
//! It translates high-level source code (primarily Prometeu Base Script - PBS) into
//! Prometeu ByteCode (.pbc), which runs on the Prometeu Virtual Machine.
//!
//! ## Architecture Overview:
//!
//! The compiler follows a multi-stage pipeline:
//!
//! 1. **Frontend (Parsing & Analysis)**:
//! - Uses the PBS parser to generate an Abstract Syntax Tree (AST).
//! - Performs semantic analysis and validation.
//! - Lowers the AST into the **Intermediate Representation (IR)**.
//! - *Example*: Converting a `a + b` expression into IR instructions like `Push(a)`, `Push(b)`, `Add`.
//!
//! 2. **IR Optimization (Optional/Planned)**:
//! - Simplifies the IR to improve performance or reduce bytecode size.
//!
//! 3. **Backend (Code Generation)**:
//! - **Lowering**: Converts the high-level IR into a flat list of ByteCode instructions.
//! - **Assembly**: Resolves branch labels into actual memory offsets.
//! - **Serialization**: Encodes the instructions into the binary PBC format.
//!
//! 4. **Artifact Export**:
//! - Generates the `.pbc` binary file.
//! - Optionally produces `.disasm` (disassembly for debugging) and `.json` (symbol maps).
//!
//! ## Example Usage (CLI):
//!
//! ```bash
//! # Build a project from a directory
//! prometeu-compiler build ./my-game --entry ./src/main.pbs --out ./game.pbc
//! ```
//!
//! ## Programmatic Entry Point:
//!
//! See the [`compiler`] module for the main entry point to trigger a compilation programmatically.
pub mod common;
pub mod ir_vm;
pub mod ir_core;
pub mod lowering;
pub mod backend;
pub mod frontends;
pub mod compiler;
pub mod manifest;
pub mod deps;
pub mod sources;
pub mod building;
pub mod semantics;
use anyhow::Result;
use clap::{Parser, Subcommand};
use std::path::PathBuf;
/// Command line interface for the Prometeu Compiler.
#[derive(Parser)]
#[command(name = "prometeu-compiler")]
#[command(version, about = "Official compiler for the PROMETEU Virtual Machine", long_about = None)]
pub struct Cli {
/// The action to perform (build or verify).
#[command(subcommand)]
pub command: Commands,
}
/// Available subcommands for the compiler.
#[derive(Subcommand)]
pub enum Commands {
/// Builds a Prometeu project by compiling source code into a PBC file.
Build {
/// Path to the project root directory.
project_dir: PathBuf,
/// Explicit path to the entry file (defaults to src/main.pbs).
#[arg(short, long)]
entry: Option<PathBuf>,
/// Path to save the compiled .pbc file.
#[arg(short, long)]
out: Option<PathBuf>,
/// Whether to generate a .json symbols file for source mapping.
#[arg(long, default_value_t = true)]
emit_symbols: bool,
/// Disable symbol generation.
#[arg(long)]
no_symbols: bool,
/// Whether to generate a .disasm file for debugging.
#[arg(long, default_value_t = true)]
emit_disasm: bool,
/// Disable disassembly generation.
#[arg(long)]
no_disasm: bool,
/// Whether to explain the dependency resolution process.
#[arg(long)]
explain_deps: bool,
},
/// Verifies if a Prometeu project is syntactically and semantically valid without emitting code.
Verify {
/// Path to the project root directory.
project_dir: PathBuf,
/// Whether to explain the dependency resolution process.
#[arg(long)]
explain_deps: bool,
},
}
/// Main entry point for the compiler library's execution logic.
/// Parses CLI arguments and dispatches to the appropriate compiler functions.
pub fn run() -> Result<()> {
let cli = Cli::parse();
match cli.command {
Commands::Build {
project_dir,
out,
emit_disasm,
no_disasm,
emit_symbols,
no_symbols,
explain_deps,
..
} => {
let build_dir = project_dir.join("build");
let out = out.unwrap_or_else(|| build_dir.join("program.pbc"));
let emit_symbols = emit_symbols && !no_symbols;
let emit_disasm = emit_disasm && !no_disasm;
if !build_dir.exists() {
std::fs::create_dir_all(&build_dir)?;
}
println!("Building project at {:?}", project_dir);
println!("Output: {:?}", out);
let compilation_unit = compiler::compile_ext(&project_dir, explain_deps)?;
compilation_unit.export(&out, emit_disasm, emit_symbols)?;
}
Commands::Verify { project_dir, explain_deps } => {
println!("Verifying project at {:?}", project_dir);
compiler::compile_ext(&project_dir, explain_deps)?;
println!("Project is valid!");
}
}
Ok(())
}