Skip to content

Commit

Permalink
Move some types out of the ast module
Browse files Browse the repository at this point in the history
  • Loading branch information
brendanzab committed Aug 14, 2016
1 parent 0c006a8 commit c1acd63
Show file tree
Hide file tree
Showing 12 changed files with 135 additions and 125 deletions.
92 changes: 2 additions & 90 deletions base/src/ast.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
//! Module containing the types which make up `gluon`'s AST (Abstract Syntax Tree)
use std::cmp::Ordering;
use std::fmt;
use std::ops::Deref;

use pos::{BytePos, CharPos};
use pos::{CharPos, Located, Span};
use symbol::Symbol;
use types::{self, Alias, AliasData, Kind, Type, TypeEnv, TypeVariable};

Expand Down Expand Up @@ -169,94 +169,6 @@ impl<Id, Env> IdentEnv for TcIdentEnv<Id, Env>
}
}

/// Representation of a location in a source file
#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash, Ord, PartialOrd)]
pub struct Location {
pub row: u32,
pub column: CharPos,
pub absolute: BytePos,
}

impl Location {
fn line_offset(mut self, offset: CharPos) -> Location {
self.column += offset;
self
}
}

impl fmt::Display for Location {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Line: {}, Column: {}", self.row, self.column)
}
}

/// Struct which represents a span in a source file
#[derive(Copy, Clone, PartialEq, Debug)]
pub struct Span {
pub start: Location,
pub end: Location,
}

impl Span {
pub fn containment(&self, location: &Location) -> Ordering {
use std::cmp::Ordering::*;
match (location.cmp(&self.start), location.cmp(&self.end)) {
(Equal, _) | (Greater, Less) => Equal,
(Less, _) => Less,
(_, Equal) | (_, Greater) => Greater,
}
}
pub fn containment_exclusive(&self, location: &Location) -> Ordering {
if self.end == *location {
Ordering::Greater
} else {
self.containment(location)
}
}
}

#[derive(Copy, Clone, PartialEq, Debug)]
pub struct Spanned<T> {
pub span: Span,
pub value: T,
}

impl<T: fmt::Display> fmt::Display for Spanned<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}: {}", self.span.start, self.value)
}
}

#[derive(Clone, Debug)]
pub struct Located<T> {
pub location: Location,
pub value: T,
}
impl<T: PartialEq> PartialEq for Located<T> {
fn eq(&self, other: &Located<T>) -> bool {
self.value == other.value
}
}
impl<T> Deref for Located<T> {
type Target = T;
fn deref(&self) -> &T {
&self.value
}
}

impl<T: fmt::Display> fmt::Display for Located<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}: {}", self.location, self.value)
}
}

pub fn located<T>(location: Location, value: T) -> Located<T> {
Located {
location: location,
value: value,
}
}

#[derive(Clone, PartialEq, Debug)]
pub enum LiteralEnum {
Byte(u8),
Expand Down
3 changes: 2 additions & 1 deletion base/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
//! Module containing a few common error wrappers which allows more information to be saved for
//! later display to the user
use std::any::Any;
use std::error::Error as StdError;
use std::fmt;

use ast::Spanned;
use pos::Spanned;

/// An error type which can represent multiple errors.
#[derive(Debug, PartialEq)]
Expand Down
94 changes: 93 additions & 1 deletion base/src/pos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
//!
//! [libsyntax_pos]: https://github.com/rust-lang/rust/blob/ae774103501337ed63b42b673c6c4fdbf369e80e/src/libsyntax_pos/lib.rs
use std::cmp::Ordering;
use std::fmt;
use std::ops::{Add, AddAssign, Sub, SubAssign};
use std::ops::{Add, AddAssign, Deref, Sub, SubAssign};

/// A byte offset in a source string
#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
Expand Down Expand Up @@ -104,3 +105,94 @@ impl fmt::Display for CharPos {
self.0.fmt(f)
}
}

/// A location in a source file
#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash, Ord, PartialOrd)]
pub struct Location {
pub row: u32,
pub column: CharPos,
pub absolute: BytePos,
}

impl Location {
pub fn line_offset(mut self, offset: CharPos) -> Location {
self.column += offset;
self
}
}

impl fmt::Display for Location {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Line: {}, Column: {}", self.row, self.column)
}
}

/// A span between two locations in a source file
#[derive(Copy, Clone, PartialEq, Debug)]
pub struct Span {
pub start: Location,
pub end: Location,
}

impl Span {
pub fn containment(&self, location: &Location) -> Ordering {
use std::cmp::Ordering::*;
match (location.cmp(&self.start), location.cmp(&self.end)) {
(Equal, _) | (Greater, Less) => Equal,
(Less, _) => Less,
(_, Equal) | (_, Greater) => Greater,
}
}

pub fn containment_exclusive(&self, location: &Location) -> Ordering {
if self.end == *location {
Ordering::Greater
} else {
self.containment(location)
}
}
}

#[derive(Copy, Clone, PartialEq, Debug)]
pub struct Spanned<T> {
pub span: Span,
pub value: T,
}

impl<T: fmt::Display> fmt::Display for Spanned<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}: {}", self.span.start, self.value)
}
}

#[derive(Clone, Debug)]
pub struct Located<T> {
pub location: Location,
pub value: T,
}

impl<T: PartialEq> PartialEq for Located<T> {
fn eq(&self, other: &Located<T>) -> bool {
self.value == other.value
}
}

impl<T> Deref for Located<T> {
type Target = T;
fn deref(&self) -> &T {
&self.value
}
}

impl<T: fmt::Display> fmt::Display for Located<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}: {}", self.location, self.value)
}
}

pub fn located<T>(location: Location, value: T) -> Located<T> {
Located {
location: location,
value: value,
}
}
5 changes: 3 additions & 2 deletions check/src/completion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
use std::iter::once;
use std::cmp::Ordering;

use base::ast::{self, DisplayEnv, Expr, LExpr, Location, LPattern, Pattern, TcIdent, Typed};
use base::ast::{DisplayEnv, Expr, LExpr, LPattern, Pattern, TcIdent, Typed};
use base::instantiate;
use base::pos::{Location, Span};
use base::scoped_map::ScopedMap;
use base::symbol::Symbol;
use base::types::{TcType, Type, TypeEnv};
Expand Down Expand Up @@ -111,7 +112,7 @@ struct FindVisitor<'a, F> {
impl<'a, F> FindVisitor<'a, F> {
fn select_spanned<'e, I, S, T>(&self, iter: I, mut span: S) -> (bool, Option<&'e T>)
where I: IntoIterator<Item = &'e T>,
S: FnMut(&T) -> ast::Span
S: FnMut(&T) -> Span
{
let mut iter = iter.into_iter().peekable();
let mut prev = None;
Expand Down
5 changes: 3 additions & 2 deletions check/src/rename.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::fmt;

use base::ast::{self, DisplayEnv, Expr, LExpr, Location, MutVisitor, Spanned, Typed};
use base::ast::{self, DisplayEnv, Expr, LExpr, MutVisitor, Typed};
use base::pos::{self, Location, Spanned};
use base::error::Errors;
use base::fnv::FnvMap;
use base::scoped_map::ScopedMap;
Expand Down Expand Up @@ -213,7 +214,7 @@ pub fn rename(symbols: &mut SymbolModule,
None => {
if let Some(new_id) = try!(self.rename(id, &field.typ)) {
debug!("Rename record field {} = {}", id, new_id);
*maybe_expr = Some(ast::located(expr.location,
*maybe_expr = Some(pos::located(expr.location,
Expr::Identifier(TcIdent {
name: new_id,
typ: field.typ.clone(),
Expand Down
31 changes: 16 additions & 15 deletions check/src/typecheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ use std::mem;

use base::scoped_map::ScopedMap;
use base::ast::{self, Typed, DisplayEnv, MutVisitor};
use base::types::{self, RcKind, Type, Generic, Kind};
use base::error::Errors;
use base::instantiate::{self, Instantiator};
use base::pos::{Span, Spanned};
use base::symbol::{Symbol, SymbolRef, SymbolModule, Symbols};
use base::types::{self, RcKind, Type, Generic, Kind};
use base::types::{KindEnv, TypeEnv, PrimitiveEnv, TcIdent, Alias, AliasData, TcType, TypeVariable};
use base::instantiate::{self, Instantiator};
use kindcheck::{self, KindCheck};
use substitution::Substitution;
use unify::Error as UnifyError;
Expand Down Expand Up @@ -207,13 +208,13 @@ pub struct Typecheck<'a> {
original_symbols: ScopedMap<Symbol, Symbol>,
subs: Substitution<TcType>,
inst: Instantiator,
errors: Errors<ast::Spanned<TypeError<Symbol>>>,
errors: Errors<Spanned<TypeError<Symbol>>>,
/// Type variables `let test: a -> b` (`a` and `b`)
type_variables: ScopedMap<Symbol, TcType>,
}

/// Error returned when unsuccessfully typechecking an expression
pub type Error = Errors<ast::Spanned<TypeError<Symbol>>>;
pub type Error = Errors<Spanned<TypeError<Symbol>>>;

impl<'a> Typecheck<'a> {
/// Create a new typechecker which typechecks expressions in `module`
Expand All @@ -237,8 +238,8 @@ impl<'a> Typecheck<'a> {
}
}

fn error(&mut self, span: ast::Span, error: TypeError<Symbol>) -> TcType {
self.errors.error(ast::Spanned {
fn error(&mut self, span: Span, error: TypeError<Symbol>) -> TcType {
self.errors.error(Spanned {
span: span,
value: error,
});
Expand All @@ -249,7 +250,7 @@ impl<'a> Typecheck<'a> {
self.environment.get_bool().clone()
}

fn find_at(&mut self, span: ast::Span, id: &Symbol) -> TcType {
fn find_at(&mut self, span: Span, id: &Symbol) -> TcType {
match self.find(id) {
Ok(typ) => typ,
Err(err) => self.error(span, err),
Expand Down Expand Up @@ -402,8 +403,8 @@ impl<'a> Typecheck<'a> {
Ok(typ)
}
Err(errors) => {
for ast::Spanned { span, value } in errors.errors {
self.errors.error(ast::Spanned {
for Spanned { span, value } in errors.errors {
self.errors.error(Spanned {
span: span,
value: value.into(),
});
Expand Down Expand Up @@ -444,7 +445,7 @@ impl<'a> Typecheck<'a> {
}
Err(err) => {
returned_type = self.subs.new_var();
self.errors.error(ast::Spanned {
self.errors.error(Spanned {
span: expr.span(&ast::TcIdentEnvWrapper(&self.symbols)),
value: err,
});
Expand Down Expand Up @@ -984,7 +985,7 @@ impl<'a> Typecheck<'a> {
// Finally insert the declared types into the global scope
for bind in bindings {
if self.environment.stack_types.get(&bind.name).is_some() {
self.errors.error(ast::Spanned {
self.errors.error(Spanned {
span: expr.span(&ast::TcIdentEnvWrapper(&self.symbols)),
value: DuplicateTypeDefinition(bind.name.clone()),
});
Expand Down Expand Up @@ -1226,7 +1227,7 @@ impl<'a> Typecheck<'a> {
}

fn merge_signature(&mut self,
span: ast::Span,
span: Span,
level: u32,
expected: &TcType,
mut actual: TcType)
Expand All @@ -1245,7 +1246,7 @@ impl<'a> Typecheck<'a> {
actual = self.subs.set_type(actual);
let err =
TypeError::Unification(expected, actual, apply_subs(&self.subs, errors.errors));
self.errors.error(ast::Spanned {
self.errors.error(Spanned {
span: span,
value: err,
});
Expand All @@ -1254,11 +1255,11 @@ impl<'a> Typecheck<'a> {
}
}

fn unify_span(&mut self, span: ast::Span, expected: &TcType, actual: TcType) -> TcType {
fn unify_span(&mut self, span: Span, expected: &TcType, actual: TcType) -> TcType {
match self.unify(expected, actual) {
Ok(typ) => typ,
Err(err) => {
self.errors.error(ast::Spanned {
self.errors.error(Spanned {
span: span,
value: err,
});
Expand Down
4 changes: 2 additions & 2 deletions check/tests/completion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ extern crate gluon_base as base;
extern crate gluon_parser as parser;
extern crate gluon_check as check;

use base::ast::{self, Location};
use base::pos::{BytePos, CharPos};
use base::ast;
use base::pos::{BytePos, CharPos, Location};
use base::types::{Type, TcType};
use check::completion;

Expand Down
Loading

0 comments on commit c1acd63

Please sign in to comment.