Merge pull request #3116 from rtfeldman/formatter-remove-space-between-square-braces

This commit is contained in:
Richard Feldman 2022-05-22 18:06:03 -04:00 committed by GitHub
commit 8fa80fa69b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
86 changed files with 343 additions and 300 deletions

View File

@ -1,6 +1,6 @@
app "formatted"
packages { pf: "platform" } imports []
provides [ main ] to pf
provides [main] to pf
main : Str
main = Dep1.value1 {}

View File

@ -1,6 +1,6 @@
app "formatted"
packages { pf: "platform" } imports []
provides [ main ] to pf
provides [main] to pf
main : Str
main = Dep1.value1 {}

View File

@ -1,8 +1,8 @@
interface Bool
exposes [ Bool, and, or, not, isEq, isNotEq ]
exposes [Bool, and, or, not, isEq, isNotEq]
imports []
Bool : [ True, False ]
Bool : [True, False]
## Returns `True` when given `True` and `True`, and `False` when either argument is `False`.
##

View File

@ -1,5 +1,5 @@
interface Box
exposes [ box, unbox ]
exposes [box, unbox]
imports []
box : a -> Box a

View File

@ -71,7 +71,7 @@ interface Dict
## An empty dictionary.
empty : Dict k v
single : k, v -> Dict k v
get : Dict k v, k -> Result v [ KeyNotFound ]*
get : Dict k v, k -> Result v [KeyNotFound]*
walk : Dict k v, state, (state, k, v -> state) -> state
insert : Dict k v, k, v -> Dict k v
len : Dict k v -> Nat

View File

@ -201,7 +201,7 @@ isEmpty : List a -> Bool
isEmpty = \list ->
List.len list == 0
get : List a, Nat -> Result a [ OutOfBounds ]*
get : List a, Nat -> Result a [OutOfBounds]*
replace : List a, Nat, a -> { list : List a, value : a }
## Replaces the element at the given index with a replacement.
@ -248,7 +248,7 @@ len : List a -> Nat
concat : List a, List a -> List a
## Returns the last element in the list, or `ListWasEmpty` if it was empty.
last : List a -> Result a [ ListWasEmpty ]*
last : List a -> Result a [ListWasEmpty]*
## A list with a single element in it.
##
@ -332,7 +332,7 @@ walkBackwards : List elem, state, (state, elem -> state) -> state
##
## As such, it is typically better for performance to use this over [List.walk]
## if returning `Done` earlier than the last element is expected to be common.
walkUntil : List elem, state, (state, elem -> [ Continue state, Stop state ]) -> state
walkUntil : List elem, state, (state, elem -> [Continue state, Stop state]) -> state
sum : List (Num a) -> Num a
sum = \list ->
@ -443,7 +443,7 @@ mapWithIndex : List a, (a, Nat -> b) -> List b
##
## >>> List.range 2 8
range : Int a, Int a -> List (Int a)
sortWith : List a, (a, a -> [ LT, EQ, GT ]) -> List a
sortWith : List a, (a, a -> [LT, EQ, GT]) -> List a
## Sorts a list in ascending order (lowest to highest), using a function which
## specifies a way to represent each element as a number.
@ -462,7 +462,7 @@ sortDesc = \list -> List.sortWith list (\a, b -> Num.compare b a)
swap : List a, Nat, Nat -> List a
## Returns the first element in the list, or `ListWasEmpty` if it was empty.
first : List a -> Result a [ ListWasEmpty ]*
first : List a -> Result a [ListWasEmpty]*
## Remove the first element from the list.
##
@ -539,7 +539,7 @@ drop : List elem, Nat -> List elem
## To replace the element at a given index, instead of dropping it, see [List.set].
dropAt : List elem, Nat -> List elem
min : List (Num a) -> Result (Num a) [ ListWasEmpty ]*
min : List (Num a) -> Result (Num a) [ListWasEmpty]*
min = \list ->
when List.first list is
Ok initial ->
@ -555,7 +555,7 @@ minHelp = \list, initial ->
else
bestSoFar
max : List (Num a) -> Result (Num a) [ ListWasEmpty ]*
max : List (Num a) -> Result (Num a) [ListWasEmpty]*
max = \list ->
when List.first list is
Ok initial ->
@ -581,7 +581,7 @@ joinMap = \list, mapper ->
## Returns the first element of the list satisfying a predicate function.
## If no satisfying element is found, an `Err NotFound` is returned.
find : List elem, (elem -> Bool) -> Result elem [ NotFound ]*
find : List elem, (elem -> Bool) -> Result elem [NotFound]*
## Returns a subsection of the given list, beginning at the `start` index and
## including a total of `len` elements.

View File

@ -510,10 +510,10 @@ Dec : Num (FloatingPoint Decimal)
toStr : Num * -> Str
intCast : Int a -> Int b
bytesToU16 : List U8, Nat -> Result U16 [ OutOfBounds ]
bytesToU32 : List U8, Nat -> Result U32 [ OutOfBounds ]
bytesToU16 : List U8, Nat -> Result U16 [OutOfBounds]
bytesToU32 : List U8, Nat -> Result U32 [OutOfBounds]
compare : Num a, Num a -> [ LT, EQ, GT ]
compare : Num a, Num a -> [LT, EQ, GT]
## Returns `True` if the first number is less than the second.
##
@ -714,9 +714,9 @@ atan : Frac a -> Frac a
##
## >>> Num.sqrt -4.0f64
sqrt : Frac a -> Frac a
sqrtChecked : Frac a -> Result (Frac a) [ SqrtOfNegative ]*
sqrtChecked : Frac a -> Result (Frac a) [SqrtOfNegative]*
log : Frac a -> Frac a
logChecked : Frac a -> Result (Frac a) [ LogNeedsPositive ]*
logChecked : Frac a -> Result (Frac a) [LogNeedsPositive]*
## Divide one [Frac] by another.
##
@ -749,9 +749,9 @@ logChecked : Frac a -> Result (Frac a) [ LogNeedsPositive ]*
## >>> Num.pi
## >>> |> Num.div 2.0
div : Frac a, Frac a -> Frac a
divChecked : Frac a, Frac a -> Result (Frac a) [ DivByZero ]*
divChecked : Frac a, Frac a -> Result (Frac a) [DivByZero]*
divCeil : Int a, Int a -> Int a
divCeilChecked : Int a, Int a -> Result (Int a) [ DivByZero ]*
divCeilChecked : Int a, Int a -> Result (Int a) [DivByZero]*
## Divide two integers, truncating the result towards zero.
##
@ -770,7 +770,7 @@ divCeilChecked : Int a, Int a -> Result (Int a) [ DivByZero ]*
## >>> Num.divTrunc 8 -3
##
divTrunc : Int a, Int a -> Int a
divTruncChecked : Int a, Int a -> Result (Int a) [ DivByZero ]*
divTruncChecked : Int a, Int a -> Result (Int a) [DivByZero]*
## Obtain the remainder (truncating modulo) from the division of two integers.
##
@ -784,7 +784,7 @@ divTruncChecked : Int a, Int a -> Result (Int a) [ DivByZero ]*
##
## >>> Num.rem -8 -3
rem : Int a, Int a -> Int a
remChecked : Int a, Int a -> Result (Int a) [ DivByZero ]*
remChecked : Int a, Int a -> Result (Int a) [DivByZero]*
isMultipleOf : Int a, Int a -> Bool
@ -842,7 +842,7 @@ addSaturated : Num a, Num a -> Num a
##
## This is the same as [Num.add] except if the operation overflows, instead of
## panicking or returning ∞ or -∞, it will return `Err Overflow`.
addChecked : Num a, Num a -> Result (Num a) [ Overflow ]*
addChecked : Num a, Num a -> Result (Num a) [Overflow]*
subWrap : Int range, Int range -> Int range
@ -859,7 +859,7 @@ subSaturated : Num a, Num a -> Num a
##
## This is the same as [Num.sub] except if the operation overflows, instead of
## panicking or returning ∞ or -∞, it will return `Err Overflow`.
subChecked : Num a, Num a -> Result (Num a) [ Overflow ]*
subChecked : Num a, Num a -> Result (Num a) [Overflow]*
mulWrap : Int range, Int range -> Int range
# mulSaturated : Num a, Num a -> Num a
@ -867,7 +867,7 @@ mulWrap : Int range, Int range -> Int range
##
## This is the same as [Num.mul] except if the operation overflows, instead of
## panicking or returning ∞ or -∞, it will return `Err Overflow`.
mulChecked : Num a, Num a -> Result (Num a) [ Overflow ]*
mulChecked : Num a, Num a -> Result (Num a) [Overflow]*
## The lowest number that can be stored in an [I8] without underflowing its
## available memory and crashing.
@ -1114,19 +1114,19 @@ toF64 : Num * -> F64
## Converts a [Int] to an [I8].
## If the given integer can't be precisely represented in an [I8], returns
## `Err OutOfBounds`.
toI8Checked : Int * -> Result I8 [ OutOfBounds ]*
toI16Checked : Int * -> Result I16 [ OutOfBounds ]*
toI32Checked : Int * -> Result I32 [ OutOfBounds ]*
toI64Checked : Int * -> Result I64 [ OutOfBounds ]*
toI128Checked : Int * -> Result I128 [ OutOfBounds ]*
toU8Checked : Int * -> Result U8 [ OutOfBounds ]*
toU16Checked : Int * -> Result U16 [ OutOfBounds ]*
toU32Checked : Int * -> Result U32 [ OutOfBounds ]*
toU64Checked : Int * -> Result U64 [ OutOfBounds ]*
toU128Checked : Int * -> Result U128 [ OutOfBounds ]*
toNatChecked : Int * -> Result Nat [ OutOfBounds ]*
toF32Checked : Num * -> Result F32 [ OutOfBounds ]*
toF64Checked : Num * -> Result F64 [ OutOfBounds ]*
toI8Checked : Int * -> Result I8 [OutOfBounds]*
toI16Checked : Int * -> Result I16 [OutOfBounds]*
toI32Checked : Int * -> Result I32 [OutOfBounds]*
toI64Checked : Int * -> Result I64 [OutOfBounds]*
toI128Checked : Int * -> Result I128 [OutOfBounds]*
toU8Checked : Int * -> Result U8 [OutOfBounds]*
toU16Checked : Int * -> Result U16 [OutOfBounds]*
toU32Checked : Int * -> Result U32 [OutOfBounds]*
toU64Checked : Int * -> Result U64 [OutOfBounds]*
toU128Checked : Int * -> Result U128 [OutOfBounds]*
toNatChecked : Int * -> Result Nat [OutOfBounds]*
toF32Checked : Num * -> Result F32 [OutOfBounds]*
toF64Checked : Num * -> Result F64 [OutOfBounds]*
# Special Floating-Point operations
## When given a [F64] or [F32] value, returns `False` if that value is

View File

@ -1,10 +1,10 @@
interface Result
exposes [ Result, isOk, isErr, map, mapErr, after, withDefault ]
imports [ Bool.{ Bool } ]
exposes [Result, isOk, isErr, map, mapErr, after, withDefault]
imports [Bool.{ Bool }]
## The result of an operation that could fail: either the operation went
## okay, or else there was an error of some sort.
Result ok err : [ Ok ok, Err err ]
Result ok err : [Ok ok, Err err]
## Return True if the result indicates a success, else return False
##

View File

@ -14,7 +14,7 @@ interface Set
intersection,
difference,
]
imports [ List, Bool.{ Bool }, Dict.{ values } ]
imports [List, Bool.{ Bool }, Dict.{ values }]
## An empty set.
empty : Set k

View File

@ -33,7 +33,7 @@ interface Str
toU8,
toI8,
]
imports [ Bool.{ Bool }, Result.{ Result } ]
imports [Bool.{ Bool }, Result.{ Result }]
## # Types
##
@ -187,8 +187,8 @@ toUtf8 : Str -> List U8
# fromUtf8 : List U8 -> Result Str [ BadUtf8 Utf8Problem ]*
# fromUtf8Range : List U8 -> Result Str [ BadUtf8 Utf8Problem Nat, OutOfBounds ]*
fromUtf8 : List U8 -> Result Str [ BadUtf8 Utf8ByteProblem Nat ]*
fromUtf8Range : List U8, { start : Nat, count : Nat } -> Result Str [ BadUtf8 Utf8ByteProblem Nat, OutOfBounds ]*
fromUtf8 : List U8 -> Result Str [BadUtf8 Utf8ByteProblem Nat]*
fromUtf8Range : List U8, { start : Nat, count : Nat } -> Result Str [BadUtf8 Utf8ByteProblem Nat, OutOfBounds]*
startsWith : Str, Str -> Bool
endsWith : Str, Str -> Bool
@ -199,17 +199,17 @@ trim : Str -> Str
trimLeft : Str -> Str
trimRight : Str -> Str
toDec : Str -> Result Dec [ InvalidNumStr ]*
toF64 : Str -> Result F64 [ InvalidNumStr ]*
toF32 : Str -> Result F32 [ InvalidNumStr ]*
toNat : Str -> Result Nat [ InvalidNumStr ]*
toU128 : Str -> Result U128 [ InvalidNumStr ]*
toI128 : Str -> Result I128 [ InvalidNumStr ]*
toU64 : Str -> Result U64 [ InvalidNumStr ]*
toI64 : Str -> Result I64 [ InvalidNumStr ]*
toU32 : Str -> Result U32 [ InvalidNumStr ]*
toI32 : Str -> Result I32 [ InvalidNumStr ]*
toU16 : Str -> Result U16 [ InvalidNumStr ]*
toI16 : Str -> Result I16 [ InvalidNumStr ]*
toU8 : Str -> Result U8 [ InvalidNumStr ]*
toI8 : Str -> Result I8 [ InvalidNumStr ]*
toDec : Str -> Result Dec [InvalidNumStr]*
toF64 : Str -> Result F64 [InvalidNumStr]*
toF32 : Str -> Result F32 [InvalidNumStr]*
toNat : Str -> Result Nat [InvalidNumStr]*
toU128 : Str -> Result U128 [InvalidNumStr]*
toI128 : Str -> Result I128 [InvalidNumStr]*
toU64 : Str -> Result U64 [InvalidNumStr]*
toI64 : Str -> Result I64 [InvalidNumStr]*
toU32 : Str -> Result U32 [InvalidNumStr]*
toI32 : Str -> Result I32 [InvalidNumStr]*
toU16 : Str -> Result U16 [InvalidNumStr]*
toI16 : Str -> Result I16 [InvalidNumStr]*
toU8 : Str -> Result U8 [InvalidNumStr]*
toI8 : Str -> Result I8 [InvalidNumStr]*

View File

@ -1,5 +1,5 @@
use crate::{
collection::fmt_collection,
collection::{fmt_collection, Braces},
spaces::{fmt_comments_only, fmt_spaces, NewlineAt, INDENT},
Buf,
};
@ -295,7 +295,7 @@ impl<'a> Formattable for TypeAnnotation<'a> {
Inferred => buf.push('_'),
TagUnion { tags, ext } => {
fmt_collection(buf, indent, '[', ']', *tags, newlines);
fmt_collection(buf, indent, Braces::Square, *tags, newlines);
if let Some(loc_ext_ann) = *ext {
loc_ext_ann.value.format(buf, indent);
@ -303,7 +303,7 @@ impl<'a> Formattable for TypeAnnotation<'a> {
}
Record { fields, ext } => {
fmt_collection(buf, indent, '{', '}', *fields, newlines);
fmt_collection(buf, indent, Braces::Curly, *fields, newlines);
if let Some(loc_ext_ann) = *ext {
loc_ext_ann.value.format(buf, indent);
@ -584,7 +584,7 @@ impl<'a> Formattable for Derived<'a> {
}
buf.push_str("has");
buf.spaces(1);
fmt_collection(buf, indent, '[', ']', *derived, newlines);
fmt_collection(buf, indent, Braces::Square, *derived, newlines);
}
Derived::SpaceBefore(derived, spaces) => {
buf.newline();

View File

@ -6,16 +6,31 @@ use crate::{
Buf,
};
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub enum Braces {
Square,
Curly,
}
pub fn fmt_collection<'a, 'buf, T: ExtractSpaces<'a> + Formattable>(
buf: &mut Buf<'buf>,
indent: u16,
start: char,
end: char,
braces: Braces,
items: Collection<'a, T>,
newline: Newlines,
) where
<T as ExtractSpaces<'a>>::Item: Formattable,
{
let start = match braces {
Braces::Curly => '{',
Braces::Square => '[',
};
let end = match braces {
Braces::Curly => '}',
Braces::Square => ']',
};
if items.is_multiline() {
let braces_indent = indent;
let item_indent = braces_indent + INDENT;
@ -74,16 +89,19 @@ pub fn fmt_collection<'a, 'buf, T: ExtractSpaces<'a> + Formattable>(
// there is no comment to add
buf.indent(indent);
buf.push(start);
let mut iter = items.iter().peekable();
while let Some(item) = iter.next() {
buf.spaces(1);
let mut iter = items.iter().enumerate().peekable();
while let Some((index, item)) = iter.next() {
if braces == Braces::Curly || index != 0 {
buf.spaces(1);
}
item.format(buf, indent);
if iter.peek().is_some() {
buf.push(',');
}
}
if !items.is_empty() {
if !items.is_empty() && braces == Braces::Curly {
buf.spaces(1);
}
}

View File

@ -1,5 +1,5 @@
use crate::annotation::{Formattable, Newlines, Parens};
use crate::collection::fmt_collection;
use crate::collection::{fmt_collection, Braces};
use crate::def::fmt_def;
use crate::pattern::fmt_pattern;
use crate::spaces::{count_leading_newlines, fmt_comments_only, fmt_spaces, NewlineAt, INDENT};
@ -353,7 +353,7 @@ impl<'a> Formattable for Expr<'a> {
fmt_if(buf, branches, final_else, self.is_multiline(), indent);
}
When(loc_condition, branches) => fmt_when(buf, loc_condition, branches, indent),
List(items) => fmt_collection(buf, indent, '[', ']', *items, Newlines::No),
List(items) => fmt_collection(buf, indent, Braces::Square, *items, Newlines::No),
BinOps(lefts, right) => fmt_bin_ops(buf, lefts, right, false, parens, indent),
UnaryOp(sub_expr, unary_op) => {
buf.indent(indent);

View File

@ -1,5 +1,5 @@
use crate::annotation::{Formattable, Newlines};
use crate::collection::fmt_collection;
use crate::collection::{fmt_collection, Braces};
use crate::expr::fmt_str_literal;
use crate::spaces::{fmt_default_spaces, fmt_spaces, INDENT};
use crate::Buf;
@ -173,7 +173,7 @@ pub fn fmt_platform_header<'a, 'buf>(buf: &mut Buf<'buf>, header: &'a PlatformHe
}
fn fmt_requires<'a, 'buf>(buf: &mut Buf<'buf>, requires: &PlatformRequires<'a>, indent: u16) {
fmt_collection(buf, indent, '{', '}', requires.rigids, Newlines::No);
fmt_collection(buf, indent, Braces::Curly, requires.rigids, Newlines::No);
buf.push_str(" {");
buf.spaces(1);
@ -242,7 +242,13 @@ fn fmt_imports<'a, 'buf>(
loc_entries: Collection<'a, Loc<Spaced<'a, ImportsEntry<'a>>>>,
indent: u16,
) {
fmt_collection(buf, indent + INDENT, '[', ']', loc_entries, Newlines::No)
fmt_collection(
buf,
indent + INDENT,
Braces::Square,
loc_entries,
Newlines::No,
)
}
fn fmt_provides<'a, 'buf>(
@ -251,10 +257,16 @@ fn fmt_provides<'a, 'buf>(
loc_provided_types: Option<Collection<'a, Loc<Spaced<'a, UppercaseIdent<'a>>>>>,
indent: u16,
) {
fmt_collection(buf, indent, '[', ']', loc_exposed_names, Newlines::No);
fmt_collection(buf, indent, Braces::Square, loc_exposed_names, Newlines::No);
if let Some(loc_provided) = loc_provided_types {
fmt_default_spaces(buf, &[], indent);
fmt_collection(buf, indent + INDENT, '{', '}', loc_provided, Newlines::No);
fmt_collection(
buf,
indent + INDENT,
Braces::Curly,
loc_provided,
Newlines::No,
);
}
}
@ -272,7 +284,13 @@ fn fmt_exposes<'buf, N: Formattable + Copy>(
loc_entries: Collection<'_, Loc<Spaced<'_, N>>>,
indent: u16,
) {
fmt_collection(buf, indent + INDENT, '[', ']', loc_entries, Newlines::No)
fmt_collection(
buf,
indent + INDENT,
Braces::Square,
loc_entries,
Newlines::No,
)
}
pub trait FormatName {
@ -323,7 +341,7 @@ fn fmt_packages<'a, 'buf>(
loc_entries: Collection<'a, Loc<Spaced<'a, PackageEntry<'a>>>>,
indent: u16,
) {
fmt_collection(buf, indent, '{', '}', loc_entries, Newlines::No)
fmt_collection(buf, indent, Braces::Curly, loc_entries, Newlines::No)
}
impl<'a> Formattable for PackageEntry<'a> {
@ -364,7 +382,13 @@ fn fmt_imports_entry<'a, 'buf>(buf: &mut Buf<'buf>, entry: &ImportsEntry<'a>, in
if !loc_exposes_entries.is_empty() {
buf.push('.');
fmt_collection(buf, indent, '{', '}', *loc_exposes_entries, Newlines::No)
fmt_collection(
buf,
indent,
Braces::Curly,
*loc_exposes_entries,
Newlines::No,
)
}
}
@ -376,7 +400,7 @@ fn fmt_imports_entry<'a, 'buf>(buf: &mut Buf<'buf>, entry: &ImportsEntry<'a>, in
if !entries.is_empty() {
buf.push('.');
fmt_collection(buf, indent, '{', '}', *entries, Newlines::No)
fmt_collection(buf, indent, Braces::Curly, *entries, Newlines::No)
}
}
}

View File

@ -1528,7 +1528,7 @@ mod test_fmt {
expr_formats_same(indoc!(
r#"
func = \_ ->
[ 1, 2, 3 ]
[1, 2, 3]
func
"#
@ -1603,7 +1603,7 @@ mod test_fmt {
r#"
result = func
arg
[ 1, 2, 3 ]
[1, 2, 3]
result
"#
@ -2192,7 +2192,7 @@ mod test_fmt {
expr_formats_same(indoc!(
r#"
x :
[ Int ]
[Int]
x
"#
@ -2455,13 +2455,14 @@ mod test_fmt {
#[test]
fn one_item_list() {
expr_formats_same(indoc!("[ 4 ] "));
expr_formats_same(indoc!("[4]"));
expr_formats_to(indoc!("[ 4 ]"), indoc!("[4]"));
}
#[test]
fn two_item_list() {
expr_formats_same(indoc!("[ 7, 8 ] "));
expr_formats_to(indoc!("[ 7 , 8 ] "), indoc!("[ 7, 8 ] "));
expr_formats_same(indoc!("[7, 8]"));
expr_formats_to(indoc!("[ 7 , 8 ]"), indoc!("[7, 8]"));
}
#[test]
@ -2688,7 +2689,7 @@ mod test_fmt {
expr_formats_same(indoc!(
r#"
l =
[ 1, 2 ]
[1, 2]
l
"#
@ -4167,7 +4168,7 @@ mod test_fmt {
fn func_call_trailing_multiline_lambda() {
expr_formats_same(indoc!(
r#"
list = List.map [ 1, 2, 3 ] \x ->
list = List.map [1, 2, 3] \x ->
x + 1
list
@ -4218,7 +4219,7 @@ mod test_fmt {
module_formats_same(indoc!(
r#"
interface Foo
exposes [ Bar, Baz, a, b ]
exposes [Bar, Baz, a, b]
imports []"#
));
}
@ -4228,8 +4229,8 @@ mod test_fmt {
module_formats_same(indoc!(
r#"
interface Foo
exposes [ Bar, Baz, a, b ]
imports [ Blah, Thing.{ foo, bar }, Stuff ]"#
exposes [Bar, Baz, a, b]
imports [Blah, Thing.{ foo, bar }, Stuff]"#
));
}
@ -4256,7 +4257,7 @@ mod test_fmt {
fn single_line_app() {
module_formats_same(indoc!(
r#"
app "Foo" packages { pf: "platform" } imports [] provides [ main ] to pf"#
app "Foo" packages { pf: "platform" } imports [] provides [main] to pf"#
));
}
@ -4267,8 +4268,8 @@ mod test_fmt {
requires { Model, Msg } { main : Effect {} } \
exposes [] \
packages {} \
imports [ Task.{ Task } ] \
provides [ mainForHost ]",
imports [Task.{ Task }] \
provides [mainForHost]",
);
}
@ -4296,7 +4297,7 @@ mod test_fmt {
exposes []
packages {}
imports []
provides [ mainForHost ]
provides [mainForHost]
mainForHost : { init : ({} -> Model) as Init, update : (Model, Str -> Model) as Update, view : (Model -> Str) as View }
mainForHost = main
@ -4344,7 +4345,7 @@ mod test_fmt {
fn list_alias() {
expr_formats_same(indoc!(
r#"
ConsList a : [ Cons a (ConsList a), Nil ]
ConsList a : [Cons a (ConsList a), Nil]
f : ConsList a -> ConsList a
f = \_ -> Nil
@ -4394,7 +4395,7 @@ mod test_fmt {
expr_formats_same(indoc!(
r#"
b :
[ True, False ]
[True, False]
b
"#
@ -4500,7 +4501,7 @@ mod test_fmt {
fn tag_union() {
expr_formats_same(indoc!(
r#"
f : [ True, False ] -> [ True, False ]
f : [True, False] -> [True, False]
f = \x -> x
a
@ -4534,7 +4535,7 @@ mod test_fmt {
fn recursive_tag_union() {
expr_formats_same(indoc!(
r#"
f : [ Cons a (ConsList a), Nil ] as ConsList a -> [ Just a, Nothing ]
f : [Cons a (ConsList a), Nil] as ConsList a -> [Just a, Nothing]
f = \list ->
when list is
Nil ->
@ -4763,7 +4764,7 @@ mod test_fmt {
fn opaque_has_clause() {
expr_formats_same(indoc!(
r#"
A := U8 has [ Eq, Hash ]
A := U8 has [Eq, Hash]
0
"#
@ -4773,7 +4774,7 @@ mod test_fmt {
r#"
A :=
U8
has [ Eq, Hash ]
has [Eq, Hash]
0
"#
@ -4791,7 +4792,7 @@ mod test_fmt {
r#"
A :=
a | a has Hash
has [ Eq, Hash ]
has [Eq, Hash]
0
"#

View File

@ -3,7 +3,7 @@ platform "fibonacci"
exposes []
packages {}
imports []
provides [ mainForHost ]
provides [mainForHost]
mainForHost : I64 -> I64
mainForHost = \a -> main a

View File

@ -1,7 +1,7 @@
app "fibonacci"
packages { pf: "fibonacci-platform" }
imports []
provides [ main ] to pf
provides [main] to pf
main = \n -> fib n 0 1

View File

@ -3,7 +3,7 @@ platform "quicksort"
exposes []
packages {}
imports []
provides [ mainForHost ]
provides [mainForHost]
mainForHost : List I64 -> List I64
mainForHost = \list -> quicksort list

View File

@ -1,7 +1,7 @@
app "quicksort"
packages { pf: "quicksort-platform" }
imports []
provides [ quicksort ] to pf
provides [quicksort] to pf
quicksort = \originalList ->
n = List.len originalList
@ -19,7 +19,7 @@ quicksortHelp = \list, low, high ->
else
list
partition : Nat, Nat, List (Num a) -> [ Pair Nat (List (Num a)) ]
partition : Nat, Nat, List (Num a) -> [Pair Nat (List (Num a))]
partition = \low, high, initialList ->
when List.get initialList high is
Ok pivot ->
@ -29,7 +29,7 @@ partition = \low, high, initialList ->
Err _ ->
Pair low initialList
partitionHelp : Nat, Nat, List (Num c), Nat, Num c -> [ Pair Nat (List (Num c)) ]
partitionHelp : Nat, Nat, List (Num c), Nat, Num c -> [Pair Nat (List (Num c))]
partitionHelp = \i, j, list, high, pivot ->
if j < high then
when List.get list j is

View File

@ -1,4 +1,4 @@
interface AStar exposes [ findPath, Model, initialModel, cheapestOpen, reconstructPath ] imports [ Quicksort ]
interface AStar exposes [findPath, Model, initialModel, cheapestOpen, reconstructPath] imports [Quicksort]
findPath = \costFn, moveFn, start, end ->
astar costFn moveFn end (initialModel start)

View File

@ -1,7 +1,7 @@
interface Base64 exposes [ fromBytes, fromStr, toBytes, toStr ] imports [ Base64.Decode, Base64.Encode ]
interface Base64 exposes [fromBytes, fromStr, toBytes, toStr] imports [Base64.Decode, Base64.Encode]
# base 64 encoding from a sequence of bytes
fromBytes : List U8 -> Result Str [ InvalidInput ]*
fromBytes : List U8 -> Result Str [InvalidInput]*
fromBytes = \bytes ->
when Base64.Decode.fromBytes bytes is
Ok v ->
@ -10,16 +10,16 @@ fromBytes = \bytes ->
Err InvalidInput
# base 64 encoding from a string
fromStr : Str -> Result Str [ InvalidInput ]*
fromStr : Str -> Result Str [InvalidInput]*
fromStr = \str ->
fromBytes (Str.toUtf8 str)
# base64-encode bytes to the original
toBytes : Str -> Result (List U8) [ InvalidInput ]*
toBytes : Str -> Result (List U8) [InvalidInput]*
toBytes = \str ->
Ok (Base64.Encode.toBytes str)
toStr : Str -> Result Str [ InvalidInput ]*
toStr : Str -> Result Str [InvalidInput]*
toStr = \str ->
when toBytes str is
Ok bytes ->

View File

@ -1,4 +1,4 @@
interface Base64.Decode exposes [ fromBytes ] imports [ Bytes.Decode.{ Decoder, DecodeProblem } ]
interface Base64.Decode exposes [fromBytes] imports [Bytes.Decode.{ Decoder, DecodeProblem }]
fromBytes : List U8 -> Result Str DecodeProblem
fromBytes = \bytes ->
@ -88,11 +88,11 @@ bitsToCharsHelp = \bits, missing ->
when missing is
0 ->
[ p, q, r, s ]
[p, q, r, s]
1 ->
[ p, q, r, equals ]
[p, q, r, equals]
2 ->
[ p, q, equals, equals ]
[p, q, equals, equals]
_ ->
# unreachable
[]

View File

@ -1,6 +1,6 @@
interface Base64.Encode
exposes [ toBytes ]
imports [ Bytes.Encode.{ Encoder } ]
exposes [toBytes]
imports [Bytes.Encode.{ Encoder }]
InvalidChar : U8
@ -133,7 +133,7 @@ encodeCharacters = \a, b, c, d ->
combined : U16
combined = Num.intCast (Num.shiftRightBy 8 n)
Ok (Bytes.Encode.sequence [ Bytes.Encode.u16 BE combined, Bytes.Encode.u8 b3 ])
Ok (Bytes.Encode.sequence [Bytes.Encode.u16 BE combined, Bytes.Encode.u8 b3])
# is the character a base64 digit?
# The base16 digits are: A-Z, a-z, 0-1, '+' and '/'

View File

@ -1,10 +1,10 @@
interface Bytes.Decode exposes [ Decoder, decode, map, map2, u8, loop, Step, succeed, DecodeProblem, after, map3 ] imports []
interface Bytes.Decode exposes [Decoder, decode, map, map2, u8, loop, Step, succeed, DecodeProblem, after, map3] imports []
State : { bytes : List U8, cursor : Nat }
DecodeProblem : [ OutOfBytes ]
DecodeProblem : [OutOfBytes]
Decoder a := State -> [ Good State a, Bad DecodeProblem ]
Decoder a := State -> [Good State a, Bad DecodeProblem]
decode : List U8, Decoder a -> Result a DecodeProblem
decode = \bytes, @Decoder decoder ->
@ -80,7 +80,7 @@ u8 = @Decoder
Err _ ->
Bad OutOfBytes
Step state b : [ Loop state, Done b ]
Step state b : [Loop state, Done b]
loop : (state -> Decoder (Step state a)), state -> Decoder a
loop = \stepper, initial ->

View File

@ -1,8 +1,8 @@
interface Bytes.Encode exposes [ Encoder, sequence, u8, u16, bytes, empty, encode ] imports []
interface Bytes.Encode exposes [Encoder, sequence, u8, u16, bytes, empty, encode] imports []
Endianness : [ BE, LE ]
Endianness : [BE, LE]
Encoder : [ Signed8 I8, Unsigned8 U8, Signed16 Endianness I16, Unsigned16 Endianness U16, Sequence Nat (List Encoder), Bytes (List U8) ]
Encoder : [Signed8 I8, Unsigned8 U8, Signed16 Endianness I16, Unsigned16 Endianness U16, Sequence Nat (List Encoder), Bytes (List U8)]
u8 : U8 -> Encoder
u8 = \value -> Unsigned8 value

View File

@ -1,7 +1,7 @@
app "cfold"
packages { pf: "platform" }
imports [ pf.Task ]
provides [ main ] to pf
imports [pf.Task]
provides [main] to pf
# adapted from https://github.com/koka-lang/koka/blob/master/test/bench/haskell/cfold.hs
main : Task.Task {} []

View File

@ -1,7 +1,7 @@
app "closure"
packages { pf: "platform" }
imports [ pf.Task ]
provides [ main ] to pf
imports [pf.Task]
provides [main] to pf
# see https://github.com/rtfeldman/roc/issues/985
main : Task.Task {} []

View File

@ -1,7 +1,7 @@
app "deriv"
packages { pf: "platform" }
imports [ pf.Task ]
provides [ main ] to pf
imports [pf.Task]
provides [main] to pf
# based on: https://github.com/koka-lang/koka/blob/master/test/bench/haskell/deriv.hs
IO a : Task.Task a []
@ -26,7 +26,7 @@ nest = \f, n, e -> Task.loop { s: n, f, m: n, x: e } nestHelp
State : { s : I64, f : I64, Expr -> IO Expr, m : I64, x : Expr }
nestHelp : State -> IO [ Step State, Done Expr ]
nestHelp : State -> IO [Step State, Done Expr]
nestHelp = \{ s, f, m, x } ->
when m is
0 ->
@ -36,9 +36,9 @@ nestHelp = \{ s, f, m, x } ->
Task.succeed (Step { s, f, m: (m - 1), x: w })
Expr : [ Val I64, Var Str, Add Expr Expr, Mul Expr Expr, Pow Expr Expr, Ln Expr ]
Expr : [Val I64, Var Str, Add Expr Expr, Mul Expr Expr, Pow Expr Expr, Ln Expr]
divmod : I64, I64 -> Result { div : I64, mod : I64 } [ DivByZero ]*
divmod : I64, I64 -> Result { div : I64, mod : I64 } [DivByZero]*
divmod = \l, r ->
when Pair (Num.divTruncChecked l r) (Num.remChecked l r) is
Pair (Ok div) (Ok mod) ->

View File

@ -1,7 +1,7 @@
app "issue2279"
packages { pf: "platform" }
imports [ Issue2279Help, pf.Task ]
provides [ main ] to pf
imports [Issue2279Help, pf.Task]
provides [main] to pf
main =
text =

View File

@ -1,5 +1,5 @@
interface Issue2279Help
exposes [ text, asText ]
exposes [text, asText]
imports []
text = "Hello, world!"

View File

@ -1,7 +1,7 @@
app "nqueens"
packages { pf: "platform" }
imports [ pf.Task ]
provides [ main ] to pf
imports [pf.Task]
provides [main] to pf
main : Task.Task {} []
main =
@ -13,7 +13,7 @@ main =
|> Num.toStr
|> Task.putLine
ConsList a : [ Nil, Cons a (ConsList a) ]
ConsList a : [Nil, Cons a (ConsList a)]
queens = \n -> length (findSolutions n n)

View File

@ -1,4 +1,4 @@
interface Quicksort exposes [ sortBy, sortWith, show ] imports []
interface Quicksort exposes [sortBy, sortWith, show] imports []
show : List I64 -> Str
show = \list ->
@ -16,9 +16,9 @@ sortBy : List a, (a -> Num *) -> List a
sortBy = \list, toComparable ->
sortWith list (\x, y -> Num.compare (toComparable x) (toComparable y))
Order a : a, a -> [ LT, GT, EQ ]
Order a : a, a -> [LT, GT, EQ]
sortWith : List a, (a, a -> [ LT, GT, EQ ]) -> List a
sortWith : List a, (a, a -> [LT, GT, EQ]) -> List a
sortWith = \list, order ->
n = List.len list
@ -35,7 +35,7 @@ quicksortHelp = \list, order, low, high ->
else
list
partition : Nat, Nat, List a, Order a -> [ Pair Nat (List a) ]
partition : Nat, Nat, List a, Order a -> [Pair Nat (List a)]
partition = \low, high, initialList, order ->
when List.get initialList high is
Ok pivot ->
@ -45,7 +45,7 @@ partition = \low, high, initialList, order ->
Err _ ->
Pair low initialList
partitionHelp : Nat, Nat, List c, Order c, Nat, c -> [ Pair Nat (List c) ]
partitionHelp : Nat, Nat, List c, Order c, Nat, c -> [Pair Nat (List c)]
partitionHelp = \i, j, list, order, high, pivot ->
if j < high then
when List.get list j is

File diff suppressed because one or more lines are too long

View File

@ -1,15 +1,15 @@
app "rbtree-ck"
packages { pf: "platform" }
imports [ pf.Task ]
provides [ main ] to pf
imports [pf.Task]
provides [main] to pf
Color : [ Red, Black ]
Color : [Red, Black]
Tree a b : [ Leaf, Node Color (Tree a b) a b (Tree a b) ]
Tree a b : [Leaf, Node Color (Tree a b) a b (Tree a b)]
Map : Tree I64 Bool
ConsList a : [ Nil, Cons a (ConsList a) ]
ConsList a : [Nil, Cons a (ConsList a)]
makeMap : I64, I64 -> ConsList Map
makeMap = \freq, n ->

View File

@ -1,15 +1,15 @@
app "rbtree-del"
packages { pf: "platform" }
imports [ pf.Task ]
provides [ main ] to pf
imports [pf.Task]
provides [main] to pf
Color : [ Red, Black ]
Color : [Red, Black]
Tree a b : [ Leaf, Node Color (Tree a b) a b (Tree a b) ]
Tree a b : [Leaf, Node Color (Tree a b) a b (Tree a b)]
Map : Tree I64 Bool
ConsList a : [ Nil, Cons a (ConsList a) ]
ConsList a : [Nil, Cons a (ConsList a)]
main : Task.Task {} []
main =
@ -156,7 +156,7 @@ isBlack = \c ->
Red ->
False
Del a b : [ Del (Tree a b) Bool ]
Del a b : [Del (Tree a b) Bool]
setRed : Map -> Map
setRed = \t ->

View File

@ -1,7 +1,7 @@
app "rbtree-insert"
packages { pf: "platform" }
imports [ pf.Task ]
provides [ main ] to pf
imports [pf.Task]
provides [main] to pf
main : Task.Task {} []
main =
@ -47,9 +47,9 @@ showColor = \color ->
Black ->
"Black"
NodeColor : [ Red, Black ]
NodeColor : [Red, Black]
RedBlackTree k v : [ Node NodeColor k v (RedBlackTree k v) (RedBlackTree k v), Empty ]
RedBlackTree k v : [Node NodeColor k v (RedBlackTree k v) (RedBlackTree k v), Empty]
Key k : Num k

View File

@ -1,7 +1,7 @@
app "test-astar"
packages { pf: "platform" }
imports [ pf.Task, AStar ]
provides [ main ] to pf
imports [pf.Task, AStar]
provides [main] to pf
main : Task.Task {} []
main =
@ -25,7 +25,7 @@ showBool = \b ->
test1 : Bool
test1 =
example1 == [ 2, 4 ]
example1 == [2, 4]
example1 : List I64
example1 =
@ -33,11 +33,11 @@ example1 =
step = \n ->
when n is
1 ->
Set.fromList [ 2, 3 ]
Set.fromList [2, 3]
2 ->
Set.fromList [ 4 ]
Set.fromList [4]
3 ->
Set.fromList [ 4 ]
Set.fromList [4]
_ ->
Set.fromList []

View File

@ -1,7 +1,7 @@
app "test-base64"
packages { pf: "platform" }
imports [ pf.Task, Base64 ]
provides [ main ] to pf
imports [pf.Task, Base64]
provides [main] to pf
IO a : Task.Task a []

View File

@ -1,7 +1,7 @@
hosted Effect
exposes [ Effect, after, map, always, forever, loop, putLine, putInt, getInt ]
exposes [Effect, after, map, always, forever, loop, putLine, putInt, getInt]
imports []
generates Effect with [ after, map, always, forever, loop ]
generates Effect with [after, map, always, forever, loop]
putLine : Str -> Effect {}

View File

@ -2,8 +2,8 @@ platform "benchmarks"
requires {} { main : Task {} [] }
exposes []
packages {}
imports [ Task.{ Task } ]
provides [ mainForHost ]
imports [Task.{ Task }]
provides [mainForHost]
mainForHost : Task {} [] as Fx
mainForHost = main

View File

@ -1,6 +1,6 @@
interface Task
exposes [ Task, succeed, fail, after, map, putLine, putInt, getInt, forever, loop ]
imports [ pf.Effect ]
exposes [Task, succeed, fail, after, map, putLine, putInt, getInt, forever, loop]
imports [pf.Effect]
Task ok err : Effect.Effect (Result ok err)
@ -18,7 +18,7 @@ forever = \task ->
Effect.loop {} looper
loop : state, (state -> Task [ Step state, Done done ] err) -> Task done err
loop : state, (state -> Task [Step state, Done done] err) -> Task done err
loop = \state, step ->
looper = \current ->
step current

View File

@ -1,7 +1,7 @@
app "breakout"
packages { pf: "platform" }
imports [ pf.Game.{ Bounds, Elem, Event } ]
provides [ program ] { Model } to pf
imports [pf.Game.{ Bounds, Elem, Event }]
provides [program] { Model } to pf
paddleWidth = 0.2# width of the paddle, as a % of screen width
paddleHeight = 50# height of the paddle, in pixels
@ -136,7 +136,7 @@ render = \model ->
color,
}
[ outer, inner ]
[outer, inner]
ball =
color = { r: 0.7, g: 0.3, b: 0.9, a: 1.0 }
@ -156,6 +156,6 @@ render = \model ->
Rect { left, top, width, height, color }
List.concat rects [ paddle, ball ]
List.concat rects [paddle, ball]
program = { init, update, render }

View File

@ -1,7 +1,7 @@
app "breakout"
packages { pf: "platform" }
imports [ pf.Game.{ Bounds, Elem, Event } ]
provides [ program ] { Model } to pf
imports [pf.Game.{ Bounds, Elem, Event }]
provides [program] { Model } to pf
Model : { text : Str }
@ -12,6 +12,6 @@ update : Model, Event -> Model
update = \model, _ -> model
render : Model -> List Elem
render = \model -> [ Text model.text ]
render = \model -> [Text model.text]
program = { init, update, render }

View File

@ -1,8 +1,8 @@
interface Action
exposes [ Action, none, update, map ]
exposes [Action, none, update, map]
imports []
Action state : [ None, Update state ]
Action state : [None, Update state]
none : Action *
none = None

View File

@ -1,6 +1,6 @@
interface Elem
exposes [ Elem, PressEvent, row, col, text, button, none, translate, list ]
imports [ Action.{ Action } ]
exposes [Elem, PressEvent, row, col, text, button, none, translate, list]
imports [Action.{ Action }]
Elem state :
# PERFORMANCE NOTE:
@ -12,7 +12,7 @@ Elem state :
Text Str,
Col (List (Elem state)),
Row (List (Elem state)),
Lazy (Result { state, elem : Elem state } [ NotCached ] -> { state, elem : Elem state }),
Lazy (Result { state, elem : Elem state } [NotCached] -> { state, elem : Elem state }),
# TODO FIXME: using this definition of Lazy causes a stack overflow in the compiler!
# Lazy (Result (Cached state) [ NotCached ] -> Cached state),
None,
@ -23,7 +23,7 @@ Cached state : { state, elem : Elem state }
ButtonConfig state : { onPress : state, PressEvent -> Action state }
PressEvent : { button : [ Touch, Mouse [ Left, Right, Middle ] ] }
PressEvent : { button : [Touch, Mouse [Left, Right, Middle]] }
text : Str -> Elem *
text = \str ->

View File

@ -1,13 +1,13 @@
interface Game
exposes [ Bounds, Elem, Event ]
exposes [Bounds, Elem, Event]
imports []
Rgba : { r : F32, g : F32, b : F32, a : F32 }
Bounds : { height : F32, width : F32 }
Elem : [ Rect { color : Rgba, left : F32, top : F32, width : F32, height : F32 }, Text Str ]
Elem : [Rect { color : Rgba, left : F32, top : F32, width : F32, height : F32 }, Text Str]
KeyCode : [ Left, Right, Other ]
KeyCode : [Left, Right, Other]
Event : [ Resize { width : F32, height : F32 }, KeyDown KeyCode, KeyUp KeyCode, Tick U128 ]
Event : [Resize { width : F32, height : F32 }, KeyDown KeyCode, KeyUp KeyCode, Tick U128]

View File

@ -1,9 +1,9 @@
platform "gui"
requires { Model } { program : _ }
exposes [ Game ]
exposes [Game]
packages {}
imports [ Game.{ Bounds, Elem, Event } ]
provides [ programForHost ]
imports [Game.{ Bounds, Elem, Event }]
provides [programForHost]
# TODO allow changing the window title - maybe via a Task, since that shouldn't happen all the time
programForHost : {

View File

@ -1,15 +1,15 @@
interface Context
exposes [ Context, Data, with, getChar, Option, pushStack, popStack, toStr, inWhileScope ]
imports [ pf.File, pf.Task.{ Task }, Variable.{ Variable } ]
exposes [Context, Data, with, getChar, Option, pushStack, popStack, toStr, inWhileScope]
imports [pf.File, pf.Task.{ Task }, Variable.{ Variable }]
Option a : [ Some a, None ]
Option a : [Some a, None]
# The underlying context of the current location within the file
Data : [ Lambda (List U8), Number I32, Var Variable ]
Data : [Lambda (List U8), Number I32, Var Variable]
# While loops are special and have their own Scope specific state.
WhileState : { cond : List U8, body : List U8, state : [ InCond, InBody ] }
WhileState : { cond : List U8, body : List U8, state : [InCond, InBody] }
Scope : { data : Option File.Handle, index : Nat, buf : List U8, whileInfo : Option WhileState }
State : [ Executing, InComment, InLambda Nat (List U8), InString (List U8), InNumber I32, InSpecialChar, LoadChar ]
State : [Executing, InComment, InLambda Nat (List U8), InString (List U8), InNumber I32, InSpecialChar, LoadChar]
Context : { scopes : List Scope, stack : List Data, vars : List Data, state : State }
pushStack : Context, Data -> Context
@ -19,7 +19,7 @@ pushStack = \ctx, data ->
# I think an open tag union should just work here.
# Instead at a call sites, I need to match on the error and then return the same error.
# Otherwise it hits unreachable code in ir.rs
popStack : Context -> Result [ T Context Data ] [ EmptyStack ]*
popStack : Context -> Result [T Context Data] [EmptyStack]*
popStack = \ctx ->
when List.last ctx.stack is
Ok val ->
@ -72,10 +72,10 @@ with = \path, callback ->
# I cant define scope here and put it in the list in callback. It breaks alias anaysis.
# Instead I have to inline this.
# root_scope = { data: Some handle, index: 0, buf: [], whileInfo: None }
callback { scopes: [ { data: Some handle, index: 0, buf: [], whileInfo: None } ], state: Executing, stack: [], vars: List.repeat (Number 0) Variable.totalCount }
callback { scopes: [{ data: Some handle, index: 0, buf: [], whileInfo: None }], state: Executing, stack: [], vars: List.repeat (Number 0) Variable.totalCount }
# I am pretty sure there is a syntax to destructure and keep a reference to the whole, but Im not sure what it is.
getChar : Context -> Task [ T U8 Context ] [ EndOfData, NoScope ]*
getChar : Context -> Task [T U8 Context] [EndOfData, NoScope]*
getChar = \ctx ->
when List.last ctx.scopes is
Ok scope ->
@ -84,7 +84,7 @@ getChar = \ctx ->
Err ListWasEmpty ->
Task.fail NoScope
getCharScope : Scope -> Task [ T U8 Scope ] [ EndOfData, NoScope ]*
getCharScope : Scope -> Task [T U8 Scope] [EndOfData, NoScope]*
getCharScope = \scope ->
when List.get scope.buf scope.index is
Ok val ->

View File

@ -1,7 +1,7 @@
app "false"
packages { pf: "platform" }
imports [ pf.Task.{ Task }, pf.Stdout, pf.Stdin, Context.{ Context }, Variable.{ Variable } ]
provides [ main ] to pf
imports [pf.Task.{ Task }, pf.Stdout, pf.Stdin, Context.{ Context }, Variable.{ Variable }]
provides [main] to pf
# An interpreter for the False programming language: https://strlen.com/false-language/
# This is just a silly example to test this variety of program.
@ -16,14 +16,14 @@ app "false"
# In an imperative language, a few of these pieces would be in while loops and it would basically never overflow.
# This implementation is easy to overflow, either make the input long enough or make a false while loop run long enough.
# I assume all of the Task.awaits are the cause of this, but I am not 100% sure.
InterpreterErrors : [ BadUtf8, DivByZero, EmptyStack, InvalidBooleanValue, InvalidChar Str, MaxInputNumber, NoLambdaOnStack, NoNumberOnStack, NoVariableOnStack, NoScope, OutOfBounds, UnexpectedEndOfData ]
InterpreterErrors : [BadUtf8, DivByZero, EmptyStack, InvalidBooleanValue, InvalidChar Str, MaxInputNumber, NoLambdaOnStack, NoNumberOnStack, NoVariableOnStack, NoScope, OutOfBounds, UnexpectedEndOfData]
main : Str -> Task {} []
main = \filename ->
interpretFile filename
|> Task.onFail (\StringErr e -> Stdout.line "Ran into problem:\n\(e)\n")
interpretFile : Str -> Task {} [ StringErr Str ]
interpretFile : Str -> Task {} [StringErr Str]
interpretFile = \filename ->
ctx <- Context.with filename
result <- Task.attempt (interpretCtx ctx)
@ -79,7 +79,7 @@ interpretCtx : Context -> Task Context InterpreterErrors
interpretCtx = \ctx ->
Task.loop ctx interpretCtxLoop
interpretCtxLoop : Context -> Task [ Step Context, Done Context ] InterpreterErrors
interpretCtxLoop : Context -> Task [Step Context, Done Context] InterpreterErrors
interpretCtxLoop = \ctx ->
when ctx.state is
Executing if Context.inWhileScope ctx ->
@ -412,7 +412,7 @@ stepExecCtx = \ctx, char ->
# `,` write char
when popNumber ctx is
Ok (T popCtx num) ->
when Str.fromUtf8 [ Num.intCast num ] is
when Str.fromUtf8 [Num.intCast num] is
Ok str ->
{} <- Task.await (Stdout.raw str)
Task.succeed popCtx
@ -488,7 +488,7 @@ binaryOp = \ctx, op ->
(T popCtx2 numL) <- Result.after (popNumber popCtx1)
Ok (Context.pushStack popCtx2 (Number (op numL numR)))
popNumber : Context -> Result [ T Context I32 ] InterpreterErrors
popNumber : Context -> Result [T Context I32] InterpreterErrors
popNumber = \ctx ->
when Context.popStack ctx is
Ok (T popCtx (Number num)) ->
@ -498,7 +498,7 @@ popNumber = \ctx ->
Err EmptyStack ->
Err EmptyStack
popLambda : Context -> Result [ T Context (List U8) ] InterpreterErrors
popLambda : Context -> Result [T Context (List U8)] InterpreterErrors
popLambda = \ctx ->
when Context.popStack ctx is
Ok (T popCtx (Lambda bytes)) ->
@ -508,7 +508,7 @@ popLambda = \ctx ->
Err EmptyStack ->
Err EmptyStack
popVariable : Context -> Result [ T Context Variable ] InterpreterErrors
popVariable : Context -> Result [T Context Variable] InterpreterErrors
popVariable = \ctx ->
when Context.popStack ctx is
Ok (T popCtx (Var var)) ->

View File

@ -1,5 +1,5 @@
interface Variable
exposes [ Variable, fromUtf8, toIndex, totalCount, toStr ]
exposes [Variable, fromUtf8, toIndex, totalCount, toStr]
imports []
# Variables in False can only be single letters. Thus, the valid variables are "a" to "z".
@ -16,13 +16,13 @@ totalCount =
toStr : Variable -> Str
toStr = \@Variable char ->
when Str.fromUtf8 [ char ] is
when Str.fromUtf8 [char] is
Ok str ->
str
_ ->
"_"
fromUtf8 : U8 -> Result Variable [ InvalidVariableUtf8 ]
fromUtf8 : U8 -> Result Variable [InvalidVariableUtf8]
fromUtf8 = \char ->
if
char

View File

@ -1,7 +1,7 @@
hosted Effect
exposes [ Effect, after, map, always, forever, loop, openFile, closeFile, withFileOpen, getFileLine, getFileBytes, putLine, putRaw, getLine, getChar ]
exposes [Effect, after, map, always, forever, loop, openFile, closeFile, withFileOpen, getFileLine, getFileBytes, putLine, putRaw, getLine, getChar]
imports []
generates Effect with [ after, map, always, forever, loop ]
generates Effect with [after, map, always, forever, loop]
openFile : Str -> Effect U64

View File

@ -1,6 +1,6 @@
interface File
exposes [ line, Handle, withOpen, chunk ]
imports [ pf.Effect, Task.{ Task } ]
exposes [line, Handle, withOpen, chunk]
imports [pf.Effect, Task.{ Task }]
Handle := U64

View File

@ -2,8 +2,8 @@ platform "false-interpreter"
requires {} { main : Str -> Task {} [] }
exposes []
packages {}
imports [ Task.{ Task } ]
provides [ mainForHost ]
imports [Task.{ Task }]
provides [mainForHost]
mainForHost : Str -> Task {} [] as Fx
mainForHost = \file -> main file

View File

@ -1,6 +1,6 @@
interface Stdin
exposes [ char ]
imports [ pf.Effect, Task ]
exposes [char]
imports [pf.Effect, Task]
# line : Task.Task Str *
# line = Effect.after Effect.getLine Task.succeed # TODO FIXME Effect.getLine should suffice

View File

@ -1,6 +1,6 @@
interface Stdout
exposes [ line, raw ]
imports [ pf.Effect, Task.{ Task } ]
exposes [line, raw]
imports [pf.Effect, Task.{ Task }]
line : Str -> Task {} *
line = \str -> Effect.map (Effect.putLine str) (\_ -> Ok {})

View File

@ -1,10 +1,10 @@
interface Task
exposes [ Task, succeed, fail, await, map, onFail, attempt, fromResult, loop ]
imports [ pf.Effect ]
exposes [Task, succeed, fail, await, map, onFail, attempt, fromResult, loop]
imports [pf.Effect]
Task ok err : Effect.Effect (Result ok err)
loop : state, (state -> Task [ Step state, Done done ] err) -> Task done err
loop : state, (state -> Task [Step state, Done done] err) -> Task done err
loop = \state, step ->
looper = \current ->
step current

View File

@ -1,7 +1,7 @@
app "hello-gui"
packages { pf: "platform" }
imports []# [ pf.Action.{ Action }, pf.Elem.{ button, text, row, col } ]
provides [ render ] to pf
provides [render] to pf
render =
rgba = \r, g, b, a -> { r: r / 255, g: g / 255, b: b / 255, a }

View File

@ -1,8 +1,8 @@
interface Action
exposes [ Action, none, update, map ]
exposes [Action, none, update, map]
imports []
Action state : [ None, Update state ]
Action state : [None, Update state]
none : Action *
none = None

View File

@ -1,6 +1,6 @@
interface Elem
exposes [ Elem, PressEvent, row, col, text, button, none, translate, list ]
imports [ Action.{ Action } ]
exposes [Elem, PressEvent, row, col, text, button, none, translate, list]
imports [Action.{ Action }]
Elem state :
# PERFORMANCE NOTE:
@ -12,7 +12,7 @@ Elem state :
Text Str,
Col (List (Elem state)),
Row (List (Elem state)),
Lazy (Result { state, elem : Elem state } [ NotCached ] -> { state, elem : Elem state }),
Lazy (Result { state, elem : Elem state } [NotCached] -> { state, elem : Elem state }),
# TODO FIXME: using this definition of Lazy causes a stack overflow in the compiler!
# Lazy (Result (Cached state) [ NotCached ] -> Cached state),
None,
@ -23,7 +23,7 @@ Cached state : { state, elem : Elem state }
ButtonConfig state : { onPress : state, PressEvent -> Action state }
PressEvent : { button : [ Touch, Mouse [ Left, Right, Middle ] ] }
PressEvent : { button : [Touch, Mouse [Left, Right, Middle]] }
text : Str -> Elem *
text = \str ->

View File

@ -3,13 +3,13 @@ platform "gui"
exposes []
packages {}
imports []
provides [ renderForHost ]
provides [renderForHost]
Rgba : { r : F32, g : F32, b : F32, a : F32 }
ButtonStyles : { bgColor : Rgba, borderColor : Rgba, borderWidth : F32, textColor : Rgba }
Elem : [ Button Elem ButtonStyles, Col (List Elem), Row (List Elem), Text Str ]
Elem : [Button Elem ButtonStyles, Col (List Elem), Row (List Elem), Text Str]
renderForHost : Elem
renderForHost = render

View File

@ -3,7 +3,7 @@ platform "hello-world-in-c"
exposes []
packages {}
imports []
provides [ mainForHost ]
provides [mainForHost]
mainForHost : Str
mainForHost = main

View File

@ -1,6 +1,6 @@
app "helloC"
packages { pf: "." }
imports []
provides [ main ] to pf
provides [main] to pf
main = "Hello, World!\n"

View File

@ -6,6 +6,6 @@ app "helloWorld"
# packages { pf: "web-platform" } # See ./web-platform/README.md
# packages { pf: "zig-platform" }
imports []
provides [ main ] to pf
provides [main] to pf
main = "Hello, World!\n"

View File

@ -3,7 +3,7 @@ platform "hello-world-in-rust"
exposes []
packages {}
imports []
provides [ mainForHost ]
provides [mainForHost]
mainForHost : Str
mainForHost = main

View File

@ -1,6 +1,6 @@
app "helloRust"
packages { pf: "." }
imports []
provides [ main ] to pf
provides [main] to pf
main = "Hello, World!\n"

View File

@ -3,7 +3,7 @@ platform "hello-world-in-swift"
exposes []
packages {}
imports []
provides [ mainForHost ]
provides [mainForHost]
mainForHost : Str
mainForHost = main

View File

@ -1,6 +1,6 @@
app "helloSwift"
packages { pf: "." }
imports []
provides [ main ] to pf
provides [main] to pf
main = "Hello, World!\n"

View File

@ -3,7 +3,7 @@ platform "hello-world-in-web-assembly"
exposes []
packages {}
imports []
provides [ mainForHost ]
provides [mainForHost]
mainForHost : Str
mainForHost = main

View File

@ -1,6 +1,6 @@
app "helloWeb"
packages { pf: "." }
imports []
provides [ main ] to pf
provides [main] to pf
main = "Hello, World!\n"

View File

@ -3,7 +3,7 @@ platform "hello-world-in-zig"
exposes []
packages {}
imports []
provides [ mainForHost ]
provides [mainForHost]
mainForHost : Str
mainForHost = main

View File

@ -1,6 +1,6 @@
app "helloZig"
packages { pf: "." }
imports []
provides [ main ] to pf
provides [main] to pf
main = "Hello, World!\n"

View File

@ -1,7 +1,7 @@
hosted Effect
exposes [ Effect, after, map, always, forever, loop, putLine, getLine ]
exposes [Effect, after, map, always, forever, loop, putLine, getLine]
imports []
generates Effect with [ after, map, always, forever, loop ]
generates Effect with [after, map, always, forever, loop]
putLine : Str -> Effect {}

View File

@ -2,8 +2,8 @@ platform "cli"
requires {} { main : Task {} [] }
exposes []
packages {}
imports [ Task.{ Task } ]
provides [ mainForHost ]
imports [Task.{ Task }]
provides [mainForHost]
mainForHost : Task {} [] as Fx
mainForHost = main

View File

@ -1,6 +1,6 @@
interface Stdin
exposes [ line ]
imports [ pf.Effect, Task ]
exposes [line]
imports [pf.Effect, Task]
line : Task.Task Str *
line = Effect.after Effect.getLine Task.succeed# TODO FIXME Effect.getLine should suffice

View File

@ -1,6 +1,6 @@
interface Stdout
exposes [ line ]
imports [ pf.Effect, Task.{ Task } ]
exposes [line]
imports [pf.Effect, Task.{ Task }]
line : Str -> Task {} *
line = \str -> Effect.map (Effect.putLine str) (\_ -> Ok {})

View File

@ -1,6 +1,6 @@
interface Task
exposes [ Task, succeed, fail, await, map, onFail, attempt, forever, loop ]
imports [ pf.Effect ]
exposes [Task, succeed, fail, await, map, onFail, attempt, forever, loop]
imports [pf.Effect]
Task ok err : Effect.Effect (Result ok err)
@ -18,7 +18,7 @@ forever = \task ->
Effect.loop {} looper
loop : state, (state -> Task [ Step state, Done done ] err) -> Task done err
loop : state, (state -> Task [Step state, Done done] err) -> Task done err
loop = \state, step ->
looper = \current ->
step current

View File

@ -1,7 +1,7 @@
app "countdown"
packages { pf: "cli-platform" }
imports [ pf.Stdin, pf.Stdout, pf.Task.{ await, loop, succeed } ]
provides [ main ] to pf
imports [pf.Stdin, pf.Stdout, pf.Task.{ await, loop, succeed }]
provides [main] to pf
main =
_ <- await (Stdout.line "\nLet's count down from 10 together - all you have to do is press <ENTER>.")

View File

@ -1,7 +1,7 @@
app "echo"
packages { pf: "cli-platform" }
imports [ pf.Stdin, pf.Stdout, pf.Task ]
provides [ main ] to pf
imports [pf.Stdin, pf.Stdout, pf.Task]
provides [main] to pf
main : Task.Task {} []
main =

View File

@ -1,7 +1,7 @@
hosted Effect
exposes [ Effect, after, map, always, forever, putLine, getLine ]
exposes [Effect, after, map, always, forever, putLine, getLine]
imports []
generates Effect with [ after, map, always, forever ]
generates Effect with [after, map, always, forever]
putLine : Str -> Effect {}

View File

@ -2,8 +2,8 @@ platform "effects"
requires {} { main : Effect.Effect {} }
exposes []
packages {}
imports [ pf.Effect ]
provides [ mainForHost ]
imports [pf.Effect]
provides [mainForHost]
mainForHost : Effect.Effect {} as Fx
mainForHost = main

View File

@ -1,7 +1,7 @@
app "effects"
packages { pf: "effects-platform" }
imports [ pf.Effect ]
provides [ main ] to pf
imports [pf.Effect]
provides [main] to pf
main : Effect.Effect {}
main =

View File

@ -1,7 +1,7 @@
app "form"
packages { pf: "cli-platform" }
imports [ pf.Stdin, pf.Stdout, pf.Task.{ await, Task } ]
provides [ main ] to pf
imports [pf.Stdin, pf.Stdout, pf.Task.{ await, Task }]
provides [main] to pf
main : Task {} *
main =

View File

@ -3,7 +3,7 @@ platform "tui"
exposes []
packages {}
imports []
provides [ mainForHost ]
provides [mainForHost]
mainForHost : { init : ({} -> Model) as Init, update : (Model, Str -> Model) as Update, view : (Model -> Str) as View }
mainForHost = main

View File

@ -1,5 +1,5 @@
interface Program
exposes [ Program ]
exposes [Program]
imports []
Program model :

View File

@ -1,7 +1,7 @@
app "tui"
packages { pf: "tui-platform" }
imports [ pf.Program.{ Program } ]
provides [ main ] { Model } to pf
imports [pf.Program.{ Program }]
provides [main] { Model } to pf
Model : Str

View File

@ -258,34 +258,34 @@ fn literal_empty_list() {
#[cfg(not(feature = "wasm"))]
#[test]
fn literal_empty_list_empty_record() {
expect_success("[ {} ]", "[ {} ] : List {}");
expect_success("[ {} ]", "[{}] : List {}");
}
#[test]
fn literal_num_list() {
expect_success("[ 1, 2, 3 ]", "[ 1, 2, 3 ] : List (Num *)");
expect_success("[ 1, 2, 3 ]", "[1, 2, 3] : List (Num *)");
}
#[test]
fn literal_int_list() {
expect_success("[ 0x1, 0x2, 0x3 ]", "[ 1, 2, 3 ] : List (Int *)");
expect_success("[ 0x1, 0x2, 0x3 ]", "[1, 2, 3] : List (Int *)");
}
#[test]
fn literal_float_list() {
expect_success("[ 1.1, 2.2, 3.3 ]", "[ 1.1, 2.2, 3.3 ] : List (Float *)");
expect_success("[ 1.1, 2.2, 3.3 ]", "[1.1, 2.2, 3.3] : List (Float *)");
}
#[test]
fn literal_string_list() {
expect_success(r#"[ "a", "b", "cd" ]"#, r#"[ "a", "b", "cd" ] : List Str"#);
expect_success(r#"[ "a", "b", "cd" ]"#, r#"["a", "b", "cd"] : List Str"#);
}
#[test]
fn nested_string_list() {
expect_success(
r#"[ [ [ "a", "b", "cd" ], [ "y", "z" ] ], [ [] ], [] ]"#,
r#"[ [ [ "a", "b", "cd" ], [ "y", "z" ] ], [ [] ], [] ] : List (List (List Str))"#,
r#"[[["a", "b", "cd"], ["y", "z"]], [[]], []] : List (List (List Str))"#,
);
}
@ -293,7 +293,7 @@ fn nested_string_list() {
fn nested_num_list() {
expect_success(
r#"[ [ [ 4, 3, 2 ], [ 1, 0 ] ], [ [] ], [] ]"#,
r#"[ [ [ 4, 3, 2 ], [ 1, 0 ] ], [ [] ], [] ] : List (List (List (Num *)))"#,
r#"[[[4, 3, 2], [1, 0]], [[]], []] : List (List (List (Num *)))"#,
);
}
@ -301,7 +301,7 @@ fn nested_num_list() {
fn nested_int_list() {
expect_success(
r#"[ [ [ 4, 3, 2 ], [ 1, 0x0 ] ], [ [] ], [] ]"#,
r#"[ [ [ 4, 3, 2 ], [ 1, 0 ] ], [ [] ], [] ] : List (List (List Int *))"#,
r#"[[[4, 3, 2], [1, 0]], [[]], []] : List (List (List Int *))"#,
);
}
@ -309,7 +309,7 @@ fn nested_int_list() {
fn nested_float_list() {
expect_success(
r#"[ [ [ 4, 3, 2 ], [ 1, 0.0 ] ], [ [] ], [] ]"#,
r#"[ [ [ 4, 3, 2 ], [ 1, 0 ] ], [ [] ], [] ] : List (List (List (Float *)))"#,
r#"[[[4, 3, 2], [1, 0]], [[]], []] : List (List (List (Float *)))"#,
);
}
@ -386,7 +386,7 @@ fn num_mul_checked() {
fn list_concat() {
expect_success(
"List.concat [ 1.1, 2.2 ] [ 3.3, 4.4, 5.5 ]",
"[ 1.1, 2.2, 3.3, 4.4, 5.5 ] : List (Float *)",
"[1.1, 2.2, 3.3, 4.4, 5.5] : List (Float *)",
);
}
@ -508,14 +508,14 @@ fn basic_3_field_record() {
fn list_of_1_field_records() {
// Even though these get unwrapped at runtime, the repl should still
// report them as records
expect_success("[ { foo: 42 } ]", "[ { foo: 42 } ] : List { foo : Num * }");
expect_success("[ { foo: 42 } ]", "[{ foo: 42 }] : List { foo : Num * }");
}
#[test]
fn list_of_2_field_records() {
expect_success(
"[ { foo: 4.1, bar: 2 } ]",
"[ { bar: 2, foo: 4.1 } ] : List { bar : Num *, foo : Float * }",
"[{ bar: 2, foo: 4.1 }] : List { bar : Num *, foo : Float * }",
);
}
@ -547,7 +547,7 @@ fn multiline_string() {
fn list_of_3_field_records() {
expect_success(
"[ { foo: 4.1, bar: 2, baz: 0x3 } ]",
"[ { bar: 2, baz: 3, foo: 4.1 } ] : List { bar : Num *, baz : Int *, foo : Float * }",
"[{ bar: 2, baz: 3, foo: 4.1 }] : List { bar : Num *, baz : Int *, foo : Float * }",
);
}
@ -738,7 +738,7 @@ fn non_nullable_unwrapped_tag_union() {
combo
"#
),
r#"Tree "combo" [ Tree "e1" [], Tree "e2" [] ] : RoseTree Str"#,
r#"Tree "combo" [Tree "e1" [], Tree "e2" []] : RoseTree Str"#,
)
}
@ -822,7 +822,7 @@ fn issue_2300() {
fn function_in_list() {
expect_success(
r#"[\x -> x + 1, \s -> s * 2]"#,
r#"[ <function>, <function> ] : List (Num a -> Num a)"#,
r#"[<function>, <function>] : List (Num a -> Num a)"#,
)
}