Skip to content
Merged
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
4 changes: 4 additions & 0 deletions src/between.mbt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
///|
#as_free_fn
pub fn[A, B, C] Parser::between(
self : Parser[A],
open~ : Parser[B],
Expand All @@ -12,16 +13,19 @@ pub fn[A, B, C] Parser::between(
}

///|
#as_free_fn
pub fn[A] Parser::round_bracket(self : Parser[A]) -> Parser[A] {
self.between(open=char('('), close=char(')'))
}

///|
#as_free_fn
pub fn[A] Parser::square_bracket(self : Parser[A]) -> Parser[A] {
self.between(open=char('['), close=char(']'))
}

///|
#as_free_fn
pub fn[A] Parser::curly_bracket(self : Parser[A]) -> Parser[A] {
self.between(open=char('{'), close=char('}'))
}
1 change: 1 addition & 0 deletions src/combinator.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ pub impl[A] BitOr for Parser[A] with lor(x, y) {
}

///|
#as_free_fn
pub fn[A] Parser::label(x : Parser[A], msg : String) -> Parser[A] {
fn(input) { x(input) catch { ParseError(_) as e => raise e.cons(msg) } }
}
6 changes: 6 additions & 0 deletions src/consumer.mbt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
///|
#as_free_fn
pub fn Parser::satisfy(f : (Char) -> Bool, label~ : String) -> Parser[Char] {
fn(input) {
let { chars, row, col } = input
Expand All @@ -15,16 +16,19 @@ pub fn Parser::satisfy(f : (Char) -> Bool, label~ : String) -> Parser[Char] {
}

///|
#as_free_fn
pub fn Parser::char(ch : Char) -> Parser[Char] {
satisfy(c => c == ch, label=ch.to_string())
}

///|
#as_free_fn
pub fn Parser::one_of(xs : String) -> Parser[Char] {
satisfy(String::contains_char(xs, _), label="one of \{xs.iter()}}")
}

///|
#as_free_fn
pub fn Parser::none_of(xs : String) -> Parser[Char] {
satisfy(
ch => not(String::contains_char(xs, ch)),
Expand All @@ -33,6 +37,7 @@ pub fn Parser::none_of(xs : String) -> Parser[Char] {
}

///|
#as_free_fn
pub fn Parser::string(str : String) -> Parser[String] {
fn(input) {
guard not(str.contains_char('\n')) else { panic() }
Expand All @@ -49,6 +54,7 @@ pub fn Parser::string(str : String) -> Parser[String] {
}

///|
#as_free_fn
pub fn[A] Parser::eof(x : A) -> Parser[A] {
fn(input) {
let { chars, row, col } = input
Expand Down
57 changes: 6 additions & 51 deletions src/ex_lisp_test.mbt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
///|
typealias String as Name
type Name = String

///|
enum Raw {
Expand All @@ -14,7 +14,6 @@ enum Tm {
Ix(Int)
Lam(Name, Tm)
App(Tm, Tm)
SrcPos(SourcePos, Tm)
}

///|
Expand All @@ -40,7 +39,7 @@ impl Show for Raw with output(self, logger) {
}

///|
fnalias @list.(cons, empty)
using @list {cons, empty}

///|
impl Show for Tm with output(self, logger) {
Expand All @@ -64,7 +63,6 @@ impl Show for Tm with output(self, logger) {
let name = ns.nth(ix).unwrap()
logger.write_string(name)
}
SrcPos(_, e) => dfs(e, ns)
}
}

Expand Down Expand Up @@ -112,7 +110,7 @@ test "parse" {
}

///|
typealias @list.List[Val] as Env
type Env = @list.List[Val]

///|
enum Closure {
Expand Down Expand Up @@ -165,7 +163,6 @@ fn Tm::eval(self : Tm, env : Env) -> Val {
}
Lam(x, t) => VLam(x, Closure(env, t))
Ix(x) => env.nth(x).unwrap()
SrcPos(_, e) => e.eval(env)
}
}

Expand Down Expand Up @@ -206,10 +203,10 @@ fn Raw::to_tm(self : Raw) -> Tm raise {
RVar(name) =>
Ix(
ns
.find_index(Eq::op_equal(_, name))
.or_error(ScopeError(pos, name, ns)),
.find_index(fn(x) { x == name })
.unwrap_or_error(ScopeError(pos, name, ns)),
)
RSrcPos(pos, e) => SrcPos(pos, dfs(e, ns, pos))
RSrcPos(pos, e) => dfs(e, ns, pos)
}
}

Expand All @@ -235,7 +232,6 @@ test "chunch" {
let five = five.to_tm()
let add = add.to_tm()
let mul = mul.to_tm()
let succ = succ.to_tm()
let ten = App(App(add, five), five).nf(empty())
inspect(
ten,
Expand All @@ -248,47 +244,6 @@ test "chunch" {
)
}

///|
fn[T : Compare] max(x : T, y : T) -> T {
if x > y {
x
} else {
y
}
}

///|
fn srcpos_depth(self : Raw) -> Int {
match self {
RLam(_, t) => t.srcpos_depth()
RApp(t, u) => max(t.srcpos_depth(), u.srcpos_depth())
RVar(_) => 0
RSrcPos(_, e) => 1 + e.srcpos_depth()
}
}

///|
fn collect_srcpos(self : Raw) -> Array[SourcePos] {
let res = []
fn dfs(self) {
match self {
RLam(_, t) => dfs(t)
RApp(t, u) => {
dfs(t)
dfs(u)
}
RVar(_) => ()
RSrcPos(pos, e) => {
res.push(pos)
dfs(e)
}
}
}

dfs(self)
res
}

///|
test "scope error" {
let e1 = parser.run(input("(fun x y)"))
Expand Down
14 changes: 8 additions & 6 deletions src/ex_test.mbt
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
///|
fnalias Input::new as input
fn input(chars : StringView) -> Input {
Input::new(chars)
}

///|
test "foldr/none" {
Expand Down Expand Up @@ -56,10 +58,10 @@ test "calculator" {
pure((acc, x) => acc * 10 + (Char::to_int(x) - '0'.to_int())),
)
inspect(integer.run(input), content="123456")
let add = char('+').discard_left(pure(Int::op_add))
let sub = char('-').discard_left(pure(Int::op_sub))
let mul = char('*').discard_left(pure(Int::op_mul))
let div = char('/').discard_left(pure(Int::op_div))
let add = char('+').discard_left(pure(Int::add))
let sub = char('-').discard_left(pure(Int::sub))
let mul = char('*').discard_left(pure(Int::mul))
let div = char('/').discard_left(pure(Int::div))
letrec expr = fn(input) -> (Int, Input) raise ParseError {
foldl1(term, add | sub)(input)
}
Expand Down Expand Up @@ -214,7 +216,7 @@ test "pure" {
}

///|
test "between" {
test "between/spaces" {
let x = pure(0).round_bracket()
inspect(x.run(input("()")), content="0")
inspect(x.run(input(" ()")), content="0")
Expand Down
6 changes: 6 additions & 0 deletions src/fold.mbt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
///|
#as_free_fn
pub fn[A, B] Parser::foldl(
x : Parser[A],
z : Parser[B],
Expand All @@ -17,6 +18,7 @@ pub fn[A, B] Parser::foldl(
}

///|
#as_free_fn
pub fn[A, B] Parser::foldr(
x : Parser[A],
z : Parser[B],
Expand All @@ -40,16 +42,19 @@ pub fn[A, B] Parser::foldr(
}

///|
#as_free_fn
pub fn[A] Parser::foldr1(x : Parser[A], f : Parser[(A, A) -> A]) -> Parser[A] {
foldr(x, x, f)
}

///|
#as_free_fn
pub fn[A] Parser::foldl1(x : Parser[A], f : Parser[(A, A) -> A]) -> Parser[A] {
foldl(x, x, f)
}

///|
#as_free_fn
pub fn[A] Parser::many_each(x : Parser[A], f : (A) -> Unit) -> Parser[Unit] {
fn(input) {
let r = x(input)
Expand All @@ -64,6 +69,7 @@ pub fn[A] Parser::many_each(x : Parser[A], f : (A) -> Unit) -> Parser[Unit] {
}

///|
#as_free_fn
pub fn[A] Parser::many(self : Parser[A]) -> Parser[Array[A]] {
self.foldl(
pure([]),
Expand Down
6 changes: 6 additions & 0 deletions src/monadic.mbt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
///|
#as_free_fn
pub fn[A, B] Parser::bind(x : Parser[A], f : (A) -> Parser[B]) -> Parser[B] {
fn(input) {
let (v, rest) = x(input)
Expand All @@ -7,16 +8,19 @@ pub fn[A, B] Parser::bind(x : Parser[A], f : (A) -> Parser[B]) -> Parser[B] {
}

///|
#as_free_fn
pub fn[A] Parser::pure(x : A) -> Parser[A] {
fn(input) { (x, input) }
}

///|
#as_free_fn
pub fn[A, B] Parser::map(self : Parser[A], f : (A) -> B) -> Parser[B] {
self.bind(x => pure(f(x)))
}

///|
#as_free_fn
pub fn[A, B] Parser::map_srcpos(
self : Parser[A],
f : (SourcePos, A) -> B,
Expand All @@ -29,11 +33,13 @@ pub fn[A, B] Parser::map_srcpos(
}

///|
#as_free_fn
pub fn[A, B] Parser::discard_left(x : Parser[A], y : Parser[B]) -> Parser[B] {
x.bind(_ => y)
}

///|
#as_free_fn
pub fn[A, B] Parser::discard_right(x : Parser[A], y : Parser[B]) -> Parser[A] {
x.bind(r => y.bind(_ => pure(r)))
}
4 changes: 1 addition & 3 deletions src/moon.pkg.json
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
{
"warn-list": "-1-2-3-5-6-7-8-9-10-29"
}
{}
Loading