From bc6159c5380e728a3e41f52005a13c4f492e90fc Mon Sep 17 00:00:00 2001 From: Skgland Date: Sat, 6 Feb 2021 19:32:52 +0100 Subject: [PATCH] change prolog_parse_rebis to use 2018 edition rust so all crates use the same edition --- crates/prolog_parser/Cargo.toml | 1 + crates/prolog_parser/src/ast.rs | 351 +++++++++--------- crates/prolog_parser/src/lexer.rs | 303 ++++++++-------- crates/prolog_parser/src/lib.rs | 18 +- crates/prolog_parser/src/parser.rs | 561 +++++++++++++++-------------- 5 files changed, 626 insertions(+), 608 deletions(-) diff --git a/crates/prolog_parser/Cargo.toml b/crates/prolog_parser/Cargo.toml index dfdc5a32..83114a6e 100644 --- a/crates/prolog_parser/Cargo.toml +++ b/crates/prolog_parser/Cargo.toml @@ -2,6 +2,7 @@ name = "prolog_parser_rebis" version = "0.8.68" authors = ["Mark Thom "] +edition = "2018" repository = "https://github.com/mthom/prolog_parser" description = " An operator precedence parser for the Rebis development version of Scryer Prolog, an up and coming ISO Prolog implementation." license = "BSD-3-Clause" diff --git a/crates/prolog_parser/src/ast.rs b/crates/prolog_parser/src/ast.rs index d337e9c7..ba480415 100644 --- a/crates/prolog_parser/src/ast.rs +++ b/crates/prolog_parser/src/ast.rs @@ -1,8 +1,8 @@ -use rug::{Integer, Rational}; +use crate::tabled_rc::*; use ordered_float::*; -use tabled_rc::*; +use rug::{Integer, Rational}; -use put_back_n::*; +use crate::put_back_n::*; use std::cell::Cell; use std::cmp::Ordering; @@ -27,112 +27,140 @@ pub const MAX_ARITY: usize = 1023; pub const XFX: u32 = 0x0001; pub const XFY: u32 = 0x0002; pub const YFX: u32 = 0x0004; -pub const XF: u32 = 0x0010; -pub const YF: u32 = 0x0020; -pub const FX: u32 = 0x0040; -pub const FY: u32 = 0x0080; +pub const XF: u32 = 0x0010; +pub const YF: u32 = 0x0020; +pub const FX: u32 = 0x0040; +pub const FY: u32 = 0x0080; pub const DELIMITER: u32 = 0x0100; -pub const TERM: u32 = 0x1000; +pub const TERM: u32 = 0x1000; pub const LTERM: u32 = 0x3000; pub const NEGATIVE_SIGN: u32 = 0x0200; #[macro_export] macro_rules! clause_name { - ($name: expr, $tbl: expr) => ( + ($name: expr, $tbl: expr) => { ClauseName::User(TabledRc::new($name, $tbl.clone())) - ) ; - ($name: expr) => ( + }; + ($name: expr) => { ClauseName::BuiltIn($name) - ) + }; } #[macro_export] macro_rules! atom { - ($e:expr, $tbl:expr) => ( + ($e:expr, $tbl:expr) => { Constant::Atom(ClauseName::User(tabled_rc!($e, $tbl)), None) - ); - ($e:expr) => ( + }; + ($e:expr) => { Constant::Atom(clause_name!($e), None) - ) + }; } #[macro_export] macro_rules! rc_atom { - ($e:expr) => ( + ($e:expr) => { Rc::new(String::from($e)) - ) + }; } macro_rules! is_term { - ($x:expr) => ( ($x & TERM) != 0 ) + ($x:expr) => { + ($x & TERM) != 0 + }; } macro_rules! is_lterm { - ($x:expr) => ( ($x & LTERM) != 0 ) + ($x:expr) => { + ($x & LTERM) != 0 + }; } macro_rules! is_op { - ($x:expr) => ( $x & (XF | YF | FX | FY | XFX | XFY | YFX) != 0 ) + ($x:expr) => { + $x & (XF | YF | FX | FY | XFX | XFY | YFX) != 0 + }; } macro_rules! is_negate { - ($x:expr) => ( ($x & NEGATIVE_SIGN) != 0 ) + ($x:expr) => { + ($x & NEGATIVE_SIGN) != 0 + }; } #[macro_export] macro_rules! is_prefix { - ($x:expr) => ( $x & (FX | FY) != 0 ) + ($x:expr) => { + $x & (FX | FY) != 0 + }; } #[macro_export] macro_rules! is_postfix { - ($x:expr) => ( $x & (XF | YF) != 0 ) + ($x:expr) => { + $x & (XF | YF) != 0 + }; } #[macro_export] macro_rules! is_infix { - ($x:expr) => ( ($x & (XFX | XFY | YFX)) != 0 ) + ($x:expr) => { + ($x & (XFX | XFY | YFX)) != 0 + }; } #[macro_export] macro_rules! is_xfx { - ($x:expr) => ( ($x & XFX) != 0 ) + ($x:expr) => { + ($x & XFX) != 0 + }; } #[macro_export] macro_rules! is_xfy { - ($x:expr) => ( ($x & XFY) != 0 ) + ($x:expr) => { + ($x & XFY) != 0 + }; } #[macro_export] macro_rules! is_yfx { - ($x:expr) => ( ($x & YFX) != 0 ) + ($x:expr) => { + ($x & YFX) != 0 + }; } #[macro_export] macro_rules! is_yf { - ($x:expr) => ( ($x & YF) != 0 ) + ($x:expr) => { + ($x & YF) != 0 + }; } #[macro_export] macro_rules! is_xf { - ($x:expr) => ( ($x & XF) != 0 ) + ($x:expr) => { + ($x & XF) != 0 + }; } #[macro_export] macro_rules! is_fx { - ($x:expr) => ( ($x & FX) != 0 ) + ($x:expr) => { + ($x & FX) != 0 + }; } #[macro_export] macro_rules! is_fy { - ($x:expr) => ( ($x & FY) != 0 ) + ($x:expr) => { + ($x & FY) != 0 + }; } #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum RegType { Perm(usize), - Temp(usize) + Temp(usize), } impl Default for RegType { @@ -144,14 +172,14 @@ impl Default for RegType { impl RegType { pub fn reg_num(self) -> usize { match self { - RegType::Perm(reg_num) | RegType::Temp(reg_num) => reg_num + RegType::Perm(reg_num) | RegType::Temp(reg_num) => reg_num, } } pub fn is_perm(self) -> bool { match self { RegType::Perm(_) => true, - _ => false + _ => false, } } } @@ -160,7 +188,7 @@ impl fmt::Display for RegType { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { &RegType::Perm(val) => write!(f, "Y{}", val), - &RegType::Temp(val) => write!(f, "X{}", val) + &RegType::Temp(val) => write!(f, "X{}", val), } } } @@ -168,13 +196,13 @@ impl fmt::Display for RegType { #[derive(Debug, PartialEq, Eq, Clone, Copy)] pub enum VarReg { ArgAndNorm(RegType, usize), - Norm(RegType) + Norm(RegType), } impl VarReg { pub fn norm(self) -> RegType { match self { - VarReg::ArgAndNorm(reg, _) | VarReg::Norm(reg) => reg + VarReg::ArgAndNorm(reg, _) | VarReg::Norm(reg) => reg, } } } @@ -184,10 +212,8 @@ impl fmt::Display for VarReg { match self { &VarReg::Norm(RegType::Perm(reg)) => write!(f, "Y{}", reg), &VarReg::Norm(RegType::Temp(reg)) => write!(f, "X{}", reg), - &VarReg::ArgAndNorm(RegType::Perm(reg), arg) => - write!(f, "Y{} A{}", reg, arg), - &VarReg::ArgAndNorm(RegType::Temp(reg), arg) => - write!(f, "X{} A{}", reg, arg) + &VarReg::ArgAndNorm(RegType::Perm(reg), arg) => write!(f, "Y{} A{}", reg, arg), + &VarReg::ArgAndNorm(RegType::Temp(reg), arg) => write!(f, "X{} A{}", reg, arg), } } } @@ -200,28 +226,30 @@ impl Default for VarReg { #[macro_export] macro_rules! temp_v { - ($x:expr) => ( + ($x:expr) => { RegType::Temp($x) - ) + }; } #[macro_export] macro_rules! perm_v { - ($x:expr) => ( + ($x:expr) => { RegType::Perm($x) - ) + }; } #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] pub enum GenContext { - Head, Mid(usize), Last(usize) // Mid & Last: chunk_num + Head, + Mid(usize), + Last(usize), // Mid & Last: chunk_num } impl GenContext { pub fn chunk_num(self) -> usize { match self { GenContext::Head => 0, - GenContext::Mid(cn) | GenContext::Last(cn) => cn + GenContext::Mid(cn) | GenContext::Last(cn) => cn, } } } @@ -247,18 +275,22 @@ pub type OpDir = HashMap; #[derive(Debug, Clone, Copy)] pub struct MachineFlags { - pub double_quotes: DoubleQuotes + pub double_quotes: DoubleQuotes, } impl Default for MachineFlags { fn default() -> Self { - MachineFlags { double_quotes: DoubleQuotes::default() } + MachineFlags { + double_quotes: DoubleQuotes::default(), + } } } #[derive(Debug, Clone, Copy)] pub enum DoubleQuotes { - Atom, Chars, Codes + Atom, + Chars, + Codes, } impl DoubleQuotes { @@ -296,10 +328,10 @@ impl Default for DoubleQuotes { pub fn default_op_dir() -> OpDir { let mut op_dir = OpDir::new(); - op_dir.insert((clause_name!(":-"), Fixity::In), OpDirValue::new(XFX, 1200)); - op_dir.insert((clause_name!(":-"), Fixity::Pre), OpDirValue::new(FX, 1200)); - op_dir.insert((clause_name!("?-"), Fixity::Pre), OpDirValue::new(FX, 1200)); - op_dir.insert((clause_name!(","), Fixity::In), OpDirValue::new(XFY, 1000)); + op_dir.insert((clause_name!(":-"), Fixity::In), OpDirValue::new(XFX, 1200)); + op_dir.insert((clause_name!(":-"), Fixity::Pre), OpDirValue::new(FX, 1200)); + op_dir.insert((clause_name!("?-"), Fixity::Pre), OpDirValue::new(FX, 1200)); + op_dir.insert((clause_name!(","), Fixity::In), OpDirValue::new(XFY, 1000)); op_dir } @@ -307,7 +339,7 @@ pub fn default_op_dir() -> OpDir { #[derive(Debug, Clone)] pub enum ArithmeticError { NonEvaluableFunctor(Constant, usize), - UninstantiatedVar + UninstantiatedVar, } #[derive(Debug)] @@ -321,47 +353,35 @@ pub enum ParserError { MissingQuote(usize, usize), NonPrologChar(usize, usize), ParseBigInt(usize, usize), - Utf8Error(usize, usize) + Utf8Error(usize, usize), } impl ParserError { pub fn line_and_col_num(&self) -> Option<(usize, usize)> { match self { &ParserError::BackQuotedString(line_num, col_num) - | &ParserError::UnexpectedChar(_, line_num, col_num) - | &ParserError::IncompleteReduction(line_num, col_num) - | &ParserError::MissingQuote(line_num, col_num) - | &ParserError::NonPrologChar(line_num, col_num) - | &ParserError::ParseBigInt(line_num, col_num) - | &ParserError::Utf8Error(line_num, col_num) => - Some((line_num, col_num)), - _ => - None + | &ParserError::UnexpectedChar(_, line_num, col_num) + | &ParserError::IncompleteReduction(line_num, col_num) + | &ParserError::MissingQuote(line_num, col_num) + | &ParserError::NonPrologChar(line_num, col_num) + | &ParserError::ParseBigInt(line_num, col_num) + | &ParserError::Utf8Error(line_num, col_num) => Some((line_num, col_num)), + _ => None, } } pub fn as_str(&self) -> &'static str { match self { - &ParserError::BackQuotedString(..) => - "back_quoted_string", - &ParserError::UnexpectedChar(..) => - "unexpected_char", - &ParserError::UnexpectedEOF => - "unexpected_end_of_file", - &ParserError::IncompleteReduction(..) => - "incomplete_reduction", - &ParserError::InvalidSingleQuotedCharacter(..) => - "invalid_single_quoted_character", - &ParserError::IO(_) => - "input_output_error", - &ParserError::MissingQuote(..) => - "missing_quote", - &ParserError::NonPrologChar(..) => - "non_prolog_character", - &ParserError::ParseBigInt(..) => - "cannot_parse_big_int", - &ParserError::Utf8Error(..) => - "utf8_conversion_error", + &ParserError::BackQuotedString(..) => "back_quoted_string", + &ParserError::UnexpectedChar(..) => "unexpected_char", + &ParserError::UnexpectedEOF => "unexpected_end_of_file", + &ParserError::IncompleteReduction(..) => "incomplete_reduction", + &ParserError::InvalidSingleQuotedCharacter(..) => "invalid_single_quoted_character", + &ParserError::IO(_) => "input_output_error", + &ParserError::MissingQuote(..) => "missing_quote", + &ParserError::NonPrologChar(..) => "non_prolog_character", + &ParserError::ParseBigInt(..) => "cannot_parse_big_int", + &ParserError::Utf8Error(..) => "utf8_conversion_error", } } } @@ -382,39 +402,38 @@ impl From<&IOError> for ParserError { } } - #[derive(Debug, Clone, Copy)] pub struct CompositeOpDir<'a, 'b> { pub primary_op_dir: Option<&'b OpDir>, pub secondary_op_dir: &'a OpDir, } -impl<'a, 'b> CompositeOpDir<'a, 'b> -{ +impl<'a, 'b> CompositeOpDir<'a, 'b> { #[inline] pub fn new(secondary_op_dir: &'a OpDir, primary_op_dir: Option<&'b OpDir>) -> Self { - CompositeOpDir { primary_op_dir, secondary_op_dir } + CompositeOpDir { + primary_op_dir, + secondary_op_dir, + } } #[inline] - pub(crate) - fn get(&self, name: ClauseName, fixity: Fixity) -> Option<&OpDirValue> - { - let entry = - if let Some(ref primary_op_dir) = &self.primary_op_dir { - primary_op_dir.get(&(name.clone(), fixity)) - } else { - None - }; + pub(crate) fn get(&self, name: ClauseName, fixity: Fixity) -> Option<&OpDirValue> { + let entry = if let Some(ref primary_op_dir) = &self.primary_op_dir { + primary_op_dir.get(&(name.clone(), fixity)) + } else { + None + }; entry.or_else(move || self.secondary_op_dir.get(&(name, fixity))) } } - #[derive(Debug, Clone, Copy, Eq, Hash, PartialEq, PartialOrd, Ord)] pub enum Fixity { - In, Post, Pre + In, + Post, + Pre, } #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] @@ -496,28 +515,21 @@ pub enum Constant { impl fmt::Display for Constant { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - &Constant::Atom(ref atom, _) => + &Constant::Atom(ref atom, _) => { if atom.as_str().chars().any(|c| "`.$'\" ".contains(c)) { write!(f, "'{}'", atom.as_str()) } else { write!(f, "{}", atom.as_str()) - }, - &Constant::Char(c) => - write!(f, "'{}'", c as u32), - &Constant::EmptyList => - write!(f, "[]"), - &Constant::Fixnum(n) => - write!(f, "{}", n), - &Constant::Integer(ref n) => - write!(f, "{}", n), - &Constant::Rational(ref n) => - write!(f, "{}", n), - &Constant::Float(ref n) => - write!(f, "{}", n), - &Constant::String(ref s) => - write!(f, "\"{}\"", &s), - &Constant::Usize(integer) => - write!(f, "u{}", integer), + } + } + &Constant::Char(c) => write!(f, "'{}'", c as u32), + &Constant::EmptyList => write!(f, "[]"), + &Constant::Fixnum(n) => write!(f, "{}", n), + &Constant::Integer(ref n) => write!(f, "{}", n), + &Constant::Rational(ref n) => write!(f, "{}", n), + &Constant::Float(ref n) => write!(f, "{}", n), + &Constant::String(ref s) => write!(f, "\"{}\"", &s), + &Constant::Usize(integer) => write!(f, "u{}", integer), } } } @@ -526,37 +538,27 @@ impl PartialEq for Constant { fn eq(&self, other: &Constant) -> bool { match (self, other) { (&Constant::Atom(ref atom, _), &Constant::Char(c)) - | (&Constant::Char(c), &Constant::Atom(ref atom, _)) => { - atom.is_char() && Some(c) == atom.as_str().chars().next() - }, - (&Constant::Atom(ref a1, _), &Constant::Atom(ref a2, _)) => - a1.as_str() == a2.as_str(), - (&Constant::Char(c1), &Constant::Char(c2)) => - c1 == c2, - (&Constant::Fixnum(n1), &Constant::Fixnum(n2)) => - n1 == n2, - (&Constant::Fixnum(n1), &Constant::Integer(ref n2)) | - (&Constant::Integer(ref n2), &Constant::Fixnum(n1)) => { + | (&Constant::Char(c), &Constant::Atom(ref atom, _)) => { + atom.is_char() && Some(c) == atom.as_str().chars().next() + } + (&Constant::Atom(ref a1, _), &Constant::Atom(ref a2, _)) => a1.as_str() == a2.as_str(), + (&Constant::Char(c1), &Constant::Char(c2)) => c1 == c2, + (&Constant::Fixnum(n1), &Constant::Fixnum(n2)) => n1 == n2, + (&Constant::Fixnum(n1), &Constant::Integer(ref n2)) + | (&Constant::Integer(ref n2), &Constant::Fixnum(n1)) => { if let Some(n2) = n2.to_isize() { n1 == n2 } else { false } } - (&Constant::Integer(ref n1), &Constant::Integer(ref n2)) => - n1 == n2, - (&Constant::Rational(ref n1), &Constant::Rational(ref n2)) => - n1 == n2, - (&Constant::Float(ref n1), &Constant::Float(ref n2)) => - n1 == n2, - (&Constant::String(ref s1), &Constant::String(ref s2)) => { - &s1 == &s2 - } - (&Constant::EmptyList, &Constant::EmptyList) => - true, - (&Constant::Usize(u1), &Constant::Usize(u2)) => - u1 == u2, - _ => false + (&Constant::Integer(ref n1), &Constant::Integer(ref n2)) => n1 == n2, + (&Constant::Rational(ref n1), &Constant::Rational(ref n2)) => n1 == n2, + (&Constant::Float(ref n1), &Constant::Float(ref n2)) => n1 == n2, + (&Constant::String(ref s1), &Constant::String(ref s2)) => &s1 == &s2, + (&Constant::EmptyList, &Constant::EmptyList) => true, + (&Constant::Usize(u1), &Constant::Usize(u2)) => u1 == u2, + _ => false, } } } @@ -567,7 +569,7 @@ impl Constant { pub fn to_atom(self) -> Option { match self { Constant::Atom(a, _) => Some(a.defrock_brackets()), - _ => None + _ => None, } } } @@ -575,7 +577,7 @@ impl Constant { #[derive(Debug, Clone)] pub enum ClauseName { BuiltIn(&'static str), - User(TabledRc) + User(TabledRc), } impl fmt::Display for ClauseName { @@ -622,10 +624,12 @@ impl ClauseName { match self { &ClauseName::User(ref name) => { let module = name.owning_module(); - ClauseName::User(TabledRc { atom: module.clone(), - table: TabledData::new(module) }) - }, - _ => clause_name!("user") + ClauseName::User(TabledRc { + atom: module.clone(), + table: TabledData::new(module), + }) + } + _ => clause_name!("user"), } } @@ -633,7 +637,7 @@ impl ClauseName { pub fn to_rc(&self) -> Rc { match self { &ClauseName::BuiltIn(s) => Rc::new(s.to_string()), - &ClauseName::User(ref rc) => rc.inner() + &ClauseName::User(ref rc) => rc.inner(), } } @@ -666,9 +670,7 @@ impl ClauseName { false } } - ClauseName::User(ref name) => { - other.has_table(&name.table) - } + ClauseName::User(ref name) => other.has_table(&name.table), } } @@ -676,7 +678,7 @@ impl ClauseName { pub fn as_str(&self) -> &str { match self { &ClauseName::BuiltIn(s) => s, - &ClauseName::User(ref name) => name.as_ref() + &ClauseName::User(ref name) => name.as_ref(), } } @@ -688,17 +690,17 @@ impl ClauseName { pub fn defrock_brackets(self) -> Self { fn defrock_brackets(s: &str) -> &str { if s.starts_with('(') && s.ends_with(')') { - &s[1 .. s.len() - 1] + &s[1..s.len() - 1] } else { s } } match self { - ClauseName::BuiltIn(s) => - ClauseName::BuiltIn(defrock_brackets(s)), - ClauseName::User(s) => + ClauseName::BuiltIn(s) => ClauseName::BuiltIn(defrock_brackets(s)), + ClauseName::User(s) => { ClauseName::User(tabled_rc!(defrock_brackets(s.as_str()).to_owned(), s.table)) + } } } } @@ -713,10 +715,15 @@ impl AsRef for ClauseName { #[derive(Debug, PartialEq, Eq, Clone)] pub enum Term { AnonVar, - Clause(Cell, ClauseName, Vec>, Option), + Clause( + Cell, + ClauseName, + Vec>, + Option, + ), Cons(Cell, Box, Box), Constant(Cell, Constant), - Var(Cell, Rc) + Var(Cell, Rc), } impl Term { @@ -724,30 +731,29 @@ impl Term { match self { &Term::Clause(_, _, _, ref spec) => spec.clone(), &Term::Constant(_, Constant::Atom(_, ref spec)) => spec.clone(), - _ => None + _ => None, } } pub fn to_constant(self) -> Option { match self { Term::Constant(_, c) => Some(c), - _ => None + _ => None, } } pub fn first_arg(&self) -> Option<&Term> { match self { - &Term::Clause(_, _, ref terms, _) => - terms.first().map(|bt| bt.as_ref()), - _ => None + &Term::Clause(_, _, ref terms, _) => terms.first().map(|bt| bt.as_ref()), + _ => None, } } pub fn set_name(&mut self, new_name: ClauseName) { match self { Term::Constant(_, Constant::Atom(ref mut atom, _)) - | Term::Clause(_, ref mut atom, ..) => { - *atom = new_name; + | Term::Clause(_, ref mut atom, ..) => { + *atom = new_name; } _ => {} } @@ -755,16 +761,17 @@ impl Term { pub fn name(&self) -> Option { match self { - &Term::Constant(_, Constant::Atom(ref atom, _)) - | &Term::Clause(_, ref atom, ..) => Some(atom.clone()), - _ => None + &Term::Constant(_, Constant::Atom(ref atom, _)) | &Term::Clause(_, ref atom, ..) => { + Some(atom.clone()) + } + _ => None, } } pub fn arity(&self) -> usize { match self { &Term::Clause(_, _, ref child_terms, ..) => child_terms.len(), - _ => 0 + _ => 0, } } } diff --git a/crates/prolog_parser/src/lexer.rs b/crates/prolog_parser/src/lexer.rs index b1656a55..16c60d19 100644 --- a/crates/prolog_parser/src/lexer.rs +++ b/crates/prolog_parser/src/lexer.rs @@ -1,9 +1,9 @@ -use crate::lexical::parse_lossy; -use crate::ordered_float::*; use crate::rug::Integer; +use lexical::parse_lossy; +use ordered_float::*; -use ast::*; -use tabled_rc::*; +use crate::ast::*; +use crate::tabled_rc::*; use std::convert::TryFrom; use std::fmt; @@ -11,13 +11,13 @@ use std::io::Read; use std::rc::Rc; macro_rules! is_not_eof { - ($c:expr) => ( + ($c:expr) => { match $c { Ok(c) => c, Err(ParserError::UnexpectedEOF) => return Ok(true), - Err(e) => return Err(e) + Err(e) => return Err(e), } - ) + }; } macro_rules! consume_chars_with { @@ -27,26 +27,26 @@ macro_rules! consume_chars_with { Ok(Some(c)) => $token.push(c), Ok(None) => continue, Err(ParserError::UnexpectedChar(..)) => break, - Err(e) => return Err(e) + Err(e) => return Err(e), } } - } + }; } #[derive(Debug, Clone, PartialEq)] pub enum Token { Constant(Constant), Var(Rc), - Open, // '(' - OpenCT, // '(' - Close, // ')' - OpenList, // '[' - CloseList, // ']' - OpenCurly, // '{' - CloseCurly, // '}' + Open, // '(' + OpenCT, // '(' + Close, // ')' + OpenList, // '[' + CloseList, // ']' + OpenCurly, // '{' + CloseCurly, // '}' HeadTailSeparator, // '|' - Comma, // ',' - End + Comma, // ',' + End, } pub struct Lexer<'a, R: Read> { @@ -54,17 +54,17 @@ pub struct Lexer<'a, R: Read> { pub(crate) reader: &'a mut ParsingStream, pub(crate) flags: MachineFlags, pub(crate) line_num: usize, - pub(crate) col_num: usize + pub(crate) col_num: usize, } impl<'a, R: Read + fmt::Debug> fmt::Debug for Lexer<'a, R> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Lexer") - .field("atom_tbl", &self.atom_tbl) - .field("reader", &"&'a mut ParsingStream") // Hacky solution. - .field("line_num", &self.line_num) - .field("col_num", &self.col_num) - .finish() + .field("atom_tbl", &self.atom_tbl) + .field("reader", &"&'a mut ParsingStream") // Hacky solution. + .field("line_num", &self.line_num) + .field("col_num", &self.col_num) + .finish() } } @@ -74,7 +74,13 @@ impl<'a, R: Read> Lexer<'a, R> { flags: MachineFlags, src: &'a mut ParsingStream, ) -> Self { - Lexer { atom_tbl, flags, reader: src, line_num: 0, col_num: 0 } + Lexer { + atom_tbl, + flags, + reader: src, + line_num: 0, + col_num: 0, + } } fn return_char(&mut self, c: char) { @@ -128,8 +134,7 @@ impl<'a, R: Read> Lexer<'a, R> { } } - fn single_line_comment(&mut self) -> Result<(), ParserError> - { + fn single_line_comment(&mut self) -> Result<(), ParserError> { loop { if self.reader.peek().is_none() || new_line_char!(self.skip_char()?) { break; @@ -229,8 +234,7 @@ impl<'a, R: Read> Lexer<'a, R> { } } - fn get_single_quoted_item(&mut self) -> Result, ParserError> - { + fn get_single_quoted_item(&mut self) -> Result, ParserError> { if backslash_char!(self.lookahead_char()?) { let c = self.skip_char()?; @@ -264,14 +268,13 @@ impl<'a, R: Read> Lexer<'a, R> { } } - fn get_double_quoted_item(&mut self) -> Result, ParserError> - { + fn get_double_quoted_item(&mut self) -> Result, ParserError> { if backslash_char!(self.lookahead_char()?) { let c = self.skip_char()?; if new_line_char!(self.lookahead_char()?) { self.skip_char()?; - return Ok(None) + return Ok(None); } else { self.return_char(c); } @@ -299,8 +302,7 @@ impl<'a, R: Read> Lexer<'a, R> { } } - fn get_control_escape_sequence(&mut self) -> Result - { + fn get_control_escape_sequence(&mut self) -> Result { let escaped = match self.lookahead_char()? { 'a' => '\u{07}', // UTF-8 alert 'b' => '\u{08}', // UTF-8 backspace @@ -309,20 +311,18 @@ impl<'a, R: Read> Lexer<'a, R> { 't' => '\t', 'n' => '\n', 'r' => '\r', - c => return Err(ParserError::UnexpectedChar(c, self.line_num, self.col_num)) + c => return Err(ParserError::UnexpectedChar(c, self.line_num, self.col_num)), }; self.skip_char()?; return Ok(escaped); } - fn get_octal_escape_sequence(&mut self) -> Result - { + fn get_octal_escape_sequence(&mut self) -> Result { self.escape_sequence_to_char(|c| octal_digit_char!(c), 8) } - fn get_hexadecimal_escape_sequence(&mut self) -> Result - { + fn get_hexadecimal_escape_sequence(&mut self) -> Result { self.skip_char()?; let c = self.lookahead_char()?; @@ -354,12 +354,13 @@ impl<'a, R: Read> Lexer<'a, R> { if backslash_char!(c) { self.skip_char()?; - u32::from_str_radix(&token, radix) - .map_or_else( - |_| Err(ParserError::ParseBigInt(self.line_num, self.col_num)), - |n| char::try_from(n) + u32::from_str_radix(&token, radix).map_or_else( + |_| Err(ParserError::ParseBigInt(self.line_num, self.col_num)), + |n| { + char::try_from(n) .map_err(|_| ParserError::Utf8Error(self.line_num, self.col_num)) - ) + }, + ) } else { // on failure, restore the token characters and backslash. self.reader.put_back_all(token.chars().map(Ok)); @@ -423,11 +424,8 @@ impl<'a, R: Read> Lexer<'a, R> { .map(|n| Token::Constant(Constant::Fixnum(n))) .or_else(|_| { Integer::from_str_radix(&token, 16) - .map(|n| Token::Constant(Constant::Integer(Rc::new(n)))) - .map_err(|_| ParserError::ParseBigInt( - self.line_num, - self.col_num, - )) + .map(|n| Token::Constant(Constant::Integer(Rc::new(n)))) + .map_err(|_| ParserError::ParseBigInt(self.line_num, self.col_num)) }) } else { self.return_char('x'); @@ -449,11 +447,8 @@ impl<'a, R: Read> Lexer<'a, R> { .map(|n| Token::Constant(Constant::Fixnum(n))) .or_else(|_| { Integer::from_str_radix(&token, 8) - .map(|n| Token::Constant(Constant::Integer(Rc::new(n)))) - .map_err(|_| ParserError::ParseBigInt( - self.line_num, - self.col_num, - )) + .map(|n| Token::Constant(Constant::Integer(Rc::new(n)))) + .map_err(|_| ParserError::ParseBigInt(self.line_num, self.col_num)) }) } else { self.return_char('o'); @@ -475,11 +470,8 @@ impl<'a, R: Read> Lexer<'a, R> { .map(|n| Token::Constant(Constant::Fixnum(n))) .or_else(|_| { Integer::from_str_radix(&token, 2) - .map(|n| Token::Constant(Constant::Integer(Rc::new(n)))) - .map_err(|_| ParserError::ParseBigInt( - self.line_num, - self.col_num, - )) + .map(|n| Token::Constant(Constant::Integer(Rc::new(n)))) + .map_err(|_| ParserError::ParseBigInt(self.line_num, self.col_num)) }) } else { self.return_char('b'); @@ -531,12 +523,14 @@ impl<'a, R: Read> Lexer<'a, R> { } } } else { - return Err(ParserError::InvalidSingleQuotedCharacter(self.lookahead_char()?)) + return Err(ParserError::InvalidSingleQuotedCharacter( + self.lookahead_char()?, + )); } } else { match self.get_back_quoted_string() { - Ok(_) => return Err(ParserError::BackQuotedString(self.line_num, self.col_num)), - Err(e) => return Err(e) + Ok(_) => return Err(ParserError::BackQuotedString(self.line_num, self.col_num)), + Err(e) => return Err(e), } } @@ -575,12 +569,10 @@ impl<'a, R: Read> Lexer<'a, R> { isize::from_str_radix(&token, 10) .map(|n| Token::Constant(Constant::Fixnum(n))) .or_else(|_| { - token.parse::() - .map(|n| Token::Constant(Constant::Integer(Rc::new(n)))) - .map_err(|_| ParserError::ParseBigInt( - self.line_num, - self.col_num, - )) + token + .parse::() + .map(|n| Token::Constant(Constant::Integer(Rc::new(n)))) + .map_err(|_| ParserError::ParseBigInt(self.line_num, self.col_num)) }) } else if decimal_digit_char!(self.lookahead_char()?) { token.push('.'); @@ -599,7 +591,7 @@ impl<'a, R: Read> Lexer<'a, R> { let c = match self.lookahead_char() { Err(_) => return Ok(self.vacate_with_float(token)), - Ok(c) => c + Ok(c) => c, }; if !sign_char!(c) && !decimal_digit_char!(c) { @@ -613,8 +605,8 @@ impl<'a, R: Read> Lexer<'a, R> { Err(_) => { self.return_char(token.pop().unwrap()); return Ok(self.vacate_with_float(token)); - }, - Ok(c) => c + } + Ok(c) => c, }; if !decimal_digit_char!(c) { @@ -645,70 +637,65 @@ impl<'a, R: Read> Lexer<'a, R> { isize::from_str_radix(&token, 10) .map(|n| Token::Constant(Constant::Fixnum(n))) .or_else(|_| { - token.parse::() - .map(|n| Token::Constant(Constant::Integer(Rc::new(n)))) - .map_err(|_| ParserError::ParseBigInt( - self.line_num, - self.col_num, - )) + token + .parse::() + .map(|n| Token::Constant(Constant::Integer(Rc::new(n)))) + .map_err(|_| ParserError::ParseBigInt(self.line_num, self.col_num)) }) } } else { if token.starts_with('0') && token.len() == 1 { if c == 'x' { - self.hexadecimal_constant() - .or_else(|e| { - if let ParserError::ParseBigInt(..) = e { - isize::from_str_radix(&token, 10) - .map(|n| Token::Constant(Constant::Fixnum(n))) - .or_else(|_| { - token.parse::() - .map(|n| Token::Constant(Constant::Integer(Rc::new(n)))) - .map_err(|_| ParserError::ParseBigInt( - self.line_num, - self.col_num, - )) - }) - } else { - Err(e) - } - }) + self.hexadecimal_constant().or_else(|e| { + if let ParserError::ParseBigInt(..) = e { + isize::from_str_radix(&token, 10) + .map(|n| Token::Constant(Constant::Fixnum(n))) + .or_else(|_| { + token + .parse::() + .map(|n| Token::Constant(Constant::Integer(Rc::new(n)))) + .map_err(|_| { + ParserError::ParseBigInt(self.line_num, self.col_num) + }) + }) + } else { + Err(e) + } + }) } else if c == 'o' { - self.octal_constant() - .or_else(|e| { - if let ParserError::ParseBigInt(..) = e { - isize::from_str_radix(&token, 10) - .map(|n| Token::Constant(Constant::Fixnum(n))) - .or_else(|_| { - token.parse::() - .map(|n| Token::Constant(Constant::Integer(Rc::new(n)))) - .map_err(|_| ParserError::ParseBigInt( - self.line_num, - self.col_num, - )) - }) - } else { - Err(e) - } - }) + self.octal_constant().or_else(|e| { + if let ParserError::ParseBigInt(..) = e { + isize::from_str_radix(&token, 10) + .map(|n| Token::Constant(Constant::Fixnum(n))) + .or_else(|_| { + token + .parse::() + .map(|n| Token::Constant(Constant::Integer(Rc::new(n)))) + .map_err(|_| { + ParserError::ParseBigInt(self.line_num, self.col_num) + }) + }) + } else { + Err(e) + } + }) } else if c == 'b' { - self.binary_constant() - .or_else(|e| { - if let ParserError::ParseBigInt(..) = e { - isize::from_str_radix(&token, 10) - .map(|n| Token::Constant(Constant::Fixnum(n))) - .or_else(|_| { - token.parse::() - .map(|n| Token::Constant(Constant::Integer(Rc::new(n)))) - .map_err(|_| ParserError::ParseBigInt( - self.line_num, - self.col_num, - )) - }) - } else { - Err(e) - } - }) + self.binary_constant().or_else(|e| { + if let ParserError::ParseBigInt(..) = e { + isize::from_str_radix(&token, 10) + .map(|n| Token::Constant(Constant::Fixnum(n))) + .or_else(|_| { + token + .parse::() + .map(|n| Token::Constant(Constant::Integer(Rc::new(n)))) + .map_err(|_| { + ParserError::ParseBigInt(self.line_num, self.col_num) + }) + }) + } else { + Err(e) + } + }) } else if single_quote_char!(c) { self.skip_char()?; @@ -726,45 +713,39 @@ impl<'a, R: Read> Lexer<'a, R> { } self.get_single_quoted_char() - .and_then(|c| { - Ok(Token::Constant(Constant::Fixnum(c as isize))) - }) + .and_then(|c| Ok(Token::Constant(Constant::Fixnum(c as isize)))) .or_else(|_| { self.return_char(c); isize::from_str_radix(&token, 10) .map(|n| Token::Constant(Constant::Fixnum(n))) .or_else(|_| { - token.parse::() - .map(|n| Token::Constant(Constant::Integer(Rc::new(n)))) - .map_err(|_| ParserError::ParseBigInt( - self.line_num, - self.col_num, - )) + token + .parse::() + .map(|n| Token::Constant(Constant::Integer(Rc::new(n)))) + .map_err(|_| { + ParserError::ParseBigInt(self.line_num, self.col_num) + }) }) }) } else { isize::from_str_radix(&token, 10) .map(|n| Token::Constant(Constant::Fixnum(n))) .or_else(|_| { - token.parse::() - .map(|n| Token::Constant(Constant::Integer(Rc::new(n)))) - .map_err(|_| ParserError::ParseBigInt( - self.line_num, - self.col_num, - )) + token + .parse::() + .map(|n| Token::Constant(Constant::Integer(Rc::new(n)))) + .map_err(|_| ParserError::ParseBigInt(self.line_num, self.col_num)) }) } } else { isize::from_str_radix(&token, 10) .map(|n| Token::Constant(Constant::Fixnum(n))) .or_else(|_| { - token.parse::() - .map(|n| Token::Constant(Constant::Integer(Rc::new(n)))) - .map_err(|_| ParserError::ParseBigInt( - self.line_num, - self.col_num, - )) + token + .parse::() + .map(|n| Token::Constant(Constant::Integer(Rc::new(n)))) + .map_err(|_| ParserError::ParseBigInt(self.line_num, self.col_num)) }) } } @@ -781,18 +762,19 @@ impl<'a, R: Read> Lexer<'a, R> { Ok(c) if layout_char!(c) || new_line_char!(c) => { self.skip_char()?; layout_inserted = true; - }, + } Ok(c) if end_line_comment_char!(c) => { self.single_line_comment()?; layout_inserted = true; - }, - Ok(c) if comment_1_char!(c) => + } + Ok(c) if comment_1_char!(c) => { if self.bracketed_comment()? { layout_inserted = true; } else { more_layout = false; - }, - _ => more_layout = false + } + } + _ => more_layout = false, }; if !more_layout { @@ -825,8 +807,11 @@ impl<'a, R: Read> Lexer<'a, R> { if c == '(' { self.skip_char()?; - return Ok(if layout_inserted { Token::Open } - else { Token::OpenCT }); + return Ok(if layout_inserted { + Token::Open + } else { + Token::OpenCT + }); } if c == '.' { @@ -839,7 +824,7 @@ impl<'a, R: Read> Lexer<'a, R> { } return Ok(Token::End); - }, + } Err(ParserError::UnexpectedEOF) => { return Ok(Token::End); } @@ -891,8 +876,8 @@ impl<'a, R: Read> Lexer<'a, R> { } self.name_token(c) - }, - Err(e) => Err(e) + } + Err(e) => Err(e), } } } diff --git a/crates/prolog_parser/src/lib.rs b/crates/prolog_parser/src/lib.rs index f8ef7536..2c37cea6 100644 --- a/crates/prolog_parser/src/lib.rs +++ b/crates/prolog_parser/src/lib.rs @@ -1,14 +1,14 @@ -extern crate lexical; -extern crate ordered_float; -#[cfg(feature = "rug")] -extern crate rug; #[cfg(feature = "num-rug-adapter")] -extern crate num_rug_adapter as rug; -extern crate unicode_reader; +use num_rug_adapter as rug; +#[cfg(feature = "rug")] +use rug; -#[macro_use] pub mod tabled_rc; -#[macro_use] pub mod ast; -#[macro_use] pub mod macros; +#[macro_use] +pub mod tabled_rc; +#[macro_use] +pub mod ast; +#[macro_use] +pub mod macros; pub mod parser; pub mod put_back_n; diff --git a/crates/prolog_parser/src/parser.rs b/crates/prolog_parser/src/parser.rs index 19fd7912..87785daa 100644 --- a/crates/prolog_parser/src/parser.rs +++ b/crates/prolog_parser/src/parser.rs @@ -1,10 +1,10 @@ -use ast::*; -use lexer::*; -use tabled_rc::*; +use crate::ast::*; +use crate::lexer::*; +use crate::tabled_rc::*; use ordered_float::OrderedFloat; -use rug::ops::NegAssign; +use crate::rug::ops::NegAssign; use std::cell::Cell; use std::io::Read; @@ -16,24 +16,29 @@ enum TokenType { Term, Open, OpenCT, - OpenList, // '[' - OpenCurly, // '{' + OpenList, // '[' + OpenCurly, // '{' HeadTailSeparator, // '|' - Comma, // ',' + Comma, // ',' Close, - CloseList, // ']' - CloseCurly, // '}' - End + CloseList, // ']' + CloseCurly, // '}' + End, } impl TokenType { fn is_sep(self) -> bool { match self { - TokenType::HeadTailSeparator | TokenType::OpenCT | TokenType::Open | - TokenType::Close | TokenType::OpenList | TokenType::CloseList | - TokenType::OpenCurly | TokenType::CloseCurly | TokenType::Comma - => true, - _ => false + TokenType::HeadTailSeparator + | TokenType::OpenCT + | TokenType::Open + | TokenType::Close + | TokenType::OpenList + | TokenType::CloseList + | TokenType::OpenCurly + | TokenType::CloseCurly + | TokenType::Comma => true, + _ => false, } } } @@ -42,12 +47,14 @@ impl TokenType { struct TokenDesc { tt: TokenType, priority: usize, - spec: u32 + spec: u32, } -pub -fn get_clause_spec(name: ClauseName, arity: usize, op_dir: &CompositeOpDir) -> Option -{ +pub fn get_clause_spec( + name: ClauseName, + arity: usize, + op_dir: &CompositeOpDir, +) -> Option { match arity { 1 => { /* This is a clause with an operator principal functor. Prefix operators @@ -60,20 +67,25 @@ fn get_clause_spec(name: ClauseName, arity: usize, op_dir: &CompositeOpDir) -> O if let Some(OpDirValue(cell)) = op_dir.get(name, Fixity::Post) { return Some(cell.clone()); } - }, - 2 => + } + 2 => { if let Some(OpDirValue(cell)) = op_dir.get(name, Fixity::In) { return Some(cell.clone()); - }, + } + } _ => {} }; None } -pub fn get_op_desc(name: ClauseName, op_dir: &CompositeOpDir) -> Option -{ - let mut op_desc = OpDesc { pre: 0, inf: 0, post: 0, spec: 0 }; +pub fn get_op_desc(name: ClauseName, op_dir: &CompositeOpDir) -> Option { + let mut op_desc = OpDesc { + pre: 0, + inf: 0, + post: 0, + spec: 0, + }; if let Some(OpDirValue(cell)) = op_dir.get(name.clone(), Fixity::Pre) { let (pri, spec) = cell.get(); @@ -111,8 +123,7 @@ pub fn get_op_desc(name: ClauseName, op_dir: &CompositeOpDir) -> Option } } -fn affirm_xfx(priority: usize, d2: TokenDesc, d3: TokenDesc, d1: TokenDesc) -> bool -{ +fn affirm_xfx(priority: usize, d2: TokenDesc, d3: TokenDesc, d1: TokenDesc) -> bool { d2.priority <= priority && is_term!(d3.spec) && is_term!(d1.spec) @@ -120,18 +131,15 @@ fn affirm_xfx(priority: usize, d2: TokenDesc, d3: TokenDesc, d1: TokenDesc) -> b && d1.priority < d2.priority } -fn affirm_yfx(priority: usize, d2: TokenDesc, d3: TokenDesc, d1: TokenDesc) -> bool -{ +fn affirm_yfx(priority: usize, d2: TokenDesc, d3: TokenDesc, d1: TokenDesc) -> bool { d2.priority <= priority - && ((is_term!(d3.spec) && d3.priority < d2.priority) - || (is_lterm!(d3.spec) && d3.priority == d2.priority)) + && ((is_term!(d3.spec) && d3.priority < d2.priority) + || (is_lterm!(d3.spec) && d3.priority == d2.priority)) && is_term!(d1.spec) && d1.priority < d2.priority } - -fn affirm_xfy(priority: usize, d2: TokenDesc, d3: TokenDesc, d1: TokenDesc) -> bool -{ +fn affirm_xfy(priority: usize, d2: TokenDesc, d3: TokenDesc, d1: TokenDesc) -> bool { d2.priority < priority && is_term!(d3.spec) && d3.priority < d2.priority @@ -139,49 +147,35 @@ fn affirm_xfy(priority: usize, d2: TokenDesc, d3: TokenDesc, d1: TokenDesc) -> b && d1.priority <= d2.priority } -fn affirm_yf(d1: TokenDesc, d2: TokenDesc) -> bool -{ +fn affirm_yf(d1: TokenDesc, d2: TokenDesc) -> bool { let is_valid_lterm = is_lterm!(d2.spec) && d2.priority == d1.priority; (is_term!(d2.spec) && d2.priority < d1.priority) || is_valid_lterm } -fn affirm_xf(d1: TokenDesc, d2: TokenDesc) -> bool -{ +fn affirm_xf(d1: TokenDesc, d2: TokenDesc) -> bool { is_term!(d2.spec) && d2.priority < d1.priority } -fn affirm_fy(priority: usize, d1: TokenDesc, d2: TokenDesc) -> bool -{ +fn affirm_fy(priority: usize, d1: TokenDesc, d2: TokenDesc) -> bool { d2.priority < priority && is_term!(d1.spec) && d1.priority <= d2.priority } -fn affirm_fx(priority: usize, d1: TokenDesc, d2: TokenDesc) -> bool -{ +fn affirm_fx(priority: usize, d1: TokenDesc, d2: TokenDesc) -> bool { d2.priority <= priority && is_term!(d1.spec) && d1.priority < d2.priority } -fn sep_to_atom(tt: TokenType) -> Option -{ +fn sep_to_atom(tt: TokenType) -> Option { match tt { - TokenType::Open | TokenType::OpenCT => - Some(clause_name!("(")), - TokenType::Close => - Some(clause_name!(")")), - TokenType::OpenList => - Some(clause_name!("[")), - TokenType::CloseList => - Some(clause_name!("]")), - TokenType::OpenCurly => - Some(clause_name!("{")), - TokenType::CloseCurly => - Some(clause_name!("}")), - TokenType::HeadTailSeparator => - Some(clause_name!("|")), - TokenType::Comma => - Some(clause_name!(",")), - TokenType::End => - Some(clause_name!(".")), - _ => None + TokenType::Open | TokenType::OpenCT => Some(clause_name!("(")), + TokenType::Close => Some(clause_name!(")")), + TokenType::OpenList => Some(clause_name!("[")), + TokenType::CloseList => Some(clause_name!("]")), + TokenType::OpenCurly => Some(clause_name!("{")), + TokenType::CloseCurly => Some(clause_name!("}")), + TokenType::HeadTailSeparator => Some(clause_name!("|")), + TokenType::Comma => Some(clause_name!(",")), + TokenType::End => Some(clause_name!(".")), + _ => None, } } @@ -190,7 +184,7 @@ pub struct OpDesc { pub pre: usize, pub inf: usize, pub post: usize, - pub spec: Specifier + pub spec: Specifier, } #[derive(Debug)] @@ -201,8 +195,7 @@ pub struct Parser<'a, R: Read> { terms: Vec, } -fn read_tokens<'a, R: Read>(lexer: &mut Lexer<'a, R>) -> Result, ParserError> -{ +fn read_tokens<'a, R: Read>(lexer: &mut Lexer<'a, R>) -> Result, ParserError> { let mut tokens = vec![]; loop { @@ -227,10 +220,12 @@ impl<'a, R: Read> Parser<'a, R> { atom_tbl: TabledData, flags: MachineFlags, ) -> Self { - Parser { lexer: Lexer::new(atom_tbl, flags, stream), - tokens: vec![], - stack: Vec::new(), - terms: Vec::new() } + Parser { + lexer: Lexer::new(atom_tbl, flags, stream), + tokens: vec![], + stack: Vec::new(), + terms: Vec::new(), + } } #[inline] @@ -255,50 +250,46 @@ impl<'a, R: Read> Parser<'a, R> { fn get_term_name(&mut self, td: TokenDesc) -> Option<(ClauseName, Option)> { match td.tt { - TokenType::HeadTailSeparator => { - Some((clause_name!("|"), Some(SharedOpDesc::new(td.priority, td.spec)))) - } - TokenType::Comma => { - Some((clause_name!(","), Some(SharedOpDesc::new(1000, XFY)))) - } - TokenType::Term => { - match self.terms.pop() { - Some(Term::Constant(_, Constant::Atom(atom, spec))) => - Some((atom, spec)), - Some(term) => { - self.terms.push(term); - None - }, - _ => None + TokenType::HeadTailSeparator => Some(( + clause_name!("|"), + Some(SharedOpDesc::new(td.priority, td.spec)), + )), + TokenType::Comma => Some((clause_name!(","), Some(SharedOpDesc::new(1000, XFY)))), + TokenType::Term => match self.terms.pop() { + Some(Term::Constant(_, Constant::Atom(atom, spec))) => Some((atom, spec)), + Some(term) => { + self.terms.push(term); + None } - } - _ => { - None - } + _ => None, + }, + _ => None, } } - fn push_binary_op(&mut self, td: TokenDesc, spec: Specifier) - { + fn push_binary_op(&mut self, td: TokenDesc, spec: Specifier) { if let Some(arg2) = self.terms.pop() { if let Some((name, shared_op_desc)) = self.get_term_name(td) { if let Some(arg1) = self.terms.pop() { - let term = Term::Clause(Cell::default(), - name, - vec![Box::new(arg1), Box::new(arg2)], - shared_op_desc); + let term = Term::Clause( + Cell::default(), + name, + vec![Box::new(arg1), Box::new(arg2)], + shared_op_desc, + ); self.terms.push(term); - self.stack.push(TokenDesc { tt: TokenType::Term, - priority: td.priority, - spec }); + self.stack.push(TokenDesc { + tt: TokenType::Term, + priority: td.priority, + spec, + }); } } } } - fn push_unary_op(&mut self, td: TokenDesc, spec: Specifier, assoc: u32) - { + fn push_unary_op(&mut self, td: TokenDesc, spec: Specifier, assoc: u32) { if let Some(mut arg1) = self.terms.pop() { if let Some(mut name) = self.terms.pop() { if is_postfix!(assoc) { @@ -306,52 +297,61 @@ impl<'a, R: Read> Parser<'a, R> { } if let Term::Constant(_, Constant::Atom(name, shared_op_desc)) = name { - let term = Term::Clause(Cell::default(), name, vec![Box::new(arg1)], - shared_op_desc); + let term = + Term::Clause(Cell::default(), name, vec![Box::new(arg1)], shared_op_desc); self.terms.push(term); - self.stack.push(TokenDesc { tt: TokenType::Term, - priority: td.priority, - spec }); + self.stack.push(TokenDesc { + tt: TokenType::Term, + priority: td.priority, + spec, + }); } } } } - fn promote_atom_op(&mut self, atom: ClauseName, priority: usize, assoc: u32, - op_dir_val: Option<&OpDirValue>) - { + fn promote_atom_op( + &mut self, + atom: ClauseName, + priority: usize, + assoc: u32, + op_dir_val: Option<&OpDirValue>, + ) { let spec = op_dir_val.map(|op_dir_val| op_dir_val.shared_op_desc()); - self.terms.push(Term::Constant(Cell::default(), Constant::Atom(atom, spec))); - self.stack.push(TokenDesc { tt: TokenType::Term, priority, spec: assoc }); + self.terms + .push(Term::Constant(Cell::default(), Constant::Atom(atom, spec))); + self.stack.push(TokenDesc { + tt: TokenType::Term, + priority, + spec: assoc, + }); } - fn shift(&mut self, token: Token, priority: usize, spec: Specifier) - { + fn shift(&mut self, token: Token, priority: usize, spec: Specifier) { let tt = match token { - Token::Constant(Constant::String(s)) - if self.lexer.flags.double_quotes.is_codes() => { - let mut list = Term::Constant(Cell::default(), Constant::EmptyList); + Token::Constant(Constant::String(s)) if self.lexer.flags.double_quotes.is_codes() => { + let mut list = Term::Constant(Cell::default(), Constant::EmptyList); - for c in s.chars().rev() { - list = Term::Cons( + for c in s.chars().rev() { + list = Term::Cons( + Cell::default(), + Box::new(Term::Constant( Cell::default(), - Box::new(Term::Constant( - Cell::default(), - Constant::Fixnum(c as isize), - )), - Box::new(list), - ); - } - - self.terms.push(list); - TokenType::Term + Constant::Fixnum(c as isize), + )), + Box::new(list), + ); } + + self.terms.push(list); + TokenType::Term + } Token::Constant(c) => { self.terms.push(Term::Constant(Cell::default(), c)); TokenType::Term - }, + } Token::Var(v) => { if v.trim() == "_" { self.terms.push(Term::AnonVar); @@ -360,7 +360,7 @@ impl<'a, R: Read> Parser<'a, R> { } TokenType::Term - }, + } Token::Comma => TokenType::Comma, Token::Open => TokenType::Open, Token::Close => TokenType::Close, @@ -381,18 +381,13 @@ impl<'a, R: Read> Parser<'a, R> { if let Some(desc1) = self.stack.pop() { if let Some(desc2) = self.stack.pop() { if let Some(desc3) = self.stack.pop() { - if is_xfx!(desc2.spec) && affirm_xfx(priority, desc2, desc3, desc1) - { + if is_xfx!(desc2.spec) && affirm_xfx(priority, desc2, desc3, desc1) { self.push_binary_op(desc2, LTERM); continue; - } - else if is_yfx!(desc2.spec) && affirm_yfx(priority, desc2, desc3, desc1) - { + } else if is_yfx!(desc2.spec) && affirm_yfx(priority, desc2, desc3, desc1) { self.push_binary_op(desc2, LTERM); continue; - } - else if is_xfy!(desc2.spec) && affirm_xfy(priority, desc2, desc3, desc1) - { + } else if is_xfy!(desc2.spec) && affirm_xfy(priority, desc2, desc3, desc1) { self.push_binary_op(desc2, TERM); continue; } else { @@ -425,12 +420,12 @@ impl<'a, R: Read> Parser<'a, R> { } } - fn compute_arity_in_brackets(&self) -> Option - { + fn compute_arity_in_brackets(&self) -> Option { let mut arity = 0; for (i, desc) in self.stack.iter().rev().enumerate() { - if i % 2 == 0 { // expect a term or non-comma operator. + if i % 2 == 0 { + // expect a term or non-comma operator. if let TokenType::Comma = desc.tt { return None; } else if is_term!(desc.spec) || is_op!(desc.spec) || is_negate!(desc.spec) { @@ -454,8 +449,7 @@ impl<'a, R: Read> Parser<'a, R> { None } - fn reduce_term(&mut self, op_dir: &CompositeOpDir) -> bool - { + fn reduce_term(&mut self, op_dir: &CompositeOpDir) -> bool { if self.stack.is_empty() { return false; } @@ -464,7 +458,7 @@ impl<'a, R: Read> Parser<'a, R> { let arity = match self.compute_arity_in_brackets() { Some(arity) => arity, - None => return false + None => return false, }; if self.stack.len() > 2 * arity { @@ -490,9 +484,7 @@ impl<'a, R: Read> Parser<'a, R> { if self.atomize_term(&self.terms[idx - 1]).is_some() { self.stack.truncate(stack_len + 1); - let mut subterms: Vec<_> = self.terms.drain(idx ..) - .map(|t| Box::new(t)) - .collect(); + let mut subterms: Vec<_> = self.terms.drain(idx..).map(|t| Box::new(t)).collect(); if let Some(name) = self.terms.pop().and_then(|t| self.atomize_term(&t)) { // reduce the '.' functor to a cons cell if it applies. @@ -503,11 +495,15 @@ impl<'a, R: Read> Parser<'a, R> { self.terms.push(Term::Cons(Cell::default(), head, tail)); } else { let spec = get_clause_spec(name.clone(), subterms.len(), op_dir); - self.terms.push(Term::Clause(Cell::default(), name, subterms, spec)); + self.terms + .push(Term::Clause(Cell::default(), name, subterms, spec)); } - if let Some(&mut TokenDesc { ref mut priority, ref mut spec, - ref mut tt }) = self.stack.last_mut() + if let Some(&mut TokenDesc { + ref mut priority, + ref mut spec, + ref mut tt, + }) = self.stack.last_mut() { *tt = TokenType::Term; *priority = 0; @@ -523,7 +519,7 @@ impl<'a, R: Read> Parser<'a, R> { } pub fn devour_whitespace(&mut self) -> Result<(), ParserError> { - self.lexer.scan_for_layout()?; + self.lexer.scan_for_layout()?; Ok(()) } @@ -531,8 +527,7 @@ impl<'a, R: Read> Parser<'a, R> { self.stack.clear() } - fn expand_comma_compacted_terms(&mut self, index: usize) -> usize - { + fn expand_comma_compacted_terms(&mut self, index: usize) -> usize { if let Some(term) = self.terms.pop() { let op_desc = self.stack[index - 1]; @@ -548,8 +543,7 @@ impl<'a, R: Read> Parser<'a, R> { self.terms.extend(terms.into_iter()); return arity; } - _ => { - } + _ => {} } } @@ -559,12 +553,12 @@ impl<'a, R: Read> Parser<'a, R> { 0 } - fn compute_arity_in_list(&self) -> Option - { + fn compute_arity_in_list(&self) -> Option { let mut arity = 0; for (i, desc) in self.stack.iter().rev().enumerate() { - if i % 2 == 0 { // expect a term or non-comma operator. + if i % 2 == 0 { + // expect a term or non-comma operator. if let TokenType::Comma = desc.tt { return None; } else if is_term!(desc.spec) || is_op!(desc.spec) { @@ -590,8 +584,7 @@ impl<'a, R: Read> Parser<'a, R> { None } - fn reduce_list(&mut self) -> Result - { + fn reduce_list(&mut self) -> Result { if self.stack.is_empty() { return Ok(false); } @@ -602,7 +595,8 @@ impl<'a, R: Read> Parser<'a, R> { td.tt = TokenType::Term; td.priority = 0; - self.terms.push(Term::Constant(Cell::default(), Constant::EmptyList)); + self.terms + .push(Term::Constant(Cell::default(), Constant::EmptyList)); return Ok(true); } } @@ -611,7 +605,7 @@ impl<'a, R: Read> Parser<'a, R> { let mut arity = match self.compute_arity_in_list() { Some(arity) => arity, - None => return Ok(false) + None => return Ok(false), }; // we know that self.stack.len() >= 2 by this point. @@ -621,12 +615,15 @@ impl<'a, R: Read> Parser<'a, R> { let end_term = if self.stack[idx].tt != TokenType::HeadTailSeparator { Term::Constant(Cell::default(), Constant::EmptyList) } else { - let term = - match self.terms.pop() { - Some(term) => term, - _ => return Err(ParserError::IncompleteReduction(self.lexer.line_num, - self.lexer.col_num)) - }; + let term = match self.terms.pop() { + Some(term) => term, + _ => { + return Err(ParserError::IncompleteReduction( + self.lexer.line_num, + self.lexer.col_num, + )) + } + }; if self.stack[idx].priority > 1000 { arity += self.expand_comma_compacted_terms(idx); @@ -639,15 +636,17 @@ impl<'a, R: Read> Parser<'a, R> { let idx = self.terms.len() - arity; - let list = self.terms.drain(idx ..) - .rev() - .fold(end_term, |acc, t| Term::Cons(Cell::default(), - Box::new(t), - Box::new(acc))); + let list = self.terms.drain(idx..).rev().fold(end_term, |acc, t| { + Term::Cons(Cell::default(), Box::new(t), Box::new(acc)) + }); self.stack.truncate(list_len); - self.stack.push(TokenDesc { tt: TokenType::Term, priority: 0, spec: TERM }); + self.stack.push(TokenDesc { + tt: TokenType::Term, + priority: 0, + spec: TERM, + }); self.terms.push(list); Ok(true) @@ -664,8 +663,7 @@ impl<'a, R: Read> Parser<'a, R> { td.priority = 0; td.spec = TERM; - let term = Term::Constant(Cell::default(), - atom!("{}", self.lexer.atom_tbl)); + let term = Term::Constant(Cell::default(), atom!("{}", self.lexer.atom_tbl)); self.terms.push(term); return Ok(true); } @@ -687,17 +685,19 @@ impl<'a, R: Read> Parser<'a, R> { let term = match self.terms.pop() { Some(term) => term, - _ => return Err(ParserError::IncompleteReduction( - self.lexer.line_num, - self.lexer.col_num, - )) + _ => { + return Err(ParserError::IncompleteReduction( + self.lexer.line_num, + self.lexer.col_num, + )) + } }; self.terms.push(Term::Clause( Cell::default(), clause_name!("{}"), vec![Box::new(term)], - None + None, )); return Ok(true); @@ -723,29 +723,35 @@ impl<'a, R: Read> Parser<'a, R> { let idx = self.stack.len() - 2; match self.stack.remove(idx) { - td => - match td.tt { - TokenType::Open | TokenType::OpenCT => { - if self.stack[idx].tt == TokenType::Comma { - return false; - } + td => match td.tt { + TokenType::Open | TokenType::OpenCT => { + if self.stack[idx].tt == TokenType::Comma { + return false; + } - if let Some(atom) = sep_to_atom(self.stack[idx].tt) { - self.terms.push(Term::Constant(Cell::default(), Constant::Atom(atom, None))); - } + if let Some(atom) = sep_to_atom(self.stack[idx].tt) { + self.terms + .push(Term::Constant(Cell::default(), Constant::Atom(atom, None))); + } - self.stack[idx].spec = TERM; - self.stack[idx].tt = TokenType::Term; - self.stack[idx].priority = 0; - true - }, - _ => false + self.stack[idx].spec = TERM; + self.stack[idx].tt = TokenType::Term; + self.stack[idx].priority = 0; + true } + _ => false, + }, } } fn shift_op(&mut self, name: ClauseName, op_dir: &CompositeOpDir) -> Result { - if let Some(OpDesc { pre, inf, post, spec }) = get_op_desc(name.clone(), op_dir) { + if let Some(OpDesc { + pre, + inf, + post, + spec, + }) = get_op_desc(name.clone(), op_dir) + { if (pre > 0 && inf + post > 0) || is_negate!(spec) { match self.tokens.last().ok_or(ParserError::UnexpectedEOF)? { // do this when layout hasn't been inserted, @@ -764,7 +770,7 @@ impl<'a, R: Read> Parser<'a, R> { spec & (XFX | XFY | YFX | YF | XF), op_dir_val, ); - }, + } _ => { self.reduce_op(inf + post); @@ -782,11 +788,21 @@ impl<'a, R: Read> Parser<'a, R> { ); } else { let op_dir_val = op_dir.get(name.clone(), Fixity::Pre); - self.promote_atom_op(name, pre, spec & (FX | FY | NEGATIVE_SIGN), op_dir_val); + self.promote_atom_op( + name, + pre, + spec & (FX | FY | NEGATIVE_SIGN), + op_dir_val, + ); } } else { let op_dir_val = op_dir.get(name.clone(), Fixity::Pre); - self.promote_atom_op(name, pre, spec & (FX | FY | NEGATIVE_SIGN), op_dir_val); + self.promote_atom_op( + name, + pre, + spec & (FX | FY | NEGATIVE_SIGN), + op_dir_val, + ); } } } @@ -807,7 +823,8 @@ impl<'a, R: Read> Parser<'a, R> { } Ok(true) - } else { // not an operator. + } else { + // not an operator. Ok(false) } } @@ -815,41 +832,37 @@ impl<'a, R: Read> Parser<'a, R> { fn atomize_term(&self, term: &Term) -> Option { match term { &Term::Constant(_, ref c) => self.atomize_constant(c), - _ => None + _ => None, } } fn atomize_constant(&self, c: &Constant) -> Option { match c { &Constant::Atom(ref name, _) => Some(name.clone()), - &Constant::Char(c) => - Some(clause_name!(c.to_string(), self.lexer.atom_tbl)), - &Constant::EmptyList => - Some(clause_name!(c.to_string(), self.lexer.atom_tbl)), - _ => None + &Constant::Char(c) => Some(clause_name!(c.to_string(), self.lexer.atom_tbl)), + &Constant::EmptyList => Some(clause_name!(c.to_string(), self.lexer.atom_tbl)), + _ => None, } } - fn negate_number( - &mut self, - n: N, - negator: Negator, - constr: ToConstant - ) - where Negator: Fn(N) -> N, - ToConstant: Fn(N) -> Constant + fn negate_number(&mut self, n: N, negator: Negator, constr: ToConstant) + where + Negator: Fn(N) -> N, + ToConstant: Fn(N) -> Constant, { if let Some(desc) = self.stack.last().cloned() { if let Some(term) = self.terms.last().cloned() { match term { Term::Constant(_, Constant::Atom(ref name, _)) - if name.as_str() == "-" && (is_prefix!(desc.spec) || is_negate!(desc.spec)) => { - self.stack.pop(); - self.terms.pop(); + if name.as_str() == "-" + && (is_prefix!(desc.spec) || is_negate!(desc.spec)) => + { + self.stack.pop(); + self.terms.pop(); - self.shift(Token::Constant(constr(negator(n))), 0, TERM); - return; - }, + self.shift(Token::Constant(constr(negator(n))), 0, TERM); + return; + } _ => {} } } @@ -864,38 +877,36 @@ impl<'a, R: Read> Parser<'a, R> { Some(t) => { t.neg_assign(); } - None => { - } + None => {} }; t } match token { - Token::Constant(Constant::Fixnum(n)) => - self.negate_number(n, |n| -n, Constant::Fixnum), - Token::Constant(Constant::Integer(n)) => - self.negate_number(n, negate_rc, Constant::Integer), - Token::Constant(Constant::Rational(n)) => - self.negate_number(n, negate_rc, Constant::Rational), - Token::Constant(Constant::Float(n)) => - self.negate_number( - n, - |n| OrderedFloat(-n.into_inner()), - |n| Constant::Float(n) - ), - Token::Constant(c) => + Token::Constant(Constant::Fixnum(n)) => self.negate_number(n, |n| -n, Constant::Fixnum), + Token::Constant(Constant::Integer(n)) => { + self.negate_number(n, negate_rc, Constant::Integer) + } + Token::Constant(Constant::Rational(n)) => { + self.negate_number(n, negate_rc, Constant::Rational) + } + Token::Constant(Constant::Float(n)) => { + self.negate_number(n, |n| OrderedFloat(-n.into_inner()), |n| Constant::Float(n)) + } + Token::Constant(c) => { if let Some(name) = self.atomize_constant(&c) { if !self.shift_op(name, op_dir)? { self.shift(Token::Constant(c), 0, TERM); } } else { self.shift(Token::Constant(c), 0, TERM); - }, + } + } Token::Var(v) => self.shift(Token::Var(v), 0, TERM), - Token::Open => self.shift(Token::Open, 1300, DELIMITER), + Token::Open => self.shift(Token::Open, 1300, DELIMITER), Token::OpenCT => self.shift(Token::OpenCT, 1300, DELIMITER), - Token::Close => + Token::Close => { if !self.reduce_term(op_dir) { if !self.reduce_brackets() { return Err(ParserError::IncompleteReduction( @@ -903,23 +914,26 @@ impl<'a, R: Read> Parser<'a, R> { self.lexer.col_num, )); } - }, - Token::OpenList => self.shift(Token::OpenList, 1300, DELIMITER), - Token::CloseList => + } + } + Token::OpenList => self.shift(Token::OpenList, 1300, DELIMITER), + Token::CloseList => { if !self.reduce_list()? { return Err(ParserError::IncompleteReduction( self.lexer.line_num, self.lexer.col_num, )); - }, + } + } Token::OpenCurly => self.shift(Token::OpenCurly, 1300, DELIMITER), - Token::CloseCurly => + Token::CloseCurly => { if !self.reduce_curly()? { return Err(ParserError::IncompleteReduction( self.lexer.line_num, self.lexer.col_num, )); - }, + } + } Token::HeadTailSeparator => { /* '|' as an operator must have priority > 1000 and can only be infix. * See: http://www.complang.tuwien.ac.at/ulrich/iso-prolog/dtc2#Res_A78 @@ -930,23 +944,25 @@ impl<'a, R: Read> Parser<'a, R> { self.reduce_op(priority); self.shift(Token::HeadTailSeparator, priority, spec); - }, + } Token::Comma => { self.reduce_op(1000); self.shift(Token::Comma, 1000, XFY); - }, - Token::End => - match self.stack.last().map(|t| t.tt) { - Some(TokenType::Open) - | Some(TokenType::OpenCT) - | Some(TokenType::OpenList) - | Some(TokenType::OpenCurly) - | Some(TokenType::HeadTailSeparator) - | Some(TokenType::Comma) - => return Err(ParserError::IncompleteReduction(self.lexer.line_num, - self.lexer.col_num)), - _ => {} + } + Token::End => match self.stack.last().map(|t| t.tt) { + Some(TokenType::Open) + | Some(TokenType::OpenCT) + | Some(TokenType::OpenList) + | Some(TokenType::OpenCurly) + | Some(TokenType::HeadTailSeparator) + | Some(TokenType::Comma) => { + return Err(ParserError::IncompleteReduction( + self.lexer.line_num, + self.lexer.col_num, + )) } + _ => {} + }, } Ok(()) @@ -957,8 +973,7 @@ impl<'a, R: Read> Parser<'a, R> { self.lexer.eof() } - pub fn read_term(&mut self, op_dir: &CompositeOpDir) -> Result - { + pub fn read_term(&mut self, op_dir: &CompositeOpDir) -> Result { self.tokens = read_tokens(&mut self.lexer)?; while let Some(token) = self.tokens.pop() { @@ -968,21 +983,31 @@ impl<'a, R: Read> Parser<'a, R> { self.reduce_op(1400); if self.terms.len() > 1 || self.stack.len() > 1 { - return Err(ParserError::IncompleteReduction(self.lexer.line_num, self.lexer.col_num)); + return Err(ParserError::IncompleteReduction( + self.lexer.line_num, + self.lexer.col_num, + )); } match self.terms.pop() { - Some(term) => if self.terms.is_empty() { - Ok(term) - } else { - Err(ParserError::IncompleteReduction(self.lexer.line_num, self.lexer.col_num)) - }, - _ => Err(ParserError::IncompleteReduction(self.lexer.line_num, self.lexer.col_num)) + Some(term) => { + if self.terms.is_empty() { + Ok(term) + } else { + Err(ParserError::IncompleteReduction( + self.lexer.line_num, + self.lexer.col_num, + )) + } + } + _ => Err(ParserError::IncompleteReduction( + self.lexer.line_num, + self.lexer.col_num, + )), } } - pub fn read(&mut self, op_dir: &CompositeOpDir) -> Result, ParserError> - { + pub fn read(&mut self, op_dir: &CompositeOpDir) -> Result, ParserError> { let mut terms = Vec::new(); loop { -- 2.54.0