jetcrab\api/
engine.rs

1//! # JavaScript Engine API
2//!
3//! Provides the main execution engine for JavaScript code, combining parsing,
4//! semantic analysis, bytecode generation, and VM execution.
5//!
6//! ## Overview
7//!
8//! The Engine is the primary entry point for JavaScript execution:
9//!
10//! - **Source Code Input**: Accepts JavaScript source as strings
11//! - **Complete Pipeline**: Parsing → Analysis → Compilation → Execution
12//! - **Result Output**: Returns computed values or error messages
13//! - **Context Management**: Maintains execution state and context
14//!
15//! ## Execution Flow
16//!
17//! ```text
18//! Source Code → Parser → AST → Semantic Analysis → Bytecode → VM → Result
19//! ```
20//!
21//! ## Usage
22//!
23//! ```rust
24//! use jetcrab::api::Engine;
25//!
26//! let mut engine = Engine::new();
27//! let result = engine.evaluate("2 + 2 * 3")?;
28//! println!("Result: {:?}", result);
29//! ```
30
31use crate::bytecode::BytecodeGenerator;
32use crate::parser::Parser;
33use crate::runtime::Context;
34use crate::semantic::SemanticAnalyzer;
35use crate::vm::executor::Executor;
36use crate::vm::{Bytecode, Value};
37
38/// Main JavaScript execution engine
39///
40/// Combines all components needed for JavaScript execution:
41/// parsing, semantic analysis, bytecode generation, and VM execution.
42pub struct Engine {
43    context: Context,
44    executor: Executor,
45    generator: BytecodeGenerator,
46    analyzer: SemanticAnalyzer,
47}
48
49impl Default for Engine {
50    fn default() -> Self {
51        Self::new()
52    }
53}
54
55impl Engine {
56    pub fn new() -> Self {
57        Self {
58            context: Context::new(),
59            executor: Executor::new(),
60            generator: BytecodeGenerator::new(),
61            analyzer: SemanticAnalyzer::new(),
62        }
63    }
64
65    pub fn evaluate(&mut self, source: &str) -> Result<Value, String> {
66        let mut parser = Parser::new(source);
67        let ast = parser.parse().map_err(|e| format!("Parser error: {e}"))?;
68
69        self.analyzer
70            .analyze(&ast)
71            .map_err(|e| format!("Semantic error: {e}"))?;
72
73        let instructions = self.generator.generate(&ast);
74        let constants = self.generator.get_constants().clone();
75
76        let values: Vec<Value> = constants
77            .iter()
78            .map(|s| {
79                // Check if it's a string that starts and ends with quotes (string literal)
80                if s.starts_with('"') && s.ends_with('"') {
81                    // Remove quotes and treat as string literal
82                    let content = &s[1..s.len() - 1];
83                    Value::String(content.to_string())
84                } else if s.starts_with("'") && s.ends_with("'") {
85                    // Remove quotes and treat as string literal
86                    let content = &s[1..s.len() - 1];
87                    Value::String(content.to_string())
88                } else if let Ok(num) = s.parse::<f64>() {
89                    // Check if it's actually a number (not a string that happens to be numeric)
90                    if s.contains('.') || s.parse::<i64>().is_ok() {
91                        Value::Number(num)
92                    } else {
93                        // If it's a string that looks like a number, keep it as string
94                        Value::String(s.clone())
95                    }
96                } else if s == "true" {
97                    Value::Boolean(true)
98                } else if s == "false" {
99                    Value::Boolean(false)
100                } else if s == "null" {
101                    Value::Null
102                } else if s == "undefined" {
103                    Value::Undefined
104                } else {
105                    Value::String(s.clone())
106                }
107            })
108            .collect();
109
110        let bytecode = Bytecode::new(instructions);
111        self.executor
112            .execute(&bytecode, &values)
113            .map_err(|e| format!("Execution error: {}", e))?;
114
115        Ok(self.executor.stack_mut().pop().unwrap_or(Value::Undefined))
116    }
117
118    pub fn get_context(&self) -> &Context {
119        &self.context
120    }
121
122    pub fn get_context_mut(&mut self) -> &mut Context {
123        &mut self.context
124    }
125}