use colored::*;
use magc::compiler::Compiler;
use magc::lexer::Lexer;
use magc::parser::Parser;
use magc::types::{Expression, ParserError, Token};
use strontium::Strontium;
pub struct RuntimeConfig {
pub debug: bool,
}
pub struct Runtime {
pub config: RuntimeConfig,
pub lexer: Lexer,
pub parser: Parser,
pub compiler: Compiler,
pub machine: Strontium,
}
impl Runtime {
pub fn new(config: RuntimeConfig) -> Self {
Self {
lexer: Lexer::new(),
parser: Parser::new(),
compiler: Compiler::new(),
machine: Strontium::new(config.debug),
config,
}
}
pub fn lex(&mut self, source: String) -> Vec<Token> {
self.lexer.add_text(source);
self.lexer.parse()
}
pub fn parse(&mut self, source: String) -> Result<Vec<Expression>, ParserError> {
self.lexer.add_text(source.clone());
let tokens = self.lexer.parse();
self.parser.add_tokens(source, tokens);
self.parser.parse()
}
pub fn compile(&mut self, source: String) -> Result<Vec<strontium::Instruction>, String> {
self.lexer.add_text(source.clone());
let tokens = self.lexer.parse();
self.parser.add_tokens(source, tokens);
let expressions = self.parser.parse();
match expressions {
Ok(expressions) => {
let mut bytecode = vec![];
for expression in expressions {
let compiled = self.compiler.compile_expression(expression, None);
match compiled {
Ok(mut compiled) => {
bytecode.append(&mut compiled);
}
Err(e) => {
return Err(format!("{:?}", e));
}
}
}
Ok(bytecode)
}
Err(e) => Err(format!("{:?}", e)),
}
}
pub fn execute_source(&mut self, source: String) {
let expressions_result = self.compile(source);
match expressions_result {
Ok(instructions) => {
for instruction in instructions {
self.machine.push_instruction(instruction);
}
self.machine.execute().unwrap();
}
Err(e) => {
println!("{} {:?}", "error:".bright_red().bold(), e);
}
}
}
}