diff --git a/base/src/ast.rs b/base/src/ast.rs index 10acf39375..c00a3ff7ac 100644 --- a/base/src/ast.rs +++ b/base/src/ast.rs @@ -370,3 +370,7 @@ 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) +} diff --git a/base/src/types.rs b/base/src/types.rs index 44dc26d1ec..ee08c979db 100644 --- a/base/src/types.rs +++ b/base/src/types.rs @@ -7,7 +7,7 @@ use std::marker::PhantomData; use pretty::{DocAllocator, Arena, DocBuilder}; -use ast::DisplayEnv; +use ast::{DisplayEnv, is_operator_char}; use symbol::{Symbol, SymbolRef}; /// Trait for values which contains kinded values which can be refered by name @@ -800,6 +800,14 @@ impl<'a, I, T, E> DisplayType<'a, I, T, E> fn pretty(&self, arena: &'a Arena<'a>) -> DocBuilder<'a, Arena<'a>> where I: AsRef, { + fn ident<'b>(arena: &'b Arena<'b>, name: &'b str) -> DocBuilder<'b, Arena<'b>> { + if name.starts_with(is_operator_char) { + chain![arena; "(", name, ")"] + } else { + arena.text(name) + } + } + let p = self.prec; match *self.typ { Type::Hole => arena.text("_"), @@ -913,7 +921,7 @@ impl<'a, I, T, E> DisplayType<'a, I, T, E> _ => rhs = rhs.nest(4), } let f = chain![arena; - self.env.string(&field.name), + ident(arena, self.env.string(&field.name)), " : ", rhs.group(), if i + 1 != fields.len() { diff --git a/base/tests/types.rs b/base/tests/types.rs index 682db08dea..70f45165cf 100644 --- a/base/tests/types.rs +++ b/base/tests/types.rs @@ -66,6 +66,10 @@ fn some_record() -> ArcType<&'static str> { Field { name: "test", typ: test.clone(), + }, + Field { + name: "+", + typ: Type::function(vec![Type::int(), Type::int()], Type::int()), }]) } @@ -97,7 +101,7 @@ fn show_record() { }]); assert_eq_display!(format!("{}", typ), "{ Test a = a -> String, x : Int }"); assert_eq_display!(format!("{}", some_record()), - "{ Test a = a -> String, x : Int, test : Test a }"); + "{ Test a = a -> String, x : Int, test : Test a, (+) : Int -> Int -> Int }"); let typ = Type::record(vec![Field { name: "Test", typ: Alias::new("Test", @@ -159,7 +163,8 @@ fn show_record_multi_line() { record_looooooooooooooooooooooooooooooooooong : { Test a = a -> String, x : Int, - test : Test a + test : Test a, + (+) : Int -> Int -> Int }, looooooooooooooooooooooooooooooooooong_field : Test a }"#; diff --git a/parser/src/lexer.rs b/parser/src/lexer.rs index a1d09e86e5..dfde5e4242 100644 --- a/parser/src/lexer.rs +++ b/parser/src/lexer.rs @@ -1,6 +1,7 @@ use std::cmp::Ordering; use std::fmt; +use base::ast::is_operator_char; use base::pos::{BytePos, CharPos, Location, Span, Spanned}; use combine::primitives::{Consumed, Error as CombineError, RangeStream}; @@ -303,10 +304,6 @@ impl Contexts { } } -fn is_operator_char(c: char) -> bool { - "+-*/&|=<>".chars().any(|x| x == c) -} - pub struct Lexer<'input, I> where I: RangeStream, {