use { std::collections::HashMap, std::sync::{Arc, RwLock}, std::{boxed::Box, ops::Deref}, }; mod expr; mod lexer; mod parser; mod procedure_compiler; mod runtime; mod symbols; use crate::{ expr::{LTExpr, Statement}, procedure_compiler::ProcedureCompiler, symbols::Scope, }; fn compile( scope: &Arc<RwLock<Scope>>, name: &str, source: impl Iterator<Item = char>, ) -> Vec<tisc::assembler::AssemblyWord> { ProcedureCompiler::new(scope) .compile( &parser::parse_expr( &scope.read().unwrap().typectx, &mut lexer::LTIRLexer::from(source.peekable()) .filter(|tok| match tok { (_, Ok(lexer::LTIRToken::Comment(_))) => false, _ => true }) .peekable(), ) .expect("syntax error"), ) .into_asm(&name.into()) } /* TODO: * - Parser error reporting * - Compiler error reporting * - write to address resulting from expression * - sized objects * - Typecheck for LTExpr::Application * - typecheck & inference for rest */ fn main() { // create virtual machine with 4096 words of memory let mut vm = tisc::VM::new(0x1000); let mut linker = tisc::Linker::new(); let root_scope = crate::runtime::init_runtime(&mut linker); let main_scope = Scope::with_parent(&root_scope); let typectx = main_scope.read().unwrap().typectx.clone(); let args: Vec<String> = std::env::args().collect(); let path = &args[1]; let iter_chars = iterate_text::file::characters::IterateFileCharacters::new(path); /* link assembly-program to symbols */ linker.add_procedure("main", compile(&main_scope, "main", iter_chars)); /* load & run compiled bytecode */ let main_addr = linker .get_link_addr(&"main".into()) .expect("'main' not linked"); vm.load(linker.link_total().expect("could not link")); vm.execute(main_addr); eprintln!( "\n====\nVM execution finished\ndatastack = {:?}\n====", vm.data_stack ); }