cl-ast: Cleanup
- Function bind is now one Pattern - TyRef now allows &Ty (i.e. &[i32], &(char, bool) - Range patterns (they cannot bind, only check whether a value is in range - ArrayRep repeat has been reverted to usize, for now, until early consteval is implemented.
This commit is contained in:
@@ -57,9 +57,6 @@ impl Callable for Function {
|
||||
let FnDecl { name, bind, body, sign: _ } = &*self.decl;
|
||||
|
||||
// Check arg mapping
|
||||
if args.len() != bind.len() {
|
||||
return Err(Error::ArgNumber(bind.len(), args.len()));
|
||||
}
|
||||
if self.is_constructor {
|
||||
return Ok(ConValue::TupleStruct(Box::new((
|
||||
name.to_ref(),
|
||||
@@ -73,14 +70,10 @@ impl Callable for Function {
|
||||
let upvars = self.upvars.take();
|
||||
env.push_frame("upvars", upvars);
|
||||
|
||||
eprintln!("{name}{args:?}");
|
||||
|
||||
// TODO: completely refactor data storage
|
||||
let mut frame = env.frame("fn args");
|
||||
for (bind, value) in bind.iter().zip(args) {
|
||||
for (name, value) in pattern::substitution(bind, value.clone())? {
|
||||
frame.insert(*name, Some(value));
|
||||
}
|
||||
for (name, value) in pattern::substitution(bind, ConValue::Tuple(args.into()))? {
|
||||
frame.insert(*name, Some(value));
|
||||
}
|
||||
let res = body.interpret(&mut frame);
|
||||
drop(frame);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//! Collects the "Upvars" of a function at the point of its creation, allowing variable capture
|
||||
use crate::{convalue::ConValue, env::Environment};
|
||||
use cl_ast::{ast_visitor::visit::*, Function, Let, Path, PathPart, Pattern, Sym};
|
||||
use cl_ast::{Function, Let, Path, PathPart, Pattern, Sym, ast_visitor::visit::*};
|
||||
use std::collections::{HashMap, HashSet};
|
||||
|
||||
pub fn collect_upvars(f: &Function, env: &Environment) -> super::Upvars {
|
||||
@@ -67,7 +67,7 @@ impl<'a> Visit<'a> for CollectUpvars<'_> {
|
||||
fn visit_function(&mut self, f: &'a cl_ast::Function) {
|
||||
let Function { name: _, sign: _, bind, body } = f;
|
||||
// parameters can never be upvars
|
||||
bind.iter().for_each(|pat| self.visit_pattern(pat));
|
||||
self.visit_pattern(bind);
|
||||
if let Some(body) = body {
|
||||
self.visit_expr(body);
|
||||
}
|
||||
@@ -115,6 +115,8 @@ impl<'a> Visit<'a> for CollectUpvars<'_> {
|
||||
self.visit_mutability(mutability);
|
||||
self.visit_pattern(pattern);
|
||||
}
|
||||
Pattern::RangeExc(_, _) => {}
|
||||
Pattern::RangeInc(_, _) => {}
|
||||
Pattern::Tuple(patterns) => {
|
||||
patterns.iter().for_each(|p| self.visit_pattern(p));
|
||||
}
|
||||
|
||||
@@ -134,11 +134,12 @@ impl Interpret for Struct {
|
||||
.into(),
|
||||
),
|
||||
},
|
||||
bind: args
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(idx, _)| Pattern::Name(idx.to_string().into()))
|
||||
.collect(),
|
||||
bind: Pattern::Tuple(
|
||||
args.iter()
|
||||
.enumerate()
|
||||
.map(|(idx, _)| Pattern::Name(idx.to_string().into()))
|
||||
.collect(),
|
||||
),
|
||||
body: None,
|
||||
};
|
||||
let constructor = crate::function::Function::new_constructor(constructor);
|
||||
@@ -814,12 +815,8 @@ impl Interpret for Array {
|
||||
impl Interpret for ArrayRep {
|
||||
fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
|
||||
let Self { value, repeat } = self;
|
||||
let repeat = match repeat.interpret(env)? {
|
||||
ConValue::Int(v) => v,
|
||||
_ => Err(Error::TypeError())?,
|
||||
};
|
||||
let value = value.interpret(env)?;
|
||||
Ok(ConValue::Array(vec![value; repeat as usize].into()))
|
||||
Ok(ConValue::Array(vec![value; *repeat].into()))
|
||||
}
|
||||
}
|
||||
impl Interpret for AddrOf {
|
||||
|
||||
@@ -20,6 +20,8 @@ pub fn variables(pat: &Pattern) -> Vec<&Sym> {
|
||||
Pattern::Rest(Some(pattern)) => patvars(set, pattern),
|
||||
Pattern::Rest(None) => {}
|
||||
Pattern::Ref(_, pattern) => patvars(set, pattern),
|
||||
Pattern::RangeExc(_, _) => {}
|
||||
Pattern::RangeInc(_, _) => {}
|
||||
Pattern::Tuple(patterns) | Pattern::Array(patterns) => {
|
||||
patterns.iter().for_each(|pat| patvars(set, pat))
|
||||
}
|
||||
@@ -127,6 +129,70 @@ pub fn append_sub<'pat>(
|
||||
todo!("Dereference <{r}> in pattern matching {pat}")
|
||||
}
|
||||
|
||||
(Pattern::RangeExc(head, tail), value) => match (head.as_ref(), tail.as_ref(), value) {
|
||||
(
|
||||
Pattern::Literal(Literal::Int(a)),
|
||||
Pattern::Literal(Literal::Int(c)),
|
||||
ConValue::Int(b),
|
||||
) => (*a as isize <= b as _ && b < *c as isize)
|
||||
.then_some(())
|
||||
.ok_or(Error::NotAssignable()),
|
||||
(
|
||||
Pattern::Literal(Literal::Char(a)),
|
||||
Pattern::Literal(Literal::Char(c)),
|
||||
ConValue::Char(b),
|
||||
) => (*a <= b && b < *c)
|
||||
.then_some(())
|
||||
.ok_or(Error::NotAssignable()),
|
||||
(
|
||||
Pattern::Literal(Literal::Float(a)),
|
||||
Pattern::Literal(Literal::Float(c)),
|
||||
ConValue::Float(b),
|
||||
) => (f64::from_bits(*a) <= b && b < f64::from_bits(*c))
|
||||
.then_some(())
|
||||
.ok_or(Error::NotAssignable()),
|
||||
(
|
||||
Pattern::Literal(Literal::String(a)),
|
||||
Pattern::Literal(Literal::String(c)),
|
||||
ConValue::String(b),
|
||||
) => (a.as_str() <= b.to_ref() && b.to_ref() < c.as_str())
|
||||
.then_some(())
|
||||
.ok_or(Error::NotAssignable()),
|
||||
_ => Err(Error::NotAssignable()),
|
||||
},
|
||||
|
||||
(Pattern::RangeInc(head, tail), value) => match (head.as_ref(), tail.as_ref(), value) {
|
||||
(
|
||||
Pattern::Literal(Literal::Int(a)),
|
||||
Pattern::Literal(Literal::Int(c)),
|
||||
ConValue::Int(b),
|
||||
) => (*a as isize <= b && b <= *c as isize)
|
||||
.then_some(())
|
||||
.ok_or(Error::NotAssignable()),
|
||||
(
|
||||
Pattern::Literal(Literal::Char(a)),
|
||||
Pattern::Literal(Literal::Char(c)),
|
||||
ConValue::Char(b),
|
||||
) => (*a <= b && b <= *c)
|
||||
.then_some(())
|
||||
.ok_or(Error::NotAssignable()),
|
||||
(
|
||||
Pattern::Literal(Literal::Float(a)),
|
||||
Pattern::Literal(Literal::Float(c)),
|
||||
ConValue::Float(b),
|
||||
) => (f64::from_bits(*a) <= b && b <= f64::from_bits(*c))
|
||||
.then_some(())
|
||||
.ok_or(Error::NotAssignable()),
|
||||
(
|
||||
Pattern::Literal(Literal::String(a)),
|
||||
Pattern::Literal(Literal::String(c)),
|
||||
ConValue::String(b),
|
||||
) => (a.as_str() <= b.to_ref() && b.to_ref() <= c.as_str())
|
||||
.then_some(())
|
||||
.ok_or(Error::NotAssignable()),
|
||||
_ => Err(Error::NotAssignable()),
|
||||
},
|
||||
|
||||
(Pattern::Array(patterns), ConValue::Array(values)) => {
|
||||
match rest_binding(sub, patterns, values.into_vec().into())? {
|
||||
Some((pattern, values)) => {
|
||||
|
||||
Reference in New Issue
Block a user