forked from Orchid/orchid
Backup commit before crunch
This commit is contained in:
4
src/external/bool/equals.rs
vendored
4
src/external/bool/equals.rs
vendored
@@ -34,12 +34,14 @@ externfn_impl!(Equals1, |this: &Self, x: ExprInst| {
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Equals0 { a: Literal, x: ExprInst }
|
||||
atomic_redirect!(Equals0, x);
|
||||
atomic_impl!(Equals0, |Self{ a, x }: &Self| {
|
||||
atomic_impl!(Equals0, |Self{ a, x }: &Self, _| {
|
||||
let eqls = with_lit(x, |l| Ok(match (a, l) {
|
||||
(Literal::Char(c1), Literal::Char(c2)) => c1 == c2,
|
||||
(Literal::Num(n1), Literal::Num(n2)) => n1 == n2,
|
||||
(Literal::Str(s1), Literal::Str(s2)) => s1 == s2,
|
||||
(Literal::Uint(i1), Literal::Uint(i2)) => i1 == i2,
|
||||
(Literal::Num(n1), Literal::Uint(u1)) => *n1 == (*u1 as f64),
|
||||
(Literal::Uint(u1), Literal::Num(n1)) => *n1 == (*u1 as f64),
|
||||
(_, _) => AssertionError::fail(x.clone(), "the expected type")?,
|
||||
}))?;
|
||||
Ok(Boolean::from(eqls).to_atom_cls())
|
||||
|
||||
2
src/external/bool/ifthenelse.rs
vendored
2
src/external/bool/ifthenelse.rs
vendored
@@ -22,7 +22,7 @@ externfn_impl!(IfThenElse1, |_: &Self, x: ExprInst| Ok(IfThenElse0{x}));
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct IfThenElse0{ x: ExprInst }
|
||||
atomic_redirect!(IfThenElse0, x);
|
||||
atomic_impl!(IfThenElse0, |this: &Self| {
|
||||
atomic_impl!(IfThenElse0, |this: &Self, _| {
|
||||
let Boolean(b) = this.x.clone().try_into()
|
||||
.map_err(|_| AssertionError::ext(this.x.clone(), "a boolean"))?;
|
||||
Ok(if b { Clause::Lambda {
|
||||
|
||||
4
src/external/bool/mod.rs
vendored
4
src/external/bool/mod.rs
vendored
@@ -9,6 +9,8 @@ use crate::{pipeline::ConstTree, interner::Interner};
|
||||
pub fn bool(i: &Interner) -> ConstTree {
|
||||
ConstTree::tree([
|
||||
(i.i("ifthenelse"), ConstTree::xfn(ifthenelse::IfThenElse1)),
|
||||
(i.i("equals"), ConstTree::xfn(equals::Equals2))
|
||||
(i.i("equals"), ConstTree::xfn(equals::Equals2)),
|
||||
(i.i("true"), ConstTree::atom(Boolean(true))),
|
||||
(i.i("false"), ConstTree::atom(Boolean(false)))
|
||||
])
|
||||
}
|
||||
2
src/external/conv/parse_float.rs
vendored
2
src/external/conv/parse_float.rs
vendored
@@ -24,7 +24,7 @@ externfn_impl!(ParseFloat1, |_: &Self, x: ExprInst| Ok(ParseFloat0{x}));
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ParseFloat0{ x: ExprInst }
|
||||
atomic_redirect!(ParseFloat0, x);
|
||||
atomic_impl!(ParseFloat0, |Self{ x }: &Self| {
|
||||
atomic_impl!(ParseFloat0, |Self{ x }: &Self, _| {
|
||||
let number = with_lit(x, |l| Ok(match l {
|
||||
Literal::Str(s) => {
|
||||
let parser = float_parser();
|
||||
|
||||
2
src/external/conv/parse_uint.rs
vendored
2
src/external/conv/parse_uint.rs
vendored
@@ -23,7 +23,7 @@ externfn_impl!(ParseUint1, |_: &Self, x: ExprInst| Ok(ParseUint0{x}));
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ParseUint0{ x: ExprInst }
|
||||
atomic_redirect!(ParseUint0, x);
|
||||
atomic_impl!(ParseUint0, |Self{ x }: &Self| {
|
||||
atomic_impl!(ParseUint0, |Self{ x }: &Self, _| {
|
||||
let uint = with_lit(x, |l| Ok(match l {
|
||||
Literal::Str(s) => {
|
||||
let parser = int_parser();
|
||||
|
||||
2
src/external/conv/to_string.rs
vendored
2
src/external/conv/to_string.rs
vendored
@@ -20,7 +20,7 @@ externfn_impl!(ToString1, |_: &Self, x: ExprInst| Ok(ToString0{x}));
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ToString0{ x: ExprInst }
|
||||
atomic_redirect!(ToString0, x);
|
||||
atomic_impl!(ToString0, |Self{ x }: &Self| {
|
||||
atomic_impl!(ToString0, |Self{ x }: &Self, _| {
|
||||
let string = with_lit(x, |l| Ok(match l {
|
||||
Literal::Char(c) => c.to_string(),
|
||||
Literal::Uint(i) => i.to_string(),
|
||||
|
||||
33
src/external/cpsio/debug.rs
vendored
Normal file
33
src/external/cpsio/debug.rs
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
use std::fmt::Debug;
|
||||
|
||||
use crate::foreign::{Atomic, AtomicReturn};
|
||||
use crate::interner::InternedDisplay;
|
||||
use crate::interpreter::Context;
|
||||
use crate::{externfn_impl, atomic_defaults};
|
||||
use crate::representations::interpreted::ExprInst;
|
||||
|
||||
/// Debug function
|
||||
///
|
||||
/// Next state: [Debug0]
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Debug2;
|
||||
externfn_impl!(Debug2, |_: &Self, x: ExprInst| Ok(Debug1{x}));
|
||||
|
||||
/// Partially applied Print function
|
||||
///
|
||||
/// Prev state: [Debug1]
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Debug1{ x: ExprInst }
|
||||
impl Atomic for Debug1 {
|
||||
atomic_defaults!();
|
||||
fn run(&self, ctx: Context) -> crate::foreign::AtomicResult {
|
||||
println!("{}", self.x.bundle(&ctx.interner));
|
||||
Ok(AtomicReturn{
|
||||
clause: self.x.expr().clause.clone(),
|
||||
gas: ctx.gas.map(|g| g - 1),
|
||||
inert: false
|
||||
})
|
||||
}
|
||||
}
|
||||
6
src/external/cpsio/mod.rs
vendored
6
src/external/cpsio/mod.rs
vendored
@@ -2,10 +2,14 @@ use crate::{interner::Interner, pipeline::ConstTree};
|
||||
|
||||
mod print;
|
||||
mod readline;
|
||||
mod debug;
|
||||
mod panic;
|
||||
|
||||
pub fn cpsio(i: &Interner) -> ConstTree {
|
||||
ConstTree::tree([
|
||||
(i.i("print"), ConstTree::xfn(print::Print2)),
|
||||
(i.i("readline"), ConstTree::xfn(readline::Readln2))
|
||||
(i.i("readline"), ConstTree::xfn(readline::Readln2)),
|
||||
(i.i("debug"), ConstTree::xfn(debug::Debug2)),
|
||||
(i.i("panic"), ConstTree::xfn(panic::Panic1))
|
||||
])
|
||||
}
|
||||
29
src/external/cpsio/panic.rs
vendored
Normal file
29
src/external/cpsio/panic.rs
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
use std::fmt::Display;
|
||||
|
||||
use crate::{atomic_impl, atomic_redirect, externfn_impl};
|
||||
use crate::external::litconv::with_str;
|
||||
use crate::representations::interpreted::ExprInst;
|
||||
use crate::foreign::ExternError;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Panic1;
|
||||
externfn_impl!(Panic1, |_: &Self, x: ExprInst| Ok(Panic0{ x }));
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Panic0{ x: ExprInst }
|
||||
atomic_redirect!(Panic0, x);
|
||||
atomic_impl!(Panic0, |Self{ x }: &Self, _| {
|
||||
with_str(x, |s| {
|
||||
Err(OrchidPanic(s.clone()).into_extern())
|
||||
})
|
||||
});
|
||||
|
||||
pub struct OrchidPanic(String);
|
||||
|
||||
impl Display for OrchidPanic {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "Orchid code panicked: {}", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl ExternError for OrchidPanic {}
|
||||
4
src/external/cpsio/print.rs
vendored
4
src/external/cpsio/print.rs
vendored
@@ -1,4 +1,5 @@
|
||||
use std::fmt::Debug;
|
||||
use std::io::{self, Write};
|
||||
use std::rc::Rc;
|
||||
|
||||
use crate::external::litconv::with_str;
|
||||
@@ -21,9 +22,10 @@ externfn_impl!(Print2, |_: &Self, x: ExprInst| Ok(Print1{x}));
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Print1{ x: ExprInst }
|
||||
atomic_redirect!(Print1, x);
|
||||
atomic_impl!(Print1, |Self{ x }: &Self| {
|
||||
atomic_impl!(Print1, |Self{ x }: &Self, _| {
|
||||
with_str(x, |s| {
|
||||
print!("{}", s);
|
||||
io::stdout().flush().unwrap();
|
||||
Ok(Clause::Lambda {
|
||||
args: Some(PathSet{ steps: Rc::new(vec![]), next: None }),
|
||||
body: Clause::LambdaArg.wrap()
|
||||
|
||||
2
src/external/cpsio/readline.rs
vendored
2
src/external/cpsio/readline.rs
vendored
@@ -21,7 +21,7 @@ externfn_impl!(Readln2, |_: &Self, x: ExprInst| Ok(Readln1{x}));
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Readln1{ x: ExprInst }
|
||||
atomic_redirect!(Readln1, x);
|
||||
atomic_impl!(Readln1, |Self{ x }: &Self| {
|
||||
atomic_impl!(Readln1, |Self{ x }: &Self, _| {
|
||||
let mut buf = String::new();
|
||||
stdin().read_line(&mut buf)
|
||||
.map_err(|e| RuntimeError::ext(e.to_string(), "reading from stdin"))?;
|
||||
|
||||
2
src/external/num/numeric.rs
vendored
2
src/external/num/numeric.rs
vendored
@@ -48,7 +48,7 @@ impl Sub for Numeric {
|
||||
|
||||
fn sub(self, rhs: Self) -> Self::Output {
|
||||
match (self, rhs) {
|
||||
(Numeric::Uint(a), Numeric::Uint(b)) if b < a => Numeric::Uint(a - b),
|
||||
(Numeric::Uint(a), Numeric::Uint(b)) if b <= a => Numeric::Uint(a - b),
|
||||
(Numeric::Uint(a), Numeric::Uint(b))
|
||||
=> Numeric::num(a as f64 - b as f64),
|
||||
(Numeric::Num(a), Numeric::Num(b)) => Numeric::num(a - b),
|
||||
|
||||
7
src/external/num/operators/add.rs
vendored
7
src/external/num/operators/add.rs
vendored
@@ -9,7 +9,6 @@ use crate::representations::interpreted::ExprInst;
|
||||
/// Add function
|
||||
///
|
||||
/// Next state: [Add1]
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Add2;
|
||||
externfn_impl!(Add2, |_: &Self, x: ExprInst| Ok(Add1{x}));
|
||||
@@ -17,7 +16,6 @@ externfn_impl!(Add2, |_: &Self, x: ExprInst| Ok(Add1{x}));
|
||||
/// Partially applied Add function
|
||||
///
|
||||
/// Prev state: [Add2]; Next state: [Add0]
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Add1{ x: ExprInst }
|
||||
atomic_redirect!(Add1, x);
|
||||
@@ -30,11 +28,12 @@ externfn_impl!(Add1, |this: &Self, x: ExprInst| {
|
||||
/// Fully applied Add function.
|
||||
///
|
||||
/// Prev state: [Add1]
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Add0 { a: Numeric, x: ExprInst }
|
||||
atomic_redirect!(Add0, x);
|
||||
atomic_impl!(Add0, |Self{ a, x }: &Self| {
|
||||
atomic_impl!(Add0, |Self{ a, x }: &Self, _| {
|
||||
let b: Numeric = x.clone().try_into()?;
|
||||
Ok((*a + b).into())
|
||||
});
|
||||
|
||||
|
||||
|
||||
2
src/external/num/operators/divide.rs
vendored
2
src/external/num/operators/divide.rs
vendored
@@ -34,7 +34,7 @@ externfn_impl!(Divide1, |this: &Self, x: ExprInst| {
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Divide0 { a: Numeric, x: ExprInst }
|
||||
atomic_redirect!(Divide0, x);
|
||||
atomic_impl!(Divide0, |Self{ a, x }: &Self| {
|
||||
atomic_impl!(Divide0, |Self{ a, x }: &Self, _| {
|
||||
let b: Numeric = x.clone().try_into()?;
|
||||
Ok((*a / b).into())
|
||||
});
|
||||
2
src/external/num/operators/multiply.rs
vendored
2
src/external/num/operators/multiply.rs
vendored
@@ -34,7 +34,7 @@ externfn_impl!(Multiply1, |this: &Self, x: ExprInst| {
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Multiply0 { a: Numeric, x: ExprInst }
|
||||
atomic_redirect!(Multiply0, x);
|
||||
atomic_impl!(Multiply0, |Self{ a, x }: &Self| {
|
||||
atomic_impl!(Multiply0, |Self{ a, x }: &Self, _| {
|
||||
let b: Numeric = x.clone().try_into()?;
|
||||
Ok((*a * b).into())
|
||||
});
|
||||
2
src/external/num/operators/remainder.rs
vendored
2
src/external/num/operators/remainder.rs
vendored
@@ -34,7 +34,7 @@ externfn_impl!(Remainder1, |this: &Self, x: ExprInst| {
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Remainder0 { a: Numeric, x: ExprInst }
|
||||
atomic_redirect!(Remainder0, x);
|
||||
atomic_impl!(Remainder0, |Self{ a, x }: &Self| {
|
||||
atomic_impl!(Remainder0, |Self{ a, x }: &Self, _| {
|
||||
let b: Numeric = x.clone().try_into()?;
|
||||
Ok((*a % b).into())
|
||||
});
|
||||
2
src/external/num/operators/subtract.rs
vendored
2
src/external/num/operators/subtract.rs
vendored
@@ -34,7 +34,7 @@ externfn_impl!(Subtract1, |this: &Self, x: ExprInst| {
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Subtract0 { a: Numeric, x: ExprInst }
|
||||
atomic_redirect!(Subtract0, x);
|
||||
atomic_impl!(Subtract0, |Self{ a, x }: &Self| {
|
||||
atomic_impl!(Subtract0, |Self{ a, x }: &Self, _| {
|
||||
let b: Numeric = x.clone().try_into()?;
|
||||
Ok((*a - b).into())
|
||||
});
|
||||
2
src/external/str/char_at.rs
vendored
2
src/external/str/char_at.rs
vendored
@@ -33,7 +33,7 @@ externfn_impl!(CharAt1, |this: &Self, x: ExprInst| {
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct CharAt0 { s: String, x: ExprInst }
|
||||
atomic_redirect!(CharAt0, x);
|
||||
atomic_impl!(CharAt0, |Self{ s, x }: &Self| {
|
||||
atomic_impl!(CharAt0, |Self{ s, x }: &Self, _| {
|
||||
with_uint(x, |i| if let Some(c) = s.chars().nth(i as usize) {
|
||||
Ok(Clause::P(Primitive::Literal(Literal::Char(c))))
|
||||
} else {
|
||||
|
||||
2
src/external/str/concatenate.rs
vendored
2
src/external/str/concatenate.rs
vendored
@@ -32,7 +32,7 @@ externfn_impl!(Concatenate1, |this: &Self, c: ExprInst| {
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Concatenate0 { a: String, c: ExprInst }
|
||||
atomic_redirect!(Concatenate0, c);
|
||||
atomic_impl!(Concatenate0, |Self{ a, c }: &Self| {
|
||||
atomic_impl!(Concatenate0, |Self{ a, c }: &Self, _| {
|
||||
with_str(c, |b| Ok(Clause::P(Primitive::Literal(
|
||||
Literal::Str(a.to_owned() + b)
|
||||
))))
|
||||
|
||||
@@ -39,7 +39,7 @@ use std::fmt::Debug;
|
||||
#[macro_export]
|
||||
macro_rules! atomic_impl {
|
||||
($typ:ident) => {
|
||||
atomic_impl!{$typ, |this: &Self| {
|
||||
atomic_impl!{$typ, |this: &Self, _: $crate::interpreter::Context| {
|
||||
use $crate::foreign::ExternFn;
|
||||
Ok(this.clone().to_xfn_cls())
|
||||
}}
|
||||
@@ -64,7 +64,7 @@ macro_rules! atomic_impl {
|
||||
>::from((self, state));
|
||||
// branch off or wrap up
|
||||
let clause = if inert {
|
||||
match ($next_phase)(&next_self) {
|
||||
match ($next_phase)(&next_self, ctx) {
|
||||
Ok(r) => r,
|
||||
Err(e) => return Err(
|
||||
$crate::interpreter::RuntimeError::Extern(e)
|
||||
|
||||
@@ -82,7 +82,10 @@ pub fn apply(
|
||||
(new_xpr.clause.clone(), (ctx.gas.map(|x| x - 1), false))
|
||||
} else {(body.expr().clause.clone(), (ctx.gas, false))}),
|
||||
Clause::Constant(name) => {
|
||||
let symval = ctx.symbols.get(name).expect("missing symbol for function").clone();
|
||||
let symval = if let Some(sym) = ctx.symbols.get(name) {sym.clone()}
|
||||
else { panic!("missing symbol for function {}",
|
||||
ctx.interner.extern_vec(*name).join("::")
|
||||
)};
|
||||
Ok((Clause::Apply { f: symval, x, }, (ctx.gas, false)))
|
||||
}
|
||||
Clause::P(Primitive::Atom(atom)) => { // take a step in expanding atom
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
use hashbrown::HashMap;
|
||||
|
||||
use crate::representations::interpreted::ExprInst;
|
||||
use crate::interner::Token;
|
||||
use crate::interner::{Token, Interner};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Context<'a> {
|
||||
pub symbols: &'a HashMap<Token<Vec<Token<String>>>, ExprInst>,
|
||||
pub interner: &'a Interner,
|
||||
pub gas: Option<usize>,
|
||||
}
|
||||
|
||||
|
||||
@@ -66,8 +66,8 @@ fn namespace_parser<'a>(
|
||||
.ignore_then(filter_map_lex(enum_filter!(Lexeme::Name)))
|
||||
.then(
|
||||
any().repeated().delimited_by(
|
||||
Lexeme::LP('{').parser(),
|
||||
Lexeme::RP('{').parser()
|
||||
Lexeme::LP('(').parser(),
|
||||
Lexeme::RP('(').parser()
|
||||
).try_map(move |body, _| {
|
||||
split_lines(&body)
|
||||
.map(|l| line.parse(l))
|
||||
@@ -120,6 +120,7 @@ pub fn line_parser<'a>(ctx: impl Context + 'a)
|
||||
pub fn split_lines(data: &[Entry]) -> impl Iterator<Item = &[Entry]> {
|
||||
let mut source = data.iter().enumerate();
|
||||
let mut last_slice = 0;
|
||||
let mut finished = false;
|
||||
iter::from_fn(move || {
|
||||
let mut paren_count = 0;
|
||||
while let Some((i, Entry{ lexeme, .. })) = source.next() {
|
||||
@@ -134,6 +135,11 @@ pub fn split_lines(data: &[Entry]) -> impl Iterator<Item = &[Entry]> {
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
// Include last line even without trailing newline
|
||||
if !finished {
|
||||
finished = true;
|
||||
return Some(&data[last_slice..])
|
||||
}
|
||||
None
|
||||
}).filter(|s| s.len() > 0)
|
||||
}
|
||||
|
||||
@@ -6,6 +6,20 @@ use crate::{utils::Substack, interner::{Token, Interner}, pipeline::{ProjectModu
|
||||
|
||||
use super::{alias_map::AliasMap, decls::InjectedAsFn};
|
||||
|
||||
fn resolve(
|
||||
token: Token<Vec<Token<String>>>,
|
||||
alias_map: &AliasMap,
|
||||
i: &Interner,
|
||||
) -> Option<Vec<Token<String>>> {
|
||||
if let Some(alias) = alias_map.resolve(token) {
|
||||
Some(i.r(alias).clone())
|
||||
} else if let Some((foot, body)) = i.r(token).split_last() {
|
||||
let mut new_beginning = resolve(i.i(body), alias_map, i)?;
|
||||
new_beginning.push(*foot);
|
||||
Some(new_beginning)
|
||||
} else {None}
|
||||
}
|
||||
|
||||
fn process_expr(
|
||||
expr: &Expr,
|
||||
alias_map: &AliasMap,
|
||||
@@ -14,9 +28,15 @@ fn process_expr(
|
||||
) -> Expr {
|
||||
expr.map_names(&|n| {
|
||||
injected_as(&i.r(n)[..]).or_else(|| {
|
||||
alias_map.resolve(n).map(|n| {
|
||||
injected_as(&i.r(n)[..]).unwrap_or(n)
|
||||
})
|
||||
let next_v = resolve(n, alias_map, i)?;
|
||||
// println!("Resolved alias {} to {}",
|
||||
// i.extern_vec(n).join("::"),
|
||||
// i.extern_all(&next_v).join("::")
|
||||
// );
|
||||
Some(
|
||||
injected_as(&next_v)
|
||||
.unwrap_or_else(|| i.i(&next_v))
|
||||
)
|
||||
})
|
||||
}).unwrap_or_else(|| expr.clone())
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
use std::rc::Rc;
|
||||
|
||||
use itertools::Itertools;
|
||||
|
||||
use crate::interner::Interner;
|
||||
use crate::pipeline::error::ProjectError;
|
||||
use crate::pipeline::project_tree::ProjectTree;
|
||||
@@ -23,6 +25,14 @@ pub fn resolve_imports(
|
||||
&project, &mut map,
|
||||
i, injected_as
|
||||
)?;
|
||||
println!("Aliases: {{{:?}}}",
|
||||
map.targets.iter()
|
||||
.map(|(kt, vt)| format!("{} => {}",
|
||||
i.extern_vec(*kt).join("::"),
|
||||
i.extern_vec(*vt).join("::")
|
||||
))
|
||||
.join(", ")
|
||||
);
|
||||
let new_mod = apply_aliases(project.0.as_ref(), &map, i, injected_as);
|
||||
Ok(ProjectTree(Rc::new(new_mod)))
|
||||
}
|
||||
@@ -39,7 +39,7 @@ pub fn parse_layer<'a>(
|
||||
))
|
||||
};
|
||||
let source = source_loader::load_source(
|
||||
targets, i, loader, &|path| injected_as(path).is_some()
|
||||
targets, prelude, i, loader, &|path| injected_as(path).is_some()
|
||||
)?;
|
||||
let tree = project_tree::build_tree(source, i, prelude, &injected_names)?;
|
||||
let sum = ProjectTree(Rc::new(
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use std::rc::Rc;
|
||||
|
||||
use hashbrown::HashMap;
|
||||
use itertools::Itertools;
|
||||
|
||||
use crate::pipeline::error::ProjectError;
|
||||
use crate::interner::{Token, Interner};
|
||||
@@ -138,6 +139,11 @@ fn source_to_module(
|
||||
_ => None,
|
||||
})
|
||||
.collect::<HashMap<_, _>>();
|
||||
// println!(
|
||||
// "Constructing file-module {} with members ({})",
|
||||
// i.extern_all(&path_v[..]).join("::"),
|
||||
// exports.keys().map(|t| i.r(*t)).join(", ")
|
||||
// );
|
||||
Rc::new(Module {
|
||||
imports,
|
||||
items,
|
||||
@@ -174,10 +180,15 @@ fn files_to_module(
|
||||
(namespace, ModEntry{ exported: true, member })
|
||||
})
|
||||
.collect::<HashMap<_, _>>();
|
||||
let exports = items.keys()
|
||||
let exports: HashMap<_, _> = items.keys()
|
||||
.copied()
|
||||
.map(|name| (name, i.i(&pushed(&path_v, name))))
|
||||
.collect();
|
||||
// println!(
|
||||
// "Constructing module {} with items ({})",
|
||||
// i.extern_all(&path_v[..]).join("::"),
|
||||
// exports.keys().map(|t| i.r(*t)).join(", ")
|
||||
// );
|
||||
Rc::new(Module{
|
||||
items,
|
||||
imports: vec![],
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
use std::println;
|
||||
use std::rc::Rc;
|
||||
|
||||
use hashbrown::HashSet;
|
||||
use itertools::Itertools;
|
||||
|
||||
use crate::representations::tree::WalkErrorKind;
|
||||
use crate::pipeline::source_loader::LoadedSourceTable;
|
||||
@@ -30,7 +32,13 @@ pub fn collect_exported_ops(
|
||||
i: &Interner,
|
||||
injected: &impl InjectedOperatorsFn
|
||||
) -> OpsResult {
|
||||
if let Some(i) = injected(path) {return Ok(i)}
|
||||
if let Some(ops) = injected(path) {
|
||||
if path == i.i(&[i.i("prelude")][..]) {
|
||||
println!("%%% Prelude exported ops %%%");
|
||||
println!("{}", ops.iter().map(|t| i.r(*t)).join(", "));
|
||||
}
|
||||
return Ok(ops)
|
||||
}
|
||||
let is_file = |n: &[Token<String>]| loaded.contains_key(&i.i(n));
|
||||
let path_s = &i.r(path)[..];
|
||||
let name_split = split_name(path_s, &is_file);
|
||||
@@ -59,11 +67,15 @@ pub fn collect_exported_ops(
|
||||
.collect()
|
||||
}.rc(),
|
||||
})?;
|
||||
Ok(Rc::new(module.items.iter()
|
||||
let out: HashSet<_> = module.items.iter()
|
||||
.filter(|(_, v)| v.exported)
|
||||
.map(|(k, _)| *k)
|
||||
.collect()
|
||||
))
|
||||
.collect();
|
||||
if path == i.i(&[i.i("prelude")][..]) {
|
||||
println!("%%% Prelude exported ops %%%");
|
||||
println!("{}", out.iter().map(|t| i.r(*t)).join(", "));
|
||||
}
|
||||
Ok(Rc::new(out))
|
||||
}
|
||||
|
||||
pub fn mk_cache<'a>(
|
||||
@@ -71,5 +83,7 @@ pub fn mk_cache<'a>(
|
||||
i: &'a Interner,
|
||||
injected: &'a impl InjectedOperatorsFn,
|
||||
) -> ExportedOpsCache<'a> {
|
||||
Cache::new(|path, _this| collect_exported_ops(path, loaded, i, injected))
|
||||
Cache::new(|path, _this| {
|
||||
collect_exported_ops(path, loaded, i, injected)
|
||||
})
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
use std::rc::Rc;
|
||||
|
||||
use hashbrown::HashSet;
|
||||
use itertools::Itertools;
|
||||
|
||||
use crate::parse::is_op;
|
||||
use crate::pipeline::error::ProjectError;
|
||||
@@ -34,9 +35,11 @@ pub fn collect_ops_for(
|
||||
) -> OpsResult {
|
||||
let tree = &loaded[&i.i(file)].preparsed.0;
|
||||
let mut ret = HashSet::new();
|
||||
println!("collecting ops for {}", i.extern_all(file).join("::"));
|
||||
tree_all_ops(tree.as_ref(), &mut ret);
|
||||
tree.visit_all_imports(&mut |modpath, module, import| {
|
||||
if let Some(n) = import.name { ret.insert(n); } else {
|
||||
println!("\tglob import from {}", i.extern_vec(import.path).join("::"));
|
||||
let path = import_abs_path(
|
||||
&file, modpath, module, &i.r(import.path)[..], i
|
||||
).expect("This error should have been caught during loading");
|
||||
@@ -45,5 +48,9 @@ pub fn collect_ops_for(
|
||||
Ok::<_, Rc<dyn ProjectError>>(())
|
||||
})?;
|
||||
ret.drain_filter(|t| !is_op(i.r(*t)));
|
||||
if file == &[i.i("map")][..] {
|
||||
println!(" %%% ops in map %%% ");
|
||||
println!("{}", ret.iter().map(|t| i.r(*t)).join(", "))
|
||||
}
|
||||
Ok(Rc::new(ret))
|
||||
}
|
||||
@@ -5,7 +5,7 @@ use hashbrown::HashMap;
|
||||
use crate::representations::tree::{ModEntry, ModMember, Module};
|
||||
use crate::representations::Primitive;
|
||||
use crate::representations::location::Location;
|
||||
use crate::foreign::ExternFn;
|
||||
use crate::foreign::{ExternFn, Atomic, Atom};
|
||||
use crate::interner::{Token, Interner};
|
||||
use crate::ast::{Expr, Clause};
|
||||
use crate::utils::{Substack, pushed};
|
||||
@@ -17,12 +17,18 @@ pub enum ConstTree {
|
||||
Tree(HashMap<Token<String>, ConstTree>)
|
||||
}
|
||||
impl ConstTree {
|
||||
pub fn xfn(xfn: impl ExternFn + 'static) -> Self {
|
||||
pub fn primitive(primitive: Primitive) -> Self {
|
||||
Self::Const(Expr{
|
||||
location: Location::Unknown,
|
||||
value: Clause::P(Primitive::ExternFn(Box::new(xfn)))
|
||||
value: Clause::P(primitive)
|
||||
})
|
||||
}
|
||||
pub fn xfn(xfn: impl ExternFn + 'static) -> Self {
|
||||
Self::primitive(Primitive::ExternFn(Box::new(xfn)))
|
||||
}
|
||||
pub fn atom(atom: impl Atomic + 'static) -> Self {
|
||||
Self::primitive(Primitive::Atom(Atom(Box::new(atom))))
|
||||
}
|
||||
pub fn tree(
|
||||
arr: impl IntoIterator<Item = (Token<String>, Self)>
|
||||
) -> Self {
|
||||
|
||||
@@ -7,6 +7,7 @@ use crate::pipeline::split_name::split_name;
|
||||
use crate::interner::{Token, Interner};
|
||||
|
||||
use crate::pipeline::file_loader::{Loaded, load_text, IOResult};
|
||||
use crate::representations::sourcefile::FileEntry;
|
||||
use super::loaded_source::{LoadedSourceTable, LoadedSource};
|
||||
use super::preparse::preparse;
|
||||
|
||||
@@ -15,6 +16,7 @@ use super::preparse::preparse;
|
||||
fn load_abs_path_rec(
|
||||
abs_path: Token<Vec<Token<String>>>,
|
||||
table: &mut LoadedSourceTable,
|
||||
prelude: &[FileEntry],
|
||||
i: &Interner,
|
||||
get_source: &impl Fn(Token<Vec<Token<String>>>) -> IOResult,
|
||||
is_injected: &impl Fn(&[Token<String>]) -> bool
|
||||
@@ -39,7 +41,7 @@ fn load_abs_path_rec(
|
||||
.chain(iter::once(i.i(item)))
|
||||
.collect::<Vec<_>>();
|
||||
load_abs_path_rec(
|
||||
i.i(&abs_subpath), table, i, get_source, is_injected
|
||||
i.i(&abs_subpath), table, prelude, i, get_source, is_injected
|
||||
)?
|
||||
}
|
||||
return Ok(());
|
||||
@@ -48,7 +50,7 @@ fn load_abs_path_rec(
|
||||
let text = load_text(i.i(filename), &get_source, i)?;
|
||||
let preparsed = preparse(
|
||||
filename.iter().map(|t| i.r(*t)).cloned().collect(),
|
||||
text.as_str(), i
|
||||
text.as_str(), prelude, i
|
||||
)?;
|
||||
table.insert(abs_path, LoadedSource{ text, preparsed: preparsed.clone() });
|
||||
// recurse on all imported modules
|
||||
@@ -58,7 +60,9 @@ fn load_abs_path_rec(
|
||||
module, &import.nonglob_path(i), i
|
||||
)?;
|
||||
// recurse on imported module
|
||||
load_abs_path_rec(i.i(&abs_pathv), table, i, get_source, is_injected)
|
||||
load_abs_path_rec(
|
||||
i.i(&abs_pathv), table, prelude, i, get_source, is_injected
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -66,6 +70,7 @@ fn load_abs_path_rec(
|
||||
/// imports that aren't injected.
|
||||
pub fn load_source(
|
||||
targets: &[Token<Vec<Token<String>>>],
|
||||
prelude: &[FileEntry],
|
||||
i: &Interner,
|
||||
get_source: &impl Fn(Token<Vec<Token<String>>>) -> IOResult,
|
||||
is_injected: &impl Fn(&[Token<String>]) -> bool,
|
||||
@@ -75,6 +80,7 @@ pub fn load_source(
|
||||
load_abs_path_rec(
|
||||
*target,
|
||||
&mut table,
|
||||
prelude,
|
||||
i, get_source, is_injected
|
||||
)?
|
||||
}
|
||||
|
||||
@@ -38,23 +38,27 @@ fn add_export<K: Eq + Hash>(
|
||||
}
|
||||
|
||||
/// Convert source lines into a module
|
||||
fn to_module(src: &[FileEntry], i: &Interner) -> Rc<Module<(), ()>>
|
||||
{
|
||||
let imports = imports(src.iter()).cloned().collect::<Vec<_>>();
|
||||
let mut items = src.iter().filter_map(|ent| match ent {
|
||||
fn to_module(
|
||||
src: &[FileEntry],
|
||||
prelude: &[FileEntry],
|
||||
i: &Interner
|
||||
) -> Rc<Module<(), ()>> {
|
||||
let all_src = || src.iter().chain(prelude.iter());
|
||||
let imports = imports(all_src()).cloned().collect::<Vec<_>>();
|
||||
let mut items = all_src().filter_map(|ent| match ent {
|
||||
FileEntry::Internal(Member::Namespace(name, data)) => {
|
||||
let member = ModMember::Sub(to_module(data, i));
|
||||
let member = ModMember::Sub(to_module(data, prelude, i));
|
||||
let entry = ModEntry{ exported: false, member };
|
||||
Some((*name, entry))
|
||||
}
|
||||
FileEntry::Exported(Member::Namespace(name, data)) => {
|
||||
let member = ModMember::Sub(to_module(data, i));
|
||||
let member = ModMember::Sub(to_module(data, prelude, i));
|
||||
let entry = ModEntry{ exported: true, member };
|
||||
Some((*name, entry))
|
||||
}
|
||||
_ => None
|
||||
}).collect::<HashMap<_, _>>();
|
||||
for file_entry in src { match file_entry {
|
||||
for file_entry in all_src() { match file_entry {
|
||||
FileEntry::Comment(_) | FileEntry::Import(_)
|
||||
| FileEntry::Internal(Member::Namespace(..))
|
||||
| FileEntry::Exported(Member::Namespace(..)) => (),
|
||||
@@ -83,8 +87,12 @@ fn to_module(src: &[FileEntry], i: &Interner) -> Rc<Module<(), ()>>
|
||||
|
||||
/// Preparse the module. At this stage, only the imports and
|
||||
/// names defined by the module can be parsed
|
||||
pub fn preparse(file: Vec<String>, source: &str, i: &Interner)
|
||||
-> Result<Preparsed, Rc<dyn ProjectError>> {
|
||||
pub fn preparse(
|
||||
file: Vec<String>,
|
||||
source: &str,
|
||||
prelude: &[FileEntry],
|
||||
i: &Interner,
|
||||
) -> Result<Preparsed, Rc<dyn ProjectError>> {
|
||||
// Parse with no operators
|
||||
let ctx = ParsingContext::<&str>::new(&[], i, Rc::new(file.clone()));
|
||||
let entries = parse::parse(source, ctx)
|
||||
@@ -98,5 +106,5 @@ pub fn preparse(file: Vec<String>, source: &str, i: &Interner)
|
||||
namespace: ns.into_iter().map(|t| i.r(t)).cloned().collect(),
|
||||
file: Rc::new(file.clone())
|
||||
}.rc())?;
|
||||
Ok(Preparsed(to_module(&normalized, i)))
|
||||
Ok(Preparsed(to_module(&normalized, prelude, i)))
|
||||
}
|
||||
@@ -8,6 +8,7 @@ pub fn any_match<'a>(matcher: &AnyMatcher, seq: &'a [Expr])
|
||||
match matcher {
|
||||
AnyMatcher::Scalar(scalv) => scalv_match(scalv, seq),
|
||||
AnyMatcher::Vec{ left, mid, right } => {
|
||||
if seq.len() < left.len() + right.len() {return None};
|
||||
let left_split = left.len();
|
||||
let right_split = seq.len() - right.len();
|
||||
let mut state = scalv_match(left, &seq[..left_split])?;
|
||||
|
||||
@@ -28,24 +28,26 @@ 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=> (
|
||||
export do { ...$statement ; ...$rest:1 } =0x2p543=> (
|
||||
statement (...$statement) do { ...$rest }
|
||||
)
|
||||
export do { ...$return } =10_000=> (...$return)
|
||||
export do { ...$return } =0x1p543=> (...$return)
|
||||
|
||||
export statement (let $name = ...$value) ...$next =10_000=> (
|
||||
export statement (let $name = ...$value) ...$next =0x1p1000=> (
|
||||
(\$name. ...$next) (...$value)
|
||||
)
|
||||
export statement (cps $name = ...$operation) ...$next =10_001=> (
|
||||
export statement (cps $name = ...$operation) ...$next =0x2p1000=> (
|
||||
(...$operation) \$name. ...$next
|
||||
)
|
||||
export statement (cps ...$operation) ...$next =10_000=> (
|
||||
export statement (cps ...$operation) ...$next =0x1p1000=> (
|
||||
(...$operation) (...$next)
|
||||
)
|
||||
|
||||
export if ...$cond then ...$true else ...$false:1 =5_000=> (
|
||||
export if ...$cond then ...$true else ...$false:1 =0x1p320=> (
|
||||
ifthenelse (...$cond) (...$true) (...$false)
|
||||
)
|
||||
|
||||
export ::(,)
|
||||
"#;
|
||||
|
||||
fn prelude_path(i: &Interner) -> Token<Vec<Token<String>>>
|
||||
@@ -100,7 +102,7 @@ pub fn run_dir(dir: &Path) {
|
||||
rule.bundle(&i)
|
||||
)
|
||||
});
|
||||
println!("Repo dump: {}", repo.bundle(&i));
|
||||
// println!("Repo dump: {}", repo.bundle(&i));
|
||||
let mut exec_table = HashMap::new();
|
||||
for (name, source) in consts.iter() {
|
||||
// let nval = entrypoint(&i); let name = &nval; let source = &consts[name];
|
||||
@@ -125,6 +127,7 @@ pub fn run_dir(dir: &Path) {
|
||||
println!("macro execution complete");
|
||||
let ctx = interpreter::Context {
|
||||
symbols: &exec_table,
|
||||
interner: &i,
|
||||
gas: None
|
||||
};
|
||||
let entrypoint = exec_table.get(&entrypoint(&i))
|
||||
|
||||
Reference in New Issue
Block a user