Skip to content

Commit

Permalink
Converting to interned types
Browse files Browse the repository at this point in the history
  • Loading branch information
NicholasLYang committed Jul 11, 2023
1 parent 33cbbc6 commit 9ac9471
Show file tree
Hide file tree
Showing 6 changed files with 353 additions and 252 deletions.
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/vicuna-compiler/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ wasm-opt = false
[dependencies]
anyhow = { workspace = true }
chumsky = { version = "0.9.2", default-features = false, features = ["std"] }
id-arena = "2.2.1"
miette = { version = "5.8.0", features = ["fancy"] }
serde = { version = "1.0.147", features = ["derive", "rc"] }
thiserror = "1.0.40"
Expand Down
35 changes: 29 additions & 6 deletions crates/vicuna-compiler/src/ast.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use serde::ser::{SerializeMap, SerializeSeq};
use serde::Serialize;
use std::fmt::Debug;
use std::hash::Hash;
Expand All @@ -9,21 +10,43 @@ pub struct Program {
}

#[derive(Debug, Clone, PartialEq, Serialize)]
pub struct Span<T: Debug + Clone + PartialEq + Serialize>(pub T, pub Range<usize>);
pub struct Span<T: Debug + Clone + PartialEq>(pub T, pub Range<usize>);

impl<T: Debug + Clone + PartialEq + Serialize + Hash> Eq for Span<T> {}

pub type TypeParams = Span<Vec<Span<String>>>;

#[derive(Debug, Clone, PartialEq, Serialize)]
pub enum Fields<T: Debug + Clone + PartialEq + Serialize> {
#[derive(Debug, Clone, PartialEq)]
pub enum Fields<T: Debug + Clone + PartialEq> {
Named(Vec<(Span<String>, Span<T>)>),
Tuple(Vec<Span<T>>),
Empty,
}

impl<T: Debug + Clone + PartialEq + Serialize> Fields<T> {
pub fn map<U: Debug + Clone + PartialEq + Serialize>(
impl<T: Serialize + Debug + Clone + PartialEq> Serialize for Fields<T> {
fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
match self {
Fields::Named(fields) => {
let mut map = serializer.serialize_map(Some(fields.len()))?;
for (name, value) in fields {
map.serialize_entry(name, value)?;
}
map.end()
}
Fields::Tuple(fields) => {
let mut seq = serializer.serialize_seq(Some(fields.len()))?;
for value in fields {
seq.serialize_element(value)?;
}
seq.end()
}
Fields::Empty => serializer.serialize_none(),
}
}
}

impl<T: Debug + Clone + PartialEq> Fields<T> {
pub fn map<U: Debug + Clone + PartialEq>(
&self,
mut f: impl FnMut(&Span<T>) -> Span<U>,
) -> Fields<U> {
Expand All @@ -34,7 +57,7 @@ impl<T: Debug + Clone + PartialEq + Serialize> Fields<T> {
.map(|(name, value)| (name.clone(), f(value)))
.collect(),
),
Fields::Tuple(fields) => Fields::Tuple(fields.iter().map(|value| f(value)).collect()),
Fields::Tuple(fields) => Fields::Tuple(fields.iter().map(f).collect()),
Fields::Empty => Fields::Empty,
}
}
Expand Down
12 changes: 6 additions & 6 deletions crates/vicuna-compiler/src/js_backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ impl<T: Write> JsBackend<T> {
fn emit_stmt(&mut self, stmt: &Span<Stmt>) -> Result<()> {
match &stmt.0 {
Stmt::Let(name, if_expr @ Span(Expr::If { .. } | Expr::Match { .. }, _)) => {
write!(self.output, "let {};\n", name.0)?;
writeln!(self.output, "let {};", name.0)?;
let old_expression_block_state = mem::replace(
&mut self.expression_block_state,
Some(ExprBlockState::Binding(name.0.clone())),
Expand Down Expand Up @@ -321,7 +321,7 @@ impl<T: Write> JsBackend<T> {
fn emit_expr_fields(&mut self, fields: &ExprFields) -> Result<()> {
match fields {
ExprFields::Tuple(fields) => {
for (i, field) in fields.into_iter().enumerate() {
for (i, field) in fields.iter().enumerate() {
self.output.write_all(format!("{}: ", i).as_bytes())?;
self.emit_expr(field)?;
if i < fields.len() - 1 {
Expand All @@ -330,7 +330,7 @@ impl<T: Write> JsBackend<T> {
}
}
ExprFields::Named(fields) => {
for (i, (name, field)) in fields.into_iter().enumerate() {
for (i, (name, field)) in fields.iter().enumerate() {
self.output.write_all(name.0.as_bytes())?;
self.output.write_all(b": ")?;
self.emit_expr(field)?;
Expand All @@ -348,7 +348,7 @@ impl<T: Write> JsBackend<T> {
fn emit_match_bindings(&mut self, bindings: &MatchBindings) -> Result<()> {
match bindings {
MatchBindings::Tuple(fields) => {
for (idx, field) in fields.into_iter().enumerate() {
for (idx, field) in fields.iter().enumerate() {
self.output.write_all(b"const ")?;
self.output.write_all(field.0.as_bytes())?;
self.output.write_all(b" = __match__[")?;
Expand All @@ -358,7 +358,7 @@ impl<T: Write> JsBackend<T> {
}
MatchBindings::Named(fields) => {
for (field, rename) in fields {
let name = rename.as_ref().unwrap_or(&field);
let name = rename.as_ref().unwrap_or(field);

self.output.write_all(b"const ")?;
self.output.write_all(name.0.as_bytes())?;
Expand All @@ -380,7 +380,7 @@ impl<T: Write> JsBackend<T> {
// If the end expression is an if expression, we don't bind or return,
// and let the if expression determine that itself.
Some(if_expr @ Span(Expr::If { .. }, _)) => {
self.emit_expr(&if_expr)?;
self.emit_expr(if_expr)?;
}
Some(end_expr) => {
let expr_block_state = self
Expand Down
8 changes: 4 additions & 4 deletions crates/vicuna-compiler/src/symbol_table.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::type_checker::{EnumSchema, Name, StructSchema, Type};
use crate::type_checker::{EnumSchema, Name, StructSchema, TypeId};
use std::collections::HashMap;
use std::fmt::{Debug, Formatter};
use std::sync::Arc;
Expand All @@ -7,7 +7,7 @@ use std::sync::Arc;
#[derive(Debug, Clone)]
pub enum SymbolTableEntry {
/// Normal variables like parameters or let bindings
Variable { ty: Type },
Variable { ty: TypeId },
/// Generic type variables that is meant to be solved. I.e. you call a generic function
/// `<T>(T) -> T` with a concrete type `i32` and the type checker will solve
/// the type variable `T = i32`.
Expand Down Expand Up @@ -76,11 +76,11 @@ impl SymbolTable {
impl Debug for SymbolTable {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
for scope in &self.scopes {
println!("---------------------");
writeln!(f, "---------------------")?;
for (name, entry) in scope {
writeln!(f, "{}: {:?}", name, entry)?;
}
println!("---------------------");
writeln!(f, "---------------------")?;
}

Ok(())
Expand Down
Loading

0 comments on commit 9ac9471

Please sign in to comment.