Skip to content

Commit

Permalink
Merge pull request #18 from yeslogic/brendanzab/repr-errors
Browse files Browse the repository at this point in the history
Remove unwraps from parser and typechecker and add repr error type
  • Loading branch information
brendanzab authored Oct 26, 2017
2 parents bd0f2ee + 5755cab commit c06ec18
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 35 deletions.
21 changes: 11 additions & 10 deletions src/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,12 +209,18 @@ pub enum KindError<N> {
expected: binary::Kind,
found: binary::Kind,
},
/// No host representation was found for this type
NoReprForType { ty: binary::Type<N> },
/// A repr error
Repr(binary::ReprError<N>),
/// A type error
Type(TypeError<N>),
}

impl<N> From<binary::ReprError<N>> for KindError<N> {
fn from(src: binary::ReprError<N>) -> KindError<N> {
KindError::Repr(src)
}
}

impl<N> From<TypeError<N>> for KindError<N> {
fn from(src: TypeError<N>) -> KindError<N> {
KindError::Type(src)
Expand Down Expand Up @@ -257,7 +263,7 @@ pub fn kind_of<N: Name>(ctx: &Ctx<N>, ty: &binary::Type<N>) -> Result<binary::Ki
expect_ty(
ctx,
&**pred_expr,
host::Type::arrow(ty.repr().unwrap(), host::Type::bool()),
host::Type::arrow(ty.repr()?, host::Type::bool()),
)?;

Ok(Kind::Type)
Expand All @@ -269,7 +275,7 @@ pub fn kind_of<N: Name>(ctx: &Ctx<N>, ty: &binary::Type<N>) -> Result<binary::Ki
expect_ty(
ctx,
&**conv_expr,
host::Type::arrow(ty.repr().unwrap(), host_ty.clone()),
host::Type::arrow(ty.repr()?, host_ty.clone()),
)?;

Ok(Kind::Type)
Expand Down Expand Up @@ -301,12 +307,7 @@ pub fn kind_of<N: Name>(ctx: &Ctx<N>, ty: &binary::Type<N>) -> Result<binary::Ki
expect_ty_kind(&ctx, &field.value)?;

let field_ty = simplify_ty(&ctx, &field.value);
let repr_ty = field_ty.repr().map_err(|_| {
KindError::NoReprForType {
ty: field_ty.clone(),
}
})?;
ctx.extend(field.name.clone(), Binding::Expr(repr_ty));
ctx.extend(field.name.clone(), Binding::Expr(field_ty.repr()?));
}

Ok(Kind::Type)
Expand Down
16 changes: 10 additions & 6 deletions src/parser/grammar.lalrpop
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use lalrpop_util::ParseError;

use syntax::{Definition, Field};
use syntax::binary::Type;
use syntax::host::{Binop, Expr, Unop};
use parser::lexer::{Token, Error as LexerError};
use parser::GrammarError;
use parser::lexer::Token;
use source::BytePos;


Expand All @@ -12,7 +15,7 @@ grammar<'input>();

extern {
type Location = BytePos;
type Error = LexerError;
type Error = GrammarError<String>;

enum Token<'input> {
// Data
Expand Down Expand Up @@ -82,10 +85,11 @@ pub Type: Type<String> = {

PrimaryType: Type<String> = {
AtomicType,
<ty: PrimaryType> "where" <param: "Ident"> "=>" <pred: PrimaryExpr> => {
// FIXME: unwrap
let repr_ty = Box::new(ty.repr().unwrap());
Type::cond(ty, Expr::abs((param, repr_ty), pred))
<ty: PrimaryType> "where" <param: "Ident"> "=>" <pred: PrimaryExpr> =>? {
let repr_ty = Box::new(ty.repr().map_err(|err| {
ParseError::User { error: GrammarError::from(err) }
})?);
Ok(Type::cond(ty, Expr::abs((param, repr_ty), pred)))
},
};

Expand Down
47 changes: 30 additions & 17 deletions src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,27 +9,40 @@ mod grammar;

use self::lexer::{Error as LexerError, Lexer, Token};

pub type ParseError<'input> = lalrpop_util::ParseError<BytePos, Token<'input>, LexerError>;

pub fn parse<'input>(
src: &'input str,
) -> Result<
Vec<Definition<String>>,
ParseError<'input>,
> {
grammar::parse_Definitions(Lexer::new(src))
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum GrammarError<N> {
Repr(binary::ReprError<N>),
Lexer(LexerError),
}

pub fn parse_expr<'input>(
src: &'input str,
) -> Result<host::Expr<String>, ParseError<'input>> {
grammar::parse_Expr(Lexer::new(src))
impl<N> From<binary::ReprError<N>> for GrammarError<N> {
fn from(src: binary::ReprError<N>) -> GrammarError<N> {
GrammarError::Repr(src)
}
}

impl<N> From<LexerError> for GrammarError<N> {
fn from(src: LexerError) -> GrammarError<N> {
GrammarError::Lexer(src)
}
}

pub type ParseError<'input> = lalrpop_util::ParseError<
BytePos,
Token<'input>,
GrammarError<String>,
>;

pub fn parse<'input>(src: &'input str) -> Result<Vec<Definition<String>>, ParseError<'input>> {
grammar::parse_Definitions(Lexer::new(src).map(|x| x.map_err(GrammarError::from)))
}

pub fn parse_expr<'input>(src: &'input str) -> Result<host::Expr<String>, ParseError<'input>> {
grammar::parse_Expr(Lexer::new(src).map(|x| x.map_err(GrammarError::from)))
}

pub fn parse_ty<'input>(
src: &'input str,
) -> Result<binary::Type<String>, ParseError<'input>> {
grammar::parse_Type(Lexer::new(src))
pub fn parse_ty<'input>(src: &'input str) -> Result<binary::Type<String>, ParseError<'input>> {
grammar::parse_Type(Lexer::new(src).map(|x| x.map_err(GrammarError::from)))
}

#[cfg(test)]
Expand Down
13 changes: 11 additions & 2 deletions src/syntax/binary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@ impl Kind {
}
}

/// An error that occurred when trying to convert a binary type to
/// its host representation
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ReprError<N> {
NoCorrespondingHostType(Type<N>),
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum TypeConst {
Bit,
Expand Down Expand Up @@ -223,7 +230,7 @@ impl<N: Name> Type<N> {
self.instantiate_at(0, ty);
}

pub fn repr(&self) -> Result<host::Type<N>, ()> {
pub fn repr(&self) -> Result<host::Type<N>, ReprError<N>> {
match *self {
Type::Var(ref v) => Ok(host::Type::Var(v.clone()).into()),
Type::Const(TypeConst::Bit) => Ok(host::Type::Const(host::TypeConst::Bit).into()),
Expand All @@ -248,7 +255,9 @@ impl<N: Name> Type<N> {

Ok(host::Type::Struct(repr_fields).into())
}
Type::Abs(_, _) | Type::App(_, _) => Err(()),
Type::Abs(_, _) | Type::App(_, _) => {
Err(ReprError::NoCorrespondingHostType(self.clone()))
}
}
}
}
Expand Down

0 comments on commit c06ec18

Please sign in to comment.