From 2a0dea6659956986d0ce4e8cbdcdbf7710b91660 Mon Sep 17 00:00:00 2001 From: Brendan Zabarauskas Date: Tue, 10 Nov 2020 19:42:43 +1100 Subject: [PATCH] Simplify AST and improve naming of variants --- pikelet/src/lang/core.rs | 10 +-- pikelet/src/lang/core/semantics.rs | 12 +-- pikelet/src/lang/core/typing.rs | 6 +- pikelet/src/lang/surface.rs | 22 ++--- pikelet/src/lang/surface/grammar.lalrpop | 13 +-- pikelet/src/pass/core_to_pretty.rs | 2 +- pikelet/src/pass/core_to_surface.rs | 32 +++---- pikelet/src/pass/surface_to_core.rs | 110 ++++++++++++++--------- pikelet/src/pass/surface_to_pretty.rs | 18 ++-- 9 files changed, 114 insertions(+), 111 deletions(-) diff --git a/pikelet/src/lang/core.rs b/pikelet/src/lang/core.rs index 2beb94a39..ad6ce6fe5 100644 --- a/pikelet/src/lang/core.rs +++ b/pikelet/src/lang/core.rs @@ -133,7 +133,7 @@ pub enum TermData { RecordElim(Arc, String), /// Ordered sequences. - Sequence(Vec>), + SequenceTerm(Vec>), /// Constants. Constant(Constant), @@ -424,7 +424,7 @@ impl TryFromTerm for Vec { fn try_from_term(term: &Term) -> Result, ()> { match &term.data { - TermData::Sequence(entry_terms) => entry_terms + TermData::SequenceTerm(entry_terms) => entry_terms .iter() .map(|entry_term| T::try_from_term(entry_term).map_err(|_| ())) .collect::, ()>>(), @@ -440,7 +440,7 @@ macro_rules! impl_try_from_term_array { fn try_from_term(term: &Term) -> Result<[T; $len], ()> { match &term.data { - TermData::Sequence(entry_terms) if entry_terms.len() == $len => { + TermData::SequenceTerm(entry_terms) if entry_terms.len() == $len => { use std::mem::MaybeUninit; let mut entries: [MaybeUninit::; $len] = unsafe { @@ -523,7 +523,7 @@ impl_to_term!(str, |value| TermData::from(Constant::String( impl ToTerm for Vec { fn to_term(&self) -> Term { - Term::from(TermData::Sequence( + Term::from(TermData::SequenceTerm( self.iter() .map(|entry_term| Arc::new(T::to_term(entry_term))) .collect(), @@ -535,7 +535,7 @@ macro_rules! impl_to_term_array { ($($len:expr),*) => { $(impl ToTerm for [T; $len] { fn to_term(&self) -> Term { - Term::from(TermData::Sequence( + Term::from(TermData::SequenceTerm( self.iter() .map(|entry_term| Arc::new(T::to_term(entry_term))) .collect(), diff --git a/pikelet/src/lang/core/semantics.rs b/pikelet/src/lang/core/semantics.rs index 81cc909de..76c4d1352 100644 --- a/pikelet/src/lang/core/semantics.rs +++ b/pikelet/src/lang/core/semantics.rs @@ -60,7 +60,7 @@ pub enum Value { RecordTerm(RecordClosure), /// Ordered sequences. - Sequence(Vec>), + SequenceTerm(Vec>), /// Constants. Constant(Constant), @@ -382,13 +382,13 @@ pub fn eval_term( apply_function_elim(globals, head, Arc::new(input)) } - TermData::Sequence(term_entries) => { + TermData::SequenceTerm(term_entries) => { let value_entries = term_entries .iter() .map(|entry_term| eval_term(globals, universe_offset, locals, entry_term)) .collect(); - Arc::new(Value::Sequence(value_entries)) + Arc::new(Value::SequenceTerm(value_entries)) } TermData::Constant(constant) => Arc::new(Value::from(constant.clone())), @@ -594,7 +594,7 @@ pub fn read_back_value( Term::from(TermData::RecordTerm(term_entries.into())) } - Value::Sequence(value_entries) => { + Value::SequenceTerm(value_entries) => { let term_entries = value_entries .iter() .map(|value_entry| { @@ -602,7 +602,7 @@ pub fn read_back_value( }) .collect(); - Term::from(TermData::Sequence(term_entries)) + Term::from(TermData::SequenceTerm(term_entries)) } Value::Constant(constant) => Term::from(TermData::from(constant.clone())), @@ -760,7 +760,7 @@ fn is_equal(globals: &Globals, local_size: LocalSize, value0: &Value, value1: &V true } - (Value::Sequence(value_entries0), Value::Sequence(value_entries1)) => { + (Value::SequenceTerm(value_entries0), Value::SequenceTerm(value_entries1)) => { if value_entries0.len() != value_entries1.len() { return false; } diff --git a/pikelet/src/lang/core/typing.rs b/pikelet/src/lang/core/typing.rs index 08cdd6b98..8fee90545 100644 --- a/pikelet/src/lang/core/typing.rs +++ b/pikelet/src/lang/core/typing.rs @@ -198,7 +198,7 @@ impl<'me> State<'me> { } } - (TermData::Sequence(entry_terms), Value::Stuck(Head::Global(name, _), spine)) => { + (TermData::SequenceTerm(entry_terms), Value::Stuck(Head::Global(name, _), spine)) => { match (name.as_ref(), spine.as_slice()) { ("Array", [Elim::Function(len), Elim::Function(entry_type)]) => { let entry_type = entry_type.force(self.globals); @@ -227,7 +227,7 @@ impl<'me> State<'me> { } } } - (TermData::Sequence(_), _) => { + (TermData::SequenceTerm(_), _) => { let expected_type = self.read_back_value(expected_type); self.report(CoreTypingMessage::NoSequenceConversion { expected_type }) } @@ -401,7 +401,7 @@ impl<'me> State<'me> { Arc::new(Value::Error) } - TermData::Sequence(_) => { + TermData::SequenceTerm(_) => { self.report(CoreTypingMessage::AmbiguousTerm { term: AmbiguousTerm::Sequence, }); diff --git a/pikelet/src/lang/surface.rs b/pikelet/src/lang/surface.rs index 8ace540fa..753146665 100644 --- a/pikelet/src/lang/surface.rs +++ b/pikelet/src/lang/surface.rs @@ -14,17 +14,6 @@ mod grammar { include!(concat!(env!("OUT_DIR"), "/lang/surface/grammar.rs")); } -/// Literals. -#[derive(Debug, Clone)] -pub enum Literal { - /// Character literals. - Char(String), - /// String literals. - String(String), - /// Numeric literals. - Number(String), -} - /// Entry in a [record type](Term::RecordType). pub type TypeEntry = (Ranged, Option>, Term); /// Entry in a [record term](Term::RecordTerm). @@ -73,10 +62,13 @@ pub enum TermData { RecordElim(Box, Ranged), /// Ordered sequences. - Sequence(Vec), - - /// Literals. - Literal(Literal), + SequenceTerm(Vec), + /// Character literals. + CharTerm(String), + /// String literals. + StringTerm(String), + /// Numeric literals. + NumberTerm(String), /// Error sentinel. Error, diff --git a/pikelet/src/lang/surface/grammar.lalrpop b/pikelet/src/lang/surface/grammar.lalrpop index 7d14858e7..a898b0a92 100644 --- a/pikelet/src/lang/surface/grammar.lalrpop +++ b/pikelet/src/lang/surface/grammar.lalrpop @@ -1,5 +1,5 @@ use crate::lang::Ranged; -use crate::lang::surface::{Term, TermData, Literal, TypeEntry, TermEntry}; +use crate::lang::surface::{Term, TermData, TypeEntry, TermEntry}; use crate::lang::surface::lexer::Token; use crate::reporting::LexerError; @@ -86,7 +86,9 @@ AtomicTermData: TermData = { "record" "{" > "}" => TermData::RecordTerm(entries), "." > => TermData::RecordElim(Box::new(head_term), label), "[" > "]" => TermData::Sequence(entries), - => TermData::Literal(literal), + "character literal" => TermData::CharTerm(<>.to_owned()), + "string literal" => TermData::StringTerm(<>.to_owned()), + "numeric literal" => TermData::NumberTerm(<>.to_owned()), }; #[inline] @@ -116,13 +118,6 @@ Name: String = { "name" => (<>).to_owned(), }; -#[inline] -Literal: Literal = { - "character literal" => Literal::Char(<>.to_owned()), - "string literal" => Literal::String(<>.to_owned()), - "numeric literal" => Literal::Number(<>.to_owned()), -}; - #[inline] Ranged: Ranged = { => Ranged::new(start..end, data), diff --git a/pikelet/src/pass/core_to_pretty.rs b/pikelet/src/pass/core_to_pretty.rs index d274e7689..ce13318e4 100644 --- a/pikelet/src/pass/core_to_pretty.rs +++ b/pikelet/src/pass/core_to_pretty.rs @@ -148,7 +148,7 @@ where .append(".") .append(alloc.text(label)), - TermData::Sequence(term_entries) => (alloc.nil()) + TermData::SequenceTerm(term_entries) => (alloc.nil()) .append("[") .group() .append( diff --git a/pikelet/src/pass/core_to_surface.rs b/pikelet/src/pass/core_to_surface.rs index 576265b69..841f33ede 100644 --- a/pikelet/src/pass/core_to_surface.rs +++ b/pikelet/src/pass/core_to_surface.rs @@ -230,29 +230,29 @@ impl<'me> State<'me> { Ranged::from(label.clone()), ), - TermData::Sequence(entry_terms) => { + TermData::SequenceTerm(entry_terms) => { let core_entry_terms = entry_terms .iter() .map(|entry_term| self.from_term(entry_term)) .collect(); - surface::TermData::Sequence(core_entry_terms) + surface::TermData::SequenceTerm(core_entry_terms) } - TermData::Constant(constant) => surface::TermData::Literal(match constant { - Constant::U8(value) => surface::Literal::Number(value.to_string()), - Constant::U16(value) => surface::Literal::Number(value.to_string()), - Constant::U32(value) => surface::Literal::Number(value.to_string()), - Constant::U64(value) => surface::Literal::Number(value.to_string()), - Constant::S8(value) => surface::Literal::Number(value.to_string()), - Constant::S16(value) => surface::Literal::Number(value.to_string()), - Constant::S32(value) => surface::Literal::Number(value.to_string()), - Constant::S64(value) => surface::Literal::Number(value.to_string()), - Constant::F32(value) => surface::Literal::Number(value.to_string()), - Constant::F64(value) => surface::Literal::Number(value.to_string()), - Constant::Char(value) => surface::Literal::Char(format!("{:?}", value)), - Constant::String(value) => surface::Literal::String(format!("{:?}", value)), - }), + TermData::Constant(constant) => match constant { + Constant::U8(value) => surface::TermData::NumberTerm(value.to_string()), + Constant::U16(value) => surface::TermData::NumberTerm(value.to_string()), + Constant::U32(value) => surface::TermData::NumberTerm(value.to_string()), + Constant::U64(value) => surface::TermData::NumberTerm(value.to_string()), + Constant::S8(value) => surface::TermData::NumberTerm(value.to_string()), + Constant::S16(value) => surface::TermData::NumberTerm(value.to_string()), + Constant::S32(value) => surface::TermData::NumberTerm(value.to_string()), + Constant::S64(value) => surface::TermData::NumberTerm(value.to_string()), + Constant::F32(value) => surface::TermData::NumberTerm(value.to_string()), + Constant::F64(value) => surface::TermData::NumberTerm(value.to_string()), + Constant::Char(value) => surface::TermData::CharTerm(format!("{:?}", value)), + Constant::String(value) => surface::TermData::StringTerm(format!("{:?}", value)), + }, TermData::Error => surface::TermData::Error, }; diff --git a/pikelet/src/pass/surface_to_core.rs b/pikelet/src/pass/surface_to_core.rs index ab95961e7..22ea37e34 100644 --- a/pikelet/src/pass/surface_to_core.rs +++ b/pikelet/src/pass/surface_to_core.rs @@ -13,7 +13,7 @@ use std::sync::Arc; use crate::lang::core; use crate::lang::core::semantics::{self, Elim, Head, RecordClosure, Unfold, Value}; -use crate::lang::surface::{Literal, Term, TermData}; +use crate::lang::surface::{Term, TermData}; use crate::literal; use crate::pass::core_to_surface; use crate::reporting::{AmbiguousTerm, ExpectedType, Message, SurfaceToCoreMessage}; @@ -310,7 +310,7 @@ impl<'me> State<'me> { ) } - (TermData::Sequence(entry_terms), Value::Stuck(Head::Global(name, _), spine)) => { + (TermData::SequenceTerm(entry_terms), Value::Stuck(Head::Global(name, _), spine)) => { match (name.as_ref(), spine.as_slice()) { ("Array", [Elim::Function(len), Elim::Function(core_entry_type)]) => { let core_entry_type = core_entry_type.force(self.globals); @@ -328,7 +328,7 @@ impl<'me> State<'me> { { core::Term::new( term.range(), - core::TermData::Sequence(core_entry_terms), + core::TermData::SequenceTerm(core_entry_terms), ) } Value::Error => core::Term::new(term.range(), core::TermData::Error), @@ -352,7 +352,10 @@ impl<'me> State<'me> { }) .collect(); - core::Term::new(term.range(), core::TermData::Sequence(core_entry_terms)) + core::Term::new( + term.range(), + core::TermData::SequenceTerm(core_entry_terms), + ) } _ => { let expected_type = self.read_back_to_surface_term(expected_type); @@ -364,7 +367,7 @@ impl<'me> State<'me> { } } } - (TermData::Sequence(_), _) => { + (TermData::SequenceTerm(_), _) => { let expected_type = self.read_back_to_surface_term(expected_type); self.report(SurfaceToCoreMessage::NoSequenceConversion { range: term.range(), @@ -373,34 +376,57 @@ impl<'me> State<'me> { core::Term::new(term.range(), core::TermData::Error) } - (TermData::Literal(literal), Value::Stuck(Head::Global(name, _), spine)) => { - use crate::lang::core::Constant::*; - - let range = term.range(); - match (literal, name.as_ref(), spine.as_slice()) { - (Literal::Number(data), "U8", []) => self.parse_unsigned(range, data, U8), - (Literal::Number(data), "U16", []) => self.parse_unsigned(range, data, U16), - (Literal::Number(data), "U32", []) => self.parse_unsigned(range, data, U32), - (Literal::Number(data), "U64", []) => self.parse_unsigned(range, data, U64), - (Literal::Number(data), "S8", []) => self.parse_signed(range, data, S8), - (Literal::Number(data), "S16", []) => self.parse_signed(range, data, S16), - (Literal::Number(data), "S32", []) => self.parse_signed(range, data, S32), - (Literal::Number(data), "S64", []) => self.parse_signed(range, data, S64), - (Literal::Number(data), "F32", []) => self.parse_float(range, data, F32), - (Literal::Number(data), "F64", []) => self.parse_float(range, data, F64), - (Literal::Char(data), "Char", []) => self.parse_char(range, data), - (Literal::String(data), "String", []) => self.parse_string(range, data), - (_, _, _) => { + (TermData::NumberTerm(data), Value::Stuck(Head::Global(name, _), spine)) => { + match (name.as_ref(), spine.as_slice()) { + ("U8", []) => self.parse_unsigned(term.range(), data, core::Constant::U8), + ("U16", []) => self.parse_unsigned(term.range(), data, core::Constant::U16), + ("U32", []) => self.parse_unsigned(term.range(), data, core::Constant::U32), + ("U64", []) => self.parse_unsigned(term.range(), data, core::Constant::U64), + ("S8", []) => self.parse_signed(term.range(), data, core::Constant::S8), + ("S16", []) => self.parse_signed(term.range(), data, core::Constant::S16), + ("S32", []) => self.parse_signed(term.range(), data, core::Constant::S32), + ("S64", []) => self.parse_signed(term.range(), data, core::Constant::S64), + ("F32", []) => self.parse_float(term.range(), data, core::Constant::F32), + ("F64", []) => self.parse_float(term.range(), data, core::Constant::F64), + (_, _) => { + let expected_type = self.read_back_to_surface_term(expected_type); + self.report(SurfaceToCoreMessage::NoLiteralConversion { + range: term.range(), + expected_type, + }); + core::Term::new(term.range(), core::TermData::Error) + } + } + } + (TermData::CharTerm(data), Value::Stuck(Head::Global(name, _), spine)) => { + match (name.as_ref(), spine.as_slice()) { + ("Char", []) => self.parse_char(term.range(), data), + (_, _) => { let expected_type = self.read_back_to_surface_term(expected_type); self.report(SurfaceToCoreMessage::NoLiteralConversion { - range, + range: term.range(), expected_type, }); core::Term::new(term.range(), core::TermData::Error) } } } - (TermData::Literal(_), _) => { + (TermData::StringTerm(data), Value::Stuck(Head::Global(name, _), spine)) => { + match (name.as_ref(), spine.as_slice()) { + ("String", []) => self.parse_string(term.range(), data), + (_, _) => { + let expected_type = self.read_back_to_surface_term(expected_type); + self.report(SurfaceToCoreMessage::NoLiteralConversion { + range: term.range(), + expected_type, + }); + core::Term::new(term.range(), core::TermData::Error) + } + } + } + (TermData::NumberTerm(_), _) + | (TermData::CharTerm(_), _) + | (TermData::StringTerm(_), _) => { let expected_type = self.read_back_to_surface_term(expected_type); self.report(SurfaceToCoreMessage::NoLiteralConversion { range: term.range(), @@ -703,7 +729,7 @@ impl<'me> State<'me> { (error_term(), Arc::new(Value::Error)) } - TermData::Sequence(_) => { + TermData::SequenceTerm(_) => { self.report(SurfaceToCoreMessage::AmbiguousTerm { range: term.range(), term: AmbiguousTerm::Sequence, @@ -711,23 +737,21 @@ impl<'me> State<'me> { (error_term(), Arc::new(Value::Error)) } - TermData::Literal(literal) => match literal { - Literal::Number(_) => { - self.report(SurfaceToCoreMessage::AmbiguousTerm { - range: term.range(), - term: AmbiguousTerm::NumberLiteral, - }); - (error_term(), Arc::new(Value::Error)) - } - Literal::Char(data) => ( - self.parse_char(term.range(), data), - Arc::new(Value::global("Char", 0)), - ), - Literal::String(data) => ( - self.parse_string(term.range(), data), - Arc::new(Value::global("String", 0)), - ), - }, + TermData::NumberTerm(_) => { + self.report(SurfaceToCoreMessage::AmbiguousTerm { + range: term.range(), + term: AmbiguousTerm::NumberLiteral, + }); + (error_term(), Arc::new(Value::Error)) + } + TermData::CharTerm(data) => ( + self.parse_char(term.range(), data), + Arc::new(Value::global("Char", 0)), + ), + TermData::StringTerm(data) => ( + self.parse_string(term.range(), data), + Arc::new(Value::global("String", 0)), + ), TermData::Error => (error_term(), Arc::new(Value::Error)), } diff --git a/pikelet/src/pass/surface_to_pretty.rs b/pikelet/src/pass/surface_to_pretty.rs index 525ad281a..2a175eb52 100644 --- a/pikelet/src/pass/surface_to_pretty.rs +++ b/pikelet/src/pass/surface_to_pretty.rs @@ -4,7 +4,7 @@ use pretty::{DocAllocator, DocBuilder}; -use crate::lang::surface::{Literal, Term, TermData}; +use crate::lang::surface::{Term, TermData}; /// The precedence of a term. #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] @@ -202,7 +202,7 @@ where .append(".") .append(&label.data), - TermData::Sequence(term_entries) => (alloc.nil()) + TermData::SequenceTerm(term_entries) => (alloc.nil()) .append("[") .group() .append( @@ -215,22 +215,14 @@ where ) .append("]"), - TermData::Literal(literal) => from_literal(alloc, literal), + TermData::CharTerm(text) | TermData::StringTerm(text) | TermData::NumberTerm(text) => { + alloc.text(text) + } TermData::Error => alloc.text("!"), } } -pub fn from_literal<'a, D>(alloc: &'a D, literal: &'a Literal) -> DocBuilder<'a, D> -where - D: DocAllocator<'a>, - D::Doc: Clone, -{ - match literal { - Literal::Char(text) | Literal::String(text) | Literal::Number(text) => alloc.text(text), - } -} - fn paren<'a, D>(alloc: &'a D, b: bool, doc: DocBuilder<'a, D>) -> DocBuilder<'a, D> where D: DocAllocator<'a>,