bug fixes and performance improvements

This commit is contained in:
2023-05-07 22:35:38 +01:00
parent f3ce910f66
commit a604e40bad
167 changed files with 5965 additions and 4229 deletions

View File

@@ -1,6 +1,3 @@
#![feature(specialization)]
#![feature(adt_const_params)]
#![feature(generic_const_exprs)]
#![feature(generators, generator_trait)]
#![feature(never_type)]
#![feature(unwrap_infallible)]
@@ -8,124 +5,51 @@
#![feature(hasher_prefixfree_extras)]
#![feature(closure_lifetime_binder)]
#![feature(generic_arg_infer)]
use std::{env::current_dir, collections::HashMap};
#![feature(array_chunks)]
#![feature(fmt_internals)]
#![feature(map_try_insert)]
#![feature(slice_group_by)]
#![feature(trait_alias)]
// mod executor;
mod parse;
pub(crate) mod project;
mod interner;
mod interpreter;
mod utils;
mod representations;
mod rule;
mod scheduler;
pub(crate) mod foreign;
mod external;
mod foreign_macros;
use lasso::Rodeo;
mod pipeline;
mod run_dir;
mod cli;
use std::{path::PathBuf, fs::File};
use clap::Parser;
use cli::prompt;
pub use representations::ast;
use ast::{Expr, Clause};
// use representations::typed as t;
use mappable_rc::Mrc;
use project::{rule_collector, file_loader};
use rule::Repository;
use utils::to_mrc_slice;
use run_dir::run_dir;
use crate::external::std::std;
use crate::project::{map_loader, string_loader, Loader, ModuleError};
use crate::representations::{ast_to_postmacro, postmacro_to_interpreted};
fn literal(orig: &[&str]) -> Mrc<[String]> {
to_mrc_slice(vliteral(orig))
}
fn vliteral(orig: &[&str]) -> Vec<String> {
orig.iter().map(|&s| s.to_owned()).collect()
}
static PRELUDE:&str = r#"
import std::(
num::(add, subtract, multiply, remainder, divide),
bool::(equals, ifthenelse),
str::concatenate
)
export (...$a + ...$b) =1001=> (add (...$a) (...$b))
export (...$a - ...$b:1) =1001=> (subtract (...$a) (...$b))
export (...$a * ...$b) =1000=> (multiply (...$a) (...$b))
export (...$a % ...$b:1) =1000=> (remainder (...$a) (...$b))
export (...$a / ...$b:1) =1000=> (divide (...$a) (...$b))
export (...$a == ...$b) =1002=> (equals (...$a) (...$b))
export (...$a ++ ...$b) =1003=> (concatenate (...$a) (...$b))
export do { ...$statement ; ...$rest:1 } =10_001=> (
statement (...$statement) do { ...$rest }
)
export do { ...$return } =10_000=> (...$return)
export statement (let $_name = ...$value) ...$next =10_000=> (
(\$_name. ...$next) (...$value)
)
export statement (cps $_name = ...$operation) ...$next =10_001=> (
(...$operation) \$_name. ...$next
)
export statement (cps ...$operation) ...$next =10_000=> (
(...$operation) (...$next)
)
export if ...$cond then ...$true else ...$false:1 =5_000=> (
ifthenelse (...$cond) (...$true) (...$false)
)
"#;
fn initial_tree() -> Mrc<[Expr]> {
to_mrc_slice(vec![Expr(Clause::Name {
local: None,
qualified: literal(&["mod", "main", "main"])
}, to_mrc_slice(vec![]))])
}
#[allow(unused)]
fn load_project() {
let mut rodeo = Rodeo::default();
let collect_rules = rule_collector(
rodeo,
map_loader(HashMap::from([
("std", std().boxed()),
("prelude", string_loader(PRELUDE).boxed()),
("mod", file_loader(current_dir().expect("Missing CWD!")).boxed())
]))
);
let rules = match collect_rules.try_find(&literal(&["mod", "main"])) {
Ok(rules) => rules,
Err(err) => if let ModuleError::Syntax(pe) = err {
panic!("{}", pe);
} else {panic!("{:#?}", err)}
};
let mut tree = initial_tree();
println!("Start processing {tree:?}");
let repo = Repository::new(rules.as_ref().to_owned());
println!("Ruleset: {repo:?}");
xloop!(let mut i = 0; i < 100; i += 1; {
match repo.step(Mrc::clone(&tree)) {
Ok(Some(phase)) => {
//println!("Step {i}: {phase:?}");
tree = phase;
},
Ok(None) => {
println!("Execution complete");
break
},
Err(e) => panic!("Rule error: {e:?}")
}
}; panic!("Macro execution didn't halt"));
let pmtree = ast_to_postmacro::exprv(tree.as_ref())
.unwrap_or_else(|e| panic!("Postmacro conversion error: {e}"));
let runtree = postmacro_to_interpreted::expr_rec(&pmtree)
.unwrap_or_else(|e| panic!("Interpreted conversion error: {e}"));
let stable = runtree.run_to_completion()
.unwrap_or_else(|e| panic!("Runtime error {e}"));
println!("Settled at {stable:?}")
/// Orchid interpreter
#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
struct Args {
/// Folder containing main.orc
#[arg(short, long)]
pub project: Option<String>
}
fn main() {
load_project();
let args = Args::parse();
let path = args.project.unwrap_or_else(|| {
prompt("Enter a project root", ".".to_string(), |p| {
let mut path: PathBuf = p.trim().into();
path.push("main.orc");
match File::open(&path) {
Ok(_) => Ok(p),
Err(e) => Err(format!("{}: {e}", path.display()))
}
})
});
run_dir(&PathBuf::try_from(path).unwrap());
}