start testing, fixing
This commit is contained in:
parent
d48a787447
commit
ec38bcdc8c
30
src/main.rs
30
src/main.rs
|
@ -38,6 +38,7 @@
|
|||
|
||||
use chumsky::{input::Stream, prelude::*};
|
||||
use rust_embed::Embed;
|
||||
use std::collections::HashMap;
|
||||
|
||||
mod spans;
|
||||
|
||||
|
@ -135,7 +136,7 @@ pub fn run(src: &'static str) {
|
|||
let tokens = tokens.unwrap();
|
||||
let to_parse = tokens.clone();
|
||||
|
||||
let (ast, parse_errors) = parser()
|
||||
let (parse_result, parse_errors) = parser()
|
||||
.parse(Stream::from_iter(to_parse).map((0..src.len()).into(), |(t, s)| (t, s)))
|
||||
.into_output_errors();
|
||||
if !parse_errors.is_empty() {
|
||||
|
@ -143,22 +144,31 @@ pub fn run(src: &'static str) {
|
|||
return;
|
||||
}
|
||||
|
||||
let ast = ast.unwrap().0;
|
||||
let (ast, span) = parse_result.unwrap();
|
||||
|
||||
let mut ctx = prelude();
|
||||
ctx.ast = *
|
||||
let dummy_prelude = vec![];
|
||||
|
||||
let result = ctx.eval();
|
||||
let mut valxor = validator::Validator::new(&ast, span, &dummy_prelude);
|
||||
|
||||
match result {
|
||||
Ok(result) => println!("{}", result),
|
||||
Err(LErr { msg, .. }) => println!("Errors!\n{}", msg),
|
||||
}
|
||||
valxor.validate();
|
||||
|
||||
dbg!(valxor);
|
||||
|
||||
// let mut ctx = prelude();
|
||||
// ctx.ast = *
|
||||
|
||||
// let result = ctx.eval();
|
||||
|
||||
// match result {
|
||||
// Ok(result) => println!("{}", result),
|
||||
// Err(LErr { msg, .. }) => println!("Errors!\n{}", msg),
|
||||
// }
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
let src = "
|
||||
add (1, 2)
|
||||
box foo = 42
|
||||
foo
|
||||
";
|
||||
run(src);
|
||||
// struct_scalpel::print_dissection_info::<value::Value>()
|
||||
|
|
|
@ -49,7 +49,7 @@ pub struct Validator<'a> {
|
|||
}
|
||||
|
||||
impl<'a> Validator<'a> {
|
||||
fn new(ast: &'a mut Ast, span: Span, prelude: &'a Vec<String>) -> Validator<'a> {
|
||||
pub fn new(ast: &'a Ast, span: Span, prelude: &'a Vec<String>) -> Validator<'a> {
|
||||
Validator {
|
||||
locals: vec![],
|
||||
prelude,
|
||||
|
@ -99,13 +99,15 @@ impl<'a> Validator<'a> {
|
|||
self.status.used_bindings.push(name);
|
||||
}
|
||||
|
||||
fn validate(&mut self) {
|
||||
pub fn validate(&mut self) {
|
||||
let root = self.ast;
|
||||
match root {
|
||||
Ast::Error => unreachable!(),
|
||||
Ast::Word(name) | Ast::Splat(name) => {
|
||||
if !self.resolved(name) {
|
||||
self.err(format!("unbound name {name}"))
|
||||
self.err(format!("unbound name `{name}`"))
|
||||
} else {
|
||||
self.use_name(name.to_string())
|
||||
}
|
||||
}
|
||||
Ast::Interpolated(parts) => {
|
||||
|
@ -113,7 +115,9 @@ impl<'a> Validator<'a> {
|
|||
if let (StringPart::Word(name), span) = part {
|
||||
self.span = *span;
|
||||
if !self.resolved(name.as_str()) {
|
||||
self.err(format!("unbound name {name}"))
|
||||
self.err(format!("unbound name `{name}`"));
|
||||
} else {
|
||||
self.use_name(name.to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -276,14 +280,26 @@ impl<'a> Validator<'a> {
|
|||
Ast::Box(name, boxed) => {
|
||||
if self.bound(name).is_some() {
|
||||
self.err(format!("box name `{name}` is already bound"));
|
||||
} else {
|
||||
self.bind(name.to_string());
|
||||
}
|
||||
let (expr, span) = boxed.as_ref();
|
||||
self.ast = expr;
|
||||
self.span = *span;
|
||||
self.validate();
|
||||
}
|
||||
Ast::Let(lhs, rhs) => todo!(),
|
||||
Ast::Match(scrutinee, clauses) => todo!(),
|
||||
Ast::Let(lhs, rhs) => {
|
||||
let (expr, span) = rhs.as_ref();
|
||||
self.ast = expr;
|
||||
self.span = *span;
|
||||
self.validate();
|
||||
}
|
||||
Ast::Match(scrutinee, clauses) => {
|
||||
let (expr, span) = scrutinee.as_ref();
|
||||
self.ast = expr;
|
||||
self.span = *span;
|
||||
self.validate();
|
||||
}
|
||||
|
||||
Ast::FnDeclaration(name) => {
|
||||
let tailpos = self.status.tail_position;
|
||||
|
@ -312,10 +328,17 @@ impl<'a> Validator<'a> {
|
|||
// add clause arity to arities
|
||||
}
|
||||
|
||||
// this should be right
|
||||
// we can't bind anything that's already bound,
|
||||
// even in arg names
|
||||
// so anything that is already bound and used
|
||||
// will, of necessity, be closed over
|
||||
// we don't want to try to close over locals in functions
|
||||
let mut closed_over = HashSet::new();
|
||||
|
||||
for binding in self.status.used_bindings.iter().skip(from) {
|
||||
closed_over.insert(binding.clone());
|
||||
if self.bound(binding.as_str()).is_some() {
|
||||
closed_over.insert(binding.clone());
|
||||
}
|
||||
}
|
||||
|
||||
let info = FnInfo::Defined(arities, closed_over);
|
||||
|
@ -361,14 +384,29 @@ impl<'a> Validator<'a> {
|
|||
let in_loop = self.status.in_loop;
|
||||
self.status.in_loop = true;
|
||||
|
||||
let (expr, span) = body;
|
||||
self.span = span;
|
||||
self.expr = expr;
|
||||
self.validate();
|
||||
// let (expr, span) = body;
|
||||
// self.span = span;
|
||||
// self.expr = expr;
|
||||
// self.validate();
|
||||
|
||||
self.status.in_loop = in_loop;
|
||||
}
|
||||
Ast::Recur(args) => {}
|
||||
Ast::Recur(args) => {
|
||||
if !self.status.in_loop {
|
||||
self.err("you may only use `recur` in a loop form".to_string());
|
||||
}
|
||||
if !self.status.tail_position {
|
||||
self.err("you may only use `recur` in tail position".to_string());
|
||||
}
|
||||
|
||||
self.status.tail_position = false;
|
||||
for arg in args {
|
||||
let (expr, span) = arg;
|
||||
self.ast = expr;
|
||||
self.span = *span;
|
||||
self.validate();
|
||||
}
|
||||
}
|
||||
// terminals can never be invalid
|
||||
Ast::Nil | Ast::Boolean(_) | Ast::Number(_) | Ast::Keyword(_) | Ast::String(_) => (),
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue
Block a user