lt-core/src/main.rs

80 lines
2.1 KiB
Rust

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
);
}