// an implementation of Ludus // curently left undone (and not adding for a while yet): // * sets // * interpolated strings & string patterns // * pkgs, namespaces, imports, `use` forms // * with forms // * test forms // * ignored words // todo: // * [x] rewrite fn parser to use chumsky::Recursive::declare/define // - [x] do this to extract/simplify/DRY things like tuple patterns, fn clauses, etc. // * [x] Work around chumsky::Stream::from_iter().spanned disappearing in most recent version // * [x] investigate using labels (which is behind a compiler flag, somehow) // * [ ] wire up Ariadne parsing errors // * [ ] validation // * [x] break this out into multiple files // * [x] write a tree-walk VM // - [x] learn how to deal with lifetimes // - [x] with stack mechanics and refcounting // - [ ] with tail-call optimization (nb: this may not be possible w/ a TW-VM) // - [ ] with all the necessary forms for current Ludus // * [ ] guards in match clauses // * [ ] `as` patterns // * [ ] splat patterns in tuples, lists, dicts // * [ ] splats in list and dict literals // * [ ] `loop` and `recur` // * [~] write `base` in Rust // * [ ] turn this into a library function // * [ ] compile this into WASM // * [ ] perf testing use chumsky::{input::Stream, prelude::*}; use std::rc::Rc; mod spans; mod lexer; use crate::lexer::*; mod value; use crate::value::*; mod parser; use crate::parser::*; mod vm; use crate::vm::*; mod base; use crate::base::*; pub fn main() { let src = " "; let (tokens, lex_errs) = lexer().parse(src).into_output_errors(); if lex_errs.len() > 0 { println!("{:?}", lex_errs); return (); } let tokens = tokens.unwrap(); let to_parse = tokens.clone(); // for (token, _) in tokens { // println!("{}", token) // } let (ast, _) = parser() .parse(Stream::from_iter(to_parse).map((0..src.len()).into(), |(t, s)| (t, s))) .unwrap(); // println!("{}", ast); let mut ctx = base(); let result = eval(&ast, &mut ctx).unwrap(); println!("{}", result); }