fusabi_frontend/
lib.rs

1//! Fusabi Frontend - Parser, Typechecker, and Bytecode Compiler
2//!
3//! This crate implements the frontend of the Fusabi (F# Script Runtime System),
4//! responsible for parsing F# source code into an AST, performing type checking,
5//! and compiling to bytecode for the Fusabi VM.
6//!
7//! # Modules
8//!
9//! - `ast`: Core AST (Abstract Syntax Tree) definitions
10//! - `lexer`: Lexer/Tokenizer for Mini-F# source code
11//! - `parser`: Recursive-descent parser for Mini-F# expressions
12//! - `compiler`: Bytecode compiler (AST → Bytecode)
13//! - `types`: Type system infrastructure for Hindley-Milner type inference
14//! - `inference`: Type inference engine (Hindley-Milner algorithm)
15//! - `typed_ast`: Optional typed AST with type annotations
16//! - `span`: Source location tracking for error reporting
17//! - `error`: Error types with beautiful formatting and suggestions
18//! - `modules`: Module system for code organization
19//!
20//! # Example
21//!
22//! ```rust
23//! use fusabi_frontend::ast::{Expr, Literal, BinOp};
24//! use fusabi_frontend::lexer::Lexer;
25//! use fusabi_frontend::parser::Parser;
26//! use fusabi_frontend::compiler::{Compiler, CompileOptions};
27//! use fusabi_frontend::inference::TypeInference;
28//! use fusabi_frontend::types::TypeEnv;
29//!
30//! // Full pipeline: source -> tokens -> AST -> type check -> bytecode
31//! let source = "let x = 42 in x + 1";
32//! let mut lexer = Lexer::new(source);
33//! let tokens = lexer.tokenize().unwrap();
34//! let mut parser = Parser::new(tokens);
35//! let ast = parser.parse().unwrap();
36//!
37//! // Type check
38//! let mut infer = TypeInference::new();
39//! let env = TypeEnv::new();
40//! let ty = infer.infer_and_solve(&ast, &env).unwrap();
41//!
42//! // Compile without type checking (backward compatible)
43//! let chunk = Compiler::compile(&ast).unwrap();
44//!
45//! // Or compile with type checking enabled
46//! let options = CompileOptions {
47//!     enable_type_checking: true,
48//!     ..Default::default()
49//! };
50//! let chunk_checked = Compiler::compile_with_options(&ast, options).unwrap();
51//!
52//! // Chunk is ready for VM execution
53//! assert!(chunk.instructions.len() > 0);
54//! ```
55
56pub mod ast;
57pub mod compiler;
58pub mod error;
59pub mod inference;
60pub mod lexer;
61pub mod loader;
62pub mod modules;
63pub mod parser;
64pub mod span;
65pub mod typed_ast;
66pub mod types;
67
68// Re-export commonly used types for convenience
69pub use ast::{BinOp, Expr, Literal, LoadDirective, ModuleDef, ModuleItem, Pattern, Program};
70pub use compiler::{CompileError, CompileOptions, Compiler};
71pub use error::{TypeError, TypeErrorKind};
72pub use inference::TypeInference;
73pub use lexer::{LexError, Lexer, Position, Token, TokenWithPos};
74pub use loader::{FileLoader, LoadError, LoadedFile};
75pub use modules::{Module, ModulePath, ModuleRegistry, TypeDefinition as ModuleTypeDef};
76pub use parser::{ParseError, Parser};
77pub use span::Span;
78pub use typed_ast::{TypedExpr, TypedPattern};
79pub use types::{Substitution, Type, TypeEnv, TypeScheme, TypeVar};
80
81use fusabi_vm::chunk::Chunk;
82
83/// Convenience function to compile a program from source code
84///
85/// This is a high-level API that performs the full compilation pipeline:
86/// 1. Lexing (source -> tokens)
87/// 2. Parsing (tokens -> Program AST)
88/// 3. Compilation (Program AST -> Bytecode)
89///
90/// # Example
91///
92/// ```rust
93/// use fusabi_frontend::compile_program_from_source;
94///
95/// // Note: Module parsing is available but not all features are implemented yet
96/// let source = "42";
97///
98/// let chunk = compile_program_from_source(source).unwrap();
99/// assert!(chunk.instructions.len() > 0);
100/// ```
101pub fn compile_program_from_source(source: &str) -> Result<Chunk, CompilationError> {
102    let mut lexer = Lexer::new(source);
103    let tokens = lexer.tokenize().map_err(CompilationError::LexError)?;
104    let mut parser = Parser::new(tokens);
105    let program = parser
106        .parse_program()
107        .map_err(CompilationError::ParseError)?;
108    let chunk = Compiler::compile_program(&program).map_err(CompilationError::CompileError)?;
109    Ok(chunk)
110}
111
112/// Unified error type for the compilation pipeline
113#[derive(Debug)]
114pub enum CompilationError {
115    LexError(LexError),
116    ParseError(ParseError),
117    CompileError(CompileError),
118}
119
120impl std::fmt::Display for CompilationError {
121    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
122        match self {
123            CompilationError::LexError(e) => write!(f, "Lexer error: {}", e),
124            CompilationError::ParseError(e) => write!(f, "Parse error: {}", e),
125            CompilationError::CompileError(e) => write!(f, "Compile error: {}", e),
126        }
127    }
128}
129
130impl std::error::Error for CompilationError {}