Skip to content

Commit

Permalink
Merge pull request #103 from brendanzab/lalrpop_parser
Browse files Browse the repository at this point in the history
Rewrite parser using LALRPOP
  • Loading branch information
brendanzab authored Nov 30, 2016
2 parents c87c733 + c05428e commit cc3d326
Show file tree
Hide file tree
Showing 34 changed files with 2,753 additions and 2,220 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@

target
Cargo.lock

parser/src/grammar.rs
13 changes: 7 additions & 6 deletions base/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,10 @@ pub struct Lambda<Id> {
pub body: Box<SpannedExpr<Id>>,
}

/// Expression which contains a location
pub type SpannedExpr<Id> = Spanned<Expr<Id>, BytePos>;

pub type SpannedIdent<Id> = Spanned<TypedIdent<Id>, BytePos>;

/// The representation of gluon's expression syntax
#[derive(Clone, PartialEq, Debug)]
pub enum Expr<Id> {
Expand All @@ -114,7 +115,7 @@ pub enum Expr<Id> {
/// Pattern match expression
Match(Box<SpannedExpr<Id>>, Vec<Alternative<Id>>),
/// Infix operator expression eg. `f >> g`
Infix(Box<SpannedExpr<Id>>, TypedIdent<Id>, Box<SpannedExpr<Id>>),
Infix(Box<SpannedExpr<Id>>, SpannedIdent<Id>, Box<SpannedExpr<Id>>),
/// Record field projection, eg. `value.field`
Projection(Box<SpannedExpr<Id>>, Id, ArcType<Id>),
/// Array construction
Expand Down Expand Up @@ -177,7 +178,7 @@ pub fn walk_mut_expr<V: ?Sized + MutVisitor>(v: &mut V, e: &mut SpannedExpr<V::I
}
Expr::Infix(ref mut lhs, ref mut id, ref mut rhs) => {
v.visit_expr(lhs);
v.visit_typ(&mut id.typ);
v.visit_typ(&mut id.value.typ);
v.visit_expr(rhs);
}
Expr::LetBindings(ref mut bindings, ref mut body) => {
Expand Down Expand Up @@ -278,7 +279,7 @@ pub fn walk_expr<V: ?Sized + Visitor>(v: &mut V, e: &SpannedExpr<V::Ident>) {
}
Expr::Infix(ref lhs, ref id, ref rhs) => {
v.visit_expr(lhs);
v.visit_typ(&id.typ);
v.visit_typ(&id.value.typ);
v.visit_expr(rhs);
}
Expr::LetBindings(ref bindings, ref body) => {
Expand Down Expand Up @@ -394,7 +395,7 @@ impl Typed for Expr<Symbol> {
Type::unit()
}
Expr::Infix(_, ref op, _) => {
if let Type::App(_, ref args) = *op.typ.clone() {
if let Type::App(_, ref args) = *op.value.typ.clone() {
if let Type::App(_, ref args) = *args[1] {
return args[1].clone();
}
Expand Down Expand Up @@ -473,5 +474,5 @@ fn get_return_type(env: &TypeEnv, alias_type: &ArcType, arg_count: usize) -> Arc
}

pub fn is_operator_char(c: char) -> bool {
"+-*/&|=<>".chars().any(|x| x == c)
"#+-*/&|=<>:.".chars().any(|x| x == c)
}
63 changes: 60 additions & 3 deletions base/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,88 @@
use std::any::Any;
use std::error::Error as StdError;
use std::fmt;
use std::iter::{Extend, FromIterator};
use std::slice;
use std::vec;

use pos::{BytePos, Location, Span, Spanned, spanned2};
use source::Source;

/// An error type which can represent multiple errors.
#[derive(Debug, PartialEq)]
pub struct Errors<T> {
pub errors: Vec<T>,
errors: Vec<T>,
}

impl<T> Errors<T> {
/// Creates a new, empty `Errors` instance.
pub fn new() -> Errors<T> {
Errors { errors: Vec::new() }
Errors::from(Vec::new())
}

/// Returns true if `self` contains any errors
pub fn has_errors(&self) -> bool {
!self.errors.is_empty()
}

/// The number of errors in the error list
pub fn len(&self) -> usize {
self.errors.len()
}

/// Adds an error to `self`
pub fn error(&mut self, t: T) {
pub fn push(&mut self, t: T) {
self.errors.push(t);
}

/// Pops and error off the error list
pub fn pop(&mut self) -> Option<T> {
self.errors.pop()
}
}

impl<T> Extend<T> for Errors<T> {
fn extend<Iter: IntoIterator<Item = T>>(&mut self, iter: Iter) {
self.errors.extend(iter);
}
}

impl<T> From<Vec<T>> for Errors<T> {
fn from(errors: Vec<T>) -> Errors<T> {
Errors { errors: errors }
}
}

impl<T> FromIterator<T> for Errors<T> {
fn from_iter<Iter: IntoIterator<Item = T>>(iter: Iter) -> Errors<T> {
Errors { errors: iter.into_iter().collect() }
}
}

impl<T> Into<Vec<T>> for Errors<T> {
fn into(self) -> Vec<T> {
self.errors
}
}

impl<T> IntoIterator for Errors<T> {
type Item = T;

type IntoIter = vec::IntoIter<T>;

fn into_iter(self) -> vec::IntoIter<T> {
self.errors.into_iter()
}
}

impl<'a, T> IntoIterator for &'a Errors<T> {
type Item = &'a T;

type IntoIter = slice::Iter<'a, T>;

fn into_iter(self) -> slice::Iter<'a, T> {
self.errors.iter()
}
}

impl<T: fmt::Display> fmt::Display for Errors<T> {
Expand Down
31 changes: 21 additions & 10 deletions base/src/pos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,18 +96,14 @@ pub struct Location {
}

impl Location {
pub fn bump(&mut self, ch: char) {
pub fn shift(mut self, ch: char) -> Location {
if ch == '\n' {
self.line += Line::from(1);
self.column = Column::from(0);
} else {
self.column += Column::from(1);
}
self.absolute += BytePos::from(ch.len_utf8());
}

pub fn line_offset(mut self, offset: Column) -> Location {
self.column += offset;
self
}
}
Expand Down Expand Up @@ -224,6 +220,17 @@ pub struct Spanned<T, Pos> {
pub value: T,
}

impl<T, Pos> Spanned<T, Pos> {
pub fn map<U, F>(self, mut f: F) -> Spanned<U, Pos>
where F: FnMut(T) -> U,
{
Spanned {
span: self.span,
value: f(self.value),
}
}
}

impl<T: PartialEq, Pos> PartialEq for Spanned<T, Pos> {
fn eq(&self, other: &Spanned<T, Pos>) -> bool {
self.value == other.value
Expand All @@ -236,6 +243,14 @@ impl<T: fmt::Display, Pos: fmt::Display> fmt::Display for Spanned<T, Pos> {
}
}

pub fn span<Pos>(start: Pos, end: Pos) -> Span<Pos> {
Span {
start: start,
end: end,
expansion_id: NO_EXPANSION,
}
}

pub fn spanned<T, Pos>(span: Span<Pos>, value: T) -> Spanned<T, Pos> {
Spanned {
span: span,
Expand All @@ -245,11 +260,7 @@ pub fn spanned<T, Pos>(span: Span<Pos>, value: T) -> Spanned<T, Pos> {

pub fn spanned2<T, Pos>(start: Pos, end: Pos, value: T) -> Spanned<T, Pos> {
Spanned {
span: Span {
start: start,
end: end,
expansion_id: NO_EXPANSION,
},
span: span(start, end),
value: value,
}
}
9 changes: 9 additions & 0 deletions base/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,15 @@ pub struct Field<Id, T = ArcType<Id>> {
/// increasing the size of `Type`.
pub type AppVec<T> = SmallVec<[T; 2]>;

impl<Id, T> Field<Id, T> {
pub fn new(name: Id, typ: T) -> Field<Id, T> {
Field {
name: name,
typ: typ,
}
}
}

/// The representation of gluon's types.
///
/// For efficency this enum is not stored directly but instead a pointer wrapper which derefs to
Expand Down
2 changes: 1 addition & 1 deletion benches/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ fn prelude(b: &mut ::test::Bencher) {
let mut symbols = Symbols::new();
let mut symbols = SymbolModule::new("".into(), &mut symbols);
let expr = parser::parse_expr(&mut symbols, &text)
.unwrap_or_else(|(_, err)| panic!("{:?}", err));
.unwrap_or_else(|err| panic!("{:?}", err));
::test::black_box(expr)
})
}
2 changes: 1 addition & 1 deletion check/src/completion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ impl<F> FindVisitor<F>
Expr::Infix(ref l, ref op, ref r) => {
match (l.span.containment(&self.pos), r.span.containment(&self.pos)) {
(Ordering::Greater, Ordering::Less) => {
self.on_found.ident(current, &op.name, &op.typ)
self.on_found.ident(current, &op.value.name, &op.value.typ)
}
(_, Ordering::Greater) |
(_, Ordering::Equal) => self.visit_expr(r),
Expand Down
14 changes: 7 additions & 7 deletions check/src/rename.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,15 +217,15 @@ pub fn rename(symbols: &mut SymbolModule,
}
}
}
Expr::Infix(ref mut l, ref mut id, ref mut r) => {
if let Some(new_id) = self.rename(&id.name, &id.typ)? {
Expr::Infix(ref mut lhs, ref mut op, ref mut rhs) => {
if let Some(new_id) = self.rename(&op.value.name, &op.value.typ)? {
debug!("Rename {} = {}",
self.symbols.string(&id.name),
self.symbols.string(&op.value.name),
self.symbols.string(&new_id));
id.name = new_id;
op.value.name = new_id;
}
self.visit_expr(l);
self.visit_expr(r);
self.visit_expr(lhs);
self.visit_expr(rhs);
}
Expr::Match(ref mut expr, ref mut alts) => {
self.visit_expr(expr);
Expand Down Expand Up @@ -290,7 +290,7 @@ pub fn rename(symbols: &mut SymbolModule,

fn visit_expr(&mut self, expr: &mut SpannedExpr<Self::Ident>) {
if let Err(err) = self.rename_expr(expr) {
self.errors.error(Spanned {
self.errors.push(Spanned {
span: expr.span,
value: err,
});
Expand Down
Loading

0 comments on commit cc3d326

Please sign in to comment.