some simple bytecodes!
This commit is contained in:
parent
86aea78c21
commit
eff2ed90d5
|
@ -1,47 +0,0 @@
|
|||
use crate::compiler::Chunk;
|
||||
use crate::parser::Ast;
|
||||
use crate::spans::Spanned;
|
||||
use imbl::{HashMap, Vector};
|
||||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct LBox {
|
||||
pub name: usize,
|
||||
pub cell: RefCell<Value>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct LFn {
|
||||
pub name: &'static str,
|
||||
pub body: Vec<Spanned<Ast>>,
|
||||
pub doc: Option<&'static str>,
|
||||
pub enclosing: Vec<(usize, Value)>,
|
||||
pub has_run: bool,
|
||||
pub input: &'static str,
|
||||
pub src: &'static str,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum Value {
|
||||
Nil,
|
||||
Boolean(bool),
|
||||
Keyword(usize), // use an idx, rather than a raw index
|
||||
Interned(usize),
|
||||
FnDecl(usize),
|
||||
String(Rc<String>),
|
||||
Number(f64),
|
||||
List(Box<Vector<Value>>),
|
||||
Dict(Box<HashMap<&'static str, Value>>),
|
||||
Box(Rc<LBox>),
|
||||
Fn(Rc<RefCell<LFn>>),
|
||||
}
|
||||
|
||||
impl Value {
|
||||
fn show(&self, ctx: &Chunk) -> String {
|
||||
use Value::*;
|
||||
match &self {
|
||||
Nil => format!("nil"),
|
||||
}
|
||||
}
|
||||
}
|
193
src/old_value.rs
Normal file
193
src/old_value.rs
Normal file
|
@ -0,0 +1,193 @@
|
|||
use crate::base::*;
|
||||
use crate::parser::*;
|
||||
use crate::spans::*;
|
||||
use imbl::*;
|
||||
use std::cell::RefCell;
|
||||
use std::fmt;
|
||||
use std::rc::Rc;
|
||||
use struct_scalpel::Dissectible;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Fn<'src> {
|
||||
pub name: String,
|
||||
pub body: &'src Vec<Spanned<Ast>>,
|
||||
pub doc: Option<String>,
|
||||
pub enclosing: Vec<(String, Value<'src>)>,
|
||||
pub has_run: bool,
|
||||
pub input: &'static str,
|
||||
pub src: &'static str,
|
||||
}
|
||||
|
||||
#[derive(Debug, Dissectible)]
|
||||
pub enum Value<'src> {
|
||||
Nil,
|
||||
Placeholder,
|
||||
Boolean(bool),
|
||||
Number(f64),
|
||||
Keyword(&'static str),
|
||||
InternedString(&'static str),
|
||||
AllocatedString(Rc<String>),
|
||||
// on the heap for now
|
||||
Tuple(Rc<Vec<Self>>),
|
||||
Args(Rc<Vec<Self>>),
|
||||
List(Vector<Self>),
|
||||
Dict(HashMap<&'static str, Self>),
|
||||
Box(&'static str, Rc<RefCell<Self>>),
|
||||
Fn(Rc<RefCell<Fn<'src>>>),
|
||||
FnDecl(&'static str),
|
||||
Base(BaseFn<'src>),
|
||||
Recur(Vec<Self>),
|
||||
// Set(HashSet<Self>),
|
||||
// Sets are hard
|
||||
// Sets require Eq
|
||||
// Eq is not implemented on f64, because NaNs
|
||||
// We could use ordered_float::NotNan
|
||||
// Let's defer that
|
||||
// We're not really using sets in Ludus
|
||||
|
||||
// Other things we're not implementing yet:
|
||||
// pkgs, nses, tests
|
||||
}
|
||||
|
||||
impl<'src> Clone for Value<'src> {
|
||||
fn clone(&self) -> Value<'src> {
|
||||
match self {
|
||||
Value::Nil => Value::Nil,
|
||||
Value::Boolean(b) => Value::Boolean(*b),
|
||||
Value::InternedString(s) => Value::InternedString(s),
|
||||
Value::AllocatedString(s) => Value::AllocatedString(s.clone()),
|
||||
Value::Keyword(s) => Value::Keyword(s),
|
||||
Value::Number(n) => Value::Number(*n),
|
||||
Value::Tuple(t) => Value::Tuple(t.clone()),
|
||||
Value::Args(a) => Value::Args(a.clone()),
|
||||
Value::Fn(f) => Value::Fn(f.clone()),
|
||||
Value::FnDecl(name) => Value::FnDecl(name),
|
||||
Value::List(l) => Value::List(l.clone()),
|
||||
Value::Dict(d) => Value::Dict(d.clone()),
|
||||
Value::Box(name, b) => Value::Box(name, b.clone()),
|
||||
Value::Placeholder => Value::Placeholder,
|
||||
Value::Base(b) => Value::Base(b.clone()),
|
||||
Value::Recur(..) => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Value<'_> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
Value::Nil => write!(f, "nil"),
|
||||
Value::Boolean(b) => write!(f, "{b}"),
|
||||
Value::Number(n) => write!(f, "{n}"),
|
||||
Value::Keyword(k) => write!(f, ":{k}"),
|
||||
Value::InternedString(s) => write!(f, "\"{s}\""),
|
||||
Value::AllocatedString(s) => write!(f, "\"{s}\""),
|
||||
Value::Fn(fun) => write!(f, "fn {}", fun.borrow().name),
|
||||
Value::FnDecl(name) => write!(f, "fn {name}"),
|
||||
Value::Tuple(t) | Value::Args(t) => write!(
|
||||
f,
|
||||
"({})",
|
||||
t.iter()
|
||||
.map(|x| x.to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
),
|
||||
Value::List(l) => write!(
|
||||
f,
|
||||
"[{}]",
|
||||
l.iter()
|
||||
.map(|x| x.to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
),
|
||||
Value::Dict(d) => write!(
|
||||
f,
|
||||
"#{{{}}}",
|
||||
d.iter()
|
||||
.map(|(k, v)| format!(":{k} {v}"))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
),
|
||||
Value::Box(name, value) => {
|
||||
write!(
|
||||
f,
|
||||
"box {}: [{}]",
|
||||
name,
|
||||
&value.try_borrow().unwrap().to_string()
|
||||
)
|
||||
}
|
||||
Value::Placeholder => write!(f, "_"),
|
||||
Value::Base(..) => unreachable!(),
|
||||
Value::Recur(..) => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Value<'_> {
|
||||
pub fn bool(&self) -> bool {
|
||||
!matches!(self, Value::Nil | Value::Boolean(false))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'src> PartialEq for Value<'src> {
|
||||
fn eq(&self, other: &Value<'src>) -> bool {
|
||||
match (self, other) {
|
||||
// value equality types
|
||||
(Value::Nil, Value::Nil) => true,
|
||||
(Value::Boolean(x), Value::Boolean(y)) => x == y,
|
||||
(Value::Number(x), Value::Number(y)) => x == y,
|
||||
(Value::InternedString(x), Value::InternedString(y)) => x == y,
|
||||
(Value::AllocatedString(x), Value::AllocatedString(y)) => x == y,
|
||||
(Value::InternedString(x), Value::AllocatedString(y)) => *x == **y,
|
||||
(Value::AllocatedString(x), Value::InternedString(y)) => **x == *y,
|
||||
(Value::Keyword(x), Value::Keyword(y)) => x == y,
|
||||
(Value::Tuple(x), Value::Tuple(y)) => x == y,
|
||||
(Value::List(x), Value::List(y)) => x == y,
|
||||
(Value::Dict(x), Value::Dict(y)) => x == y,
|
||||
// reference equality types
|
||||
(Value::Fn(x), Value::Fn(y)) => {
|
||||
Rc::<RefCell<Fn<'_>>>::as_ptr(x) == Rc::<RefCell<Fn<'_>>>::as_ptr(y)
|
||||
}
|
||||
(Value::Box(_, x), Value::Box(_, y)) => {
|
||||
Rc::<RefCell<Value<'_>>>::as_ptr(x) == Rc::<RefCell<Value<'_>>>::as_ptr(y)
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for Value<'_> {}
|
||||
|
||||
impl Value<'_> {
|
||||
pub fn interpolate(&self) -> String {
|
||||
match self {
|
||||
Value::Nil => String::new(),
|
||||
Value::Boolean(b) => format!("{b}"),
|
||||
Value::Number(n) => format!("{n}"),
|
||||
Value::Keyword(k) => format!(":{k}"),
|
||||
Value::AllocatedString(s) => format!("{s}"),
|
||||
Value::InternedString(s) => s.to_string(),
|
||||
Value::Box(_, x) => x.borrow().interpolate(),
|
||||
Value::Tuple(xs) => xs
|
||||
.iter()
|
||||
.map(|x| x.interpolate())
|
||||
.collect::<Vec<_>>()
|
||||
.join(", "),
|
||||
Value::List(xs) => xs
|
||||
.iter()
|
||||
.map(|x| x.interpolate())
|
||||
.collect::<Vec<_>>()
|
||||
.join(", "),
|
||||
Value::Dict(xs) => xs
|
||||
.iter()
|
||||
.map(|(k, v)| format!(":{} {}", k, v.interpolate()))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", "),
|
||||
Value::Fn(x) => format!("fn {}", x.borrow().name),
|
||||
Value::FnDecl(name) => format!("fn {name}"),
|
||||
Value::Placeholder => unreachable!(),
|
||||
Value::Args(_) => unreachable!(),
|
||||
Value::Recur(_) => unreachable!(),
|
||||
Value::Base(_) => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
208
src/value.rs
208
src/value.rs
|
@ -1,193 +1,47 @@
|
|||
use crate::base::*;
|
||||
use crate::parser::*;
|
||||
use crate::spans::*;
|
||||
use imbl::*;
|
||||
use crate::compiler::Chunk;
|
||||
use crate::parser::Ast;
|
||||
use crate::spans::Spanned;
|
||||
use imbl::{HashMap, Vector};
|
||||
use std::cell::RefCell;
|
||||
use std::fmt;
|
||||
use std::rc::Rc;
|
||||
use struct_scalpel::Dissectible;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Fn<'src> {
|
||||
pub name: String,
|
||||
pub body: &'src Vec<Spanned<Ast>>,
|
||||
pub doc: Option<String>,
|
||||
pub enclosing: Vec<(String, Value<'src>)>,
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct LBox {
|
||||
pub name: usize,
|
||||
pub cell: RefCell<Value>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct LFn {
|
||||
pub name: &'static str,
|
||||
pub body: Vec<Spanned<Ast>>,
|
||||
pub doc: Option<&'static str>,
|
||||
pub enclosing: Vec<(usize, Value)>,
|
||||
pub has_run: bool,
|
||||
pub input: &'static str,
|
||||
pub src: &'static str,
|
||||
}
|
||||
|
||||
#[derive(Debug, Dissectible)]
|
||||
pub enum Value<'src> {
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum Value {
|
||||
Nil,
|
||||
Placeholder,
|
||||
Boolean(bool),
|
||||
Keyword(usize), // use an idx, rather than a raw index
|
||||
Interned(usize),
|
||||
FnDecl(usize),
|
||||
String(Rc<String>),
|
||||
Number(f64),
|
||||
Keyword(&'static str),
|
||||
InternedString(&'static str),
|
||||
AllocatedString(Rc<String>),
|
||||
// on the heap for now
|
||||
Tuple(Rc<Vec<Self>>),
|
||||
Args(Rc<Vec<Self>>),
|
||||
List(Vector<Self>),
|
||||
Dict(HashMap<&'static str, Self>),
|
||||
Box(&'static str, Rc<RefCell<Self>>),
|
||||
Fn(Rc<RefCell<Fn<'src>>>),
|
||||
FnDecl(&'static str),
|
||||
Base(BaseFn<'src>),
|
||||
Recur(Vec<Self>),
|
||||
// Set(HashSet<Self>),
|
||||
// Sets are hard
|
||||
// Sets require Eq
|
||||
// Eq is not implemented on f64, because NaNs
|
||||
// We could use ordered_float::NotNan
|
||||
// Let's defer that
|
||||
// We're not really using sets in Ludus
|
||||
|
||||
// Other things we're not implementing yet:
|
||||
// pkgs, nses, tests
|
||||
List(Box<Vector<Value>>),
|
||||
Dict(Box<HashMap<&'static str, Value>>),
|
||||
Box(Rc<LBox>),
|
||||
Fn(Rc<RefCell<LFn>>),
|
||||
}
|
||||
|
||||
impl<'src> Clone for Value<'src> {
|
||||
fn clone(&self) -> Value<'src> {
|
||||
match self {
|
||||
Value::Nil => Value::Nil,
|
||||
Value::Boolean(b) => Value::Boolean(*b),
|
||||
Value::InternedString(s) => Value::InternedString(s),
|
||||
Value::AllocatedString(s) => Value::AllocatedString(s.clone()),
|
||||
Value::Keyword(s) => Value::Keyword(s),
|
||||
Value::Number(n) => Value::Number(*n),
|
||||
Value::Tuple(t) => Value::Tuple(t.clone()),
|
||||
Value::Args(a) => Value::Args(a.clone()),
|
||||
Value::Fn(f) => Value::Fn(f.clone()),
|
||||
Value::FnDecl(name) => Value::FnDecl(name),
|
||||
Value::List(l) => Value::List(l.clone()),
|
||||
Value::Dict(d) => Value::Dict(d.clone()),
|
||||
Value::Box(name, b) => Value::Box(name, b.clone()),
|
||||
Value::Placeholder => Value::Placeholder,
|
||||
Value::Base(b) => Value::Base(b.clone()),
|
||||
Value::Recur(..) => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Value<'_> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
Value::Nil => write!(f, "nil"),
|
||||
Value::Boolean(b) => write!(f, "{b}"),
|
||||
Value::Number(n) => write!(f, "{n}"),
|
||||
Value::Keyword(k) => write!(f, ":{k}"),
|
||||
Value::InternedString(s) => write!(f, "\"{s}\""),
|
||||
Value::AllocatedString(s) => write!(f, "\"{s}\""),
|
||||
Value::Fn(fun) => write!(f, "fn {}", fun.borrow().name),
|
||||
Value::FnDecl(name) => write!(f, "fn {name}"),
|
||||
Value::Tuple(t) | Value::Args(t) => write!(
|
||||
f,
|
||||
"({})",
|
||||
t.iter()
|
||||
.map(|x| x.to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
),
|
||||
Value::List(l) => write!(
|
||||
f,
|
||||
"[{}]",
|
||||
l.iter()
|
||||
.map(|x| x.to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
),
|
||||
Value::Dict(d) => write!(
|
||||
f,
|
||||
"#{{{}}}",
|
||||
d.iter()
|
||||
.map(|(k, v)| format!(":{k} {v}"))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
),
|
||||
Value::Box(name, value) => {
|
||||
write!(
|
||||
f,
|
||||
"box {}: [{}]",
|
||||
name,
|
||||
&value.try_borrow().unwrap().to_string()
|
||||
)
|
||||
}
|
||||
Value::Placeholder => write!(f, "_"),
|
||||
Value::Base(..) => unreachable!(),
|
||||
Value::Recur(..) => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Value<'_> {
|
||||
pub fn bool(&self) -> bool {
|
||||
!matches!(self, Value::Nil | Value::Boolean(false))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'src> PartialEq for Value<'src> {
|
||||
fn eq(&self, other: &Value<'src>) -> bool {
|
||||
match (self, other) {
|
||||
// value equality types
|
||||
(Value::Nil, Value::Nil) => true,
|
||||
(Value::Boolean(x), Value::Boolean(y)) => x == y,
|
||||
(Value::Number(x), Value::Number(y)) => x == y,
|
||||
(Value::InternedString(x), Value::InternedString(y)) => x == y,
|
||||
(Value::AllocatedString(x), Value::AllocatedString(y)) => x == y,
|
||||
(Value::InternedString(x), Value::AllocatedString(y)) => *x == **y,
|
||||
(Value::AllocatedString(x), Value::InternedString(y)) => **x == *y,
|
||||
(Value::Keyword(x), Value::Keyword(y)) => x == y,
|
||||
(Value::Tuple(x), Value::Tuple(y)) => x == y,
|
||||
(Value::List(x), Value::List(y)) => x == y,
|
||||
(Value::Dict(x), Value::Dict(y)) => x == y,
|
||||
// reference equality types
|
||||
(Value::Fn(x), Value::Fn(y)) => {
|
||||
Rc::<RefCell<Fn<'_>>>::as_ptr(x) == Rc::<RefCell<Fn<'_>>>::as_ptr(y)
|
||||
}
|
||||
(Value::Box(_, x), Value::Box(_, y)) => {
|
||||
Rc::<RefCell<Value<'_>>>::as_ptr(x) == Rc::<RefCell<Value<'_>>>::as_ptr(y)
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for Value<'_> {}
|
||||
|
||||
impl Value<'_> {
|
||||
pub fn interpolate(&self) -> String {
|
||||
match self {
|
||||
Value::Nil => String::new(),
|
||||
Value::Boolean(b) => format!("{b}"),
|
||||
Value::Number(n) => format!("{n}"),
|
||||
Value::Keyword(k) => format!(":{k}"),
|
||||
Value::AllocatedString(s) => format!("{s}"),
|
||||
Value::InternedString(s) => s.to_string(),
|
||||
Value::Box(_, x) => x.borrow().interpolate(),
|
||||
Value::Tuple(xs) => xs
|
||||
.iter()
|
||||
.map(|x| x.interpolate())
|
||||
.collect::<Vec<_>>()
|
||||
.join(", "),
|
||||
Value::List(xs) => xs
|
||||
.iter()
|
||||
.map(|x| x.interpolate())
|
||||
.collect::<Vec<_>>()
|
||||
.join(", "),
|
||||
Value::Dict(xs) => xs
|
||||
.iter()
|
||||
.map(|(k, v)| format!(":{} {}", k, v.interpolate()))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", "),
|
||||
Value::Fn(x) => format!("fn {}", x.borrow().name),
|
||||
Value::FnDecl(name) => format!("fn {name}"),
|
||||
Value::Placeholder => unreachable!(),
|
||||
Value::Args(_) => unreachable!(),
|
||||
Value::Recur(_) => unreachable!(),
|
||||
Value::Base(_) => unreachable!(),
|
||||
impl Value {
|
||||
fn show(&self, ctx: &Chunk) -> String {
|
||||
use Value::*;
|
||||
match &self {
|
||||
Nil => format!("nil"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user