cl-typeck: Crate-spanning refactor
TODO: remove all unreferenced files TODO: Finish resolving statically known types of values TODO: Type inference
This commit is contained in:
@@ -1,15 +1,14 @@
|
||||
use cl_typeck::{
|
||||
entry::Entry, import::import, populate::Populator, table::Table,
|
||||
type_expression::TypeExpression,
|
||||
};
|
||||
|
||||
use cl_ast::{
|
||||
ast_visitor::{Fold, Visit},
|
||||
desugar::*,
|
||||
};
|
||||
use cl_lexer::Lexer;
|
||||
use cl_parser::{inliner::ModuleInliner, Parser};
|
||||
use cl_typeck::{
|
||||
handle::Handle,
|
||||
name_collector::NameCollector,
|
||||
project::Project,
|
||||
type_resolver::resolve,
|
||||
};
|
||||
use repline::{error::Error as RlError, prebaked::*};
|
||||
use std::{error::Error, path};
|
||||
|
||||
@@ -31,7 +30,7 @@ const C_LISTING: &str = "\x1b[38;5;117m";
|
||||
static mut TREES: TreeManager = TreeManager::new();
|
||||
|
||||
fn main() -> Result<(), Box<dyn Error>> {
|
||||
let mut prj = Project::default();
|
||||
let mut prj = Table::default();
|
||||
|
||||
let mut parser = Parser::new(Lexer::new(STDLIB));
|
||||
let code = match parser.file() {
|
||||
@@ -42,13 +41,14 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||
}
|
||||
};
|
||||
let code = inline_modules(code, concat!(env!("PWD"), "/stdlib"));
|
||||
NameCollector::new(&mut prj).visit_file(unsafe { TREES.push(code) });
|
||||
Populator::new(&mut prj).visit_file(unsafe { TREES.push(code) });
|
||||
// NameCollector::new(&mut prj).visit_file(unsafe { TREES.push(code) });
|
||||
|
||||
main_menu(&mut prj)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn main_menu(prj: &mut Project) -> Result<(), RlError> {
|
||||
fn main_menu(prj: &mut Table) -> Result<(), RlError> {
|
||||
banner();
|
||||
read_and(C_MAIN, "mu>", "? >", |line| {
|
||||
match line.trim() {
|
||||
@@ -80,7 +80,7 @@ fn main_menu(prj: &mut Project) -> Result<(), RlError> {
|
||||
})
|
||||
}
|
||||
|
||||
fn enter_code(prj: &mut Project) -> Result<(), RlError> {
|
||||
fn enter_code(prj: &mut Table) -> Result<(), RlError> {
|
||||
read_and(C_CODE, "cl>", "? >", |line| {
|
||||
if line.trim().is_empty() {
|
||||
return Ok(Response::Break);
|
||||
@@ -89,8 +89,7 @@ fn enter_code(prj: &mut Project) -> Result<(), RlError> {
|
||||
let code = inline_modules(code, "");
|
||||
let code = WhileElseDesugar.fold_file(code);
|
||||
// Safety: this is totally unsafe
|
||||
NameCollector::new(prj).visit_file(unsafe { TREES.push(code) });
|
||||
|
||||
Populator::new(prj).visit_file(unsafe { TREES.push(code) });
|
||||
Ok(Response::Accept)
|
||||
})
|
||||
}
|
||||
@@ -113,22 +112,22 @@ fn live_desugar() -> Result<(), RlError> {
|
||||
})
|
||||
}
|
||||
|
||||
fn query_type_expression(prj: &mut Project) -> Result<(), RlError> {
|
||||
fn query_type_expression(prj: &mut Table) -> Result<(), RlError> {
|
||||
read_and(C_RESV, "ty>", "? >", |line| {
|
||||
if line.trim().is_empty() {
|
||||
return Ok(Response::Break);
|
||||
}
|
||||
// parse it as a path, and convert the path into a borrowed path
|
||||
let ty = Parser::new(Lexer::new(line)).ty()?.kind;
|
||||
let id = prj.evaluate(&ty, prj.root)?.handle_unchecked(prj);
|
||||
pretty_handle(id)?;
|
||||
let id = ty.evaluate(prj, prj.root())?;
|
||||
pretty_handle(id.to_entry(prj))?;
|
||||
Ok(Response::Accept)
|
||||
})
|
||||
}
|
||||
|
||||
fn get_by_id(prj: &mut Project) -> Result<(), RlError> {
|
||||
fn get_by_id(prj: &mut Table) -> Result<(), RlError> {
|
||||
use cl_structures::index_map::MapIndex;
|
||||
use cl_typeck::handle::DefID;
|
||||
use cl_typeck::handle::Handle;
|
||||
read_and(C_BYID, "id>", "? >", |line| {
|
||||
if line.trim().is_empty() {
|
||||
return Ok(Response::Break);
|
||||
@@ -141,9 +140,7 @@ fn get_by_id(prj: &mut Project) -> Result<(), RlError> {
|
||||
let mut path = parser.path().unwrap_or_default();
|
||||
path.absolute = false;
|
||||
|
||||
let Some(handle) = DefID::from_usize(def_id).handle(prj) else {
|
||||
return Ok(Response::Deny);
|
||||
};
|
||||
let handle = Handle::from_usize(def_id).to_entry(prj);
|
||||
|
||||
print!(" > {{{C_LISTING}{handle}\x1b[0m}}");
|
||||
if !path.parts.is_empty() {
|
||||
@@ -151,65 +148,114 @@ fn get_by_id(prj: &mut Project) -> Result<(), RlError> {
|
||||
}
|
||||
println!();
|
||||
|
||||
let (ty, value) = handle.navigate((&path).into());
|
||||
if let (None, None) = (ty, value) {
|
||||
let Some(handle) = handle.nav(&path.parts) else {
|
||||
Err("No results.")?
|
||||
}
|
||||
if let Some(t) = ty {
|
||||
println!("Result: {}", t.id());
|
||||
pretty_handle(t)?;
|
||||
}
|
||||
if let Some(v) = value {
|
||||
println!("Result in value namespace: {}", v.id());
|
||||
pretty_handle(v)?;
|
||||
}
|
||||
};
|
||||
|
||||
pretty_handle(handle)?;
|
||||
|
||||
Ok(Response::Accept)
|
||||
})
|
||||
}
|
||||
|
||||
fn resolve_all(prj: &mut Project) -> Result<(), Box<dyn Error>> {
|
||||
prj.resolve_imports()?;
|
||||
for id in prj.pool.keys() {
|
||||
resolve(prj, id)?;
|
||||
fn resolve_all(prj: &mut Table) -> Result<(), Box<dyn Error>> {
|
||||
println!("Resolving imports:");
|
||||
for (id, error) in import(prj) {
|
||||
eprintln!("{error} in {} ({id})", id.to_entry(prj))
|
||||
}
|
||||
println!("Types resolved successfully!");
|
||||
// todo!("Resolve imports");
|
||||
// prj.resolve_imports()?;
|
||||
// for id in prj.pool.keys() {
|
||||
// resolve(prj, id)?;
|
||||
// }
|
||||
// println!("Types resolved successfully!");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn list_types(prj: &mut Project) {
|
||||
println!(" name | type");
|
||||
for (idx, key) in prj.pool.keys().enumerate() {
|
||||
let handle = key.handle_unchecked(prj);
|
||||
let vis = handle.vis().unwrap_or_default();
|
||||
fn list_types(prj: &mut Table) {
|
||||
for handle in prj.debug_handle_iter() {
|
||||
let id = handle.id();
|
||||
let kind = handle.kind().unwrap();
|
||||
let name = handle.name().unwrap_or("".into());
|
||||
println!("{idx:3}: {name:16}| {vis}{handle}");
|
||||
println!("{id:3}: {name:16}| {kind} {handle}");
|
||||
}
|
||||
}
|
||||
|
||||
fn pretty_handle(handle: Handle) -> Result<(), std::io::Error> {
|
||||
fn pretty_handle(h: Entry) -> Result<(), std::io::Error> {
|
||||
use std::io::Write;
|
||||
let mut stdout = std::io::stdout().lock();
|
||||
let Some(vis) = handle.vis() else {
|
||||
return writeln!(stdout, "Invalid handle: {handle}");
|
||||
let mut out = std::io::stdout().lock();
|
||||
let Some(kind) = h.kind() else {
|
||||
return writeln!(out, "Invalid handle: {h}");
|
||||
};
|
||||
writeln!(stdout, "{C_LISTING}{}\x1b[0m: {vis}{handle}", handle.id())?;
|
||||
if let Some(parent) = handle.parent() {
|
||||
writeln!(stdout, "{C_LISTING}Parent\x1b[0m: {parent}")?;
|
||||
write!(out, "{C_LISTING}{kind}")?;
|
||||
if let Some(name) = h.name() {
|
||||
write!(out, " {name}")?;
|
||||
}
|
||||
if let Some(types) = handle.types() {
|
||||
writeln!(stdout, "{C_LISTING}Types:\x1b[0m")?;
|
||||
for (name, def) in types {
|
||||
writeln!(stdout, "- {C_LISTING}{name}\x1b[0m: {}", handle.with(*def))?
|
||||
writeln!(out, "\x1b[0m: {h}")?;
|
||||
|
||||
if let Some(parent) = h.parent() {
|
||||
writeln!(out, "- {C_LISTING}Parent\x1b[0m: {parent}")?;
|
||||
}
|
||||
|
||||
if let Some(span) = h.span() {
|
||||
writeln!(
|
||||
out,
|
||||
"- {C_LISTING}Span:\x1b[0m ({}, {})",
|
||||
span.head, span.tail
|
||||
)?;
|
||||
}
|
||||
|
||||
match h.meta() {
|
||||
Some(meta) if !meta.is_empty() => {
|
||||
writeln!(out, "- {C_LISTING}Meta:\x1b[0m")?;
|
||||
for meta in meta {
|
||||
writeln!(out, " - {meta}")?;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
if let Some(children) = h.children() {
|
||||
writeln!(out, "- {C_LISTING}Children:\x1b[0m")?;
|
||||
for (name, child) in children {
|
||||
writeln!(
|
||||
out,
|
||||
" - {C_LISTING}{name}\x1b[0m ({child}): {}",
|
||||
h.with_id(*child)
|
||||
)?
|
||||
}
|
||||
}
|
||||
if let Some(values) = handle.values() {
|
||||
writeln!(stdout, "{C_LISTING}Values:\x1b[0m")?;
|
||||
for (name, def) in values {
|
||||
writeln!(stdout, "- {C_LISTING}{name}\x1b[0m: {}", handle.with(*def))?
|
||||
|
||||
if let Some(imports) = h.imports() {
|
||||
writeln!(out, "- {C_LISTING}Imports:\x1b[0m")?;
|
||||
for (name, child) in imports {
|
||||
writeln!(
|
||||
out,
|
||||
" - {C_LISTING}{name}\x1b[0m ({child}): {}",
|
||||
h.with_id(*child)
|
||||
)?
|
||||
}
|
||||
}
|
||||
write!(stdout, "\x1b[0m")
|
||||
|
||||
// let Some(vis) = handle.vis() else {
|
||||
// return writeln!(stdout, "Invalid handle: {handle}");
|
||||
// };
|
||||
// writeln!(stdout, "{C_LISTING}{}\x1b[0m: {vis}{handle}", handle.id())?;
|
||||
// if let Some(parent) = handle.parent() {
|
||||
// }
|
||||
// if let Some(types) = handle.types() {
|
||||
// writeln!(stdout, "{C_LISTING}Types:\x1b[0m")?;
|
||||
// for (name, def) in types {
|
||||
// }
|
||||
// }
|
||||
// if let Some(values) = handle.values() {
|
||||
// writeln!(stdout, "{C_LISTING}Values:\x1b[0m")?;
|
||||
// for (name, def) in values {
|
||||
// writeln!(stdout, "- {C_LISTING}{name}\x1b[0m: {}", handle.with(*def))?
|
||||
// }
|
||||
// }
|
||||
// write!(stdout, "\x1b[0m")
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn inline_modules(code: cl_ast::File, path: impl AsRef<path::Path>) -> cl_ast::File {
|
||||
|
||||
Reference in New Issue
Block a user