Skip to main content

neutron_engine/iris/
mod.rs

1/// Iris Programming Language - Interpreter Module
2/// 
3/// Iris adalah bahasa scripting dengan paradigm hybrid:
4/// - Object-oriented (prototype-based seperti JavaScript)
5/// - Imperative (control flow seperti C/Rust)
6/// - Functional (first-class functions, closures)
7
8pub mod lexer;
9pub mod parser;
10pub mod interpreter;
11pub mod value;
12
13use std::fs;
14use std::path::Path;
15
16/// Run an Iris source file
17pub fn run_file(path: &str) -> Result<(), String> {
18    let source = fs::read_to_string(path)
19        .map_err(|e| format!("Failed to read '{}': {}", path, e))?;
20    let base = Path::new(path).parent().unwrap_or(Path::new("."));
21    let file_name = Path::new(path).file_name().unwrap_or_default().to_str().unwrap_or("");
22    run_with_base(&source, base.to_str().unwrap_or("."), Some(file_name))
23}
24
25/// Run Iris source code directly
26pub fn run(source: &str) -> Result<(), String> {
27    run_with_base(source, ".", None)
28}
29
30/// Run with base path for imports
31pub fn run_with_base(source: &str, base_path: &str, entry_file: Option<&str>) -> Result<(), String> {
32    let tokens = lexer::tokenize(source)?;
33    let ast = parser::parse(&tokens)?;
34    let mut interp = interpreter::Interpreter::new().with_base_path(base_path);
35    if let Some(file) = entry_file {
36        interp.mark_imported(file);
37    }
38    interp.execute(&ast)?;
39    Ok(())
40}
41
42/// REPL - Read Eval Print Loop
43pub fn repl() {
44    use std::io::{self, Write};
45    
46    println!("Iris REPL v0.1.0");
47    println!("Type 'exit' or press Ctrl+C to quit.\n");
48    
49    let mut interp = interpreter::Interpreter::new();
50    
51    loop {
52        print!("iris> ");
53        io::stdout().flush().unwrap();
54        
55        let mut input = String::new();
56        if io::stdin().read_line(&mut input).is_err() {
57            break;
58        }
59        
60        let input = input.trim();
61        if input == "exit" || input == "quit" {
62            break;
63        }
64        if input.is_empty() {
65            continue;
66        }
67        
68        match lexer::tokenize(input) {
69            Ok(tokens) => {
70                match parser::parse(&tokens) {
71                    Ok(ast) => {
72                        match interp.execute(&ast) {
73                            Ok(result) => {
74                                if !matches!(result, value::Value::Null) {
75                                    println!("{}", result);
76                                }
77                            }
78                            Err(e) => eprintln!("Runtime error: {}", e),
79                        }
80                    }
81                    Err(e) => eprintln!("Parse error: {}", e),
82                }
83            }
84            Err(e) => eprintln!("Lex error: {}", e),
85        }
86    }
87}
88