Skip to content

Commit

Permalink
Work on records for a bit
Browse files Browse the repository at this point in the history
  • Loading branch information
fmease committed Sep 11, 2023
1 parent 841c8ba commit 7f2ac29
Show file tree
Hide file tree
Showing 38 changed files with 333 additions and 189 deletions.
35 changes: 18 additions & 17 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,24 @@ rustflags = [
"-Dunused_crate_dependencies",
"-Dclippy::all",
"-Dclippy::pedantic",
"-Aclippy::blocks_in_if_conditions", # too many false positives with rustfmt's style
"-Aclippy::empty_enum", # for type-level programming
"-Aclippy::enum_glob_use", # alternative is too verbose
"-Aclippy::if_not_else", # too opinionated, sometimes the negative case is the more common one
"-Aclippy::items_after_statements", # too opinionated
"-Aclippy::match_bool", # too opinionated
"-Aclippy::missing_errors_doc", # not a priority right now
"-Aclippy::missing_panics_doc", # @Temporary, a churn to fix, not a priority right now
"-Aclippy::module_name_repetitions", # false positives, too opinionated
"-Aclippy::must_use_candidate", # @Temporary, a churn to fix, not a priority right now
"-Aclippy::result_unit_err", # ‘Result<_, ()>’ has its uses, in some cases an alt. to ‘Option<_>’
"-Aclippy::return_self_not_must_use", # @Temporary, a churn to fix, not a priority right now
"-Aclippy::similar_names", # too strict
"-Aclippy::single_match_else", # too opinionated, match exprs look better in many cases
"-Aclippy::struct_excessive_bools", # too many false postives with CLI flag structs
"-Aclippy::too_many_lines", # too opinionated
"-Aclippy::trait_duplication_in_bounds", # @Temporary false positives: rust-clippy#8757
"-Aclippy::blocks_in_if_conditions", # too many false positives with rustfmt's style
"-Aclippy::empty_enum", # for type-level programming
"-Aclippy::enum_glob_use", # alternative is too verbose
"-Aclippy::if_not_else", # too opinionated, sometimes the negative case is the more common one
"-Aclippy::items_after_statements", # too opinionated
"-Aclippy::match_bool", # too opinionated
"-Aclippy::missing_errors_doc", # not a priority right now
"-Aclippy::missing_panics_doc", # @Temporary, a churn to fix, not a priority right now
"-Aclippy::module_name_repetitions", # false positives, too opinionated
"-Aclippy::must_use_candidate", # @Temporary, a churn to fix, not a priority right now
"-Aclippy::result_unit_err", # ‘Result<_, ()>’ has its uses, in some cases an alt. to ‘Option<_>’
"-Aclippy::return_self_not_must_use", # @Temporary, a churn to fix, not a priority right now
"-Aclippy::similar_names", # too strict
"-Aclippy::single_match_else", # too opinionated, match exprs look better in many cases
"-Aclippy::struct_excessive_bools", # too many false postives with CLI flag structs
"-Aclippy::too_many_lines", # too opinionated
"-Aclippy::trait_duplication_in_bounds", # @Temporary false positives: rust-clippy#8757
"-Aclippy::redundant_closure_for_method_calls", # @Temporary false positives: rust-clippy#9335
] # workaround for cargo#5034

# Used by the GitHub CI workflow.
Expand Down
4 changes: 2 additions & 2 deletions README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -55,15 +55,15 @@ data Option A of
use Option.(none, some)

@public
map 'A 'B (x: Option A) (f: A -> B): B =
map 'A 'B (f: A -> B) (x: Option A): Option B =
case x of
none => none
some (let x) => some (f x)

use extern.core.(type.Type, nat.(Nat, +, *))

process (n: Option Nat): Option Nat =
map n for n => + n 1
map (for n => + n 1) n


@public @transparent
Expand Down
10 changes: 5 additions & 5 deletions compiler/ast/src/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ mod format_struct {
pub(super) fn name(mut self, name: &str) -> Self {
self.result = self
.result
.and_then(|_| write!(self.formatter, "{}", name.color(palette::NAME).bold()));
.and_then(|()| write!(self.formatter, "{}", name.color(palette::NAME).bold()));

self
}
Expand All @@ -86,15 +86,15 @@ mod format_struct {
self.indentation = self.indentation.increased();
}

self.result = self.result.and_then(|_| {
self.result = self.result.and_then(|()| {
if self.inline {
write!(self.formatter, " ")
} else {
writeln!(self.formatter)
}
});

self.result = self.result.and_then(|_| {
self.result = self.result.and_then(|()| {
if !self.inline {
write!(self.formatter, "{}", self.indentation)?;
}
Expand Down Expand Up @@ -589,8 +589,8 @@ impl<T: Format> Format for super::Field<T> {
fn format(&self, f: &mut Formatter<'_>, indentation: Indentation) -> Result {
FormatStruct::new(f, indentation)
.name("Field")
.field("name", &self.name)
.field("value", &self.item)
.field("binder", &self.binder)
.field("body", &self.body)
.finish()
}
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/ast/src/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,6 @@ pub struct RecordLiteral<T> {

pub struct Field<T> {
// @Task generalize this to some new kind of path that is delimited by "::" OR "."
pub name: Identifier,
pub item: Option<T>,
pub binder: Identifier,
pub body: Option<T>,
}
10 changes: 6 additions & 4 deletions compiler/codegen_llvm/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//! The LLVM-IR generator.
#![feature(let_chains, io_error_other)]
#![feature(let_chains)]
#![allow(clippy::match_same_arms)] // @Temporary

use diagnostics::{error::Result, Diagnostic};
Expand Down Expand Up @@ -379,6 +379,7 @@ impl<'a, 'ctx> Generator<'a, 'ctx> {
PiType(_) => todo!(),
Number(number) => self.compile_number(number).into(),
Text(_) => todo!(),
Record(_) => todo!(),
Binding(_) => todo!(),
Lambda(_)
| CaseAnalysis(_)
Expand Down Expand Up @@ -437,6 +438,7 @@ impl<'a, 'ctx> Generator<'a, 'ctx> {
}
Number(number) => Some(self.compile_number(number).into()),
Text(_) => todo!("compiling text"),
Record(_) => todo!("compiling records"),
Binding(binding) if self.session.specials().is(binding.0, Type::Type) => None,
Binding(binding) => {
use hir::Index::*;
Expand Down Expand Up @@ -531,7 +533,7 @@ impl<'a, 'ctx> Generator<'a, 'ctx> {
IntrinsicApplication(_) => todo!(),
Projection(_) => todo!(),
Error(_) => todo!(),
Number(_) | Text(_) | IO(_) => unreachable!(),
Number(_) | Text(_) | Record(_) | IO(_) => unreachable!(),
}
}

Expand All @@ -547,15 +549,14 @@ impl<'a, 'ctx> Generator<'a, 'ctx> {
codomain.fn_type(&[domain.into()], false)
}
Application(_) => todo!(),
Number(_) | Text(_) => unreachable!(),
Binding(_) => todo!(),
Lambda(_) => todo!(),
CaseAnalysis(_) => todo!(),
Substituted(_) => todo!(),
IntrinsicApplication(_) => todo!(),
Projection(_) => todo!(),
IO(_) => todo!(),
Error(_) => todo!(),
Number(_) | Text(_) | Record(_) | IO(_) => unreachable!(),
}
}
}
Expand Down Expand Up @@ -584,6 +585,7 @@ impl ExpressionExt for hir::Expression {
Substituted(_) => todo!(),
Projection(_) => todo!(),
IO(_) => todo!(),
Record(_) => todo!(),
Error(_) => todo!(),
}
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/diagnostics/src/format/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,7 @@ warning: it
hopefully
help: less helpful
tip",
)
);
}

#[test]
Expand Down Expand Up @@ -768,7 +768,7 @@ warning: this file looks spooky
┌─ scary.exe
help: better delete it",
)
);
}

#[test]
Expand Down
3 changes: 2 additions & 1 deletion compiler/documenter/src/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,8 +198,9 @@ impl<'a> Formatter<'a> {
Number(literal) => self.write(&literal.to_string()),
Text(literal) => self.write(&literal.to_string()),
Binding(binding) => self.format_binder(&binding.0),
// @Beacon @Temporary @Task just write out the path
// @Task
Projection(_projection) => self.write("⟨projection⟩"),
Record(_record) => self.write("⟨record⟩"),
IO(io) => {
self.write("⟨io ");
self.write(&io.index.to_string());
Expand Down
11 changes: 6 additions & 5 deletions compiler/documenter/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -850,10 +850,10 @@ fn add_declaration_attribute(attribute: &Attribute, parent: &mut Element<'_>, ur
Unstable(_) => parent.add_child(Element::div("experimental").child("experimental")),
Unsafe => parent.add_child(Element::div("unsafe").child("unsafe")),

// rendered separately
// Rendered separately.
Doc { .. } => {}

// not rendered
// Not rendered since they are not part of the API.
Allow { .. }
| Deny { .. }
| Forbid { .. }
Expand All @@ -863,10 +863,11 @@ fn add_declaration_attribute(attribute: &Attribute, parent: &mut Element<'_>, ur
| Statistics
| Warn { .. } => {}

// should not exist at this point in time
// Not rendered since they are truly internal and not part of the surface language.
Context | Record | Trait => {}

// Should not exist at this stage.
Ignore | Include | Test => unreachable!(),
// render given-declarations properly
Context => todo!(),
}
}

Expand Down
10 changes: 5 additions & 5 deletions compiler/driver/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -435,7 +435,7 @@ impl TypedValueParser for ColorModeParser {
) -> Result<Self::Value, clap::Error> {
let source = parse_utf8(source)?;

source.parse().map_err(|_| {
source.parse().map_err(|()| {
// @Task smh. avoid using `Error::raw` and smh. pass along the context.
// https://github.com/clap-rs/clap/discussions/4029
clap::Error::raw(
Expand Down Expand Up @@ -700,7 +700,7 @@ impl TypedValueParser for WordParser {
) -> Result<Self::Value, clap::Error> {
let source = parse_utf8(source)?;

Word::parse(source.to_owned()).map_err(|_| {
Word::parse(source.to_owned()).map_err(|()| {
// @Task smh. avoid using `Error::raw` and smh. pass along the context.
// https://github.com/clap-rs/clap/discussions/4029
clap::Error::raw(
Expand All @@ -726,7 +726,7 @@ impl TypedValueParser for ComponentTypeParser {
let source = parse_utf8(source)?;

// @Task smh. also support the shorthands (e.g. `exe`, `lib`)
source.parse().map_err(|_| {
source.parse().map_err(|()| {
// @Task smh. avoid using `Error::raw` and smh. pass along the context.
// https://github.com/clap-rs/clap/discussions/4029
clap::Error::raw(
Expand Down Expand Up @@ -757,7 +757,7 @@ impl TypedValueParser for BackendParser {
) -> Result<Self::Value, clap::Error> {
let source = parse_utf8(source)?;

source.parse().map_err(|_| {
source.parse().map_err(|()| {
// @Task smh. avoid using `Error::raw` and smh. pass along the context.
// https://github.com/clap-rs/clap/discussions/4029
clap::Error::raw(
Expand Down Expand Up @@ -1064,7 +1064,7 @@ mod unstable {
}

impl From<()> for ParseError {
fn from(_: ()) -> Self {
fn from((): ()) -> Self {
Self::UndefinedOption
}
}
Expand Down
31 changes: 25 additions & 6 deletions compiler/hir/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

use diagnostics::{error::PossiblyErroneous, reporter::ErasedReportedError};
use joinery::JoinableIterator;
use span::SourceFileIndex;
use span::{SourceFileIndex, Spanned};
use special::NumericType;
use std::{
fmt,
Expand Down Expand Up @@ -109,17 +109,18 @@ pub type Expression = Item<BareExpression>;

#[derive(Clone)]
pub enum BareExpression {
PiType(Box<PiType>),
Application(Box<Application<Expression>>),
Number(Box<Number>),
Text(Box<Text>),
Binding(Box<Binding>),
Lambda(Box<Lambda>),
CaseAnalysis(Box<CaseAnalysis>),
Substituted(Box<Substituted>),
Application(Box<Application<Expression>>),
IntrinsicApplication(Box<IntrinsicApplication>),
Record(Box<Record>),
Projection(Box<Projection>),
PiType(Box<PiType>),
Lambda(Box<Lambda>),
IO(Box<IO>),
CaseAnalysis(Box<CaseAnalysis>),
Substituted(Box<Substituted>),
Error(ErasedReportedError),
}

Expand Down Expand Up @@ -224,6 +225,24 @@ impl From<IntrinsicApplication> for BareExpression {
}
}

#[derive(Clone)]
pub struct Record {
pub type_: Spanned<DeclarationIndex>,
pub fields: Vec<Field>,
}

impl From<Record> for BareExpression {
fn from(record: Record) -> Self {
Self::Record(Box::new(record))
}
}

#[derive(Clone)]
pub struct Field {
pub binder: ast::Identifier,
pub body: Expression,
}

#[derive(Clone)]
pub struct Projection {
pub basis: Expression,
Expand Down
30 changes: 16 additions & 14 deletions compiler/hir_format/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,8 @@ fn write_lower_expression(
write_lower_expression(&projection.basis, session, f)?;
write!(f, "::{}", projection.field)
}
// @Task
Record(_record) => f.write_str("⟨record⟩"),
IO(io) => {
// @Temporary format
write!(f, "⟨io {}", io.index)?;
Expand Down Expand Up @@ -538,26 +540,26 @@ impl ComponentExt for Component {
) -> String {
let entity = &self[index];
// @Task rewrite this recursive approach to an iterative one!
if let Some(parent) = entity.parent {
let mut parent_path = self.local_index_with_root_to_extern_path(parent, root);
let Some(parent) = entity.parent else {
return root;
};

let parent_is_symbol = parent_path.chars().next_back().unwrap().is_symbol();
let mut parent_path = self.local_index_with_root_to_extern_path(parent, root);

if parent_is_symbol {
parent_path.push(' ');
}
let parent_is_symbol = parent_path.chars().next_back().unwrap().is_symbol();

parent_path.push('.');
if parent_is_symbol {
parent_path.push(' ');
}

if entity.source.is_symbol() && parent_is_symbol {
parent_path.push(' ');
}
parent_path.push('.');

parent_path += entity.source.to_str();
parent_path
} else {
root
if entity.source.is_symbol() && parent_is_symbol {
parent_path.push(' ');
}

parent_path += entity.source.to_str();
parent_path
}

fn local_index_to_path_segments(
Expand Down
2 changes: 1 addition & 1 deletion compiler/hir_format/src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -721,7 +721,7 @@ fn attributes() {
.into(),
),
&session,
)
);
}

#[test]
Expand Down
Loading

0 comments on commit 7f2ac29

Please sign in to comment.