Skip to main content

spydecy_hir/
lib.rs

1//! Spydecy Unified High-Level Intermediate Representation (HIR)
2//!
3//! This module defines the core data structures for Spydecy's Unified HIR.
4//! The HIR is the central innovation that enables cross-layer optimization
5//! by unifying Python and C representations.
6//!
7//! # Architecture
8//!
9//! ```text
10//! ┌──────────┐       ┌──────────┐
11//! │ Python   │       │   C      │
12//! │  AST     │       │  AST     │
13//! └────┬─────┘       └────┬─────┘
14//!      │                  │
15//!      ▼                  ▼
16//! ┌──────────┐       ┌──────────┐
17//! │ Python   │       │   C      │
18//! │  HIR     │       │  HIR     │
19//! └────┬─────┘       └────┬─────┘
20//!      │                  │
21//!      └────────┬─────────┘
22//!               ▼
23//!       ┌──────────────┐
24//!       │ Unified HIR  │ ⭐ Core Innovation
25//!       └──────┬───────┘
26//!              ▼
27//!       ┌──────────────┐
28//!       │  Optimizer   │
29//!       └──────┬───────┘
30//!              ▼
31//!       ┌──────────────┐
32//!       │   Codegen    │
33//!       └──────┬───────┘
34//!              ▼
35//!         Rust Code
36//! ```
37//!
38//! # Sprint 0 Validation
39//!
40//! Sprint 0 validated this architecture with a minimal implementation:
41//! - Python `len()` + C `list_length()` → Unified HIR → Rust `Vec::len()`
42//! - 8/8 tests passing ✅
43//! - Zero FFI, zero unsafe ✅
44//!
45//! This production version extends that success to handle real code.
46
47#![warn(missing_docs, clippy::all, clippy::pedantic)]
48#![deny(unsafe_code)]
49#![allow(clippy::module_name_repetitions)]
50#![allow(clippy::unnested_or_patterns)]
51#![allow(clippy::uninlined_format_args)]
52#![allow(clippy::single_match_else)]
53
54pub mod c;
55pub mod error;
56pub mod metadata;
57pub mod python;
58pub mod types;
59pub mod unified;
60
61use serde::{Deserialize, Serialize};
62use std::fmt;
63
64/// Programming language source
65#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
66pub enum Language {
67    /// Python source code
68    Python,
69    /// C source code (including `CPython` implementation)
70    C,
71    /// Rust target code (output)
72    Rust,
73}
74
75impl fmt::Display for Language {
76    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
77        match self {
78            Self::Python => write!(f, "Python"),
79            Self::C => write!(f, "C"),
80            Self::Rust => write!(f, "Rust"),
81        }
82    }
83}
84
85/// Source location for error reporting and debugging
86#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
87pub struct SourceLocation {
88    /// Source file path
89    pub file: String,
90    /// Line number (1-indexed)
91    pub line: usize,
92    /// Column number (1-indexed)
93    pub column: usize,
94    /// Source language
95    pub language: Language,
96}
97
98impl SourceLocation {
99    /// Create a new source location
100    #[must_use]
101    pub const fn new(file: String, line: usize, column: usize, language: Language) -> Self {
102        Self {
103            file,
104            line,
105            column,
106            language,
107        }
108    }
109}
110
111/// Unique identifier for HIR nodes (for cross-referencing)
112#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
113pub struct NodeId(pub u64);
114
115impl NodeId {
116    /// Create a new node ID
117    #[must_use]
118    pub const fn new(id: u64) -> Self {
119        Self(id)
120    }
121}
122
123/// Visibility modifier
124#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
125pub enum Visibility {
126    /// Public (exported)
127    Public,
128    /// Private (internal)
129    Private,
130    /// Module-level (Python) or static (C)
131    Module,
132}
133
134#[cfg(test)]
135mod tests {
136    use super::*;
137
138    #[test]
139    fn test_language_display() {
140        assert_eq!(Language::Python.to_string(), "Python");
141        assert_eq!(Language::C.to_string(), "C");
142        assert_eq!(Language::Rust.to_string(), "Rust");
143    }
144
145    #[test]
146    fn test_source_location_creation() {
147        let loc = SourceLocation::new("test.py".to_owned(), 10, 5, Language::Python);
148        assert_eq!(loc.line, 10);
149        assert_eq!(loc.column, 5);
150        assert_eq!(loc.language, Language::Python);
151    }
152
153    #[test]
154    fn test_node_id_creation() {
155        let id = NodeId::new(42);
156        assert_eq!(id.0, 42);
157    }
158}