diff --git a/src/between.mbt b/src/between.mbt index 5657864..24bb5ae 100644 --- a/src/between.mbt +++ b/src/between.mbt @@ -1,4 +1,5 @@ ///| +#as_free_fn pub fn[A, B, C] Parser::between( self : Parser[A], open~ : Parser[B], @@ -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('}')) } diff --git a/src/combinator.mbt b/src/combinator.mbt index d8d448b..f24ab63 100644 --- a/src/combinator.mbt +++ b/src/combinator.mbt @@ -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) } } } diff --git a/src/consumer.mbt b/src/consumer.mbt index a645ec0..26e2bcc 100644 --- a/src/consumer.mbt +++ b/src/consumer.mbt @@ -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 @@ -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)), @@ -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() } @@ -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 diff --git a/src/ex_lisp_test.mbt b/src/ex_lisp_test.mbt index 8de6790..0b22b6b 100644 --- a/src/ex_lisp_test.mbt +++ b/src/ex_lisp_test.mbt @@ -1,5 +1,5 @@ ///| -typealias String as Name +type Name = String ///| enum Raw { @@ -14,7 +14,6 @@ enum Tm { Ix(Int) Lam(Name, Tm) App(Tm, Tm) - SrcPos(SourcePos, Tm) } ///| @@ -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) { @@ -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) } } @@ -112,7 +110,7 @@ test "parse" { } ///| -typealias @list.List[Val] as Env +type Env = @list.List[Val] ///| enum Closure { @@ -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) } } @@ -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) } } @@ -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, @@ -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)")) diff --git a/src/ex_test.mbt b/src/ex_test.mbt index 668a989..8a18281 100644 --- a/src/ex_test.mbt +++ b/src/ex_test.mbt @@ -1,5 +1,7 @@ ///| -fnalias Input::new as input +fn input(chars : StringView) -> Input { + Input::new(chars) +} ///| test "foldr/none" { @@ -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) } @@ -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") diff --git a/src/fold.mbt b/src/fold.mbt index 0551512..1e034c5 100644 --- a/src/fold.mbt +++ b/src/fold.mbt @@ -1,4 +1,5 @@ ///| +#as_free_fn pub fn[A, B] Parser::foldl( x : Parser[A], z : Parser[B], @@ -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], @@ -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) @@ -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([]), diff --git a/src/monadic.mbt b/src/monadic.mbt index 8fb1ba1..0983b59 100644 --- a/src/monadic.mbt +++ b/src/monadic.mbt @@ -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) @@ -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, @@ -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))) } diff --git a/src/moon.pkg.json b/src/moon.pkg.json index 2f58fac..0967ef4 100644 --- a/src/moon.pkg.json +++ b/src/moon.pkg.json @@ -1,3 +1 @@ -{ - "warn-list": "-1-2-3-5-6-7-8-9-10-29" -} +{} diff --git a/src/pkg.generated.mbti b/src/pkg.generated.mbti new file mode 100644 index 0000000..c729458 --- /dev/null +++ b/src/pkg.generated.mbti @@ -0,0 +1,109 @@ +// Generated using `moon info`, DON'T EDIT IT +package "illusory0x0/simple_parserc" + +import( + "moonbitlang/core/list" +) + +// Values +pub let alphabetic : Parser[Char] + +pub let any : Parser[Char] + +pub let digit : Parser[Char] + +pub let space : Parser[Char] + +pub let space1 : Parser[Char] + +pub let spaces : Parser[Char] + +// Errors +pub(all) suberror ParseError { + ParseError(SourcePos, @list.List[String]) +} +pub fn ParseError::cons(Self, String) -> Self +#as_free_fn +pub fn ParseError::expect(row~ : Int, col~ : Int, String) -> Self +pub fn ParseError::source_pos(Self) -> SourcePos +pub impl Show for ParseError + +// Types and methods +pub(all) struct Input { + chars : StringView + row : Int + col : Int +} +#as_free_fn +pub fn Input::new(StringView) -> Self +pub impl Show for Input + +pub(all) struct Parser[A]((Input) -> (A, Input) raise ParseError) +#as_free_fn +pub fn[A, B, C] Parser::between(Self[A], open~ : Self[B], close~ : Self[C]) -> Self[A] +#as_free_fn +pub fn[A, B] Parser::bind(Self[A], (A) -> Self[B]) -> Self[B] +#as_free_fn +pub fn Parser::char(Char) -> Self[Char] +#as_free_fn +pub fn[A] Parser::curly_bracket(Self[A]) -> Self[A] +#as_free_fn +pub fn[A, B] Parser::discard_left(Self[A], Self[B]) -> Self[B] +#as_free_fn +pub fn[A, B] Parser::discard_right(Self[A], Self[B]) -> Self[A] +#as_free_fn +pub fn[A] Parser::discard_spaces(Self[A]) -> Self[A] +#as_free_fn +pub fn[A] Parser::eof(A) -> Self[A] +#as_free_fn +pub fn[A, B] Parser::foldl(Self[A], Self[B], Self[(B, A) -> B]) -> Self[B] +#as_free_fn +pub fn[A] Parser::foldl1(Self[A], Self[(A, A) -> A]) -> Self[A] +#as_free_fn +pub fn[A, B] Parser::foldr(Self[A], Self[B], Self[(B, A) -> B]) -> Self[B] +#as_free_fn +pub fn[A] Parser::foldr1(Self[A], Self[(A, A) -> A]) -> Self[A] +#deprecated +pub fn[A] Parser::inner(Self[A]) -> (Input) -> (A, Input) raise ParseError +#as_free_fn +pub fn[A] Parser::label(Self[A], String) -> Self[A] +#as_free_fn +pub fn[A] Parser::many(Self[A]) -> Self[Array[A]] +#as_free_fn +pub fn[A] Parser::many_each(Self[A], (A) -> Unit) -> Self[Unit] +#as_free_fn +pub fn[A, B] Parser::map(Self[A], (A) -> B) -> Self[B] +#as_free_fn +pub fn[A, B] Parser::map_srcpos(Self[A], (SourcePos, A) -> B) -> Self[B] +#as_free_fn +pub fn Parser::none_of(String) -> Self[Char] +#as_free_fn +pub fn Parser::one_of(String) -> Self[Char] +#as_free_fn +pub fn[A] Parser::or(Self[A], Self[A]) -> Self[A] +#as_free_fn +pub fn[A] Parser::pure(A) -> Self[A] +#as_free_fn +pub fn[A] Parser::round_bracket(Self[A]) -> Self[A] +#as_free_fn +pub fn[A] Parser::run(Self[A], Input) -> A raise ParseError +#as_free_fn +pub fn Parser::satisfy((Char) -> Bool, label~ : String) -> Self[Char] +#as_free_fn +pub fn[A] Parser::square_bracket(Self[A]) -> Self[A] +#as_free_fn +pub fn Parser::string(String) -> Self[String] +pub impl[A] BitOr for Parser[A] + +pub(all) struct SourcePos { + row : Int + col : Int +} +pub impl Compare for SourcePos +pub impl Eq for SourcePos +pub impl Show for SourcePos + +// Type aliases + +// Traits + diff --git a/src/types.mbt b/src/types.mbt index 3c6d2c9..cb6801f 100644 --- a/src/types.mbt +++ b/src/types.mbt @@ -6,7 +6,7 @@ pub(all) struct SourcePos { ///| pub(all) struct Input { - chars : @string.View + chars : StringView row : Int col : Int } derive(Show) diff --git a/src/utils.mbt b/src/utils.mbt index baaae96..4d4ca71 100644 --- a/src/utils.mbt +++ b/src/utils.mbt @@ -1,54 +1,29 @@ ///| -pub fn Input::new(chars : @string.View) -> Input { +#as_free_fn +pub fn Input::new(chars : StringView) -> Input { Input::{ chars, row: 0, col: 0 } } ///| +#as_free_fn pub fn[A] Parser::run(self : Parser[A], input : Input) -> A raise ParseError { self(input).0 } ///| +#as_free_fn pub fn[A] Parser::discard_spaces(self : Parser[A]) -> Parser[A] { spaces.discard_left(self) } ///| -pub fnalias Parser::( - between, - bind, - char, - discard_left, - discard_right, - eof, - label, - map, - none_of, - one_of, - round_bracket, - square_bracket, - curly_bracket, - pure, - run, - satisfy, - string, - foldl, - foldr, - foldl1, - foldr1, - discard_spaces, - many, - many_each, - map_srcpos, - or -) - -///| +#as_free_fn pub fn[A] Parser::or(x : Parser[A], y : Parser[A]) -> Parser[A] { x | y } ///| +#as_free_fn pub fn ParseError::expect(row~ : Int, col~ : Int, msg : String) -> ParseError { ParseError({ row, col }, @list.List::singleton(msg)) } @@ -65,6 +40,3 @@ pub fn ParseError::cons(self : ParseError, x : String) -> ParseError { let ParseError(pos, xs) = self ParseError(pos, @list.List::cons(x, xs)) } - -///| -pub fnalias ParseError::expect