Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Fix exposure related bugs #137

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions misc/grammar/lushui.grammar
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,8 @@ Argument ::=
; | Lower-Expression
; | Explicitness "(" (#Identifier "=")? Expression ")"

Lower-Expression ::= Attribute* Naked-Lower-Expression
; @Task rename into Field-Or-Lower
Naked-Lower-Expression ::= Lowest-Expression ("::" Identifier)*
Lower-Expression ::= Attribute* Field-Or-Lower
Field-Or-Lower ::= Lowest-Expression ("::" Identifier)*
Lowest-Expression ::=
| Path
| "Type"
Expand Down
2 changes: 1 addition & 1 deletion src/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ impl<'a> Compiler<'a> {
todo!()
}
}
Field(_field) => todo!(),
Lambda(lambda) => {
let mut body = self.compile_expression(&lambda.body, LambdaParent::Lambda)?;

Expand All @@ -245,7 +246,6 @@ impl<'a> Compiler<'a> {
Error => todo!(),
Substitution(_substitution) => todo!(),
ForeignApplication(_application) => todo!(),
Projection(_projection) => todo!(),
IO(_io) => todo!(),
};

Expand Down
22 changes: 17 additions & 5 deletions src/lowerer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -552,10 +552,20 @@ impl<'a> Lowerer<'a> {
binder: *path,
}
}),
// @Beacon @Task
Field(_field) => Err(errors.inserted(
Diagnostic::unimplemented("record fields").with_primary_span(expression.span),
)),
Field(field) => {
let base = self
.lower_expression(field.base, context)
.try_in(&mut errors);

errors.err_or(expr! {
Field {
attributes,
expression.span;
base,
member: field.member,
}
})
}
LambdaLiteral(lambda) => {
let mut expression = self
.lower_expression(lambda.body, context)
Expand Down Expand Up @@ -1047,7 +1057,9 @@ impl<'a> Lowerer<'a> {
// but I think we lack a method for this right now
return Err(Diagnostic::error()
.with_code(Code::E017)
.with_message("field marker `::` used outside of a constructor declaration")
.with_message(
"record field marker `::` used outside of a constructor declaration",
)
.with_primary_span(field)
.with_labeled_secondary_span(context.declaration, "not a constructor"));
}
Expand Down
10 changes: 10 additions & 0 deletions src/lowerer/lowered_ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ pub struct Use {

pub type Expression = Item<ExpressionKind>;

// @Task use a naming scheme that is closer to the one of the AST's
// e.g. `PiTypeLiteral` and `Path`
#[derive(Clone)]
pub enum ExpressionKind {
PiType(Rc<PiType>),
Expand All @@ -70,6 +72,7 @@ pub enum ExpressionKind {
Number(Rc<Number>),
Text(Rc<String>),
Binding(Rc<Binding>),
Field(Rc<Field>),
Lambda(Rc<Lambda>),
UseIn,
CaseAnalysis(Rc<CaseAnalysis>),
Expand Down Expand Up @@ -101,11 +104,18 @@ pub struct Application {
pub explicitness: Explicitness,
}

// @Question inline?
#[derive(Clone)]
pub struct Binding {
pub binder: Path,
}

#[derive(Clone)]
pub struct Field {
pub base: Expression,
pub member: Identifier,
}

#[derive(Clone)]
pub struct Lambda {
pub parameter: Identifier,
Expand Down
2 changes: 2 additions & 0 deletions src/lowerer/lowered_ast/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,8 @@ impl fmt::Display for super::Expression {
Number(literal) => write!(f, "{}", literal),
Text(literal) => write!(f, "{:?}", literal),
Binding(binding) => write!(f, "{}", binding.binder),
// @Task less brackets
Field(field) => write!(f, "({})::{}", field.base, field.member),
Lambda(lambda) => write!(f, "{}", lambda),
UseIn => todo!(),
// @Task fix indentation
Expand Down
7 changes: 2 additions & 5 deletions src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1001,9 +1001,8 @@ impl<'a> Parser<'a> {
/// ## Grammar
///
/// ```ebnf
/// Lower-Expression ::= Attribute* Naked-Lower-Expression
/// ; @Task rename into Field-Or-Lower
/// Naked-Lower-Expression ::= Lowest-Expression ("::" Identifier)*
/// Lower-Expression ::= Attribute* Field-Or-Lower
/// Field-Or-Lower ::= Lowest-Expression ("::" Identifier)*
/// Lowest-Expression ::=
/// | Path
/// | "Type"
Expand All @@ -1026,8 +1025,6 @@ impl<'a> Parser<'a> {
let attributes = self.parse_attributes(SkipLineBreaks::No)?;

let mut span = self.current_token().span;
// @Task don't pass attributes down but make them empty at first, then update the attributes
// dependeninh on if it's a field or not
let mut expression = match self.current_token().kind {
kind if kind.is_path_head() => {
let path = self.parse_path()?;
Expand Down
30 changes: 27 additions & 3 deletions src/resolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ use crate::{
error::{accumulate_errors, obtain, ManyErrExt, PossiblyErroneous, TransposeExt, TryIn},
lowered_ast::{self, AttributeKeys, AttributeKind},
};
use colored::Colorize;
use hir::{decl, expr, pat};
pub use scope::{
CrateIndex, CrateScope, DeBruijnIndex, Exposure, FunctionScope, Identifier, Index, Namespace,
Expand Down Expand Up @@ -70,18 +71,30 @@ impl<'a> Resolver<'a> {
) -> Results<hir::Declaration> {
// @Note awkward manual error propagation, very error prone
// topic: horrible error handling APIs

eprintln!("{}", "[#] Resolver::start_resolve_declaration()".yellow()); // @Temporary
self.start_resolve_declaration(&declaration, None, Context::default())
.map_err(|error| error.diagnostics(mem::take(&mut self.scope.duplicate_definitions)))?;
eprintln!("[#] CrateScope: {:?}", self.scope);

eprintln!("{}", "[#] CrateScope::resolve_use_bindings()".yellow());
self.scope.resolve_use_bindings();
eprintln!("[#] CrateScope: {:?}", self.scope);

// @Task @Beacon don't return early here
self.scope.resolve_exposure_reaches()?;
eprintln!("{}", "[#] CrateScope::resolve_exposure_reaches()".yellow());
self.scope.resolve_exposure_reaches();
eprintln!("[#] CrateScope: {:?}", self.scope);

eprintln!(
"{}",
"[#] CrateScope::finish_resolve_declaration()".yellow()
);
let declaration = self
.finish_resolve_declaration(declaration, None, Context::default())
.try_in(&mut self.scope.errors);

// dbg!(&self.scope); // @Temporary

self.scope.errors.take().err_or(declaration)
}

Expand Down Expand Up @@ -477,6 +490,17 @@ impl<'a> Resolver<'a> {
binder: scope.resolve_binding(&binding.binder, &self.scope).many_err()?,
}
},
Field(field) => {
let base = self.resolve_expression(field.base.clone(), scope)?;

expr! {
Field {
expression.attributes, expression.span;
base,
member: field.member.clone(),
}
}
}
// @Task @Beacon @Beacon don't use try_in here: you don't need to: use
// accumulate_err, the stuff here is independent! right??
Lambda(lambda) => expr! {
Expand All @@ -500,7 +524,7 @@ impl<'a> Resolver<'a> {
},
UseIn => {
return Err(
Diagnostic::unimplemented("use/in expression").with_primary_span(&expression)
Diagnostic::unimplemented("use/in-expressions").with_primary_span(&expression)
)
.many_err()
}
Expand Down
13 changes: 7 additions & 6 deletions src/resolver/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,11 @@ pub enum ExpressionKind {
Text(Rc<String>),
Binding(Rc<Binding>),
Lambda(Rc<Lambda>),
Field(Rc<Field>),
UseIn,
CaseAnalysis(Rc<CaseAnalysis>),
Substitution(Rc<Substitution>),
ForeignApplication(Rc<ForeignApplication>),
Projection(Rc<Projection>),
IO(Rc<IO>),
Error,
}
Expand Down Expand Up @@ -114,6 +114,12 @@ pub struct Binding {
pub binder: Identifier,
}

#[derive(Clone)]
pub struct Field {
pub base: Expression,
pub member: crate::ast::Identifier,
}

#[derive(Clone)]
pub struct Lambda {
pub parameter: Identifier,
Expand Down Expand Up @@ -143,11 +149,6 @@ pub struct ForeignApplication {
pub arguments: Vec<Expression>,
}

// @Temporary until we have better case analysis support to replace it with
// @Task @Beacon
#[derive(Clone)]
pub struct Projection {}

#[derive(Clone)]
pub struct IO {
pub index: usize, // @Task IOIndex
Expand Down
4 changes: 2 additions & 2 deletions src/resolver/hir/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -244,8 +244,8 @@ fn format_lower_expression(
"{}",
super::FunctionScope::absolute_path(&binding.binder, scope)
),
// @Beacon @Temporary @Task just write out the path
Projection(_projection) => write!(f, "?(projection)"),
// @Beacon @Task less brackets!
Field(field) => write!(f, "({})::{}", field.base.with(scope), field.member),
IO(io) => write!(
f,
"?(io {} {})",
Expand Down
Loading