many refactorings; unfucked lifetimes?

This commit is contained in:
Scott Richmond 2024-12-08 23:33:02 -05:00
parent 525ca2c8cb
commit 383f21fbd8
5 changed files with 182 additions and 92 deletions

View File

@ -10,5 +10,5 @@ ariadne = { git = "https://github.com/zesterer/ariadne" }
chumsky = { git = "https://github.com/zesterer/chumsky", features = ["label"] } chumsky = { git = "https://github.com/zesterer/chumsky", features = ["label"] }
imbl = "3.0.0" imbl = "3.0.0"
struct_scalpel = "0.1.1" struct_scalpel = "0.1.1"
tailcall = "1.0.1"
ran = "2.0.1" ran = "2.0.1"
rust-embed = "8.5.0"

View File

@ -571,62 +571,61 @@ pub fn r#mod<'src>(x: &Value, y: &Value) -> Value<'src> {
} }
pub fn base<'src>() -> Vec<(String, Value<'src>)> { pub fn base<'src>() -> Vec<(String, Value<'src>)> {
vec![ let members = vec![
("add".to_string(), Value::Base(Base::Binary(add))), ("add", Value::Base(Base::Binary(add))),
("and".to_string(), Value::Base(Base::Binary(and))), ("and", Value::Base(Base::Binary(and))),
("append".to_string(), Value::Base(Base::Binary(append))), ("append", Value::Base(Base::Binary(append))),
("assoc".to_string(), Value::Base(Base::Ternary(assoc))), ("assoc", Value::Base(Base::Ternary(assoc))),
("at".to_string(), Value::Base(Base::Binary(at))), ("at", Value::Base(Base::Binary(at))),
("atan_2".to_string(), Value::Base(Base::Binary(atan_2))), ("atan_2", Value::Base(Base::Binary(atan_2))),
("bool".to_string(), Value::Base(Base::Unary(r#bool))), ("bool", Value::Base(Base::Unary(r#bool))),
("ceil".to_string(), Value::Base(Base::Unary(ceil))), ("ceil", Value::Base(Base::Unary(ceil))),
("chars".to_string(), Value::Base(Base::Unary(chars))), ("chars", Value::Base(Base::Unary(chars))),
("concat".to_string(), Value::Base(Base::Binary(concat))), ("concat", Value::Base(Base::Binary(concat))),
("cos".to_string(), Value::Base(Base::Unary(cos))), ("cos", Value::Base(Base::Unary(cos))),
("count".to_string(), Value::Base(Base::Unary(count))), ("count", Value::Base(Base::Unary(count))),
("dec".to_string(), Value::Base(Base::Unary(dec))), ("dec", Value::Base(Base::Unary(dec))),
("dissoc".to_string(), Value::Base(Base::Binary(dissoc))), ("dissoc", Value::Base(Base::Binary(dissoc))),
("div".to_string(), Value::Base(Base::Binary(div))), ("div", Value::Base(Base::Binary(div))),
("doc!".to_string(), Value::Base(Base::Unary(doc))), ("doc!", Value::Base(Base::Unary(doc))),
("downcase".to_string(), Value::Base(Base::Unary(downcase))), ("downcase", Value::Base(Base::Unary(downcase))),
("eq?".to_string(), Value::Base(Base::Binary(eq))), ("eq?", Value::Base(Base::Binary(eq))),
("first".to_string(), Value::Base(Base::Unary(first))), ("first", Value::Base(Base::Unary(first))),
("floor".to_string(), Value::Base(Base::Unary(floor))), ("floor", Value::Base(Base::Unary(floor))),
("get".to_string(), Value::Base(Base::Binary(get))), ("get", Value::Base(Base::Binary(get))),
("gt?".to_string(), Value::Base(Base::Binary(gt))), ("gt?", Value::Base(Base::Binary(gt))),
("gte?".to_string(), Value::Base(Base::Binary(gte))), ("gte?", Value::Base(Base::Binary(gte))),
("inc".to_string(), Value::Base(Base::Unary(inc))), ("inc", Value::Base(Base::Unary(inc))),
("last".to_string(), Value::Base(Base::Unary(last))), ("last", Value::Base(Base::Unary(last))),
("list".to_string(), Value::Base(Base::Unary(list))), ("list", Value::Base(Base::Unary(list))),
("lt?".to_string(), Value::Base(Base::Binary(lt))), ("lt?", Value::Base(Base::Binary(lt))),
("lte?".to_string(), Value::Base(Base::Binary(lte))), ("lte?", Value::Base(Base::Binary(lte))),
("mod".to_string(), Value::Base(Base::Binary(r#mod))), ("mod", Value::Base(Base::Binary(r#mod))),
("mult".to_string(), Value::Base(Base::Binary(mult))), ("mult", Value::Base(Base::Binary(mult))),
("number".to_string(), Value::Base(Base::Unary(number))), ("number", Value::Base(Base::Unary(number))),
("or".to_string(), Value::Base(Base::Binary(or))), ("or", Value::Base(Base::Binary(or))),
("pi".to_string(), Value::Number(std::f64::consts::PI)), ("pi", Value::Number(std::f64::consts::PI)),
("print!".to_string(), Value::Base(Base::Unary(print))), ("print!", Value::Base(Base::Unary(print))),
("random".to_string(), Value::Base(Base::Nullary(random))), ("random", Value::Base(Base::Nullary(random))),
("range".to_string(), Value::Base(Base::Binary(range))), ("range", Value::Base(Base::Binary(range))),
("rest".to_string(), Value::Base(Base::Unary(rest))), ("rest", Value::Base(Base::Unary(rest))),
("round".to_string(), Value::Base(Base::Unary(round))), ("round", Value::Base(Base::Unary(round))),
("show".to_string(), Value::Base(Base::Unary(show))), ("show", Value::Base(Base::Unary(show))),
("sin".to_string(), Value::Base(Base::Unary(sin))), ("sin", Value::Base(Base::Unary(sin))),
("slice".to_string(), Value::Base(Base::Ternary(slice))), ("slice", Value::Base(Base::Ternary(slice))),
("split".to_string(), Value::Base(Base::Binary(split))), ("split", Value::Base(Base::Binary(split))),
("sqrt".to_string(), Value::Base(Base::Unary(sqrt))), ("sqrt", Value::Base(Base::Unary(sqrt))),
( ("sqrt_2", Value::Number(std::f64::consts::SQRT_2)),
"sqrt_2".to_string(), ("store!", Value::Base(Base::Binary(store))),
Value::Number(std::f64::consts::SQRT_2), ("sub", Value::Base(Base::Binary(sub))),
), ("tan", Value::Base(Base::Unary(tan))),
("store!".to_string(), Value::Base(Base::Binary(store))), ("trim", Value::Base(Base::Unary(trim))),
("sub".to_string(), Value::Base(Base::Binary(sub))), ("triml", Value::Base(Base::Unary(triml))),
("tan".to_string(), Value::Base(Base::Unary(tan))), ("trimr", Value::Base(Base::Unary(trimr))),
("trim".to_string(), Value::Base(Base::Unary(trim))), ("type", Value::Base(Base::Unary(r#type))),
("triml".to_string(), Value::Base(Base::Unary(triml))), ("unbox", Value::Base(Base::Unary(unbox))),
("trimr".to_string(), Value::Base(Base::Unary(trimr))), ("upcase", Value::Base(Base::Unary(upcase))),
("type".to_string(), Value::Base(Base::Unary(r#type))), ];
("unbox".to_string(), Value::Base(Base::Unary(unbox))), let pkg = Value::Dict(HashMap::from(members));
("upcase".to_string(), Value::Base(Base::Unary(upcase))), vec![("base".to_string(), pkg)]
]
} }

View File

@ -37,7 +37,7 @@
// * [ ] perf testing // * [ ] perf testing
use chumsky::{input::Stream, prelude::*}; use chumsky::{input::Stream, prelude::*};
// use std::rc::Rc; use rust_embed::Embed;
mod spans; mod spans;
@ -45,21 +45,88 @@ mod lexer;
use crate::lexer::*; use crate::lexer::*;
mod value; mod value;
// use crate::value::*; use crate::value::*;
mod parser; mod parser;
use crate::parser::*; use crate::parser::*;
mod vm; // mod vm;
use crate::vm::*; // use crate::vm::*;
mod base; mod base;
use crate::base::*; use crate::base::*;
pub fn main() { mod context;
let src = " use crate::context::*;
let \"foo {bar} baz\" = \"foo bar baz\"
"; #[derive(Embed)]
#[folder = "assets/"]
struct Asset;
pub fn prelude<'src>() -> Context<'src> {
let prelude = Asset::get("prelude.ld").unwrap().data.into_owned();
// we know for sure Prelude should live through the whole run of the program
let leaked = Box::leak(Box::new(prelude));
let prelude = std::str::from_utf8(leaked).unwrap();
let (ptoks, perrs) = lexer().parse(prelude).into_output_errors();
if !perrs.is_empty() {
println!("Errors lexing Prelude");
println!("{:?}", perrs);
panic!();
}
let ptoks = ptoks.unwrap();
let (p_ast, perrs) = parser()
.parse(Stream::from_iter(ptoks).map((0..prelude.len()).into(), |(t, s)| (t, s)))
.into_output_errors();
if !perrs.is_empty() {
println!("Errors parsing Prelude");
println!("{:?}", perrs);
panic!();
}
let p_ast = Box::leak(Box::new(p_ast.unwrap().0));
let base_pkg = base();
let mut base_ctx = Context::<'src> {
locals: vec![],
ast: p_ast,
prelude: base_pkg,
prelude_ast: &Ast::Nil,
};
let prelude = base_ctx.eval();
let mut p_ctx = vec![];
match prelude {
Ok(Value::Dict(p_dict)) => {
for (key, value) in p_dict.iter() {
p_ctx.push((key.to_string(), value.clone()))
}
}
Ok(_) => {
println!("Bad Prelude export");
panic!();
}
Err(LErr { msg, .. }) => {
println!("Error running Prelude");
println!("{:?}", msg);
panic!();
}
};
Context {
locals: vec![],
ast: &Ast::Nil,
prelude: p_ctx,
prelude_ast: p_ast,
}
}
pub fn run(src: &'static str) {
let (tokens, lex_errs) = lexer().parse(src).into_output_errors(); let (tokens, lex_errs) = lexer().parse(src).into_output_errors();
if !lex_errs.is_empty() { if !lex_errs.is_empty() {
println!("{:?}", lex_errs); println!("{:?}", lex_errs);
@ -67,20 +134,42 @@ let \"foo {bar} baz\" = \"foo bar baz\"
} }
let tokens = tokens.unwrap(); let tokens = tokens.unwrap();
let to_parse = tokens.clone(); let to_parse = tokens.clone();
// for (token, _) in tokens {
// println!("{}", token) let (ast, parse_errors) = parser()
// }
let (ast, _) = parser()
.parse(Stream::from_iter(to_parse).map((0..src.len()).into(), |(t, s)| (t, s))) .parse(Stream::from_iter(to_parse).map((0..src.len()).into(), |(t, s)| (t, s)))
.unwrap(); .into_output_errors();
// println!("{}", ast); if !parse_errors.is_empty() {
println!("{:?}", parse_errors);
return;
}
let mut ctx = base(); let ast = ast.unwrap().0;
let result = eval(&ast, &mut ctx).unwrap(); let mut ctx = prelude();
ctx.ast = &ast;
println!("{}", result); let result = ctx.eval();
match result {
Ok(result) => println!("{}", result),
Err(LErr { msg, .. }) => println!("Errors!\n{}", msg),
}
}
pub fn main() {
let src = "
fn fib {
(1) -> 1
(2) -> 1
(n) -> add (
fib (dec (n))
fib (sub (n, 2))
)
}
fib (25)
";
run(src);
// struct_scalpel::print_dissection_info::<value::Value>() // struct_scalpel::print_dissection_info::<value::Value>()
// struct_scalpel::print_dissection_info::<parser::Ast>(); // struct_scalpel::print_dissection_info::<parser::Ast>();
// println!("{}", std::mem::size_of::<parser::Ast>()) // println!("{}", std::mem::size_of::<parser::Ast>())

View File

@ -713,19 +713,6 @@ where
(Ast::Recur(args), e.span()) (Ast::Recur(args), e.span())
}); });
simple.define(
synthetic
.or(recur)
.or(word)
.or(keyword)
.or(value)
.or(tuple.clone())
.or(list)
.or(dict)
.or(string)
.labelled("simple expression"),
);
let block = expr let block = expr
.clone() .clone()
.separated_by(terminators.clone()) .separated_by(terminators.clone())
@ -746,8 +733,10 @@ where
let if_ = just(Token::Reserved("if")) let if_ = just(Token::Reserved("if"))
.ignore_then(simple.clone()) .ignore_then(simple.clone())
.then_ignore(terminators.clone().or_not())
.then_ignore(just(Token::Reserved("then"))) .then_ignore(just(Token::Reserved("then")))
.then(expr.clone()) .then(expr.clone())
.then_ignore(terminators.clone().or_not())
.then_ignore(just(Token::Reserved("else"))) .then_ignore(just(Token::Reserved("else")))
.then(expr.clone()) .then(expr.clone())
.map_with(|((condition, then_branch), else_branch), e| { .map_with(|((condition, then_branch), else_branch), e| {
@ -886,12 +875,25 @@ where
.then(loop_multiclause.clone().or(fn_single_clause.clone())) .then(loop_multiclause.clone().or(fn_single_clause.clone()))
.map_with(|(init, body), e| (Ast::Loop(Box::new(init), body), e.span())); .map_with(|(init, body), e| (Ast::Loop(Box::new(init), body), e.span()));
simple.define(
synthetic
.or(recur)
.or(word)
.or(keyword)
.or(value)
.or(tuple.clone())
.or(list)
.or(dict)
.or(string)
.or(lambda.clone())
.labelled("simple expression"),
);
nonbinding.define( nonbinding.define(
simple simple
.clone() .clone()
.or(conditional) .or(conditional)
.or(block) .or(block)
.or(lambda)
.or(panic) .or(panic)
.or(do_) .or(do_)
.or(repeat) .or(repeat)

View File

@ -236,7 +236,7 @@ pub fn match_clauses<'src>(
pub fn apply<'src>( pub fn apply<'src>(
callee: Value<'src>, callee: Value<'src>,
caller: Value<'src>, caller: Value<'src>,
ctx: &mut Context<'src>, ctx: &mut Context,
) -> Result<Value<'src>, LudusError> { ) -> Result<Value<'src>, LudusError> {
match (callee, caller) { match (callee, caller) {
(Value::Keyword(kw), Value::Dict(dict)) => { (Value::Keyword(kw), Value::Dict(dict)) => {
@ -306,7 +306,7 @@ pub fn apply<'src>(
pub fn eval<'src, 'a>( pub fn eval<'src, 'a>(
ast: &'src Ast, ast: &'src Ast,
ctx: &'a mut Context<'src>, ctx: &'a mut Vec<(String, Value<'src>)>,
) -> Result<Value<'src>, LudusError> { ) -> Result<Value<'src>, LudusError> {
match ast { match ast {
Ast::Nil => Ok(Value::Nil), Ast::Nil => Ok(Value::Nil),