checkpoint in reconstruction
This commit is contained in:
@@ -5,8 +5,11 @@ use crate::{
|
||||
};
|
||||
use internment::ArcIntern;
|
||||
use pretty::{BoxAllocator, DocAllocator, Pretty};
|
||||
use proptest::arbitrary::Arbitrary;
|
||||
use std::{fmt, str::FromStr, sync::atomic::AtomicUsize};
|
||||
|
||||
use super::arbitrary::ProgramGenerator;
|
||||
|
||||
/// We're going to represent variables as interned strings.
|
||||
///
|
||||
/// These should be fast enough for comparison that it's OK, since it's going to end up
|
||||
@@ -45,7 +48,7 @@ pub fn gensym(base: &str) -> Variable {
|
||||
/// The type variable is, somewhat confusingly, the current definition of a type within
|
||||
/// the IR. Since the makeup of this structure may change over the life of the compiler,
|
||||
/// it's easiest to just make it an argument.
|
||||
#[derive(Debug)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Program<Type> {
|
||||
// For now, a program is just a vector of statements. In the future, we'll probably
|
||||
// extend this to include a bunch of other information, but for now: just a list.
|
||||
@@ -74,12 +77,21 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl Arbitrary for Program<Type> {
|
||||
type Parameters = ();
|
||||
type Strategy = ProgramGenerator;
|
||||
|
||||
fn arbitrary_with(_: Self::Parameters) -> Self::Strategy {
|
||||
ProgramGenerator::default()
|
||||
}
|
||||
}
|
||||
|
||||
/// A thing that can sit at the top level of a file.
|
||||
///
|
||||
/// For the moment, these are statements and functions. Other things
|
||||
/// will likely be added in the future, but for now: just statements
|
||||
/// and functions
|
||||
#[derive(Debug)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum TopLevel<Type> {
|
||||
Statement(Expression<Type>),
|
||||
Function(Variable, Vec<(Variable, Type)>, Type, Expression<Type>),
|
||||
@@ -140,8 +152,7 @@ impl<Type: Clone + TypeWithVoid> Expression<Type> {
|
||||
/// computed.
|
||||
pub fn type_of(&self) -> Type {
|
||||
match self {
|
||||
Expression::Atomic(ValueOrRef::Ref(_, t, _)) => t.clone(),
|
||||
Expression::Atomic(ValueOrRef::Value(_, t, _)) => t.clone(),
|
||||
Expression::Atomic(x) => x.type_of(),
|
||||
Expression::Cast(_, t, _) => t.clone(),
|
||||
Expression::Primitive(_, t, _, _) => t.clone(),
|
||||
Expression::Block(_, t, _) => t.clone(),
|
||||
@@ -300,6 +311,15 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<Type: Clone> ValueOrRef<Type> {
|
||||
pub fn type_of(&self) -> Type {
|
||||
match self {
|
||||
ValueOrRef::Ref(_, t, _) => t.clone(),
|
||||
ValueOrRef::Value(_, t, _) => t.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<Type> From<ValueOrRef<Type>> for Expression<Type> {
|
||||
fn from(value: ValueOrRef<Type>) -> Self {
|
||||
Expression::Atomic(value)
|
||||
@@ -322,6 +342,7 @@ pub enum Value {
|
||||
U16(Option<u8>, u16),
|
||||
U32(Option<u8>, u32),
|
||||
U64(Option<u8>, u64),
|
||||
Void,
|
||||
}
|
||||
|
||||
impl Value {
|
||||
@@ -336,6 +357,7 @@ impl Value {
|
||||
Value::U16(_, _) => Type::Primitive(PrimitiveType::U16),
|
||||
Value::U32(_, _) => Type::Primitive(PrimitiveType::U32),
|
||||
Value::U64(_, _) => Type::Primitive(PrimitiveType::U64),
|
||||
Value::Void => Type::void(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -379,6 +401,7 @@ where
|
||||
pretty_internal(opt_base, *value as u64, ConstantType::U32)
|
||||
}
|
||||
Value::U64(opt_base, value) => pretty_internal(opt_base, *value, ConstantType::U64),
|
||||
Value::Void => allocator.text("<void>"),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -389,6 +412,14 @@ pub enum Type {
|
||||
Function(Vec<Type>, Box<Type>),
|
||||
}
|
||||
|
||||
impl Type {
|
||||
/// Returns true if this variable can reasonably be passed to the print
|
||||
/// expression for printing.
|
||||
pub fn is_printable(&self) -> bool {
|
||||
matches!(self, Type::Primitive(_))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b, D, A> Pretty<'a, D, A> for &'b Type
|
||||
where
|
||||
A: 'a,
|
||||
|
||||
Reference in New Issue
Block a user