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"] }
|
||||
imbl = "3.0.0"
|
||||
struct_scalpel = "0.1.1"
|
||||
tailcall = "1.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>)> {
|
||||
vec![
|
||||
("add".to_string(), Value::Base(Base::Binary(add))),
|
||||
("and".to_string(), Value::Base(Base::Binary(and))),
|
||||
("append".to_string(), Value::Base(Base::Binary(append))),
|
||||
("assoc".to_string(), Value::Base(Base::Ternary(assoc))),
|
||||
("at".to_string(), Value::Base(Base::Binary(at))),
|
||||
("atan_2".to_string(), Value::Base(Base::Binary(atan_2))),
|
||||
("bool".to_string(), Value::Base(Base::Unary(r#bool))),
|
||||
("ceil".to_string(), Value::Base(Base::Unary(ceil))),
|
||||
("chars".to_string(), Value::Base(Base::Unary(chars))),
|
||||
("concat".to_string(), Value::Base(Base::Binary(concat))),
|
||||
("cos".to_string(), Value::Base(Base::Unary(cos))),
|
||||
("count".to_string(), Value::Base(Base::Unary(count))),
|
||||
("dec".to_string(), Value::Base(Base::Unary(dec))),
|
||||
("dissoc".to_string(), Value::Base(Base::Binary(dissoc))),
|
||||
("div".to_string(), Value::Base(Base::Binary(div))),
|
||||
("doc!".to_string(), Value::Base(Base::Unary(doc))),
|
||||
("downcase".to_string(), Value::Base(Base::Unary(downcase))),
|
||||
("eq?".to_string(), Value::Base(Base::Binary(eq))),
|
||||
("first".to_string(), Value::Base(Base::Unary(first))),
|
||||
("floor".to_string(), Value::Base(Base::Unary(floor))),
|
||||
("get".to_string(), Value::Base(Base::Binary(get))),
|
||||
("gt?".to_string(), Value::Base(Base::Binary(gt))),
|
||||
("gte?".to_string(), Value::Base(Base::Binary(gte))),
|
||||
("inc".to_string(), Value::Base(Base::Unary(inc))),
|
||||
("last".to_string(), Value::Base(Base::Unary(last))),
|
||||
("list".to_string(), Value::Base(Base::Unary(list))),
|
||||
("lt?".to_string(), Value::Base(Base::Binary(lt))),
|
||||
("lte?".to_string(), Value::Base(Base::Binary(lte))),
|
||||
("mod".to_string(), Value::Base(Base::Binary(r#mod))),
|
||||
("mult".to_string(), Value::Base(Base::Binary(mult))),
|
||||
("number".to_string(), Value::Base(Base::Unary(number))),
|
||||
("or".to_string(), Value::Base(Base::Binary(or))),
|
||||
("pi".to_string(), Value::Number(std::f64::consts::PI)),
|
||||
("print!".to_string(), Value::Base(Base::Unary(print))),
|
||||
("random".to_string(), Value::Base(Base::Nullary(random))),
|
||||
("range".to_string(), Value::Base(Base::Binary(range))),
|
||||
("rest".to_string(), Value::Base(Base::Unary(rest))),
|
||||
("round".to_string(), Value::Base(Base::Unary(round))),
|
||||
("show".to_string(), Value::Base(Base::Unary(show))),
|
||||
("sin".to_string(), Value::Base(Base::Unary(sin))),
|
||||
("slice".to_string(), Value::Base(Base::Ternary(slice))),
|
||||
("split".to_string(), Value::Base(Base::Binary(split))),
|
||||
("sqrt".to_string(), Value::Base(Base::Unary(sqrt))),
|
||||
(
|
||||
"sqrt_2".to_string(),
|
||||
Value::Number(std::f64::consts::SQRT_2),
|
||||
),
|
||||
("store!".to_string(), Value::Base(Base::Binary(store))),
|
||||
("sub".to_string(), Value::Base(Base::Binary(sub))),
|
||||
("tan".to_string(), Value::Base(Base::Unary(tan))),
|
||||
("trim".to_string(), Value::Base(Base::Unary(trim))),
|
||||
("triml".to_string(), Value::Base(Base::Unary(triml))),
|
||||
("trimr".to_string(), Value::Base(Base::Unary(trimr))),
|
||||
("type".to_string(), Value::Base(Base::Unary(r#type))),
|
||||
("unbox".to_string(), Value::Base(Base::Unary(unbox))),
|
||||
("upcase".to_string(), Value::Base(Base::Unary(upcase))),
|
||||
]
|
||||
let members = vec![
|
||||
("add", Value::Base(Base::Binary(add))),
|
||||
("and", Value::Base(Base::Binary(and))),
|
||||
("append", Value::Base(Base::Binary(append))),
|
||||
("assoc", Value::Base(Base::Ternary(assoc))),
|
||||
("at", Value::Base(Base::Binary(at))),
|
||||
("atan_2", Value::Base(Base::Binary(atan_2))),
|
||||
("bool", Value::Base(Base::Unary(r#bool))),
|
||||
("ceil", Value::Base(Base::Unary(ceil))),
|
||||
("chars", Value::Base(Base::Unary(chars))),
|
||||
("concat", Value::Base(Base::Binary(concat))),
|
||||
("cos", Value::Base(Base::Unary(cos))),
|
||||
("count", Value::Base(Base::Unary(count))),
|
||||
("dec", Value::Base(Base::Unary(dec))),
|
||||
("dissoc", Value::Base(Base::Binary(dissoc))),
|
||||
("div", Value::Base(Base::Binary(div))),
|
||||
("doc!", Value::Base(Base::Unary(doc))),
|
||||
("downcase", Value::Base(Base::Unary(downcase))),
|
||||
("eq?", Value::Base(Base::Binary(eq))),
|
||||
("first", Value::Base(Base::Unary(first))),
|
||||
("floor", Value::Base(Base::Unary(floor))),
|
||||
("get", Value::Base(Base::Binary(get))),
|
||||
("gt?", Value::Base(Base::Binary(gt))),
|
||||
("gte?", Value::Base(Base::Binary(gte))),
|
||||
("inc", Value::Base(Base::Unary(inc))),
|
||||
("last", Value::Base(Base::Unary(last))),
|
||||
("list", Value::Base(Base::Unary(list))),
|
||||
("lt?", Value::Base(Base::Binary(lt))),
|
||||
("lte?", Value::Base(Base::Binary(lte))),
|
||||
("mod", Value::Base(Base::Binary(r#mod))),
|
||||
("mult", Value::Base(Base::Binary(mult))),
|
||||
("number", Value::Base(Base::Unary(number))),
|
||||
("or", Value::Base(Base::Binary(or))),
|
||||
("pi", Value::Number(std::f64::consts::PI)),
|
||||
("print!", Value::Base(Base::Unary(print))),
|
||||
("random", Value::Base(Base::Nullary(random))),
|
||||
("range", Value::Base(Base::Binary(range))),
|
||||
("rest", Value::Base(Base::Unary(rest))),
|
||||
("round", Value::Base(Base::Unary(round))),
|
||||
("show", Value::Base(Base::Unary(show))),
|
||||
("sin", Value::Base(Base::Unary(sin))),
|
||||
("slice", Value::Base(Base::Ternary(slice))),
|
||||
("split", Value::Base(Base::Binary(split))),
|
||||
("sqrt", Value::Base(Base::Unary(sqrt))),
|
||||
("sqrt_2", Value::Number(std::f64::consts::SQRT_2)),
|
||||
("store!", Value::Base(Base::Binary(store))),
|
||||
("sub", Value::Base(Base::Binary(sub))),
|
||||
("tan", Value::Base(Base::Unary(tan))),
|
||||
("trim", Value::Base(Base::Unary(trim))),
|
||||
("triml", Value::Base(Base::Unary(triml))),
|
||||
("trimr", Value::Base(Base::Unary(trimr))),
|
||||
("type", Value::Base(Base::Unary(r#type))),
|
||||
("unbox", Value::Base(Base::Unary(unbox))),
|
||||
("upcase", Value::Base(Base::Unary(upcase))),
|
||||
];
|
||||
let pkg = Value::Dict(HashMap::from(members));
|
||||
vec![("base".to_string(), pkg)]
|
||||
}
|
||||
|
|
123
src/main.rs
123
src/main.rs
|
@ -37,7 +37,7 @@
|
|||
// * [ ] perf testing
|
||||
|
||||
use chumsky::{input::Stream, prelude::*};
|
||||
// use std::rc::Rc;
|
||||
use rust_embed::Embed;
|
||||
|
||||
mod spans;
|
||||
|
||||
|
@ -45,21 +45,88 @@ mod lexer;
|
|||
use crate::lexer::*;
|
||||
|
||||
mod value;
|
||||
// use crate::value::*;
|
||||
use crate::value::*;
|
||||
|
||||
mod parser;
|
||||
use crate::parser::*;
|
||||
|
||||
mod vm;
|
||||
use crate::vm::*;
|
||||
// mod vm;
|
||||
// use crate::vm::*;
|
||||
|
||||
mod base;
|
||||
use crate::base::*;
|
||||
|
||||
pub fn main() {
|
||||
let src = "
|
||||
let \"foo {bar} baz\" = \"foo bar baz\"
|
||||
";
|
||||
mod context;
|
||||
use crate::context::*;
|
||||
|
||||
#[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();
|
||||
if !lex_errs.is_empty() {
|
||||
println!("{:?}", lex_errs);
|
||||
|
@ -67,20 +134,42 @@ let \"foo {bar} baz\" = \"foo bar baz\"
|
|||
}
|
||||
let tokens = tokens.unwrap();
|
||||
let to_parse = tokens.clone();
|
||||
// for (token, _) in tokens {
|
||||
// println!("{}", token)
|
||||
// }
|
||||
let (ast, _) = parser()
|
||||
|
||||
let (ast, parse_errors) = parser()
|
||||
.parse(Stream::from_iter(to_parse).map((0..src.len()).into(), |(t, s)| (t, s)))
|
||||
.unwrap();
|
||||
// println!("{}", ast);
|
||||
.into_output_errors();
|
||||
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::<parser::Ast>();
|
||||
// println!("{}", std::mem::size_of::<parser::Ast>())
|
||||
|
|
|
@ -713,19 +713,6 @@ where
|
|||
(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
|
||||
.clone()
|
||||
.separated_by(terminators.clone())
|
||||
|
@ -746,8 +733,10 @@ where
|
|||
|
||||
let if_ = just(Token::Reserved("if"))
|
||||
.ignore_then(simple.clone())
|
||||
.then_ignore(terminators.clone().or_not())
|
||||
.then_ignore(just(Token::Reserved("then")))
|
||||
.then(expr.clone())
|
||||
.then_ignore(terminators.clone().or_not())
|
||||
.then_ignore(just(Token::Reserved("else")))
|
||||
.then(expr.clone())
|
||||
.map_with(|((condition, then_branch), else_branch), e| {
|
||||
|
@ -886,12 +875,25 @@ where
|
|||
.then(loop_multiclause.clone().or(fn_single_clause.clone()))
|
||||
.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(
|
||||
simple
|
||||
.clone()
|
||||
.or(conditional)
|
||||
.or(block)
|
||||
.or(lambda)
|
||||
.or(panic)
|
||||
.or(do_)
|
||||
.or(repeat)
|
||||
|
|
|
@ -236,7 +236,7 @@ pub fn match_clauses<'src>(
|
|||
pub fn apply<'src>(
|
||||
callee: Value<'src>,
|
||||
caller: Value<'src>,
|
||||
ctx: &mut Context<'src>,
|
||||
ctx: &mut Context,
|
||||
) -> Result<Value<'src>, LudusError> {
|
||||
match (callee, caller) {
|
||||
(Value::Keyword(kw), Value::Dict(dict)) => {
|
||||
|
@ -306,7 +306,7 @@ pub fn apply<'src>(
|
|||
|
||||
pub fn eval<'src, 'a>(
|
||||
ast: &'src Ast,
|
||||
ctx: &'a mut Context<'src>,
|
||||
ctx: &'a mut Vec<(String, Value<'src>)>,
|
||||
) -> Result<Value<'src>, LudusError> {
|
||||
match ast {
|
||||
Ast::Nil => Ok(Value::Nil),
|
||||
|
|
Loading…
Reference in New Issue
Block a user