diff options
author | Nadrieril Feneanar | 2019-12-24 20:41:22 +0000 |
---|---|---|
committer | GitHub | 2019-12-24 20:41:22 +0000 |
commit | 057d645a90a6b57f40f72eb7e347ba2c6219777e (patch) | |
tree | 151473a0a6cb7222fd6b4eb3abf1cfacca012aad /dhall/src/syntax | |
parent | 06e75c919d999c310f8ca1c151c6a5ad6918ca08 (diff) | |
parent | 18dd5ba3ae94fd89dd27c0ae3891ac3e43ace350 (diff) |
Merge pull request #124 from Nadrieril/catchup-spec
Catchup on standard changes
Diffstat (limited to 'dhall/src/syntax')
-rw-r--r-- | dhall/src/syntax/ast/expr.rs | 4 | ||||
-rw-r--r-- | dhall/src/syntax/ast/visitor.rs | 7 | ||||
-rw-r--r-- | dhall/src/syntax/binary/decode.rs | 5 | ||||
-rw-r--r-- | dhall/src/syntax/binary/encode.rs | 1 | ||||
-rw-r--r-- | dhall/src/syntax/text/parser.rs | 81 | ||||
-rw-r--r-- | dhall/src/syntax/text/printer.rs | 31 |
6 files changed, 96 insertions, 33 deletions
diff --git a/dhall/src/syntax/ast/expr.rs b/dhall/src/syntax/ast/expr.rs index 48c48d8..68cb524 100644 --- a/dhall/src/syntax/ast/expr.rs +++ b/dhall/src/syntax/ast/expr.rs @@ -79,6 +79,8 @@ pub enum Builtin { NaturalSubtract, IntegerToDouble, IntegerShow, + IntegerNegate, + IntegerClamp, DoubleShow, ListBuild, ListFold, @@ -163,6 +165,8 @@ pub enum ExprKind<SubExpr, Embed> { Projection(SubExpr, DupTreeSet<Label>), /// `e.(t)` ProjectionByExpr(SubExpr, SubExpr), + /// `x::y` + Completion(SubExpr, SubExpr), /// `./some/path` Import(Import<SubExpr>), /// Embeds the result of resolving an import diff --git a/dhall/src/syntax/ast/visitor.rs b/dhall/src/syntax/ast/visitor.rs index b557995..424048b 100644 --- a/dhall/src/syntax/ast/visitor.rs +++ b/dhall/src/syntax/ast/visitor.rs @@ -164,6 +164,9 @@ where ProjectionByExpr(e, x) => { ProjectionByExpr(v.visit_subexpr(e)?, v.visit_subexpr(x)?) } + Completion(e, x) => { + Completion(v.visit_subexpr(e)?, v.visit_subexpr(x)?) + } Assert(e) => Assert(v.visit_subexpr(e)?), Import(i) => Import(i.traverse_ref(|e| v.visit_subexpr(e))?), Embed(a) => Embed(v.visit_embed(a)?), @@ -281,6 +284,10 @@ where v.visit_subexpr(e)?; v.visit_subexpr(x)?; } + Completion(x, y) => { + v.visit_subexpr(x)?; + v.visit_subexpr(y)?; + } Assert(e) => v.visit_subexpr(e)?, Import(i) => i.traverse_mut(|e| v.visit_subexpr(e))?, Embed(a) => v.visit_embed(a)?, diff --git a/dhall/src/syntax/binary/decode.rs b/dhall/src/syntax/binary/decode.rs index 254ab07..c18deb5 100644 --- a/dhall/src/syntax/binary/decode.rs +++ b/dhall/src/syntax/binary/decode.rs @@ -98,6 +98,11 @@ fn cbor_value_to_dhall(data: &cbor::Value) -> Result<DecodedExpr, DecodeError> { let l = Label::from(l.as_str()); Pi(l, x, y) } + [U64(3), U64(13), x, y] => { + let x = cbor_value_to_dhall(&x)?; + let y = cbor_value_to_dhall(&y)?; + Completion(x, y) + } [U64(3), U64(n), x, y] => { let x = cbor_value_to_dhall(&x)?; let y = cbor_value_to_dhall(&y)?; diff --git a/dhall/src/syntax/binary/encode.rs b/dhall/src/syntax/binary/encode.rs index 25a545c..5e79f2d 100644 --- a/dhall/src/syntax/binary/encode.rs +++ b/dhall/src/syntax/binary/encode.rs @@ -164,6 +164,7 @@ where ProjectionByExpr(x, y) => { ser_seq!(ser; tag(10), expr(x), vec![expr(y)]) } + Completion(x, y) => ser_seq!(ser; tag(3), tag(13), expr(x), expr(y)), Import(import) => serialize_import(ser, import), Embed(_) => unimplemented!( "An expression with resolved imports cannot be binary-encoded" diff --git a/dhall/src/syntax/text/parser.rs b/dhall/src/syntax/text/parser.rs index 832472b..feaa2a5 100644 --- a/dhall/src/syntax/text/parser.rs +++ b/dhall/src/syntax/text/parser.rs @@ -57,6 +57,8 @@ impl crate::syntax::Builtin { "Natural/subtract" => Some(NaturalSubtract), "Integer/toDouble" => Some(IntegerToDouble), "Integer/show" => Some(IntegerShow), + "Integer/negate" => Some(IntegerNegate), + "Integer/clamp" => Some(IntegerClamp), "Double/show" => Some(DoubleShow), "List/build" => Some(ListBuild), "List/fold" => Some(ListFold), @@ -181,6 +183,15 @@ impl DhallParser { Ok(Label::from(input.as_str())) } + // TODO: waiting for https://github.com/dhall-lang/dhall-lang/pull/871 + // #[alias(label)] + // fn any_label_or_some(input: ParseInput) -> ParseResult<Label> { + // Ok(match_nodes!(input.into_children(); + // [label(l)] => l, + // [Some_(_)] => Label::from("Some"), + // )) + // } + fn double_quote_literal(input: ParseInput) -> ParseResult<ParsedText> { Ok(match_nodes!(input.into_children(); [double_quote_chunk(chunks)..] => { @@ -215,19 +226,18 @@ impl DhallParser { "t" => "\t".to_owned(), // "uXXXX" or "u{XXXXX}" s => { - use std::convert::{TryFrom, TryInto}; + use std::convert::TryInto; let s = &s[1..]; let s = if &s[0..1] == "{" { &s[1..s.len() - 1] } else { - &s[0..s.len()] + s }; if s.len() > 8 { Err(input.error(format!( - "Escape sequences can't have more than 8 chars: \"{}\"", - s + "Escape sequences can't have more than 8 chars" )))? } @@ -240,12 +250,10 @@ impl DhallParser { // `s` has length 8, so `bytes` has length 4 let bytes: &[u8] = &hex::decode(s).unwrap(); let i = u32::from_be_bytes(bytes.try_into().unwrap()); - let c = char::try_from(i).unwrap(); match i { - 0xD800..=0xDFFF => { - let c_ecapsed = c.escape_unicode(); - Err(input.error(format!("Escape sequences can't contain surrogate pairs: \"{}\"", c_ecapsed)))? - } + 0xD800..=0xDFFF => Err(input.error(format!( + "Escape sequences can't contain surrogate pairs" + )))?, 0x0FFFE..=0x0FFFF | 0x1FFFE..=0x1FFFF | 0x2FFFE..=0x2FFFF @@ -262,12 +270,12 @@ impl DhallParser { | 0xDFFFE..=0xDFFFF | 0xEFFFE..=0xEFFFF | 0xFFFFE..=0xFFFFF - | 0x10_FFFE..=0x10_FFFF => { - let c_ecapsed = c.escape_unicode(); - Err(input.error(format!("Escape sequences can't contain non-characters: \"{}\"", c_ecapsed)))? - } + | 0x10_FFFE..=0x10_FFFF => Err(input.error(format!( + "Escape sequences can't contain non-characters" + )))?, _ => {} } + let c: char = i.try_into().unwrap(); std::iter::once(c).collect() } }) @@ -384,19 +392,27 @@ impl DhallParser { } fn natural_literal(input: ParseInput) -> ParseResult<Natural> { - input - .as_str() - .trim() - .parse() - .map_err(|e| input.error(format!("{}", e))) + let s = input.as_str().trim(); + if s.starts_with("0x") { + let without_prefix = s.trim_start_matches("0x"); + usize::from_str_radix(without_prefix, 16) + .map_err(|e| input.error(format!("{}", e))) + } else { + s.parse().map_err(|e| input.error(format!("{}", e))) + } } fn integer_literal(input: ParseInput) -> ParseResult<Integer> { - input - .as_str() - .trim() - .parse() - .map_err(|e| input.error(format!("{}", e))) + let s = input.as_str().trim(); + let (sign, rest) = (&s[0..1], &s[1..]); + if rest.starts_with("0x") { + let without_prefix = + sign.to_owned() + rest.trim_start_matches("0x"); + isize::from_str_radix(&without_prefix, 16) + .map_err(|e| input.error(format!("{}", e))) + } else { + s.parse().map_err(|e| input.error(format!("{}", e))) + } } #[alias(expression, shortcut = true)] @@ -766,6 +782,25 @@ impl DhallParser { } #[alias(expression, shortcut = true)] + fn completion_expression(input: ParseInput) -> ParseResult<Expr> { + Ok(match_nodes!(input.children(); + [expression(e)] => e, + [expression(first), expression(rest)..] => { + rest.fold( + first, + |acc, e| { + spanned_union( + acc.span(), + e.span(), + Completion(acc, e), + ) + } + ) + }, + )) + } + + #[alias(expression, shortcut = true)] fn selector_expression(input: ParseInput) -> ParseResult<Expr> { Ok(match_nodes!(input.children(); [expression(e)] => e, diff --git a/dhall/src/syntax/text/printer.rs b/dhall/src/syntax/text/printer.rs index 78942ed..96f4c2a 100644 --- a/dhall/src/syntax/text/printer.rs +++ b/dhall/src/syntax/text/printer.rs @@ -64,6 +64,9 @@ impl<E: Display + Clone> UnspannedExpr<E> { Field(a, b) => Field(a.phase(Primitive), b), Projection(e, ls) => Projection(e.phase(Primitive), ls), ProjectionByExpr(a, b) => ProjectionByExpr(a.phase(Primitive), b), + Completion(a, b) => { + Completion(a.phase(Primitive), b.phase(Primitive)) + } e => e, } } @@ -89,9 +92,10 @@ impl<E: Display + Clone> UnspannedExpr<E> { // Precedence is magically handled by the ordering of BinOps. ExprKind::BinOp(op, _, _) => phase > PrintPhase::BinOp(*op), ExprKind::App(_, _) => phase > PrintPhase::App, - Field(_, _) | Projection(_, _) | ProjectionByExpr(_, _) => { - phase > PrintPhase::Import - } + Field(_, _) + | Projection(_, _) + | ProjectionByExpr(_, _) + | Completion(_, _) => phase > PrintPhase::Import, _ => false, }; @@ -189,13 +193,6 @@ impl<SE: Display + Clone, E: Display> Display for ExprKind<SE, E> { Field(a, b) => { write!(f, "{}.{}", a, b)?; } - Projection(e, ls) => { - write!(f, "{}.", e)?; - fmt_list("{ ", ", ", " }", ls, f, Display::fmt)?; - } - ProjectionByExpr(a, b) => { - write!(f, "{}.({})", a, b)?; - } Var(a) => a.fmt(f)?, Const(k) => k.fmt(f)?, Builtin(v) => v.fmt(f)?, @@ -224,6 +221,16 @@ impl<SE: Display + Clone, E: Display> Display for ExprKind<SE, E> { } Ok(()) })?, + Projection(e, ls) => { + write!(f, "{}.", e)?; + fmt_list("{ ", ", ", " }", ls, f, Display::fmt)?; + } + ProjectionByExpr(a, b) => { + write!(f, "{}.({})", a, b)?; + } + Completion(a, b) => { + write!(f, "{}::{}", a, b)?; + } Import(a) => a.fmt(f)?, Embed(a) => a.fmt(f)?, } @@ -322,6 +329,8 @@ impl Display for NaiveDouble { f.write_str("-Infinity") } else if v.is_nan() { f.write_str("NaN") + } else if v == 0.0 && v.is_sign_negative() { + f.write_str("-0.0") } else { let s = format!("{}", v); if s.contains('e') || s.contains('.') { @@ -459,6 +468,8 @@ impl Display for Builtin { NaturalShow => "Natural/show", NaturalSubtract => "Natural/subtract", IntegerToDouble => "Integer/toDouble", + IntegerNegate => "Integer/negate", + IntegerClamp => "Integer/clamp", IntegerShow => "Integer/show", DoubleShow => "Double/show", ListBuild => "List/build", |