interpret: try out Ref == RcRefCell. Subject to change!
This commit is contained in:
parent
7e311cb0ef
commit
06bcb6b7c6
@ -164,7 +164,7 @@ pub const Builtins: &[Builtin] = &builtins![
|
|||||||
Ok(match list {
|
Ok(match list {
|
||||||
ConValue::Empty => 0,
|
ConValue::Empty => 0,
|
||||||
ConValue::String(s) => s.chars().count() as _,
|
ConValue::String(s) => s.chars().count() as _,
|
||||||
ConValue::Ref(r) => return len(env, slice::from_ref(r.as_ref())),
|
ConValue::Ref(r) => return len(env, slice::from_ref(&r.borrow())),
|
||||||
ConValue::Array(t) => t.len() as _,
|
ConValue::Array(t) => t.len() as _,
|
||||||
ConValue::Tuple(t) => t.len() as _,
|
ConValue::Tuple(t) => t.len() as _,
|
||||||
_ => Err(Error::TypeError)?,
|
_ => Err(Error::TypeError)?,
|
||||||
@ -331,9 +331,8 @@ pub const Math: &[Builtin] = &builtins![
|
|||||||
|
|
||||||
/// Does the opposite of `&`
|
/// Does the opposite of `&`
|
||||||
fn deref(tail) {
|
fn deref(tail) {
|
||||||
use std::rc::Rc;
|
|
||||||
Ok(match tail {
|
Ok(match tail {
|
||||||
ConValue::Ref(v) => Rc::as_ref(v).clone(),
|
ConValue::Ref(v) => v.take(),
|
||||||
_ => tail.clone(),
|
_ => tail.clone(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,30 @@ use super::{
|
|||||||
function::Function,
|
function::Function,
|
||||||
Callable, Environment,
|
Callable, Environment,
|
||||||
};
|
};
|
||||||
use std::{collections::HashMap, ops::*, rc::Rc};
|
use std::{cell::RefCell, collections::HashMap, ops::*, rc::Rc};
|
||||||
|
|
||||||
|
/*
|
||||||
|
A Value can be:
|
||||||
|
- A Primitive (Empty, isize, etc.)
|
||||||
|
- A Record (Array, Tuple, Struct)
|
||||||
|
- A Variant (discriminant, Value) pair
|
||||||
|
|
||||||
|
array [
|
||||||
|
10, // 0
|
||||||
|
20, // 1
|
||||||
|
]
|
||||||
|
|
||||||
|
tuple (
|
||||||
|
10, // 0
|
||||||
|
20, // 1
|
||||||
|
)
|
||||||
|
|
||||||
|
struct {
|
||||||
|
x: 10, // x => 0
|
||||||
|
y: 20, // y => 1
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
type Integer = isize;
|
type Integer = isize;
|
||||||
|
|
||||||
@ -30,7 +53,7 @@ pub enum ConValue {
|
|||||||
/// A string
|
/// A string
|
||||||
String(Sym),
|
String(Sym),
|
||||||
/// A reference
|
/// A reference
|
||||||
Ref(Rc<ConValue>),
|
Ref(Rc<RefCell<ConValue>>),
|
||||||
/// An Array
|
/// An Array
|
||||||
Array(Box<[ConValue]>),
|
Array(Box<[ConValue]>),
|
||||||
/// A tuple
|
/// A tuple
|
||||||
@ -57,6 +80,16 @@ impl ConValue {
|
|||||||
_ => Err(Error::TypeError)?,
|
_ => Err(Error::TypeError)?,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
pub fn TupleStruct(name: Sym, values: Box<[ConValue]>) -> Self {
|
||||||
|
Self::TupleStruct(Box::new((Sym::to_ref(&name), values)))
|
||||||
|
}
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
pub fn Struct(name: Sym, values: HashMap<Sym, ConValue>) -> Self {
|
||||||
|
Self::Struct(Box::new((name, values)))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn index(&self, index: &Self) -> IResult<ConValue> {
|
pub fn index(&self, index: &Self) -> IResult<ConValue> {
|
||||||
let Self::Int(index) = index else {
|
let Self::Int(index) = index else {
|
||||||
Err(Error::TypeError)?
|
Err(Error::TypeError)?
|
||||||
@ -333,3 +366,13 @@ impl std::fmt::Display for ConValue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub macro cvstruct (
|
||||||
|
$Name:ident {
|
||||||
|
$($member:ident : $expr:expr),*
|
||||||
|
}
|
||||||
|
) {{
|
||||||
|
let mut members = HashMap::new();
|
||||||
|
$(members.insert(stringify!($member).into(), ($expr).into());)*
|
||||||
|
ConValue::Struct(Box::new((stringify!($Name).into(), members)))
|
||||||
|
}}
|
||||||
|
@ -5,11 +5,10 @@
|
|||||||
//! meaningless to get a pointer to one, and would be undefined behavior to dereference a pointer to
|
//! meaningless to get a pointer to one, and would be undefined behavior to dereference a pointer to
|
||||||
//! one in any situation.
|
//! one in any situation.
|
||||||
|
|
||||||
use std::{borrow::Borrow, rc::Rc};
|
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use cl_ast::{ast_visitor::Visit, *};
|
use cl_ast::{ast_visitor::Visit, *};
|
||||||
use cl_structures::intern::interned::Interned;
|
use cl_structures::intern::interned::Interned;
|
||||||
|
use std::{borrow::Borrow, cell::RefCell, rc::Rc};
|
||||||
/// A work-in-progress tree walk interpreter for Conlang
|
/// A work-in-progress tree walk interpreter for Conlang
|
||||||
pub trait Interpret {
|
pub trait Interpret {
|
||||||
/// Interprets this thing in the given [`Environment`].
|
/// Interprets this thing in the given [`Environment`].
|
||||||
@ -371,7 +370,12 @@ mod assignment {
|
|||||||
for (name, value) in
|
for (name, value) in
|
||||||
pattern::substitution(pat, value).map_err(|_| Error::PatFailed(pat.clone().into()))?
|
pattern::substitution(pat, value).map_err(|_| Error::PatFailed(pat.clone().into()))?
|
||||||
{
|
{
|
||||||
*env.get_mut(*name)? = Some(value);
|
match env.get_mut(*name)? {
|
||||||
|
Some(ConValue::Ref(r)) => {
|
||||||
|
r.replace(value);
|
||||||
|
}
|
||||||
|
other => *other = Some(value),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -800,7 +804,7 @@ impl Interpret for AddrOf {
|
|||||||
match &expr.kind {
|
match &expr.kind {
|
||||||
ExprKind::Index(_) => todo!("AddrOf array index"),
|
ExprKind::Index(_) => todo!("AddrOf array index"),
|
||||||
ExprKind::Path(_) => todo!("Path traversal in addrof"),
|
ExprKind::Path(_) => todo!("Path traversal in addrof"),
|
||||||
_ => Ok(ConValue::Ref(Rc::new(expr.interpret(env)?))),
|
_ => Ok(ConValue::Ref(Rc::new(RefCell::new(expr.interpret(env)?)))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,10 +8,7 @@ use crate::{
|
|||||||
error::{Error, IResult},
|
error::{Error, IResult},
|
||||||
};
|
};
|
||||||
use cl_ast::{Literal, Pattern, Sym};
|
use cl_ast::{Literal, Pattern, Sym};
|
||||||
use std::{
|
use std::collections::{HashMap, VecDeque};
|
||||||
collections::{HashMap, VecDeque},
|
|
||||||
rc::Rc,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Gets the path variables in the given Pattern
|
/// Gets the path variables in the given Pattern
|
||||||
pub fn variables(pat: &Pattern) -> Vec<&Sym> {
|
pub fn variables(pat: &Pattern) -> Vec<&Sym> {
|
||||||
@ -126,7 +123,7 @@ pub fn append_sub<'pat>(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
(Pattern::Ref(_, pat), ConValue::Ref(r)) => append_sub(sub, pat, Rc::unwrap_or_clone(r)),
|
(Pattern::Ref(_, pat), ConValue::Ref(r)) => append_sub(sub, pat, r.borrow().clone()),
|
||||||
|
|
||||||
(Pattern::Array(patterns), ConValue::Array(values)) => {
|
(Pattern::Array(patterns), ConValue::Array(values)) => {
|
||||||
match rest_binding(sub, patterns, values.into_vec().into())? {
|
match rest_binding(sub, patterns, values.into_vec().into())? {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user