mirror of
https://github.com/HigherOrderCO/Bend.git
synced 2024-09-11 03:45:29 +03:00
Add unbound refs check
This commit is contained in:
parent
6f6747ddc9
commit
3705094b6d
@ -1,3 +1,4 @@
|
|||||||
pub mod set_entrypoint;
|
pub mod set_entrypoint;
|
||||||
pub mod shared_names;
|
pub mod shared_names;
|
||||||
|
pub mod unbound_refs;
|
||||||
pub mod unbound_vars;
|
pub mod unbound_vars;
|
||||||
|
37
src/fun/check/unbound_refs.rs
Normal file
37
src/fun/check/unbound_refs.rs
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
use crate::{
|
||||||
|
diagnostics::Diagnostics,
|
||||||
|
fun::{Ctx, Definitions, Name, Term},
|
||||||
|
maybe_grow,
|
||||||
|
};
|
||||||
|
use std::collections::HashSet;
|
||||||
|
|
||||||
|
impl Ctx<'_> {
|
||||||
|
pub fn check_unbound_refs(&mut self) -> Result<(), Diagnostics> {
|
||||||
|
self.info.start_pass();
|
||||||
|
for def in self.book.defs.values() {
|
||||||
|
let mut unbounds = HashSet::new();
|
||||||
|
for rule in def.rules.iter() {
|
||||||
|
rule.body.check_unbound_refs(&self.book.defs, &mut unbounds);
|
||||||
|
}
|
||||||
|
for unbound in unbounds {
|
||||||
|
self.info.add_rule_error(format!("Reference to undefined function '{unbound}'"), def.name.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.info.fatal(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Term {
|
||||||
|
pub fn check_unbound_refs(&self, defs: &Definitions, unbounds: &mut HashSet<Name>) {
|
||||||
|
maybe_grow(|| {
|
||||||
|
if let Term::Ref { nam } = self {
|
||||||
|
if !defs.contains_key(nam) {
|
||||||
|
unbounds.insert(nam.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for child in self.children() {
|
||||||
|
child.check_unbound_refs(defs, unbounds);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
@ -36,7 +36,7 @@ impl Ctx<'_> {
|
|||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone, Default)]
|
||||||
pub struct Book {
|
pub struct Book {
|
||||||
/// The function definitions.
|
/// The function definitions.
|
||||||
pub defs: IndexMap<Name, Definition>,
|
pub defs: Definitions,
|
||||||
|
|
||||||
/// The algebraic datatypes defined by the program
|
/// The algebraic datatypes defined by the program
|
||||||
pub adts: Adts,
|
pub adts: Adts,
|
||||||
@ -48,6 +48,7 @@ pub struct Book {
|
|||||||
pub entrypoint: Option<Name>,
|
pub entrypoint: Option<Name>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub type Definitions = IndexMap<Name, Definition>;
|
||||||
pub type Adts = IndexMap<Name, Adt>;
|
pub type Adts = IndexMap<Name, Adt>;
|
||||||
pub type Constructors = IndexMap<Name, Name>;
|
pub type Constructors = IndexMap<Name, Name>;
|
||||||
|
|
||||||
|
@ -140,6 +140,8 @@ pub fn desugar_book(
|
|||||||
ctx.book.float_combinators(MAX_NET_SIZE);
|
ctx.book.float_combinators(MAX_NET_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ctx.check_unbound_refs()?;
|
||||||
|
|
||||||
ctx.prune(opts.prune);
|
ctx.prune(opts.prune);
|
||||||
|
|
||||||
if opts.merge {
|
if opts.merge {
|
||||||
|
11
tests/golden_tests/hangs/bad_dup_interaction.bend
Normal file
11
tests/golden_tests/hangs/bad_dup_interaction.bend
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
# A net that expands inifinitely like church exponentiation
|
||||||
|
# Compiles to this net:
|
||||||
|
# a
|
||||||
|
# & ({(b c) (d b)} (c d)) ~ {(e a) e}
|
||||||
|
main =
|
||||||
|
let {a1 a2} =
|
||||||
|
@b
|
||||||
|
let {b1 b2} = b
|
||||||
|
let (c1, c2) = b2
|
||||||
|
((b1 c2), c1)
|
||||||
|
(a1 a2)
|
10
tests/golden_tests/run_file/unbound_wrap.bend
Normal file
10
tests/golden_tests/run_file/unbound_wrap.bend
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
type Maybe = (Some x) | None
|
||||||
|
|
||||||
|
Maybe/bind val nxt = match val {
|
||||||
|
Maybe/Some: (nxt val.x)
|
||||||
|
Maybe/None: Maybe/None
|
||||||
|
}
|
||||||
|
|
||||||
|
main = with Maybe {
|
||||||
|
(wrap 1)
|
||||||
|
}
|
7
tests/snapshots/run_file__unbound_wrap.bend.snap
Normal file
7
tests/snapshots/run_file__unbound_wrap.bend.snap
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
source: tests/golden_tests.rs
|
||||||
|
input_file: tests/golden_tests/run_file/unbound_wrap.bend
|
||||||
|
---
|
||||||
|
[4m[1m[31mErrors:[0m
|
||||||
|
[1mIn definition '[4mmain[0m[1m':[0m
|
||||||
|
Reference to undefined function 'Maybe/wrap'
|
Loading…
Reference in New Issue
Block a user