Wire functions through everything, with some unimplemented, and add a basic scoped map.

This commit is contained in:
2023-10-07 11:06:28 +02:00
parent eba5227ebc
commit 736d27953f
18 changed files with 392 additions and 97 deletions

View File

@@ -31,7 +31,7 @@ type Variable = ArcIntern<String>;
pub struct Program {
// 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.
pub(crate) statements: Vec<Statement>,
pub(crate) items: Vec<TopLevel>,
}
impl<'a, 'b, D, A> Pretty<'a, D, A> for &'b Program
@@ -42,7 +42,7 @@ where
fn pretty(self, allocator: &'a D) -> pretty::DocBuilder<'a, D, A> {
let mut result = allocator.nil();
for stmt in self.statements.iter() {
for stmt in self.items.iter() {
// there's probably a better way to do this, rather than constantly
// adding to the end, but this works.
result = result
@@ -69,6 +69,44 @@ impl Arbitrary for Program {
}
}
/// 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)]
pub enum TopLevel {
Statement(Statement),
Function(Variable, Vec<Variable>, Expression),
}
impl<'a, 'b, D, A> Pretty<'a, D, A> for &'b TopLevel
where
A: 'a,
D: ?Sized + DocAllocator<'a, A>,
{
fn pretty(self, allocator: &'a D) -> pretty::DocBuilder<'a, D, A> {
match self {
TopLevel::Function(name, args, body) => allocator
.text("function")
.append(allocator.space())
.append(allocator.text(name.as_ref().to_string()))
.append(
allocator
.intersperse(
args.iter().map(|x| allocator.text(x.as_ref().to_string())),
", ",
)
.parens(),
)
.append(allocator.space())
.append(body.pretty(allocator)),
TopLevel::Statement(stmt) => stmt.pretty(allocator),
}
}
}
/// The representation of a statement in the language.
///
/// For now, this is either a binding site (`x = 4`) or a print statement