Skip to content

Commit

Permalink
Improve compiler errors for const defs
Browse files Browse the repository at this point in the history
  • Loading branch information
fkettelhoit committed Jun 4, 2024
1 parent 4360f88 commit af63a61
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 24 deletions.
4 changes: 2 additions & 2 deletions src/ast.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! The untyped Abstract Syntax Tree (AST).
use std::collections::HashMap;
use std::collections::{BTreeMap, HashMap};

#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
Expand All @@ -12,7 +12,7 @@ use crate::token::{MetaInfo, SignedNumType, UnsignedNumType};
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Program<T> {
/// The external constants that the top level const definitions depend upon.
pub const_deps: HashMap<String, HashMap<String, T>>,
pub const_deps: BTreeMap<String, BTreeMap<String, T>>,
/// Top level const definitions.
pub const_defs: HashMap<String, ConstDef>,
/// Top level struct type definitions.
Expand Down
6 changes: 3 additions & 3 deletions src/check.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Type-checker, transforming an untyped [`crate::ast::Program`] into a typed
//! [`crate::ast::Program`].
use std::collections::{HashMap, HashSet};
use std::collections::{BTreeMap, HashMap, HashSet};

use crate::{
ast::{
Expand Down Expand Up @@ -354,7 +354,7 @@ impl UntypedProgram {
struct_names,
enum_names,
};
let mut const_deps: HashMap<String, HashMap<String, Type>> = HashMap::new();
let mut const_deps: BTreeMap<String, BTreeMap<String, Type>> = BTreeMap::new();
let mut const_types = HashMap::with_capacity(self.const_defs.len());
let mut const_defs = HashMap::with_capacity(self.const_defs.len());
{
Expand All @@ -363,7 +363,7 @@ impl UntypedProgram {
value: &ConstExpr,
const_def: &ConstDef,
errors: &mut Vec<Option<TypeError>>,
const_deps: &mut HashMap<String, HashMap<String, Type>>,
const_deps: &mut BTreeMap<String, BTreeMap<String, Type>>,
) {
let ConstExpr(value, meta) = value;
let meta = *meta;
Expand Down
28 changes: 20 additions & 8 deletions src/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,14 @@ impl std::fmt::Display for CompilerError {
}
}

type CompiledProgram<'a> = (Circuit, &'a TypedFnDef, HashMap<String, usize>);

impl TypedProgram {
/// Compiles the (type-checked) program, producing a circuit of gates.
///
/// Assumes that the input program has been correctly type-checked and **panics** if
/// incompatible types are found that should have been caught by the type-checker.
pub fn compile(&self, fn_name: &str) -> Result<(Circuit, &TypedFnDef), CompilerError> {
pub fn compile(&self, fn_name: &str) -> Result<(Circuit, &TypedFnDef), Vec<CompilerError>> {
self.compile_with_constants(fn_name, HashMap::new())
.map(|(c, f, _)| (c, f))
}
Expand All @@ -62,19 +64,22 @@ impl TypedProgram {
&self,
fn_name: &str,
consts: HashMap<String, HashMap<String, Literal>>,
) -> Result<(Circuit, &TypedFnDef, HashMap<String, usize>), CompilerError> {
) -> Result<CompiledProgram, Vec<CompilerError>> {
let mut env = Env::new();
let mut const_sizes = HashMap::new();
let mut consts_unsigned = HashMap::new();
let mut consts_signed = HashMap::new();

let mut errs = vec![];
for (party, deps) in self.const_deps.iter() {
for (c, ty) in deps {
let Some(party_deps) = consts.get(party) else {
return Err(CompilerError::MissingConstant(party.clone(), c.clone()));
errs.push(CompilerError::MissingConstant(party.clone(), c.clone()));
continue;
};
let Some(literal) = party_deps.get(c) else {
return Err(CompilerError::MissingConstant(party.clone(), c.clone()));
errs.push(CompilerError::MissingConstant(party.clone(), c.clone()));
continue;
};
let identifier = format!("{party}::{c}");
match literal {
Expand All @@ -93,6 +98,9 @@ impl TypedProgram {
}
}
}
if !errs.is_empty() {
return Err(errs);
}
fn resolve_const_expr_unsigned(
ConstExpr(expr, _): &ConstExpr,
consts_unsigned: &HashMap<String, u64>,
Expand Down Expand Up @@ -158,13 +166,14 @@ impl TypedProgram {
}
}

let mut errs = vec![];
for (party, deps) in self.const_deps.iter() {
for (c, ty) in deps {
let Some(party_deps) = consts.get(party) else {
return Err(CompilerError::MissingConstant(party.clone(), c.clone()));
continue;
};
let Some(literal) = party_deps.get(c) else {
return Err(CompilerError::MissingConstant(party.clone(), c.clone()));
continue;
};
let identifier = format!("{party}::{c}");
if literal.is_of_type(self, ty) {
Expand All @@ -175,17 +184,20 @@ impl TypedProgram {
.collect();
env.let_in_current_scope(identifier.clone(), bits);
} else {
return Err(CompilerError::InvalidLiteralType(
errs.push(CompilerError::InvalidLiteralType(
literal.clone(),
ty.clone(),
));
}
}
}
if !errs.is_empty() {
return Err(errs);
}
let mut input_gates = vec![];
let mut wire = 2;
let Some(fn_def) = self.fn_defs.get(fn_name) else {
return Err(CompilerError::FnNotFound(fn_name.to_string()));
return Err(vec![CompilerError::FnNotFound(fn_name.to_string())]);
};
for param in fn_def.params.iter() {
let type_size = param.ty.size_in_bits_for_defs(self, &const_sizes);
Expand Down
18 changes: 9 additions & 9 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ pub enum CompileTimeError {
/// Errors originating in the type-checking phase.
TypeError(Vec<TypeError>),
/// Errors originating in the compilation phase.
CompilerError(CompilerError),
CompilerError(Vec<CompilerError>),
}

/// A generic error that combines compile-time and run-time errors.
Expand Down Expand Up @@ -249,8 +249,8 @@ impl From<Vec<TypeError>> for CompileTimeError {
}
}

impl From<CompilerError> for CompileTimeError {
fn from(e: CompilerError) -> Self {
impl From<Vec<CompilerError>> for CompileTimeError {
fn from(e: Vec<CompilerError>) -> Self {
Self::CompilerError(e)
}
}
Expand Down Expand Up @@ -323,12 +323,12 @@ impl CompileTimeError {
errs_for_display.push(("Type error", format!("{e}"), *meta));
}
}
CompileTimeError::CompilerError(e) => {
let meta = MetaInfo {
start: (0, 0),
end: (0, 0),
};
errs_for_display.push(("Compiler error", format!("{e}"), meta))
CompileTimeError::CompilerError(errs) => {
let mut pretty = String::new();
for e in errs {
pretty += &format!("\nCompiler error: {e}");
}
return pretty;
}
}
let mut msg = "".to_string();
Expand Down
8 changes: 6 additions & 2 deletions src/parse.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
//! Parses a stream of [`crate::scan::Tokens`] into an untyped [`crate::ast::Program`].
use std::{collections::HashMap, iter::Peekable, vec::IntoIter};
use std::{
collections::{BTreeMap, HashMap},
iter::Peekable,
vec::IntoIter,
};

use crate::{
ast::{
Expand Down Expand Up @@ -171,7 +175,7 @@ impl Parser {
}
if self.errors.is_empty() {
return Ok(Program {
const_deps: HashMap::new(),
const_deps: BTreeMap::new(),
const_defs,
struct_defs,
enum_defs,
Expand Down

0 comments on commit af63a61

Please sign in to comment.