Compare commits

...

2 Commits

Author SHA1 Message Date
Jesse Brault
6e37e3a5dd WIP bringing back name analysis. 2025-09-28 12:34:37 -05:00
Jesse Brault
cfe24aa107 More sketching of functor, list, and related. 2025-09-28 12:34:29 -05:00
14 changed files with 1466 additions and 1433 deletions

View File

@ -16,8 +16,8 @@ pub enum Either<L, R>
Right(R) Right(R)
end end
pub inst Functor[*T] for Option<T> pub impl Functor[*T] for Option<T>
impl fn <U> map(ftu: fn (t: T) -> U) -> Self<U> fn <U> map(ftu: fn (t: &*T) -> U) -> Self<U>
if self is Some(t) then if self is Some(t) then
Some(ftu(t)) Some(ftu(t))
else else
@ -26,20 +26,20 @@ pub inst Functor[*T] for Option<T>
end end
end end
pub inst Functor[*T] for Either<_, *T> pub impl Functor[*R] for Either<_, *R>
impl fn <U> map(ftu: fn (t: *T) -> U) -> Self<U> fn <U> map(f: fn (t: &*R) -> U) -> Self<_, U>
if self is Right(t) then if self is Right(t) then
Right(ftu(t)) Right(f(t))
else else
self self
end end
end end
end end
pub inst Functor[*L -> *R] for Either<L, R> pub impl Functor[*L -> *R] for Either<L, R>
impl fn mapLeft(flr: fn (l: *L) -> *R) -> Self<*L, *R> fn mapLeft(f: fn (l: &*L) -> *R) -> Self<*L, *R>
if self is Left(l) then if self is Left(l) then
Right(flr(l)) Right(f(l))
else else
self self
end end
@ -48,100 +48,53 @@ end
pub trait Monad[*T] pub trait Monad[*T]
static fn lift(t: *T) -> Self<*T> static fn lift(t: *T) -> Self<*T>
fn <U> flatMap(f: fn (t: *T) -> Self<U>) -> Self<U> fn <U> flatMap(f: fn (t: &*T) -> Self<U>) -> Self<U>
end end
pub trait Default pub trait Default
static fn default() -> Self static fn default() -> Self
end end
pub trait Empty[*T] where *T has Default pub trait Empty[*T]
static fn empty() -> Self<*T> static fn empty() -> Self<*T>
end end
pub trait Semigroup[*T] pub trait Semigroup[*T]
fn concat(other: &Self<*T>) -> Self<&*T> type Other<*T>
cons fn consConcat(other: Self<*T>) -> Self<*T>
fn concat(other: &Other<*T>) -> Self<&*T>
cons fn consConcat(other: Other<*T>) -> Self<*T>
end end
pub int Iterable<T> pub int Iterable<T>
fn iter() -> Iterator<T> fn iter() -> Iterator<T> ref self
cons fn consIter() -> ConsIterator<T> cons fn consIter() -> ConsIterator<T>
end end
pub int Iterator<T> pub int Iterator<T>
fn next() -> Option<&T> fn next() -> Option<&T ref self>
fn withIndex() -> Iterator<Option<(Int, &T)>>
end end
pub int ConsIterator<T> pub int ConsIterator<T>
fn next() -> Option<T> fn next() -> Option<T>
fn withIndex() -> Iterator<Option<(Int, T)>>
end end
pub int List<T> : Iterable<T> req Monad, Functor, Semigroup, Empty pub impl Semigroup[*T] for Iterable<*T>
fn add(t: T) -> Void type Other = Iterable<*T>
end
pub inst Functor[*T] for List<*T> where *T has Default fn concat(other: &Other<*T>) -> Self<*T>
impl fn <U> map(ftu: (t: *T) -> U) -> Self<U> let result: Self<*T> = ArrayList(count())
let mut result: Self<U> = Self::empty()
for t in self do for t in self do
result += Self::lift(ftu(t)) result.add(t)
end
for t in other do
result.add(t)
end end
result result
end end
end
pub class ArrayList<T> : List<T> cons fn consConcat(other: Other<*T>) -> Self<*T>
let result: Self<*T> = ArrayList(count())
let init: fn () -> T // ?: sugar for Option<fn () -> T>
let capacity: USize
let mut ts: Array<T>
let count: USize = 0
pub ctor(startCapacity: USize = 10, init: fn () -> T = Default::default) where T has Default
:= init
capacity = startCapacity // ?= sugar for Some(expr)
ts = array(startCapacity, init)
end
pub ctor(init: fn () -> T, startCapacity: USize = 10)
:= init
capacity = startCapacity
ts = array(startCapacity, init)
end
impl fn iter() -> Iterator<T>
todo()
end
impl fn add(t: T) -> Void
ts[count] = t
count++
if count == capacity then
resize()
end
end
fn resize() -> Void
let oldTs = mem::take(&ts, array(capacity * 2, init))
for (i, t) in oldTs.consIter().withIndex() do
ts[i] = t
end
end
end
pub inst Empty[*T] for ArrayList<*T>
where *T has Default
impl static fn empty() -> List<*T> = Self()
end
pub inst Semigroup[*T] for ArrayList<*T>
where *T has Default
impl fn concat(other: List<*T>) -> List<*T>
let result = Self()
for t in self do for t in self do
result.add(t) result.add(t)
end end
@ -152,18 +105,35 @@ pub inst Semigroup[*T] for ArrayList<*T>
end end
end end
pub inst Monad[*T] for ArrayList<*T> pub int List<T> : Iterable<T>
where T has Default fn add(t: T) -> Void
impl static fn lift(t: *T) -> List<*T> end
let result: List<*T> = Self()
pub impl Functor[*T] for List<*T>
fn <U> map(f: (t: &*T) -> U) -> Self<U>
let mut result: Self<U> = ArrayList(count())
for t in self do
result.add(f(t))
end
result
end
end
pub impl Empty[*T] for List<*T>
static fn empty() -> List<*T> = ArrayList()
end
pub inst Monad[*T] for List<*T>
static fn lift(t: *T) -> List<*T>
let result: List<*T> = ArrayList()
result.add(t) result.add(t)
result result
end end
impl fn <U> flatMap(f: fn (t: *T) -> List<U>) -> List<U> fn <U> flatMap(f: fn (t: &*T) -> List<U>) -> List<U>
let result: List<U> = Self() let result: List<U> = ArrayList(count())
for t in self do for t in self do
for u in f(t) do for u in f(t).consIter() do
result.add(u) result.add(u)
end end
end end
@ -171,6 +141,69 @@ pub inst Monad[*T] for ArrayList<*T>
end end
end end
pub class ArrayList<T> : List<T>
let capacity: USize
let mut ts: Array<Option<T>>
let count: USize = 0
pub ctor(startCapacity: USize = 10)
capacity = startCapacity
ts = array(startCapacity, None)
end
class ArrayListIterator<T>(owner: &ArrayList<T>) /* ref owner (implied by constructor) */ : Iterator<T>
let i: USize = 0
impl fn next() -> Option<&T ref self>
if owner.ts[i] is Some(t) then
i++
Some(t)
else
None
end
end
end
class ConsArrayListIterator<T>(ts: Array<Option<T>>) : ConsIterator<T>
let i: USize = 0
impl fn next() -> Option<T>
if ts[i] is Some then
let wrappedT = mem::take(ts[i], None)
i++
wrappedT
else
None
end
end
end
impl fn iter() -> Iterator<&T> ref self
ArrayListIterator(&self)
end
impl cons fn consIter() -> Iterator<T>
ConsArrayListIterator(mem::take(ts, arrays::empty()))
end
impl fn add(t: T) -> Void
ts[count] = Some(t)
count++
if count == capacity then
resize()
end
end
fn resize() -> Void
let oldTs = mem::take(&ts, array(capacity * 2, None))
for (i, wrappedT) in oldTs.consIter() do
ts[i] = wrappedT
end
end
end
pub mod std::core pub mod std::core
pub mod mem pub mod mem
@ -181,8 +214,8 @@ pub mod std::core
pub native fn <T> array(capacity: USize) -> Array<T> where T has Default pub native fn <T> array(capacity: USize) -> Array<T> where T has Default
pub fn <T> list(...items: Array<T>) -> List<T> where T has Default pub fn <T> list(...items: Array<T>) -> List<T>
let result = ArrayList(items.capacity(), Default[T]::default) let result = ArrayList(items.capacity())
for item in items.consIter() do for item in items.consIter() do
result.add(item) result.add(item)
end end
@ -191,8 +224,7 @@ pub mod std::core
end end
// other file // Other file
use std::collections::List
use std::hkt::{Functor[List], Monad[List]} use std::hkt::{Functor[List], Monad[List]}
fn main() fn main()

View File

@ -1,10 +1,10 @@
// mod name_analysis; mod name_analysis;
mod p3; mod p3;
// mod unparse; // mod unparse;
use std::path::PathBuf; use std::path::PathBuf;
// use crate::name_analysis::name_analysis; use crate::name_analysis::name_analysis;
use crate::p3::pretty_print_parse; use crate::p3::pretty_print_parse;
// use crate::unparse::unparse; // use crate::unparse::unparse;
use clap::{Parser, Subcommand}; use clap::{Parser, Subcommand};
@ -44,12 +44,12 @@ fn main() {
pretty_print_parse(&path) pretty_print_parse(&path)
} }
} }
// Commands::NameAnalysis { paths } => { Commands::NameAnalysis { paths } => {
// let result = name_analysis(&paths); let result = name_analysis(&paths);
// if let Err(e) = result { if let Err(e) = result {
// eprintln!("{}", e) eprintln!("{}", e)
// } }
// } }
_ => todo!(), _ => todo!(),
} }
} }

View File

@ -20,8 +20,7 @@ pub fn name_analysis(paths: &Vec<PathBuf>) -> Result<(), Box<dyn std::error::Err
match parse_result { match parse_result {
Ok(mut pairs) => { Ok(mut pairs) => {
let compilation_unit_pair = pairs.next().unwrap(); let compilation_unit = build_ast(file_id, &mut pairs);
let compilation_unit = build_ast(&path.display().to_string(), file_id, compilation_unit_pair);
compilation_units.push(compilation_unit); compilation_units.push(compilation_unit);
Ok::<(), Box<dyn std::error::Error>>(()) Ok::<(), Box<dyn std::error::Error>>(())
} }
@ -32,7 +31,10 @@ pub fn name_analysis(paths: &Vec<PathBuf>) -> Result<(), Box<dyn std::error::Err
let mut symbol_table = SymbolTable::new(); let mut symbol_table = SymbolTable::new();
add_std_core_symbols(&mut symbol_table).expect("Failed to add std::core symbols."); add_std_core_symbols(&mut symbol_table).expect("Failed to add std::core symbols.");
let diagnostics = analyze_names(&mut compilation_units, &mut symbol_table); let diagnostics = analyze_names(
&mut compilation_units.iter().map(Box::as_mut),
&mut symbol_table
);
if diagnostics.is_empty() { if diagnostics.is_empty() {
println!("Name analysis complete."); println!("Name analysis complete.");
println!("Symbol table\n-------\n{}", symbol_table); println!("Symbol table\n-------\n{}", symbol_table);

View File

@ -5,7 +5,7 @@ extern crate core;
pub mod ast; pub mod ast;
pub mod diagnostic; pub mod diagnostic;
pub mod module; pub mod module;
// pub mod name_analysis; pub mod name_analysis;
pub mod object_file; pub mod object_file;
pub mod parser; pub mod parser;
pub mod std_core; pub mod std_core;

1320
src/name_analysis/gather.rs Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -32,7 +32,7 @@ pub mod symbol;
pub mod symbol_table; pub mod symbol_table;
pub fn analyze_names( pub fn analyze_names(
compilation_units: &mut Vec<CompilationUnit>, compilation_units: &mut [CompilationUnit],
symbol_table: &mut SymbolTable, symbol_table: &mut SymbolTable,
) -> Vec<DmDiagnostic> { ) -> Vec<DmDiagnostic> {
let mut diagnostics = vec![]; let mut diagnostics = vec![];

View File

@ -1,11 +1,9 @@
use crate::ast::node::named::Named;
use crate::ast::node::*; use crate::ast::node::*;
use crate::diagnostic::DmDiagnostic; use crate::diagnostic::DmDiagnostic;
use crate::name_analysis::symbol::Symbol; use crate::name_analysis::symbol::Symbol;
use crate::name_analysis::symbol_table::{SymbolLookupError, SymbolTable}; use crate::name_analysis::symbol_table::{SymbolLookupError, SymbolTable};
use codespan_reporting::diagnostic::{Diagnostic, Label}; use codespan_reporting::diagnostic::{Diagnostic, Label};
use std::range::Range; use std::range::Range;
/* Type Use */
fn resolve_type_use( fn resolve_type_use(
type_use: &mut TypeUse, type_use: &mut TypeUse,

View File

@ -1,3 +1,4 @@
use crate::ast::node::Identifier;
use std::cell::RefCell; use std::cell::RefCell;
use std::fmt::{Debug, Display, Formatter}; use std::fmt::{Debug, Display, Formatter};
use std::ops::Deref; use std::ops::Deref;

View File

@ -1,14 +1,14 @@
// use crate::name_analysis::symbol::{FunctionSymbol, ParameterSymbol}; use crate::name_analysis::symbol::{FunctionSymbol, ParameterSymbol};
// use crate::name_analysis::symbol_table::{SymbolInsertError, SymbolTable}; use crate::name_analysis::symbol_table::{SymbolInsertError, SymbolTable};
//
// pub fn add_std_core_symbols(symbol_table: &mut SymbolTable) -> Result<(), SymbolInsertError> { pub fn add_std_core_symbols(symbol_table: &mut SymbolTable) -> Result<(), SymbolInsertError> {
// symbol_table.insert_function_symbol( symbol_table.insert_function_symbol(
// FunctionSymbol::new("std::core::println", "println", true, true, None) FunctionSymbol::new("std::core::println", "println", true, true, None)
// .with_parameters(vec![ParameterSymbol::new("msg", None)]), .with_parameters(vec![ParameterSymbol::new("msg", None)]),
// )?; )?;
// symbol_table.insert_function_symbol( symbol_table.insert_function_symbol(
// FunctionSymbol::new("std::core::print", "print", true, true, None) FunctionSymbol::new("std::core::print", "print", true, true, None)
// .with_parameters(vec![ParameterSymbol::new("msg", None)]), .with_parameters(vec![ParameterSymbol::new("msg", None)]),
// )?; )?;
// Ok(()) Ok(())
// } }