many refactorings; unfucked lifetimes?
This commit is contained in:
parent
525ca2c8cb
commit
383f21fbd8
|
@ -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"
|
||||||
|
|
115
src/base.rs
115
src/base.rs
|
@ -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)]
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
123
src/main.rs
123
src/main.rs
|
@ -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 = *
|
||||||
|
|
||||||
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>())
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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),
|
||||||
|
|
Loading…
Reference in New Issue
Block a user