carmen_lang/lib.rs
1//! # Carmen - Programmatic Music Composition Language
2//!
3//! Carmen is a novel, programmatic language designed for music composition. This library provides
4//! the core functionality to parse, interpret, and execute Carmen source code, as well as export
5//! compositions to various formats.
6//!
7//! ## Features
8//!
9//! - **Lexical Analysis**: Tokenize Carmen source code into a stream of tokens
10//! - **Parsing**: Parse tokens into an Abstract Syntax Tree (AST)
11//! - **Interpretation**: Execute Carmen programs and evaluate musical expressions
12//! - **Export**: Convert compositions to formats like LilyPond for sheet music generation
13
14pub mod ast;
15pub mod cli;
16pub mod common;
17pub mod core;
18pub mod errors;
19pub mod exporter;
20pub mod interpreter;
21pub mod lexer;
22pub mod parser;
23pub mod repl;
24
25use ast::inspector::{inspect_ast, inspect_ast_to_file};
26use errors::Result;
27use exporter::{ExportConfig, ExportFormat, ExportManager, ExportOutput};
28use interpreter::{Interpreter, Value};
29use lexer::{Lexer, Token};
30use parser::Parser;
31
32/// Executes Carmen source code and returns the resulting value.
33///
34/// This is the main entry point for running Carmen programs. It performs the complete
35/// compilation and execution pipeline: lexical analysis, parsing, and interpretation.
36///
37/// # Arguments
38///
39/// * `source` - A string slice containing the Carmen source code to execute
40///
41/// # Returns
42///
43/// Returns a `Result<Value>` where:
44/// - `Ok(Value)` contains the result of executing the Carmen program
45/// - `Err(CarmenError)` contains any compilation or runtime errors
46///
47/// # Errors
48///
49/// This function will return an error if:
50/// - The source code contains lexical errors (invalid tokens)
51/// - The source code contains syntax errors (invalid grammar)
52/// - The program encounters runtime errors during execution
53pub fn run(source: &str) -> Result<Value> {
54 let mut lexer = Lexer::new(source);
55 let tokens = lexer.tokenize()?;
56
57 let parser = Parser::new(tokens);
58 let program = parser.parse()?;
59
60 let mut interpreter = Interpreter::new();
61 interpreter.interpret(&program)
62}
63
64/// Executes Carmen source code using an existing interpreter instance.
65///
66/// This function allows you to maintain state between multiple Carmen program executions
67/// by reusing the same interpreter. This is useful for REPL environments or when you want
68/// to execute multiple related programs that share variables and functions.
69///
70/// # Arguments
71///
72/// * `interpreter` - A mutable reference to an existing `Interpreter` instance
73/// * `source` - A string slice containing the Carmen source code to execute
74///
75/// # Returns
76///
77/// Returns a `Result<Value>` where:
78/// - `Ok(Value)` contains the result of executing the Carmen program
79/// - `Err(CarmenError)` contains any compilation or runtime errors
80///
81/// # Errors
82///
83/// This function will return an error if:
84/// - The source code contains lexical errors (invalid tokens)
85/// - The source code contains syntax errors (invalid grammar)
86/// - The program encounters runtime errors during execution
87pub fn run_with_interpreter(interpreter: &mut Interpreter, source: &str) -> Result<Value> {
88 let mut lexer = Lexer::new(source);
89 let tokens = lexer.tokenize()?;
90
91 let parser = Parser::new(tokens);
92 let program = parser.parse()?;
93
94 interpreter.interpret(&program)
95}
96
97/// Parses Carmen source code into an Abstract Syntax Tree (AST).
98///
99/// This function performs lexical analysis and parsing without executing the code.
100/// It's useful for code analysis, debugging, or when you want to inspect the structure
101/// of a Carmen program before execution.
102///
103/// # Arguments
104///
105/// * `source` - A string slice containing the Carmen source code to parse
106///
107/// # Returns
108///
109/// Returns a `Result<ast::Program>` where:
110/// - `Ok(ast::Program)` contains the parsed AST representing the program structure
111/// - `Err(CarmenError)` contains any lexical or syntax errors
112///
113/// # Errors
114///
115/// This function will return an error if:
116/// - The source code contains invalid tokens
117/// - The source code contains syntax errors
118pub fn parse(source: &str) -> Result<ast::Program> {
119 let mut lexer = Lexer::new(source);
120 let tokens = lexer.tokenize()?;
121
122 let parser = Parser::new(tokens);
123 parser.parse()
124}
125
126/// Tokenizes Carmen source code into a vector of tokens.
127///
128/// This function performs lexical analysis on the source code, converting it into
129/// a sequence of tokens that can be consumed by the parser. It's useful for debugging
130/// lexical issues or understanding how Carmen code is tokenized.
131///
132/// # Arguments
133///
134/// * `source` - A string slice containing the Carmen source code to tokenize
135///
136/// # Returns
137///
138/// Returns a `Result<Vec<Token>>` where:
139/// - `Ok(Vec<Token>)` contains the sequence of tokens representing the source code
140/// - `Err(CarmenError)` contains any lexical errors
141///
142/// # Errors
143///
144/// This function will return an error if:
145/// - The source code contains invalid characters or token sequences
146/// - String literals are not properly terminated
147/// - Numeric literals are malformed
148pub fn tokenize(source: &str) -> Result<Vec<Token>> {
149 let mut lexer = Lexer::new(source);
150 lexer.tokenize()
151}