Wire functions through everything, with some unimplemented, and add a basic scoped map.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::eval::{EvalEnvironment, EvalError, Value};
|
||||
use crate::ir::{Expression, Program, Statement};
|
||||
use crate::ir::{Expression, Program, Statement, TopLevel};
|
||||
|
||||
use super::{Primitive, Type, ValueOrRef};
|
||||
|
||||
@@ -12,14 +12,16 @@ impl Program {
|
||||
let mut env = EvalEnvironment::empty();
|
||||
let mut stdout = String::new();
|
||||
|
||||
for stmt in self.statements.iter() {
|
||||
for stmt in self.items.iter() {
|
||||
match stmt {
|
||||
Statement::Binding(_, name, _, value) => {
|
||||
TopLevel::Function(_, _, _) => unimplemented!(),
|
||||
|
||||
TopLevel::Statement(Statement::Binding(_, name, _, value)) => {
|
||||
let actual_value = value.eval(&env)?;
|
||||
env = env.extend(name.clone(), actual_value);
|
||||
}
|
||||
|
||||
Statement::Print(_, _, name) => {
|
||||
TopLevel::Statement(Statement::Print(_, _, name)) => {
|
||||
let value = env.lookup(name.clone())?;
|
||||
let line = format!("{} = {}\n", name, value);
|
||||
stdout.push_str(&line);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use super::ast::{Expression, Program, Statement};
|
||||
use super::ast::{Expression, Program, Statement, TopLevel};
|
||||
use internment::ArcIntern;
|
||||
use std::collections::HashSet;
|
||||
|
||||
@@ -10,7 +10,7 @@ impl Program {
|
||||
pub fn strings(&self) -> HashSet<ArcIntern<String>> {
|
||||
let mut result = HashSet::new();
|
||||
|
||||
for stmt in self.statements.iter() {
|
||||
for stmt in self.items.iter() {
|
||||
stmt.register_strings(&mut result);
|
||||
}
|
||||
|
||||
@@ -18,6 +18,15 @@ impl Program {
|
||||
}
|
||||
}
|
||||
|
||||
impl TopLevel {
|
||||
fn register_strings(&self, string_set: &mut HashSet<ArcIntern<String>>) {
|
||||
match self {
|
||||
TopLevel::Function(_, _, body) => body.register_strings(string_set),
|
||||
TopLevel::Statement(stmt) => stmt.register_strings(string_set),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Statement {
|
||||
fn register_strings(&self, string_set: &mut HashSet<ArcIntern<String>>) {
|
||||
match self {
|
||||
|
||||
Reference in New Issue
Block a user