From 1bd3f127765a0bf997e9890db00d4716e615f587 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Thu, 3 Jun 2021 21:31:47 -0400 Subject: [PATCH 01/52] Fix a bunch of Int docs --- compiler/builtins/README.md | 6 +++--- compiler/builtins/docs/List.roc | 4 ++-- compiler/builtins/docs/Num.roc | 10 +++++----- compiler/builtins/src/std.rs | 2 +- compiler/can/src/builtins.rs | 26 +++++++++++++------------- compiler/gen/src/llvm/build.rs | 2 +- 6 files changed, 25 insertions(+), 25 deletions(-) diff --git a/compiler/builtins/README.md b/compiler/builtins/README.md index fdb5bd793b..3d9b25d73f 100644 --- a/compiler/builtins/README.md +++ b/compiler/builtins/README.md @@ -9,15 +9,15 @@ Towards the bottom of `symbol.rs` there is a `define_builtins!` macro being used Some of these have `#` inside their name (`first#list`, `#lt` ..). This is a trick we are doing to hide implementation details from Roc programmers. To a Roc programmer, a name with `#` in it is invalid, because `#` means everything after it is parsed to a comment. We are constructing these functions manually, so we are circumventing the parsing step and dont have such restrictions. We get to make functions and values with `#` which as a consequence are not accessible to Roc programmers. Roc programmers simply cannot reference them. But we can use these values and some of these are necessary for implementing builtins. For example, `List.get` returns tags, and it is not easy for us to create tags when composing LLVM. What is easier however, is: -- ..writing `List.#getUnsafe` that has the dangerous signature of `List elem, Int -> elem` in LLVM -- ..writing `List elem, Int -> Result elem [ OutOfBounds ]*` in a type safe way that uses `getUnsafe` internally, only after it checks if the `elem` at `Int` index exists. +- ..writing `List.#getUnsafe` that has the dangerous signature of `List elem, Nat -> elem` in LLVM +- ..writing `List elem, Nat -> Result elem [ OutOfBounds ]*` in a type safe way that uses `getUnsafe` internally, only after it checks if the `elem` at `Nat` index exists. ### can/src/builtins.rs Right at the top of this module is a function called `builtin_defs`. All this is doing is mapping the `Symbol` defined in `module/src/symbol.rs` to its implementation. Some of the builtins are quite complex, such as `list_get`. What makes `list_get` is that it returns tags, and in order to return tags it first has to defer to lower-level functions via an if statement. -Lets look at `List.repeat : elem, Int -> List elem`, which is more straight-forward, and points directly to its lower level implementation: +Lets look at `List.repeat : elem, Nat -> List elem`, which is more straight-forward, and points directly to its lower level implementation: ``` fn list_repeat(symbol: Symbol, var_store: &mut VarStore) -> Def { let elem_var = var_store.fresh(); diff --git a/compiler/builtins/docs/List.roc b/compiler/builtins/docs/List.roc index 02866d5d37..0398f2ab8e 100644 --- a/compiler/builtins/docs/List.roc +++ b/compiler/builtins/docs/List.roc @@ -62,7 +62,7 @@ interface List2 ## the same type. If you want to put a mix of #Int and #Str values into a list, try this: ## ## ``` -## mixedList : List [ IntElem Int, StrElem Str ]* +## mixedList : List [ IntElem I64, StrElem Str ]* ## mixedList = [ IntElem 1, IntElem 2, StrElem "a", StrElem "b" ] ## ``` ## @@ -248,7 +248,7 @@ map : List before, (before -> after) -> List after ## This works like #List.map, except it also passes the index ## of the element to the conversion function. -mapWithIndex : List before, (before, Int -> after) -> List after +mapWithIndex : List before, (before, Nat -> after) -> List after ## This works like #List.map, except at any time you can return `Err` to ## cancel the entire operation immediately, and return that #Err. diff --git a/compiler/builtins/docs/Num.roc b/compiler/builtins/docs/Num.roc index 419672c852..fac1493ea3 100644 --- a/compiler/builtins/docs/Num.roc +++ b/compiler/builtins/docs/Num.roc @@ -689,7 +689,7 @@ toD64 : Num * -> D64 ## >>> Num.divRound 8 -3 ## ## This is the same as the #// operator. -divRound : Int, Int -> Int +divRound : Int a, Int a -> Int a ## Perform flooring modulo on two integers. ## @@ -711,16 +711,16 @@ divRound : Int, Int -> Int ## >>> -8 %% -3 ## ## >>> Int.modFloor -8 -3 -#modFloor : Int, Int -> Result DivByZero Int +#modFloor : Int a, Int a -> Result (Int a) [ DivByZero ]* ## Bitwise -xor : Int, Int -> Int +xor : Int a, Int a -> Int a -and : Int, Int -> Int +and : Int a, Int a -> Int a -not : Int -> Int +not : Int a -> Int a ## Sort ascending - that is, with the lowest first, and the highest last. ## diff --git a/compiler/builtins/src/std.rs b/compiler/builtins/src/std.rs index bdfac87c00..158f0523b8 100644 --- a/compiler/builtins/src/std.rs +++ b/compiler/builtins/src/std.rs @@ -292,7 +292,7 @@ pub fn types() -> MutMap { // minInt : Int range add_type!(Symbol::NUM_MIN_INT, int_type(flex(TVAR1))); - // div : Int, Int -> Result Int [ DivByZero ]* + // divInt : Int a, Int a -> Result (Int a) [ DivByZero ]* let div_by_zero = SolvedType::TagUnion( vec![(TagName::Global("DivByZero".into()), vec![])], Box::new(SolvedType::Wildcard), diff --git a/compiler/can/src/builtins.rs b/compiler/can/src/builtins.rs index ef76fc7c44..636ca3ab19 100644 --- a/compiler/can/src/builtins.rs +++ b/compiler/can/src/builtins.rs @@ -30,7 +30,7 @@ macro_rules! macro_magic { /// Some builtins cannot be constructed in code gen alone, and need to be defined /// as separate Roc defs. For example, List.get has this type: /// -/// List.get : List elem, Int -> Result elem [ OutOfBounds ]* +/// List.get : List elem, Nat -> Result elem [ OutOfBounds ]* /// /// Because this returns an open tag union for its Err type, it's not possible /// for code gen to return a hardcoded value for OutOfBounds. For example, @@ -450,7 +450,7 @@ fn num_add(symbol: Symbol, var_store: &mut VarStore) -> Def { num_binop(symbol, var_store, LowLevel::NumAdd) } -/// Num.addWrap : Int, Int -> Int +/// Num.addWrap : Int a, Int a -> Int a fn num_add_wrap(symbol: Symbol, var_store: &mut VarStore) -> Def { num_binop(symbol, var_store, LowLevel::NumAddWrap) } @@ -549,7 +549,7 @@ fn num_sub(symbol: Symbol, var_store: &mut VarStore) -> Def { num_binop(symbol, var_store, LowLevel::NumSub) } -/// Num.subWrap : Int, Int -> Int +/// Num.subWrap : Int a, Int a -> Int a fn num_sub_wrap(symbol: Symbol, var_store: &mut VarStore) -> Def { num_binop(symbol, var_store, LowLevel::NumSubWrap) } @@ -648,7 +648,7 @@ fn num_mul(symbol: Symbol, var_store: &mut VarStore) -> Def { num_binop(symbol, var_store, LowLevel::NumMul) } -/// Num.mulWrap : Int, Int -> Int +/// Num.mulWrap : Int a, Int a -> Int a fn num_mul_wrap(symbol: Symbol, var_store: &mut VarStore) -> Def { num_binop(symbol, var_store, LowLevel::NumMulWrap) } @@ -1152,7 +1152,7 @@ fn num_ceiling(symbol: Symbol, var_store: &mut VarStore) -> Def { ) } -/// Num.powInt : Int, Int -> Int +/// Num.powInt : Int a, Int a -> Int a fn num_pow_int(symbol: Symbol, var_store: &mut VarStore) -> Def { let int_var = var_store.fresh(); @@ -1251,17 +1251,17 @@ fn num_asin(symbol: Symbol, var_store: &mut VarStore) -> Def { ) } -/// Num.bitwiseAnd : Int, Int -> Int +/// Num.bitwiseAnd : Int a, Int a -> Int a fn num_bitwise_and(symbol: Symbol, var_store: &mut VarStore) -> Def { num_binop(symbol, var_store, LowLevel::NumBitwiseAnd) } -/// Num.bitwiseXor : Int, Int -> Int +/// Num.bitwiseXor : Int a, Int a -> Int a fn num_bitwise_xor(symbol: Symbol, var_store: &mut VarStore) -> Def { num_binop(symbol, var_store, LowLevel::NumBitwiseXor) } -/// Num.bitwiseOr: Int, Int -> Int +/// Num.bitwiseOr: Int a, Int a -> Int a fn num_bitwise_or(symbol: Symbol, var_store: &mut VarStore) -> Def { num_binop(symbol, var_store, LowLevel::NumBitwiseOr) } @@ -1667,7 +1667,7 @@ fn list_concat(symbol: Symbol, var_store: &mut VarStore) -> Def { ) } -/// List.repeat : elem, Int -> List elem +/// List.repeat : elem, Nat -> List elem fn list_repeat(symbol: Symbol, var_store: &mut VarStore) -> Def { let elem_var = var_store.fresh(); let len_var = var_store.fresh(); @@ -1809,7 +1809,7 @@ fn list_get(symbol: Symbol, var_store: &mut VarStore) -> Def { ) } -/// List.set : List elem, Int, elem -> List elem +/// List.set : List elem, Nat, elem -> List elem /// /// List.set : /// Attr (w | u | v) (List (Attr u a)), @@ -2531,7 +2531,7 @@ fn set_walk(symbol: Symbol, var_store: &mut VarStore) -> Def { ) } -/// Num.rem : Int, Int -> Result Int [ DivByZero ]* +/// Num.rem : Int a, Int a -> Result (Int a) [ DivByZero ]* fn num_rem(symbol: Symbol, var_store: &mut VarStore) -> Def { let num_var = var_store.fresh(); let unbound_zero_var = var_store.fresh(); @@ -2590,7 +2590,7 @@ fn num_rem(symbol: Symbol, var_store: &mut VarStore) -> Def { ) } -/// Num.isMultipleOf : Int, Int -> Bool +/// Num.isMultipleOf : Int a, Int a -> Bool fn num_is_multiple_of(symbol: Symbol, var_store: &mut VarStore) -> Def { lowlevel_2(symbol, LowLevel::NumIsMultipleOf, var_store) } @@ -2696,7 +2696,7 @@ fn num_div_float(symbol: Symbol, var_store: &mut VarStore) -> Def { ) } -/// Num.div : Int, Int -> Result Int [ DivByZero ]* +/// Num.div : Int a , Int a -> Result (Int a) [ DivByZero ]* fn num_div_int(symbol: Symbol, var_store: &mut VarStore) -> Def { let bool_var = var_store.fresh(); let num_var = var_store.fresh(); diff --git a/compiler/gen/src/llvm/build.rs b/compiler/gen/src/llvm/build.rs index 06e08dcdd5..7037fd2f12 100644 --- a/compiler/gen/src/llvm/build.rs +++ b/compiler/gen/src/llvm/build.rs @@ -4558,7 +4558,7 @@ fn run_low_level<'a, 'ctx, 'env>( BasicValueEnum::IntValue(bool_val) } ListGetUnsafe => { - // List.get : List elem, Int -> [ Ok elem, OutOfBounds ]* + // List.get : List elem, Nat -> [ Ok elem, OutOfBounds ]* debug_assert_eq!(args.len(), 2); let (wrapper_struct, list_layout) = load_symbol_and_layout(scope, &args[0]); From 914d67aeed9d3d5b0021317cdaab3c7931266a64 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Thu, 3 Jun 2021 21:31:57 -0400 Subject: [PATCH 02/52] Drop obsolete Defaults.roc --- compiler/builtins/docs/Defaults.roc | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 compiler/builtins/docs/Defaults.roc diff --git a/compiler/builtins/docs/Defaults.roc b/compiler/builtins/docs/Defaults.roc deleted file mode 100644 index 046ba7dc3f..0000000000 --- a/compiler/builtins/docs/Defaults.roc +++ /dev/null @@ -1,7 +0,0 @@ -interface Defaults - exposes [] - imports [ - Dict.{ Dict }, - Set.{ Set }, - Num.{ Num, Int, Float } - ] From 14d20c124d7ca2fca9397ad76352108085fd4b00 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Thu, 3 Jun 2021 21:32:22 -0400 Subject: [PATCH 03/52] Fix NumParseConfig definition --- compiler/builtins/docs/Str.roc | 1 - 1 file changed, 1 deletion(-) diff --git a/compiler/builtins/docs/Str.roc b/compiler/builtins/docs/Str.roc index 0727b68af8..fae7e7e5f6 100644 --- a/compiler/builtins/docs/Str.roc +++ b/compiler/builtins/docs/Str.roc @@ -475,4 +475,3 @@ NumParseConfig : trailingZeroes ? [ Allowed, Disallowed ], wholeSep ? { mark : Str, policy : [ Allowed, Required U64 ] } } - -> Str From 1aa286bace7df3cdd996243f784f1fcfe0104111 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Thu, 3 Jun 2021 21:32:57 -0400 Subject: [PATCH 04/52] Improve a panic message --- docs/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/src/lib.rs b/docs/src/lib.rs index 718ae50ba1..2543219903 100644 --- a/docs/src/lib.rs +++ b/docs/src/lib.rs @@ -583,8 +583,8 @@ fn make_doc_link(scope: &mut Scope, interns: &Interns, doc_item: &str) -> String } Err(_) => { panic!( - "Could not find symbol in scope for module link : {}", - doc_item + "Tried to generate an automatic link in docs for symbol `{}`, but that symbol was not in scope in this module. Scope was: {:?}", + doc_item, scope ) } } From 037d41d7c7c1d2f5af9050955e2dea519f7f94d2 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Thu, 3 Jun 2021 21:33:53 -0400 Subject: [PATCH 05/52] Don't hardcode ptr_bytes --- docs/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/lib.rs b/docs/src/lib.rs index 2543219903..9bd0d2fa93 100644 --- a/docs/src/lib.rs +++ b/docs/src/lib.rs @@ -305,7 +305,7 @@ pub fn files_to_documentations( &std_lib, src_dir.as_path(), MutMap::default(), - 8, // TODO: Is it okay to hardcode ptr_bytes here? I think it should be fine since we'er only type checking (also, 8 => 32bit system) + std::mem::size_of::(), // This is just type-checking for docs, so "target" doesn't matter builtin_defs_map, ) { Ok(loaded) => files_docs.push((loaded.documentation, loaded.interns)), From d523beb54c85ac77abd935f4fc0706f5773620e1 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Thu, 3 Jun 2021 22:31:20 -0400 Subject: [PATCH 06/52] Add isFinite and friends --- compiler/builtins/docs/Num.roc | 54 ++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/compiler/builtins/docs/Num.roc b/compiler/builtins/docs/Num.roc index fac1493ea3..b351feec93 100644 --- a/compiler/builtins/docs/Num.roc +++ b/compiler/builtins/docs/Num.roc @@ -977,3 +977,57 @@ sqrt : Float a -> [Ok (Float a), InvalidSqrt]* Endi : [ Big, Little ] toBytes : Num *, Endi -> List U8 + +## When given a [F64] or [F32] value, returns `False` if that value is +## [*NaN*](https://en.wikipedia.org/wiki/NaN). (Returns `False` if that value is *Infinity* or *-Infinity*.) +## +## Always returns `False` when given a [Dec]. +## +## >>> Num.isNaN 12.3 +## +## >>> Num.isNaN (Num.sqrtOrNaN -2) +## +## See also [isPoison] and [isFinite]. +isNaN : Frac * -> Bool + +## When given a [F64] or [F32] value, returns `False` if that value is +## [*NaN*](https://en.wikipedia.org/wiki/NaN), *Infinity*, or *-Infinity*. +## +## Always returns `True` when given a [Dec]. +## +## [isPoison] returns the opposite of this. +## +## See also [isInfinite]. +isFinite : Frac * -> Bool + +## When given a [F64] or [F32] value, returns `True` if that value is +## [*NaN*](https://en.wikipedia.org/wiki/NaN), *Infinity*, or *-Infinity*. +## +## Always returns `False` when given a [Dec]. +## +## [isFinite] returns the opposite of this. +isPoison : Frac * -> Bool + +## When given a [F64] or [F32] value, returns `True` if that value is either +## *Infinity* or *-Infinity*. (Returns `False` if that value is [*NaN*](https://en.wikipedia.org/wiki/NaN).) +## +## Always returns `False` when given a [Dec]. +## +## See also [isFinite], [isPositiveInfinity], and [isNegativeInfinity]. +isInfinite : Frac * -> Bool + +## When given a [F64] or [F32] value, returns `True` if that value is +## *Infinity*. (Returns `False` if that value is *-Infinity* or [*NaN*](https://en.wikipedia.org/wiki/NaN).) +## +## Always returns `False` when given a [Dec]. +## +## See also [isNegativeInfinity], [isInfinite], and [isFinite]. +isPositiveInfinity : Frac * -> Bool + +## When given a [F64] or [F32] value, returns `True` if that value is +## *Infinity*. (Returns `False` if that value is *-Infinity* or [*NaN*](https://en.wikipedia.org/wiki/NaN).) +## +## Always returns `False` when given a [Dec]. +## +## See also [isPositiveInfinity], [isInfinite], and [isFinite]. +isNegativeInfinity : Frac * -> Bool From dcd388065ccb7c6a7eddda0bb0979e5ab1c26b9a Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Fri, 4 Jun 2021 00:26:12 -0400 Subject: [PATCH 07/52] s/Float/Frac and other changes --- compiler/builtins/docs/Num.roc | 230 ++++++++++++++++++--------------- 1 file changed, 127 insertions(+), 103 deletions(-) diff --git a/compiler/builtins/docs/Num.roc b/compiler/builtins/docs/Num.roc index b351feec93..4c14a50b4e 100644 --- a/compiler/builtins/docs/Num.roc +++ b/compiler/builtins/docs/Num.roc @@ -12,10 +12,10 @@ interface Num2 ## add : Num range, Num range -> Num range ## ``` ## -## The number 1.5 technically has the type `Num FloatingPoint`, so when you pass two of them to `Num.add`, the answer you get is `3.0 : Num FloatingPoint`. +## The number 1.5 technically has the type `Num Fraction`, so when you pass two of them to `Num.add`, the answer you get is `3.0 : Num Fraction`. ## -## The type #Float is defined to be an alias for `Num FloatingPoint`, so `3.0 : Num FloatingPoint` is the same answer as `3.0 : Float`. # # Similarly, the number 1 technically has the type `Num Integer`, so when you pass two of them to `Num.add`, the answer you get is `2 : Num Integer`. # # The type #Int is defined to be an alias for `Num Integer`, so `2 : Num Integer` is the same answer as `2 : Int`. # -## In this way, the `Num` type makes it possible to have `1 + 1` return `2 : Int` and `1.5 + 1.5` return `3.0 : Float`. +## The type #Frac is defined to be an alias for `Num Fraction`, so `3.0 : Num Fraction` is the same answer as `3.0 : Frac`. # # Similarly, the number 1 technically has the type `Num Integer`, so when you pass two of them to `Num.add`, the answer you get is `2 : Num Integer`. # # The type #Int is defined to be an alias for `Num Integer`, so `2 : Num Integer` is the same answer as `2 : Int`. # +## In this way, the `Num` type makes it possible to have `1 + 1` return `2 : Int` and `1.5 + 1.5` return `3.0 : Frac`. ## ## ## Number Literals ## @@ -272,7 +272,7 @@ Nat : Int [ @Natural ] ## If you need to do math outside these bounds, consider using a larger numeric size. Int size : Num [ @Int size ] -## A 64-bit floating-point number. All number literals with decimal points are #Float values. +## A 64-bit floating-point number. All number literals with decimal points are #Frac values. ## ## >>> 0.1 ## @@ -280,7 +280,7 @@ Int size : Num [ @Int size ] ## ## >>> 0.0 ## -## If you like, you can put underscores in your #Float literals. +## If you like, you can put underscores in your #Frac literals. ## They have no effect on the number's value, but can make things easier to read. ## ## >>> 1_000_000.000_000_001 @@ -309,7 +309,7 @@ Int size : Num [ @Int size ] ## If decimal precision is important - for example, when representing money - ## decimal floats tend to be worth the performance cost. ## -## Usually, Roc's compiler can infer a more specific type than #Float for +## Usually, Roc's compiler can infer a more specific type than #Frac for ## a particular float value, based on how it is used with other numbers. For example: ## ## >>> coordinates : { x : F32, y : F32 } @@ -330,7 +330,7 @@ Int size : Num [ @Int size ] ## If you want something else, you can write (for example) `0.1f32 + 0.2 == 0.3` ## to compare them as #F32 values instead. ## -## Both decimal and binary #Float values conform to the [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754#Interchange_formats) +## Both decimal and binary #Frac values conform to the [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754#Interchange_formats) ## specification for floating point numbers. Conforming to this specification ## means Roc's binary floats have nearly universal hardware support, and its ## decimal floats have [some hardware support](http://speleotrove.com/decimal/) @@ -343,7 +343,7 @@ Int size : Num [ @Int size ] ## - #D32 (32-bit decimal float) ## - #D64 (64-bit decimal float) # TODO show a table like we do with ints, with the min/max ranges ## -## Like #Int, it's possible for #Float operations to overflow. Like with ints, +## Like #Int, it's possible for #Frac operations to overflow. Like with ints, ## you'll typically get a crash when this happens. ## ## * In a development build, you'll get an assertion failure. @@ -352,7 +352,7 @@ Int size : Num [ @Int size ] ## Although some languages treat have first-class representations for ## `-Infinity`, `Infinity`, and the special `NaN` ("not a number") ## floating-point values described in the IEEE-754, Roc does not. -## Instead, Roc treats all of these as errors. If any Float operation +## Instead, Roc treats all of these as errors. If any Frac operation ## in a development build encounters one of these values, it will ## result in an assertion failure. ## @@ -378,13 +378,13 @@ Int size : Num [ @Int size ] ## Whenever any arithmetic operation is performed on an invalid float, ## the result is also invalid. This is called *error propagation*, and ## it is notoriously error-prone. In Roc, using equality operations like -## `==` and `!=` on an invalid float causes a crash. (See #Float.verify +## `==` and `!=` on an invalid float causes a crash. (See #Frac.verify ## to check the validity of your float.) ## ## Beause invalid floats are so error-prone, Roc discourages using them. ## Instead, by default it treats them the same way as overflow: by -## crashing whenever any #Float function would otherwise return one. -## You can also use functions like #Float.tryAdd to get an `Ok` or an error +## crashing whenever any #Frac function would otherwise return one. +## You can also use functions like #Frac.tryAdd to get an `Ok` or an error ## back so you can gracefully recover from invalid values. ## ## Quiet errors can be useful sometimes. For example, you might want to @@ -426,7 +426,7 @@ Int size : Num [ @Int size ] ## ## >>> Num.neg 0.0 ## -## This is safe to use with any #Float, but it can cause overflow when used with certain #Int values. +## This is safe to use with any #Frac, but it can cause overflow when used with certain #Int values. ## ## For example, calling #Num.neg on the lowest value of a signed integer (such as #Int.lowestI64 or #Int.lowestI32) will cause overflow. ## This is because, for any given size of signed integer (32-bit, 64-bit, etc.) its negated lowest value turns out to be 1 higher than @@ -434,7 +434,7 @@ Int size : Num [ @Int size ] ## ## Additionally, calling #Num.neg on any unsigned integer (such as any #U64 or #U32 value) other than 0 will cause overflow. ## -## (It will never crash when given a #Float, however, because of how floating point numbers represent positive and negative numbers.) +## (It will never crash when given a #Frac, however, because of how floating point numbers represent positive and negative numbers.) neg : Num range -> Num range ## Return the absolute value of the number. @@ -451,7 +451,7 @@ neg : Num range -> Num range ## ## >>> Num.abs 0.0 ## -## This is safe to use with any #Float, but it can cause overflow when used with certain #Int values. +## This is safe to use with any #Frac, but it can cause overflow when used with certain #Int values. ## ## For example, calling #Num.abs on the lowest value of a signed integer (such as #Int.lowestI64 or #Int.lowestI32) will cause overflow. ## This is because, for any given size of signed integer (32-bit, 64-bit, etc.) its negated lowest value turns out to be 1 higher than @@ -485,7 +485,7 @@ isOdd : Num * -> Bool ## Add two numbers of the same type. ## -## (To add an #Int and a #Float, first convert one so that they both have the same type. There are functions in the [`Float`](/Float) module that can convert both #Int to #Float and the other way around.) +## (To add an #Int and a #Frac, first convert one so that they both have the same type. There are functions in the [`Frac`](/Frac) module that can convert both #Int to #Frac and the other way around.) ## ## `a + b` is shorthand for `Num.add a b`. ## @@ -495,13 +495,13 @@ isOdd : Num * -> Bool ## ## `Num.add` can be convenient in pipelines. ## -## >>> Float.pi +## >>> Frac.pi ## >>> |> Num.add 1.0 add : Num range, Num range -> Num range ## Subtract two numbers of the same type. ## -## (To subtract an #Int and a #Float, first convert one so that they both have the same type. There are functions in the [`Float`](/Float) module that can convert both #Int to #Float and the other way around.) +## (To subtract an #Int and a #Frac, first convert one so that they both have the same type. There are functions in the [`Frac`](/Frac) module that can convert both #Int to #Frac and the other way around.) ## ## `a - b` is shorthand for `Num.sub a b`. ## @@ -511,13 +511,13 @@ add : Num range, Num range -> Num range ## ## `Num.sub` can be convenient in pipelines. ## -## >>> Float.pi +## >>> Frac.pi ## >>> |> Num.sub 2.0 sub : Num range, Num range -> Num range ## Multiply two numbers of the same type. ## -## (To multiply an #Int and a #Float, first convert one so that they both have the same type. There are functions in the [`Float`](/Float) module that can convert both #Int to #Float and the other way around.) +## (To multiply an #Int and a #Frac, first convert one so that they both have the same type. There are functions in the [`Frac`](/Frac) module that can convert both #Int to #Frac and the other way around.) ## ## `a * b` is shorthand for `Num.mul a b`. ## @@ -527,7 +527,7 @@ sub : Num range, Num range -> Num range ## ## `Num.mul` can be convenient in pipelines. ## -## >>> Float.pi +## >>> Frac.pi ## >>> |> Num.mul 2.0 mul : Num range, Num range -> Num range @@ -540,7 +540,7 @@ mul : Num range, Num range -> Num range ## ## >>> Num.toStr 42 ## -## Only #Float values will include a decimal point, and they will always include one. +## Only #Frac values will include a decimal point, and they will always include one. ## ## >>> Num.toStr 4.2 ## @@ -612,10 +612,10 @@ format : -> Str ## Round off the given float to the nearest integer. -round : Float * -> Int * -ceil : Float * -> Int * -floor : Float * -> Int * -trunc : Float * -> Int * +round : Frac * -> Int * +ceil : Frac * -> Int * +floor : Frac * -> Int * +trunc : Frac * -> Int * ## Convert an #Int to a #Nat. If the given number doesn't fit in #Nat, it will be truncated. ## Since #Nat has a different maximum number depending on the system you're building @@ -630,13 +630,13 @@ trunc : Float * -> Int * ## the #Nat value of 9_000_000_000. This is because on a 64-bit system, #Nat can ## hold up to #Num.maxU64, and 9_000_000_000 is lower than #Num.maxU64. ## -## To convert a #Float to a #Nat, first call either #Num.round, #Num.ceil, or #Num.floor +## To convert a #Frac to a #Nat, first call either #Num.round, #Num.ceil, or #Num.floor ## on it, then call this on the resulting #Int. toNat : Int * -> Nat ## Convert an #Int to an #I8. If the given number doesn't fit in #I8, it will be truncated. ## -## To convert a #Float to an #I8, first call either #Num.round, #Num.ceil, or #Num.floor +## To convert a #Frac to an #I8, first call either #Num.round, #Num.ceil, or #Num.floor ## on it, then call this on the resulting #Int. toI8 : Int * -> I8 toI16 : Int * -> I16 @@ -660,13 +660,9 @@ toF32 : Num * -> F32 ## there will be a loss of precision. toF64 : Num * -> F64 -## Convert a #Num to a #D32. If the given number can't be precisely represented in a #D32, +## Convert a #Num to a #Dec. If the given number can't be precisely represented in a #Dec, ## there will be a loss of precision. -toD32 : Num * -> D32 - -## Convert a #Num to a #D64. If the given number can't be precisely represented in a #D64, -## there will be a loss of precision. -toD64 : Num * -> D64 +toDec : Num * -> Dec ## Divide two integers and #Num.round the resulut. ## @@ -696,9 +692,9 @@ divRound : Int a, Int a -> Int a ## Modulo is the same as remainder when working with positive numbers, ## but if either number is negative, then modulo works differently. ## -## Additionally, flooring modulo uses #Float.floor on the result. +## Additionally, flooring modulo uses #Frac.floor on the result. ## -## (Use #Float.mod for non-flooring modulo.) +## (Use #Frac.mod for non-flooring modulo.) ## ## Return `Err DivByZero` if the second integer is zero, because division by zero is undefined in mathematics. ## @@ -739,7 +735,7 @@ desc : Num a, Num a -> [ Eq, Lt, Gt ] ## This function can crash under these circumstances: ## ## * It receives a function, or any type that contains a function (for example a record, tag, or #List containing a function) -## * It receives an erroneous #Float (`NaN`, `Infinity`, or `-Infinity` - these values can only originate from hosts) +## * It receives an erroneous #Frac (`NaN`, `Infinity`, or `-Infinity` - these values can only originate from hosts) ## ## CAUTION: This function may give different answers in future releases of Roc, ## so be aware that if you rely on the exact answer this gives today, your @@ -803,88 +799,96 @@ maxU32 : U32 ## and zero is the lowest unsigned number. Unsigned numbers cannot be negative. minU32 : U32 -## The highest supported #Float value you can have, which is approximately 1.8 × 10^308. +## The highest supported #Frac value you can have, which is approximately 1.8 × 10^308. ## ## If you go higher than this, your running Roc code will crash - so be careful not to! -maxF64 : Float * +maxF64 : Frac * -## The lowest supported #Float value you can have, which is approximately -1.8 × 10^308. +## The lowest supported #Frac value you can have, which is approximately -1.8 × 10^308. ## ## If you go lower than this, your running Roc code will crash - so be careful not to! -minF64 : Float * +minF64 : Frac * -## The highest integer that can be represented as a #Float without # losing precision. +## The highest integer that can be represented as a #Frac without # losing precision. ## It is equal to 2^53, which is approximately 9 × 10^15. ## ## Some integers higher than this can be represented, but they may lose precision. For example: ## -## >>> Float.highestInt +## >>> Frac.highestInt ## -## >>> Float.highestInt + 100 # Increasing may lose precision +## >>> Frac.highestInt + 100 # Increasing may lose precision ## -## >>> Float.highestInt - 100 # Decreasing is fine - but watch out for lowestLosslessInt! -maxPreciseInt : Float * +## >>> Frac.highestInt - 100 # Decreasing is fine - but watch out for lowestLosslessInt! +maxPreciseInt : Frac * -## The lowest integer that can be represented as a #Float without losing precision. +## The lowest integer that can be represented as a #Frac without losing precision. ## It is equal to -2^53, which is approximately -9 × 10^15. ## ## Some integers lower than this can be represented, but they may lose precision. For example: ## -## >>> Float.lowestIntVal +## >>> Frac.lowestIntVal ## -## >>> Float.lowestIntVal - 100 # Decreasing may lose precision +## >>> Frac.lowestIntVal - 100 # Decreasing may lose precision ## -## >>> Float.lowestIntVal + 100 # Increasing is fine - but watch out for highestInt! -maxPreciseInt : Float * +## >>> Frac.lowestIntVal + 100 # Increasing is fine - but watch out for highestInt! +maxPreciseInt : Frac * ## Constants ## An approximation of e, specifically 2.718281828459045. -e : Float * +e : Frac * ## An approximation of pi, specifically 3.141592653589793. -pi : Float * +pi : Frac * ## Constants ## An approximation of e, specifically 2.718281828459045. -e : Float * +e : Frac * ## An approximation of pi, specifically 3.141592653589793. -pi : Float * +pi : Frac * -#ceiling : Float -> Int +#ceiling : Frac -> Int -#floor : Float -> Int +#floor : Frac -> Int ## Trigonometry -#cos : Float -> Float +#cos : Frac -> Frac -#acos : Float -> Float +#acos : Frac -> Frac -#sin : Float -> Float +#sin : Frac -> Frac -#asin : Float -> Float +#asin : Frac -> Frac -#tan : Float -> Float +#tan : Frac -> Frac -#atan : Float -> Float +#atan : Frac -> Frac ## Other Calculations (arithmetic?) -## Divide two #Float numbers. +## Divide one [Frac] by another. ## ## `a / b` is shorthand for `Num.div a b`. ## -## Division by zero is undefined in mathematics. As such, you should make -## sure never to pass zero as the denomaintor to this function! +## [Division by zero is undefined in mathematics](https://en.wikipedia.org/wiki/Division_by_zero). +## As such, you should make sure never to pass zero as the denomaintor to this function! +## Calling [div] on a [Dec] denominator of 0 will cause a runtime error. ## -## If zero does get passed as the denominator... +## Calling [div] on [F32] and [F64] values follows these rules: +## * Dividing a positive [F32] or [F64] by zero returns [Infinity](#isPositiveInfinity). +## * Dividing a negative [F32] or [F64] by zero returns [-Infinity](#isNegativeInfinity). +## * Dividing a zero [F32] or [F64] by zero returns [NaN](#isNaN). ## -## * In a development build, you'll get an assertion failure. -## * In a release build, the function will return `Infinity`, `-Infinity`, or `NaN` depending on the arguments. +## > These rules come from the [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754) +## > floating point standard. Since almost all modern processors are built to +## > this standard, deviating from these rules has a significant performance +## > cost. Since the most common reason to choose [F32] or [F64] over [Dec] is +## > access to hardware-accelerated performance, Roc follows these rules exactly. ## -## To divide an #Int and a #Float, first convert the #Int to a #Float using one of the functions in this module. +## To divide an [Int] and a [Frac], first convert the [Int] to a [Frac] using +## one of the functions in this module like [toDec]. ## ## >>> 5.0 / 7.0 ## @@ -892,45 +896,47 @@ pi : Float * ## ## `Num.div` can be convenient in pipelines. ## -## >>> Float.pi +## >>> Num.pi ## >>> |> Num.div 2.0 -#div : Float, Float -> Result Float DivByZero -div = \numerator, denominator -> - when numerator is - 0.0 -> 0.0 # TODO return Result! - _ -> denominator +div : Frac a, Frac a -> Frac a -## Perform modulo on two #Float numbers. +## Perform modulo on two [Frac]s. ## ## Modulo is the same as remainder when working with positive numbers, ## but if either number is negative, then modulo works differently. ## -## Return `Err DivByZero` if the second number is zero, because division by zero is undefined in mathematics. +## `a % b` is shorthand for `Num.mod a b`. ## -## `a % b` is shorthand for `Float.mod a b`. +## [Division by zero is undefined in mathematics](https://en.wikipedia.org/wiki/Division_by_zero), +## and as such, so is modulo by zero. Because of this, you should make sure never +## to pass zero for the second argument to this function! +## +## Passing [mod] a [Dec] value of 0 for its second argument will cause a runtime error. +## Passing [mod] a [F32] and [F64] value for its second argument will cause it +## to return [NaN](#isNaN). ## ## >>> 5.0 % 7.0 ## -## >>> Float.mod 5 7 +## >>> Num.mod 5 7 ## -## `Float.mod` can be convenient in pipelines. +## `Num.mod` can be convenient in pipelines. ## -## >>> Float.pi -## >>> |> Float.mod 2.0 -mod : Float a, Float a -> Result (Float a) [ DivByZero ]* +## >>> Num.pi +## >>> |> Num.mod 2.0 +mod : Frac a, Frac a -> Frac a -## Raises a #Float to the power of another #Float. +## Raises a #Frac to the power of another #Frac. ## ## ` ## For an #Int alternative to this function, see #Num.raise. -pow : Float a, Float a -> Float a +pow : Frac a, Frac a -> Frac a ## Raises an integer to the power of another, by multiplying the integer by ## itself the given number of times. ## ## This process is known as [exponentiation by squaring](https://en.wikipedia.org/wiki/Exponentiation_by_squaring). ## -## For a #Float alternative to this function, which supports negative exponents, +## For a #Frac alternative to this function, which supports negative exponents, ## see #Num.exp. ## ## >>> Num.exp 5 0 @@ -947,30 +953,48 @@ pow : Float a, Float a -> Float a ## overflow expBySquaring : Int a, U8 -> Int a -## Return the reciprocal of a #Float - that is, divides `1.0` by the given number. +## Returns an approximation of the absolute value of the square root of the [Frac]. ## -## Crashes if given `0.0`, because division by zero is undefined in mathematics. +## The square root of a negative number is an irrational number, and [Frac] only +## supports rational numbers. As such, you should make sure never to pass this +## function a negative number! Calling [sqrt] on a negative [Dec] will cause a runtime error. ## -## For a version that does not crash, use #tryRecip -recip : Float a -> Result (Float a) [ DivByZero ]* +## Calling [sqrt] on [F32] and [F64] values follows these rules: +## * Passing a negative [F32] or [F64] returns [NaN](#isNaN). +## * Passing [NaN](#isNaN) or [-Infinity](isNegativeInfinity) also returns [NaN](#isNaN). +## * Passing [Infinity](isPositiveInfinity) returns [Infinity]. +## +## > These rules come from the [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754) +## > floating point standard. Since almost all modern processors are built to +## > this standard, deviating from these rules has a significant performance +## > cost. Since the most common reason to choose [F32] or [F64] over [Dec] is +## > access to hardware-accelerated performance, Roc follows these rules exactly. +## +## >>> Frac.sqrt 4.0 +## +## >>> Frac.sqrt 1.5 +## +## >>> Frac.sqrt 0.0 +## +## >>> Frac.sqrt -4.0f64 +## +## >>> Frac.sqrt -4.0dec +sqrt : Frac a -> Frac a -## NOTE: Need to come up a suffix alternative to the "try" prefix. -## This should be like (for example) recipTry so that it's more discoverable -## in documentation and editor autocomplete when you type "recip" -tryRecip : Float a -> Result (Float a) [ DivByZero ]* - -## Return an approximation of the absolute value of the square root of the #Float. +## Return an approximation of the absolute value of the square root of the #Frac, +## or a poison number if given a negative or poison number. ## -## Return #InvalidSqrt if given a negative number or an invalid #Float. The square root of a negative number is an irrational number, and #Float only supports rational numbers. +## (The square root of a negative number is an irrational number, and [Frac] +## only supports rational numbers.) ## -## >>> Float.sqrt 4.0 +## >>> Frac.sqrt 4.0 ## -## >>> Float.sqrt 1.5 +## >>> Frac.sqrt 1.5 ## -## >>> Float.sqrt 0.0 +## >>> Frac.sqrt 0.0 ## -## >>> Float.sqrt -4.0 -sqrt : Float a -> [Ok (Float a), InvalidSqrt]* +## >>> Frac.sqrt -4.0 +sqrtOrPoison : Frac a -> [Ok (Frac a), InvalidSqrt]* ## [Endianness](https://en.wikipedia.org/wiki/Endianness) From b08c70985aa128d3eca49a18b2e2bc17342547c4 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Fri, 4 Jun 2021 00:41:24 -0400 Subject: [PATCH 08/52] Remove poison. --- compiler/builtins/docs/Num.roc | 28 +--------------------------- 1 file changed, 1 insertion(+), 27 deletions(-) diff --git a/compiler/builtins/docs/Num.roc b/compiler/builtins/docs/Num.roc index 4c14a50b4e..3051260728 100644 --- a/compiler/builtins/docs/Num.roc +++ b/compiler/builtins/docs/Num.roc @@ -981,22 +981,6 @@ expBySquaring : Int a, U8 -> Int a ## >>> Frac.sqrt -4.0dec sqrt : Frac a -> Frac a -## Return an approximation of the absolute value of the square root of the #Frac, -## or a poison number if given a negative or poison number. -## -## (The square root of a negative number is an irrational number, and [Frac] -## only supports rational numbers.) -## -## >>> Frac.sqrt 4.0 -## -## >>> Frac.sqrt 1.5 -## -## >>> Frac.sqrt 0.0 -## -## >>> Frac.sqrt -4.0 -sqrtOrPoison : Frac a -> [Ok (Frac a), InvalidSqrt]* - - ## [Endianness](https://en.wikipedia.org/wiki/Endianness) Endi : [ Big, Little ] @@ -1011,7 +995,7 @@ toBytes : Num *, Endi -> List U8 ## ## >>> Num.isNaN (Num.sqrtOrNaN -2) ## -## See also [isPoison] and [isFinite]. +## See also [isFinite]. isNaN : Frac * -> Bool ## When given a [F64] or [F32] value, returns `False` if that value is @@ -1019,19 +1003,9 @@ isNaN : Frac * -> Bool ## ## Always returns `True` when given a [Dec]. ## -## [isPoison] returns the opposite of this. -## ## See also [isInfinite]. isFinite : Frac * -> Bool -## When given a [F64] or [F32] value, returns `True` if that value is -## [*NaN*](https://en.wikipedia.org/wiki/NaN), *Infinity*, or *-Infinity*. -## -## Always returns `False` when given a [Dec]. -## -## [isFinite] returns the opposite of this. -isPoison : Frac * -> Bool - ## When given a [F64] or [F32] value, returns `True` if that value is either ## *Infinity* or *-Infinity*. (Returns `False` if that value is [*NaN*](https://en.wikipedia.org/wiki/NaN).) ## From db4ce6aef3bf748f0a7eca340991e33fed41051c Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Fri, 4 Jun 2021 00:41:37 -0400 Subject: [PATCH 09/52] Revise some more Num docs. --- compiler/builtins/docs/Num.roc | 58 ++++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 23 deletions(-) diff --git a/compiler/builtins/docs/Num.roc b/compiler/builtins/docs/Num.roc index 3051260728..bd19527f59 100644 --- a/compiler/builtins/docs/Num.roc +++ b/compiler/builtins/docs/Num.roc @@ -9,13 +9,24 @@ interface Num2 ## This is useful for functions that can work on either, for example #Num.add, whose type is: ## ## ``` -## add : Num range, Num range -> Num range +## add : Num a, Num a -> Num a ## ``` ## -## The number 1.5 technically has the type `Num Fraction`, so when you pass two of them to `Num.add`, the answer you get is `3.0 : Num Fraction`. +## The number 1.5 technically has the type `Num (Fraction *)`, so when you pass +## two of them to [Num.add], the answer you get is `3.0 : Num (Fraction *)`. +# +## Similarly, the number 0x1 (that is, the integer 1 in hexadecimal notation) +## technically has the type `Num (Integer *)`, so when you pass two of them to +## [Num.add], the answer you get is `2 : Num (Integer *)`. ## -## The type #Frac is defined to be an alias for `Num Fraction`, so `3.0 : Num Fraction` is the same answer as `3.0 : Frac`. # # Similarly, the number 1 technically has the type `Num Integer`, so when you pass two of them to `Num.add`, the answer you get is `2 : Num Integer`. # # The type #Int is defined to be an alias for `Num Integer`, so `2 : Num Integer` is the same answer as `2 : Int`. # -## In this way, the `Num` type makes it possible to have `1 + 1` return `2 : Int` and `1.5 + 1.5` return `3.0 : Frac`. +## The type [`Frac a`](#Frac) is defined to be an alias for `Num (Fraction a)`, +## so `3.0 : Num (Fraction *)` is the same value as `3.0 : Frac *`. +## Similarly, the type [`Int a`](#Int) is defined to be an alias for +## `Num (Integer a)`, so `2 : Num (Integer *)` is the same value as +## `2 : Int *`. +## +## In this way, the [Num] type makes it possible to have `1 + 0x1` return +## `2 : Int *` and `1.5 + 1.5` return `3.0 : Frac`. ## ## ## Number Literals ## @@ -29,29 +40,30 @@ interface Num2 ## ends up having the type `Nat`. ## ## Sometimes number literals don't become more specific. For example, -## the #Num.toStr function has the type `Num * -> Str`. This means that +## the [Num.toStr] function has the type `Num * -> Str`. This means that ## when calling `Num.toStr (5 + 6)`, the expression `(5 + 6)` ## still has the type `Num *`. When this happens, `Num *` defaults to -## being an #I32 - so this addition expression would overflow +## being an [I64] - so this addition expression would overflow ## if either 5 or 6 were replaced with a number big enough to cause -## addition overflow on an #I32. +## addition overflow on an [I64] value. ## -## If this default of #I32 is not big enough for your purposes, -## you can add an `i64` to the end of the number literal, like so: +## If this default of [I64] is not big enough for your purposes, +## you can add an `i128` to the end of the number literal, like so: ## -## >>> Num.toStr 5_000_000_000i64 +## >>> Num.toStr 5_000_000_000i128 ## -## This `i64` suffix specifies that you want this number literal to be -## an #I64 instead of a `Num *`. All the other numeric types have -## suffixes just like `i64`; here are some other examples: +## This `i128` suffix specifies that you want this number literal to be +## an [I128] instead of a `Num *`. All the other numeric types have +## suffixes just like `i128`; here are some other examples: ## -## * `215u8` is a `215` value of type #U8 -## * `76.4f32` is a `76.4` value of type #F32 -## * `12345ulen` is a `12345` value of type #Nat +## * `215u8` is a `215` value of type [U8] +## * `76.4f32` is a `76.4` value of type [F32] +## * `123.45dec` is a `123.45` value of type [Dec] +## * `12345nat` is a `12345` value of type [Nat] ## ## In practice, these are rarely needed. It's most common to write ## number literals without any suffix. -Num range : [ @Num range ] +Num a : [ @Num a ] ## A decimal number. ## @@ -435,7 +447,7 @@ Int size : Num [ @Int size ] ## Additionally, calling #Num.neg on any unsigned integer (such as any #U64 or #U32 value) other than 0 will cause overflow. ## ## (It will never crash when given a #Frac, however, because of how floating point numbers represent positive and negative numbers.) -neg : Num range -> Num range +neg : Num a -> Num a ## Return the absolute value of the number. ## @@ -458,7 +470,7 @@ neg : Num range -> Num range ## the highest value it can represent. (For this reason, calling #Num.neg on the lowest signed value will also cause overflow.) ## ## Calling this on an unsigned integer (like #U32 or #U64) never does anything. -abs : Num range -> Num range +abs : Num a -> Num a ## Check @@ -497,7 +509,7 @@ isOdd : Num * -> Bool ## ## >>> Frac.pi ## >>> |> Num.add 1.0 -add : Num range, Num range -> Num range +add : Num a, Num a -> Num a ## Subtract two numbers of the same type. ## @@ -513,7 +525,7 @@ add : Num range, Num range -> Num range ## ## >>> Frac.pi ## >>> |> Num.sub 2.0 -sub : Num range, Num range -> Num range +sub : Num a, Num a -> Num a ## Multiply two numbers of the same type. ## @@ -529,7 +541,7 @@ sub : Num range, Num range -> Num range ## ## >>> Frac.pi ## >>> |> Num.mul 2.0 -mul : Num range, Num range -> Num range +mul : Num a, Num a -> Num a ## Convert @@ -953,7 +965,7 @@ pow : Frac a, Frac a -> Frac a ## overflow expBySquaring : Int a, U8 -> Int a -## Returns an approximation of the absolute value of the square root of the [Frac]. +## Returns an approximation of the absolute value of a [Frac]'s square root. ## ## The square root of a negative number is an irrational number, and [Frac] only ## supports rational numbers. As such, you should make sure never to pass this From 87f994039b675e55776c9eeebaaf87d87f0a2727 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Fri, 4 Jun 2021 00:43:23 -0400 Subject: [PATCH 10/52] Drop Num.hash64 --- compiler/builtins/docs/Num.roc | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/compiler/builtins/docs/Num.roc b/compiler/builtins/docs/Num.roc index bd19527f59..9f1aca4861 100644 --- a/compiler/builtins/docs/Num.roc +++ b/compiler/builtins/docs/Num.roc @@ -742,18 +742,6 @@ asc : Num a, Num a -> [ Eq, Lt, Gt ] ## desc : Num a, Num a -> [ Eq, Lt, Gt ] -## TODO should we offer hash32 etc even if someday it has to do a hash64 and truncate? -## -## This function can crash under these circumstances: -## -## * It receives a function, or any type that contains a function (for example a record, tag, or #List containing a function) -## * It receives an erroneous #Frac (`NaN`, `Infinity`, or `-Infinity` - these values can only originate from hosts) -## -## CAUTION: This function may give different answers in future releases of Roc, -## so be aware that if you rely on the exact answer this gives today, your -## code may break in a future Roc release. -hash64 : a -> U64 - ## Limits ## The highest number that can be stored in a #Nat without overflowing its From 3b1142feb8d39953e97d6d8e54cee68175a1ab71 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Fri, 4 Jun 2021 00:45:37 -0400 Subject: [PATCH 11/52] Fix some duplicate and missing Num docs --- compiler/builtins/docs/Num.roc | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/compiler/builtins/docs/Num.roc b/compiler/builtins/docs/Num.roc index 9f1aca4861..102ac26212 100644 --- a/compiler/builtins/docs/Num.roc +++ b/compiler/builtins/docs/Num.roc @@ -840,31 +840,20 @@ e : Frac * ## An approximation of pi, specifically 3.141592653589793. pi : Frac * -## Constants - -## An approximation of e, specifically 2.718281828459045. -e : Frac * - -## An approximation of pi, specifically 3.141592653589793. -pi : Frac * - -#ceiling : Frac -> Int - -#floor : Frac -> Int ## Trigonometry -#cos : Frac -> Frac +cos : Frac a -> Frac a -#acos : Frac -> Frac +acos : Frac a -> Frac a -#sin : Frac -> Frac +sin : Frac a -> Frac a -#asin : Frac -> Frac +asin : Frac a -> Frac a -#tan : Frac -> Frac +tan : Frac a -> Frac a -#atan : Frac -> Frac +atan : Frac a -> Frac a ## Other Calculations (arithmetic?) From 253f7fed4fdff92783f5264b6182d5b9cccfda56 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Fri, 4 Jun 2021 00:55:17 -0400 Subject: [PATCH 12/52] Add some Nat docs. --- compiler/builtins/docs/Num.roc | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/compiler/builtins/docs/Num.roc b/compiler/builtins/docs/Num.roc index 102ac26212..5426a36ef0 100644 --- a/compiler/builtins/docs/Num.roc +++ b/compiler/builtins/docs/Num.roc @@ -206,6 +206,17 @@ I64 : Int [ @Signed64 ] U64 : Int [ @Unsigned64 ] I128 : Int [ @Signed128 ] U128 : Int [ @Unsigned128 ] + +## A [natural number](https://en.wikipedia.org/wiki/Natural_number) represented +## as a 64-bit unsigned integer on 64-bit systems, a 32-bit unsigned integer +## on 32-bit systems, and so on. +## +## This system-specific size makes it useful for certain data structure +## functions like [List.len], because the number of elements many data strucures +## can hold is also system-specific. For example, the maximum number of elements +## a [List] can hold on a 64-bit system fits in a 64-bit unsigned integer, and +## on a 32-bit system it fits in 32-bit unsigned integer. This makes [Nat] a +## good fit for [List.len] regardless of system. Nat : Int [ @Natural ] ## A 64-bit signed integer. All number literals without decimal points are compatible with #Int values. From 23831e4be12f4a8386c6f6528f34ada29ebd92f3 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Fri, 4 Jun 2021 07:55:21 -0400 Subject: [PATCH 13/52] s/runtime error/panic in docs --- compiler/builtins/docs/Num.roc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/builtins/docs/Num.roc b/compiler/builtins/docs/Num.roc index 5426a36ef0..a7545a73e2 100644 --- a/compiler/builtins/docs/Num.roc +++ b/compiler/builtins/docs/Num.roc @@ -874,7 +874,7 @@ atan : Frac a -> Frac a ## ## [Division by zero is undefined in mathematics](https://en.wikipedia.org/wiki/Division_by_zero). ## As such, you should make sure never to pass zero as the denomaintor to this function! -## Calling [div] on a [Dec] denominator of 0 will cause a runtime error. +## Calling [div] on a [Dec] denominator of 0 will cause a panic. ## ## Calling [div] on [F32] and [F64] values follows these rules: ## * Dividing a positive [F32] or [F64] by zero returns [Infinity](#isPositiveInfinity). @@ -911,7 +911,7 @@ div : Frac a, Frac a -> Frac a ## and as such, so is modulo by zero. Because of this, you should make sure never ## to pass zero for the second argument to this function! ## -## Passing [mod] a [Dec] value of 0 for its second argument will cause a runtime error. +## Passing [mod] a [Dec] value of 0 for its second argument will cause a panic. ## Passing [mod] a [F32] and [F64] value for its second argument will cause it ## to return [NaN](#isNaN). ## @@ -957,7 +957,7 @@ expBySquaring : Int a, U8 -> Int a ## ## The square root of a negative number is an irrational number, and [Frac] only ## supports rational numbers. As such, you should make sure never to pass this -## function a negative number! Calling [sqrt] on a negative [Dec] will cause a runtime error. +## function a negative number! Calling [sqrt] on a negative [Dec] will cause a panic. ## ## Calling [sqrt] on [F32] and [F64] values follows these rules: ## * Passing a negative [F32] or [F64] returns [NaN](#isNaN). From 7e2afa949e425a62385e5f27efe02363813a2dd2 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Fri, 4 Jun 2021 07:55:35 -0400 Subject: [PATCH 14/52] Document Dict.insert and Set.add panicking on NaN --- compiler/builtins/docs/Dict.roc | 10 ++++++++++ compiler/builtins/docs/Set.roc | 1 + 2 files changed, 11 insertions(+) diff --git a/compiler/builtins/docs/Dict.roc b/compiler/builtins/docs/Dict.roc index 9486764194..178e5329ee 100644 --- a/compiler/builtins/docs/Dict.roc +++ b/compiler/builtins/docs/Dict.roc @@ -19,3 +19,13 @@ map : Dict beforeKey beforeValue, ({ key: beforeKey, value: beforeValue } -> { key: afterKey, value: afterValue }) -> Dict afterKey afterValue + +# DESIGN NOTES: The reason for panicking when given NaN is that: +# * If we allowed NaN in, Dict.insert would no longer be idempotent. +# * If we allowed NaN but overrode its semantics to make it feel like "NaN == NaN" we'd need isNaN checks in all hashing operations as well as all equality checks (during collision detection), not just insert. This would be much worse for performance than panicking on insert, which only requires one extra conditional on insert. +# * It's obviously invalid; the whole point of NaN is that an error occurred. Giving a runtime error notifies you when this problem happens. Giving it only on insert is the best for performance, because it means you aren't paying for isNaN checks on lookups as well. + +# TODO: removed `'` from signature because parser does not support it yet +# Original signature: insert : Dict 'key val, 'key, val -> Dict 'key val +## Since NaN is defined to be unequal to NaN, panics if given NaN for a key. +insert : Dict key val, key, val -> Dict key val diff --git a/compiler/builtins/docs/Set.roc b/compiler/builtins/docs/Set.roc index bc5211b407..2a6d70cc63 100644 --- a/compiler/builtins/docs/Set.roc +++ b/compiler/builtins/docs/Set.roc @@ -18,6 +18,7 @@ len : Set * -> Nat # TODO: removed `'` from signature because parser does not support it yet # Original signature: `add : Set 'elem, 'elem -> Set 'elem` +## Since NaN is defined to be unequal to NaN, panics if given NaN. add : Set elem, elem -> Set elem ## Drops the given element from the set. From 4d65cbf18317fe1215cb69c0cc8fbf8fed9b954b Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Fri, 4 Jun 2021 08:10:08 -0400 Subject: [PATCH 15/52] Clarify overflow semantics for add/sub/mul --- compiler/builtins/docs/Num.roc | 39 ++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/compiler/builtins/docs/Num.roc b/compiler/builtins/docs/Num.roc index a7545a73e2..0e41ec74a1 100644 --- a/compiler/builtins/docs/Num.roc +++ b/compiler/builtins/docs/Num.roc @@ -520,8 +520,21 @@ isOdd : Num * -> Bool ## ## >>> Frac.pi ## >>> |> Num.add 1.0 +## +## If the answer to this operation can't fit in the return value (e.g. an +## [I8] answer that's higher than 127 or lower than -128), the result is an +## *overflow*. For [F64] and [F32], overflow results in an answer of either +## [*Infinity*](#isPositiveInfinity) or [*-Infinity*](#isNegativeInfinity). For +## all other number types, overflow results in a panic. add : Num a, Num a -> Num a +## Add two numbers and check for overflow. +## +## This is the same as [Num.add] except if the operation overflows, instead of +## panicking or returning [*Infinity*](#isPositiveInfinity) or [*-Infinity*](#isNegativeInfinity), +## it will return `Err Overflow`. +addCheckOverflow : Num a, Num a -> Result (Num a) [ Overflow ]* + ## Subtract two numbers of the same type. ## ## (To subtract an #Int and a #Frac, first convert one so that they both have the same type. There are functions in the [`Frac`](/Frac) module that can convert both #Int to #Frac and the other way around.) @@ -536,8 +549,21 @@ add : Num a, Num a -> Num a ## ## >>> Frac.pi ## >>> |> Num.sub 2.0 +## +## If the answer to this operation can't fit in the return value (e.g. an +## [I8] answer that's higher than 127 or lower than -128), the result is an +## *overflow*. For [F64] and [F32], overflow results in an answer of either +## [*Infinity*](#isPositiveInfinity) or [*-Infinity*](#isNegativeInfinity). For +## all other number types, overflow results in a panic. sub : Num a, Num a -> Num a +## Subtract two numbers and check for overflow. +## +## This is the same as [Num.sub] except if the operation overflows, instead of +## panicking or returning [*Infinity*](#isPositiveInfinity) or [*-Infinity*](#isNegativeInfinity), +## it will return `Err Overflow`. +subCheckOverflow : Num a, Num a -> Result (Num a) [ Overflow ]* + ## Multiply two numbers of the same type. ## ## (To multiply an #Int and a #Frac, first convert one so that they both have the same type. There are functions in the [`Frac`](/Frac) module that can convert both #Int to #Frac and the other way around.) @@ -552,8 +578,21 @@ sub : Num a, Num a -> Num a ## ## >>> Frac.pi ## >>> |> Num.mul 2.0 +## +## If the answer to this operation can't fit in the return value (e.g. an +## [I8] answer that's higher than 127 or lower than -128), the result is an +## *overflow*. For [F64] and [F32], overflow results in an answer of either +## [*Infinity*](#isPositiveInfinity) or [*-Infinity*](#isNegativeInfinity). For +## all other number types, overflow results in a panic. mul : Num a, Num a -> Num a +## Multiply two numbers and check for overflow. +## +## This is the same as [Num.mul] except if the operation overflows, instead of +## panicking or returning [*Infinity*](#isPositiveInfinity) or [*-Infinity*](#isNegativeInfinity), +## it will return `Err Overflow`. +mulCheckOverflow : Num a, Num a -> Result (Num a) [ Overflow ]* + ## Convert ## Convert a number to a [Str]. From 4e9b11afd46b15fa6f36b126ee26ea2a809cfae0 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Fri, 4 Jun 2021 08:18:26 -0400 Subject: [PATCH 16/52] s/0/zero --- compiler/builtins/docs/Num.roc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/builtins/docs/Num.roc b/compiler/builtins/docs/Num.roc index 0e41ec74a1..ae5842c339 100644 --- a/compiler/builtins/docs/Num.roc +++ b/compiler/builtins/docs/Num.roc @@ -455,7 +455,7 @@ Int size : Num [ @Int size ] ## This is because, for any given size of signed integer (32-bit, 64-bit, etc.) its negated lowest value turns out to be 1 higher than ## the highest value it can represent. (For this reason, calling #Num.abs on the lowest signed value will also cause overflow.) ## -## Additionally, calling #Num.neg on any unsigned integer (such as any #U64 or #U32 value) other than 0 will cause overflow. +## Additionally, calling #Num.neg on any unsigned integer (such as any #U64 or #U32 value) other than zero will cause overflow. ## ## (It will never crash when given a #Frac, however, because of how floating point numbers represent positive and negative numbers.) neg : Num a -> Num a @@ -913,7 +913,7 @@ atan : Frac a -> Frac a ## ## [Division by zero is undefined in mathematics](https://en.wikipedia.org/wiki/Division_by_zero). ## As such, you should make sure never to pass zero as the denomaintor to this function! -## Calling [div] on a [Dec] denominator of 0 will cause a panic. +## Calling [div] on a [Dec] denominator of zero will cause a panic. ## ## Calling [div] on [F32] and [F64] values follows these rules: ## * Dividing a positive [F32] or [F64] by zero returns [Infinity](#isPositiveInfinity). @@ -950,7 +950,7 @@ div : Frac a, Frac a -> Frac a ## and as such, so is modulo by zero. Because of this, you should make sure never ## to pass zero for the second argument to this function! ## -## Passing [mod] a [Dec] value of 0 for its second argument will cause a panic. +## Passing [mod] a [Dec] value of zero for its second argument will cause a panic. ## Passing [mod] a [F32] and [F64] value for its second argument will cause it ## to return [NaN](#isNaN). ## From 960a4fddc5f070efc3100df3e0f1514548b128b1 Mon Sep 17 00:00:00 2001 From: Anton-4 <17049058+Anton-4@users.noreply.github.com> Date: Fri, 4 Jun 2021 19:23:44 +0200 Subject: [PATCH 17/52] added quicksort benchmark --- cli/benches/time_bench.rs | 14 +++++++------- cli/cli_utils/src/bench_utils.rs | 10 +++++++++- cli/tests/cli_run.rs | 27 +++++++++++++++------------ examples/benchmarks/Quicksort.roc | 2 +- examples/benchmarks/QuicksortApp.roc | 23 +++++++++++++++++++++++ 5 files changed, 55 insertions(+), 21 deletions(-) create mode 100644 examples/benchmarks/QuicksortApp.roc diff --git a/cli/benches/time_bench.rs b/cli/benches/time_bench.rs index 3923d83eb4..4944067555 100644 --- a/cli/benches/time_bench.rs +++ b/cli/benches/time_bench.rs @@ -1,5 +1,5 @@ use cli_utils::bench_utils::{ - bench_cfold, bench_deriv, bench_nqueens, bench_rbtree_ck, bench_rbtree_delete, + bench_cfold, bench_deriv, bench_nqueens, bench_quicksort, bench_rbtree_ck, bench_rbtree_delete, }; use criterion::{ criterion_group, criterion_main, measurement::WallTime, BenchmarkGroup, Criterion, SamplingMode, @@ -7,17 +7,17 @@ use criterion::{ fn bench_group_wall_time(c: &mut Criterion) { let mut group = c.benchmark_group("bench-group_wall-time"); - // calculate statistics based on a fixed(flat) 100 runs + // calculate statistics based on a fixed(flat) 200 runs group.sampling_mode(SamplingMode::Flat); group.sample_size(200); let bench_funcs: Vec>) -> ()> = vec![ - bench_nqueens, // queens 11 - bench_cfold, // e = mkExpr 12 1 - bench_deriv, // nest deriv 7 f - bench_rbtree_ck, // ms = makeMap 5 5600 + bench_nqueens, // queens 11 + bench_cfold, // e = mkExpr 12 1 + bench_deriv, // nest deriv 7 f + bench_rbtree_ck, // ms = makeMap 5 5600 bench_rbtree_delete, // m = makeMap 6000 - // TODO quicksort + bench_quicksort, // list size 2000 ]; for bench_func in bench_funcs.iter() { diff --git a/cli/cli_utils/src/bench_utils.rs b/cli/cli_utils/src/bench_utils.rs index a1cae5e257..03109ebb21 100644 --- a/cli/cli_utils/src/bench_utils.rs +++ b/cli/cli_utils/src/bench_utils.rs @@ -124,4 +124,12 @@ pub fn bench_rbtree_delete(bench_group_opt: Option<&mut Benchmar ); } -// TODO quicksort +pub fn bench_quicksort(bench_group_opt: Option<&mut BenchmarkGroup>) { + exec_bench_w_input( + &example_file("benchmarks", "QuicksortApp.roc"), + "1", // 1 for sorting large list, 0 for a small list + "quicksortapp", + "[ 0, 0, 0, 1, 2, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 13, 13, 14, 14, 16, 16, 16, 17, 17, 17, 18, 19, 20, 22, 22, 23, 24, 24, 24, 24, 25, 26, 26, 26, 26, 27, 27, 29, 29, 30, 30, 30, 30, 31, 31, 31, 31, 32, 32, 32, 33, 33, 33, 33, 34, 35, 35, 35, 35, 36, 36, 36, 37, 38, 39, 40, 41, 42, 43, 43, 43, 44, 44, 44, 47, 47, 47, 48, 49, 49, 49, 49, 51, 51, 52, 52, 53, 53, 54, 54, 54, 54, 55, 56, 56, 57, 58, 59, 59, 60, 62, 63, 63, 64, 65, 65, 66, 66, 66, 67, 67, 67, 68, 68, 69, 69, 70, 70, 72, 72, 72, 72, 72, 72, 73, 73, 73, 74, 74, 74, 76, 77, 77, 77, 78, 78, 78, 79, 79, 79, 80, 80, 80, 81, 81, 82, 82, 83, 83, 83, 83, 84, 85, 86, 86, 88, 88, 88, 88, 88, 89, 89, 90, 90, 91, 91, 92, 92, 93, 93, 94, 95, 95, 96, 96, 96, 98, 98, 99, 100, 101, 101, 102, 104, 105, 105, 106, 106, 107, 107, 108, 109, 112, 112, 113, 113, 113, 113, 113, 113, 115, 116, 116, 117, 118, 121, 122, 122, 122, 123, 123, 123, 123, 123, 124, 124, 125, 125, 126, 126, 126, 126, 127, 127, 128, 129, 130, 130, 130, 131, 131, 132, 132, 132, 133, 133, 135, 135, 135, 135, 136, 136, 137, 137, 139, 139, 139, 139, 141, 142, 144, 145, 146, 146, 146, 146, 146, 147, 147, 148, 148, 148, 148, 148, 148, 149, 149, 149, 150, 151, 151, 152, 152, 152, 153, 153, 153, 153, 154, 155, 155, 155, 156, 159, 159, 159, 160, 160, 160, 161, 161, 161, 162, 162, 162, 162, 165, 166, 166, 166, 167, 167, 167, 168, 168, 168, 169, 170, 170, 172, 172, 172, 172, 174, 174, 175, 176, 177, 178, 178, 178, 179, 180, 180, 180, 180, 180, 181, 182, 183, 183, 183, 184, 184, 185, 185, 186, 186, 187, 187, 187, 188, 188, 189, 189, 189, 189, 190, 190, 191, 191, 192, 193, 193, 193, 193, 193, 193, 194, 194, 195, 195, 195, 195, 195, 196, 197, 198, 198, 199, 199, 199, 199, 200, 201, 202, 202, 202, 202, 203, 204, 204, 205, 205, 205, 206, 206, 206, 207, 208, 209, 210, 210, 210, 210, 211, 211, 211, 211, 212, 212, 212, 212, 213, 213, 213, 213, 214, 214, 214, 215, 215, 215, 216, 216, 216, 216, 217, 217, 218, 218, 219, 220, 220, 220, 221, 221, 222, 222, 222, 222, 223, 223, 223, 225, 225, 225, 226, 227, 227, 228, 228, 229, 229, 229, 229, 231, 231, 233, 234, 234, 234, 234, 234, 234, 235, 235, 235, 235, 236, 236, 237, 238, 238, 238, 238, 238, 239, 239, 240, 240, 241, 241, 241, 241, 241, 242, 243, 243, 243, 244, 247, 248, 248, 248, 249, 249, 249, 250, 250, 250, 251, 252, 252, 254, 254, 254, 254, 254, 255, 255, 256, 257, 258, 259, 260, 261, 262, 262, 262, 262, 262, 263, 264, 264, 264, 265, 265, 266, 266, 266, 267, 269, 269, 269, 270, 270, 271, 271, 272, 273, 274, 274, 275, 275, 275, 276, 277, 277, 277, 278, 278, 279, 279, 281, 282, 282, 286, 287, 287, 287, 287, 287, 288, 288, 288, 288, 288, 288, 289, 289, 290, 290, 290, 291, 291, 292, 292, 292, 293, 293, 293, 293, 293, 293, 293, 294, 294, 294, 294, 295, 296, 296, 297, 297, 298, 298, 300, 300, 301, 301, 301, 301, 301, 302, 303, 303, 303, 304, 304, 304, 305, 305, 305, 306, 306, 308, 308, 309, 309, 310, 311, 312, 312, 312, 312, 313, 313, 313, 314, 314, 315, 316, 316, 317, 317, 318, 318, 318, 318, 319, 319, 320, 322, 322, 323, 323, 324, 324, 325, 325, 326, 328, 329, 329, 329, 330, 330, 330, 332, 332, 332, 333, 333, 333, 333, 334, 334, 334, 334, 335, 335, 335, 335, 335, 335, 336, 336, 337, 337, 338, 338, 338, 339, 339, 340, 341, 342, 342, 343, 343, 344, 344, 345, 345, 345, 346, 346, 348, 349, 349, 349, 349, 350, 350, 350, 351, 351, 351, 352, 352, 352, 352, 353, 353, 353, 353, 355, 355, 355, 355, 355, 356, 357, 357, 357, 358, 358, 359, 359, 359, 360, 360, 361, 361, 361, 362, 362, 363, 364, 365, 365, 367, 367, 368, 368, 369, 369, 369, 369, 369, 371, 371, 371, 371, 372, 372, 373, 373, 373, 374, 374, 375, 375, 376, 376, 376, 377, 377, 378, 378, 378, 378, 378, 378, 379, 379, 381, 381, 381, 382, 383, 383, 384, 384, 385, 385, 385, 386, 386, 386, 386, 387, 387, 388, 388, 388, 389, 389, 389, 390, 390, 390, 391, 391, 392, 392, 393, 393, 394, 394, 394, 394, 394, 395, 396, 397, 397, 397, 398, 399, 399, 400, 400, 400, 400, 401, 401, 401, 401, 402, 402, 402, 402, 402, 402, 403, 404, 404, 404, 404, 405, 405, 405, 405, 407, 409, 409, 410, 410, 410, 410, 410, 413, 414, 414, 416, 417, 417, 417, 418, 418, 418, 419, 419, 419, 420, 420, 420, 421, 422, 422, 425, 426, 426, 427, 427, 427, 428, 428, 428, 429, 430, 431, 433, 433, 433, 435, 435, 436, 436, 436, 437, 438, 438, 438, 439, 439, 439, 441, 442, 443, 443, 443, 443, 444, 444, 444, 445, 445, 447, 447, 447, 448, 448, 449, 450, 450, 450, 450, 451, 451, 451, 451, 452, 452, 452, 452, 453, 453, 454, 454, 454, 454, 455, 455, 455, 456, 456, 457, 457, 457, 457, 458, 459, 460, 460, 461, 461, 462, 462, 464, 464, 464, 465, 467, 467, 468, 469, 469, 469, 469, 471, 471, 472, 472, 473, 474, 474, 474, 475, 475, 476, 476, 477, 477, 479, 479, 480, 481, 481, 482, 483, 484, 484, 485, 485, 486, 486, 487, 487, 487, 487, 488, 489, 489, 489, 489, 490, 490, 490, 491, 493, 493, 493, 494, 494, 495, 495, 495, 495, 497, 497, 499, 499, 500, 500, 501, 501, 502, 502, 502, 503, 505, 505, 506, 506, 507, 508, 508, 508, 508, 510, 510, 511, 511, 512, 512, 513, 514, 514, 515, 516, 516, 516, 516, 517, 517, 517, 518, 518, 519, 521, 522, 522, 523, 523, 523, 523, 523, 525, 526, 526, 526, 527, 527, 528, 529, 530, 530, 531, 531, 532, 532, 532, 532, 533, 533, 533, 533, 533, 534, 534, 535, 535, 537, 539, 539, 540, 541, 542, 542, 543, 544, 547, 547, 547, 547, 547, 547, 548, 549, 550, 551, 551, 551, 552, 552, 555, 557, 558, 558, 558, 558, 559, 559, 560, 560, 561, 561, 562, 563, 563, 563, 563, 563, 564, 566, 566, 566, 567, 567, 567, 568, 568, 568, 569, 569, 571, 572, 573, 573, 574, 574, 575, 577, 578, 578, 580, 581, 582, 582, 582, 582, 583, 583, 585, 587, 587, 587, 588, 588, 589, 589, 590, 590, 590, 590, 591, 591, 591, 592, 593, 593, 595, 596, 597, 597, 598, 598, 599, 599, 600, 600, 600, 602, 602, 602, 603, 604, 605, 605, 606, 606, 606, 608, 608, 608, 608, 609, 610, 610, 610, 610, 611, 611, 612, 612, 613, 613, 614, 614, 614, 616, 616, 616, 617, 617, 617, 618, 618, 618, 618, 618, 618, 618, 619, 619, 619, 619, 619, 619, 619, 620, 620, 621, 621, 621, 624, 624, 624, 624, 625, 625, 625, 625, 626, 628, 628, 628, 630, 630, 630, 631, 631, 631, 632, 632, 632, 633, 635, 635, 635, 636, 637, 637, 638, 638, 638, 639, 639, 639, 640, 642, 643, 644, 645, 646, 646, 650, 650, 651, 651, 651, 653, 654, 654, 654, 655, 655, 656, 656, 657, 658, 659, 659, 661, 661, 661, 662, 662, 663, 663, 663, 663, 664, 665, 665, 665, 665, 666, 666, 667, 668, 668, 669, 669, 669, 670, 670, 672, 672, 672, 672, 672, 673, 674, 674, 675, 675, 676, 676, 676, 677, 677, 677, 678, 678, 679, 679, 679, 679, 679, 680, 680, 682, 683, 683, 684, 684, 685, 685, 685, 686, 687, 687, 687, 687, 687, 687, 688, 689, 689, 689, 691, 691, 692, 692, 693, 693, 696, 697, 697, 698, 698, 698, 698, 698, 699, 699, 700, 700, 700, 700, 703, 704, 704, 704, 704, 704, 705, 705, 705, 706, 706, 707, 707, 707, 708, 708, 708, 710, 711, 711, 711, 711, 712, 712, 713, 713, 713, 713, 713, 713, 713, 714, 714, 714, 715, 716, 717, 717, 717, 718, 718, 718, 719, 719, 719, 719, 719, 719, 720, 720, 720, 721, 721, 723, 723, 723, 724, 724, 725, 726, 727, 727, 727, 727, 728, 729, 729, 730, 730, 730, 730, 731, 732, 733, 734, 734, 734, 735, 735, 736, 736, 736, 736, 737, 737, 738, 739, 739, 739, 740, 743, 743, 743, 743, 743, 744, 744, 745, 745, 746, 746, 746, 747, 747, 748, 749, 750, 750, 751, 751, 751, 752, 752, 753, 753, 753, 753, 753, 753, 754, 754, 756, 757, 757, 758, 758, 758, 759, 759, 760, 760, 760, 761, 762, 762, 762, 763, 763, 766, 768, 768, 768, 768, 768, 769, 769, 772, 773, 773, 774, 775, 775, 776, 776, 776, 776, 776, 777, 777, 777, 778, 779, 779, 779, 780, 780, 780, 781, 782, 782, 782, 783, 783, 783, 783, 784, 785, 785, 785, 785, 786, 786, 786, 786, 786, 787, 788, 789, 789, 789, 790, 790, 791, 791, 791, 792, 792, 792, 792, 793, 793, 794, 794, 797, 797, 798, 798, 799, 799, 799, 800, 801, 801, 802, 803, 804, 804, 805, 805, 805, 805, 807, 807, 807, 807, 808, 808, 808, 808, 809, 809, 810, 810, 811, 811, 812, 813, 814, 815, 816, 816, 817, 818, 819, 819, 820, 820, 820, 822, 822, 823, 823, 823, 823, 826, 826, 827, 827, 829, 830, 830, 831, 831, 832, 832, 832, 833, 833, 833, 834, 834, 835, 835, 835, 836, 836, 837, 837, 838, 838, 839, 840, 840, 841, 841, 842, 842, 843, 844, 844, 845, 846, 846, 847, 847, 848, 849, 849, 851, 851, 851, 851, 852, 853, 853, 853, 854, 854, 854, 855, 856, 856, 857, 857, 858, 859, 859, 859, 860, 860, 860, 860, 860, 861, 861, 861, 861, 862, 862, 864, 865, 865, 865, 866, 866, 866, 866, 867, 868, 868, 868, 869, 869, 870, 871, 872, 872, 872, 872, 872, 873, 873, 873, 874, 874, 875, 875, 876, 877, 878, 879, 879, 880, 880, 880, 880, 882, 883, 884, 885, 885, 885, 886, 886, 886, 888, 889, 889, 891, 891, 891, 892, 892, 894, 894, 894, 894, 894, 894, 895, 896, 898, 898, 899, 899, 899, 900, 900, 901, 902, 902, 903, 905, 905, 905, 906, 906, 906, 907, 907, 907, 907, 907, 907, 907, 908, 908, 908, 908, 909, 909, 909, 910, 910, 911, 913, 913, 913, 913, 914, 914, 914, 915, 916, 917, 917, 917, 918, 918, 918, 919, 920, 920, 920, 920, 920, 920, 921, 921, 921, 922, 923, 924, 924, 924, 925, 925, 926, 926, 927, 928, 928, 928, 928, 929, 929, 930, 930, 931, 932, 932, 933, 934, 934, 934, 935, 935, 935, 936, 936, 937, 938, 938, 938, 939, 939, 939, 940, 940, 941, 941, 942, 942, 942, 943, 943, 943, 943, 943, 943, 944, 945, 946, 946, 946, 947, 947, 948, 948, 950, 950, 951, 951, 952, 952, 952, 953, 955, 955, 955, 956, 956, 957, 957, 958, 959, 959, 959, 959, 960, 961, 962, 963, 964, 964, 964, 965, 965, 965, 966, 966, 966, 967, 967, 967, 968, 968, 968, 969, 969, 970, 970, 971, 972, 973, 973, 974, 975, 975, 975, 976, 976, 977, 977, 977, 978, 978, 978, 979, 979, 980, 980, 981, 981, 982, 982, 982, 983, 986, 986, 988, 990, 991, 991, 991, 991, 991, 992, 992, 993, 993, 994, 994, 995, 995, 995, 995, 995, 997, 997, 997, 997, 998, 998, 999, 999, 999 ]\n", + bench_group_opt, + ); +} diff --git a/cli/tests/cli_run.rs b/cli/tests/cli_run.rs index 1d139a9eae..280290bd40 100644 --- a/cli/tests/cli_run.rs +++ b/cli/tests/cli_run.rs @@ -141,11 +141,12 @@ mod cli_run { #[test] #[serial(quicksort)] fn run_quicksort_not_optimized() { - check_output( - &example_file("quicksort", "Quicksort.roc"), - "quicksort", + check_output_with_stdin( + &example_file("benchmarks", "QuicksortApp.roc"), + "0", + "quicksortapp", &[], - "[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2]\n", + "[ 0, 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 6, 6, 8, 9 ]\n", true, ); } @@ -153,11 +154,12 @@ mod cli_run { #[test] #[serial(quicksort)] fn run_quicksort_optimized() { - check_output( - &example_file("quicksort", "Quicksort.roc"), - "quicksort", + check_output_with_stdin( + &example_file("benchmarks", "QuicksortApp.roc"), + "0", + "quicksortapp", &["--optimize"], - "[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2]\n", + "[ 0, 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 6, 6, 8, 9 ]\n", true, ); } @@ -165,11 +167,12 @@ mod cli_run { #[test] #[serial(quicksort)] fn run_quicksort_optimized_valgrind() { - check_output( - &example_file("quicksort", "Quicksort.roc"), - "quicksort", + check_output_with_stdin( + &example_file("benchmarks", "QuicksortApp.roc"), + "0", + "quicksortapp", &["--optimize"], - "[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2]\n", + "[ 0, 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 6, 6, 8, 9 ]\n", true, ); } diff --git a/examples/benchmarks/Quicksort.roc b/examples/benchmarks/Quicksort.roc index bbd2a90c12..271be43894 100644 --- a/examples/benchmarks/Quicksort.roc +++ b/examples/benchmarks/Quicksort.roc @@ -1,4 +1,4 @@ -interface Quicksort exposes [ sortBy, show ] imports [] +interface Quicksort exposes [ sortBy, sortWith, show ] imports [] show : List I64 -> Str show = \list -> diff --git a/examples/benchmarks/QuicksortApp.roc b/examples/benchmarks/QuicksortApp.roc new file mode 100644 index 0000000000..198003bf13 --- /dev/null +++ b/examples/benchmarks/QuicksortApp.roc @@ -0,0 +1,23 @@ +app "quicksortapp" + packages { base: "platform" } + imports [base.Task, Quicksort] + provides [ main ] to base + +main : Task.Task {} [] +main = + Task.after Task.getInt \n -> + unsortedList = + if n == 0 then + # small unsorted list of 20 elements (0-9) + [ 2, 4, 4, 0, 3, 8, 3, 6, 4, 9, 4, 6, 3, 5, 2, 2, 3, 1, 1, 3 ] + else + # big unsorted list of 2000 elements (0-1000) + [ 891, 330, 190, 304, 991, 803, 54, 362, 428, 318, 59, 631, 995, 36, 711, 450, 654, 614, 74, 288, 198, 11, 369, 290, 7, 934, 72, 642, 955, 782, 724, 811, 3, 402, 517, 128, 902, 612, 454, 281, 794, 109, 497, 454, 238, 541, 215, 672, 4, 855, 908, 868, 177, 885, 460, 133, 367, 113, 131, 191, 148, 254, 914, 680, 735, 783, 225, 720, 708, 447, 625, 526, 529, 914, 126, 857, 574, 234, 249, 433, 779, 74, 275, 302, 315, 131, 518, 572, 301, 450, 346, 630, 928, 420, 183, 287, 420, 730, 512, 533, 69, 942, 214, 801, 196, 633, 13, 493, 343, 910, 462, 939, 394, 367, 619, 583, 674, 265, 113, 909, 202, 135, 859, 924, 214, 27, 30, 531, 662, 90, 917, 35, 236, 210, 456, 758, 338, 514, 590, 907, 106, 147, 625, 199, 766, 628, 894, 552, 108, 982, 94, 751, 734, 678, 371, 894, 204, 719, 559, 676, 362, 782, 959, 826, 793, 935, 17, 837, 179, 679, 819, 33, 197, 611, 719, 718, 688, 365, 36, 62, 349, 719, 598, 826, 135, 218, 889, 282, 948, 442, 345, 453, 386, 840, 95, 921, 293, 241, 494, 774, 139, 712, 373, 730, 301, 472, 805, 41, 355, 384, 188, 168, 869, 17, 339, 55, 238, 476, 394, 725, 130, 53, 978, 762, 418, 419, 920, 913, 780, 723, 750, 277, 92, 37, 979, 971, 882, 936, 190, 216, 452, 495, 450, 597, 567, 994, 587, 777, 700, 685, 991, 995, 533, 443, 945, 56, 186, 413, 239, 286, 234, 486, 399, 410, 853, 516, 443, 999, 591, 16, 452, 314, 459, 343, 296, 189, 84, 465, 640, 616, 122, 665, 379, 858, 930, 188, 47, 445, 959, 93, 244, 89, 610, 26, 952, 294, 77, 619, 775, 661, 291, 290, 443, 458, 689, 107, 517, 794, 827, 313, 506, 568, 264, 400, 485, 972, 430, 953, 258, 409, 305, 729, 288, 146, 133, 603, 568, 748, 891, 521, 199, 12, 714, 180, 848, 317, 947, 454, 166, 776, 907, 493, 195, 5, 631, 791, 86, 932, 809, 464, 80, 846, 323, 300, 658, 869, 712, 316, 551, 700, 438, 457, 516, 747, 54, 854, 636, 72, 352, 24, 159, 222, 844, 427, 369, 969, 208, 337, 663, 388, 624, 943, 781, 868, 563, 559, 638, 818, 205, 927, 265, 235, 713, 871, 617, 34, 751, 530, 36, 418, 251, 654, 213, 99, 799, 808, 439, 609, 263, 481, 113, 706, 185, 386, 776, 152, 178, 468, 922, 0, 942, 817, 428, 66, 399, 355, 450, 792, 549, 237, 532, 212, 254, 279, 941, 685, 211, 100, 994, 182, 503, 707, 368, 472, 297, 820, 905, 83, 319, 345, 47, 547, 769, 713, 204, 153, 687, 372, 656, 914, 448, 872, 73, 955, 318, 381, 254, 849, 719, 909, 905, 558, 471, 142, 136, 865, 392, 650, 342, 698, 199, 385, 673, 632, 14, 792, 523, 862, 872, 792, 957, 739, 713, 373, 72, 464, 667, 394, 933, 305, 332, 444, 960, 322, 900, 841, 146, 566, 723, 884, 355, 153, 49, 928, 689, 304, 467, 306, 952, 277, 943, 421, 216, 704, 525, 293, 974, 754, 978, 96, 582, 5, 811, 229, 304, 52, 610, 160, 872, 831, 388, 925, 216, 665, 435, 913, 753, 381, 452, 786, 737, 834, 191, 165, 16, 174, 997, 735, 976, 189, 340, 161, 653, 849, 447, 264, 950, 349, 4, 375, 312, 3, 279, 833, 600, 721, 205, 162, 832, 451, 998, 26, 689, 870, 215, 651, 419, 831, 70, 308, 596, 500, 624, 672, 481, 522, 390, 79, 410, 77, 336, 502, 10, 95, 697, 591, 385, 820, 807, 726, 537, 359, 772, 548, 768, 981, 838, 90, 599, 172, 272, 718, 417, 789, 578, 669, 786, 534, 403, 602, 180, 115, 205, 96, 573, 359, 830, 970, 431, 533, 342, 777, 600, 880, 374, 262, 704, 31, 710, 148, 264, 288, 501, 540, 851, 929, 420, 93, 5, 350, 80, 810, 8, 153, 369, 582, 908, 756, 523, 964, 124, 842, 152, 378, 946, 720, 425, 975, 844, 211, 378, 963, 966, 297, 763, 891, 180, 505, 33, 201, 377, 167, 35, 600, 698, 801, 977, 378, 361, 35, 401, 479, 266, 758, 32, 956, 943, 705, 860, 737, 791, 727, 162, 997, 213, 785, 804, 292, 56, 651, 567, 547, 866, 531, 835, 875, 122, 721, 202, 632, 895, 117, 676, 522, 993, 357, 867, 49, 797, 655, 91, 608, 838, 322, 582, 736, 708, 65, 39, 325, 126, 619, 135, 161, 523, 228, 414, 610, 339, 952, 691, 612, 238, 400, 846, 861, 313, 161, 752, 920, 136, 650, 939, 920, 262, 358, 899, 505, 738, 155, 783, 743, 359, 605, 330, 805, 662, 608, 617, 894, 387, 568, 235, 539, 799, 58, 943, 937, 234, 386, 819, 917, 405, 490, 113, 353, 444, 437, 361, 357, 225, 656, 551, 973, 305, 892, 30, 665, 920, 716, 126, 294, 72, 635, 590, 451, 89, 236, 714, 44, 698, 401, 271, 670, 371, 919, 397, 141, 484, 847, 630, 813, 247, 414, 239, 943, 691, 277, 357, 212, 480, 220, 293, 441, 314, 193, 193, 734, 687, 515, 802, 964, 127, 547, 918, 638, 234, 145, 790, 715, 555, 160, 754, 646, 329, 861, 637, 195, 762, 33, 605, 618, 78, 938, 668, 940, 454, 606, 309, 518, 635, 211, 101, 753, 532, 743, 730, 231, 608, 516, 422, 457, 346, 155, 569, 947, 51, 334, 172, 123, 295, 885, 778, 428, 980, 621, 805, 169, 808, 316, 401, 639, 769, 118, 698, 618, 105, 744, 174, 353, 752, 957, 257, 497, 743, 260, 872, 590, 815, 543, 906, 501, 760, 358, 325, 621, 780, 189, 262, 51, 439, 341, 290, 829, 303, 705, 477, 886, 137, 6, 383, 303, 7, 149, 59, 125, 83, 877, 83, 378, 444, 318, 402, 810, 404, 329, 812, 4, 885, 44, 866, 489, 907, 860, 727, 582, 139, 808, 704, 619, 74, 909, 242, 879, 566, 221, 534, 628, 23, 916, 590, 303, 489, 523, 958, 563, 728, 657, 250, 195, 500, 88, 907, 310, 353, 745, 563, 64, 455, 91, 390, 393, 697, 65, 786, 240, 222, 617, 216, 125, 597, 913, 170, 591, 495, 840, 278, 966, 968, 978, 843, 655, 9, 557, 249, 490, 202, 550, 83, 619, 220, 351, 853, 816, 455, 561, 4, 376, 901, 300, 33, 739, 262, 991, 948, 234, 717, 857, 527, 902, 789, 624, 203, 445, 911, 288, 700, 823, 773, 970, 526, 967, 687, 144, 745, 123, 833, 889, 676, 14, 47, 96, 876, 832, 276, 60, 148, 266, 782, 456, 592, 736, 78, 451, 724, 581, 718, 993, 287, 386, 938, 243, 312, 736, 495, 493, 908, 961, 999, 404, 542, 880, 679, 433, 394, 417, 888, 448, 502, 732, 516, 22, 606, 338, 776, 711, 936, 270, 986, 275, 834, 335, 122, 287, 966, 378, 854, 233, 539, 687, 436, 193, 241, 899, 791, 698, 784, 618, 267, 194, 562, 102, 220, 866, 723, 422, 460, 924, 308, 925, 113, 508, 878, 547, 739, 475, 823, 645, 938, 959, 0, 758, 574, 706, 19, 127, 167, 344, 845, 740, 361, 768, 560, 72, 360, 866, 753, 992, 946, 929, 461, 371, 875, 599, 907, 669, 862, 67, 301, 101, 962, 827, 762, 499, 168, 183, 207, 416, 81, 333, 856, 202, 717, 533, 892, 625, 573, 313, 672, 805, 384, 294, 223, 0, 905, 410, 489, 474, 986, 842, 661, 66, 73, 918, 512, 211, 968, 26, 523, 631, 249, 621, 907, 474, 146, 388, 292, 873, 2, 404, 31, 713, 206, 225, 861, 983, 659, 743, 426, 798, 152, 9, 355, 195, 410, 618, 687, 210, 1, 928, 588, 461, 217, 132, 598, 151, 88, 320, 352, 439, 934, 968, 542, 323, 184, 227, 759, 383, 335, 146, 223, 400, 438, 451, 334, 837, 616, 753, 864, 162, 129, 913, 564, 17, 935, 951, 561, 977, 940, 956, 979, 508, 547, 513, 880, 700, 874, 485, 924, 788, 223, 162, 836, 965, 679, 696, 68, 975, 704, 44, 393, 777, 473, 209, 273, 471, 418, 350, 116, 669, 335, 639, 747, 40, 334, 417, 625, 427, 240, 248, 928, 170, 856, 159, 344, 328, 872, 123, 400, 376, 921, 934, 24, 793, 734, 839, 894, 926, 318, 389, 228, 977, 946, 613, 274, 973, 879, 757, 898, 499, 883, 405, 798, 861, 580, 577, 587, 25, 159, 391, 80, 708, 404, 593, 510, 389, 995, 786, 602, 931, 668, 368, 256, 333, 319, 918, 469, 997, 508, 334, 729, 227, 67, 666, 873, 921, 238, 112, 944, 238, 455, 287, 274, 920, 335, 820, 436, 900, 822, 880, 235, 5, 578, 502, 666, 750, 859, 467, 510, 969, 309, 369, 618, 312, 868, 999, 147, 588, 229, 967, 519, 638, 619, 982, 630, 48, 275, 807, 218, 906, 677, 841, 563, 530, 32, 494, 744, 753, 148, 43, 26, 679, 390, 135, 405, 746, 410, 487, 965, 475, 751, 199, 271, 20, 823, 833, 345, 217, 63, 13, 70, 982, 713, 491, 397, 670, 618, 85, 186, 389, 804, 355, 206, 950, 419, 637, 619, 180, 194, 773, 713, 508, 229, 77, 252, 30, 402, 558, 326, 385, 335, 995, 178, 398, 3, 116, 148, 733, 98, 447, 154, 329, 699, 104, 626, 816, 137, 43, 29, 402, 333, 292, 832, 823, 132, 449, 76, 288, 746, 730, 955, 79, 105, 52, 760, 429, 490, 377, 567, 469, 482, 614, 351, 672, 613, 942, 369, 72, 214, 54, 964, 382, 63, 18, 853, 775, 166, 551, 86, 980, 443, 659, 807, 835, 620, 288, 474, 663, 910, 935, 487, 851, 527, 763, 149, 139, 79, 333, 852, 374, 462, 241, 363, 195, 311, 822, 511, 187, 886, 180, 558, 222, 800, 66, 785, 990, 396, 243, 215, 248, 684, 780, 160, 661, 563, 457, 241, 711, 426, 296, 387, 506, 252, 289, 517, 923, 193, 787, 32, 222, 394, 692, 338, 684, 289, 809, 262, 351, 906, 231, 150, 692, 776, 187, 166, 903, 378, 583, 81, 704, 851, 552, 352, 132, 476, 759, 254, 178, 894, 183, 193, 907, 665, 683, 317, 360, 269, 348, 243, 835, 975, 193, 719, 82, 533, 874, 674, 43, 628, 167, 930, 332, 511, 176, 753, 42, 123, 768, 168, 943, 707, 783, 939, 714, 57, 799, 487, 332, 401, 335, 851, 965, 483, 654, 743, 436, 679, 675, 293, 324, 229, 337, 151, 88, 121, 469, 896, 213, 917, 608, 535, 130, 779, 672, 768, 632, 926, 29, 31, 899, 699, 4, 727, 587, 571, 830, 477, 532, 898, 293, 785, 915, 602, 291, 797, 210, 324, 711, 330, 746, 675, 149, 148, 235, 566, 212, 381, 126, 620, 49, 349, 392, 736, 693, 124, 703, 185, 569, 8, 785, 585, 488, 720, 269, 683, 457, 643, 181, 453, 976, 255, 175, 234, 644, 479, 146, 153, 719, 38, 682, 995, 865, 507, 606, 184, 886, 371, 210, 438, 123, 941, 139, 624, 854, 908, 860, 992, 372, 16, 282, 298, 270, 402, 693, 261, 402, 106, 379, 639, 156, 616, 395, 865, 409, 526, 27, 373, 604, 486, 786, 685, 814, 364, 595, 847, 792, 187, 266, 589, 981, 873, 213, 221, 293, 932, 278, 487, 760, 789, 687, 306, 680, 269, 593, 998, 790, 664, 98, 611, 959, 198, 860, 469, 779, 435, 78, 707, 717, 614, 405, 589, 92, 547, 761, 254, 88, 663, 375, 464, 489, 391, 575, 259, 427, 112, 155, 352, 544, 53, 532, 130, 663, 298, 894, 768, 336, 808, 433, 651, 452, 172, 301, 997, 82, 189, 376, 68, 250, 859, 67, 312, 514, 287, 618, 677, 250, 206, 30, 88, 991, 397, 686, 255, 353, 54, 172, 560, 783, 757, 407, 727, 22, 200, 192, 212, 248, 558, 528, 535, 495, 991, 678, 749, 484, 356, 10, 646, 920, 219, 705, 11, 988, 241, 731, 836, 350, 967, 635, 713, 610, 107, 69, 677, 349, 365, 293, 24, 860, 24, 294, 73, 113, 301, 226, 35, 31, 49, 776, 807, 951 ] + + sort unsortedList + |> Quicksort.show + |> Task.putLine + +sort : List I64 -> List I64 +sort = \list -> + Quicksort.sortWith list (\x, y -> Num.compare x y) \ No newline at end of file From 4beac319bcc2d48589997250e4b1e8ebee4cc456 Mon Sep 17 00:00:00 2001 From: Anton-4 <17049058+Anton-4@users.noreply.github.com> Date: Fri, 4 Jun 2021 20:00:45 +0200 Subject: [PATCH 18/52] Run benchmarks for longer, added README to benchmarks --- Earthfile | 1 + cli/benches/README.md | 17 +++++++++++++++++ cli/benches/time_bench.rs | 8 ++++---- cli/cli_utils/src/bench_utils.rs | 16 ++++++++-------- 4 files changed, 30 insertions(+), 12 deletions(-) create mode 100644 cli/benches/README.md diff --git a/Earthfile b/Earthfile index 766e224f12..ece11b44e4 100644 --- a/Earthfile +++ b/Earthfile @@ -115,6 +115,7 @@ bench-roc: FROM +copy-dirs-and-cache ENV RUST_BACKTRACE=full RUN cargo criterion -V + RUN ulimit -s unlimited # to prevent stack overflow errors for CFold RUN --privileged --mount=type=cache,target=$SCCACHE_DIR \ cd cli && cargo criterion && sccache --show-stats diff --git a/cli/benches/README.md b/cli/benches/README.md new file mode 100644 index 0000000000..0c91904cfa --- /dev/null +++ b/cli/benches/README.md @@ -0,0 +1,17 @@ + +# Running the benchmarks + +Install cargo criterion: +``` +cargo install cargo-criterion +``` + +To prevent stack overflow on the `CFold` benchmark: +``` +ulimit -s unlimited +``` + +In the `cli` folder execute: +``` +cargo criterion +``` \ No newline at end of file diff --git a/cli/benches/time_bench.rs b/cli/benches/time_bench.rs index 4944067555..491db64784 100644 --- a/cli/benches/time_bench.rs +++ b/cli/benches/time_bench.rs @@ -13,10 +13,10 @@ fn bench_group_wall_time(c: &mut Criterion) { let bench_funcs: Vec>) -> ()> = vec![ bench_nqueens, // queens 11 - bench_cfold, // e = mkExpr 12 1 - bench_deriv, // nest deriv 7 f - bench_rbtree_ck, // ms = makeMap 5 5600 - bench_rbtree_delete, // m = makeMap 6000 + bench_cfold, // e = mkExpr 17 1 + bench_deriv, // nest deriv 8 f + bench_rbtree_ck, // ms = makeMap 5 80000 + bench_rbtree_delete, // m = makeMap 100000 bench_quicksort, // list size 2000 ]; diff --git a/cli/cli_utils/src/bench_utils.rs b/cli/cli_utils/src/bench_utils.rs index 03109ebb21..03d1e1f3e8 100644 --- a/cli/cli_utils/src/bench_utils.rs +++ b/cli/cli_utils/src/bench_utils.rs @@ -87,9 +87,9 @@ pub fn bench_nqueens(bench_group_opt: Option<&mut BenchmarkGroup pub fn bench_cfold(bench_group_opt: Option<&mut BenchmarkGroup>) { exec_bench_w_input( &example_file("benchmarks", "CFold.roc"), - "12", + "17", "cfold", - "10426 & 10426\n", + "396354 & 396354\n", bench_group_opt, ); } @@ -97,9 +97,9 @@ pub fn bench_cfold(bench_group_opt: Option<&mut BenchmarkGroup(bench_group_opt: Option<&mut BenchmarkGroup>) { exec_bench_w_input( &example_file("benchmarks", "Deriv.roc"), - "7", + "8", "deriv", - "1 count: 6\n2 count: 22\n3 count: 90\n4 count: 420\n5 count: 2202\n6 count: 12886\n7 count: 83648\n", + "1 count: 6\n2 count: 22\n3 count: 90\n4 count: 420\n5 count: 2202\n6 count: 12886\n7 count: 83648\n8 count: 598592\n", bench_group_opt, ); } @@ -107,9 +107,9 @@ pub fn bench_deriv(bench_group_opt: Option<&mut BenchmarkGroup(bench_group_opt: Option<&mut BenchmarkGroup>) { exec_bench_w_input( &example_file("benchmarks", "RBTreeCk.roc"), - "5600", + "80000", "rbtree-ck", - "560\n", + "8000\n", bench_group_opt, ); } @@ -117,9 +117,9 @@ pub fn bench_rbtree_ck(bench_group_opt: Option<&mut BenchmarkGro pub fn bench_rbtree_delete(bench_group_opt: Option<&mut BenchmarkGroup>) { exec_bench_w_input( &example_file("benchmarks", "RBTreeDel.roc"), - "6000", + "100000", "rbtree-del", - "420\n", + "7000\n", bench_group_opt, ); } From 2b2b6e3dddc9d3dc1d2dd869740cd1a1ad71b88c Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Fri, 4 Jun 2021 21:27:26 -0400 Subject: [PATCH 19/52] Update some more docs --- compiler/builtins/docs/Bool.roc | 10 +- compiler/builtins/docs/Dict.roc | 4 +- compiler/builtins/docs/List.roc | 21 ++- compiler/builtins/docs/Num.roc | 290 +++++++++++++++++++++----------- compiler/builtins/docs/Set.roc | 4 +- compiler/builtins/docs/Str.roc | 11 +- editor/src/lang/pool.rs | 17 ++ roc-for-elm-programmers.md | 2 + 8 files changed, 255 insertions(+), 104 deletions(-) diff --git a/compiler/builtins/docs/Bool.roc b/compiler/builtins/docs/Bool.roc index 601a3d491f..5a4e4814df 100644 --- a/compiler/builtins/docs/Bool.roc +++ b/compiler/builtins/docs/Bool.roc @@ -67,11 +67,11 @@ xor : Bool, Bool -> Bool ## ## Structural equality works as follows: ## -## 1. #Int and #Float values are equal if their numbers are equal. -## 2. Records are equal if all their fields are equal. -## 3. Global tags are equal if they are the same tag, and also their contents (if any) are equal. -## 4. Private tags are equal if they are the same tag, in the same module, and also their contents (if any) are equal. -## 5. Collections (#String, #List, #Map, #Set, and #Bytes) are equal if they are the same length, and also all their corresponding elements are equal. +## 1. Global tags are equal if they are the same tag, and also their contents (if any) are equal. +## 2. Private tags are equal if they are the same tag, in the same module, and also their contents (if any) are equal. +## 3. Records are equal if all their fields are equal. +## 4. Collections ([Str], [List], [Dict], and [Set]) are equal if they are the same length, and also all their corresponding elements are equal. +## 5. #Num values are equal if their numbers are equal, with one exception: if both arguments to `isEq` are *NaN*, then `isEq` returns `False`. See [Num.isNaN] for more about *NaN*. ## ## Note that `isEq` takes `'val` instead of `val`, which means `isEq` does not ## accept arguments whose types contain functions. diff --git a/compiler/builtins/docs/Dict.roc b/compiler/builtins/docs/Dict.roc index 178e5329ee..4c7fa6c867 100644 --- a/compiler/builtins/docs/Dict.roc +++ b/compiler/builtins/docs/Dict.roc @@ -27,5 +27,7 @@ map : # TODO: removed `'` from signature because parser does not support it yet # Original signature: insert : Dict 'key val, 'key, val -> Dict 'key val -## Since NaN is defined to be unequal to NaN, panics if given NaN for a key. +## Make sure never to insert a key of *NaN* into a [Dict]! Becuase *NaN* is +## defined to be unequal to *NaN*, inserting a *NaN* key results in an entry +## that can never be retrieved or removed from the [Dict]. insert : Dict key val, key, val -> Dict key val diff --git a/compiler/builtins/docs/List.roc b/compiler/builtins/docs/List.roc index 0398f2ab8e..12b1ba7b3c 100644 --- a/compiler/builtins/docs/List.roc +++ b/compiler/builtins/docs/List.roc @@ -232,9 +232,28 @@ reverse : List elem -> List elem ## Sorts a list using a function which specifies how two elements are ordered. ## -## +## When sorting by numeric values, it's more efficient to use [sortAsc] or +## [sortDesc] instead. sort : List elem, (elem, elem -> [ Lt, Eq, Gt ]) -> List elem +## Sorts a list in ascending order (lowest to highest), using a function which +## specifies a way to represent each element as a number. +## +## This is more efficient than [sort] because it skips +## calculating the `[ Lt, Eq, Gt ]` value and uses the number directly instead. +## +## To sort in descending order (highest to lowest), use [List.sortDesc] instead. +sortAsc : List elem, (elem -> Num *) -> List elem + +## Sorts a list in descending order (highest to lowest), using a function which +## specifies a way to represent each element as a number. +## +## This is more efficient than [sort] because it skips +## calculating the `[ Lt, Eq, Gt ]` value and uses the number directly instead. +## +## To sort in ascending order (lowest to highest), use [List.sortAsc] instead. +sortDesc : List elem, (elem -> Num *) -> List elem + ## Convert each element in the list to something new, by calling a conversion ## function on each of them. Then return a new list of the converted values. ## diff --git a/compiler/builtins/docs/Num.roc b/compiler/builtins/docs/Num.roc index ae5842c339..fee411fb71 100644 --- a/compiler/builtins/docs/Num.roc +++ b/compiler/builtins/docs/Num.roc @@ -122,6 +122,30 @@ Dec : Frac [ @Decimal128 ] ## been done in a base-2 floating point calculation, which causes noticeable ## precision loss in this case. ## +## The floating-point numbers ([F32] and [F64]) also have three values which +## are not ordinary [finite numbers](https://en.wikipedia.org/wiki/Finite_number). +## They are: +## * ∞ ([infinity](https://en.wikipedia.org/wiki/Infinity)) +## * -∞ (negative infinity) +## * *NaN* ([not a number](https://en.wikipedia.org/wiki/NaN)) +## +## These values are different from ordinary numbers in that they only occur +## when a floating-point calculation encounters an error. For example: +## * Dividing a positive [F64] by `0.0` returns ∞. +## * Dividing a negative [F64] by `0.0` returns -∞. +## * Dividing a [F64] of `0.0` by `0.0` returns [*NaN*](Num.isNaN). +## +## These rules come from the [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754) +## floating point standard. Because almost all modern processors are built to +## this standard, deviating from these rules has a significant performance +## cost! Since the most common reason to choose [F64] or [F32] over [Dec] is +## access to hardware-accelerated performance, Roc follows these rules exactly. +## +## There's no literal syntax for these error values, but you can check to see if +## you ended up with one of them by using [isNaN], [isFinite], and [isInfinite]. +## Whenever a function in this module could return one of these values, that +## possibility is noted in the function's documentation. +## ## ## Performance Notes ## ## On typical modern CPUs, performance is similar between [Dec], [F64], and [F32] @@ -140,7 +164,7 @@ Dec : Frac [ @Decimal128 ] ## an even bigger performance difference. [F32] and [F64] can do these in a ## single instruction, whereas [Dec] needs entire custom procedures - which use ## loops and conditionals. If you need to do performance-critical trigonometry -## or square roots, either [F32] or [F64] is probably a better choice than the +## or square roots, either [F64] or [F32] is probably a better choice than the ## usual default choice of [Dec], despite the precision problems they bring. Frac a : Num [ @Fraction a ] @@ -524,15 +548,13 @@ isOdd : Num * -> Bool ## If the answer to this operation can't fit in the return value (e.g. an ## [I8] answer that's higher than 127 or lower than -128), the result is an ## *overflow*. For [F64] and [F32], overflow results in an answer of either -## [*Infinity*](#isPositiveInfinity) or [*-Infinity*](#isNegativeInfinity). For -## all other number types, overflow results in a panic. +## ∞ or -∞. For all other number types, overflow results in a panic. add : Num a, Num a -> Num a ## Add two numbers and check for overflow. ## ## This is the same as [Num.add] except if the operation overflows, instead of -## panicking or returning [*Infinity*](#isPositiveInfinity) or [*-Infinity*](#isNegativeInfinity), -## it will return `Err Overflow`. +## panicking or returning ∞ or -∞, it will return `Err Overflow`. addCheckOverflow : Num a, Num a -> Result (Num a) [ Overflow ]* ## Subtract two numbers of the same type. @@ -553,15 +575,13 @@ addCheckOverflow : Num a, Num a -> Result (Num a) [ Overflow ]* ## If the answer to this operation can't fit in the return value (e.g. an ## [I8] answer that's higher than 127 or lower than -128), the result is an ## *overflow*. For [F64] and [F32], overflow results in an answer of either -## [*Infinity*](#isPositiveInfinity) or [*-Infinity*](#isNegativeInfinity). For -## all other number types, overflow results in a panic. +## ∞ or -∞. For all other number types, overflow results in a panic. sub : Num a, Num a -> Num a ## Subtract two numbers and check for overflow. ## ## This is the same as [Num.sub] except if the operation overflows, instead of -## panicking or returning [*Infinity*](#isPositiveInfinity) or [*-Infinity*](#isNegativeInfinity), -## it will return `Err Overflow`. +## panicking or returning ∞ or -∞, it will return `Err Overflow`. subCheckOverflow : Num a, Num a -> Result (Num a) [ Overflow ]* ## Multiply two numbers of the same type. @@ -582,15 +602,13 @@ subCheckOverflow : Num a, Num a -> Result (Num a) [ Overflow ]* ## If the answer to this operation can't fit in the return value (e.g. an ## [I8] answer that's higher than 127 or lower than -128), the result is an ## *overflow*. For [F64] and [F32], overflow results in an answer of either -## [*Infinity*](#isPositiveInfinity) or [*-Infinity*](#isNegativeInfinity). For -## all other number types, overflow results in a panic. +## ∞ or -∞. For all other number types, overflow results in a panic. mul : Num a, Num a -> Num a ## Multiply two numbers and check for overflow. ## ## This is the same as [Num.mul] except if the operation overflows, instead of -## panicking or returning [*Infinity*](#isPositiveInfinity) or [*-Infinity*](#isNegativeInfinity), -## it will return `Err Overflow`. +## panicking or returning ∞ or -∞, it will return `Err Overflow`. mulCheckOverflow : Num a, Num a -> Result (Num a) [ Overflow ]* ## Convert @@ -608,7 +626,10 @@ mulCheckOverflow : Num a, Num a -> Result (Num a) [ Overflow ]* ## ## >>> Num.toStr 4.0 ## -## For other bases see #toHexStr, #toOctalStr, and #toBinaryStr. +## When this function is given a non-[finite](Num.isFinite) +## [F64] or [F32] value, the returned string will be `"NaN"`, `"∞"`, or `"-∞"`. +## +## To get strings in hexadecimal, octal, or binary format, use [Num.format]. toStr : Num * -> Str ## Convert a number into a [Str], formatted with the given options. @@ -780,18 +801,6 @@ and : Int a, Int a -> Int a not : Int a -> Int a -## Sort ascending - that is, with the lowest first, and the highest last. -## -## List.sort Num.asc [ 3, 6, 0 ] -## -asc : Num a, Num a -> [ Eq, Lt, Gt ] - -## Sort descending - that is, with the highest first, and the lowest last. -## -## List.sort Num.desc [ 3, 6, 0 ] -## -desc : Num a, Num a -> [ Eq, Lt, Gt ] - ## Limits ## The highest number that can be stored in a #Nat without overflowing its @@ -849,39 +858,35 @@ maxU32 : U32 ## and zero is the lowest unsigned number. Unsigned numbers cannot be negative. minU32 : U32 -## The highest supported #Frac value you can have, which is approximately 1.8 × 10^308. +## The highest supported #F64 value you can have, which is approximately 1.8 × 10^308. ## ## If you go higher than this, your running Roc code will crash - so be careful not to! -maxF64 : Frac * +maxF64 : F64 -## The lowest supported #Frac value you can have, which is approximately -1.8 × 10^308. +## The lowest supported #F64 value you can have, which is approximately -1.8 × 10^308. ## ## If you go lower than this, your running Roc code will crash - so be careful not to! -minF64 : Frac * +minF64 : F64 -## The highest integer that can be represented as a #Frac without # losing precision. -## It is equal to 2^53, which is approximately 9 × 10^15. +## The highest supported #F32 value you can have, which is approximately 1.8 × 10^308. ## -## Some integers higher than this can be represented, but they may lose precision. For example: -## -## >>> Frac.highestInt -## -## >>> Frac.highestInt + 100 # Increasing may lose precision -## -## >>> Frac.highestInt - 100 # Decreasing is fine - but watch out for lowestLosslessInt! -maxPreciseInt : Frac * +## If you go higher than this, your running Roc code will crash - so be careful not to! +maxF32 : F32 -## The lowest integer that can be represented as a #Frac without losing precision. -## It is equal to -2^53, which is approximately -9 × 10^15. +## The lowest supported #F32 value you can have, which is approximately -1.8 × 10^308. ## -## Some integers lower than this can be represented, but they may lose precision. For example: +## If you go lower than this, your running Roc code will crash - so be careful not to! +minF32 : F32 + +## The highest supported #F64 value you can have, which is approximately 1.8 × 10^308. ## -## >>> Frac.lowestIntVal +## If you go higher than this, your running Roc code will crash - so be careful not to! +maxDec : Dec + +## The lowest supported #F64 value you can have, which is approximately -1.8 × 10^308. ## -## >>> Frac.lowestIntVal - 100 # Decreasing may lose precision -## -## >>> Frac.lowestIntVal + 100 # Increasing is fine - but watch out for highestInt! -maxPreciseInt : Frac * +## If you go lower than this, your running Roc code will crash - so be careful not to! +maxDec : Dec ## Constants @@ -916,14 +921,14 @@ atan : Frac a -> Frac a ## Calling [div] on a [Dec] denominator of zero will cause a panic. ## ## Calling [div] on [F32] and [F64] values follows these rules: -## * Dividing a positive [F32] or [F64] by zero returns [Infinity](#isPositiveInfinity). -## * Dividing a negative [F32] or [F64] by zero returns [-Infinity](#isNegativeInfinity). -## * Dividing a zero [F32] or [F64] by zero returns [NaN](#isNaN). +## * Dividing a positive [F64] or [F32] by zero returns ∞. +## * Dividing a negative [F64] or [F32] by zero returns -∞. +## * Dividing a zero [F64] or [F32] by zero returns [*NaN*](Num.isNaN). ## ## > These rules come from the [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754) -## > floating point standard. Since almost all modern processors are built to +## > floating point standard. Because almost all modern processors are built to ## > this standard, deviating from these rules has a significant performance -## > cost. Since the most common reason to choose [F32] or [F64] over [Dec] is +## > cost! Since the most common reason to choose [F64] or [F32] over [Dec] is ## > access to hardware-accelerated performance, Roc follows these rules exactly. ## ## To divide an [Int] and a [Frac], first convert the [Int] to a [Frac] using @@ -952,7 +957,7 @@ div : Frac a, Frac a -> Frac a ## ## Passing [mod] a [Dec] value of zero for its second argument will cause a panic. ## Passing [mod] a [F32] and [F64] value for its second argument will cause it -## to return [NaN](#isNaN). +## to return [*NaN*](Num.isNaN). ## ## >>> 5.0 % 7.0 ## @@ -999,14 +1004,14 @@ expBySquaring : Int a, U8 -> Int a ## function a negative number! Calling [sqrt] on a negative [Dec] will cause a panic. ## ## Calling [sqrt] on [F32] and [F64] values follows these rules: -## * Passing a negative [F32] or [F64] returns [NaN](#isNaN). -## * Passing [NaN](#isNaN) or [-Infinity](isNegativeInfinity) also returns [NaN](#isNaN). -## * Passing [Infinity](isPositiveInfinity) returns [Infinity]. +## * Passing a negative [F64] or [F32] returns [*NaN*](Num.isNaN). +## * Passing [*NaN*](Num.isNaN) or -∞ also returns [*NaN*](Num.isNaN). +## * Passing ∞ returns ∞. ## ## > These rules come from the [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754) -## > floating point standard. Since almost all modern processors are built to +## > floating point standard. Because almost all modern processors are built to ## > this standard, deviating from these rules has a significant performance -## > cost. Since the most common reason to choose [F32] or [F64] over [Dec] is +## > cost! Since the most common reason to choose [F64] or [F32] over [Dec] is ## > access to hardware-accelerated performance, Roc follows these rules exactly. ## ## >>> Frac.sqrt 4.0 @@ -1020,51 +1025,148 @@ expBySquaring : Int a, U8 -> Int a ## >>> Frac.sqrt -4.0dec sqrt : Frac a -> Frac a +## Bit shifts + +## [Logical bit shift](https://en.wikipedia.org/wiki/Bitwise_operation#Logical_shift) left. +## +## `a << b` is shorthand for `Num.shl a b`. +shl : Int a, Int a -> Int a + +## [Arithmetic bit shift](https://en.wikipedia.org/wiki/Bitwise_operation#Arithmetic_shift) left. +## +## This is called `shlWrap` because any bits shifted +## off the beginning of the number will be wrapped around to +## the end. (In contrast, [shl] replaces discarded bits with zeroes.) +shlWrap : Int a, Int a -> Int a + +## [Logical bit shift](https://en.wikipedia.org/wiki/Bitwise_operation#Logical_shift) right. +## +## `a >> b` is shorthand for `Num.shr a b`. +shr : Int a, Int a -> Int a + +## [Arithmetic bit shift](https://en.wikipedia.org/wiki/Bitwise_operation#Arithmetic_shift) right. +## +## This is called `shlWrap` because any bits shifted +## off the end of the number will be wrapped around to +## the beginning. (In contrast, [shr] replaces discarded bits with zeroes.) +shrWrap : Int a, Int a -> Int a + + ## [Endianness](https://en.wikipedia.org/wiki/Endianness) Endi : [ Big, Little ] toBytes : Num *, Endi -> List U8 + +## Comparison + +## Returns `True` if the first number is less than the second. +## +## `a < b` is shorthand for `Num.isLt a b`. +## +## If either argument is [*NaN*](Num.isNaN), returns `False` no matter what. (*NaN* +## is [defined to be unordered](https://en.wikipedia.org/wiki/NaN#Comparison_with_NaN).) +## +## >>> 5 +## >>> |> Num.isLt 6 +isLt : Num a, Num a -> Bool + +## Returns `True` if the first number is less than or equal to the second. +## +## `a <= b` is shorthand for `Num.isLte a b`. +## +## If either argument is [*NaN*](Num.isNaN), returns `False` no matter what. (*NaN* +## is [defined to be unordered](https://en.wikipedia.org/wiki/NaN#Comparison_with_NaN).) +isLte : Num a, Num a -> Bool + +## Returns `True` if the first number is greater than the second. +## +## `a > b` is shorthand for `Num.isGt a b`. +## +## If either argument is [*NaN*](Num.isNaN), returns `False` no matter what. (*NaN* +## is [defined to be unordered](https://en.wikipedia.org/wiki/NaN#Comparison_with_NaN).) +## +## >>> 6 +## >>> |> Num.isGt 5 +isGt : Num a, Num a -> Bool + +## Returns `True` if the first number is greater than or equal to the second. +## +## `a >= b` is shorthand for `Num.isGte a b`. +## +## If either argument is [*NaN*](Num.isNaN), returns `False` no matter what. (*NaN* +## is [defined to be unordered](https://en.wikipedia.org/wiki/NaN#Comparison_with_NaN).) +isGte : Num a, Num a -> Bool + +## Returns the higher of two numbers. +## +## If either argument is [*NaN*](Num.isNaN), returns `False` no matter what. (*NaN* +## is [defined to be unordered](https://en.wikipedia.org/wiki/NaN#Comparison_with_NaN).) +higher : Num a, Num a -> Num a + +## Returns the lower of two numbers. +## +## If either argument is [*NaN*](Num.isNaN), returns `False` no matter what. (*NaN* +## is [defined to be unordered](https://en.wikipedia.org/wiki/NaN#Comparison_with_NaN).) +lower : Num a, Num a -> Num a + +# Branchless implementation that works for all numeric types: +# +# let is_lt = arg1 < arg2; +# let is_eq = arg1 == arg2; +# return (is_lt as i8 - is_eq as i8) + 1; +# +# 1, 1 -> (0 - 1) + 1 == 0 # Eq +# 5, 1 -> (0 - 0) + 1 == 1 # Gt +# 1, 5 -> (1 - 0) + 1 == 2 # Lt + +## Returns `Lt` if the first number is less than the second, `Gt` if +## the first is greater than the second, and `Eq` if they're equal. +## +## Although this can be passed to [List.sort], you'll get better performance +## by using [List.sortAsc] or [List.sortDesc] instead. +compare : Num a, Num a -> [ Lt, Eq, Gt ] + +## Special Floating-Point Values + ## When given a [F64] or [F32] value, returns `False` if that value is -## [*NaN*](https://en.wikipedia.org/wiki/NaN). (Returns `False` if that value is *Infinity* or *-Infinity*.) +## [*NaN*](Num.isNaN), ∞ or -∞, and `True` otherwise. +## +## Always returns `True` when given a [Dec]. +## +## This is the opposite of [isInfinite], except when given [*NaN*](Num.isNaN). Both +## [isFinite] and [isInfinite] return `False` for [*NaN*](Num.isNaN). +isFinite : Frac * -> Bool + +## When given a [F64] or [F32] value, returns `True` if that value is either +## ∞ or -∞, and `False` otherwise. +## +## Always returns `False` when given a [Dec]. +## +## This is the opposite of [isFinite], except when given [*NaN*](Num.isNaN). Both +## [isFinite] and [isInfinite] return `False` for [*NaN*](Num.isNaN). +isInfinite : Frac * -> Bool + +## When given a [F64] or [F32] value, returns `True` if that value is +## *NaN* ([not a number](https://en.wikipedia.org/wiki/NaN)), and `False` otherwise. ## ## Always returns `False` when given a [Dec]. ## ## >>> Num.isNaN 12.3 ## -## >>> Num.isNaN (Num.sqrtOrNaN -2) +## >>> Num.isNaN (Num.sqrt -2) ## -## See also [isFinite]. +## *NaN* is unusual from other numberic values in that: +## * *NaN* is not equal to any other number, even itself. [Bool.isEq] always returns `False` if either argument is *NaN*. +## * *NaN* has no ordering, so [isLt], [isLte], [isGt], and [isGte] always return `False` if either argument is *NaN*. +## +## These rules come from the [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754) +## floating point standard. Because almost all modern processors are built to +## this standard, deviating from these rules has a significant performance +## cost! Since the most common reason to choose [F64] or [F32] over [Dec] is +## access to hardware-accelerated performance, Roc follows these rules exactly. +## +## Note that you should never put a *NaN* into a [Set], or use it as the key in +## a [Dict]. The result is entries that can never be removed from those +## collections! See the documentation for [Set.add] and [Dict.insert] for details. isNaN : Frac * -> Bool - -## When given a [F64] or [F32] value, returns `False` if that value is -## [*NaN*](https://en.wikipedia.org/wiki/NaN), *Infinity*, or *-Infinity*. -## -## Always returns `True` when given a [Dec]. -## -## See also [isInfinite]. -isFinite : Frac * -> Bool - -## When given a [F64] or [F32] value, returns `True` if that value is either -## *Infinity* or *-Infinity*. (Returns `False` if that value is [*NaN*](https://en.wikipedia.org/wiki/NaN).) -## -## Always returns `False` when given a [Dec]. -## -## See also [isFinite], [isPositiveInfinity], and [isNegativeInfinity]. -isInfinite : Frac * -> Bool - -## When given a [F64] or [F32] value, returns `True` if that value is -## *Infinity*. (Returns `False` if that value is *-Infinity* or [*NaN*](https://en.wikipedia.org/wiki/NaN).) -## -## Always returns `False` when given a [Dec]. -## -## See also [isNegativeInfinity], [isInfinite], and [isFinite]. -isPositiveInfinity : Frac * -> Bool - -## When given a [F64] or [F32] value, returns `True` if that value is -## *Infinity*. (Returns `False` if that value is *-Infinity* or [*NaN*](https://en.wikipedia.org/wiki/NaN).) -## -## Always returns `False` when given a [Dec]. -## -## See also [isPositiveInfinity], [isInfinite], and [isFinite]. -isNegativeInfinity : Frac * -> Bool diff --git a/compiler/builtins/docs/Set.roc b/compiler/builtins/docs/Set.roc index 2a6d70cc63..0033ee392e 100644 --- a/compiler/builtins/docs/Set.roc +++ b/compiler/builtins/docs/Set.roc @@ -18,7 +18,9 @@ len : Set * -> Nat # TODO: removed `'` from signature because parser does not support it yet # Original signature: `add : Set 'elem, 'elem -> Set 'elem` -## Since NaN is defined to be unequal to NaN, panics if given NaN. +## Make sure never to add a *NaN* to a [Set]! Becuase *NaN* is defined to be +## unequal to *NaN*, adding a *NaN* results in an entry that can never be +## retrieved or removed from the [Set]. add : Set elem, elem -> Set elem ## Drops the given element from the set. diff --git a/compiler/builtins/docs/Str.roc b/compiler/builtins/docs/Str.roc index fae7e7e5f6..d5374b5662 100644 --- a/compiler/builtins/docs/Str.roc +++ b/compiler/builtins/docs/Str.roc @@ -456,10 +456,17 @@ parseU64 : Str, NumParseConfig -> Result { val : U64, rest : Str } [ Expected [ parseI64 : Str, NumParseConfig -> Result { val : I64, rest : Str } [ Expected [ NumI64 ]* Str ]* parseU128 : Str, NumParseConfig -> Result { val : U128, rest : Str } [ Expected [ NumU128 ]* Str ]* parseI128 : Str, NumParseConfig -> Result { val : I128, rest : Str } [ Expected [ NumI128 ]* Str ]* -parseF64 : Str, NumParseConfig -> Result { val : U128, rest : Str } [ Expected [ NumF64 ]* Str ]* -parseF32 : Str, NumParseConfig -> Result { val : I128, rest : Str } [ Expected [ NumF32 ]* Str ]* parseDec : Str, NumParseConfig -> Result { val : Dec, rest : Str } [ Expected [ NumDec ]* Str ]* +## If the string begins with a [finite](Num.isFinite) [F64] number, return +## that number along with the rest of the string after it. +## +## If the string begins with `"NaN"`, `"∞"`, and `"-∞"` (which do not represent +## [finite](Num.isFinite) numbers), they will be similarly accepted and +## translated into their respective [F64] values. +parseF64 : Str, NumParseConfig -> Result { val : F64, rest : Str } [ Expected [ NumF64 ]* Str ]* +parseF32 : Str, NumParseConfig -> Result { val : F32, rest : Str } [ Expected [ NumF32 ]* Str ]* + ## Notes: ## * You can allow a decimal mark for integers; they'll only parse if the numbers after it are all 0. ## * For `wholeSep`, `Required` has a payload for how many digits (e.g. "required every 3 digits") diff --git a/editor/src/lang/pool.rs b/editor/src/lang/pool.rs index 435f49fdf5..975d2b2655 100644 --- a/editor/src/lang/pool.rs +++ b/editor/src/lang/pool.rs @@ -42,6 +42,23 @@ pub const NODE_BYTES: usize = 32; // usize pointers, which would be too big for us to have 16B nodes. // On the plus side, we could be okay with higher memory usage early on, // and then later use the Mesh strategy to reduce long-running memory usage. +// +// With this system, we can allocate up to 4B nodes. If we wanted to keep +// a generational index in there, like https://crates.io/crates/sharded-slab +// does, we could use some of the 32 bits for that. For example, if we wanted +// to have a 5-bit generational index (supporting up to 32 generations), then +// we would have 27 bits remaining, meaning we could only support at most +// 134M nodes. Since the editor has a separate Pool for each module, is that +// enough for any single module we'll encounter in practice? Probably, and +// especially if we allocate super large collection literals on the heap instead +// of in the pool. +// +// Another possible design is to try to catch reuse bugs using an "ASan" like +// approach: in development builds, whenever we "free" a particular slot, we +// can add it to a dev-build-only "freed nodes" list and don't hand it back +// out (so, we leak the memory.) Then we can (again, in development builds only) +// check to see if we're about to store something in zeroed-out memory; if so, check +// to see if it was #[derive(Debug, Eq)] pub struct NodeId { diff --git a/roc-for-elm-programmers.md b/roc-for-elm-programmers.md index bad83663cd..575eb461e3 100644 --- a/roc-for-elm-programmers.md +++ b/roc-for-elm-programmers.md @@ -1427,6 +1427,8 @@ Here are various Roc expressions involving operators, and what they desugar to. | `a ^ b` | `Num.pow a b` | | `a % b` | `Num.rem a b` | | `a %% b` | `Num.mod a b` | +| `a >> b` | `Num.shr a b` | +| `a << b` | `Num.shl a b` | | `-a` | `Num.neg a` | | `-f x y` | `Num.neg (f x y)` | | `a == b` | `Bool.isEq a b` | From 49a85bd9464df852695c37e3633aca08a34eb819 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Fri, 4 Jun 2021 21:27:38 -0400 Subject: [PATCH 20/52] Drop obsolete docs --- compiler/builtins/docs/Num.roc | 142 --------------------------------- 1 file changed, 142 deletions(-) diff --git a/compiler/builtins/docs/Num.roc b/compiler/builtins/docs/Num.roc index fee411fb71..e57bb469f3 100644 --- a/compiler/builtins/docs/Num.roc +++ b/compiler/builtins/docs/Num.roc @@ -319,148 +319,6 @@ Nat : Int [ @Natural ] ## If you need to do math outside these bounds, consider using a larger numeric size. Int size : Num [ @Int size ] -## A 64-bit floating-point number. All number literals with decimal points are #Frac values. -## -## >>> 0.1 -## -## >>> 1.0 -## -## >>> 0.0 -## -## If you like, you can put underscores in your #Frac literals. -## They have no effect on the number's value, but can make things easier to read. -## -## >>> 1_000_000.000_000_001 -## -## Roc supports two types of floating-point numbers: -## -## - *Decimal* floating-point numbers -## - *Binary* floating-point numbers -## -## Decimal floats are precise for decimal calculations. For example: -## -## >>> 0.1 + 0.2 -## -## Operations on binary floats tend to run *much* faster than operations on -## decimal floats, because almost all processors have dedicated instructions -## for binary floats and not for decimal floats. -## However, binary floats are less precise for decimal calculations. -## -## For example, here is the same `0.1 + 0.2` calculation again, this time putting -## `f64` after the numbers to specify that they should be #F64 binary floats -## instead of the default of decimal floats. -## -## >>> 0.1f64 + 0.2f64 -## -## If decimal precision is unimportant, binary floats give better performance. -## If decimal precision is important - for example, when representing money - -## decimal floats tend to be worth the performance cost. -## -## Usually, Roc's compiler can infer a more specific type than #Frac for -## a particular float value, based on how it is used with other numbers. For example: -## -## >>> coordinates : { x : F32, y : F32 } -## >>> coordinates = { x: 1, y: 2.5 } -## >>> -## >>> coordinates.x + 1 -## -## On the last line, the compiler infers that the `1` in `+ 1` is an #F32 -## beacuse it's being added to `coordinates.x`, which was defined to be an #F32 -## on the first line. -## -## Sometimes the compiler has no information about which specific type to pick. -## For example: -## -## >>> 0.1 + 0.2 == 0.3 -## -## When this happens, the compiler defaults to choosing #D64 decimal floats. -## If you want something else, you can write (for example) `0.1f32 + 0.2 == 0.3` -## to compare them as #F32 values instead. -## -## Both decimal and binary #Frac values conform to the [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754#Interchange_formats) -## specification for floating point numbers. Conforming to this specification -## means Roc's binary floats have nearly universal hardware support, and its -## decimal floats have [some hardware support](http://speleotrove.com/decimal/) -## among the rare processors which support decimal float instructions at all. -## -## This specification covers several float formats. Here are the ones Roc supports: -## -## - #F32 (32-bit binary float) -## - #F64 (64-bit binary float) -## - #D32 (32-bit decimal float) -## - #D64 (64-bit decimal float) # TODO show a table like we do with ints, with the min/max ranges -## -## Like #Int, it's possible for #Frac operations to overflow. Like with ints, -## you'll typically get a crash when this happens. -## -## * In a development build, you'll get an assertion failure. -## * In an optimized build, you'll get [`Infinity` or `-Infinity`](https://en.wikipedia.org/wiki/IEEE_754-1985#Positive_and_negative_infinity). -## -## Although some languages treat have first-class representations for -## `-Infinity`, `Infinity`, and the special `NaN` ("not a number") -## floating-point values described in the IEEE-754, Roc does not. -## Instead, Roc treats all of these as errors. If any Frac operation -## in a development build encounters one of these values, it will -## result in an assertion failure. -## -## Stll, it's possible that these values may accidentally arise in -## release builds. If this happens, they will behave according to the usual -## IEEE-754 rules: any operation involving `NaN` will output `NaN`, -## any operation involving `Infinity` or `-Infinity` will output either -## `Infinity`, `-Infinity`, or `NaN`, and `NaN` is defined to be not -## equal to itself - meaning `(x == x)` returns `False` if `x` is `NaN`. -## -## These are very error-prone values, so if you see an assertion fail in -## developent because of one of them, take it seriously - and try to fix -## the code so that it can't come up in a release! -## -## ## Loud versus Quiet errors -## -## Besides precision problems, another reason floats are error-prone -## is that they have quiet error handling built in. For example, in -## a 64-bit floating point number, there are certain patterns of those -## 64 bits which do not represent valid floats; instead, they represent -## invalid results of previous operations. -## -## Whenever any arithmetic operation is performed on an invalid float, -## the result is also invalid. This is called *error propagation*, and -## it is notoriously error-prone. In Roc, using equality operations like -## `==` and `!=` on an invalid float causes a crash. (See #Frac.verify -## to check the validity of your float.) -## -## Beause invalid floats are so error-prone, Roc discourages using them. -## Instead, by default it treats them the same way as overflow: by -## crashing whenever any #Frac function would otherwise return one. -## You can also use functions like #Frac.tryAdd to get an `Ok` or an error -## back so you can gracefully recover from invalid values. -## -## Quiet errors can be useful sometimes. For example, you might want to -## do three floating point calculations in a row, and then gracefully handle -## the situation where any one of the three was invalid. In that situation, -## quiet errors can be more efficient than using three `try` functions, because -## it can have one condition at the end instead of three along the way. -## -## Another potential use for quiet errors is for risky performance optimizations. -## When you are absolutely certain there is no chance of overflow or other -## errors, using a *quiet* operation may save an entry in the instruction cache -## by removing a branch that would always have been predicted correctly. -## Always [measure the performance change](https://youtu.be/r-TLSBdHe1A) -## if you do this! The compiler can optimize away those branches behind the scenes, -## so you may find that using the quiet version expliitly -## makes the code riskier to future change, without actually affecting performance. -## -## ## Performance Notes -## -## Currently, loud errors are implemented using an extra conditional. Although -## this conditional will always be correctly branh-predicted unless an error -## occurs, there is a small effect on the instruction cache, which means -## quiet errors are very slightly more efficient. -## -## Long-term, it's possible that the Roc compiler may be able to implement -## loud errors using *signalling errors* in some situations, which could -## eliminate the performance difference between loud and quiet errors in -## the situation where no error occurs. - ## Convert ## Return a negative number when given a positive one, and vice versa. From c8ad4a2ca29ec2f261f7c4b5c9ad72886d763b0c Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Fri, 4 Jun 2021 21:27:42 -0400 Subject: [PATCH 21/52] Fix missing cast --- docs/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/lib.rs b/docs/src/lib.rs index 9bd0d2fa93..bfa9f7ffa1 100644 --- a/docs/src/lib.rs +++ b/docs/src/lib.rs @@ -305,7 +305,7 @@ pub fn files_to_documentations( &std_lib, src_dir.as_path(), MutMap::default(), - std::mem::size_of::(), // This is just type-checking for docs, so "target" doesn't matter + std::mem::size_of::() as u32, // This is just type-checking for docs, so "target" doesn't matter builtin_defs_map, ) { Ok(loaded) => files_docs.push((loaded.documentation, loaded.interns)), From 3acd9d13961d48d8d29daf0d1902d2e7a7cff8d1 Mon Sep 17 00:00:00 2001 From: Anton-4 <17049058+Anton-4@users.noreply.github.com> Date: Sat, 5 Jun 2021 16:42:06 +0200 Subject: [PATCH 22/52] stackoverflow fix + cargo criterion fix --- .github/workflows/benchmarks.yml | 3 +++ Earthfile | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/benchmarks.yml b/.github/workflows/benchmarks.yml index 967db61cc0..41639a5ebb 100644 --- a/.github/workflows/benchmarks.yml +++ b/.github/workflows/benchmarks.yml @@ -20,5 +20,8 @@ jobs: - name: Earthly version run: earthly --version + - name: prune cache + run: earthly prune --reset + - name: install dependencies, build, cd cli, benchmark with criterion run: ./ci/safe-earthly.sh +bench-roc diff --git a/Earthfile b/Earthfile index ece11b44e4..d3f04bfadd 100644 --- a/Earthfile +++ b/Earthfile @@ -115,7 +115,7 @@ bench-roc: FROM +copy-dirs-and-cache ENV RUST_BACKTRACE=full RUN cargo criterion -V - RUN ulimit -s unlimited # to prevent stack overflow errors for CFold + # ulimit -s unlimited to prevent stack overflow errors for CFold RUN --privileged --mount=type=cache,target=$SCCACHE_DIR \ - cd cli && cargo criterion && sccache --show-stats + ulimit -s unlimited && cd cli && cargo criterion && sccache --show-stats From 526481e847870a80b26d1a4202b51eed03b2fa31 Mon Sep 17 00:00:00 2001 From: Anton-4 <17049058+Anton-4@users.noreply.github.com> Date: Sat, 5 Jun 2021 16:49:31 +0200 Subject: [PATCH 23/52] don't clear cache anymore --- .github/workflows/benchmarks.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/benchmarks.yml b/.github/workflows/benchmarks.yml index 41639a5ebb..967db61cc0 100644 --- a/.github/workflows/benchmarks.yml +++ b/.github/workflows/benchmarks.yml @@ -20,8 +20,5 @@ jobs: - name: Earthly version run: earthly --version - - name: prune cache - run: earthly prune --reset - - name: install dependencies, build, cd cli, benchmark with criterion run: ./ci/safe-earthly.sh +bench-roc From df8d4cd270ff363b415050942a513cecef116cea Mon Sep 17 00:00:00 2001 From: Anton-4 <17049058+Anton-4@users.noreply.github.com> Date: Sat, 5 Jun 2021 17:10:42 +0200 Subject: [PATCH 24/52] increased quicksort list size to 10k --- cli/benches/time_bench.rs | 2 +- cli/cli_utils/src/bench_utils.rs | 2 +- cli/tests/cli_run.rs | 27 ++++++++++++--------------- examples/benchmarks/QuicksortApp.roc | 4 ++-- 4 files changed, 16 insertions(+), 19 deletions(-) diff --git a/cli/benches/time_bench.rs b/cli/benches/time_bench.rs index 491db64784..062d615533 100644 --- a/cli/benches/time_bench.rs +++ b/cli/benches/time_bench.rs @@ -17,7 +17,7 @@ fn bench_group_wall_time(c: &mut Criterion) { bench_deriv, // nest deriv 8 f bench_rbtree_ck, // ms = makeMap 5 80000 bench_rbtree_delete, // m = makeMap 100000 - bench_quicksort, // list size 2000 + bench_quicksort, // list size 10000 ]; for bench_func in bench_funcs.iter() { diff --git a/cli/cli_utils/src/bench_utils.rs b/cli/cli_utils/src/bench_utils.rs index 03d1e1f3e8..d74e3f5bad 100644 --- a/cli/cli_utils/src/bench_utils.rs +++ b/cli/cli_utils/src/bench_utils.rs @@ -129,7 +129,7 @@ pub fn bench_quicksort(bench_group_opt: Option<&mut BenchmarkGro &example_file("benchmarks", "QuicksortApp.roc"), "1", // 1 for sorting large list, 0 for a small list "quicksortapp", - "[ 0, 0, 0, 1, 2, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 13, 13, 14, 14, 16, 16, 16, 17, 17, 17, 18, 19, 20, 22, 22, 23, 24, 24, 24, 24, 25, 26, 26, 26, 26, 27, 27, 29, 29, 30, 30, 30, 30, 31, 31, 31, 31, 32, 32, 32, 33, 33, 33, 33, 34, 35, 35, 35, 35, 36, 36, 36, 37, 38, 39, 40, 41, 42, 43, 43, 43, 44, 44, 44, 47, 47, 47, 48, 49, 49, 49, 49, 51, 51, 52, 52, 53, 53, 54, 54, 54, 54, 55, 56, 56, 57, 58, 59, 59, 60, 62, 63, 63, 64, 65, 65, 66, 66, 66, 67, 67, 67, 68, 68, 69, 69, 70, 70, 72, 72, 72, 72, 72, 72, 73, 73, 73, 74, 74, 74, 76, 77, 77, 77, 78, 78, 78, 79, 79, 79, 80, 80, 80, 81, 81, 82, 82, 83, 83, 83, 83, 84, 85, 86, 86, 88, 88, 88, 88, 88, 89, 89, 90, 90, 91, 91, 92, 92, 93, 93, 94, 95, 95, 96, 96, 96, 98, 98, 99, 100, 101, 101, 102, 104, 105, 105, 106, 106, 107, 107, 108, 109, 112, 112, 113, 113, 113, 113, 113, 113, 115, 116, 116, 117, 118, 121, 122, 122, 122, 123, 123, 123, 123, 123, 124, 124, 125, 125, 126, 126, 126, 126, 127, 127, 128, 129, 130, 130, 130, 131, 131, 132, 132, 132, 133, 133, 135, 135, 135, 135, 136, 136, 137, 137, 139, 139, 139, 139, 141, 142, 144, 145, 146, 146, 146, 146, 146, 147, 147, 148, 148, 148, 148, 148, 148, 149, 149, 149, 150, 151, 151, 152, 152, 152, 153, 153, 153, 153, 154, 155, 155, 155, 156, 159, 159, 159, 160, 160, 160, 161, 161, 161, 162, 162, 162, 162, 165, 166, 166, 166, 167, 167, 167, 168, 168, 168, 169, 170, 170, 172, 172, 172, 172, 174, 174, 175, 176, 177, 178, 178, 178, 179, 180, 180, 180, 180, 180, 181, 182, 183, 183, 183, 184, 184, 185, 185, 186, 186, 187, 187, 187, 188, 188, 189, 189, 189, 189, 190, 190, 191, 191, 192, 193, 193, 193, 193, 193, 193, 194, 194, 195, 195, 195, 195, 195, 196, 197, 198, 198, 199, 199, 199, 199, 200, 201, 202, 202, 202, 202, 203, 204, 204, 205, 205, 205, 206, 206, 206, 207, 208, 209, 210, 210, 210, 210, 211, 211, 211, 211, 212, 212, 212, 212, 213, 213, 213, 213, 214, 214, 214, 215, 215, 215, 216, 216, 216, 216, 217, 217, 218, 218, 219, 220, 220, 220, 221, 221, 222, 222, 222, 222, 223, 223, 223, 225, 225, 225, 226, 227, 227, 228, 228, 229, 229, 229, 229, 231, 231, 233, 234, 234, 234, 234, 234, 234, 235, 235, 235, 235, 236, 236, 237, 238, 238, 238, 238, 238, 239, 239, 240, 240, 241, 241, 241, 241, 241, 242, 243, 243, 243, 244, 247, 248, 248, 248, 249, 249, 249, 250, 250, 250, 251, 252, 252, 254, 254, 254, 254, 254, 255, 255, 256, 257, 258, 259, 260, 261, 262, 262, 262, 262, 262, 263, 264, 264, 264, 265, 265, 266, 266, 266, 267, 269, 269, 269, 270, 270, 271, 271, 272, 273, 274, 274, 275, 275, 275, 276, 277, 277, 277, 278, 278, 279, 279, 281, 282, 282, 286, 287, 287, 287, 287, 287, 288, 288, 288, 288, 288, 288, 289, 289, 290, 290, 290, 291, 291, 292, 292, 292, 293, 293, 293, 293, 293, 293, 293, 294, 294, 294, 294, 295, 296, 296, 297, 297, 298, 298, 300, 300, 301, 301, 301, 301, 301, 302, 303, 303, 303, 304, 304, 304, 305, 305, 305, 306, 306, 308, 308, 309, 309, 310, 311, 312, 312, 312, 312, 313, 313, 313, 314, 314, 315, 316, 316, 317, 317, 318, 318, 318, 318, 319, 319, 320, 322, 322, 323, 323, 324, 324, 325, 325, 326, 328, 329, 329, 329, 330, 330, 330, 332, 332, 332, 333, 333, 333, 333, 334, 334, 334, 334, 335, 335, 335, 335, 335, 335, 336, 336, 337, 337, 338, 338, 338, 339, 339, 340, 341, 342, 342, 343, 343, 344, 344, 345, 345, 345, 346, 346, 348, 349, 349, 349, 349, 350, 350, 350, 351, 351, 351, 352, 352, 352, 352, 353, 353, 353, 353, 355, 355, 355, 355, 355, 356, 357, 357, 357, 358, 358, 359, 359, 359, 360, 360, 361, 361, 361, 362, 362, 363, 364, 365, 365, 367, 367, 368, 368, 369, 369, 369, 369, 369, 371, 371, 371, 371, 372, 372, 373, 373, 373, 374, 374, 375, 375, 376, 376, 376, 377, 377, 378, 378, 378, 378, 378, 378, 379, 379, 381, 381, 381, 382, 383, 383, 384, 384, 385, 385, 385, 386, 386, 386, 386, 387, 387, 388, 388, 388, 389, 389, 389, 390, 390, 390, 391, 391, 392, 392, 393, 393, 394, 394, 394, 394, 394, 395, 396, 397, 397, 397, 398, 399, 399, 400, 400, 400, 400, 401, 401, 401, 401, 402, 402, 402, 402, 402, 402, 403, 404, 404, 404, 404, 405, 405, 405, 405, 407, 409, 409, 410, 410, 410, 410, 410, 413, 414, 414, 416, 417, 417, 417, 418, 418, 418, 419, 419, 419, 420, 420, 420, 421, 422, 422, 425, 426, 426, 427, 427, 427, 428, 428, 428, 429, 430, 431, 433, 433, 433, 435, 435, 436, 436, 436, 437, 438, 438, 438, 439, 439, 439, 441, 442, 443, 443, 443, 443, 444, 444, 444, 445, 445, 447, 447, 447, 448, 448, 449, 450, 450, 450, 450, 451, 451, 451, 451, 452, 452, 452, 452, 453, 453, 454, 454, 454, 454, 455, 455, 455, 456, 456, 457, 457, 457, 457, 458, 459, 460, 460, 461, 461, 462, 462, 464, 464, 464, 465, 467, 467, 468, 469, 469, 469, 469, 471, 471, 472, 472, 473, 474, 474, 474, 475, 475, 476, 476, 477, 477, 479, 479, 480, 481, 481, 482, 483, 484, 484, 485, 485, 486, 486, 487, 487, 487, 487, 488, 489, 489, 489, 489, 490, 490, 490, 491, 493, 493, 493, 494, 494, 495, 495, 495, 495, 497, 497, 499, 499, 500, 500, 501, 501, 502, 502, 502, 503, 505, 505, 506, 506, 507, 508, 508, 508, 508, 510, 510, 511, 511, 512, 512, 513, 514, 514, 515, 516, 516, 516, 516, 517, 517, 517, 518, 518, 519, 521, 522, 522, 523, 523, 523, 523, 523, 525, 526, 526, 526, 527, 527, 528, 529, 530, 530, 531, 531, 532, 532, 532, 532, 533, 533, 533, 533, 533, 534, 534, 535, 535, 537, 539, 539, 540, 541, 542, 542, 543, 544, 547, 547, 547, 547, 547, 547, 548, 549, 550, 551, 551, 551, 552, 552, 555, 557, 558, 558, 558, 558, 559, 559, 560, 560, 561, 561, 562, 563, 563, 563, 563, 563, 564, 566, 566, 566, 567, 567, 567, 568, 568, 568, 569, 569, 571, 572, 573, 573, 574, 574, 575, 577, 578, 578, 580, 581, 582, 582, 582, 582, 583, 583, 585, 587, 587, 587, 588, 588, 589, 589, 590, 590, 590, 590, 591, 591, 591, 592, 593, 593, 595, 596, 597, 597, 598, 598, 599, 599, 600, 600, 600, 602, 602, 602, 603, 604, 605, 605, 606, 606, 606, 608, 608, 608, 608, 609, 610, 610, 610, 610, 611, 611, 612, 612, 613, 613, 614, 614, 614, 616, 616, 616, 617, 617, 617, 618, 618, 618, 618, 618, 618, 618, 619, 619, 619, 619, 619, 619, 619, 620, 620, 621, 621, 621, 624, 624, 624, 624, 625, 625, 625, 625, 626, 628, 628, 628, 630, 630, 630, 631, 631, 631, 632, 632, 632, 633, 635, 635, 635, 636, 637, 637, 638, 638, 638, 639, 639, 639, 640, 642, 643, 644, 645, 646, 646, 650, 650, 651, 651, 651, 653, 654, 654, 654, 655, 655, 656, 656, 657, 658, 659, 659, 661, 661, 661, 662, 662, 663, 663, 663, 663, 664, 665, 665, 665, 665, 666, 666, 667, 668, 668, 669, 669, 669, 670, 670, 672, 672, 672, 672, 672, 673, 674, 674, 675, 675, 676, 676, 676, 677, 677, 677, 678, 678, 679, 679, 679, 679, 679, 680, 680, 682, 683, 683, 684, 684, 685, 685, 685, 686, 687, 687, 687, 687, 687, 687, 688, 689, 689, 689, 691, 691, 692, 692, 693, 693, 696, 697, 697, 698, 698, 698, 698, 698, 699, 699, 700, 700, 700, 700, 703, 704, 704, 704, 704, 704, 705, 705, 705, 706, 706, 707, 707, 707, 708, 708, 708, 710, 711, 711, 711, 711, 712, 712, 713, 713, 713, 713, 713, 713, 713, 714, 714, 714, 715, 716, 717, 717, 717, 718, 718, 718, 719, 719, 719, 719, 719, 719, 720, 720, 720, 721, 721, 723, 723, 723, 724, 724, 725, 726, 727, 727, 727, 727, 728, 729, 729, 730, 730, 730, 730, 731, 732, 733, 734, 734, 734, 735, 735, 736, 736, 736, 736, 737, 737, 738, 739, 739, 739, 740, 743, 743, 743, 743, 743, 744, 744, 745, 745, 746, 746, 746, 747, 747, 748, 749, 750, 750, 751, 751, 751, 752, 752, 753, 753, 753, 753, 753, 753, 754, 754, 756, 757, 757, 758, 758, 758, 759, 759, 760, 760, 760, 761, 762, 762, 762, 763, 763, 766, 768, 768, 768, 768, 768, 769, 769, 772, 773, 773, 774, 775, 775, 776, 776, 776, 776, 776, 777, 777, 777, 778, 779, 779, 779, 780, 780, 780, 781, 782, 782, 782, 783, 783, 783, 783, 784, 785, 785, 785, 785, 786, 786, 786, 786, 786, 787, 788, 789, 789, 789, 790, 790, 791, 791, 791, 792, 792, 792, 792, 793, 793, 794, 794, 797, 797, 798, 798, 799, 799, 799, 800, 801, 801, 802, 803, 804, 804, 805, 805, 805, 805, 807, 807, 807, 807, 808, 808, 808, 808, 809, 809, 810, 810, 811, 811, 812, 813, 814, 815, 816, 816, 817, 818, 819, 819, 820, 820, 820, 822, 822, 823, 823, 823, 823, 826, 826, 827, 827, 829, 830, 830, 831, 831, 832, 832, 832, 833, 833, 833, 834, 834, 835, 835, 835, 836, 836, 837, 837, 838, 838, 839, 840, 840, 841, 841, 842, 842, 843, 844, 844, 845, 846, 846, 847, 847, 848, 849, 849, 851, 851, 851, 851, 852, 853, 853, 853, 854, 854, 854, 855, 856, 856, 857, 857, 858, 859, 859, 859, 860, 860, 860, 860, 860, 861, 861, 861, 861, 862, 862, 864, 865, 865, 865, 866, 866, 866, 866, 867, 868, 868, 868, 869, 869, 870, 871, 872, 872, 872, 872, 872, 873, 873, 873, 874, 874, 875, 875, 876, 877, 878, 879, 879, 880, 880, 880, 880, 882, 883, 884, 885, 885, 885, 886, 886, 886, 888, 889, 889, 891, 891, 891, 892, 892, 894, 894, 894, 894, 894, 894, 895, 896, 898, 898, 899, 899, 899, 900, 900, 901, 902, 902, 903, 905, 905, 905, 906, 906, 906, 907, 907, 907, 907, 907, 907, 907, 908, 908, 908, 908, 909, 909, 909, 910, 910, 911, 913, 913, 913, 913, 914, 914, 914, 915, 916, 917, 917, 917, 918, 918, 918, 919, 920, 920, 920, 920, 920, 920, 921, 921, 921, 922, 923, 924, 924, 924, 925, 925, 926, 926, 927, 928, 928, 928, 928, 929, 929, 930, 930, 931, 932, 932, 933, 934, 934, 934, 935, 935, 935, 936, 936, 937, 938, 938, 938, 939, 939, 939, 940, 940, 941, 941, 942, 942, 942, 943, 943, 943, 943, 943, 943, 944, 945, 946, 946, 946, 947, 947, 948, 948, 950, 950, 951, 951, 952, 952, 952, 953, 955, 955, 955, 956, 956, 957, 957, 958, 959, 959, 959, 959, 960, 961, 962, 963, 964, 964, 964, 965, 965, 965, 966, 966, 966, 967, 967, 967, 968, 968, 968, 969, 969, 970, 970, 971, 972, 973, 973, 974, 975, 975, 975, 976, 976, 977, 977, 977, 978, 978, 978, 979, 979, 980, 980, 981, 981, 982, 982, 982, 983, 986, 986, 988, 990, 991, 991, 991, 991, 991, 992, 992, 993, 993, 994, 994, 995, 995, 995, 995, 995, 997, 997, 997, 997, 998, 998, 999, 999, 999 ]\n", + "[ 0, 0, 1, 1, 2, 2, 2, 3, 3, 4, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8, 9, 10, 10, 11, 11, 12, 13, 13, 14, 14, 14, 15, 15, 15, 16, 16, 18, 18, 19, 19, 19, 20, 21, 21, 21, 21, 22, 23, 23, 23, 25, 26, 27, 27, 28, 28, 28, 29, 29, 29, 29, 30, 31, 32, 33, 34, 35, 35, 35, 36, 36, 36, 37, 38, 38, 39, 39, 39, 39, 39, 39, 40, 40, 41, 42, 42, 42, 42, 42, 43, 43, 44, 46, 47, 47, 47, 48, 50, 51, 51, 52, 52, 52, 53, 54, 54, 55, 55, 55, 56, 57, 57, 58, 58, 58, 58, 58, 59, 59, 60, 60, 61, 62, 63, 63, 63, 63, 64, 65, 65, 65, 66, 66, 66, 66, 67, 67, 68, 69, 69, 70, 70, 71, 71, 71, 72, 72, 73, 73, 73, 74, 75, 75, 75, 76, 78, 79, 79, 80, 81, 81, 82, 82, 83, 83, 84, 84, 86, 86, 87, 87, 88, 88, 88, 89, 89, 90, 90, 90, 91, 92, 92, 92, 93, 93, 93, 94, 95, 95, 96, 97, 98, 99, 100, 100, 101, 102, 102, 102, 104, 104, 105, 106, 106, 106, 106, 106, 106, 107, 107, 108, 108, 108, 109, 109, 109, 109, 110, 112, 112, 112, 113, 113, 113, 113, 113, 114, 115, 117, 117, 117, 118, 119, 119, 119, 120, 120, 121, 123, 124, 125, 125, 126, 126, 126, 126, 127, 129, 131, 131, 131, 131, 131, 131, 131, 132, 133, 133, 134, 134, 134, 135, 135, 135, 135, 135, 137, 138, 138, 138, 139, 139, 140, 141, 142, 142, 142, 144, 144, 145, 145, 145, 147, 147, 147, 147, 148, 149, 149, 149, 150, 150, 151, 151, 151, 151, 153, 155, 156, 159, 160, 160, 160, 161, 161, 162, 162, 162, 162, 162, 162, 163, 163, 163, 163, 163, 163, 164, 164, 164, 164, 164, 165, 165, 165, 165, 165, 166, 166, 166, 166, 166, 167, 167, 167, 167, 168, 169, 170, 170, 170, 170, 172, 172, 172, 173, 173, 173, 174, 175, 176, 177, 177, 178, 178, 178, 178, 179, 179, 180, 180, 181, 181, 182, 183, 183, 185, 186, 186, 186, 186, 186, 186, 186, 187, 187, 187, 188, 188, 188, 190, 190, 190, 190, 190, 192, 193, 194, 194, 194, 195, 195, 196, 197, 198, 198, 198, 199, 199, 199, 200, 200, 201, 201, 201, 204, 205, 205, 205, 207, 207, 207, 208, 208, 208, 208, 210, 210, 210, 210, 211, 211, 213, 214, 214, 214, 218, 218, 218, 218, 218, 218, 219, 221, 222, 223, 223, 223, 224, 224, 224, 224, 224, 224, 224, 225, 226, 226, 226, 226, 226, 227, 227, 228, 228, 229, 229, 229, 229, 230, 230, 230, 230, 232, 233, 233, 234, 235, 236, 236, 237, 237, 238, 240, 240, 242, 242, 243, 244, 246, 247, 247, 247, 247, 248, 248, 248, 249, 249, 249, 249, 249, 250, 250, 250, 251, 251, 252, 252, 253, 255, 255, 256, 256, 256, 257, 257, 257, 258, 258, 258, 258, 258, 259, 259, 260, 260, 260, 261, 261, 261, 262, 263, 265, 265, 266, 267, 267, 267, 268, 268, 268, 270, 270, 270, 271, 271, 273, 274, 274, 274, 275, 277, 277, 279, 279, 280, 281, 281, 282, 283, 283, 285, 286, 288, 288, 289, 289, 290, 290, 290, 290, 290, 291, 291, 291, 291, 292, 292, 292, 293, 294, 294, 295, 295, 295, 295, 295, 298, 298, 301, 301, 301, 302, 302, 303, 304, 305, 305, 306, 307, 307, 308, 308, 309, 309, 309, 309, 310, 310, 311, 311, 311, 312, 313, 313, 313, 314, 315, 316, 316, 316, 316, 317, 318, 318, 319, 319, 319, 320, 321, 321, 322, 322, 322, 322, 323, 323, 323, 324, 324, 324, 325, 326, 326, 328, 329, 329, 330, 330, 330, 331, 331, 331, 331, 332, 332, 333, 333, 333, 333, 334, 334, 334, 335, 336, 336, 337, 337, 337, 337, 339, 339, 340, 341, 341, 343, 344, 344, 345, 345, 345, 346, 346, 347, 348, 348, 348, 349, 350, 351, 351, 351, 352, 353, 354, 354, 354, 355, 356, 356, 357, 358, 358, 358, 359, 359, 360, 361, 361, 362, 362, 363, 364, 364, 365, 365, 365, 366, 366, 367, 367, 368, 368, 369, 369, 369, 370, 370, 370, 370, 370, 371, 372, 373, 373, 374, 374, 375, 375, 376, 377, 377, 378, 379, 381, 381, 383, 384, 385, 385, 385, 385, 386, 386, 387, 388, 388, 388, 389, 389, 390, 391, 391, 391, 392, 392, 393, 393, 394, 394, 394, 395, 395, 396, 396, 397, 397, 398, 399, 400, 400, 401, 401, 402, 402, 403, 404, 404, 405, 406, 406, 407, 407, 407, 408, 408, 408, 408, 408, 409, 409, 409, 411, 411, 412, 412, 413, 413, 413, 413, 413, 414, 414, 414, 415, 416, 416, 416, 416, 417, 417, 418, 418, 418, 418, 419, 420, 420, 420, 421, 421, 422, 422, 423, 423, 423, 424, 424, 424, 424, 425, 425, 425, 426, 426, 427, 427, 427, 428, 428, 429, 429, 429, 430, 430, 431, 432, 433, 433, 433, 434, 434, 434, 434, 437, 438, 438, 438, 438, 438, 439, 440, 441, 441, 442, 442, 443, 444, 444, 444, 445, 445, 445, 447, 447, 447, 448, 448, 449, 449, 450, 450, 450, 451, 452, 453, 453, 453, 453, 455, 455, 456, 456, 457, 458, 459, 459, 460, 460, 461, 461, 464, 465, 465, 465, 466, 466, 467, 467, 467, 467, 468, 469, 469, 470, 470, 471, 471, 471, 472, 473, 473, 473, 473, 474, 475, 475, 475, 476, 476, 476, 477, 477, 477, 478, 478, 479, 481, 481, 481, 482, 482, 482, 483, 483, 483, 484, 484, 485, 488, 488, 488, 488, 489, 490, 491, 491, 491, 492, 492, 493, 493, 493, 493, 493, 495, 495, 496, 496, 496, 496, 496, 496, 497, 497, 498, 498, 498, 498, 498, 499, 500, 500, 501, 501, 501, 502, 502, 502, 502, 503, 503, 503, 505, 505, 506, 507, 507, 507, 507, 508, 508, 510, 510, 510, 511, 511, 512, 512, 513, 513, 513, 513, 514, 514, 515, 516, 517, 518, 519, 519, 519, 520, 521, 521, 522, 522, 523, 523, 523, 525, 525, 526, 527, 527, 527, 528, 528, 528, 530, 531, 532, 532, 532, 532, 532, 535, 535, 537, 538, 538, 538, 540, 540, 540, 541, 541, 541, 541, 541, 542, 543, 543, 543, 543, 544, 544, 545, 545, 545, 546, 547, 547, 547, 548, 549, 549, 551, 552, 552, 553, 553, 553, 554, 554, 554, 555, 556, 557, 557, 557, 558, 558, 558, 559, 559, 559, 560, 560, 560, 561, 561, 561, 561, 562, 562, 562, 563, 563, 565, 566, 566, 567, 568, 569, 570, 570, 571, 571, 571, 571, 572, 572, 572, 574, 575, 576, 576, 577, 580, 581, 581, 582, 582, 582, 583, 583, 584, 585, 585, 585, 586, 587, 587, 588, 588, 588, 589, 591, 591, 591, 592, 592, 592, 593, 593, 593, 594, 594, 594, 594, 595, 595, 595, 596, 596, 596, 596, 596, 597, 597, 599, 599, 600, 600, 601, 601, 601, 602, 602, 603, 603, 604, 605, 605, 605, 606, 607, 608, 610, 612, 612, 613, 613, 614, 614, 615, 615, 615, 616, 616, 616, 617, 617, 619, 619, 619, 619, 620, 621, 621, 622, 624, 624, 624, 624, 625, 625, 628, 628, 628, 629, 629, 630, 630, 630, 630, 632, 633, 633, 634, 635, 638, 638, 639, 640, 641, 641, 643, 643, 644, 644, 644, 645, 645, 645, 646, 646, 646, 647, 647, 647, 647, 648, 648, 649, 650, 650, 650, 650, 650, 650, 651, 652, 652, 652, 653, 653, 653, 653, 654, 655, 655, 655, 655, 656, 657, 657, 657, 658, 658, 659, 659, 659, 659, 659, 660, 660, 661, 662, 663, 664, 665, 666, 666, 666, 667, 667, 667, 667, 667, 668, 668, 669, 670, 670, 670, 671, 672, 672, 672, 672, 672, 673, 673, 674, 674, 674, 675, 676, 676, 677, 678, 678, 679, 679, 680, 681, 681, 682, 683, 683, 684, 684, 685, 686, 686, 686, 686, 687, 687, 688, 690, 690, 691, 691, 693, 693, 694, 694, 697, 697, 698, 700, 701, 702, 702, 703, 703, 703, 704, 705, 706, 706, 707, 708, 708, 709, 709, 710, 710, 711, 712, 712, 712, 712, 712, 712, 713, 713, 714, 714, 716, 716, 716, 717, 717, 717, 718, 718, 718, 718, 719, 719, 719, 720, 720, 721, 721, 722, 723, 724, 725, 726, 726, 727, 729, 729, 729, 730, 730, 731, 731, 732, 732, 734, 734, 734, 735, 735, 736, 736, 736, 737, 737, 738, 739, 740, 740, 740, 741, 741, 742, 742, 742, 742, 744, 744, 744, 744, 745, 745, 745, 745, 746, 748, 749, 749, 749, 750, 750, 751, 751, 751, 752, 752, 753, 753, 754, 755, 756, 756, 756, 757, 757, 757, 757, 757, 761, 761, 762, 762, 762, 763, 763, 763, 763, 763, 764, 764, 764, 764, 765, 765, 766, 766, 766, 766, 767, 767, 767, 770, 770, 770, 770, 770, 771, 772, 772, 772, 773, 774, 775, 775, 775, 775, 776, 778, 778, 779, 779, 780, 780, 780, 781, 784, 784, 784, 786, 786, 786, 786, 787, 788, 789, 789, 789, 790, 791, 791, 792, 793, 793, 793, 794, 794, 795, 796, 797, 797, 798, 799, 799, 799, 800, 800, 800, 800, 801, 802, 802, 802, 802, 804, 806, 806, 806, 807, 807, 807, 807, 808, 809, 810, 810, 811, 812, 812, 812, 812, 812, 813, 813, 813, 814, 814, 814, 815, 816, 816, 817, 817, 817, 818, 818, 818, 819, 820, 820, 820, 820, 820, 821, 821, 823, 824, 824, 824, 825, 826, 826, 826, 826, 828, 828, 829, 829, 829, 829, 829, 830, 831, 831, 831, 831, 831, 832, 832, 833, 833, 833, 834, 834, 835, 835, 835, 835, 835, 836, 836, 836, 837, 839, 839, 839, 839, 839, 840, 840, 840, 841, 841, 842, 843, 844, 844, 844, 845, 845, 845, 845, 845, 846, 846, 846, 847, 847, 848, 848, 848, 849, 849, 850, 850, 851, 852, 852, 852, 852, 853, 855, 856, 857, 857, 858, 858, 858, 859, 860, 861, 861, 861, 861, 862, 863, 863, 863, 865, 865, 865, 866, 867, 867, 867, 868, 868, 870, 871, 872, 872, 873, 873, 873, 874, 874, 874, 875, 875, 875, 876, 877, 878, 878, 878, 878, 878, 879, 879, 879, 879, 880, 881, 881, 881, 882, 883, 885, 886, 886, 887, 887, 888, 888, 889, 889, 890, 890, 890, 892, 892, 892, 892, 893, 893, 894, 894, 894, 895, 896, 896, 896, 897, 899, 899, 900, 901, 901, 901, 901, 905, 905, 905, 905, 906, 907, 907, 907, 908, 908, 908, 908, 908, 908, 909, 909, 910, 910, 910, 912, 913, 913, 914, 914, 914, 915, 916, 916, 916, 916, 917, 917, 918, 919, 919, 919, 920, 920, 920, 920, 921, 921, 922, 923, 923, 923, 923, 923, 924, 925, 927, 927, 927, 928, 928, 929, 929, 929, 929, 930, 930, 931, 932, 932, 932, 933, 933, 934, 934, 935, 935, 936, 937, 937, 937, 939, 940, 940, 941, 941, 941, 941, 942, 942, 943, 943, 945, 946, 946, 946, 948, 949, 949, 951, 953, 953, 954, 954, 954, 954, 954, 955, 956, 956, 956, 957, 957, 957, 957, 959, 960, 960, 961, 961, 963, 963, 963, 964, 964, 964, 964, 965, 966, 967, 968, 969, 969, 970, 972, 972, 973, 973, 974, 975, 975, 975, 976, 977, 978, 978, 979, 979, 980, 980, 980, 980, 981, 982, 982, 984, 986, 986, 986, 986, 986, 987, 988, 988, 990, 990, 990, 990, 990, 991, 991, 991, 991, 991, 991, 992, 992, 992, 992, 992, 993, 993, 993, 993, 995, 996, 996, 996, 997, 997, 997, 997, 997, 998, 998, 998, 999, 999, 1000, 1001, 1001, 1002, 1003, 1003, 1004, 1004, 1004, 1006, 1007, 1007, 1007, 1008, 1008, 1008, 1009, 1010, 1010, 1011, 1011, 1012, 1012, 1012, 1013, 1013, 1013, 1014, 1014, 1014, 1016, 1016, 1016, 1017, 1017, 1017, 1018, 1018, 1018, 1019, 1019, 1020, 1020, 1021, 1021, 1021, 1022, 1023, 1023, 1023, 1024, 1024, 1024, 1025, 1026, 1026, 1027, 1028, 1028, 1028, 1028, 1029, 1029, 1029, 1030, 1031, 1031, 1032, 1033, 1034, 1034, 1035, 1035, 1036, 1038, 1039, 1039, 1040, 1040, 1040, 1040, 1040, 1040, 1042, 1042, 1043, 1043, 1043, 1043, 1044, 1045, 1045, 1045, 1045, 1047, 1047, 1048, 1048, 1049, 1049, 1050, 1050, 1051, 1051, 1053, 1053, 1053, 1054, 1054, 1055, 1055, 1056, 1056, 1057, 1057, 1058, 1058, 1058, 1058, 1059, 1059, 1059, 1061, 1061, 1061, 1061, 1062, 1062, 1062, 1063, 1063, 1063, 1063, 1064, 1064, 1064, 1064, 1064, 1065, 1065, 1066, 1066, 1067, 1067, 1069, 1069, 1069, 1070, 1071, 1071, 1072, 1072, 1072, 1073, 1073, 1074, 1074, 1074, 1075, 1076, 1077, 1077, 1078, 1078, 1078, 1079, 1079, 1079, 1081, 1082, 1082, 1083, 1084, 1084, 1084, 1084, 1085, 1085, 1086, 1086, 1087, 1087, 1088, 1088, 1089, 1089, 1090, 1090, 1090, 1091, 1093, 1093, 1093, 1094, 1094, 1094, 1094, 1095, 1095, 1095, 1095, 1095, 1095, 1096, 1097, 1098, 1098, 1098, 1098, 1100, 1102, 1102, 1103, 1103, 1103, 1104, 1104, 1105, 1105, 1105, 1105, 1106, 1106, 1106, 1106, 1107, 1107, 1107, 1108, 1110, 1111, 1111, 1112, 1113, 1113, 1113, 1113, 1115, 1115, 1115, 1115, 1115, 1116, 1116, 1117, 1117, 1119, 1119, 1119, 1121, 1122, 1122, 1122, 1122, 1123, 1124, 1124, 1125, 1125, 1127, 1127, 1127, 1128, 1129, 1129, 1129, 1130, 1130, 1131, 1131, 1132, 1132, 1132, 1132, 1134, 1135, 1137, 1137, 1138, 1138, 1138, 1138, 1139, 1140, 1140, 1140, 1140, 1142, 1142, 1142, 1142, 1142, 1142, 1143, 1143, 1145, 1145, 1148, 1148, 1150, 1150, 1151, 1151, 1151, 1152, 1152, 1152, 1153, 1153, 1154, 1155, 1156, 1156, 1156, 1156, 1157, 1158, 1158, 1158, 1159, 1159, 1159, 1160, 1160, 1161, 1161, 1161, 1162, 1162, 1163, 1163, 1163, 1164, 1164, 1165, 1165, 1167, 1167, 1167, 1168, 1168, 1168, 1169, 1170, 1170, 1171, 1171, 1171, 1172, 1172, 1172, 1173, 1173, 1173, 1174, 1174, 1174, 1174, 1176, 1176, 1176, 1176, 1176, 1177, 1178, 1178, 1178, 1179, 1179, 1179, 1180, 1180, 1181, 1181, 1182, 1182, 1182, 1183, 1183, 1184, 1184, 1184, 1184, 1184, 1185, 1186, 1186, 1188, 1188, 1189, 1189, 1190, 1190, 1191, 1191, 1191, 1192, 1192, 1193, 1193, 1195, 1197, 1197, 1198, 1198, 1198, 1199, 1199, 1199, 1200, 1201, 1201, 1201, 1202, 1202, 1202, 1202, 1204, 1204, 1205, 1205, 1205, 1205, 1205, 1206, 1206, 1206, 1207, 1207, 1207, 1207, 1207, 1207, 1209, 1210, 1210, 1211, 1212, 1213, 1213, 1214, 1214, 1215, 1215, 1216, 1216, 1217, 1217, 1217, 1219, 1219, 1219, 1219, 1220, 1220, 1222, 1222, 1223, 1224, 1224, 1225, 1225, 1226, 1226, 1226, 1227, 1227, 1227, 1227, 1227, 1227, 1228, 1228, 1228, 1229, 1230, 1230, 1232, 1232, 1232, 1232, 1232, 1232, 1233, 1234, 1235, 1235, 1235, 1236, 1237, 1238, 1239, 1240, 1240, 1240, 1240, 1240, 1240, 1241, 1241, 1242, 1243, 1243, 1243, 1243, 1244, 1244, 1246, 1246, 1247, 1247, 1249, 1250, 1251, 1251, 1252, 1252, 1252, 1252, 1252, 1252, 1253, 1253, 1253, 1253, 1254, 1254, 1255, 1256, 1257, 1257, 1257, 1259, 1259, 1261, 1261, 1262, 1263, 1263, 1264, 1265, 1265, 1265, 1266, 1266, 1268, 1268, 1269, 1270, 1270, 1270, 1270, 1271, 1271, 1271, 1271, 1272, 1272, 1273, 1273, 1274, 1274, 1274, 1274, 1275, 1275, 1275, 1275, 1276, 1276, 1276, 1276, 1276, 1277, 1278, 1279, 1279, 1280, 1280, 1281, 1282, 1282, 1283, 1283, 1284, 1284, 1284, 1286, 1286, 1289, 1290, 1290, 1290, 1291, 1292, 1292, 1293, 1293, 1294, 1296, 1296, 1296, 1296, 1297, 1297, 1297, 1298, 1299, 1300, 1300, 1301, 1302, 1303, 1304, 1304, 1305, 1305, 1306, 1306, 1307, 1307, 1307, 1307, 1307, 1308, 1308, 1308, 1308, 1309, 1309, 1310, 1311, 1312, 1312, 1313, 1313, 1313, 1314, 1315, 1316, 1316, 1316, 1317, 1319, 1320, 1320, 1320, 1320, 1321, 1322, 1322, 1323, 1323, 1323, 1324, 1324, 1325, 1327, 1328, 1329, 1329, 1330, 1330, 1330, 1330, 1332, 1332, 1332, 1333, 1333, 1334, 1335, 1335, 1336, 1336, 1336, 1338, 1338, 1338, 1339, 1339, 1340, 1340, 1340, 1341, 1341, 1341, 1342, 1343, 1343, 1345, 1345, 1345, 1346, 1346, 1346, 1346, 1346, 1346, 1347, 1348, 1349, 1349, 1349, 1349, 1351, 1352, 1353, 1353, 1353, 1354, 1354, 1355, 1355, 1356, 1356, 1356, 1356, 1358, 1358, 1359, 1359, 1359, 1359, 1359, 1360, 1360, 1360, 1361, 1361, 1361, 1362, 1362, 1363, 1363, 1363, 1365, 1365, 1366, 1367, 1367, 1370, 1371, 1371, 1372, 1372, 1373, 1373, 1373, 1374, 1375, 1375, 1375, 1377, 1377, 1378, 1378, 1378, 1380, 1380, 1381, 1381, 1381, 1382, 1382, 1382, 1382, 1382, 1382, 1383, 1383, 1383, 1384, 1384, 1384, 1385, 1385, 1385, 1385, 1386, 1386, 1387, 1387, 1388, 1388, 1388, 1389, 1389, 1389, 1392, 1393, 1393, 1394, 1394, 1395, 1395, 1395, 1396, 1397, 1398, 1398, 1398, 1399, 1399, 1399, 1400, 1401, 1402, 1402, 1402, 1403, 1404, 1405, 1406, 1406, 1406, 1406, 1407, 1407, 1407, 1407, 1409, 1409, 1409, 1410, 1410, 1410, 1410, 1410, 1411, 1411, 1412, 1413, 1413, 1413, 1414, 1414, 1415, 1415, 1415, 1416, 1416, 1416, 1417, 1417, 1417, 1417, 1417, 1419, 1420, 1420, 1420, 1421, 1422, 1422, 1422, 1422, 1425, 1426, 1427, 1427, 1428, 1428, 1430, 1431, 1431, 1432, 1432, 1432, 1433, 1433, 1434, 1434, 1434, 1434, 1434, 1435, 1436, 1436, 1436, 1436, 1436, 1437, 1438, 1438, 1438, 1438, 1439, 1439, 1440, 1440, 1440, 1440, 1441, 1441, 1442, 1443, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1445, 1446, 1446, 1446, 1447, 1448, 1449, 1449, 1450, 1450, 1450, 1451, 1451, 1452, 1452, 1452, 1453, 1454, 1455, 1456, 1458, 1459, 1459, 1459, 1459, 1460, 1460, 1461, 1461, 1461, 1462, 1462, 1462, 1462, 1462, 1462, 1463, 1463, 1465, 1465, 1465, 1466, 1467, 1468, 1469, 1470, 1472, 1472, 1473, 1474, 1474, 1474, 1474, 1475, 1476, 1477, 1477, 1477, 1477, 1478, 1478, 1480, 1481, 1481, 1481, 1481, 1481, 1481, 1482, 1482, 1482, 1483, 1484, 1485, 1485, 1486, 1486, 1486, 1488, 1488, 1489, 1489, 1489, 1491, 1491, 1492, 1492, 1493, 1495, 1495, 1495, 1496, 1496, 1497, 1497, 1497, 1497, 1497, 1498, 1498, 1499, 1500, 1500, 1501, 1501, 1501, 1501, 1502, 1503, 1503, 1503, 1503, 1503, 1503, 1504, 1505, 1505, 1505, 1506, 1506, 1506, 1506, 1509, 1509, 1509, 1510, 1510, 1511, 1511, 1511, 1511, 1512, 1513, 1513, 1513, 1514, 1514, 1515, 1516, 1516, 1517, 1517, 1518, 1518, 1519, 1519, 1520, 1521, 1522, 1522, 1524, 1525, 1525, 1525, 1525, 1526, 1526, 1526, 1526, 1526, 1526, 1528, 1528, 1528, 1529, 1532, 1532, 1532, 1534, 1534, 1535, 1536, 1536, 1536, 1537, 1537, 1538, 1538, 1538, 1539, 1539, 1539, 1539, 1540, 1541, 1542, 1542, 1543, 1544, 1544, 1544, 1545, 1545, 1545, 1546, 1547, 1547, 1547, 1547, 1547, 1548, 1550, 1551, 1551, 1551, 1551, 1552, 1552, 1552, 1552, 1553, 1554, 1554, 1554, 1555, 1555, 1555, 1555, 1556, 1556, 1557, 1558, 1559, 1559, 1559, 1560, 1560, 1560, 1560, 1561, 1561, 1562, 1562, 1563, 1564, 1564, 1565, 1565, 1565, 1566, 1567, 1567, 1568, 1568, 1569, 1569, 1570, 1570, 1570, 1571, 1571, 1571, 1571, 1572, 1572, 1572, 1573, 1573, 1573, 1573, 1574, 1574, 1575, 1575, 1575, 1575, 1575, 1576, 1576, 1576, 1576, 1576, 1578, 1578, 1578, 1579, 1579, 1579, 1580, 1581, 1581, 1581, 1581, 1581, 1582, 1582, 1582, 1582, 1583, 1583, 1586, 1586, 1586, 1586, 1586, 1587, 1588, 1589, 1590, 1591, 1591, 1591, 1594, 1595, 1595, 1595, 1596, 1598, 1598, 1599, 1600, 1600, 1601, 1601, 1601, 1602, 1602, 1602, 1603, 1603, 1605, 1605, 1606, 1607, 1608, 1608, 1608, 1609, 1609, 1609, 1609, 1611, 1611, 1612, 1612, 1612, 1612, 1612, 1612, 1614, 1615, 1615, 1615, 1615, 1616, 1618, 1618, 1619, 1620, 1621, 1621, 1621, 1622, 1623, 1623, 1624, 1624, 1624, 1624, 1625, 1625, 1625, 1626, 1626, 1627, 1627, 1627, 1629, 1629, 1630, 1630, 1631, 1631, 1634, 1634, 1634, 1634, 1634, 1634, 1635, 1636, 1639, 1639, 1640, 1641, 1641, 1641, 1642, 1642, 1643, 1645, 1645, 1645, 1646, 1647, 1647, 1647, 1648, 1649, 1649, 1649, 1649, 1649, 1651, 1652, 1653, 1653, 1655, 1655, 1655, 1655, 1655, 1655, 1657, 1657, 1657, 1658, 1658, 1659, 1659, 1659, 1659, 1660, 1660, 1660, 1660, 1662, 1663, 1663, 1664, 1664, 1666, 1666, 1666, 1666, 1668, 1669, 1669, 1669, 1671, 1671, 1672, 1672, 1673, 1673, 1673, 1673, 1674, 1674, 1675, 1675, 1675, 1677, 1677, 1677, 1677, 1678, 1678, 1678, 1679, 1679, 1679, 1679, 1680, 1680, 1680, 1681, 1681, 1681, 1682, 1682, 1682, 1683, 1683, 1683, 1684, 1684, 1684, 1685, 1685, 1686, 1687, 1688, 1688, 1688, 1689, 1689, 1691, 1691, 1691, 1692, 1693, 1693, 1693, 1696, 1697, 1697, 1698, 1699, 1700, 1700, 1701, 1702, 1703, 1703, 1705, 1705, 1705, 1707, 1708, 1708, 1708, 1709, 1711, 1712, 1712, 1712, 1714, 1714, 1714, 1714, 1715, 1716, 1716, 1717, 1718, 1718, 1719, 1719, 1719, 1720, 1720, 1720, 1721, 1721, 1722, 1722, 1722, 1722, 1722, 1723, 1723, 1724, 1724, 1725, 1726, 1726, 1727, 1727, 1728, 1728, 1730, 1731, 1731, 1734, 1735, 1735, 1735, 1736, 1737, 1737, 1738, 1738, 1738, 1739, 1739, 1739, 1739, 1739, 1740, 1740, 1740, 1740, 1740, 1741, 1741, 1741, 1741, 1741, 1742, 1743, 1744, 1744, 1744, 1745, 1746, 1746, 1747, 1748, 1749, 1749, 1749, 1749, 1751, 1751, 1751, 1752, 1752, 1752, 1752, 1753, 1754, 1755, 1755, 1755, 1756, 1756, 1757, 1757, 1757, 1757, 1758, 1759, 1759, 1759, 1760, 1760, 1762, 1764, 1766, 1766, 1767, 1767, 1768, 1769, 1769, 1770, 1770, 1770, 1771, 1772, 1773, 1774, 1775, 1775, 1775, 1776, 1776, 1776, 1777, 1777, 1778, 1778, 1779, 1779, 1780, 1780, 1781, 1782, 1784, 1784, 1784, 1785, 1785, 1785, 1785, 1787, 1788, 1789, 1789, 1789, 1790, 1790, 1790, 1791, 1791, 1791, 1791, 1791, 1792, 1792, 1793, 1793, 1793, 1793, 1794, 1794, 1795, 1795, 1796, 1796, 1797, 1797, 1798, 1798, 1798, 1799, 1799, 1800, 1800, 1800, 1801, 1801, 1802, 1802, 1804, 1804, 1804, 1806, 1806, 1808, 1809, 1810, 1810, 1811, 1811, 1814, 1814, 1814, 1815, 1815, 1816, 1816, 1816, 1816, 1817, 1817, 1818, 1819, 1819, 1819, 1820, 1820, 1820, 1821, 1821, 1822, 1823, 1823, 1824, 1824, 1824, 1825, 1825, 1825, 1826, 1826, 1826, 1827, 1827, 1827, 1828, 1828, 1830, 1831, 1832, 1832, 1832, 1832, 1833, 1833, 1833, 1833, 1835, 1837, 1838, 1839, 1840, 1840, 1840, 1840, 1840, 1840, 1841, 1842, 1842, 1843, 1843, 1844, 1844, 1844, 1844, 1844, 1845, 1846, 1847, 1847, 1847, 1848, 1849, 1849, 1849, 1850, 1850, 1850, 1851, 1851, 1851, 1852, 1852, 1853, 1853, 1853, 1854, 1854, 1855, 1855, 1855, 1855, 1855, 1855, 1856, 1856, 1856, 1856, 1857, 1857, 1857, 1857, 1858, 1859, 1859, 1860, 1860, 1860, 1860, 1861, 1861, 1863, 1863, 1865, 1865, 1866, 1866, 1866, 1866, 1866, 1867, 1867, 1867, 1867, 1867, 1868, 1869, 1869, 1869, 1869, 1869, 1869, 1870, 1870, 1870, 1870, 1871, 1872, 1873, 1874, 1875, 1875, 1876, 1876, 1876, 1876, 1877, 1877, 1878, 1878, 1878, 1879, 1879, 1880, 1880, 1880, 1881, 1881, 1883, 1883, 1885, 1885, 1885, 1885, 1885, 1885, 1886, 1886, 1886, 1887, 1887, 1887, 1887, 1888, 1888, 1890, 1891, 1891, 1891, 1892, 1894, 1894, 1894, 1894, 1896, 1896, 1896, 1896, 1897, 1899, 1899, 1900, 1900, 1901, 1901, 1902, 1903, 1904, 1905, 1905, 1905, 1906, 1906, 1906, 1907, 1907, 1908, 1908, 1909, 1910, 1910, 1911, 1912, 1912, 1912, 1913, 1914, 1914, 1914, 1915, 1915, 1915, 1916, 1916, 1916, 1917, 1918, 1918, 1919, 1919, 1920, 1920, 1920, 1920, 1921, 1921, 1922, 1923, 1925, 1925, 1925, 1925, 1926, 1928, 1929, 1929, 1930, 1930, 1931, 1931, 1931, 1931, 1932, 1932, 1932, 1932, 1932, 1933, 1933, 1933, 1933, 1934, 1934, 1934, 1934, 1934, 1935, 1935, 1935, 1936, 1937, 1938, 1938, 1938, 1938, 1940, 1941, 1941, 1941, 1942, 1942, 1943, 1943, 1944, 1944, 1944, 1944, 1945, 1946, 1946, 1947, 1948, 1948, 1948, 1949, 1949, 1949, 1949, 1949, 1950, 1950, 1950, 1951, 1951, 1951, 1951, 1951, 1952, 1953, 1955, 1955, 1956, 1956, 1956, 1957, 1957, 1957, 1958, 1958, 1960, 1960, 1960, 1960, 1961, 1963, 1965, 1965, 1965, 1967, 1967, 1968, 1968, 1969, 1969, 1969, 1969, 1970, 1970, 1971, 1971, 1971, 1972, 1972, 1973, 1973, 1973, 1973, 1973, 1974, 1974, 1975, 1975, 1976, 1976, 1976, 1976, 1977, 1978, 1978, 1979, 1979, 1979, 1980, 1980, 1981, 1981, 1982, 1982, 1982, 1983, 1983, 1983, 1984, 1984, 1986, 1986, 1987, 1989, 1989, 1989, 1989, 1989, 1990, 1990, 1990, 1991, 1991, 1991, 1991, 1992, 1992, 1994, 1994, 1994, 1995, 1995, 1995, 1995, 1995, 1996, 1996, 1996, 1997, 1997, 1998, 1998, 1998, 1998, 1999, 1999, 2000, 2000, 2002, 2003, 2003, 2005, 2009, 2010, 2010, 2011, 2012, 2013, 2014, 2014, 2015, 2016, 2016, 2016, 2016, 2016, 2017, 2018, 2019, 2020, 2020, 2021, 2021, 2021, 2021, 2024, 2026, 2027, 2027, 2028, 2028, 2029, 2029, 2030, 2031, 2032, 2032, 2033, 2034, 2035, 2035, 2036, 2036, 2036, 2036, 2036, 2037, 2037, 2037, 2037, 2038, 2038, 2039, 2039, 2039, 2040, 2041, 2041, 2042, 2042, 2042, 2042, 2042, 2042, 2042, 2043, 2044, 2044, 2045, 2045, 2045, 2046, 2047, 2047, 2048, 2048, 2049, 2051, 2051, 2052, 2052, 2054, 2054, 2054, 2054, 2055, 2056, 2056, 2057, 2058, 2058, 2059, 2059, 2062, 2063, 2063, 2063, 2063, 2063, 2063, 2064, 2064, 2065, 2065, 2065, 2065, 2066, 2066, 2067, 2067, 2068, 2068, 2068, 2068, 2068, 2069, 2070, 2070, 2071, 2071, 2071, 2072, 2073, 2073, 2073, 2075, 2075, 2075, 2076, 2077, 2077, 2078, 2078, 2079, 2079, 2079, 2079, 2080, 2080, 2080, 2081, 2082, 2082, 2082, 2082, 2083, 2083, 2083, 2084, 2084, 2084, 2085, 2085, 2086, 2086, 2086, 2087, 2087, 2087, 2088, 2088, 2088, 2088, 2088, 2089, 2089, 2089, 2089, 2089, 2089, 2089, 2090, 2091, 2091, 2091, 2091, 2092, 2093, 2093, 2094, 2094, 2095, 2096, 2096, 2097, 2097, 2097, 2097, 2098, 2098, 2098, 2098, 2099, 2100, 2102, 2102, 2102, 2102, 2102, 2104, 2104, 2104, 2105, 2105, 2106, 2106, 2107, 2108, 2109, 2109, 2110, 2110, 2111, 2111, 2112, 2114, 2115, 2115, 2116, 2117, 2117, 2118, 2119, 2119, 2119, 2120, 2121, 2121, 2121, 2122, 2122, 2122, 2123, 2124, 2124, 2125, 2125, 2125, 2125, 2127, 2127, 2127, 2127, 2128, 2128, 2128, 2128, 2128, 2129, 2129, 2130, 2131, 2131, 2131, 2132, 2132, 2132, 2133, 2133, 2133, 2133, 2133, 2133, 2133, 2133, 2134, 2135, 2136, 2137, 2137, 2137, 2138, 2138, 2139, 2140, 2140, 2140, 2140, 2142, 2143, 2144, 2144, 2145, 2145, 2145, 2145, 2146, 2146, 2146, 2147, 2147, 2147, 2147, 2147, 2148, 2148, 2148, 2148, 2149, 2149, 2149, 2150, 2151, 2151, 2153, 2153, 2153, 2153, 2154, 2154, 2154, 2155, 2155, 2156, 2157, 2157, 2157, 2157, 2158, 2158, 2158, 2158, 2158, 2159, 2159, 2160, 2160, 2160, 2160, 2161, 2162, 2162, 2162, 2162, 2162, 2163, 2164, 2164, 2167, 2168, 2169, 2169, 2169, 2170, 2172, 2172, 2172, 2172, 2172, 2173, 2173, 2174, 2174, 2175, 2175, 2176, 2176, 2176, 2176, 2177, 2177, 2179, 2179, 2180, 2180, 2180, 2183, 2183, 2183, 2183, 2184, 2185, 2185, 2185, 2185, 2186, 2186, 2186, 2187, 2187, 2188, 2189, 2189, 2189, 2190, 2190, 2191, 2191, 2191, 2191, 2191, 2192, 2193, 2194, 2194, 2195, 2195, 2195, 2195, 2196, 2196, 2197, 2197, 2197, 2198, 2198, 2198, 2199, 2199, 2199, 2200, 2200, 2201, 2201, 2202, 2202, 2202, 2203, 2203, 2204, 2205, 2205, 2205, 2205, 2205, 2206, 2206, 2206, 2207, 2207, 2207, 2210, 2210, 2212, 2213, 2214, 2214, 2215, 2216, 2216, 2216, 2217, 2217, 2219, 2219, 2219, 2219, 2220, 2220, 2221, 2221, 2222, 2222, 2223, 2223, 2224, 2224, 2225, 2225, 2226, 2226, 2226, 2226, 2227, 2228, 2228, 2228, 2229, 2229, 2229, 2230, 2230, 2231, 2231, 2232, 2232, 2232, 2234, 2234, 2234, 2235, 2235, 2236, 2237, 2237, 2238, 2238, 2239, 2239, 2239, 2240, 2240, 2241, 2241, 2241, 2242, 2244, 2244, 2245, 2245, 2245, 2245, 2246, 2248, 2249, 2250, 2251, 2251, 2251, 2251, 2252, 2252, 2253, 2254, 2254, 2255, 2256, 2256, 2256, 2258, 2258, 2258, 2259, 2259, 2259, 2259, 2260, 2260, 2261, 2261, 2262, 2262, 2262, 2263, 2265, 2265, 2265, 2265, 2266, 2266, 2267, 2268, 2269, 2269, 2270, 2270, 2271, 2271, 2272, 2273, 2273, 2273, 2275, 2275, 2276, 2276, 2277, 2277, 2278, 2278, 2280, 2280, 2281, 2282, 2282, 2282, 2282, 2284, 2284, 2284, 2284, 2285, 2285, 2286, 2287, 2287, 2288, 2288, 2289, 2291, 2292, 2292, 2293, 2294, 2295, 2296, 2296, 2297, 2298, 2298, 2299, 2299, 2299, 2300, 2300, 2301, 2301, 2301, 2302, 2302, 2302, 2302, 2303, 2303, 2303, 2304, 2304, 2306, 2306, 2307, 2307, 2307, 2307, 2309, 2309, 2309, 2310, 2310, 2310, 2310, 2311, 2311, 2311, 2312, 2312, 2312, 2313, 2313, 2316, 2317, 2317, 2317, 2317, 2317, 2317, 2317, 2318, 2318, 2319, 2319, 2319, 2320, 2322, 2323, 2323, 2324, 2324, 2324, 2325, 2326, 2327, 2327, 2328, 2329, 2330, 2331, 2332, 2333, 2333, 2334, 2334, 2336, 2336, 2337, 2337, 2338, 2338, 2339, 2339, 2339, 2340, 2340, 2340, 2341, 2342, 2343, 2344, 2345, 2345, 2345, 2345, 2346, 2346, 2347, 2347, 2347, 2347, 2349, 2349, 2349, 2350, 2350, 2351, 2351, 2351, 2351, 2352, 2352, 2353, 2354, 2355, 2356, 2356, 2358, 2359, 2360, 2361, 2362, 2362, 2362, 2363, 2363, 2363, 2364, 2365, 2365, 2365, 2365, 2366, 2367, 2367, 2367, 2367, 2368, 2370, 2370, 2370, 2372, 2372, 2372, 2372, 2372, 2373, 2373, 2373, 2374, 2374, 2375, 2375, 2375, 2376, 2376, 2377, 2377, 2377, 2377, 2378, 2379, 2379, 2380, 2380, 2380, 2381, 2382, 2382, 2382, 2382, 2384, 2384, 2384, 2385, 2387, 2387, 2387, 2388, 2389, 2389, 2389, 2389, 2389, 2390, 2391, 2391, 2392, 2392, 2392, 2394, 2394, 2395, 2395, 2395, 2396, 2396, 2397, 2397, 2397, 2397, 2398, 2398, 2398, 2399, 2400, 2401, 2402, 2404, 2404, 2405, 2405, 2405, 2407, 2408, 2409, 2409, 2409, 2409, 2410, 2410, 2410, 2410, 2410, 2410, 2410, 2411, 2411, 2412, 2412, 2414, 2414, 2415, 2415, 2416, 2416, 2417, 2417, 2418, 2418, 2420, 2421, 2422, 2424, 2424, 2424, 2425, 2425, 2426, 2426, 2426, 2426, 2427, 2427, 2427, 2427, 2427, 2428, 2430, 2432, 2432, 2432, 2432, 2433, 2433, 2433, 2433, 2433, 2434, 2435, 2435, 2435, 2435, 2436, 2437, 2437, 2437, 2437, 2438, 2438, 2439, 2439, 2439, 2440, 2440, 2441, 2441, 2441, 2442, 2443, 2443, 2444, 2444, 2444, 2444, 2447, 2447, 2448, 2448, 2448, 2449, 2449, 2449, 2450, 2451, 2451, 2451, 2453, 2453, 2454, 2454, 2454, 2454, 2455, 2456, 2456, 2457, 2457, 2457, 2458, 2458, 2458, 2459, 2459, 2459, 2459, 2460, 2460, 2461, 2461, 2462, 2463, 2463, 2463, 2463, 2464, 2464, 2464, 2464, 2464, 2465, 2465, 2465, 2466, 2467, 2467, 2467, 2467, 2469, 2470, 2471, 2471, 2472, 2472, 2473, 2473, 2473, 2474, 2474, 2474, 2474, 2475, 2475, 2476, 2476, 2477, 2478, 2479, 2482, 2482, 2483, 2483, 2485, 2485, 2485, 2485, 2486, 2487, 2488, 2489, 2489, 2490, 2490, 2491, 2491, 2491, 2493, 2494, 2494, 2495, 2495, 2495, 2495, 2495, 2495, 2496, 2496, 2496, 2496, 2497, 2497, 2497, 2498, 2498, 2499, 2501, 2502, 2503, 2504, 2504, 2505, 2506, 2506, 2507, 2508, 2508, 2508, 2509, 2509, 2513, 2513, 2513, 2513, 2514, 2514, 2515, 2515, 2516, 2516, 2516, 2518, 2518, 2519, 2519, 2519, 2519, 2520, 2520, 2520, 2520, 2521, 2521, 2521, 2522, 2523, 2523, 2523, 2524, 2524, 2524, 2524, 2525, 2525, 2527, 2527, 2527, 2527, 2527, 2528, 2528, 2529, 2531, 2531, 2532, 2532, 2532, 2533, 2534, 2534, 2535, 2535, 2535, 2536, 2537, 2537, 2537, 2538, 2538, 2539, 2539, 2539, 2539, 2539, 2541, 2541, 2541, 2542, 2542, 2543, 2544, 2544, 2544, 2544, 2545, 2545, 2545, 2546, 2546, 2546, 2546, 2547, 2547, 2547, 2548, 2548, 2548, 2550, 2550, 2550, 2550, 2550, 2551, 2552, 2552, 2553, 2554, 2554, 2554, 2555, 2555, 2556, 2556, 2557, 2557, 2557, 2558, 2560, 2561, 2561, 2561, 2561, 2562, 2563, 2563, 2564, 2564, 2564, 2566, 2566, 2566, 2566, 2566, 2566, 2567, 2567, 2567, 2568, 2569, 2569, 2569, 2571, 2572, 2573, 2573, 2574, 2574, 2576, 2576, 2577, 2577, 2578, 2580, 2580, 2581, 2581, 2581, 2581, 2584, 2584, 2585, 2586, 2587, 2587, 2588, 2588, 2588, 2589, 2589, 2590, 2590, 2591, 2591, 2591, 2592, 2592, 2592, 2593, 2593, 2593, 2594, 2594, 2594, 2596, 2596, 2597, 2598, 2599, 2599, 2599, 2600, 2601, 2601, 2602, 2603, 2603, 2604, 2604, 2604, 2605, 2607, 2608, 2608, 2609, 2609, 2609, 2609, 2611, 2611, 2612, 2612, 2613, 2613, 2613, 2613, 2613, 2614, 2614, 2615, 2615, 2615, 2615, 2615, 2616, 2616, 2617, 2617, 2617, 2618, 2619, 2619, 2620, 2621, 2622, 2622, 2622, 2623, 2624, 2625, 2627, 2628, 2628, 2628, 2628, 2629, 2630, 2630, 2630, 2630, 2631, 2632, 2632, 2632, 2632, 2633, 2633, 2633, 2633, 2633, 2634, 2634, 2635, 2636, 2636, 2636, 2636, 2637, 2637, 2637, 2637, 2637, 2638, 2638, 2638, 2638, 2640, 2640, 2644, 2646, 2646, 2647, 2648, 2649, 2650, 2650, 2650, 2651, 2651, 2651, 2651, 2652, 2652, 2653, 2654, 2654, 2654, 2654, 2655, 2655, 2656, 2656, 2657, 2657, 2657, 2659, 2659, 2660, 2660, 2660, 2660, 2661, 2661, 2662, 2662, 2663, 2663, 2663, 2664, 2665, 2665, 2665, 2666, 2667, 2668, 2670, 2670, 2670, 2670, 2672, 2672, 2673, 2673, 2674, 2674, 2675, 2676, 2676, 2676, 2676, 2677, 2677, 2677, 2677, 2677, 2677, 2679, 2680, 2681, 2683, 2683, 2684, 2684, 2684, 2684, 2685, 2686, 2687, 2688, 2688, 2688, 2689, 2689, 2689, 2689, 2690, 2690, 2690, 2690, 2691, 2691, 2692, 2692, 2692, 2692, 2693, 2693, 2694, 2694, 2694, 2694, 2694, 2695, 2695, 2695, 2696, 2697, 2698, 2699, 2700, 2700, 2701, 2702, 2702, 2704, 2704, 2704, 2705, 2705, 2705, 2705, 2706, 2707, 2707, 2708, 2708, 2710, 2710, 2710, 2711, 2711, 2711, 2711, 2711, 2711, 2712, 2713, 2713, 2714, 2715, 2716, 2717, 2717, 2718, 2718, 2718, 2718, 2719, 2719, 2720, 2722, 2723, 2723, 2724, 2724, 2725, 2726, 2726, 2727, 2728, 2729, 2729, 2729, 2729, 2730, 2731, 2732, 2733, 2734, 2734, 2734, 2735, 2735, 2736, 2736, 2736, 2737, 2738, 2739, 2739, 2740, 2740, 2741, 2741, 2742, 2742, 2743, 2743, 2743, 2744, 2744, 2746, 2747, 2748, 2748, 2748, 2748, 2749, 2749, 2749, 2750, 2750, 2750, 2752, 2752, 2754, 2754, 2754, 2755, 2755, 2756, 2756, 2757, 2757, 2758, 2758, 2759, 2759, 2759, 2759, 2761, 2762, 2762, 2762, 2762, 2762, 2763, 2763, 2763, 2764, 2764, 2764, 2765, 2766, 2766, 2766, 2766, 2767, 2767, 2768, 2769, 2770, 2770, 2770, 2770, 2771, 2771, 2771, 2772, 2772, 2772, 2772, 2774, 2776, 2776, 2776, 2776, 2776, 2777, 2778, 2779, 2779, 2779, 2780, 2780, 2780, 2781, 2781, 2782, 2783, 2783, 2784, 2784, 2784, 2785, 2785, 2786, 2786, 2786, 2787, 2787, 2787, 2787, 2788, 2788, 2789, 2789, 2789, 2789, 2790, 2790, 2790, 2790, 2791, 2791, 2791, 2791, 2792, 2792, 2792, 2792, 2792, 2793, 2793, 2794, 2795, 2795, 2796, 2796, 2797, 2797, 2798, 2800, 2800, 2801, 2801, 2801, 2802, 2802, 2803, 2803, 2804, 2804, 2805, 2805, 2805, 2805, 2805, 2805, 2806, 2806, 2806, 2807, 2808, 2809, 2809, 2809, 2809, 2809, 2809, 2810, 2810, 2811, 2811, 2811, 2812, 2812, 2812, 2813, 2816, 2816, 2816, 2817, 2817, 2818, 2818, 2818, 2818, 2818, 2819, 2819, 2819, 2820, 2820, 2820, 2821, 2821, 2821, 2822, 2823, 2823, 2823, 2824, 2824, 2824, 2825, 2826, 2826, 2826, 2827, 2827, 2827, 2827, 2827, 2827, 2828, 2828, 2830, 2830, 2830, 2831, 2831, 2833, 2833, 2833, 2833, 2835, 2836, 2838, 2838, 2838, 2839, 2839, 2840, 2840, 2841, 2842, 2842, 2843, 2844, 2845, 2845, 2846, 2846, 2848, 2848, 2848, 2849, 2850, 2851, 2852, 2852, 2852, 2853, 2853, 2853, 2854, 2854, 2855, 2855, 2856, 2856, 2857, 2857, 2857, 2857, 2858, 2858, 2859, 2859, 2859, 2860, 2861, 2861, 2861, 2862, 2862, 2863, 2863, 2863, 2864, 2865, 2868, 2868, 2868, 2868, 2868, 2869, 2869, 2870, 2870, 2870, 2871, 2871, 2871, 2872, 2873, 2874, 2875, 2875, 2876, 2876, 2877, 2877, 2878, 2879, 2880, 2880, 2881, 2882, 2884, 2884, 2884, 2885, 2885, 2886, 2887, 2887, 2887, 2887, 2887, 2888, 2888, 2888, 2888, 2889, 2889, 2889, 2890, 2890, 2890, 2891, 2893, 2894, 2895, 2896, 2896, 2897, 2897, 2898, 2898, 2898, 2900, 2900, 2901, 2901, 2902, 2902, 2902, 2902, 2903, 2904, 2904, 2904, 2904, 2905, 2905, 2905, 2906, 2907, 2907, 2908, 2908, 2908, 2908, 2909, 2909, 2910, 2911, 2911, 2911, 2912, 2913, 2914, 2915, 2916, 2916, 2918, 2918, 2919, 2919, 2919, 2920, 2921, 2921, 2922, 2922, 2922, 2923, 2923, 2923, 2924, 2925, 2926, 2926, 2926, 2927, 2927, 2927, 2928, 2929, 2930, 2931, 2931, 2932, 2932, 2932, 2934, 2934, 2934, 2935, 2935, 2935, 2936, 2937, 2938, 2939, 2940, 2940, 2941, 2942, 2942, 2943, 2943, 2943, 2944, 2944, 2944, 2944, 2944, 2945, 2946, 2946, 2947, 2947, 2948, 2949, 2950, 2950, 2951, 2952, 2954, 2954, 2954, 2955, 2955, 2956, 2957, 2958, 2958, 2959, 2959, 2960, 2960, 2960, 2962, 2962, 2964, 2964, 2965, 2965, 2965, 2966, 2966, 2967, 2967, 2968, 2969, 2969, 2969, 2970, 2970, 2971, 2972, 2972, 2972, 2972, 2972, 2974, 2974, 2974, 2976, 2976, 2977, 2978, 2979, 2980, 2980, 2980, 2980, 2981, 2981, 2982, 2982, 2983, 2984, 2984, 2986, 2987, 2987, 2988, 2988, 2988, 2989, 2989, 2989, 2990, 2990, 2991, 2991, 2991, 2992, 2993, 2994, 2995, 2995, 2995, 2995, 2996, 2996, 2997, 2997, 2997, 2998, 2999, 2999, 2999, 2999, 2999, 2999, 3000, 3000, 3000, 3000, 3001, 3001, 3002, 3003, 3003, 3004, 3005, 3005, 3005, 3007, 3007, 3008, 3008, 3009, 3009, 3009, 3010, 3010, 3010, 3010, 3011, 3011, 3013, 3013, 3014, 3015, 3015, 3016, 3016, 3016, 3016, 3017, 3018, 3018, 3018, 3018, 3019, 3020, 3020, 3021, 3021, 3021, 3022, 3024, 3026, 3026, 3026, 3026, 3027, 3028, 3028, 3028, 3028, 3030, 3030, 3031, 3035, 3036, 3036, 3036, 3037, 3037, 3038, 3038, 3039, 3039, 3041, 3041, 3041, 3042, 3043, 3043, 3044, 3044, 3045, 3045, 3045, 3045, 3045, 3046, 3047, 3048, 3048, 3048, 3049, 3049, 3049, 3050, 3050, 3051, 3051, 3051, 3051, 3052, 3052, 3052, 3053, 3054, 3054, 3054, 3054, 3055, 3055, 3055, 3055, 3057, 3057, 3057, 3058, 3059, 3060, 3060, 3060, 3060, 3061, 3062, 3063, 3063, 3063, 3064, 3065, 3065, 3066, 3068, 3068, 3068, 3068, 3068, 3068, 3069, 3071, 3072, 3072, 3072, 3073, 3074, 3074, 3074, 3075, 3077, 3077, 3078, 3078, 3079, 3079, 3079, 3079, 3081, 3081, 3081, 3082, 3082, 3082, 3082, 3083, 3083, 3084, 3084, 3084, 3086, 3086, 3087, 3087, 3087, 3087, 3088, 3089, 3089, 3090, 3091, 3092, 3092, 3093, 3093, 3094, 3094, 3094, 3095, 3095, 3096, 3097, 3097, 3098, 3099, 3100, 3101, 3101, 3102, 3102, 3104, 3104, 3105, 3107, 3108, 3108, 3109, 3109, 3109, 3110, 3110, 3111, 3111, 3111, 3112, 3112, 3112, 3112, 3112, 3113, 3113, 3113, 3113, 3113, 3114, 3115, 3116, 3116, 3116, 3117, 3117, 3117, 3118, 3118, 3119, 3119, 3119, 3120, 3120, 3120, 3121, 3121, 3121, 3122, 3122, 3122, 3122, 3123, 3123, 3124, 3126, 3127, 3127, 3127, 3127, 3128, 3128, 3128, 3128, 3129, 3130, 3130, 3131, 3131, 3131, 3131, 3131, 3132, 3132, 3132, 3133, 3133, 3134, 3135, 3136, 3136, 3136, 3137, 3138, 3140, 3140, 3141, 3142, 3142, 3143, 3143, 3143, 3143, 3143, 3144, 3145, 3146, 3146, 3146, 3147, 3148, 3149, 3149, 3150, 3150, 3150, 3150, 3150, 3150, 3151, 3151, 3152, 3152, 3154, 3154, 3155, 3155, 3155, 3156, 3156, 3157, 3158, 3158, 3159, 3160, 3160, 3161, 3161, 3161, 3162, 3162, 3163, 3164, 3164, 3165, 3165, 3166, 3166, 3166, 3167, 3167, 3168, 3168, 3168, 3169, 3169, 3170, 3170, 3170, 3170, 3171, 3172, 3172, 3173, 3175, 3175, 3177, 3177, 3178, 3178, 3179, 3180, 3180, 3180, 3181, 3182, 3182, 3182, 3183, 3184, 3184, 3184, 3185, 3186, 3187, 3187, 3188, 3189, 3189, 3189, 3190, 3190, 3191, 3192, 3192, 3193, 3193, 3193, 3194, 3194, 3194, 3194, 3195, 3195, 3196, 3196, 3196, 3196, 3198, 3198, 3198, 3198, 3198, 3199, 3199, 3199, 3200, 3200, 3202, 3202, 3203, 3203, 3203, 3205, 3206, 3207, 3207, 3207, 3208, 3208, 3208, 3208, 3209, 3209, 3210, 3210, 3211, 3211, 3211, 3212, 3212, 3213, 3213, 3213, 3214, 3214, 3215, 3216, 3216, 3217, 3218, 3218, 3219, 3219, 3220, 3222, 3223, 3223, 3223, 3224, 3224, 3224, 3224, 3225, 3225, 3225, 3225, 3226, 3227, 3228, 3228, 3228, 3228, 3228, 3228, 3229, 3230, 3230, 3231, 3233, 3234, 3234, 3234, 3235, 3235, 3236, 3236, 3237, 3237, 3239, 3239, 3239, 3240, 3240, 3241, 3241, 3241, 3241, 3243, 3243, 3243, 3243, 3243, 3243, 3243, 3243, 3245, 3245, 3246, 3246, 3246, 3247, 3247, 3247, 3247, 3248, 3248, 3249, 3250, 3250, 3251, 3251, 3252, 3252, 3253, 3253, 3254, 3254, 3255, 3256, 3257, 3257, 3257, 3259, 3259, 3260, 3260, 3261, 3262, 3263, 3263, 3263, 3264, 3266, 3266, 3266, 3267, 3267, 3267, 3267, 3267, 3268, 3268, 3268, 3269, 3269, 3269, 3270, 3270, 3270, 3270, 3271, 3272, 3272, 3272, 3272, 3273, 3273, 3273, 3274, 3274, 3275, 3275, 3276, 3276, 3276, 3278, 3278, 3279, 3280, 3280, 3280, 3280, 3281, 3282, 3284, 3284, 3284, 3285, 3285, 3285, 3285, 3286, 3286, 3287, 3288, 3288, 3289, 3289, 3289, 3289, 3290, 3292, 3292, 3292, 3293, 3293, 3293, 3293, 3294, 3294, 3297, 3297, 3298, 3299, 3301, 3301, 3302, 3302, 3302, 3302, 3303, 3304, 3305, 3305, 3305, 3305, 3306, 3306, 3306, 3306, 3306, 3306, 3308, 3308, 3308, 3308, 3309, 3309, 3310, 3310, 3311, 3311, 3311, 3311, 3312, 3313, 3313, 3313, 3314, 3314, 3315, 3315, 3316, 3318, 3320, 3320, 3321, 3321, 3321, 3322, 3322, 3323, 3323, 3323, 3324, 3324, 3327, 3329, 3329, 3330, 3330, 3330, 3331, 3331, 3331, 3331, 3331, 3333, 3334, 3335, 3336, 3336, 3336, 3337, 3337, 3337, 3338, 3338, 3339, 3339, 3339, 3339, 3340, 3340, 3340, 3340, 3341, 3341, 3341, 3344, 3345, 3345, 3346, 3347, 3347, 3347, 3347, 3347, 3348, 3348, 3348, 3348, 3349, 3349, 3349, 3350, 3350, 3351, 3351, 3352, 3352, 3352, 3352, 3353, 3354, 3357, 3358, 3358, 3358, 3358, 3359, 3359, 3359, 3360, 3360, 3361, 3361, 3361, 3362, 3363, 3363, 3363, 3365, 3365, 3367, 3367, 3367, 3368, 3369, 3369, 3369, 3370, 3370, 3371, 3372, 3372, 3373, 3374, 3374, 3377, 3377, 3377, 3377, 3378, 3379, 3379, 3380, 3380, 3381, 3381, 3382, 3383, 3383, 3383, 3384, 3384, 3385, 3385, 3385, 3386, 3386, 3387, 3387, 3388, 3388, 3388, 3389, 3389, 3389, 3390, 3392, 3393, 3394, 3394, 3394, 3395, 3396, 3397, 3397, 3397, 3398, 3398, 3398, 3398, 3399, 3399, 3400, 3400, 3400, 3401, 3401, 3402, 3402, 3402, 3402, 3403, 3403, 3405, 3405, 3405, 3405, 3405, 3406, 3407, 3407, 3408, 3410, 3410, 3411, 3411, 3411, 3412, 3412, 3412, 3413, 3414, 3414, 3414, 3414, 3415, 3415, 3417, 3419, 3419, 3420, 3420, 3420, 3421, 3421, 3421, 3422, 3422, 3423, 3423, 3423, 3423, 3424, 3425, 3425, 3425, 3426, 3427, 3427, 3428, 3428, 3429, 3429, 3430, 3431, 3431, 3431, 3432, 3432, 3432, 3434, 3435, 3435, 3435, 3436, 3437, 3438, 3438, 3438, 3439, 3439, 3439, 3440, 3440, 3441, 3441, 3442, 3443, 3443, 3443, 3444, 3444, 3444, 3445, 3445, 3445, 3446, 3446, 3447, 3447, 3447, 3448, 3448, 3449, 3449, 3449, 3450, 3450, 3450, 3451, 3452, 3452, 3453, 3453, 3454, 3454, 3454, 3454, 3455, 3456, 3456, 3456, 3457, 3457, 3460, 3461, 3461, 3461, 3462, 3462, 3462, 3463, 3463, 3463, 3463, 3463, 3464, 3464, 3464, 3466, 3467, 3467, 3467, 3468, 3468, 3469, 3470, 3471, 3472, 3473, 3473, 3473, 3474, 3475, 3475, 3475, 3476, 3476, 3476, 3478, 3479, 3479, 3480, 3481, 3481, 3481, 3482, 3483, 3484, 3484, 3485, 3485, 3486, 3486, 3486, 3486, 3487, 3487, 3487, 3487, 3489, 3489, 3490, 3490, 3490, 3491, 3491, 3491, 3492, 3492, 3493, 3493, 3494, 3494, 3494, 3495, 3495, 3495, 3495, 3495, 3495, 3495, 3496, 3497, 3497, 3498, 3498, 3499, 3499, 3499, 3499, 3500, 3501, 3501, 3503, 3503, 3503, 3504, 3504, 3504, 3504, 3504, 3505, 3505, 3505, 3506, 3507, 3508, 3508, 3508, 3511, 3511, 3511, 3511, 3511, 3511, 3511, 3512, 3512, 3512, 3512, 3513, 3514, 3514, 3514, 3515, 3515, 3516, 3517, 3517, 3518, 3518, 3518, 3518, 3519, 3520, 3520, 3520, 3520, 3521, 3521, 3521, 3521, 3521, 3524, 3525, 3527, 3528, 3528, 3530, 3530, 3531, 3532, 3532, 3533, 3534, 3534, 3534, 3535, 3535, 3535, 3535, 3536, 3537, 3537, 3538, 3539, 3539, 3539, 3539, 3540, 3540, 3540, 3541, 3541, 3541, 3543, 3544, 3544, 3547, 3548, 3548, 3549, 3549, 3550, 3551, 3551, 3551, 3551, 3552, 3553, 3553, 3553, 3553, 3554, 3554, 3554, 3554, 3555, 3555, 3556, 3556, 3557, 3558, 3558, 3558, 3558, 3559, 3559, 3560, 3560, 3560, 3561, 3561, 3562, 3562, 3563, 3565, 3566, 3566, 3566, 3566, 3567, 3567, 3567, 3567, 3568, 3569, 3569, 3570, 3570, 3571, 3572, 3572, 3573, 3573, 3573, 3574, 3574, 3575, 3575, 3576, 3577, 3578, 3579, 3581, 3581, 3582, 3582, 3582, 3583, 3583, 3583, 3583, 3583, 3584, 3584, 3585, 3586, 3586, 3587, 3587, 3588, 3588, 3588, 3589, 3591, 3591, 3593, 3594, 3594, 3595, 3596, 3596, 3597, 3599, 3599, 3599, 3600, 3600, 3600, 3601, 3601, 3602, 3602, 3602, 3603, 3604, 3605, 3607, 3608, 3609, 3609, 3609, 3609, 3610, 3610, 3611, 3612, 3612, 3613, 3614, 3614, 3615, 3615, 3615, 3615, 3615, 3616, 3617, 3617, 3617, 3617, 3619, 3619, 3619, 3621, 3621, 3621, 3622, 3623, 3624, 3624, 3625, 3627, 3628, 3628, 3628, 3628, 3629, 3630, 3630, 3630, 3631, 3631, 3631, 3631, 3632, 3633, 3633, 3633, 3634, 3634, 3634, 3636, 3637, 3638, 3638, 3638, 3639, 3639, 3639, 3639, 3641, 3642, 3642, 3642, 3643, 3643, 3643, 3643, 3644, 3644, 3645, 3646, 3646, 3647, 3647, 3647, 3647, 3648, 3648, 3649, 3649, 3650, 3650, 3651, 3652, 3652, 3653, 3653, 3654, 3655, 3656, 3656, 3657, 3658, 3659, 3660, 3661, 3662, 3663, 3664, 3664, 3664, 3665, 3666, 3667, 3667, 3668, 3669, 3669, 3669, 3670, 3670, 3671, 3671, 3672, 3672, 3673, 3677, 3678, 3678, 3678, 3678, 3679, 3679, 3679, 3681, 3681, 3681, 3682, 3682, 3683, 3683, 3684, 3684, 3685, 3685, 3685, 3687, 3687, 3687, 3688, 3688, 3688, 3688, 3688, 3689, 3690, 3690, 3690, 3693, 3693, 3694, 3694, 3695, 3695, 3696, 3698, 3698, 3699, 3699, 3700, 3702, 3703, 3704, 3705, 3705, 3705, 3705, 3706, 3706, 3706, 3706, 3706, 3707, 3707, 3707, 3708, 3708, 3710, 3710, 3710, 3711, 3712, 3713, 3713, 3713, 3713, 3714, 3714, 3714, 3715, 3715, 3716, 3716, 3717, 3717, 3717, 3717, 3718, 3718, 3718, 3718, 3719, 3719, 3719, 3720, 3720, 3721, 3721, 3722, 3722, 3722, 3722, 3722, 3723, 3724, 3725, 3726, 3727, 3727, 3728, 3728, 3729, 3729, 3731, 3731, 3731, 3731, 3731, 3732, 3734, 3734, 3734, 3734, 3735, 3735, 3736, 3736, 3736, 3736, 3737, 3738, 3739, 3739, 3739, 3740, 3740, 3740, 3741, 3741, 3741, 3742, 3742, 3743, 3744, 3744, 3744, 3745, 3745, 3745, 3746, 3746, 3747, 3747, 3747, 3748, 3748, 3749, 3751, 3751, 3751, 3751, 3751, 3752, 3753, 3753, 3753, 3753, 3754, 3755, 3756, 3757, 3757, 3758, 3758, 3758, 3759, 3759, 3759, 3762, 3763, 3763, 3763, 3763, 3764, 3765, 3765, 3766, 3766, 3766, 3766, 3767, 3767, 3768, 3768, 3769, 3769, 3770, 3770, 3770, 3770, 3771, 3771, 3772, 3772, 3773, 3773, 3774, 3775, 3775, 3776, 3776, 3776, 3776, 3776, 3777, 3777, 3779, 3779, 3779, 3779, 3780, 3780, 3781, 3781, 3782, 3783, 3783, 3784, 3785, 3785, 3787, 3787, 3787, 3788, 3788, 3788, 3788, 3789, 3789, 3790, 3790, 3791, 3792, 3792, 3792, 3793, 3793, 3794, 3794, 3795, 3795, 3796, 3797, 3797, 3797, 3797, 3798, 3798, 3799, 3800, 3800, 3800, 3800, 3801, 3801, 3801, 3802, 3802, 3802, 3802, 3803, 3804, 3805, 3806, 3806, 3807, 3808, 3808, 3809, 3809, 3811, 3813, 3814, 3814, 3816, 3816, 3816, 3817, 3818, 3819, 3820, 3820, 3821, 3821, 3821, 3822, 3822, 3822, 3825, 3825, 3825, 3825, 3826, 3828, 3828, 3828, 3829, 3830, 3830, 3830, 3830, 3831, 3831, 3831, 3832, 3832, 3833, 3833, 3833, 3833, 3834, 3835, 3835, 3836, 3837, 3837, 3837, 3837, 3838, 3838, 3838, 3839, 3841, 3841, 3842, 3842, 3842, 3842, 3843, 3843, 3843, 3843, 3843, 3844, 3844, 3844, 3845, 3846, 3847, 3847, 3848, 3849, 3850, 3850, 3851, 3851, 3851, 3854, 3854, 3854, 3855, 3855, 3856, 3857, 3858, 3858, 3858, 3859, 3859, 3859, 3859, 3860, 3860, 3861, 3861, 3861, 3861, 3862, 3862, 3862, 3862, 3863, 3863, 3865, 3865, 3865, 3865, 3866, 3866, 3867, 3867, 3867, 3867, 3868, 3868, 3869, 3869, 3870, 3871, 3871, 3871, 3872, 3873, 3873, 3873, 3874, 3874, 3874, 3875, 3875, 3876, 3877, 3878, 3878, 3878, 3879, 3879, 3879, 3880, 3880, 3881, 3881, 3881, 3881, 3883, 3883, 3884, 3884, 3884, 3884, 3884, 3886, 3887, 3887, 3887, 3887, 3888, 3888, 3889, 3890, 3890, 3891, 3891, 3891, 3891, 3892, 3892, 3892, 3892, 3893, 3893, 3893, 3893, 3894, 3894, 3894, 3895, 3895, 3895, 3895, 3897, 3897, 3897, 3899, 3899, 3900, 3901, 3902, 3904, 3904, 3905, 3905, 3906, 3906, 3906, 3907, 3907, 3907, 3908, 3909, 3910, 3911, 3911, 3912, 3913, 3914, 3915, 3915, 3915, 3915, 3916, 3917, 3917, 3917, 3919, 3919, 3919, 3920, 3921, 3921, 3922, 3922, 3923, 3923, 3923, 3924, 3924, 3925, 3925, 3926, 3926, 3926, 3928, 3928, 3928, 3929, 3929, 3930, 3930, 3930, 3931, 3931, 3931, 3932, 3932, 3932, 3932, 3932, 3933, 3933, 3933, 3934, 3934, 3934, 3935, 3935, 3935, 3935, 3936, 3937, 3937, 3937, 3938, 3938, 3939, 3942, 3942, 3943, 3943, 3943, 3945, 3945, 3945, 3946, 3947, 3947, 3948, 3948, 3948, 3948, 3948, 3951, 3952, 3952, 3952, 3952, 3953, 3954, 3954, 3956, 3957, 3957, 3957, 3957, 3958, 3958, 3958, 3959, 3960, 3961, 3961, 3961, 3962, 3963, 3964, 3964, 3964, 3965, 3965, 3965, 3965, 3967, 3968, 3969, 3969, 3970, 3970, 3971, 3972, 3972, 3973, 3973, 3974, 3974, 3975, 3975, 3976, 3976, 3977, 3977, 3977, 3977, 3978, 3978, 3979, 3979, 3979, 3979, 3979, 3980, 3980, 3981, 3981, 3981, 3981, 3982, 3982, 3982, 3982, 3983, 3984, 3984, 3984, 3984, 3984, 3984, 3986, 3986, 3986, 3987, 3988, 3988, 3988, 3988, 3989, 3989, 3989, 3990, 3990, 3991, 3992, 3993, 3994, 3995, 3996, 3996, 3998, 3998, 3998, 3999, 4000, 4000, 4000, 4001, 4001, 4001, 4001, 4002, 4002, 4002, 4002, 4003, 4004, 4004, 4004, 4005, 4006, 4006, 4007, 4007, 4008, 4008, 4008, 4009, 4010, 4010, 4010, 4010, 4011, 4011, 4013, 4014, 4015, 4016, 4017, 4018, 4018, 4019, 4020, 4020, 4020, 4021, 4021, 4022, 4022, 4022, 4023, 4023, 4023, 4024, 4024, 4025, 4025, 4025, 4026, 4026, 4027, 4027, 4028, 4028, 4028, 4029, 4030, 4031, 4031, 4031, 4031, 4032, 4032, 4032, 4032, 4033, 4033, 4033, 4033, 4035, 4035, 4035, 4035, 4035, 4037, 4038, 4038, 4038, 4038, 4038, 4039, 4039, 4039, 4040, 4040, 4040, 4041, 4041, 4041, 4041, 4041, 4041, 4041, 4042, 4042, 4043, 4043, 4043, 4043, 4044, 4044, 4045, 4045, 4045, 4047, 4047, 4048, 4048, 4049, 4050, 4050, 4050, 4051, 4052, 4052, 4053, 4053, 4054, 4055, 4055, 4056, 4056, 4057, 4058, 4058, 4059, 4059, 4060, 4060, 4060, 4061, 4061, 4061, 4062, 4063, 4063, 4064, 4065, 4065, 4065, 4066, 4067, 4068, 4068, 4068, 4069, 4069, 4069, 4070, 4070, 4070, 4071, 4071, 4072, 4072, 4072, 4072, 4072, 4073, 4073, 4074, 4074, 4075, 4076, 4076, 4076, 4076, 4077, 4077, 4078, 4078, 4078, 4080, 4081, 4081, 4082, 4082, 4082, 4083, 4083, 4085, 4085, 4085, 4085, 4085, 4086, 4086, 4086, 4087, 4087, 4087, 4088, 4088, 4089, 4089, 4090, 4090, 4091, 4091, 4092, 4093, 4093, 4093, 4094, 4095, 4096, 4096, 4096, 4097, 4097, 4098, 4099, 4099, 4099, 4099, 4100, 4100, 4101, 4101, 4102, 4102, 4103, 4104, 4104, 4104, 4104, 4104, 4105, 4106, 4106, 4106, 4106, 4107, 4108, 4108, 4109, 4109, 4109, 4109, 4110, 4111, 4112, 4112, 4112, 4112, 4112, 4113, 4113, 4114, 4114, 4114, 4115, 4115, 4116, 4116, 4117, 4117, 4117, 4118, 4118, 4118, 4119, 4119, 4121, 4121, 4122, 4122, 4122, 4123, 4124, 4125, 4125, 4126, 4127, 4129, 4129, 4130, 4131, 4131, 4132, 4132, 4132, 4134, 4134, 4134, 4135, 4135, 4135, 4135, 4135, 4135, 4135, 4135, 4136, 4136, 4136, 4136, 4136, 4136, 4137, 4137, 4137, 4139, 4140, 4140, 4140, 4141, 4141, 4142, 4142, 4142, 4143, 4144, 4144, 4144, 4144, 4145, 4145, 4145, 4145, 4146, 4147, 4147, 4147, 4148, 4148, 4148, 4149, 4149, 4149, 4149, 4149, 4150, 4150, 4151, 4153, 4153, 4154, 4155, 4155, 4156, 4156, 4156, 4157, 4158, 4158, 4159, 4159, 4160, 4160, 4161, 4161, 4161, 4161, 4163, 4163, 4163, 4164, 4164, 4164, 4164, 4165, 4165, 4165, 4166, 4166, 4166, 4167, 4168, 4169, 4170, 4170, 4170, 4171, 4171, 4172, 4173, 4173, 4173, 4173, 4174, 4175, 4175, 4176, 4176, 4176, 4177, 4177, 4177, 4177, 4178, 4178, 4179, 4179, 4179, 4179, 4179, 4179, 4179, 4180, 4180, 4180, 4181, 4181, 4181, 4181, 4182, 4182, 4183, 4184, 4185, 4186, 4187, 4187, 4187, 4188, 4188, 4188, 4189, 4189, 4189, 4189, 4190, 4190, 4190, 4190, 4190, 4191, 4192, 4192, 4192, 4192, 4194, 4195, 4196, 4196, 4196, 4196, 4197, 4197, 4198, 4198, 4198, 4198, 4200, 4200, 4201, 4202, 4202, 4203, 4203, 4204, 4205, 4205, 4207, 4210, 4210, 4210, 4210, 4211, 4211, 4213, 4214, 4214, 4215, 4215, 4215, 4216, 4216, 4216, 4217, 4217, 4218, 4218, 4218, 4218, 4218, 4219, 4220, 4220, 4220, 4221, 4222, 4223, 4223, 4223, 4225, 4225, 4226, 4226, 4227, 4227, 4228, 4228, 4228, 4228, 4229, 4230, 4230, 4232, 4233, 4233, 4233, 4233, 4234, 4235, 4235, 4235, 4235, 4236, 4236, 4236, 4237, 4238, 4238, 4238, 4238, 4238, 4239, 4239, 4239, 4239, 4239, 4240, 4240, 4241, 4243, 4243, 4243, 4243, 4243, 4243, 4244, 4244, 4244, 4244, 4244, 4245, 4245, 4245, 4247, 4247, 4247, 4248, 4248, 4249, 4249, 4249, 4250, 4250, 4250, 4251, 4251, 4252, 4252, 4253, 4253, 4253, 4253, 4253, 4254, 4255, 4255, 4255, 4256, 4256, 4257, 4257, 4257, 4258, 4258, 4258, 4258, 4259, 4259, 4260, 4260, 4261, 4261, 4261, 4261, 4261, 4261, 4262, 4262, 4262, 4263, 4264, 4265, 4265, 4265, 4266, 4267, 4268, 4269, 4269, 4269, 4270, 4270, 4271, 4271, 4271, 4272, 4272, 4273, 4273, 4273, 4273, 4274, 4274, 4274, 4275, 4275, 4277, 4279, 4279, 4280, 4280, 4280, 4281, 4281, 4282, 4282, 4282, 4282, 4282, 4283, 4283, 4283, 4283, 4284, 4285, 4285, 4285, 4285, 4285, 4286, 4286, 4287, 4287, 4287, 4287, 4288, 4289, 4290, 4290, 4291, 4291, 4291, 4292, 4293, 4293, 4293, 4293, 4294, 4294, 4295, 4296, 4297, 4297, 4297, 4297, 4297, 4297, 4298, 4299, 4299, 4299, 4299, 4300, 4300, 4301, 4301, 4302, 4302, 4302, 4302, 4303, 4304, 4305, 4306, 4306, 4306, 4307, 4307, 4308, 4308, 4309, 4309, 4309, 4309, 4310, 4311, 4311, 4312, 4312, 4312, 4312, 4312, 4313, 4314, 4315, 4315, 4316, 4316, 4317, 4317, 4317, 4318, 4318, 4319, 4319, 4320, 4320, 4321, 4322, 4322, 4323, 4325, 4327, 4327, 4327, 4327, 4327, 4328, 4328, 4330, 4330, 4330, 4331, 4331, 4332, 4332, 4334, 4335, 4335, 4336, 4336, 4337, 4337, 4338, 4338, 4338, 4338, 4339, 4339, 4339, 4340, 4340, 4340, 4340, 4340, 4340, 4341, 4341, 4341, 4343, 4343, 4344, 4344, 4344, 4345, 4346, 4347, 4347, 4348, 4348, 4348, 4352, 4353, 4355, 4356, 4356, 4357, 4357, 4358, 4358, 4358, 4358, 4359, 4360, 4360, 4360, 4361, 4361, 4361, 4361, 4362, 4362, 4363, 4363, 4364, 4365, 4365, 4365, 4368, 4370, 4370, 4370, 4371, 4371, 4371, 4372, 4372, 4372, 4372, 4374, 4374, 4374, 4375, 4375, 4376, 4376, 4377, 4377, 4380, 4380, 4381, 4381, 4381, 4382, 4382, 4384, 4386, 4386, 4387, 4387, 4389, 4389, 4389, 4389, 4389, 4389, 4390, 4391, 4391, 4392, 4393, 4393, 4394, 4394, 4394, 4394, 4395, 4395, 4396, 4398, 4398, 4398, 4399, 4400, 4400, 4400, 4401, 4401, 4402, 4403, 4403, 4403, 4404, 4405, 4405, 4405, 4407, 4408, 4408, 4408, 4409, 4410, 4410, 4410, 4410, 4411, 4411, 4412, 4412, 4413, 4413, 4414, 4414, 4414, 4414, 4414, 4415, 4415, 4419, 4419, 4419, 4419, 4420, 4420, 4420, 4421, 4421, 4421, 4421, 4423, 4424, 4425, 4426, 4427, 4427, 4428, 4429, 4429, 4430, 4430, 4430, 4431, 4431, 4431, 4431, 4432, 4432, 4432, 4432, 4432, 4432, 4433, 4433, 4434, 4434, 4435, 4435, 4435, 4435, 4436, 4436, 4436, 4436, 4437, 4437, 4438, 4438, 4438, 4438, 4438, 4439, 4439, 4440, 4440, 4441, 4441, 4442, 4443, 4444, 4444, 4446, 4446, 4447, 4447, 4447, 4448, 4448, 4448, 4449, 4450, 4451, 4452, 4453, 4453, 4454, 4454, 4455, 4455, 4455, 4456, 4456, 4456, 4457, 4457, 4457, 4457, 4457, 4457, 4457, 4457, 4459, 4460, 4460, 4461, 4462, 4462, 4462, 4462, 4465, 4465, 4466, 4467, 4468, 4468, 4469, 4470, 4470, 4471, 4471, 4471, 4471, 4471, 4471, 4471, 4471, 4472, 4472, 4472, 4473, 4473, 4474, 4474, 4474, 4475, 4475, 4476, 4477, 4479, 4479, 4479, 4479, 4481, 4481, 4481, 4481, 4482, 4482, 4482, 4483, 4483, 4484, 4484, 4486, 4487, 4487, 4487, 4487, 4487, 4488, 4488, 4488, 4489, 4491, 4491, 4492, 4492, 4493, 4493, 4494, 4494, 4494, 4494, 4494, 4495, 4495, 4495, 4496, 4496, 4496, 4497, 4498, 4499, 4500, 4500, 4501, 4501, 4503, 4503, 4503, 4504, 4504, 4506, 4509, 4509, 4509, 4509, 4510, 4510, 4511, 4511, 4511, 4512, 4513, 4513, 4514, 4514, 4514, 4515, 4517, 4518, 4521, 4521, 4521, 4521, 4522, 4523, 4523, 4524, 4524, 4525, 4525, 4525, 4525, 4525, 4526, 4526, 4527, 4527, 4528, 4528, 4528, 4529, 4529, 4529, 4529, 4530, 4531, 4532, 4533, 4533, 4534, 4535, 4536, 4536, 4536, 4536, 4537, 4537, 4538, 4539, 4539, 4542, 4542, 4542, 4543, 4543, 4543, 4544, 4544, 4546, 4547, 4547, 4548, 4548, 4549, 4549, 4550, 4550, 4551, 4552, 4552, 4552, 4553, 4553, 4554, 4554, 4554, 4554, 4554, 4555, 4555, 4556, 4556, 4557, 4557, 4558, 4558, 4559, 4559, 4559, 4560, 4560, 4562, 4563, 4563, 4564, 4565, 4566, 4566, 4566, 4567, 4567, 4567, 4567, 4567, 4568, 4568, 4568, 4569, 4569, 4570, 4571, 4572, 4572, 4572, 4572, 4573, 4574, 4574, 4574, 4575, 4575, 4575, 4575, 4575, 4575, 4576, 4576, 4577, 4577, 4578, 4578, 4578, 4579, 4579, 4579, 4579, 4580, 4580, 4580, 4580, 4580, 4581, 4581, 4582, 4583, 4584, 4584, 4586, 4586, 4587, 4588, 4589, 4590, 4590, 4592, 4592, 4592, 4593, 4594, 4594, 4594, 4595, 4595, 4595, 4596, 4597, 4597, 4597, 4598, 4598, 4600, 4600, 4600, 4600, 4601, 4601, 4602, 4602, 4602, 4603, 4604, 4604, 4605, 4605, 4605, 4606, 4607, 4608, 4608, 4608, 4609, 4609, 4609, 4610, 4611, 4611, 4612, 4612, 4614, 4614, 4614, 4614, 4615, 4615, 4616, 4616, 4616, 4616, 4617, 4617, 4617, 4617, 4618, 4618, 4618, 4618, 4620, 4621, 4621, 4621, 4622, 4623, 4623, 4623, 4624, 4624, 4625, 4625, 4626, 4626, 4627, 4627, 4627, 4629, 4629, 4630, 4630, 4631, 4631, 4631, 4631, 4631, 4631, 4632, 4633, 4634, 4634, 4634, 4635, 4635, 4635, 4635, 4636, 4636, 4636, 4636, 4637, 4637, 4638, 4639, 4639, 4640, 4640, 4640, 4641, 4641, 4642, 4643, 4643, 4643, 4644, 4644, 4645, 4646, 4646, 4647, 4648, 4649, 4649, 4649, 4649, 4651, 4651, 4653, 4654, 4655, 4655, 4656, 4656, 4657, 4658, 4658, 4658, 4659, 4659, 4659, 4659, 4659, 4660, 4661, 4662, 4662, 4663, 4663, 4664, 4664, 4665, 4665, 4666, 4666, 4666, 4667, 4667, 4668, 4669, 4669, 4669, 4669, 4670, 4670, 4670, 4671, 4673, 4673, 4674, 4674, 4674, 4674, 4675, 4675, 4675, 4676, 4677, 4678, 4678, 4679, 4679, 4679, 4679, 4680, 4680, 4681, 4681, 4683, 4683, 4683, 4683, 4684, 4684, 4685, 4685, 4686, 4686, 4687, 4687, 4688, 4690, 4690, 4690, 4690, 4691, 4691, 4693, 4693, 4693, 4693, 4693, 4695, 4695, 4697, 4697, 4698, 4699, 4699, 4700, 4700, 4700, 4701, 4701, 4701, 4702, 4703, 4703, 4704, 4704, 4704, 4705, 4705, 4705, 4706, 4707, 4707, 4707, 4708, 4708, 4709, 4709, 4710, 4710, 4710, 4711, 4711, 4712, 4712, 4714, 4715, 4716, 4716, 4717, 4718, 4718, 4718, 4718, 4719, 4719, 4720, 4720, 4720, 4720, 4721, 4721, 4721, 4722, 4722, 4725, 4725, 4726, 4726, 4727, 4728, 4728, 4728, 4728, 4728, 4729, 4729, 4730, 4730, 4731, 4731, 4732, 4732, 4733, 4733, 4733, 4733, 4733, 4734, 4734, 4734, 4734, 4735, 4735, 4735, 4736, 4737, 4738, 4738, 4738, 4738, 4738, 4739, 4739, 4740, 4740, 4741, 4741, 4743, 4743, 4743, 4744, 4744, 4744, 4744, 4744, 4746, 4746, 4746, 4746, 4747, 4747, 4747, 4748, 4748, 4748, 4749, 4749, 4749, 4750, 4751, 4751, 4751, 4752, 4753, 4753, 4753, 4755, 4755, 4756, 4756, 4757, 4757, 4757, 4758, 4758, 4760, 4760, 4760, 4761, 4761, 4762, 4762, 4762, 4763, 4764, 4764, 4765, 4766, 4767, 4767, 4768, 4768, 4769, 4770, 4771, 4771, 4771, 4773, 4774, 4774, 4774, 4774, 4775, 4778, 4779, 4780, 4780, 4780, 4781, 4781, 4782, 4782, 4782, 4783, 4785, 4785, 4786, 4787, 4787, 4787, 4787, 4788, 4788, 4788, 4788, 4788, 4789, 4790, 4790, 4790, 4791, 4791, 4791, 4792, 4792, 4792, 4792, 4792, 4792, 4793, 4794, 4794, 4796, 4796, 4796, 4796, 4797, 4798, 4798, 4799, 4799, 4799, 4799, 4801, 4801, 4802, 4802, 4802, 4803, 4805, 4805, 4808, 4808, 4808, 4810, 4810, 4810, 4811, 4811, 4811, 4811, 4812, 4812, 4813, 4814, 4815, 4815, 4816, 4816, 4816, 4816, 4816, 4817, 4817, 4817, 4818, 4818, 4818, 4819, 4819, 4820, 4822, 4822, 4822, 4822, 4822, 4822, 4823, 4823, 4823, 4824, 4824, 4825, 4826, 4826, 4827, 4827, 4828, 4828, 4828, 4829, 4829, 4830, 4830, 4830, 4831, 4831, 4831, 4832, 4832, 4833, 4834, 4834, 4834, 4834, 4835, 4835, 4835, 4836, 4837, 4838, 4838, 4838, 4838, 4838, 4838, 4839, 4839, 4839, 4839, 4840, 4840, 4841, 4842, 4842, 4842, 4843, 4843, 4843, 4843, 4843, 4844, 4844, 4845, 4846, 4846, 4847, 4847, 4847, 4847, 4847, 4848, 4848, 4849, 4849, 4849, 4849, 4849, 4850, 4850, 4851, 4853, 4853, 4853, 4854, 4854, 4856, 4856, 4857, 4857, 4857, 4858, 4858, 4859, 4859, 4859, 4859, 4860, 4860, 4861, 4862, 4862, 4863, 4863, 4863, 4863, 4864, 4864, 4864, 4864, 4865, 4865, 4866, 4866, 4867, 4867, 4869, 4870, 4870, 4870, 4870, 4870, 4870, 4871, 4871, 4871, 4872, 4873, 4873, 4874, 4874, 4875, 4875, 4876, 4876, 4876, 4876, 4877, 4879, 4879, 4879, 4881, 4882, 4882, 4883, 4883, 4883, 4884, 4884, 4886, 4888, 4888, 4888, 4889, 4890, 4890, 4890, 4891, 4891, 4892, 4892, 4892, 4892, 4893, 4893, 4893, 4894, 4894, 4894, 4894, 4894, 4894, 4895, 4898, 4899, 4899, 4900, 4901, 4901, 4901, 4901, 4902, 4902, 4903, 4904, 4904, 4904, 4904, 4904, 4905, 4906, 4908, 4908, 4909, 4910, 4910, 4911, 4911, 4912, 4912, 4913, 4913, 4914, 4914, 4914, 4915, 4915, 4916, 4917, 4917, 4918, 4918, 4920, 4921, 4921, 4921, 4921, 4922, 4922, 4922, 4922, 4923, 4923, 4924, 4924, 4924, 4925, 4926, 4926, 4926, 4927, 4928, 4928, 4928, 4928, 4928, 4928, 4929, 4930, 4930, 4931, 4932, 4934, 4934, 4935, 4935, 4936, 4936, 4937, 4937, 4937, 4937, 4937, 4938, 4939, 4939, 4939, 4939, 4939, 4939, 4942, 4943, 4943, 4944, 4944, 4944, 4944, 4944, 4945, 4946, 4946, 4946, 4947, 4948, 4948, 4948, 4949, 4949, 4950, 4950, 4950, 4950, 4951, 4951, 4952, 4956, 4956, 4957, 4957, 4957, 4957, 4958, 4960, 4960, 4960, 4961, 4961, 4961, 4962, 4962, 4962, 4963, 4963, 4964, 4964, 4964, 4965, 4966, 4967, 4967, 4968, 4968, 4968, 4971, 4971, 4972, 4972, 4974, 4975, 4975, 4975, 4976, 4976, 4977, 4978, 4978, 4979, 4979, 4979, 4980, 4980, 4980, 4981, 4981, 4981, 4981, 4982, 4982, 4982, 4982, 4982, 4983, 4983, 4983, 4983, 4984, 4985, 4985, 4986, 4986, 4986, 4986, 4987, 4987, 4988, 4989, 4989, 4989, 4990, 4991, 4992, 4992, 4993, 4993, 4994, 4995, 4995, 4996, 4997, 4997, 4997, 4997, 4997, 4998, 4998, 4999, 4999 ]\n", bench_group_opt, ); } diff --git a/cli/tests/cli_run.rs b/cli/tests/cli_run.rs index 280290bd40..1d139a9eae 100644 --- a/cli/tests/cli_run.rs +++ b/cli/tests/cli_run.rs @@ -141,12 +141,11 @@ mod cli_run { #[test] #[serial(quicksort)] fn run_quicksort_not_optimized() { - check_output_with_stdin( - &example_file("benchmarks", "QuicksortApp.roc"), - "0", - "quicksortapp", + check_output( + &example_file("quicksort", "Quicksort.roc"), + "quicksort", &[], - "[ 0, 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 6, 6, 8, 9 ]\n", + "[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2]\n", true, ); } @@ -154,12 +153,11 @@ mod cli_run { #[test] #[serial(quicksort)] fn run_quicksort_optimized() { - check_output_with_stdin( - &example_file("benchmarks", "QuicksortApp.roc"), - "0", - "quicksortapp", + check_output( + &example_file("quicksort", "Quicksort.roc"), + "quicksort", &["--optimize"], - "[ 0, 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 6, 6, 8, 9 ]\n", + "[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2]\n", true, ); } @@ -167,12 +165,11 @@ mod cli_run { #[test] #[serial(quicksort)] fn run_quicksort_optimized_valgrind() { - check_output_with_stdin( - &example_file("benchmarks", "QuicksortApp.roc"), - "0", - "quicksortapp", + check_output( + &example_file("quicksort", "Quicksort.roc"), + "quicksort", &["--optimize"], - "[ 0, 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 6, 6, 8, 9 ]\n", + "[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2]\n", true, ); } diff --git a/examples/benchmarks/QuicksortApp.roc b/examples/benchmarks/QuicksortApp.roc index 198003bf13..a1290d2fae 100644 --- a/examples/benchmarks/QuicksortApp.roc +++ b/examples/benchmarks/QuicksortApp.roc @@ -11,8 +11,8 @@ main = # small unsorted list of 20 elements (0-9) [ 2, 4, 4, 0, 3, 8, 3, 6, 4, 9, 4, 6, 3, 5, 2, 2, 3, 1, 1, 3 ] else - # big unsorted list of 2000 elements (0-1000) - [ 891, 330, 190, 304, 991, 803, 54, 362, 428, 318, 59, 631, 995, 36, 711, 450, 654, 614, 74, 288, 198, 11, 369, 290, 7, 934, 72, 642, 955, 782, 724, 811, 3, 402, 517, 128, 902, 612, 454, 281, 794, 109, 497, 454, 238, 541, 215, 672, 4, 855, 908, 868, 177, 885, 460, 133, 367, 113, 131, 191, 148, 254, 914, 680, 735, 783, 225, 720, 708, 447, 625, 526, 529, 914, 126, 857, 574, 234, 249, 433, 779, 74, 275, 302, 315, 131, 518, 572, 301, 450, 346, 630, 928, 420, 183, 287, 420, 730, 512, 533, 69, 942, 214, 801, 196, 633, 13, 493, 343, 910, 462, 939, 394, 367, 619, 583, 674, 265, 113, 909, 202, 135, 859, 924, 214, 27, 30, 531, 662, 90, 917, 35, 236, 210, 456, 758, 338, 514, 590, 907, 106, 147, 625, 199, 766, 628, 894, 552, 108, 982, 94, 751, 734, 678, 371, 894, 204, 719, 559, 676, 362, 782, 959, 826, 793, 935, 17, 837, 179, 679, 819, 33, 197, 611, 719, 718, 688, 365, 36, 62, 349, 719, 598, 826, 135, 218, 889, 282, 948, 442, 345, 453, 386, 840, 95, 921, 293, 241, 494, 774, 139, 712, 373, 730, 301, 472, 805, 41, 355, 384, 188, 168, 869, 17, 339, 55, 238, 476, 394, 725, 130, 53, 978, 762, 418, 419, 920, 913, 780, 723, 750, 277, 92, 37, 979, 971, 882, 936, 190, 216, 452, 495, 450, 597, 567, 994, 587, 777, 700, 685, 991, 995, 533, 443, 945, 56, 186, 413, 239, 286, 234, 486, 399, 410, 853, 516, 443, 999, 591, 16, 452, 314, 459, 343, 296, 189, 84, 465, 640, 616, 122, 665, 379, 858, 930, 188, 47, 445, 959, 93, 244, 89, 610, 26, 952, 294, 77, 619, 775, 661, 291, 290, 443, 458, 689, 107, 517, 794, 827, 313, 506, 568, 264, 400, 485, 972, 430, 953, 258, 409, 305, 729, 288, 146, 133, 603, 568, 748, 891, 521, 199, 12, 714, 180, 848, 317, 947, 454, 166, 776, 907, 493, 195, 5, 631, 791, 86, 932, 809, 464, 80, 846, 323, 300, 658, 869, 712, 316, 551, 700, 438, 457, 516, 747, 54, 854, 636, 72, 352, 24, 159, 222, 844, 427, 369, 969, 208, 337, 663, 388, 624, 943, 781, 868, 563, 559, 638, 818, 205, 927, 265, 235, 713, 871, 617, 34, 751, 530, 36, 418, 251, 654, 213, 99, 799, 808, 439, 609, 263, 481, 113, 706, 185, 386, 776, 152, 178, 468, 922, 0, 942, 817, 428, 66, 399, 355, 450, 792, 549, 237, 532, 212, 254, 279, 941, 685, 211, 100, 994, 182, 503, 707, 368, 472, 297, 820, 905, 83, 319, 345, 47, 547, 769, 713, 204, 153, 687, 372, 656, 914, 448, 872, 73, 955, 318, 381, 254, 849, 719, 909, 905, 558, 471, 142, 136, 865, 392, 650, 342, 698, 199, 385, 673, 632, 14, 792, 523, 862, 872, 792, 957, 739, 713, 373, 72, 464, 667, 394, 933, 305, 332, 444, 960, 322, 900, 841, 146, 566, 723, 884, 355, 153, 49, 928, 689, 304, 467, 306, 952, 277, 943, 421, 216, 704, 525, 293, 974, 754, 978, 96, 582, 5, 811, 229, 304, 52, 610, 160, 872, 831, 388, 925, 216, 665, 435, 913, 753, 381, 452, 786, 737, 834, 191, 165, 16, 174, 997, 735, 976, 189, 340, 161, 653, 849, 447, 264, 950, 349, 4, 375, 312, 3, 279, 833, 600, 721, 205, 162, 832, 451, 998, 26, 689, 870, 215, 651, 419, 831, 70, 308, 596, 500, 624, 672, 481, 522, 390, 79, 410, 77, 336, 502, 10, 95, 697, 591, 385, 820, 807, 726, 537, 359, 772, 548, 768, 981, 838, 90, 599, 172, 272, 718, 417, 789, 578, 669, 786, 534, 403, 602, 180, 115, 205, 96, 573, 359, 830, 970, 431, 533, 342, 777, 600, 880, 374, 262, 704, 31, 710, 148, 264, 288, 501, 540, 851, 929, 420, 93, 5, 350, 80, 810, 8, 153, 369, 582, 908, 756, 523, 964, 124, 842, 152, 378, 946, 720, 425, 975, 844, 211, 378, 963, 966, 297, 763, 891, 180, 505, 33, 201, 377, 167, 35, 600, 698, 801, 977, 378, 361, 35, 401, 479, 266, 758, 32, 956, 943, 705, 860, 737, 791, 727, 162, 997, 213, 785, 804, 292, 56, 651, 567, 547, 866, 531, 835, 875, 122, 721, 202, 632, 895, 117, 676, 522, 993, 357, 867, 49, 797, 655, 91, 608, 838, 322, 582, 736, 708, 65, 39, 325, 126, 619, 135, 161, 523, 228, 414, 610, 339, 952, 691, 612, 238, 400, 846, 861, 313, 161, 752, 920, 136, 650, 939, 920, 262, 358, 899, 505, 738, 155, 783, 743, 359, 605, 330, 805, 662, 608, 617, 894, 387, 568, 235, 539, 799, 58, 943, 937, 234, 386, 819, 917, 405, 490, 113, 353, 444, 437, 361, 357, 225, 656, 551, 973, 305, 892, 30, 665, 920, 716, 126, 294, 72, 635, 590, 451, 89, 236, 714, 44, 698, 401, 271, 670, 371, 919, 397, 141, 484, 847, 630, 813, 247, 414, 239, 943, 691, 277, 357, 212, 480, 220, 293, 441, 314, 193, 193, 734, 687, 515, 802, 964, 127, 547, 918, 638, 234, 145, 790, 715, 555, 160, 754, 646, 329, 861, 637, 195, 762, 33, 605, 618, 78, 938, 668, 940, 454, 606, 309, 518, 635, 211, 101, 753, 532, 743, 730, 231, 608, 516, 422, 457, 346, 155, 569, 947, 51, 334, 172, 123, 295, 885, 778, 428, 980, 621, 805, 169, 808, 316, 401, 639, 769, 118, 698, 618, 105, 744, 174, 353, 752, 957, 257, 497, 743, 260, 872, 590, 815, 543, 906, 501, 760, 358, 325, 621, 780, 189, 262, 51, 439, 341, 290, 829, 303, 705, 477, 886, 137, 6, 383, 303, 7, 149, 59, 125, 83, 877, 83, 378, 444, 318, 402, 810, 404, 329, 812, 4, 885, 44, 866, 489, 907, 860, 727, 582, 139, 808, 704, 619, 74, 909, 242, 879, 566, 221, 534, 628, 23, 916, 590, 303, 489, 523, 958, 563, 728, 657, 250, 195, 500, 88, 907, 310, 353, 745, 563, 64, 455, 91, 390, 393, 697, 65, 786, 240, 222, 617, 216, 125, 597, 913, 170, 591, 495, 840, 278, 966, 968, 978, 843, 655, 9, 557, 249, 490, 202, 550, 83, 619, 220, 351, 853, 816, 455, 561, 4, 376, 901, 300, 33, 739, 262, 991, 948, 234, 717, 857, 527, 902, 789, 624, 203, 445, 911, 288, 700, 823, 773, 970, 526, 967, 687, 144, 745, 123, 833, 889, 676, 14, 47, 96, 876, 832, 276, 60, 148, 266, 782, 456, 592, 736, 78, 451, 724, 581, 718, 993, 287, 386, 938, 243, 312, 736, 495, 493, 908, 961, 999, 404, 542, 880, 679, 433, 394, 417, 888, 448, 502, 732, 516, 22, 606, 338, 776, 711, 936, 270, 986, 275, 834, 335, 122, 287, 966, 378, 854, 233, 539, 687, 436, 193, 241, 899, 791, 698, 784, 618, 267, 194, 562, 102, 220, 866, 723, 422, 460, 924, 308, 925, 113, 508, 878, 547, 739, 475, 823, 645, 938, 959, 0, 758, 574, 706, 19, 127, 167, 344, 845, 740, 361, 768, 560, 72, 360, 866, 753, 992, 946, 929, 461, 371, 875, 599, 907, 669, 862, 67, 301, 101, 962, 827, 762, 499, 168, 183, 207, 416, 81, 333, 856, 202, 717, 533, 892, 625, 573, 313, 672, 805, 384, 294, 223, 0, 905, 410, 489, 474, 986, 842, 661, 66, 73, 918, 512, 211, 968, 26, 523, 631, 249, 621, 907, 474, 146, 388, 292, 873, 2, 404, 31, 713, 206, 225, 861, 983, 659, 743, 426, 798, 152, 9, 355, 195, 410, 618, 687, 210, 1, 928, 588, 461, 217, 132, 598, 151, 88, 320, 352, 439, 934, 968, 542, 323, 184, 227, 759, 383, 335, 146, 223, 400, 438, 451, 334, 837, 616, 753, 864, 162, 129, 913, 564, 17, 935, 951, 561, 977, 940, 956, 979, 508, 547, 513, 880, 700, 874, 485, 924, 788, 223, 162, 836, 965, 679, 696, 68, 975, 704, 44, 393, 777, 473, 209, 273, 471, 418, 350, 116, 669, 335, 639, 747, 40, 334, 417, 625, 427, 240, 248, 928, 170, 856, 159, 344, 328, 872, 123, 400, 376, 921, 934, 24, 793, 734, 839, 894, 926, 318, 389, 228, 977, 946, 613, 274, 973, 879, 757, 898, 499, 883, 405, 798, 861, 580, 577, 587, 25, 159, 391, 80, 708, 404, 593, 510, 389, 995, 786, 602, 931, 668, 368, 256, 333, 319, 918, 469, 997, 508, 334, 729, 227, 67, 666, 873, 921, 238, 112, 944, 238, 455, 287, 274, 920, 335, 820, 436, 900, 822, 880, 235, 5, 578, 502, 666, 750, 859, 467, 510, 969, 309, 369, 618, 312, 868, 999, 147, 588, 229, 967, 519, 638, 619, 982, 630, 48, 275, 807, 218, 906, 677, 841, 563, 530, 32, 494, 744, 753, 148, 43, 26, 679, 390, 135, 405, 746, 410, 487, 965, 475, 751, 199, 271, 20, 823, 833, 345, 217, 63, 13, 70, 982, 713, 491, 397, 670, 618, 85, 186, 389, 804, 355, 206, 950, 419, 637, 619, 180, 194, 773, 713, 508, 229, 77, 252, 30, 402, 558, 326, 385, 335, 995, 178, 398, 3, 116, 148, 733, 98, 447, 154, 329, 699, 104, 626, 816, 137, 43, 29, 402, 333, 292, 832, 823, 132, 449, 76, 288, 746, 730, 955, 79, 105, 52, 760, 429, 490, 377, 567, 469, 482, 614, 351, 672, 613, 942, 369, 72, 214, 54, 964, 382, 63, 18, 853, 775, 166, 551, 86, 980, 443, 659, 807, 835, 620, 288, 474, 663, 910, 935, 487, 851, 527, 763, 149, 139, 79, 333, 852, 374, 462, 241, 363, 195, 311, 822, 511, 187, 886, 180, 558, 222, 800, 66, 785, 990, 396, 243, 215, 248, 684, 780, 160, 661, 563, 457, 241, 711, 426, 296, 387, 506, 252, 289, 517, 923, 193, 787, 32, 222, 394, 692, 338, 684, 289, 809, 262, 351, 906, 231, 150, 692, 776, 187, 166, 903, 378, 583, 81, 704, 851, 552, 352, 132, 476, 759, 254, 178, 894, 183, 193, 907, 665, 683, 317, 360, 269, 348, 243, 835, 975, 193, 719, 82, 533, 874, 674, 43, 628, 167, 930, 332, 511, 176, 753, 42, 123, 768, 168, 943, 707, 783, 939, 714, 57, 799, 487, 332, 401, 335, 851, 965, 483, 654, 743, 436, 679, 675, 293, 324, 229, 337, 151, 88, 121, 469, 896, 213, 917, 608, 535, 130, 779, 672, 768, 632, 926, 29, 31, 899, 699, 4, 727, 587, 571, 830, 477, 532, 898, 293, 785, 915, 602, 291, 797, 210, 324, 711, 330, 746, 675, 149, 148, 235, 566, 212, 381, 126, 620, 49, 349, 392, 736, 693, 124, 703, 185, 569, 8, 785, 585, 488, 720, 269, 683, 457, 643, 181, 453, 976, 255, 175, 234, 644, 479, 146, 153, 719, 38, 682, 995, 865, 507, 606, 184, 886, 371, 210, 438, 123, 941, 139, 624, 854, 908, 860, 992, 372, 16, 282, 298, 270, 402, 693, 261, 402, 106, 379, 639, 156, 616, 395, 865, 409, 526, 27, 373, 604, 486, 786, 685, 814, 364, 595, 847, 792, 187, 266, 589, 981, 873, 213, 221, 293, 932, 278, 487, 760, 789, 687, 306, 680, 269, 593, 998, 790, 664, 98, 611, 959, 198, 860, 469, 779, 435, 78, 707, 717, 614, 405, 589, 92, 547, 761, 254, 88, 663, 375, 464, 489, 391, 575, 259, 427, 112, 155, 352, 544, 53, 532, 130, 663, 298, 894, 768, 336, 808, 433, 651, 452, 172, 301, 997, 82, 189, 376, 68, 250, 859, 67, 312, 514, 287, 618, 677, 250, 206, 30, 88, 991, 397, 686, 255, 353, 54, 172, 560, 783, 757, 407, 727, 22, 200, 192, 212, 248, 558, 528, 535, 495, 991, 678, 749, 484, 356, 10, 646, 920, 219, 705, 11, 988, 241, 731, 836, 350, 967, 635, 713, 610, 107, 69, 677, 349, 365, 293, 24, 860, 24, 294, 73, 113, 301, 226, 35, 31, 49, 776, 807, 951 ] + # big unsorted list of 10000 elements (0-5000) + [ 4281, 4149, 4579, 3763, 4892, 3305, 740, 1003, 3748, 4353, 1027, 2205, 4096, 4047, 1883, 3757, 3813, 2757, 2241, 1417, 2054, 1819, 680, 3645, 1979, 3897, 2180, 4072, 3688, 3440, 1107, 3511, 133, 4586, 3432, 3279, 2743, 1489, 4058, 2880, 141, 3039, 3270, 1518, 3879, 3241, 577, 981, 233, 2238, 1571, 1056, 721, 2856, 2309, 1274, 969, 1132, 1492, 2659, 106, 1145, 2328, 3854, 998, 2594, 1359, 1172, 3952, 4137, 3539, 3558, 3947, 1705, 1726, 1292, 1669, 2636, 661, 1079, 4190, 4398, 3954, 2016, 4704, 2748, 2273, 261, 321, 1278, 917, 713, 1241, 1827, 1402, 2956, 4481, 3126, 250, 3932, 727, 2689, 2566, 4584, 1718, 1634, 3977, 3045, 3360, 1072, 982, 2277, 4175, 707, 1192, 3124, 2408, 2734, 4173, 4491, 3060, 1095, 845, 4405, 4617, 2762, 1431, 2720, 4510, 1516, 1770, 1010, 499, 2346, 4191, 2684, 3979, 1794, 2796, 1973, 407, 2764, 1975, 3629, 3945, 4635, 2157, 497, 1720, 583, 520, 2036, 3638, 561, 2168, 2301, 4432, 4086, 1465, 1560, 90, 4092, 2882, 3496, 3609, 4961, 507, 106, 242, 1752, 2154, 4410, 4066, 2333, 1570, 621, 1622, 1915, 517, 4424, 2901, 4704, 394, 1066, 4001, 4645, 624, 3833, 165, 2312, 3795, 3707, 557, 4567, 1897, 4894, 4840, 2805, 655, 1514, 2376, 3504, 1029, 4207, 3054, 4802, 4253, 2339, 2278, 3180, 2426, 861, 1582, 1373, 131, 4390, 4168, 4749, 1948, 2489, 586, 614, 2833, 840, 4136, 2443, 4112, 1850, 2207, 4087, 162, 1030, 1983, 2464, 2840, 4644, 2613, 1305, 4340, 3742, 1422, 1703, 1184, 2389, 997, 413, 3787, 199, 1727, 780, 1055, 879, 3400, 4592, 2140, 4564, 3466, 4630, 2127, 197, 4719, 4045, 2818, 2817, 2207, 507, 3047, 3619, 2327, 4196, 1659, 1603, 2104, 1649, 3893, 1615, 2905, 2216, 224, 2140, 4018, 2590, 3647, 3456, 2173, 1573, 4315, 2389, 2787, 137, 4287, 792, 4260, 1363, 3609, 3610, 2550, 2788, 1020, 4347, 2513, 4633, 3633, 3875, 4670, 503, 1698, 4651, 4725, 3394, 1085, 1275, 407, 4394, 132, 2102, 1239, 2186, 588, 1212, 4641, 4371, 4448, 1910, 3735, 4489, 2793, 2422, 2177, 3639, 2284, 3887, 2759, 4667, 2735, 976, 2055, 2791, 2593, 1406, 2439, 1010, 1160, 14, 3388, 3788, 3982, 3907, 3423, 996, 2863, 2370, 2846, 2297, 18, 1961, 1495, 290, 2390, 4248, 3001, 2365, 513, 2494, 1963, 3833, 3284, 375, 4760, 2711, 1436, 195, 1891, 3935, 4384, 1943, 3347, 126, 1582, 3977, 1398, 2483, 528, 230, 1896, 1421, 1843, 4487, 2893, 4240, 3157, 4135, 2887, 113, 1307, 1960, 593, 2435, 4358, 102, 4780, 537, 1394, 1901, 4554, 2099, 2599, 4467, 4145, 192, 1759, 4141, 4102, 3631, 3425, 467, 3017, 1210, 1108, 1243, 3980, 2772, 1525, 2382, 2795, 4731, 2688, 2303, 1511, 3260, 4863, 4792, 3306, 432, 3068, 1586, 3358, 1327, 3136, 3715, 1515, 4144, 4902, 3557, 3891, 1116, 172, 4655, 2079, 1759, 366, 1223, 2066, 155, 1343, 1106, 1016, 3055, 810, 1430, 4618, 1031, 4488, 2571, 240, 4196, 1896, 2887, 4930, 3694, 2395, 1156, 2889, 4749, 4109, 112, 1578, 450, 1422, 1505, 2266, 3756, 3597, 2655, 3748, 3371, 1659, 1867, 139, 879, 469, 1601, 2566, 3471, 1905, 4403, 2714, 1657, 3867, 563, 1820, 4992, 3084, 4559, 2727, 493, 1045, 4884, 1304, 4596, 4843, 978, 3010, 2282, 3267, 1995, 3942, 4235, 2676, 528, 417, 1860, 4944, 2352, 2603, 496, 2395, 4391, 1183, 4271, 3431, 3219, 3728, 873, 4956, 4460, 3638, 1935, 511, 1820, 1753, 2536, 131, 2253, 736, 1438, 2762, 4677, 4836, 8, 4524, 4711, 1575, 334, 3860, 4697, 4237, 3095, 4017, 3574, 2925, 2398, 4938, 2612, 408, 2086, 1938, 1349, 3405, 2827, 4158, 2071, 858, 377, 1043, 776, 4126, 3981, 81, 4471, 916, 52, 427, 8, 4922, 310, 43, 4770, 800, 3928, 1616, 848, 2818, 1300, 4847, 2744, 2528, 3825, 3582, 4781, 2911, 4309, 1188, 2451, 447, 2057, 966, 1159, 2683, 2542, 4010, 367, 252, 1199, 3765, 3974, 1794, 3464, 55, 501, 3389, 745, 763, 3937, 1077, 624, 2896, 3609, 4555, 3830, 3731, 1240, 1844, 4091, 3081, 587, 424, 3000, 1682, 2332, 3235, 3995, 3520, 3567, 2748, 501, 4661, 594, 385, 3271, 3980, 401, 2904, 1184, 1240, 3933, 825, 4068, 1561, 4387, 2776, 2581, 3117, 2219, 3224, 980, 2160, 1941, 2588, 3254, 4410, 261, 414, 802, 1536, 4245, 2935, 1059, 4098, 2750, 4707, 224, 1867, 740, 593, 2448, 408, 2244, 3719, 4149, 1952, 1509, 893, 558, 2409, 409, 4287, 4817, 3790, 2356, 3100, 4204, 416, 2778, 3876, 894, 1115, 4071, 630, 386, 1346, 41, 4039, 2816, 3001, 500, 1557, 15, 775, 42, 3161, 1449, 2916, 2333, 4947, 3883, 4744, 2792, 2434, 1929, 3599, 831, 4511, 813, 927, 4273, 4285, 496, 4068, 2450, 3893, 4982, 173, 667, 3347, 370, 2424, 3855, 538, 2692, 3084, 456, 107, 4433, 4088, 1181, 1755, 4761, 4932, 3014, 221, 1925, 1649, 2944, 1646, 3994, 1389, 4617, 4609, 3952, 2870, 3535, 4859, 4733, 3696, 3549, 1038, 716, 3474, 2122, 4629, 3495, 992, 4594, 4766, 2389, 4901, 4041, 2453, 894, 2077, 874, 188, 2405, 543, 991, 3601, 3121, 329, 402, 2948, 4382, 3203, 3387, 2098, 3473, 3986, 516, 3243, 2341, 490, 4828, 861, 4527, 2197, 3777, 4860, 1031, 1546, 751, 4670, 826, 4832, 2813, 3820, 4927, 3628, 2082, 4043, 3990, 2929, 1545, 4235, 3792, 4680, 131, 4097, 2694, 652, 4785, 4419, 3044, 3127, 470, 3, 1198, 3754, 2969, 503, 3957, 582, 4109, 1982, 4487, 4330, 1452, 2202, 3601, 3797, 4331, 3630, 471, 1655, 1435, 3624, 394, 4306, 207, 1488, 126, 367, 4870, 3969, 3448, 4265, 3475, 1058, 2437, 267, 591, 4352, 4363, 1096, 3807, 2547, 4328, 2811, 4251, 3241, 3518, 1377, 4983, 1353, 1900, 676, 1969, 1213, 190, 1700, 4020, 2219, 4822, 4659, 1324, 4961, 4675, 2317, 467, 835, 179, 1129, 1093, 852, 1360, 3585, 1999, 742, 3284, 3485, 3383, 4864, 4474, 3600, 653, 1333, 767, 4075, 2345, 4888, 1263, 4482, 2638, 4430, 1173, 4543, 2068, 1466, 4302, 3583, 345, 2633, 2515, 2630, 3717, 693, 1906, 2944, 510, 4609, 4064, 3643, 4010, 657, 3435, 2258, 630, 3037, 3199, 3904, 1139, 1446, 1776, 492, 2942, 188, 2935, 1247, 2000, 4413, 1036, 3485, 4691, 606, 1678, 541, 4380, 2673, 3241, 4403, 1896, 1202, 3323, 2433, 2982, 647, 1564, 3543, 1916, 483, 4040, 2974, 4234, 4025, 3208, 2109, 1055, 2989, 4210, 1944, 3504, 465, 1687, 1569, 2783, 97, 65, 4948, 3311, 1885, 2228, 3961, 4695, 4268, 4063, 166, 3998, 2070, 3547, 2148, 2995, 2451, 2833, 4243, 438, 951, 23, 2913, 1301, 2593, 4557, 2278, 4460, 1142, 3740, 2562, 3369, 2601, 3222, 2230, 2475, 4720, 4568, 572, 2737, 4157, 685, 1934, 3377, 4864, 1586, 3916, 2828, 1462, 2539, 4147, 3028, 4734, 3198, 4312, 234, 3578, 1409, 3776, 291, 1168, 1437, 1454, 3965, 4735, 2310, 3865, 4361, 4374, 3684, 1920, 3844, 3982, 1316, 3922, 2116, 641, 4220, 684, 4937, 313, 2456, 65, 4674, 4960, 2432, 4547, 4090, 624, 210, 3766, 3452, 2226, 1189, 605, 4665, 1528, 1553, 1532, 1669, 4051, 2136, 2392, 4053, 2251, 1601, 992, 3924, 2205, 444, 3260, 417, 922, 2362, 3285, 3414, 2350, 4612, 806, 2803, 1990, 2229, 4273, 3311, 379, 2451, 3479, 1900, 4704, 744, 3895, 1795, 817, 3163, 1770, 1677, 4136, 3643, 2368, 2223, 923, 1526, 3917, 2906, 4849, 4457, 4614, 482, 1340, 4931, 1243, 595, 1297, 720, 3060, 2013, 3678, 1163, 2373, 2067, 4725, 2306, 1205, 4180, 4280, 4069, 600, 648, 3515, 762, 778, 1094, 2792, 2495, 1410, 1023, 1627, 3494, 3172, 2991, 2502, 2014, 4077, 3158, 706, 3970, 1436, 4509, 3981, 1207, 1725, 1552, 738, 3873, 4389, 4788, 448, 784, 729, 355, 3491, 308, 328, 4536, 3921, 871, 330, 3655, 4562, 2544, 1274, 3874, 3156, 3979, 1462, 3874, 4016, 4828, 1497, 2818, 4819, 4440, 4833, 2974, 4997, 232, 4843, 4631, 3602, 3109, 1249, 1565, 4556, 3899, 4216, 791, 2908, 2877, 3838, 3102, 3187, 1579, 472, 1916, 3707, 4749, 2701, 2184, 3172, 3743, 4503, 4928, 79, 4743, 1840, 4946, 2584, 1103, 4328, 1819, 4892, 1850, 749, 1717, 3878, 3507, 957, 1469, 57, 3449, 3451, 2988, 4790, 440, 2495, 770, 3417, 4243, 4273, 4189, 757, 2809, 2711, 444, 23, 3318, 3323, 2848, 316, 2036, 44, 2443, 1718, 2042, 1755, 1361, 1049, 2577, 2771, 4908, 3446, 2370, 2802, 3208, 1352, 1932, 2292, 439, 546, 2160, 4736, 4236, 625, 302, 2662, 1115, 3377, 1892, 4705, 1164, 1657, 4675, 2581, 3397, 2128, 744, 4944, 3110, 1673, 672, 4960, 3888, 1621, 3368, 4293, 3066, 3140, 1191, 1965, 2444, 4717, 218, 1385, 1668, 1207, 2764, 588, 2350, 964, 3098, 4045, 764, 3454, 4673, 1115, 3129, 3415, 4340, 1040, 2705, 924, 2776, 1, 3048, 2226, 2977, 3184, 222, 258, 4304, 453, 2176, 4623, 4166, 1949, 3002, 3917, 2304, 4147, 473, 4184, 441, 4788, 4072, 4982, 1434, 1227, 3484, 2237, 2781, 4271, 4578, 1609, 3531, 482, 2884, 1737, 1193, 4598, 2875, 2117, 1684, 2827, 4542, 3435, 908, 4076, 145, 4829, 1008, 445, 3505, 3711, 3246, 3289, 1011, 3018, 2962, 3631, 3019, 120, 4109, 2033, 2615, 4078, 3339, 1183, 3553, 969, 2093, 1306, 1102, 4674, 4567, 3871, 208, 4076, 2969, 2475, 2923, 960, 1618, 1666, 4600, 4468, 290, 4774, 4164, 2037, 2039, 187, 248, 4995, 1048, 1934, 4592, 2120, 3030, 4183, 4832, 1816, 1653, 839, 1832, 16, 2201, 2838, 323, 3270, 2133, 1722, 3816, 3469, 2197, 4336, 3734, 2088, 4666, 2299, 4975, 2704, 3493, 3574, 1152, 853, 1294, 95, 3057, 3010, 1821, 2855, 909, 4879, 620, 4944, 3780, 2516, 4279, 4588, 1714, 2439, 3161, 320, 1382, 1444, 4825, 4228, 3487, 2604, 2232, 1539, 201, 3867, 2869, 411, 46, 3228, 247, 3911, 3511, 351, 2769, 1322, 4826, 2203, 890, 3788, 2824, 3837, 1896, 1967, 3239, 2078, 2617, 3591, 4943, 2532, 2276, 3184, 3456, 312, 2519, 1270, 3996, 2548, 908, 333, 1845, 1167, 369, 1957, 4307, 1501, 1971, 3247, 4857, 3054, 807, 3738, 3072, 4964, 4901, 3514, 2858, 3055, 4569, 3854, 1774, 1876, 770, 2121, 2326, 1937, 2661, 163, 201, 2200, 4013, 3648, 1735, 2438, 3907, 3636, 4299, 3736, 21, 4253, 2514, 186, 466, 2205, 4728, 1035, 1754, 2873, 3581, 3441, 3539, 2999, 4225, 1547, 1689, 2009, 1691, 3751, 3759, 3438, 4774, 867, 1777, 2616, 7, 756, 3411, 1973, 2544, 1132, 2400, 1380, 2520, 2538, 423, 702, 3146, 2029, 3476, 4848, 1003, 3617, 1455, 666, 134, 1296, 813, 1842, 723, 2874, 160, 4041, 1240, 1907, 1634, 725, 1881, 3700, 1238, 1639, 3915, 4499, 2692, 940, 3218, 1931, 3801, 1719, 764, 4816, 1876, 4402, 3599, 890, 198, 940, 1534, 599, 3052, 1232, 910, 3055, 2397, 2772, 1996, 250, 3285, 3573, 2523, 3802, 828, 4554, 4330, 1176, 1222, 4915, 1798, 1580, 4738, 4551, 3322, 1683, 4755, 2995, 4512, 1820, 3685, 224, 4170, 1802, 2824, 2628, 4285, 4236, 4198, 3336, 2651, 10, 2809, 4060, 3718, 831, 2947, 3734, 928, 3624, 849, 2567, 2310, 4474, 4721, 2904, 1491, 4365, 4447, 2052, 4744, 3973, 2650, 3480, 876, 2463, 1084, 3942, 691, 1073, 4757, 229, 1497, 2229, 1669, 674, 256, 2206, 3311, 2800, 592, 2838, 1042, 2123, 602, 434, 552, 2776, 4179, 2976, 4592, 686, 2805, 4840, 484, 4134, 789, 2790, 73, 3113, 4158, 1956, 1377, 1199, 4901, 4755, 1026, 2821, 2649, 3301, 2651, 1398, 330, 1482, 4844, 687, 1116, 4131, 659, 3150, 4282, 475, 2162, 2084, 4439, 3145, 145, 4693, 2926, 3200, 4720, 4341, 4980, 4850, 3961, 3565, 4604, 466, 4441, 832, 2084, 4875, 739, 2790, 523, 3983, 4160, 630, 4038, 1891, 2324, 667, 420, 1361, 2710, 1205, 412, 2410, 2888, 4873, 2372, 612, 1923, 2857, 2725, 4823, 1042, 1721, 2140, 4529, 2801, 3637, 1995, 1503, 4956, 1766, 3910, 1474, 644, 1410, 4705, 3892, 617, 532, 3475, 3111, 646, 4344, 4830, 571, 3380, 862, 4291, 4558, 2115, 861, 1151, 3521, 4244, 2037, 2272, 39, 1371, 1355, 4179, 3072, 442, 4189, 3669, 93, 3968, 3759, 1213, 4340, 1154, 2941, 1192, 3821, 1289, 2307, 559, 424, 3911, 3161, 1996, 4525, 3811, 2902, 3669, 1219, 770, 2820, 1780, 1950, 4995, 345, 3772, 307, 1887, 1452, 3359, 835, 4830, 3846, 2849, 2132, 4070, 1971, 1797, 2890, 3468, 1600, 3872, 937, 4282, 1998, 3550, 908, 4867, 2377, 3462, 2349, 4434, 3216, 1461, 2681, 1775, 4752, 1439, 3203, 4235, 4147, 4750, 4041, 2051, 10, 2780, 2054, 3566, 4111, 2698, 3520, 3816, 2589, 4700, 2338, 1973, 2444, 1465, 1741, 712, 3457, 4272, 4895, 1409, 4963, 2163, 3369, 4570, 1976, 4879, 1459, 2809, 477, 4946, 3800, 3455, 4720, 434, 2919, 4824, 3688, 3555, 2618, 3615, 385, 4330, 4140, 1552, 737, 4288, 4000, 4086, 186, 1673, 2449, 3272, 3262, 1682, 14, 3119, 1206, 2461, 1625, 4644, 2637, 224, 2300, 1708, 2596, 3650, 1312, 775, 4863, 1556, 3868, 1180, 1061, 836, 4295, 2343, 2063, 2186, 3632, 674, 169, 2082, 3316, 2149, 2812, 1032, 2852, 114, 2735, 4646, 58, 744, 3299, 3623, 3607, 3923, 2972, 3414, 3583, 765, 3515, 2965, 295, 4348, 4470, 647, 4716, 2449, 3788, 643, 4188, 3504, 2477, 3341, 1219, 3362, 3267, 3859, 4867, 356, 576, 914, 4799, 2016, 464, 326, 1346, 170, 3880, 4708, 3797, 3992, 2334, 1675, 2084, 481, 421, 1967, 3402, 2183, 766, 2457, 1001, 2993, 3087, 2149, 1252, 3249, 108, 1506, 4488, 2467, 4145, 4475, 3194, 3128, 829, 2059, 3855, 3016, 4874, 1767, 4926, 4170, 119, 3115, 3378, 1256, 1436, 1124, 2819, 592, 522, 3965, 1341, 543, 4912, 2172, 2042, 4834, 4408, 4710, 1863, 4139, 1023, 3996, 2430, 3018, 1574, 2133, 2783, 3716, 1290, 4735, 2425, 4100, 4572, 596, 3189, 2472, 2581, 1409, 2491, 394, 1688, 4597, 2323, 3615, 218, 391, 3287, 2251, 2159, 448, 1178, 925, 228, 3149, 129, 4113, 4031, 2203, 3489, 2631, 268, 2556, 1934, 4581, 712, 4455, 2137, 2474, 3369, 2065, 4924, 3954, 3654, 4730, 3018, 2201, 3975, 1824, 1174, 3195, 1826, 3162, 3273, 1324, 2747, 3767, 619, 714, 3690, 4744, 4198, 597, 604, 1481, 2615, 658, 701, 3166, 4601, 2613, 2864, 3198, 2340, 593, 697, 2345, 4135, 503, 4291, 1559, 3834, 2900, 601, 3722, 613, 313, 896, 1389, 210, 896, 1019, 1174, 1272, 4386, 1672, 2158, 58, 3045, 1933, 2193, 3534, 1660, 2259, 3120, 4678, 1699, 857, 2200, 4399, 2460, 4972, 2731, 166, 3209, 1124, 3143, 249, 2763, 3986, 4186, 1018, 875, 2707, 294, 4042, 1571, 2964, 1407, 780, 4172, 1436, 4576, 543, 2045, 4535, 774, 1744, 4726, 2401, 2392, 1832, 4104, 2271, 4690, 477, 1582, 433, 4457, 2891, 3310, 1586, 4998, 228, 4771, 2426, 3411, 3969, 1677, 610, 4306, 1486, 2107, 341, 2435, 2791, 2670, 4437, 543, 3487, 3252, 3308, 653, 2615, 1414, 247, 2325, 4668, 166, 4087, 4913, 395, 1459, 3842, 4085, 4738, 4150, 4796, 3732, 409, 109, 2460, 3631, 3196, 4989, 4543, 115, 2910, 1277, 3398, 2277, 2748, 3873, 4529, 4035, 2397, 1047, 290, 4040, 2444, 4099, 4129, 344, 3112, 2617, 2039, 1399, 2786, 3335, 258, 1057, 2648, 2521, 4177, 2132, 4976, 2691, 4035, 3683, 1648, 4866, 336, 4792, 2064, 681, 4395, 3937, 1383, 179, 3190, 4743, 3518, 190, 3276, 3536, 4118, 998, 2950, 315, 3981, 1849, 655, 4864, 2239, 667, 1854, 505, 672, 2905, 3005, 2902, 848, 2674, 1363, 2172, 1997, 164, 183, 943, 619, 496, 86, 4457, 1680, 15, 13, 2785, 4164, 2774, 2497, 1415, 1930, 1784, 4144, 2684, 1093, 1712, 959, 3937, 4338, 1185, 4047, 3026, 788, 3554, 856, 2842, 4365, 1365, 3869, 601, 4791, 872, 4103, 2249, 3718, 4285, 2845, 108, 673, 833, 4721, 863, 793, 3078, 4059, 2608, 1448, 4657, 4414, 1090, 1232, 4575, 4572, 4087, 2080, 4579, 301, 4170, 3781, 186, 3661, 3120, 3710, 1090, 4137, 2690, 1002, 1378, 3566, 4420, 1529, 4317, 147, 2660, 4156, 3361, 2691, 4853, 2907, 1066, 1353, 3779, 1257, 3063, 3499, 1749, 719, 3958, 3278, 1047, 646, 2964, 405, 483, 2180, 4509, 2785, 1833, 4437, 3314, 4822, 1122, 1222, 2021, 1598, 4674, 1441, 288, 1657, 2195, 3179, 4479, 3943, 144, 2018, 2633, 4544, 2660, 3875, 3266, 4555, 2934, 3211, 3275, 3769, 1122, 1680, 2140, 2433, 979, 92, 1207, 4971, 583, 964, 3770, 1427, 4636, 1320, 3383, 639, 3218, 438, 1905, 4190, 3919, 1235, 381, 4334, 4223, 4435, 901, 1383, 333, 3596, 2853, 2455, 812, 4043, 2766, 717, 213, 416, 4165, 1130, 1416, 2119, 929, 519, 8, 4904, 4318, 732, 3043, 1728, 3011, 786, 4442, 1085, 2812, 873, 2545, 0, 4085, 4022, 3708, 633, 414, 2440, 1506, 1065, 4450, 4968, 3964, 2380, 3439, 469, 1505, 1001, 1138, 2042, 4548, 826, 298, 2688, 1860, 4108, 3749, 2870, 4513, 1655, 4236, 3919, 4107, 2159, 2809, 4569, 753, 2943, 4429, 4401, 4903, 1727, 28, 4438, 3322, 3042, 4108, 2398, 1697, 2448, 1057, 3503, 1125, 3337, 477, 2051, 986, 4733, 4114, 3420, 48, 1215, 2541, 4511, 1560, 4966, 1588, 2444, 1061, 4625, 4125, 4792, 1184, 4061, 1296, 4415, 3554, 2496, 1860, 267, 916, 3203, 1612, 2416, 4188, 665, 3186, 305, 1590, 4456, 3020, 3224, 3352, 1270, 1526, 3658, 3837, 3119, 2982, 2003, 3052, 1934, 3280, 4316, 1643, 3127, 4071, 493, 3411, 3367, 718, 712, 527, 1844, 4150, 4344, 3559, 4891, 3679, 3341, 1934, 4526, 4279, 2921, 1827, 3431, 2588, 4870, 3826, 2388, 1028, 361, 2999, 2922, 2094, 4244, 139, 4082, 2190, 2652, 1028, 4033, 4299, 280, 178, 4238, 3511, 1381, 1374, 3551, 3766, 4112, 4130, 3104, 2021, 542, 599, 1814, 4610, 2997, 331, 3988, 4890, 2068, 4253, 3929, 2127, 1849, 2185, 4164, 2904, 3439, 4543, 4256, 4934, 4869, 4192, 1043, 799, 4027, 4173, 3357, 4348, 2056, 4101, 2143, 3038, 2384, 1281, 4937, 200, 2489, 1413, 4841, 3930, 3444, 4835, 833, 1938, 4381, 766, 4436, 3167, 2287, 3828, 4270, 2539, 2365, 2508, 3965, 4631, 3099, 2806, 4160, 1234, 1811, 427, 820, 1093, 2433, 4020, 2786, 535, 566, 556, 4616, 4227, 893, 277, 3345, 2043, 3202, 1756, 2757, 2485, 2876, 719, 365, 789, 1865, 1740, 58, 684, 2535, 3405, 3233, 787, 4600, 2421, 1935, 3757, 1462, 4891, 3377, 3338, 4793, 931, 1931, 1105, 1413, 3060, 1602, 531, 1095, 375, 372, 1809, 1276, 2307, 3231, 1493, 344, 3842, 2380, 2042, 3500, 4944, 1290, 1009, 3114, 2857, 937, 4159, 3801, 4189, 4252, 978, 428, 2146, 1386, 182, 558, 2147, 4472, 3930, 3932, 4225, 2803, 4052, 2102, 3013, 267, 901, 1181, 4125, 2851, 4699, 28, 3887, 553, 3347, 2091, 2564, 1176, 3894, 1551, 3435, 1722, 4968, 4875, 3005, 4179, 2207, 2281, 3621, 1336, 2068, 84, 3681, 3086, 4740, 3802, 2458, 4982, 1095, 4132, 4280, 3031, 4305, 1142, 512, 4683, 1554, 3895, 1477, 498, 1242, 4849, 3286, 1396, 3081, 1204, 975, 2235, 2340, 2545, 746, 75, 763, 2986, 1127, 403, 560, 83, 2602, 3947, 485, 4218, 3570, 311, 420, 3835, 2016, 2726, 2372, 1879, 1714, 1202, 3171, 2427, 1227, 3891, 2887, 3736, 2324, 1641, 4637, 4550, 1356, 817, 1207, 789, 4859, 4249, 1438, 4504, 3388, 2365, 3958, 3082, 283, 94, 4211, 2433, 2134, 2256, 1406, 1137, 150, 2519, 2215, 1393, 3664, 4962, 4491, 4873, 282, 4187, 2245, 1296, 3150, 1359, 4711, 4, 4986, 4376, 1933, 549, 3639, 3690, 2302, 4220, 2204, 21, 4578, 1827, 2654, 833, 465, 1340, 303, 4747, 3926, 4667, 69, 4510, 2911, 4950, 3194, 4501, 3167, 923, 2779, 4962, 316, 2158, 1576, 528, 2863, 835, 453, 4153, 3682, 4604, 279, 3484, 797, 1075, 4679, 461, 3688, 3821, 1589, 3247, 589, 1433, 1053, 4798, 2262, 1252, 745, 3621, 814, 997, 1658, 585, 2823, 2677, 3168, 1806, 3065, 3228, 1779, 4536, 4985, 659, 1323, 2465, 4608, 963, 845, 4132, 4142, 2232, 3475, 650, 4563, 1772, 2816, 4082, 4732, 60, 4223, 4211, 4238, 2573, 2569, 737, 178, 3722, 2675, 2632, 4457, 1870, 2275, 1915, 865, 4310, 3789, 1225, 4035, 1217, 4180, 3858, 2130, 1957, 2226, 452, 1307, 917, 713, 4780, 1161, 4473, 393, 829, 1855, 4188, 3483, 4258, 1210, 4033, 3714, 3888, 3897, 4081, 2573, 4360, 960, 4116, 2805, 2854, 4939, 426, 4636, 2845, 4617, 4297, 4341, 1481, 1134, 2437, 2880, 1104, 694, 3780, 4247, 4179, 4870, 2589, 4813, 4651, 1298, 3268, 1018, 657, 2514, 3414, 845, 603, 2546, 1548, 1817, 3770, 844, 2303, 4894, 1581, 4758, 290, 3948, 3456, 2670, 3584, 4368, 706, 1762, 561, 1730, 4119, 4831, 1684, 4001, 1232, 794, 3548, 2316, 765, 1309, 1671, 2616, 1978, 1261, 2111, 570, 23, 210, 2020, 2259, 1078, 1930, 160, 1885, 3150, 511, 144, 4710, 3274, 4083, 4744, 2621, 615, 2967, 1974, 4789, 1044, 672, 283, 3747, 2104, 163, 2959, 1853, 1649, 4748, 1999, 3346, 1339, 2609, 4163, 4669, 4514, 4991, 4621, 1751, 2345, 2265, 3182, 628, 2759, 3863, 2615, 1767, 2935, 1311, 800, 3241, 3998, 3740, 1481, 66, 2898, 4816, 1176, 1462, 2096, 1065, 302, 59, 63, 4819, 2476, 2387, 2607, 3751, 3089, 2947, 4332, 2265, 3890, 2041, 67, 90, 3051, 3009, 4818, 3734, 3008, 1228, 2036, 2741, 3020, 481, 2609, 1641, 4509, 3847, 3822, 1501, 2265, 3800, 2127, 3822, 270, 3206, 927, 90, 3112, 3427, 2096, 1855, 3829, 4611, 1058, 870, 3113, 1028, 798, 4890, 2958, 4104, 2574, 4894, 2454, 4271, 4728, 1253, 1230, 359, 1095, 1297, 2153, 1004, 383, 2781, 2733, 2319, 3984, 3581, 337, 1103, 1911, 1253, 4525, 527, 3394, 1785, 2506, 1539, 1449, 3729, 2402, 1064, 3705, 4892, 4521, 2836, 3505, 3806, 4918, 459, 1495, 3599, 2139, 3809, 1373, 3871, 1919, 3702, 3097, 1211, 1887, 3487, 1286, 3467, 3142, 2636, 1319, 4275, 3138, 756, 4254, 1752, 1608, 4401, 829, 57, 4105, 4566, 135, 4106, 846, 4560, 4673, 4659, 52, 3188, 4244, 4053, 815, 2640, 112, 2280, 3000, 1838, 3639, 2581, 4828, 218, 374, 4038, 1241, 3499, 2158, 3540, 1951, 4771, 131, 3189, 1341, 4741, 4690, 3817, 1552, 2086, 2351, 1451, 1861, 1639, 836, 881, 1385, 14, 1481, 3476, 4453, 3713, 4419, 1995, 4432, 3933, 2167, 734, 1848, 1040, 225, 1488, 1707, 2, 1347, 1341, 2519, 87, 88, 3706, 1880, 2256, 33, 2289, 2942, 3924, 1321, 21, 3769, 3912, 3953, 3425, 4693, 163, 2861, 4181, 1918, 3838, 4871, 2532, 2235, 226, 2219, 4503, 4273, 3782, 4358, 1951, 4361, 2410, 4951, 4377, 2912, 2063, 260, 4937, 1140, 603, 1292, 1330, 3068, 4365, 363, 424, 2708, 291, 3102, 3857, 4466, 3747, 4476, 1544, 293, 1013, 387, 1142, 3991, 2793, 4335, 2122, 289, 3397, 1722, 961, 2172, 4921, 2191, 2301, 3566, 4118, 1498, 1035, 2410, 3879, 2613, 675, 348, 4728, 1150, 1723, 4122, 236, 3486, 3306, 3026, 1049, 2766, 582, 1034, 1514, 840, 2317, 4649, 3800, 4575, 2363, 2059, 2226, 2550, 109, 3517, 2474, 3835, 4790, 4665, 3450, 3113, 2911, 1274, 2086, 4997, 4145, 3349, 1284, 3109, 4474, 2385, 3716, 3594, 3228, 786, 1578, 4239, 2035, 2381, 2447, 4433, 4161, 749, 455, 1320, 343, 1227, 3263, 3308, 1739, 910, 2148, 3094, 4190, 3752, 2966, 3170, 100, 2063, 4427, 3092, 3553, 2156, 4876, 2690, 4148, 4794, 2999, 921, 4758, 3498, 119, 4431, 1373, 2311, 3320, 3801, 2102, 888, 1800, 4792, 4403, 794, 664, 1703, 4190, 1673, 4827, 3331, 4359, 3843, 2091, 4935, 1691, 4164, 3736, 1067, 1412, 2192, 2441, 993, 2410, 3892, 4322, 1768, 2554, 1517, 198, 585, 18, 2312, 3513, 4572, 253, 3077, 4655, 2776, 1869, 719, 4484, 318, 2119, 3315, 1825, 4639, 1419, 3410, 4547, 3713, 2801, 4241, 1079, 2440, 4985, 4035, 285, 1024, 488, 3046, 2216, 1782, 4521, 204, 71, 4435, 4202, 214, 3166, 1885, 3467, 2997, 433, 3705, 230, 2486, 2652, 3802, 2552, 801, 4835, 4055, 1252, 3653, 3586, 1079, 2474, 1473, 3170, 2868, 872, 3832, 4600, 1873, 2454, 1024, 2988, 4640, 3016, 2003, 3122, 434, 3207, 4173, 3078, 4822, 1787, 3109, 4302, 4286, 1542, 4455, 3286, 2360, 3340, 1605, 3196, 2927, 63, 165, 1659, 252, 828, 3844, 3134, 2907, 3043, 4389, 3915, 2876, 1581, 1384, 2097, 3746, 4788, 4533, 1998, 3945, 1152, 449, 4479, 2896, 2604, 330, 3460, 4743, 2939, 3668, 4762, 4924, 3843, 3198, 138, 2740, 4389, 4432, 1226, 4685, 1914, 2818, 3514, 2613, 1389, 4971, 523, 190, 3365, 1581, 2881, 1496, 4997, 530, 243, 4823, 2188, 2995, 3679, 615, 1558, 3394, 3649, 102, 2823, 849, 4905, 4605, 3137, 2944, 3796, 4154, 1945, 1734, 2830, 2496, 2410, 741, 150, 3602, 1605, 3330, 4904, 3214, 4181, 2082, 3408, 3305, 4255, 2608, 2121, 1180, 3495, 42, 2012, 3516, 1143, 4904, 3505, 4714, 3037, 255, 3984, 1279, 2083, 3934, 4372, 2172, 4196, 1207, 339, 2467, 2205, 4089, 3789, 3887, 3402, 3881, 2546, 2132, 4635, 3569, 3082, 1323, 4763, 824, 628, 4253, 1791, 3744, 3302, 3074, 3350, 1994, 3086, 260, 1098, 2633, 799, 4808, 4419, 334, 3884, 2767, 3681, 4939, 465, 1791, 4214, 148, 1674, 3905, 4072, 4337, 717, 726, 3989, 2816, 625, 4911, 1463, 2830, 4210, 4909, 2550, 2155, 1581, 993, 3728, 4693, 370, 4989, 223, 4136, 1160, 4339, 2693, 3075, 1071, 4358, 2647, 3148, 4649, 4513, 1265, 3939, 3646, 4659, 2926, 1088, 4221, 2628, 744, 4574, 4347, 4239, 2228, 2234, 2897, 1140, 3273, 2629, 616, 1422, 1445, 2548, 104, 2711, 2339, 3861, 826, 2622, 3041, 1195, 1602, 4566, 4780, 1304, 2718, 3972, 32, 4140, 3108, 341, 4285, 1365, 2246, 821, 3118, 3870, 1290, 1407, 3457, 1086, 2415, 2634, 4370, 3196, 181, 4192, 6, 1960, 4244, 1957, 595, 1684, 3267, 4396, 1526, 1579, 2437, 1509, 400, 2432, 1074, 2092, 2441, 229, 1606, 1822, 2384, 1510, 4921, 3583, 3862, 4081, 1113, 2367, 105, 4072, 1064, 2072, 2797, 3705, 3351, 1444, 4913, 4757, 4559, 757, 4167, 198, 3736, 4580, 4124, 1111, 4575, 4135, 1857, 3280, 1078, 4269, 423, 3107, 3773, 905, 3074, 2804, 2551, 2572, 3859, 2437, 1328, 1338, 3276, 2349, 4462, 1007, 1819, 3847, 4720, 3077, 2085, 38, 68, 4117, 1411, 2495, 98, 3819, 2619, 1544, 2908, 2811, 1240, 2075, 4228, 518, 806, 3722, 4286, 3039, 3989, 4695, 3899, 4683, 4528, 594, 4761, 752, 800, 4070, 63, 3577, 4086, 1886, 1367, 3256, 99, 1024, 762, 4021, 581, 1744, 2024, 4842, 3200, 3255, 2777, 829, 2524, 2587, 2354, 1506, 224, 1677, 88, 3306, 4582, 470, 2997, 2632, 3862, 2743, 2692, 4571, 2414, 1815, 654, 4387, 2367, 4666, 1640, 3251, 2550, 442, 1440, 1138, 3562, 2363, 3573, 131, 2508, 2276, 991, 1340, 686, 3266, 1538, 491, 2199, 2729, 2843, 249, 4163, 3714, 377, 4539, 4381, 1678, 1871, 1856, 1086, 2347, 1811, 4552, 2802, 3865, 4272, 4960, 2091, 2482, 3890, 1233, 2742, 134, 3301, 2754, 4374, 4176, 2805, 218, 495, 3130, 2889, 1972, 2668, 2436, 839, 2317, 941, 1230, 1309, 4118, 1921, 1556, 3664, 1844, 596, 1791, 3706, 1949, 1658, 4501, 2779, 4255, 2787, 3714, 3309, 3478, 860, 1894, 2324, 660, 3633, 2079, 659, 186, 909, 1000, 317, 392, 3779, 2710, 1609, 4514, 1410, 3321, 1232, 218, 1649, 1314, 324, 2661, 396, 736, 4007, 2544, 3026, 3382, 3923, 4223, 4553, 3045, 945, 1459, 4189, 1608, 1122, 574, 920, 2039, 4058, 2464, 4074, 4093, 310, 1682, 2503, 2960, 566, 4729, 1480, 3270, 357, 58, 3374, 3036, 3333, 821, 3462, 3443, 1415, 3967, 3793, 745, 3359, 894, 4308, 2100, 4701, 2670, 3667, 2736, 2835, 1660, 2755, 368, 2968, 1872, 4315, 2504, 1681, 3688, 878, 415, 3089, 1860, 2191, 4922, 818, 525, 1943, 4214, 1308, 1401, 4893, 2459, 1176, 2365, 2987, 980, 4515, 2718, 4421, 1216, 2459, 1992, 4982, 3582, 1969, 1372, 4283, 4824, 4142, 820, 2895, 2601, 3261, 4060, 2493, 3268, 1184, 1618, 766, 3678, 135, 3016, 3763, 438, 2127, 2270, 1254, 4129, 84, 3175, 298, 2473, 2766, 1040, 244, 242, 2339, 1984, 3900, 4950, 261, 4625, 2174, 4011, 418, 4636, 391, 4405, 2464, 3734, 1385, 2628, 3979, 1463, 19, 1316, 4524, 453, 3443, 93, 1798, 1555, 2133, 2591, 1094, 3512, 331, 1497, 3906, 4080, 3643, 2296, 4069, 3662, 3288, 2495, 1404, 2890, 4265, 1739, 740, 3281, 1477, 2981, 4261, 3177, 447, 2231, 2435, 2379, 42, 1903, 3718, 513, 1444, 779, 708, 3737, 2397, 1841, 4847, 2250, 4312, 4115, 4319, 4457, 1244, 2044, 4594, 1958, 258, 2414, 1308, 31, 4846, 4539, 324, 1167, 4073, 1362, 3209, 4703, 1255, 575, 354, 1951, 3452, 831, 3948, 3464, 4311, 4653, 1987, 4624, 953, 993, 949, 4178, 1296, 3863, 2705, 2066, 2702, 313, 4355, 351, 1407, 2772, 1991, 2640, 968, 3672, 4233, 187, 2687, 73, 406, 513, 1384, 309, 4239, 4542, 2524, 3196, 1950, 4627, 3253, 641, 2394, 842, 2808, 4831, 4647, 381, 3671, 667, 424, 571, 619, 4815, 3068, 2690, 3984, 2479, 1268, 2128, 3331, 3825, 4595, 807, 376, 1757, 1131, 883, 3861, 4361, 4950, 4270, 1602, 3162, 1793, 2187, 2150, 1776, 4769, 2580, 3677, 2980, 1320, 3573, 4496, 4839, 4202, 2313, 2041, 1227, 3071, 4110, 532, 3861, 388, 3687, 2102, 2869, 3600, 1447, 1272, 4372, 3851, 1850, 4928, 3808, 4074, 3003, 1224, 541, 3323, 3370, 4420, 1760, 161, 3133, 4654, 3154, 1179, 2089, 74, 1399, 3331, 3450, 3683, 3254, 1017, 1386, 4010, 81, 4215, 4881, 3132, 4283, 2980, 109, 3784, 2042, 2240, 2868, 124, 3021, 8, 4578, 863, 265, 3412, 3501, 928, 836, 175, 3229, 1366, 1720, 4179, 3854, 2632, 2663, 2900, 3858, 2694, 4116, 2485, 1481, 1779, 2539, 943, 807, 1496, 3670, 4705, 1700, 592, 1933, 180, 4716, 3236, 1332, 1359, 858, 2155, 4587, 4327, 3897, 4718, 3906, 4900, 3178, 2603, 2137, 1478, 4453, 4142, 3359, 2497, 4972, 1854, 1929, 1969, 1325, 3503, 176, 3398, 1740, 2567, 147, 391, 3762, 2557, 4957, 4638, 251, 2897, 3165, 507, 2062, 2904, 4156, 3717, 3223, 3143, 4701, 1789, 3205, 2688, 973, 3495, 2638, 3003, 4371, 4457, 4481, 4546, 505, 1432, 1171, 4641, 1859, 2234, 3384, 1719, 2932, 3087, 4153, 1596, 224, 1568, 4192, 3708, 4949, 2739, 149, 106, 3739, 3182, 3682, 51, 2409, 3891, 1890, 1948, 3705, 784, 354, 456, 1989, 2885, 4830, 2674, 4783, 2717, 335, 3495, 3425, 4217, 444, 790, 1912, 4043, 645, 2713, 4688, 4774, 887, 126, 4560, 4218, 1059, 1674, 4238, 2718, 162, 1814, 892, 4297, 4253, 4500, 996, 1227, 4801, 2862, 1723, 3398, 3443, 54, 1655, 2016, 3079, 3412, 2399, 479, 4144, 36, 3119, 2269, 3960, 1801, 2726, 766, 3105, 3795, 540, 423, 2656, 3552, 1708, 722, 4275, 347, 1232, 1901, 4341, 1360, 1045, 4670, 1906, 4109, 3952, 4078, 865, 3438, 2860, 1607, 186, 514, 3656, 2520, 1680, 4414, 4614, 4117, 1804, 1858, 3613, 4863, 3363, 3576, 1367, 897, 1931, 949, 4701, 4601, 764, 3517, 2338, 1573, 3554, 4393, 4552, 2438, 4181, 551, 2115, 890, 362, 3771, 2195, 1757, 4247, 4787, 557, 4465, 4134, 2704, 2656, 4228, 3758, 1960, 3087, 1970, 4052, 2723, 3321, 2185, 1069, 3802, 3492, 3652, 2566, 2710, 3449, 2227, 308, 1014, 889, 1740, 3667, 1020, 4190, 1359, 658, 3422, 4067, 2280, 659, 4816, 314, 268, 1878, 3742, 1651, 4025, 4844, 1491, 3329, 3340, 2742, 3028, 1760, 4123, 2537, 1878, 3331, 449, 3430, 4031, 1012, 1691, 3324, 2859, 3554, 3745, 1434, 1345, 3053, 1983, 1202, 2791, 4137, 95, 991, 165, 1751, 3568, 2485, 475, 3831, 3175, 4882, 3159, 629, 1965, 1199, 1217, 2538, 916, 1150, 1663, 1094, 690, 3561, 4980, 1555, 997, 563, 4943, 4839, 3615, 4441, 3288, 1634, 4320, 4618, 2952, 1346, 40, 1219, 2474, 2853, 4762, 591, 972, 2563, 3383, 1522, 1051, 3833, 3491, 844, 2622, 4282, 2878, 4411, 3556, 3263, 3429, 1426, 2763, 4631, 4687, 630, 752, 1823, 1016, 4114, 3155, 3524, 1857, 735, 538, 226, 3958, 488, 3794, 730, 1467, 4327, 4494, 200, 622, 3035, 4786, 2592, 2724, 4860, 797, 500, 3508, 1012, 1764, 166, 4178, 3422, 1995, 4290, 3630, 3825, 3454, 3225, 4548, 3445, 2567, 4834, 1215, 3884, 368, 4876, 4356, 2063, 4032, 1, 496, 3074, 4871, 4703, 3560, 954, 932, 82, 3628, 475, 3915, 2700, 2268, 1458, 4327, 3365, 2557, 1170, 3284, 541, 4590, 3276, 326, 1375, 1816, 4114, 3069, 3223, 4634, 476, 1470, 1538, 1626, 1624, 468, 2987, 3251, 3093, 562, 2870, 2010, 2097, 3147, 4738, 3792, 358, 1994, 845, 2554, 425, 3420, 4979, 3131, 1802, 919, 1532, 770, 4811, 4025, 1869, 663, 3909, 2544, 4643, 1998, 64, 4990, 3615, 4085, 2125, 929, 1949, 2028, 4337, 1932, 2690, 666, 1799, 584, 4602, 1444, 4007, 1063, 2459, 2105, 1475, 2220, 4257, 3128, 1276, 990, 659, 385, 1143, 1444, 2553, 673, 3783, 812, 4135, 4291, 3535, 3788, 2736, 3405, 249, 1081, 519, 2699, 4818, 2472, 4746, 1991, 3982, 4715, 2762, 3868, 1793, 3363, 1995, 1746, 3892, 1378, 1755, 3272, 2598, 1958, 295, 3169, 3193, 3302, 1191, 2548, 421, 4620, 3079, 3804, 106, 1722, 1460, 404, 476, 4923, 66, 4327, 1201, 2284, 1167, 4200, 4949, 1302, 3315, 992, 4312, 4835, 4916, 3600, 549, 2133, 55, 4078, 3062, 3633, 58, 839, 1100, 3388, 3694, 3007, 1129, 4679, 3745, 4746, 164, 199, 1528, 1098, 117, 3426, 3895, 3880, 1581, 773, 2260, 2081, 4563, 255, 3112, 1793, 561, 2161, 4728, 4928, 846, 1077, 4671, 4348, 413, 1459, 1781, 3051, 3057, 847, 331, 1660, 123, 2945, 1965, 980, 4853, 294, 1271, 3068, 398, 3272, 1251, 3595, 916, 2532, 2991, 667, 2537, 3977, 2978, 4634, 1645, 3381, 1397, 3087, 3116, 1105, 3427, 4799, 142, 3490, 4602, 349, 1257, 488, 3091, 2258, 223, 1505, 1881, 3444, 3403, 3327, 3586, 1202, 1847, 3116, 1297, 2285, 4287, 185, 756, 4939, 4802, 3685, 4646, 1123, 3666, 177, 886, 1148, 4627, 4200, 4617, 1645, 3818, 4556, 991, 1434, 2577, 3177, 3926, 3110, 2353, 4258, 4261, 3154, 1348, 1450, 1876, 1634, 362, 3839, 3622, 1818, 2566, 4680, 4471, 164, 1339, 3770, 4233, 2296, 1857, 4293, 4710, 1771, 1600, 974, 2342, 1280, 1839, 3068, 1679, 3845, 2653, 3048, 1621, 3282, 1169, 4805, 2175, 3851, 127, 1207, 4414, 1793, 3907, 751, 194, 263, 3127, 3731, 72, 9, 1444, 2884, 3639, 4444, 3021, 4549, 899, 3216, 3344, 2609, 2306, 2164, 3121, 3213, 2375, 2128, 1299, 271, 4975, 2541, 3553, 671, 384, 510, 954, 4247, 2670, 2771, 104, 2552, 1029, 4799, 4048, 559, 4702, 956, 4229, 91, 2149, 3302, 2684, 1920, 523, 1831, 1877, 4523, 2958, 2739, 2160, 1828, 2677, 1586, 2180, 3892, 1595, 4260, 4008, 4264, 3943, 260, 1322, 502, 2729, 4002, 1481, 119, 4338, 3146, 109, 1414, 3901, 369, 1938, 2660, 1172, 1938, 2091, 3088, 4504, 2311, 3943, 2109, 4803, 3092, 2853, 411, 2672, 2485, 1833, 757, 554, 4912, 1642, 948, 1975, 2065, 1620, 4827, 4028, 1823, 3776, 2694, 2293, 395, 1612, 4950, 4952, 4982, 2592, 1489, 3656, 3068, 27, 4957, 2073, 1346, 4753, 2286, 3224, 2146, 370, 292, 1182, 1551, 402, 4870, 1063, 1387, 2063, 4629, 1840, 196, 4332, 2496, 1830, 540, 147, 219, 2457, 923, 755, 102, 4733, 3289, 587, 810, 2088, 3113, 493, 934, 1008, 3836, 2827, 4764, 3095, 1329, 2356, 3619, 784, 135, 2980, 1004, 4722, 4568, 4471, 4187, 418, 492, 4838, 3731, 2442, 3410, 2295, 2516, 2269, 3263, 4575, 3195, 3540, 1482, 1021, 3777, 795, 2002, 889, 742, 3831, 1438, 1073, 3934, 4554, 4865, 4144, 3396, 151, 2695, 4436, 268, 4554, 71, 1438, 1712, 4603, 2831, 4261, 4472, 3234, 1275, 2251, 650, 3407, 640, 3140, 1497, 3230, 4831, 1356, 2183, 4958, 930, 2185, 2578, 935, 3865, 4846, 772, 3225, 3672, 2593, 4589, 1976, 4259, 2439, 2921, 1338, 918, 560, 39, 2312, 2105, 972, 4567, 2384, 3560, 2990, 3194, 1741, 70, 700, 181, 2999, 4095, 1642, 2307, 4035, 3351, 4676, 2809, 734, 1191, 366, 1547, 3419, 167, 1214, 846, 1906, 385, 2202, 1586, 3467, 4389, 3776, 913, 4760, 1132, 3334, 3423, 4948, 2638, 1082, 2689, 2262, 4684, 2967, 292, 2070, 1059, 3508, 1061, 2189, 4530, 852, 26, 230, 2667, 1263, 3651, 1058, 65, 1693, 1243, 2844, 164, 2989, 47, 3180, 2770, 3490, 4822, 3884, 306, 4574, 407, 4669, 1784, 1739, 4751, 2073, 2740, 1275, 309, 2310, 2928, 4132, 2214, 1662, 3128, 3402, 1406, 2927, 2638, 1320, 1043, 4526, 3883, 4345, 4257, 4263, 1941, 2991, 178, 2520, 4227, 4068, 4446, 3634, 4106, 709, 1094, 3058, 2650, 3687, 1007, 4837, 3630, 4999, 4642, 2827, 514, 4300, 4267, 4884, 1737, 3614, 4249, 4112, 3486, 3399, 1395, 434, 934, 4978, 834, 337, 4459, 4410, 4627, 4741, 2955, 525, 4883, 745, 2826, 1815, 4838, 3190, 576, 3952, 4733, 1932, 1552, 1315, 4412, 1262, 720, 3781, 333, 2992, 4261, 2539, 3548, 3285, 4621, 3589, 1792, 1567, 4942, 2038, 3497, 817, 4322, 1091, 669, 478, 2614, 3234, 3338, 4085, 4434, 4249, 2693, 4579, 2833, 3803, 2236, 2225, 2300, 2049, 4447, 3511, 164, 4849, 4528, 1869, 3741, 650, 4041, 1411, 2382, 2527, 980, 4243, 2574, 806, 3111, 596, 2960, 1062, 4292, 3821, 844, 2694, 2771, 2098, 2435, 953, 2770, 2318, 2151, 3816, 3643, 1536, 2839, 1855, 1914, 946, 2291, 1254, 996, 4041, 3904, 1800, 3345, 4649, 1061, 4659, 3117, 820, 702, 4122, 3727, 3869, 644, 2258, 2887, 4471, 4674, 930, 1719, 3349, 3833, 932, 2914, 3198, 1554, 3698, 698, 4175, 4580, 3245, 3055, 506, 672, 1129, 4028, 4448, 259, 1064, 251, 322, 1724, 3707, 1008, 1877, 3575, 4494, 1063, 324, 2663, 3856, 905, 2144, 273, 3906, 2790, 35, 3765, 653, 818, 1217, 2378, 478, 4928, 2288, 3180, 4372, 1209, 4738, 4479, 489, 2036, 1747, 1776, 775, 2309, 4608, 3041, 1572, 2923, 1624, 1904, 1878, 1153, 657, 2232, 1928, 2125, 4822, 3504, 2042, 3558, 1349, 2498, 3717, 4525, 878, 4357, 1777, 1400, 3111, 2179, 4243, 2495, 1070, 1284, 2498, 812, 875, 120, 1573, 4038, 4583, 3193, 990, 2522, 3127, 2089, 2588, 1721, 4945, 1615, 3699, 2088, 1677, 1336, 3719, 3240, 2663, 4439, 316, 3843, 211, 3767, 912, 1474, 1076, 3243, 1738, 2191, 2317, 1416, 3401, 3514, 1486, 3791, 3712, 1107, 553, 1749, 2090, 2271, 3948, 2175, 4712, 1112, 3250, 941, 174, 2299, 4849, 1354, 4217, 861, 1801, 3084, 2189, 2196, 3448, 291, 4205, 988, 20, 1797, 4161, 1446, 2347, 1631, 1869, 2225, 3698, 881, 4104, 3866, 1177, 3083, 3243, 3160, 2665, 301, 863, 3440, 2124, 3151, 831, 1182, 1310, 1925, 2635, 2144, 3511, 1623, 3511, 786, 547, 1236, 473, 3844, 4262, 3349, 4740, 914, 4747, 100, 3617, 2622, 2432, 3499, 878, 3988, 1013, 1274, 1138, 4549, 4706, 471, 1226, 3226, 1382, 2749, 2729, 4438, 4536, 2133, 2659, 1375, 4493, 3596, 3082, 389, 1844, 4697, 4435, 4498, 4205, 4008, 3247, 4822, 1925, 3081, 4331, 1949, 521, 165, 666, 1981, 1980, 2183, 4274, 2398, 4060, 4838, 4394, 1179, 1679, 892, 2016, 2755, 4796, 110, 262, 1784, 4096, 4436, 2345, 3308, 3379, 3340, 3521, 2237, 2716, 4266, 4849, 3304, 4198, 4169, 2162, 1477, 4679, 3473, 4447, 2162, 3269, 112, 3120, 2655, 1283, 1330, 2021, 956, 2805, 1420, 3571, 4038, 4978, 1300, 1382, 1498, 3894, 4421, 3644, 4219, 4360, 4149, 3703, 2979, 1164, 1062, 3182, 2467, 1171, 3386, 4093, 413, 1018, 594, 431, 2187, 1125, 3272, 2160, 2524, 852, 4586, 235, 1869, 3164, 1247, 2657, 3220, 987, 3450, 4669, 2302, 2424, 151, 2865, 4729, 467, 4848, 4615, 358, 3704, 96, 2700, 3132, 3339, 3814, 878, 3951, 438, 4946, 304, 510, 1716, 2395, 1228, 205, 771, 159, 1731, 3135, 337, 4796, 837, 2151, 4102, 2255, 1565, 1569, 3787, 1576, 3981, 2628, 977, 4656, 4462, 4611, 2206, 1161, 2176, 1960, 2826, 4590, 4274, 1810, 2464, 401, 4024, 4718, 3173, 594, 998, 173, 3970, 2133, 3136, 676, 2902, 4838, 2490, 2527, 2959, 2199, 1220, 3090, 4171, 4283, 356, 4457, 3367, 4602, 1701, 742, 3512, 1025, 1595, 3822, 2846, 2748, 3979, 55, 3928, 2625, 1847, 878, 1265, 3248, 2972, 1382, 2627, 501, 3660, 4987, 1422, 2924, 1489, 2617, 332, 2473, 1332, 2125, 1856, 162, 3498, 3358, 901, 4243, 1572, 1127, 3609, 101, 388, 562, 2954, 4718, 1740, 1752, 2855, 233, 4226, 703, 2157, 2189, 2702, 1913, 1796, 3212, 2868, 3, 4135, 6, 3131, 4076, 3000, 3267, 4033, 4283, 4413, 1612, 1598, 814, 4767, 3588, 4134, 812, 75, 274, 2758, 4981, 2129, 166, 316, 3207, 4044, 990, 761, 2557, 4785, 2666, 3211, 1450, 2491, 3354, 2307, 4251, 1666, 1891, 2128, 2908, 2424, 932, 3336, 2358, 2619, 4375, 1566, 3974, 1252, 208, 1113, 1375, 775, 2988, 3462, 1933, 1084, 195, 3280, 3403, 1887, 1201, 3470, 340, 408, 4421, 1349, 1462, 214, 4664, 3537, 999, 3935, 2784, 4605, 4685, 4997, 2768, 3118, 4448, 149, 2098, 4658, 502, 848, 1500, 839, 1724, 1693, 726, 4083, 2417, 729, 4957, 4462, 1526, 1563, 1821, 2752, 2644, 2651, 2221, 3398, 4854, 3489, 3867, 1874, 841, 4196, 2898, 406, 686, 3933, 309, 2411, 4309, 2112, 992, 2599, 4529, 162, 4964, 1844, 4043, 3360, 3152, 955, 1017, 3123, 3215, 2094, 3990, 3928, 1791, 4937, 1441, 1575, 3987, 1097, 1609, 2744, 1788, 1043, 2857, 4790, 4576, 3446, 1875, 3908, 632, 4073, 2373, 121, 1119, 3010, 2231, 3096, 107, 1532, 2660, 4567, 1968, 360, 1513, 1163, 1824, 3306, 647, 4026, 2527, 1229, 3744, 2654, 4739, 1102, 2273, 2030, 678, 807, 1883, 1832, 990, 3932, 3028, 4979, 4394, 1268, 1495, 3185, 2222, 4631, 2697, 3274, 830, 793, 3555, 1413, 1492, 3851, 1866, 160, 1876, 643, 751, 3935, 1541, 4925, 2153, 2199, 1537, 3004, 1673, 67, 4282, 1271, 2518, 2838, 4185, 1997, 3521, 1158, 4580, 992, 1333, 1875, 1095, 3117, 2949, 3977, 3454, 2374, 647, 4472, 2984, 4135, 975, 2823, 1647, 1940, 4738, 4994, 1122, 1555, 4691, 2245, 1866, 559, 2654, 2372, 4669, 4605, 2805, 1619, 710, 493, 1276, 4894, 2097, 1095, 2317, 4049, 880, 3946, 4718, 4297, 4675, 772, 1739, 4487, 887, 4400, 4850, 2525, 3973, 4477, 4386, 1976, 1224, 61, 4361, 2142, 1072, 1509, 3363, 4686, 4980, 1119, 2198, 4649, 2176, 2632, 1511, 2741, 963, 4106, 277, 1392, 4883, 1832, 3582, 1666, 4077, 923, 4194, 3347, 2715, 1040, 1536, 4398, 3671, 1171, 3112, 4614, 4127, 3931, 2154, 1013, 2118, 2905, 3381, 2708, 1824, 4663, 2046, 4050, 4469, 2854, 3189, 2219, 311, 1342, 1016, 3268, 3199, 4290, 2054, 4721, 3731, 1863, 3915, 167, 2858, 1282, 2194, 207, 4876, 2158, 2550, 4346, 1561, 484, 4693, 990, 292, 108, 3642, 4805, 3187, 1735, 2153, 1635, 3389, 1996, 2972, 1346, 1840, 1078, 4579, 2380, 3432, 3520, 3753, 337, 2241, 1855, 3131, 1664, 4101, 2494, 226, 4762, 4693, 3234, 4902, 4568, 1028, 4699, 3843, 1625, 2466, 4104, 3594, 3337, 3385, 1291, 4438, 4423, 1992, 1791, 2821, 3753, 655, 3957, 1968, 526, 3353, 2597, 319, 1526, 4431, 4005, 4483, 3931, 2261, 1482, 4166, 3766, 4781, 3837, 2427, 3191, 3570, 4371, 835, 1140, 3825, 4037, 1887, 2322, 4062, 2241, 2146, 4876, 3243, 2612, 2238, 868, 2068, 491, 318, 1766, 2344, 4593, 4782, 1979, 741, 1806, 2487, 1559, 786, 2490, 2426, 1283, 1273, 4533, 425, 1835, 2637, 3558, 3779, 4042, 3441, 1145, 3464, 3016, 3842, 2694, 2186, 3463, 1338, 2665, 4181, 4470, 3116, 237, 2591, 1410, 2789, 2569, 1932, 3113, 1056, 4001, 4245, 3045, 4149, 3832, 1265, 1778, 3439, 2459, 3689, 4343, 3544, 1697, 1851, 2458, 602, 4854, 4615, 393, 2983, 2317, 4002, 4779, 4811, 1011, 3785, 4316, 3773, 1206, 3143, 369, 1279, 125, 1226, 2734, 3250, 1361, 1861, 4843, 165, 2071, 481, 4000, 2951, 386, 2630, 2756, 4787, 1611, 834, 1403, 1885, 4023, 4858, 1855, 3558, 3518, 954, 1082, 4203, 4471, 4000, 1307, 4117, 4659, 133, 3108, 170, 1828, 309, 1306, 4511, 802, 1989, 2885, 963, 2067, 117, 1722, 42, 991, 3567, 92, 3713, 3642, 1615, 1382, 1671, 3405, 1214, 4327, 711, 4431, 4022, 2412, 2662, 3072, 205, 4801, 1627, 471, 3998, 1206, 4986, 2488, 2592, 796, 1106, 2416, 1381, 3482, 4934, 4815, 2591, 4230, 4864, 2147, 1276, 638, 908, 4099, 3389, 3227, 3225, 2523, 4155, 2561, 1119, 3121, 1107, 3292, 4595, 3722, 4094, 2940, 3275, 2145, 2387, 2970, 4838, 1168, 2872, 1692, 3758, 2106, 177, 4222, 4839, 2646, 3693, 82, 4746, 4165, 4527, 4888, 1796, 1303, 4119, 3320, 4121, 201, 2531, 1083, 473, 703, 1460, 3572, 257, 712, 3842, 240, 1675, 582, 3830, 4888, 1474, 4197, 3479, 4115, 832, 211, 1625, 1575, 2064, 3373, 3614, 39, 939, 2082, 1612, 3535, 4061, 1989, 1259, 352, 4924, 1773, 1664, 2298, 4226, 1870, 677, 2944, 199, 617, 73, 1510, 2363, 3986, 1349, 1098, 4238, 1225, 4968, 1385, 3293, 4877, 857, 3858, 2685, 1190, 2704, 2483, 2762, 1741, 1757, 271, 113, 3828, 1752, 2585, 4261, 4636, 1846, 1451, 2239, 588, 3487, 3247, 4210, 2888, 2568, 3132, 2108, 2508, 4085, 4607, 4250, 4782, 508, 4165, 2377, 3984, 4536, 4926, 4243, 1564, 3399, 3245, 1595, 3302, 553, 2894, 1627, 4951, 2918, 1539, 3392, 459, 1744, 2789, 4006, 802, 2676, 3453, 3567, 1894, 194, 547, 2089, 668, 2960, 4436, 4010, 4914, 3710, 545, 4904, 1751, 4096, 4690, 1681, 2229, 1388, 3669, 4937, 3877, 170, 3122, 1497, 4621, 332, 569, 1715, 731, 3518, 4744, 1193, 1675, 1450, 1518, 188, 1583, 3528, 2902, 2026, 4299, 3239, 1907, 4297, 4358, 2379, 942, 4936, 875, 1513, 4606, 4594, 93, 634, 3094, 2415, 3922, 4782, 4773, 3527, 3401, 4575, 162, 4145, 1205, 1575, 858, 4197, 1253, 2795, 3166, 1173, 2042, 1683, 4203, 1182, 1609, 2657, 831, 2754, 2555, 2318, 35, 4454, 4421, 2513, 2723, 42, 3766, 1407, 3735, 1982, 4364, 1406, 399, 4302, 3794, 3583, 1908, 2162, 4748, 1266, 3419, 1798, 295, 1689, 2889, 3434, 1833, 80, 66, 4148, 4218, 1948, 4487, 1659, 2052, 1944, 2412, 370, 4522, 35, 3828, 908, 4486, 3774, 3744, 3881, 1243, 888, 3988, 3764, 2684, 4748, 4339, 4136, 3617, 168, 4414, 1843, 1174, 2252, 605, 1362, 2529, 2093, 2104, 4318, 1346, 729, 4894, 2509, 3770, 4261, 2537, 1867, 2972, 173, 4284, 2787, 3314, 2938, 823, 1428, 3463, 3945, 4054, 451, 3530, 238, 4863, 1582, 3684, 3695, 1506, 3919, 1105, 2821, 4287, 2495, 1547, 4449, 4616, 3082, 1503, 1573, 4914, 418, 2076, 4059, 2331, 3495, 2047, 4484, 1759, 2065, 339, 3559, 2465, 1131, 4314, 1535, 3902, 4616, 4482, 1663, 1647, 4679, 3806, 874, 835, 2890, 4538, 2554, 3027, 364, 1163, 1520, 498, 39, 2191, 1748, 1444, 2270, 1817, 3534, 412, 1087, 3491, 4339, 2273, 3717, 2996, 345, 1417, 735, 3731, 527, 3741, 3739, 2976, 1511, 4757, 3544, 2792, 4910, 1308, 3028, 3101, 3400, 2336, 4293, 3461, 3243, 986, 2340, 2095, 4531, 2157, 1980, 1578, 3018, 1856, 2886, 3884, 3685, 2584, 3556, 4529, 4872, 183, 2467, 12, 2462, 4658, 906, 1944, 4557, 1184, 2759, 2521, 734, 498, 3038, 957, 3763, 540, 2129, 1039, 1534, 717, 1894, 2119, 1155, 4317, 2448, 2516, 4032, 4393, 3331, 3212, 3713, 2840, 4612, 3776, 4309, 4626, 4082, 1501, 3168, 3213, 205, 1476, 4030, 2432, 2507, 4294, 3473, 3289, 3747, 532, 2950, 3881, 4856, 2458, 2646, 3253, 2718, 1973, 4660, 997, 2223, 1591, 597, 3421, 3584, 2946, 3202, 3192, 3133, 2665, 4747, 2637, 400, 635, 920, 3463, 2909, 1739, 1634, 655, 2284, 4281, 1899, 644, 2738, 1264, 1240, 2217, 2145, 1312, 2114, 4407, 3144, 266, 1935, 3758, 2389, 4865, 3650, 3217, 3837, 1074, 2131, 194, 413, 4626, 4091, 445, 1918, 4161, 1990, 2158, 2689, 4431, 3923, 2806, 4595, 3285, 404, 2971, 1440, 3587, 2620, 2623, 1631, 694, 3604, 3311, 2657, 3605, 4308, 118, 1284, 3820, 89, 3984, 3935, 2376, 633, 1113, 3293, 4858, 3798, 2931, 3859, 693, 4920, 4922, 2075, 1852, 4430, 1567, 3905, 4834, 11, 1951, 3168, 1720, 2367, 131, 1560, 2566, 1022, 2145, 3048, 3305, 1857, 323, 1503, 2677, 2065, 2045, 3638, 4019, 1054, 2359, 1416, 2848, 1579, 4857, 1591, 3278, 4818, 323, 1188, 3150, 804, 2056, 778, 1257, 3886, 2213, 4728, 4908, 2362, 4918, 4525, 2759, 4495, 4218, 458, 2174, 1110, 3421, 2766, 4787, 2677, 3059, 4663, 1867, 4965, 4146, 4981, 3292, 281, 847, 4020, 3009, 1770, 3787, 4981, 4269, 3511, 3871, 3720, 4726, 3534, 3008, 1360, 1516, 305, 2292, 1121, 2822, 4712, 3612, 4700, 2425, 3494, 3841, 2117, 3894, 2728, 4274, 3508, 2361, 8, 286, 2528, 4989, 1434, 388, 1427, 259, 319, 2580, 4506, 2501, 2426, 2527, 2780, 2707, 3999, 608, 920, 247, 1756, 1062, 1227, 2812, 72, 2224, 4719, 151, 488, 4136, 1235, 1688, 4479, 3779, 2252, 3751, 2145, 679, 3486, 4584, 2476, 2337, 4906, 3525, 4648, 2630, 4370, 1363, 4070, 2833, 455, 936, 2677, 3350, 56, 1655, 1113, 956, 1679, 2170, 961, 555, 1332, 3495, 3136, 429, 3776, 3972, 1432, 1612, 1925, 4161, 4817, 999, 2842, 3170, 1979, 4662, 2473, 2190, 3551, 892, 4894, 1989, 3243, 841, 2604, 3506, 3874, 3169, 3269, 907, 3965, 3975, 1568, 149, 1983, 512, 1343, 265, 3290, 1276, 2191, 4768, 3049, 1269, 907, 4981, 1179, 2282, 3472, 3199, 4993, 34, 935, 4432, 866, 2624, 3280, 2972, 2373, 2465, 2729, 3030, 4870, 346, 4683, 4684, 2862, 214, 1867, 2367, 3841, 3805, 2590, 1394, 4983, 3653, 3210, 2787, 4258, 226, 2966, 4553, 2810, 2463, 1655, 135, 4135, 496, 4851, 2147, 1371, 656, 4500, 3348, 4658, 1189, 430, 2047, 4550, 946, 4233, 1789, 1023, 1137, 2788, 686, 1425, 4380, 3652, 616, 4357, 1950, 2032, 3237, 3181, 600, 1742, 3142, 1922, 1174, 4722, 995, 708, 2599, 2411, 1271, 2319, 2183, 2934, 2169, 3938, 4112, 1702, 3579, 2048, 2244, 2433, 2083, 1356, 3535, 3887, 4565, 986, 1128, 1769, 885, 3688, 47, 764, 3549, 2944, 419, 3862, 4456, 780, 3155, 820, 113, 2931, 161, 1053, 4023, 839, 4964, 3644, 2282, 2809, 1500, 3956, 39, 1012, 39, 1115, 3989, 4061, 2230, 88, 142, 558, 2636, 1947, 4496, 1353, 4774, 4410, 1308, 4198, 2513, 1307, 319, 2903, 2263, 1228, 2420, 4303, 2409, 4173, 38, 3673, 4514, 1388, 4751, 3979, 2259, 2762, 1436, 1261, 3772, 1977, 3808, 1138, 2524, 29, 163, 4859, 4811, 4014, 811, 3539, 4707, 4343, 4823, 2346, 808, 4856, 4826, 3150, 3367, 2758, 4405, 3445, 4537, 1178, 1399, 653, 850, 879, 4301, 493, 270, 4962, 2027, 3759, 2352, 1685, 1440, 3800, 4155, 2576, 3444, 3497, 4751, 3798, 4768, 3533, 2852, 1074, 4492, 1106, 3830, 2164, 2818, 2355, 3372, 3948, 2124, 4496, 1158, 1356, 2984, 4503, 4760, 378, 3519, 3352, 2034, 3751, 907, 2375, 371, 2888, 4148, 3848, 4634, 2428, 3861, 51, 3850, 1565, 4764, 4032, 3755, 4494, 437, 2320, 1433, 483, 1814, 40, 4420, 1624, 4983, 840, 3421, 2121, 3348, 2138, 3257, 346, 1151, 1293, 4574, 1528, 4791, 4425, 2534, 3838, 1920, 988, 4391, 4614, 2179, 1064, 258, 1641, 295, 1840, 648, 3297, 3246, 365, 2637, 1973, 2299, 2275, 450, 732, 1978, 1917, 4963, 4983, 1142, 4622, 3520, 3775, 709, 1198, 4471, 1623, 4149, 4097, 1951, 4374, 353, 919, 1560, 1151, 2303, 4775, 4631, 3859, 2405, 1743, 1358, 62, 4245, 3164, 855, 1539, 2789, 3891, 1415, 167, 359, 4220, 967, 4400, 4319, 616, 4810, 498, 905, 2228, 1440, 4435, 3932, 445, 2083, 1446, 3374, 1545, 1172, 208, 3211, 3324, 2807, 1148, 2776, 3348, 4362, 4829, 3358, 1170, 3575, 3143, 1021, 425, 3608, 1696, 348, 3289, 4177, 4265, 3649, 1681, 4944, 15, 2954, 1336, 3720, 1235, 4285, 2919, 2079, 1270, 896, 2266, 4140, 1282, 2752, 1746, 3303, 650, 4929, 4309, 4299, 4038, 3849, 3540, 2521, 1894, 1461, 289, 2547, 2387, 3306, 4451, 2927, 1629, 2122, 3308, 1885, 2058, 4899, 2216, 2282, 4456, 1571, 4408, 1936, 1714, 4794, 1090, 3569, 3628, 3718, 2630, 2194, 3432, 2989, 1653, 4948, 1833, 1485, 3063, 2749, 3572, 2932, 3693, 791, 4106, 1547, 1899, 2078, 4004, 997, 1127, 4039, 3612, 1250, 1603, 554, 3259, 2916, 1666, 886, 1501, 2, 4618, 3790, 4967, 226, 4069, 572, 153, 4984, 1645, 2133, 2527, 4056, 820, 3228, 1453, 4967, 1852, 2491, 473, 4737, 3235, 1736, 544, 4440, 4817, 229, 3678, 2664, 2923, 1745, 2594, 4986, 1316, 3746, 1220, 256, 2820, 4255, 2541, 2957, 3494, 3348, 1562, 3588, 3407, 4961, 1942, 2330, 390, 4414, 1050, 1870, 4987, 4089, 4044, 4936, 668, 867, 163, 1388, 224, 1804, 1634, 4886, 2195, 354, 4088, 638, 1201, 3339, 591, 336, 1712, 3150, 373, 2497, 2301, 2790, 3429, 581, 279, 1252, 3013, 892, 4297, 350, 1007, 718, 754, 83, 4910, 2797, 2695, 4482, 1354, 2908, 3269, 4320, 1434, 4843, 2871, 1004, 2937, 716, 4889, 3723, 2711, 2036, 3178, 4883, 1232, 2831, 2713, 1683, 3679, 4171, 163, 4179, 248, 2311, 3073, 4816, 920, 4321, 428, 772, 2173, 3775, 2058, 4258, 1990, 4001, 113, 2382, 275, 4487, 250, 915, 1956, 2633, 1355, 1335, 2000, 4616, 3293, 1868, 2313, 2819, 1472, 3889, 2068, 2934, 3493, 2496, 426, 4566, 1270, 2525, 4575, 79, 1237, 1345, 3934, 3878, 767, 1758, 92, 2779, 1477, 1946, 4517, 2611, 3170, 3664, 2063, 1621, 2547, 4544, 1785, 1067, 2806, 358, 3330, 1879, 1104, 4455, 2749, 2586, 2044, 1468, 1197, 1462, 1804, 4810, 2392, 4072, 4525, 1714, 2456, 2999, 2637, 3402, 2677, 1472, 28, 4215, 901, 4847, 3361, 957, 422, 2909, 3156, 4340, 4808, 1330, 814, 1865, 4992, 71, 1156, 809, 748, 4408, 2089, 3036, 1519, 4454, 927, 3219, 1040, 3893, 1885, 3149, 3264, 4296, 3112, 679, 3044, 3377, 3751, 937, 2884, 2021, 2260, 2404, 2261, 1956, 767, 688, 29, 541, 4799, 1140, 2154, 3141, 3011, 1629, 3420, 3252, 2898, 3964, 295, 813, 2125, 4404, 2848, 4179, 2038, 3387, 2224, 4298, 3329, 2071, 374, 397, 4497, 2453, 4182, 845, 2364, 3961, 3064, 571, 3397, 0, 1519, 1111, 2265, 4056, 4935, 515, 4177, 3122, 621, 1926, 4031, 3481, 3541, 3503, 3745, 3352, 819, 1914, 1735, 2560, 4055, 2457, 4481, 1594, 187, 4112, 3442, 1982, 3553, 2463, 651, 1372, 429, 957, 1888, 3971, 2717, 4187, 1789, 1502, 482, 4344, 3468, 560, 2461, 1089, 545, 2995, 2131, 2926, 2763, 3386, 1313, 3739, 3192, 2447, 2509, 4256, 1826, 749, 66, 3634, 2750, 1486, 552, 2545, 1190, 1186, 4306, 3405, 557, 2027, 334, 4257, 2336, 2131, 1485, 2871, 1998, 2954, 2520, 3123, 1071, 409, 1393, 3007, 2556, 2943, 2859, 1576, 3214, 986, 3061, 1034, 1402, 2827, 2470, 433, 4428, 3208, 2523, 4429, 1608, 2169, 210, 1259, 4269, 1252, 2234, 2302, 453, 2372, 712, 3341, 4843, 4430, 4678, 460, 1200, 1205, 652, 2789, 2561, 2351, 4917, 4411, 2449, 1840, 3768, 1313, 2248, 3771, 2169, 147, 3447, 307, 2202, 779, 4048, 2711, 4845, 1521, 22, 2198, 4842, 3352, 396, 502, 2650, 249, 4859, 229, 1790, 2019, 1465, 3294, 881, 1856, 4847, 3438, 2794, 2262, 3305, 2930, 2377, 4462, 3267, 2471, 1559, 2817, 4006, 544, 2133, 3678, 4468, 2613, 125, 1688, 802, 2138, 4216, 824, 2087, 2294, 4597, 4898, 3428, 4975, 1611, 230, 1969, 1029, 2469, 180, 2087, 1986, 1006, 3634, 1792, 2875, 3237, 4997, 3243, 3228, 1026, 1986, 2391, 851, 2148, 3528, 3380, 430, 3931, 2980, 538, 4861, 2089, 2918, 1275, 521, 3005, 247, 596, 742, 4939, 4792, 1910, 2692, 4939, 3993, 4600, 1359, 3049, 258, 4340, 134, 4356, 1855, 941, 1991, 816, 2048, 2310, 3591, 565, 3768, 843, 4882, 145, 4554, 3390, 730, 4974, 770, 2214, 4250, 1991, 3719, 2010, 3257, 37, 2859, 207, 2098, 2732, 1526, 1955, 4494, 50, 2596, 4023, 4362, 1432, 4662, 908, 4015, 1186, 2205, 850, 4232, 4398, 4301, 4131, 2079, 70, 2394, 36, 4099, 4862, 416, 333, 2110, 4521, 4375, 1575, 4040, 11, 1921, 1870, 2515, 954, 2861, 1949, 4871, 2673, 1955, 60, 1286, 4746, 652, 1039, 1280, 1953, 4870, 4213, 3476, 3236, 2736, 4708, 3641, 4065, 4166, 4631, 2351, 3225, 1176, 1381, 761, 3130, 829, 172, 1383, 2965, 4141, 2499, 2996, 497, 919, 2427, 2863, 3881, 3415, 78, 3621, 2088, 1158, 3266, 1063, 373, 4707, 3063, 3330, 4471, 3490, 4771, 2405, 4767, 4238, 2347, 1562, 1652, 1398, 585, 4340, 2743, 2106, 4104, 4312, 3647, 4381, 3313, 3412, 3094, 4438, 2922, 1021, 460, 2087, 474, 1785, 1524, 2137, 2609, 3273, 4233, 3665, 3929, 1543, 3541, 1571, 4174, 519, 3437, 567, 365, 914, 2454, 2770, 2351, 3449, 3862, 4216, 4239, 4176, 859, 3093, 2349, 1880, 4325, 571, 2705, 69, 3423, 964, 495, 670, 1636, 683, 2069, 3722, 3663, 3406, 2820, 3060, 2089, 4488, 3537, 3797, 545, 1630, 867, 1431, 1738, 1417, 2298, 1045, 2784, 3567, 4523, 3292, 3447, 1405, 3079, 4700, 4765, 3183, 1554, 3964, 3207, 2531, 4635, 1826, 3022, 2615, 1587, 3588, 580, 4300, 2073, 1130, 441, 4808, 3306, 1271, 1984, 3431, 3340, 4609, 3312, 1152, 126, 4432, 929, 4753, 4415, 1069, 4690, 151, 1570, 4687, 3921, 1088, 4495, 2772, 4136, 364, 1785, 993, 53, 3313, 2254, 3461, 1672, 2404, 750, 2329, 2080, 1246, 4389, 496, 4979, 4857, 1775, 1395, 4240, 1461, 548, 4143, 4838, 3895, 905, 3160, 4999, 3143, 3866, 4893, 1162, 3741, 4494, 3379, 3486, 4976, 186, 2319, 498, 1484, 507, 1115, 457, 522, 2798, 2302, 1840, 2680, 645, 3681, 4372, 763, 1329, 4656, 1053, 3541, 1970, 3015, 1769, 1583, 4294, 2256, 954, 4986, 170, 2396, 1159, 2097, 2879, 691, 3792, 2679, 2337, 4008, 4024, 2040, 674, 1576, 2195, 1869, 1305, 2217, 1920, 138, 678, 389, 2212, 3152, 2915, 910, 2080, 3932, 3131, 3463, 4182, 2464, 4623, 1512, 3670, 1576, 629, 2441, 3551, 2706, 1384, 3257, 3610, 450, 2672, 4573, 491, 1551, 2888, 4370, 1851, 3631, 4041, 2654, 547, 2370, 3045, 1859, 3539, 1678, 447, 3445, 1439, 2830, 52, 1538, 1087, 2482, 3930, 2730, 3721, 568, 2780, 1866, 4338, 3893, 3481, 3785, 2259, 3194, 3049, 757, 1410, 1853, 4921, 724, 933, 1741, 3725, 1014, 4558, 89, 2767, 1976, 7, 1106, 2946, 2611, 2427, 1417, 2633, 672, 3009, 3052, 246, 2770, 1555, 2970, 1219, 4624, 4866, 4050, 1156, 714, 1624, 3336, 106, 1880, 3602, 4814, 2410, 443, 2940, 3424, 1866, 800, 1709, 2111, 8, 4567, 2563, 4921, 1971, 1908, 2382, 1711, 156, 3642, 1647, 731, 1162, 670, 3015, 3797, 2287, 2824, 1810, 4874, 3193, 2147, 4534, 986, 3036, 3361, 718, 3988, 2868, 2546, 824, 3978, 461, 2254, 4122, 1912, 975, 2792, 4521, 2417, 2535, 2887, 3957, 4788, 2786, 1153, 4063, 4730, 4928, 710, 2962, 1655, 4930, 3521, 4446, 502, 2153, 3243, 1790, 1428, 612, 3122, 2221, 2197, 3706, 4323, 683, 3727, 1981, 2015, 1909, 2309, 1989, 2804, 4681, 4623, 4195, 793, 554, 2391, 3740, 4788, 1780, 1323, 4580, 3128, 4572, 3814, 3690, 1731, 3313, 4011, 1808, 3393, 4002, 4597, 4360, 3521, 3948, 3414, 2037, 2810, 2827, 414, 1693, 4452, 607, 1941, 1545, 4395, 2801, 361, 4890, 3384, 416, 1513, 4639, 4473, 408, 2792, 973, 2955, 4419, 2791, 3878, 2366, 3294, 4735, 2267, 2037, 3963, 4018, 3158, 2251, 3131, 3504, 2564, 4003, 1679, 4630, 4559, 4176, 4996, 1132, 4537, 3583, 1253, 3959, 2245, 1240, 2784, 1615, 3763, 1503, 2245, 3850, 2035, 4988, 4438, 331, 1098, 2410, 1825, 628, 2288, 4928, 3246, 2323, 2317, 208, 2919, 1601, 535, 4812, 2513, 237, 3210, 1499, 3687, 3860, 1544, 4041, 1117, 2719, 2566, 2396, 3423, 2634, 2852, 1705, 2397, 47, 3799, 4277, 4163, 2372, 1916, 4412, 1156, 1246, 3699, 274, 4598, 1915, 3560, 2542, 4802, 2711, 288, 2135, 2222, 4492, 1912, 418, 1525, 3298, 4993, 1517, 3873, 1551, 1017, 877, 1033, 4471, 1051, 2454, 2534, 3151, 2857, 3097, 1103, 2999, 301, 1686, 1630, 4862, 1205, 4509, 716, 1849, 4338, 2240, 3436, 4917, 3512, 140, 929, 1837, 895, 2651, 1741, 899, 1251, 2871, 2901, 311, 135, 3715, 2427, 3976, 3413, 4922, 681, 1902, 1165, 2705, 3843, 257, 2506, 3428, 2198, 3593, 3198, 3165, 4914, 1244, 4812, 3753, 4839, 1799, 3321, 2504, 4618, 1570, 3208, 4683, 913, 2327, 4528, 4977, 1198, 1293, 882, 3453, 2564, 868, 2377, 2605, 427, 4532, 690, 420, 351, 762, 1550, 1420, 1888, 781, 1387, 86, 4336, 3461, 2029, 646, 2054, 3051, 624, 2102, 3223, 2826, 4280, 4159, 3647, 1045, 4363, 249, 4335, 984, 3938, 1417, 4787, 322, 3957, 3248, 1716, 1511, 4461, 2471, 29, 2761, 2856, 4090, 1525, 4004, 4057, 3538, 532, 1660, 4643, 4727, 1019, 4004, 687, 2561, 508, 3710, 4317, 4252, 4302, 3978, 2162, 964, 4709, 138, 329, 3695, 4640, 4031, 979, 3000, 3530, 1749, 4177, 2045, 4409, 3337, 1626, 2157, 4432, 3492, 3724, 3454, 223, 3050, 763, 561, 3706, 16, 2696, 1942, 923, 2839, 3625, 4465, 826, 2600, 2185, 874, 705, 397, 1547, 1931, 2375, 3224, 3358, 2990, 281, 645, 3657, 2011, 4842, 613, 2969, 1522, 595, 3562, 1649, 4093, 36, 2965, 941, 982, 818, 1946, 4686, 193, 3532, 2196, 1307, 3647, 3659, 2587, 3753, 1905, 3026, 4681, 1064, 1173, 4899, 54, 1089, 4753, 3587, 2032, 4250, 2825, 2782, 4400, 1069, 1266, 2841, 1165, 1574, 4457, 1335, 4009, 3184, 4577, 4475, 1612, 2796, 4026, 3230, 4443, 4228, 4210, 4307, 2594, 3293, 392, 3372, 3962, 2974, 1685, 1525, 3057, 682, 3347, 227, 1317, 650, 662, 2210, 2519, 2920, 1537, 1757, 3865, 1708, 2828, 2206, 4637, 1738, 3913, 2077, 4022, 4002, 2020, 1313, 1330, 3297, 190, 3917, 2569, 1790, 87, 541, 4180, 1084, 3309, 19, 3481, 3867, 4834, 3051, 3926, 1749, 2750, 2389, 1886, 1503, 3984, 3310, 2409, 370, 3936, 2, 4733, 4643, 614, 2558, 2561, 3213, 3240, 19, 3879, 605, 2754, 4734, 1117, 438, 2304, 3501, 1161, 1420, 2764, 1040, 1072, 572, 1442, 4810, 1816, 2683, 4483, 4045, 3914, 2172, 1204, 703, 4033, 1542, 712, 1358, 3385, 2334, 4282, 1084, 3512, 4293, 4376, 4244, 2877, 1599, 4911, 4581, 619, 3648, 2722, 2128, 4923, 865, 2676, 2936, 4262, 2347, 3463, 921, 4151, 2028, 2242, 697, 4879, 2686, 4313, 1591, 1740, 3793, 1932, 1351, 2407, 1705, 3041, 2220, 4904, 422, 4289, 2284, 4027, 1866, 1504, 2850, 718, 799, 186, 322, 1135, 1050, 3627, 2676, 3726, 1378, 4792, 4121, 325, 2088, 270, 4065, 1142, 3611, 4756, 2756, 1919, 601, 1944, 4218, 4731, 2085, 2518, 3104, 4032, 4426, 1614, 615, 274, 4382, 4577, 3982, 3239, 2463, 1345, 348, 1800, 43, 4798, 1503, 2533, 3155, 4915, 131, 4853, 2765, 2811, 1853, 2868, 3054, 2418, 4778, 736, 4262, 812, 2555, 4076, 3617, 4734, 532, 2110, 3532, 2943, 1395, 4100, 76, 4297, 4664, 29, 3270, 4632, 4192, 4640, 3706, 1014, 21, 4050, 3054, 1842, 1054, 570, 4259, 429, 1728, 4847, 596, 1370, 2800, 1058, 3259, 4215, 4230, 63, 2031, 3646, 3146, 1795, 4796, 218, 1452, 4021, 117, 2418, 4389, 1142, 4998, 750, 3101, 2362, 227, 753, 721, 4065, 2148, 3628, 2712, 2374, 4797, 1474, 3976, 3615, 513, 3783, 4926, 1847, 4635, 4495, 2176, 2734, 3619, 4239, 3065, 4135, 1444, 4518, 4709, 4039, 1972, 25, 704, 2535, 3024, 660, 142, 3563, 1197, 4732, 2689, 2861, 1851, 3809, 3385, 4099, 2285, 4892, 2210, 4698, 3616, 1456, 1443, 670, 3010, 1816, 1825, 2089, 1157, 413, 4957, 2539, 4394, 476, 1168, 2746, 763, 1483, 3370, 1478, 1974, 1178, 248, 562, 75, 2981, 178, 1382, 4542, 4427, 2014, 942, 408, 2177, 2005, 4939, 1048, 3729, 4481, 1159, 1380, 4377, 2239, 3447, 2724, 4739, 4201, 2932, 852, 4816, 965, 2719, 2505, 4029, 1572, 257, 4552, 4493, 3920, 2576, 2998, 4811, 1216, 3499, 106, 900, 3830, 4893, 2819, 1273, 4666, 991, 2994, 3400, 649, 4820, 167, 4248, 2546, 4791, 162, 3339, 4028, 321, 2922, 3603, 1778, 3395, 650, 1540, 3721, 4113, 3079, 2478, 291, 3551, 190, 113, 30, 4734, 467, 946, 3566, 2543, 879, 2636, 4392, 2695, 27, 1726, 4444, 3083, 4901, 1105, 1402, 322, 2147, 1886, 1775, 172, 873, 13, 4580, 2017, 3561, 3050, 1334, 4608, 4311, 1994, 236, 4235, 59, 4156, 3831, 933, 3495, 256, 4756, 3021, 757, 290, 970, 2614, 3228, 3925, 3884, 3925, 4312, 816, 2075 ] sort unsortedList |> Quicksort.show From ed3f720dd24c97443932f11f883846733994b9f4 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Sat, 5 Jun 2021 19:01:48 -0400 Subject: [PATCH 25/52] Change some Bool docs --- compiler/builtins/docs/Bool.roc | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/compiler/builtins/docs/Bool.roc b/compiler/builtins/docs/Bool.roc index 5a4e4814df..077909e84d 100644 --- a/compiler/builtins/docs/Bool.roc +++ b/compiler/builtins/docs/Bool.roc @@ -55,12 +55,14 @@ and : Bool, Bool -> Bool ## ## In some languages, `&&` and `||` are special-cased in the compiler to skip ## evaluating the expression after the operator under certain circumstances. -## # In Roc, this is not the case. See the performance notes for #Bool.and for details. +## # In Roc, this is not the case. See the performance notes for [Bool.and] for details. or : Bool, Bool -> Bool ## Exclusive or xor : Bool, Bool -> Bool +# TODO: removed `'` from signature because parser does not support it yet +# Original signature: `isEq : 'val, 'val -> Bool` ## Returns `True` if the two values are *structurally equal*, and `False` otherwise. ## ## `a == b` is shorthand for `Bool.isEq a b` @@ -71,20 +73,18 @@ xor : Bool, Bool -> Bool ## 2. Private tags are equal if they are the same tag, in the same module, and also their contents (if any) are equal. ## 3. Records are equal if all their fields are equal. ## 4. Collections ([Str], [List], [Dict], and [Set]) are equal if they are the same length, and also all their corresponding elements are equal. -## 5. #Num values are equal if their numbers are equal, with one exception: if both arguments to `isEq` are *NaN*, then `isEq` returns `False`. See [Num.isNaN] for more about *NaN*. +## 5. [Num] values are equal if their numbers are equal, with one exception: if both arguments to `isEq` are *NaN*, then `isEq` returns `False`. See [Num.isNaN] for more about *NaN*. ## ## Note that `isEq` takes `'val` instead of `val`, which means `isEq` does not ## accept arguments whose types contain functions. -# TODO: removed `'` from signature because parser does not support it yet -# Original signature: `isEq : 'val, 'val -> Bool` isEq : val, val -> Bool -## Calls #eq on the given values, then calls #not on the result. +# TODO: removed `'` from signature because parser does not support it yet +# Original signature: `isNotEq : 'val, 'val -> Bool` +## Calls [isEq] on the given values, then calls [not] on the result. ## ## `a != b` is shorthand for `Bool.isNotEq a b` ## ## Note that `isNotEq` takes `'val` instead of `val`, which means `isNotEq` does not ## accept arguments whose types contain functions. -# TODO: removed `'` from signature because parser does not support it yet -# Original signature: `isNotEq : 'val, 'val -> Bool` isNotEq : val, val -> Bool From adb9e6e1f864bdccf47fa9df40c7e4a8f4719e09 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Sat, 5 Jun 2021 19:02:22 -0400 Subject: [PATCH 26/52] Add www.roc-lang.org assets --- www/build.sh | 4 + www/netlify.toml | 30 +++ www/public/favicon.svg | 4 + www/public/index.html | 23 ++ www/public/license/index.html | 29 ++ www/public/logo.svg | 9 + www/public/search.js | 38 +++ www/public/styles.css | 479 ++++++++++++++++++++++++++++++++++ 8 files changed, 616 insertions(+) create mode 100755 www/build.sh create mode 100644 www/netlify.toml create mode 100644 www/public/favicon.svg create mode 100644 www/public/index.html create mode 100644 www/public/license/index.html create mode 100644 www/public/logo.svg create mode 100644 www/public/search.js create mode 100644 www/public/styles.css diff --git a/www/build.sh b/www/build.sh new file mode 100755 index 0000000000..ffdae71a9b --- /dev/null +++ b/www/build.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +rm -rf build/ +cp -r public/ build/ diff --git a/www/netlify.toml b/www/netlify.toml new file mode 100644 index 0000000000..0e3070a0f6 --- /dev/null +++ b/www/netlify.toml @@ -0,0 +1,30 @@ +# This is the file that generates and deploys https://www.roc-lang.org, +# which is served on Netlify. +# +# Netlify's docs for how this configuration file works: +# https://docs.netlify.com/routing/headers/#syntax-for-the-netlify-configuration-file +[build] + publish = "build/" + command = "bash build.sh" + +[[headers]] + for = "/*" + [headers.values] + X-Frame-Options = "DENY" + X-XSS-Protection = "1; mode=block" + Content-Security-Policy = "default-src 'self'; img-src *;" + X-Content-Type-Options = "nosniff" + +# Redirect roc-lang.org/authors to the AUTHORS file in this repo +# +# This is referenced in the LICENSE file, which says to see roc-lang.org/authors +# for a list of authors! +[[redirects]] + from = "/authors" + to = "https://github.com/rtfeldman/roc/blob/trunk/AUTHORS" + force = true + status = 302 # TODO once the repo is public, use status = 200 and this URL: + # https://raw.githubusercontent.com/rtfeldman/roc/trunk/AUTHORS + # + # This way, roc-lang.org/authors will show the authors directly, + # proxied from the current AUTHORS file on GitHub, no redirects. diff --git a/www/public/favicon.svg b/www/public/favicon.svg new file mode 100644 index 0000000000..e0cff74b57 --- /dev/null +++ b/www/public/favicon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/www/public/index.html b/www/public/index.html new file mode 100644 index 0000000000..442e9d266f --- /dev/null +++ b/www/public/index.html @@ -0,0 +1,23 @@ + + + + + + + The Roc Programming Language + + + + + + + +

Work in Progress

+

Roc's initial release is still under development, and this website is a placeholder until that release is ready.

+

In the meantime, if you'd like to learn more about Roc, here are some videos:

+ + + diff --git a/www/public/license/index.html b/www/public/license/index.html new file mode 100644 index 0000000000..4eea2d8c39 --- /dev/null +++ b/www/public/license/index.html @@ -0,0 +1,29 @@ + + + + + + Roc's license: The Universal Permissive License (UPL), Version 1.0 + + + + + +
Copyright (c) 2019 Richard Feldman and subsequent Roc authors <https://roc-lang.org/authors>
+
+The Universal Permissive License (UPL), Version 1.0
+
+Subject to the condition set forth below, permission is hereby granted to any person obtaining a copy of this software, associated documentation and/or data (collectively the "Software"), free of charge and under any and all copyright rights in the Software, and any and all patent rights owned or freely licensable by each licensor hereunder covering either (i) the unmodified Software as contributed to or provided by such licensor, or (ii) the Larger Works (as defined below), to deal in both
+
+(a) the Software, and
+
+(b) any piece of software and/or hardware listed in the lrgrwrks.txt file if one is included with the Software (each a “Larger Work” to which the Software is contributed by such licensors),
+
+without restriction, including without limitation the rights to copy, create derivative works of, display, perform, and distribute the Software and make, use, sell, offer for sale, import, export, have made, and have sold the Software and the Larger Work(s), and to sublicense the foregoing rights on either these or other terms.
+
+This license is subject to the following condition:
+
+The above copyright notice and either this complete permission notice or at a minimum a reference to the UPL must be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ diff --git a/www/public/logo.svg b/www/public/logo.svg new file mode 100644 index 0000000000..bb673d5013 --- /dev/null +++ b/www/public/logo.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/www/public/search.js b/www/public/search.js new file mode 100644 index 0000000000..0bc719563b --- /dev/null +++ b/www/public/search.js @@ -0,0 +1,38 @@ +(function() { + let sidebar = document.getElementById("sidebar-nav"); + let searchBox = document.getElementById("module-search"); + + function search() { + let text = searchBox.value.toLowerCase(); // Search is case-insensitive. + + if (text === "") { + // Un-hide everything + sidebar.querySelectorAll(".sidebar-entry a").forEach((entry) => entry.classList.remove("hidden")); + + // Re-hide all the sub-entries except for those of the first module + sidebar.querySelectorAll(".sidebar-entry:not(:first-of-type) .sidebar-sub-entries a").forEach((entry) => entry.classList.add("hidden")); + } else { + // First, show/hide all the sub-entries within each module (top-level functions etc.) + sidebar.querySelectorAll(".sidebar-sub-entries a").forEach((entry) => { + if (entry.textContent.toLowerCase().includes(text)) { + entry.classList.remove("hidden"); + } else { + entry.classList.add("hidden"); + } + }); + + // Then, show/hide modules based on whether they match, or any of their sub-entries matched + sidebar.querySelectorAll(".sidebar-module-link").forEach((entry) => { + if (entry.textContent.toLowerCase().includes(text) || entry.parentNode.querySelectorAll(".sidebar-sub-entries a:not(.hidden)").length > 0) { + entry.classList.remove("hidden"); + } else { + entry.classList.add("hidden"); + } + }); + } + } + + searchBox.addEventListener("input", search); + + search(); +})(); diff --git a/www/public/styles.css b/www/public/styles.css new file mode 100644 index 0000000000..27f88aacd1 --- /dev/null +++ b/www/public/styles.css @@ -0,0 +1,479 @@ +:root { + --link-color: #612bde; + --code-link-color: #5721d4; + --text-color: #333333; + --code-color: #222222; + --code-bg-color: #eeeeee; + --body-bg-color: #fdfdfd; + --border-color: #e9e9e9; + --faded-color: #4c4c4c; + --monospace-font; + --font-sans: -apple-system, BlinkMacSystemFont, Roboto, Helvetica, Arial, sans-serif; + --font-mono: SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace; + --top-header-height: 67px; + --sidebar-width: 280px; + --top-bar-bg: #8257e5; + --top-bar-fg: #ffffff; + --nav-link-hover-color: #000000; +} + +a { + color: #972395; +} + +.logo { + padding: 2px 8px; +} + +.logo svg { + height: 48px; + width: 48px; + fill: var(--top-bar-fg); +} + +.logo:hover { + text-decoration: none; +} + +.logo svg:hover { + fill: var(--nav-link-hover-color); +} + +.pkg-full-name { + color: var(--text-color); + display: flex; + align-items: center; + font-size: 32px; + margin: 0 8px; + font-weight: normal; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + height: 100%; +} + +.pkg-full-name a { + padding-top: 12px; + padding-bottom: 16px; +} + +a { + text-decoration: none; +} + +a:hover { + text-decoration: underline; +} + +.pkg-and-logo { + min-width: 0; /* necessary for text-overflow: ellipsis to work in descendants */ + display: flex; + align-items: center; + height: 100%; + background-color: var(--top-bar-bg); +} + +.pkg-and-logo a, .pkg-and-logo a:visited { + color: var(--top-bar-fg); +} + +.pkg-and-logo a:hover { + color: var(--nav-link-hover-color); + text-decoration: none; +} + +.main-container { + min-width: 0; /* necessary for text-overflow: ellipsis to work in descendants */ +} + +.search-button { + flex-shrink: 0; /* always shrink the package name before these; they have a relatively constrained length */ + padding: 12px 18px; + margin-right: 42px; + display: none; /* only show this in the mobile view */ +} + +.version { + padding: 18px 10px; + min-width: 48px; + margin-right: 8px; +} + +body { + display: grid; + grid-template-columns: [before-sidebar] 1fr [sidebar] var(--sidebar-width) [main-content] fit-content(calc(1280px - var(--sidebar-width))) [end] 1fr; + grid-template-rows: [top-header] var(--top-header-height) [above-footer] auto [footer] auto; + box-sizing: border-box; + margin: 0; + padding: 0; + font-family: var(--font-sans); + color: var(--text-color); + background-color: var(--body-bg-color); +} + +main { + grid-column-start: main-content; + grid-column-end: main-content; + grid-row-start: above-footer; + grid-row-end: above-footer; + box-sizing: border-box; + position: relative; + font-size: 18px; + line-height: 1.85em; + margin-top: 2px; + padding: 48px; +} + +#sidebar-nav { + grid-column-start: sidebar; + grid-column-end: sidebar; + grid-row-start: above-footer; + grid-row-end: above-footer; + position: relative; + display: flex; + flex-direction: column; + box-sizing: border-box; + padding-left: 56px; + padding-top: 6px; + width: 100%; +} + +.top-header-extension { + grid-column-start: before-sidebar; + grid-column-end: sidebar; + grid-row-start: top-header; + grid-row-end: top-header; + background-color: var(--top-bar-bg); +} + +.top-header { + grid-column-start: sidebar; + grid-column-end: end; + grid-row-start: top-header; + grid-row-end: top-header; + display: flex; + flex-direction: row; + align-items: center; + flex-wrap: nowrap; + flex-grow: 1; + box-sizing: border-box; + font-family: var(--font-sans); + font-size: 24px; + height: 100%; + min-width: 0; /* necessary for text-overflow: ellipsis to work in descendants */ +} + +.top-header-triangle { + /* This used to be a clip-path, but Firefox on Android (at least as of early 2020) + * rendered the page extremely slowly in that version. With this approach it's super fast. + */ + width: 0; + height: 0; + border-style: solid; + border-width: var(--top-header-height) 0 0 48px; + border-color: transparent transparent transparent var(--top-bar-bg); +} + +p { + overflow-wrap: break-word; + margin: 24px 0; +} + +footer { + grid-column-start: main-content; + grid-column-end: main-content; + grid-row-start: footer; + grid-row-end: footer; + max-width: var(--main-content-max-width); + font-size: 14px; + box-sizing: border-box; + padding: 16px; +} + +footer p { + display: inline-block; + margin-top: 0; + margin-bottom: 8px; +} + +.content { + box-sizing: border-box; + display: flex; + flex-direction: row; + justify-content: space-between; +} + +.sidebar-entry ul { + list-style-type: none; + margin: 0; +} + +.sidebar-entry a { + box-sizing: border-box; + min-height: 48px; + min-width: 48px; + padding: 12px 16px; + font-family: var(--font-mono); +} + +.sidebar-sub-entries a { + display: block; + line-height: 24px; + width: 100%; + overflow: hidden; + text-overflow: ellipsis; + padding-left: 36px; +} + +.module-name { + font-size: 56px; + line-height: 1em; + font-family: var(--font-mono); + font-weight: bold; + margin-top: 18px; + margin-bottom: 48px; +} + +.module-name a, .module-name a:visited { + color: inherit; +} + +.sidebar-module-link { + box-sizing: border-box; + font-size: 18px; + line-height: 24px; + font-family: var(--font-mono); + font-weight: bold; + display: block; + width: 100%; + padding: 8px 0; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +a, a:visited { + color: var(--link-color); +} + +h3 { + font-size: 32px; + margin: 48px 0 24px 0; +} + +h4 { + font-size: 24px; +} + +.type-def { + font-size: 24px; + color: var(--link-color); +} + +.code-snippet { + padding: 12px 16px; + display: block; + box-sizing: border-box; + font-family: var(--font-mono); + background-color: var(--code-bg-color); +} + +code { + font-family: var(--font-mono); + color: var(--code-color); + background-color: var(--code-bg-color); + padding: 2px 8px; + display: inline-block; +} + +code a { + color: var(--code-link-color); +} + +code a:visited { + color: var(--code-link-color); +} + +pre { + margin: 36px 0; + padding: 8px; + box-sizing: border-box; + background-color: var(--code-bg-color); + overflow-x: auto; +} + +pre code { + padding: 6px 8px; +} + +.hidden { + /* Use !important to win all specificity fights. */ + display: none !important; +} + +#module-search:placeholder-shown { + padding: 0; + opacity: 0; + height: 0; +} + +#module-search, #module-search:focus { + opacity: 1; + padding: 12px 16px; + height: 48px; +} + +/* Show the "Search" label link when the text input has a placeholder */ +#module-search:placeholder-shown + #search-link { + display: flex; +} + +/* Hide the "Search" label link when the text input has focus */ +#module-search:focus + #search-link { + display: none; +} + +#module-search { + display: block; + box-sizing: border-box; + background-color: var(--code-bg-color); + width: 100%; + box-sizing: border-box; + font-size: 18px; + line-height: 18px; + margin-top: 6px; + border: none; + color: var(--faded-color); + background-color: var(--code-bg-color); + font-family: var(--font-serif); +} + +#module-search::placeholder { + color: var(--faded-color); + opacity: 1; +} + +#search-link { + box-sizing: border-box; + display: none; + align-items: center; + font-size: 18px; + line-height: 18px; + padding: 12px 16px; + height: 48px; + cursor: pointer; + color: var(--link-color); +} + +#search-link:hover { + text-decoration: underline; +} + +@media (prefers-color-scheme: dark) { + :root { + --body-bg-color: #303030; + --code-bg-color: #393939; + --border-color: #555555; + --code-color: #eeeeee; + --text-color: #cccccc; + --logo-solid: #777777; + --faded-color: #bbbbbb; + --link-color: #c5a8ff; + --code-link-color: #b894ff; + --top-bar-bg: #6845b9; + --top-bar-fg: #eeeeee; + } + + html { + scrollbar-color: #444444 #2f2f2f; + } +} + +@media only screen and (max-device-width: 480px) { + .search-button { + display: block; /* This is only visible in mobile. */ + } + + .top-header { + width: auto; + } + + .pkg-full-name { + margin-left: 8px; + margin-right: 12px; + font-size: 24px; + padding-bottom: 14px; + } + + .pkg-full-name a { + vertical-align: middle; + padding: 18px 0; + } + + .logo { + padding-left: 2px; + width: 50px; + height: 54px; + } + + .version { + margin: 0; + font-weight: normal; + font-size: 18px; + padding-bottom: 16px; + } + + .module-name { + font-size: 36px; + margin-top: 8px; + margin-bottom: 8px; + max-width: calc(100% - 18px); + overflow: hidden; + text-overflow: ellipsis; + } + + main { + padding: 18px; + font-size: 16px; + } + + .container { + margin: 0; + min-width: 320px; + max-width: 100%; + } + + .content { + flex-direction: column; + } + + .sidebar { + margin-top: 0; + padding-left: 0; + width: auto; + } + + #sidebar-heading { + font-size: 24px; + margin: 16px; + } + + h3 { + font-size: 18px; + margin: 0; + padding: 0; + } + + h4 { + font-size: 16px; + } + + .top-header { + justify-content: space-between; + } + + .content { + /* Display the sidebar below
without affecting tab index */ + flex-direction: column-reverse; + } +} From 855818014c952e057f4372dfa2c67856b2df9040 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Sat, 5 Jun 2021 19:02:06 -0400 Subject: [PATCH 27/52] Add www github workflow --- .github/workflows/ci.yml | 1 - .github/workflows/nightly.yml | 2 +- .github/workflows/www.yml | 22 ++++++++++++++++++++++ 3 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/www.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 413c22db1b..5fd1f8f542 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,4 +22,3 @@ jobs: - name: install dependencies, build, run zig tests, rustfmt, clippy, cargo test --release run: ./ci/safe-earthly.sh +test-all - diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 934baf2e8f..9f3791e4ee 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -1,4 +1,4 @@ -on: +on: schedule: - cron: '0 0 * * *' diff --git a/.github/workflows/www.yml b/.github/workflows/www.yml new file mode 100644 index 0000000000..308cc4dd0e --- /dev/null +++ b/.github/workflows/www.yml @@ -0,0 +1,22 @@ +name: deploy www.roc-lang.org + +# Whenever a commit lands on trunk, deploy the site +on: + push: + branches: + - deploy-www # TODO change to trunk + +jobs: + deploy: + name: 'Deploy to Netlify' + runs-on: [self-hosted] + steps: + - uses: jsmrcaga/action-netlify-deploy@v1.6.0 + with: + install_command: 'pwd; cd ../../www' + build_command: 'bash build.sh' + build_directory: 'build' + NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }} + NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }} + NETLIFY_DEPLOY_MESSAGE: "Deploy git ref ${{ github.ref }}" + NETLIFY_DEPLOY_TO_PROD: true From f1f7c0bdf62e2ea0eb3758800ae77a864031bd37 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Sat, 5 Jun 2021 19:24:53 -0400 Subject: [PATCH 28/52] Revert "Add www github workflow" This reverts commit 855818014c952e057f4372dfa2c67856b2df9040. --- .github/workflows/ci.yml | 1 + .github/workflows/nightly.yml | 2 +- .github/workflows/www.yml | 22 ---------------------- 3 files changed, 2 insertions(+), 23 deletions(-) delete mode 100644 .github/workflows/www.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5fd1f8f542..413c22db1b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,3 +22,4 @@ jobs: - name: install dependencies, build, run zig tests, rustfmt, clippy, cargo test --release run: ./ci/safe-earthly.sh +test-all + diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 9f3791e4ee..934baf2e8f 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -1,4 +1,4 @@ -on: +on: schedule: - cron: '0 0 * * *' diff --git a/.github/workflows/www.yml b/.github/workflows/www.yml deleted file mode 100644 index 308cc4dd0e..0000000000 --- a/.github/workflows/www.yml +++ /dev/null @@ -1,22 +0,0 @@ -name: deploy www.roc-lang.org - -# Whenever a commit lands on trunk, deploy the site -on: - push: - branches: - - deploy-www # TODO change to trunk - -jobs: - deploy: - name: 'Deploy to Netlify' - runs-on: [self-hosted] - steps: - - uses: jsmrcaga/action-netlify-deploy@v1.6.0 - with: - install_command: 'pwd; cd ../../www' - build_command: 'bash build.sh' - build_directory: 'build' - NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }} - NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }} - NETLIFY_DEPLOY_MESSAGE: "Deploy git ref ${{ github.ref }}" - NETLIFY_DEPLOY_TO_PROD: true From 15a240220880a09cbc0c8eeb31a7b1476ec38d08 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Sat, 5 Jun 2021 19:37:50 -0400 Subject: [PATCH 29/52] Add .gitignore --- www/.gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 www/.gitignore diff --git a/www/.gitignore b/www/.gitignore new file mode 100644 index 0000000000..378eac25d3 --- /dev/null +++ b/www/.gitignore @@ -0,0 +1 @@ +build From cb7ee34f21ebc7274bc9d67da8f3d289a64d454c Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Sat, 5 Jun 2021 19:38:07 -0400 Subject: [PATCH 30/52] Generate builtins when buiding www site --- www/build.sh | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/www/build.sh b/www/build.sh index ffdae71a9b..ffe80908a6 100755 --- a/www/build.sh +++ b/www/build.sh @@ -1,4 +1,12 @@ #!/bin/bash +set -euxo pipefail + rm -rf build/ cp -r public/ build/ + +pushd .. +echo 'Generating docs...' +cargo run docs compiler/builtins/docs/Bool.roc +mv generated-docs/ www/build/builtins +popd From 0b00afdd510111d1ef5c7f06df8b1a206fb5bc49 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Sat, 5 Jun 2021 22:05:45 -0400 Subject: [PATCH 31/52] Revert "Revert "Add www github workflow"" This reverts commit f1f7c0bdf62e2ea0eb3758800ae77a864031bd37. --- .github/workflows/ci.yml | 1 - .github/workflows/nightly.yml | 2 +- .github/workflows/www.yml | 22 ++++++++++++++++++++++ 3 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/www.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 413c22db1b..5fd1f8f542 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,4 +22,3 @@ jobs: - name: install dependencies, build, run zig tests, rustfmt, clippy, cargo test --release run: ./ci/safe-earthly.sh +test-all - diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 934baf2e8f..9f3791e4ee 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -1,4 +1,4 @@ -on: +on: schedule: - cron: '0 0 * * *' diff --git a/.github/workflows/www.yml b/.github/workflows/www.yml new file mode 100644 index 0000000000..308cc4dd0e --- /dev/null +++ b/.github/workflows/www.yml @@ -0,0 +1,22 @@ +name: deploy www.roc-lang.org + +# Whenever a commit lands on trunk, deploy the site +on: + push: + branches: + - deploy-www # TODO change to trunk + +jobs: + deploy: + name: 'Deploy to Netlify' + runs-on: [self-hosted] + steps: + - uses: jsmrcaga/action-netlify-deploy@v1.6.0 + with: + install_command: 'pwd; cd ../../www' + build_command: 'bash build.sh' + build_directory: 'build' + NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }} + NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }} + NETLIFY_DEPLOY_MESSAGE: "Deploy git ref ${{ github.ref }}" + NETLIFY_DEPLOY_TO_PROD: true From e09696113c5a768d8c15902a73077d713eecfd8e Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Sat, 5 Jun 2021 22:20:32 -0400 Subject: [PATCH 32/52] Allow running bash www/build.sh --- www/build.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/www/build.sh b/www/build.sh index ffe80908a6..bc1a7c0a35 100755 --- a/www/build.sh +++ b/www/build.sh @@ -2,6 +2,12 @@ set -euxo pipefail +# cd into the directory where this script lives. +# This allows us to run this script from the root project directory, +# which is what Netlify wants to do. +SCRIPT_RELATIVE_DIR=$(dirname "${BASH_SOURCE[0]}") +cd $SCRIPT_RELATIVE_DIR + rm -rf build/ cp -r public/ build/ From e9007f97029b9d7e36cded6b882fa9fdecff63cf Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Sat, 5 Jun 2021 22:21:08 -0400 Subject: [PATCH 33/52] Run the www workflow on push to www --- .github/workflows/www.yml | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/.github/workflows/www.yml b/.github/workflows/www.yml index 308cc4dd0e..4628b00459 100644 --- a/.github/workflows/www.yml +++ b/.github/workflows/www.yml @@ -4,19 +4,11 @@ name: deploy www.roc-lang.org on: push: branches: - - deploy-www # TODO change to trunk - + - www jobs: - deploy: + build: name: 'Deploy to Netlify' runs-on: [self-hosted] steps: - - uses: jsmrcaga/action-netlify-deploy@v1.6.0 - with: - install_command: 'pwd; cd ../../www' - build_command: 'bash build.sh' - build_directory: 'build' - NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }} - NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }} - NETLIFY_DEPLOY_MESSAGE: "Deploy git ref ${{ github.ref }}" - NETLIFY_DEPLOY_TO_PROD: true + - name: curl request to netlify build hook + run: curl -X POST -d {} https://api.netlify.com/build_hooks/${{ secrets.NETLIFY_BUILD_HOOK }} From 84699d4f2fb2186fdc887f546d78da838c93ba3f Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Sat, 5 Jun 2021 22:21:15 -0400 Subject: [PATCH 34/52] Revert "Run the www workflow on push to www" This reverts commit e9007f97029b9d7e36cded6b882fa9fdecff63cf. --- .github/workflows/www.yml | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/.github/workflows/www.yml b/.github/workflows/www.yml index 4628b00459..308cc4dd0e 100644 --- a/.github/workflows/www.yml +++ b/.github/workflows/www.yml @@ -4,11 +4,19 @@ name: deploy www.roc-lang.org on: push: branches: - - www + - deploy-www # TODO change to trunk + jobs: - build: + deploy: name: 'Deploy to Netlify' runs-on: [self-hosted] steps: - - name: curl request to netlify build hook - run: curl -X POST -d {} https://api.netlify.com/build_hooks/${{ secrets.NETLIFY_BUILD_HOOK }} + - uses: jsmrcaga/action-netlify-deploy@v1.6.0 + with: + install_command: 'pwd; cd ../../www' + build_command: 'bash build.sh' + build_directory: 'build' + NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }} + NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }} + NETLIFY_DEPLOY_MESSAGE: "Deploy git ref ${{ github.ref }}" + NETLIFY_DEPLOY_TO_PROD: true From 0e5619c42285e3032c9b718444824fdecd6c0325 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Sat, 5 Jun 2021 22:31:37 -0400 Subject: [PATCH 35/52] Skip zig build on Netlify --- compiler/builtins/build.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/compiler/builtins/build.rs b/compiler/builtins/build.rs index c621196cb9..e0d493457b 100644 --- a/compiler/builtins/build.rs +++ b/compiler/builtins/build.rs @@ -8,6 +8,13 @@ use std::process::Command; use std::str; fn main() { + // When we build on Netlify, zig is not installed (but also not used, + // since all we're doing is generating docs), so we can skip the steps + // that require having zig installed. + if env::var_os("NO_ZIG_INSTALLED").is_some() { + return; + } + let out_dir = env::var_os("OUT_DIR").unwrap(); let big_sur_path = "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/lib"; From b05342c67872e92e747f37ecbfbc0d9184682ffb Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Sun, 6 Jun 2021 00:17:42 -0400 Subject: [PATCH 36/52] Split out an optional "llvm" feature Also move OptLevel out of roc_gen (which should really be called gen_llvm) and into roc_mono, so it's no longer coupled to LLVM. --- Cargo.toml | 6 +++ cli/Cargo.toml | 14 ++++--- cli/src/build.rs | 3 +- cli/src/lib.rs | 6 ++- cli/src/main.rs | 10 ++++- cli/src/repl.rs | 20 ++++++++-- cli/src/repl/gen.rs | 2 +- compiler/build/Cargo.toml | 8 +++- compiler/build/src/link.rs | 32 +++++++++++---- compiler/build/src/program.rs | 32 +++++++++------ compiler/build/src/target.rs | 57 +++++++++++++++++---------- compiler/gen/src/llvm/build.rs | 18 +-------- compiler/mono/src/ir.rs | 6 +++ compiler/test_gen/src/helpers/eval.rs | 5 ++- 14 files changed, 143 insertions(+), 76 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index b5535db0d9..84016c05b1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,6 +32,12 @@ members = [ "roc_std", "docs" ] +# Needed to be able to run `cargo run -p roc_cli --no-default-features` - +# see www/build.sh for more. +# +# Without the `-p` flag, cargo ignores `--no-default-features` when you have a +# workspace, and without `resolver = "2"` here, you can't use `-p` like this. +resolver = "2" # Optimizations based on https://deterministic.space/high-performance-rust.html [profile.release] diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 7aa61cb768..177f9783cf 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -15,7 +15,11 @@ test = false bench = false [features] -default = ["target-x86"] +default = ["target-x86", "llvm"] + +# This is a separate feature because when we generate docs on Netlify, +# it doesn't have LLVM installed. (Also, it doesn't need to do code gen.) +llvm = ["inkwell", "roc_gen", "roc_build/llvm"] target-x86 = [] @@ -45,8 +49,8 @@ roc_unify = { path = "../compiler/unify" } roc_solve = { path = "../compiler/solve" } roc_mono = { path = "../compiler/mono" } roc_load = { path = "../compiler/load" } -roc_gen = { path = "../compiler/gen" } -roc_build = { path = "../compiler/build" } +roc_gen = { path = "../compiler/gen", optional = true } +roc_build = { path = "../compiler/build", default-features = false } roc_fmt = { path = "../compiler/fmt" } roc_reporting = { path = "../compiler/reporting" } roc_editor = { path = "../editor" } @@ -62,7 +66,7 @@ inlinable_string = "0.1" libc = "0.2" libloading = "0.6" -inkwell = { path = "../vendor/inkwell" } +inkwell = { path = "../vendor/inkwell", optional = true } target-lexicon = "0.10" tempfile = "3.1.0" @@ -74,7 +78,7 @@ quickcheck = "0.8" quickcheck_macros = "0.8" serial_test = "0.5" tempfile = "3.1.0" -criterion = { git = "https://github.com/Anton-4/criterion.rs"} +criterion = { git = "https://github.com/Anton-4/criterion.rs"} cli_utils = { path = "cli_utils" } # Keep the commented deps, they are commented because they require nightly rust # criterion-perf-events = "0.1.3" diff --git a/cli/src/build.rs b/cli/src/build.rs index e6f753ec11..a1f3add2bc 100644 --- a/cli/src/build.rs +++ b/cli/src/build.rs @@ -5,8 +5,8 @@ use roc_build::{ }; use roc_can::builtins::builtin_defs_map; use roc_collections::all::MutMap; -use roc_gen::llvm::build::OptLevel; use roc_load::file::LoadingProblem; +use roc_mono::ir::OptLevel; use std::path::PathBuf; use std::time::{Duration, SystemTime}; use target_lexicon::Triple; @@ -32,6 +32,7 @@ pub struct BuiltFile { pub total_time: Duration, } +#[cfg(feature = "llvm")] pub fn build_file<'a>( arena: &'a Bump, target: &Triple, diff --git a/cli/src/lib.rs b/cli/src/lib.rs index 91948044c2..664c56908e 100644 --- a/cli/src/lib.rs +++ b/cli/src/lib.rs @@ -1,12 +1,12 @@ #[macro_use] extern crate clap; -use build::{build_file, BuildOutcome, BuiltFile}; +use build::{BuildOutcome, BuiltFile}; use bumpalo::Bump; use clap::{App, AppSettings, Arg, ArgMatches}; use roc_build::link::LinkType; -use roc_gen::llvm::build::OptLevel; use roc_load::file::LoadingProblem; +use roc_mono::ir::OptLevel; use std::env; use std::io; use std::path::{Path, PathBuf}; @@ -116,7 +116,9 @@ pub enum BuildConfig { BuildAndRun { roc_file_arg_index: usize }, } +#[cfg(feature = "llvm")] pub fn build(target: &Triple, matches: &ArgMatches, config: BuildConfig) -> io::Result { + use build::build_file; use BuildConfig::*; let arena = Bump::new(); diff --git a/cli/src/main.rs b/cli/src/main.rs index 191e8409b0..bd38a5e56a 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -1,11 +1,19 @@ use roc_cli::{ - build, build_app, docs, repl, BuildConfig, CMD_BUILD, CMD_DOCS, CMD_EDIT, CMD_REPL, CMD_RUN, + build_app, docs, repl, BuildConfig, CMD_BUILD, CMD_DOCS, CMD_EDIT, CMD_REPL, CMD_RUN, DIRECTORY_OR_FILES, ROC_FILE, }; use std::io; use std::path::{Path, PathBuf}; use target_lexicon::Triple; +#[cfg(feature = "llvm")] +use roc_cli::build; + +#[cfg(not(feature = "llvm"))] +fn build(_target: &Triple, _matches: &clap::ArgMatches, _config: BuildConfig) -> io::Result { + panic!("Building without LLVM is not currently supported."); +} + fn main() -> io::Result<()> { let matches = build_app().get_matches(); diff --git a/cli/src/repl.rs b/cli/src/repl.rs index c0d7e03917..4de48bb3df 100644 --- a/cli/src/repl.rs +++ b/cli/src/repl.rs @@ -1,15 +1,12 @@ use const_format::concatcp; +#[cfg(feature = "llvm")] use gen::{gen_and_eval, ReplOutput}; -use roc_gen::llvm::build::OptLevel; use roc_parse::parser::{EExpr, SyntaxError}; -use rustyline::error::ReadlineError; use rustyline::highlight::{Highlighter, PromptInfo}; use rustyline::validate::{self, ValidationContext, ValidationResult, Validator}; -use rustyline::Editor; use rustyline_derive::{Completer, Helper, Hinter}; use std::borrow::Cow; use std::io; -use target_lexicon::Triple; const BLUE: &str = "\u{001b}[36m"; const PINK: &str = "\u{001b}[35m"; @@ -30,7 +27,9 @@ pub const INSTRUCTIONS: &str = "Enter an expression, or :help, or :exit/:q.\n"; pub const PROMPT: &str = concatcp!("\n", BLUE, "»", END_COL, " "); pub const CONT_PROMPT: &str = concatcp!(BLUE, "…", END_COL, " "); +#[cfg(feature = "llvm")] mod eval; +#[cfg(feature = "llvm")] mod gen; #[derive(Completer, Helper, Hinter)] @@ -107,7 +106,16 @@ impl Validator for InputValidator { } } +#[cfg(not(feature = "llvm"))] pub fn main() -> io::Result<()> { + panic!("The REPL currently requires being built with LLVM."); +} + +#[cfg(feature = "llvm")] +pub fn main() -> io::Result<()> { + use rustyline::error::ReadlineError; + use rustyline::Editor; + // To debug rustyline: // env_logger::init(); // RUST_LOG=rustyline=debug cargo run repl 2> debug.log @@ -226,7 +234,11 @@ fn report_parse_error(fail: SyntaxError) { println!("TODO Gracefully report parse error in repl: {:?}", fail); } +#[cfg(feature = "llvm")] fn eval_and_format<'a>(src: &str) -> Result> { + use roc_mono::ir::OptLevel; + use target_lexicon::Triple; + gen_and_eval(src.as_bytes(), Triple::host(), OptLevel::Normal).map(|output| match output { ReplOutput::NoProblems { expr, expr_type } => { format!("\n{} {}:{} {}", expr, PINK, END_COL, expr_type) diff --git a/cli/src/repl/gen.rs b/cli/src/repl/gen.rs index 49d47e54a3..b9bb9a2799 100644 --- a/cli/src/repl/gen.rs +++ b/cli/src/repl/gen.rs @@ -8,9 +8,9 @@ use roc_can::builtins::builtin_defs_map; use roc_collections::all::{MutMap, MutSet}; use roc_fmt::annotation::Formattable; use roc_fmt::annotation::{Newlines, Parens}; -use roc_gen::llvm::build::OptLevel; use roc_gen::llvm::externs::add_default_roc_externs; use roc_load::file::LoadingProblem; +use roc_mono::ir::OptLevel; use roc_parse::parser::SyntaxError; use roc_types::pretty_print::{content_to_string, name_all_type_vars}; use std::path::{Path, PathBuf}; diff --git a/compiler/build/Cargo.toml b/compiler/build/Cargo.toml index aa3a13f3d8..11a5e9effb 100644 --- a/compiler/build/Cargo.toml +++ b/compiler/build/Cargo.toml @@ -19,7 +19,7 @@ roc_unify = { path = "../unify" } roc_solve = { path = "../solve" } roc_mono = { path = "../mono" } roc_load = { path = "../load" } -roc_gen = { path = "../gen" } +roc_gen = { path = "../gen", optional = true } roc_reporting = { path = "../reporting" } im = "14" # im and im-rc should always have the same version! im-rc = "14" # im and im-rc should always have the same version! @@ -28,7 +28,7 @@ inlinable_string = "0.1.0" libloading = "0.6" tempfile = "3.1.0" serde_json = "1.0" -inkwell = { path = "../../vendor/inkwell" } +inkwell = { path = "../../vendor/inkwell", optional = true } target-lexicon = "0.10" [dev-dependencies] @@ -39,6 +39,10 @@ quickcheck = "0.8" quickcheck_macros = "0.8" [features] +default = ["llvm"] target-arm = [] target-aarch64 = [] target-webassembly = [] +# This is a separate feature because when we generate docs on Netlify, +# it doesn't have LLVM installed. (Also, it doesn't need to do code gen.) +llvm = ["inkwell", "roc_gen"] diff --git a/compiler/build/src/link.rs b/compiler/build/src/link.rs index c535f86e57..61068d11b8 100644 --- a/compiler/build/src/link.rs +++ b/compiler/build/src/link.rs @@ -1,16 +1,14 @@ -use crate::target; use crate::target::arch_str; -use inkwell::module::Module; -use inkwell::targets::{CodeModel, FileType, RelocMode}; +#[cfg(feature = "llvm")] use libloading::{Error, Library}; -use roc_gen::llvm::build::OptLevel; +#[cfg(feature = "llvm")] +use roc_mono::ir::OptLevel; use std::collections::HashMap; use std::env; use std::io; use std::path::{Path, PathBuf}; use std::process::{Child, Command, Output}; use target_lexicon::{Architecture, OperatingSystem, Triple}; -use tempfile::tempdir; #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub enum LinkType { @@ -360,6 +358,9 @@ fn link_linux( }; let env_path = env::var("PATH").unwrap_or_else(|_| "".to_string()); + + init_arch(target); + // NOTE: order of arguments to `ld` matters here! // The `-l` flags should go after the `.o` arguments Ok(( @@ -477,12 +478,16 @@ fn link_macos( )) } +#[cfg(feature = "llvm")] pub fn module_to_dylib( - module: &Module, + module: &inkwell::module::Module, target: &Triple, opt_level: OptLevel, ) -> Result { - let dir = tempdir().unwrap(); + use crate::target::{self, convert_opt_level}; + use inkwell::targets::{CodeModel, FileType, RelocMode}; + + let dir = tempfile::tempdir().unwrap(); let filename = PathBuf::from("Test.roc"); let file_path = dir.path().join(filename); let mut app_o_file = file_path; @@ -492,7 +497,8 @@ pub fn module_to_dylib( // Emit the .o file using position-indepedent code (PIC) - needed for dylibs let reloc = RelocMode::PIC; let model = CodeModel::Default; - let target_machine = target::target_machine(target, opt_level.into(), reloc, model).unwrap(); + let target_machine = + target::target_machine(target, convert_opt_level(opt_level), reloc, model).unwrap(); target_machine .write_to_file(module, FileType::Object, &app_o_file) @@ -529,3 +535,13 @@ fn validate_output(file_name: &str, cmd_name: &str, output: Output) { } } } + +#[cfg(feature = "llvm")] +fn init_arch(target: &Triple) { + crate::target::init_arch(target); +} + +#[cfg(not(feature = "llvm"))] +fn init_arch(_target: &Triple) { + panic!("Tried to initialize LLVM when crate was not built with `feature = \"llvm\"` enabled"); +} diff --git a/compiler/build/src/program.rs b/compiler/build/src/program.rs index 4d087664c0..5d3b7a984a 100644 --- a/compiler/build/src/program.rs +++ b/compiler/build/src/program.rs @@ -1,13 +1,14 @@ -use crate::target; -use bumpalo::Bump; -use inkwell::context::Context; -use inkwell::targets::{CodeModel, FileType, RelocMode}; +#[cfg(feature = "llvm")] +use roc_gen::llvm::build::module_from_builtins; +#[cfg(feature = "llvm")] pub use roc_gen::llvm::build::FunctionIterator; -use roc_gen::llvm::build::{module_from_builtins, OptLevel}; +#[cfg(feature = "llvm")] use roc_load::file::MonomorphizedModule; +#[cfg(feature = "llvm")] +use roc_mono::ir::OptLevel; +#[cfg(feature = "llvm")] use std::path::{Path, PathBuf}; -use std::time::{Duration, SystemTime}; -use target_lexicon::Triple; +use std::time::Duration; #[derive(Debug, Clone, Copy, Default)] pub struct CodeGenTiming { @@ -18,16 +19,24 @@ pub struct CodeGenTiming { // TODO how should imported modules factor into this? What if those use builtins too? // TODO this should probably use more helper functions // TODO make this polymorphic in the llvm functions so it can be reused for another backend. +#[cfg(feature = "llvm")] #[allow(clippy::cognitive_complexity)] pub fn gen_from_mono_module( - arena: &Bump, + arena: &bumpalo::Bump, mut loaded: MonomorphizedModule, roc_file_path: &Path, - target: Triple, + target: target_lexicon::Triple, app_o_file: &Path, opt_level: OptLevel, emit_debug_info: bool, ) -> CodeGenTiming { + use crate::target::{self, convert_opt_level}; + use inkwell::attributes::{Attribute, AttributeLoc}; + use inkwell::context::Context; + use inkwell::module::Linkage; + use inkwell::targets::{CodeModel, FileType, RelocMode}; + use std::time::SystemTime; + use roc_reporting::report::{ can_problem, mono_problem, type_problem, RocDocAllocator, DEFAULT_PALETTE, }; @@ -87,9 +96,6 @@ pub fn gen_from_mono_module( // module.strip_debug_info(); // mark our zig-defined builtins as internal - use inkwell::attributes::{Attribute, AttributeLoc}; - use inkwell::module::Linkage; - let app_ll_file = { let mut temp = PathBuf::from(roc_file_path); temp.set_extension("ll"); @@ -226,7 +232,7 @@ pub fn gen_from_mono_module( let reloc = RelocMode::Default; let model = CodeModel::Default; let target_machine = - target::target_machine(&target, opt_level.into(), reloc, model).unwrap(); + target::target_machine(&target, convert_opt_level(opt_level), reloc, model).unwrap(); target_machine .write_to_file(&env.module, FileType::Object, &app_o_file) diff --git a/compiler/build/src/target.rs b/compiler/build/src/target.rs index 8137357377..f1a10a830f 100644 --- a/compiler/build/src/target.rs +++ b/compiler/build/src/target.rs @@ -1,7 +1,10 @@ -use inkwell::targets::{ - CodeModel, InitializationConfig, RelocMode, Target, TargetMachine, TargetTriple, +#[cfg(feature = "llvm")] +use inkwell::{ + targets::{CodeModel, InitializationConfig, RelocMode, Target, TargetMachine, TargetTriple}, + OptimizationLevel, }; -use inkwell::OptimizationLevel; +#[cfg(feature = "llvm")] +use roc_mono::ir::OptLevel; use target_lexicon::{Architecture, OperatingSystem, Triple}; pub fn target_triple_str(target: &Triple) -> &'static str { @@ -28,36 +31,20 @@ pub fn target_triple_str(target: &Triple) -> &'static str { } } -/// NOTE: arch_str is *not* the same as the beginning of the magic target triple -/// string! For example, if it's "x86-64" here, the magic target triple string -/// will begin with "x86_64" (with an underscore) instead. -pub fn arch_str(target: &Triple) -> &'static str { - // Best guide I've found on how to determine these magic strings: - // - // https://stackoverflow.com/questions/15036909/clang-how-to-list-supported-target-architectures +#[cfg(feature = "llvm")] +pub fn init_arch(target: &Triple) { match target.architecture { Architecture::X86_64 => { Target::initialize_x86(&InitializationConfig::default()); - - "x86-64" } Architecture::Aarch64(_) if cfg!(feature = "target-aarch64") => { Target::initialize_aarch64(&InitializationConfig::default()); - "aarch64" } Architecture::Arm(_) if cfg!(feature = "target-arm") => { - // NOTE: why not enable arm and wasm by default? - // - // We had some trouble getting them to link properly. This may be resolved in the - // future, or maybe it was just some weird configuration on one machine. Target::initialize_arm(&InitializationConfig::default()); - - "arm" } Architecture::Wasm32 if cfg!(feature = "target-webassembly") => { Target::initialize_webassembly(&InitializationConfig::default()); - - "wasm32" } _ => panic!( "TODO gracefully handle unsupported target architecture: {:?}", @@ -66,6 +53,26 @@ pub fn arch_str(target: &Triple) -> &'static str { } } +/// NOTE: arch_str is *not* the same as the beginning of the magic target triple +/// string! For example, if it's "x86-64" here, the magic target triple string +/// will begin with "x86_64" (with an underscore) instead. +pub fn arch_str(target: &Triple) -> &'static str { + // Best guide I've found on how to determine these magic strings: + // + // https://stackoverflow.com/questions/15036909/clang-how-to-list-supported-target-architectures + match target.architecture { + Architecture::X86_64 => "x86-64", + Architecture::Aarch64(_) if cfg!(feature = "target-aarch64") => "aarch64", + Architecture::Arm(_) if cfg!(feature = "target-arm") => "arm", + Architecture::Wasm32 if cfg!(feature = "target-webassembly") => "wasm32", + _ => panic!( + "TODO gracefully handle unsupported target architecture: {:?}", + target.architecture + ), + } +} + +#[cfg(feature = "llvm")] pub fn target_machine( target: &Triple, opt: OptimizationLevel, @@ -83,3 +90,11 @@ pub fn target_machine( model, ) } + +#[cfg(feature = "llvm")] +pub fn convert_opt_level(level: OptLevel) -> OptimizationLevel { + match level { + OptLevel::Normal => OptimizationLevel::None, + OptLevel::Optimize => OptimizationLevel::Aggressive, + } +} diff --git a/compiler/gen/src/llvm/build.rs b/compiler/gen/src/llvm/build.rs index 7037fd2f12..46025e3a49 100644 --- a/compiler/gen/src/llvm/build.rs +++ b/compiler/gen/src/llvm/build.rs @@ -49,7 +49,8 @@ use roc_module::ident::TagName; use roc_module::low_level::LowLevel; use roc_module::symbol::{Interns, ModuleId, Symbol}; use roc_mono::ir::{ - BranchInfo, CallType, ExceptionId, JoinPointId, ModifyRc, TopLevelFunctionLayout, Wrapped, + BranchInfo, CallType, ExceptionId, JoinPointId, ModifyRc, OptLevel, TopLevelFunctionLayout, + Wrapped, }; use roc_mono::layout::{Builtin, InPlace, LambdaSet, Layout, LayoutIds, UnionLayout}; use target_lexicon::CallingConvention; @@ -86,21 +87,6 @@ macro_rules! debug_info_init { }}; } -#[derive(Debug, Clone, Copy)] -pub enum OptLevel { - Normal, - Optimize, -} - -impl From for OptimizationLevel { - fn from(level: OptLevel) -> Self { - match level { - OptLevel::Normal => OptimizationLevel::None, - OptLevel::Optimize => OptimizationLevel::Aggressive, - } - } -} - /// Iterate over all functions in an llvm module pub struct FunctionIterator<'ctx> { next: Option>, diff --git a/compiler/mono/src/ir.rs b/compiler/mono/src/ir.rs index 29da0e66e3..c967fc14b2 100644 --- a/compiler/mono/src/ir.rs +++ b/compiler/mono/src/ir.rs @@ -43,6 +43,12 @@ macro_rules! return_on_layout_error { }; } +#[derive(Debug, Clone, Copy)] +pub enum OptLevel { + Normal, + Optimize, +} + #[derive(Clone, Debug, PartialEq)] pub enum MonoProblem { PatternProblem(crate::exhaustive::Error), diff --git a/compiler/test_gen/src/helpers/eval.rs b/compiler/test_gen/src/helpers/eval.rs index 14dffa71d5..e8511b2586 100644 --- a/compiler/test_gen/src/helpers/eval.rs +++ b/compiler/test_gen/src/helpers/eval.rs @@ -6,6 +6,7 @@ use roc_can::def::Def; use roc_collections::all::{MutMap, MutSet}; use roc_gen::llvm::externs::add_default_roc_externs; use roc_module::symbol::Symbol; +use roc_mono::ir::OptLevel; use roc_types::subs::VarStore; fn promote_expr_to_module(src: &str) -> String { @@ -190,9 +191,9 @@ pub fn helper<'a>( module.strip_debug_info(); let opt_level = if cfg!(debug_assertions) { - roc_gen::llvm::build::OptLevel::Normal + OptLevel::Normal } else { - roc_gen::llvm::build::OptLevel::Optimize + OptLevel::Optimize }; let module = arena.alloc(module); From 9eee9df29bcf0b836f6eabc38a548babf2ac3eb3 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Sun, 6 Jun 2021 00:33:11 -0400 Subject: [PATCH 37/52] Don't use LLVM when building docs --- www/build.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/www/build.sh b/www/build.sh index bc1a7c0a35..28d29a85b6 100755 --- a/www/build.sh +++ b/www/build.sh @@ -13,6 +13,8 @@ cp -r public/ build/ pushd .. echo 'Generating docs...' -cargo run docs compiler/builtins/docs/Bool.roc +# We run the CLI with --no-default-features because that way we don't have a LLVM +# dependency. (Netlify's build servers have Rust installed, but not LLVM.) +cargo run -p roc_cli --no-default-features docs compiler/builtins/docs/Bool.roc mv generated-docs/ www/build/builtins popd From 5b91de40db0d3a8ff67032ab91afd257ad4b58da Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Sun, 6 Jun 2021 00:51:17 -0400 Subject: [PATCH 38/52] Only include_bytes when actually building --- compiler/builtins/src/bitcode.rs | 6 ------ compiler/gen/src/llvm/build.rs | 4 +++- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/compiler/builtins/src/bitcode.rs b/compiler/builtins/src/bitcode.rs index ad36d544b3..3e5d71ebe6 100644 --- a/compiler/builtins/src/bitcode.rs +++ b/compiler/builtins/src/bitcode.rs @@ -3,12 +3,6 @@ pub const OBJ_PATH: &str = env!( "Env var BUILTINS_O not found. Is there a problem with the build script?" ); -pub fn as_bytes() -> &'static [u8] { - // In the build script for the builtins module, - // we compile the builtins into LLVM bitcode - include_bytes!("../bitcode/builtins.bc") -} - pub const NUM_ASIN: &str = "roc_builtins.num.asin"; pub const NUM_ACOS: &str = "roc_builtins.num.acos"; pub const NUM_ATAN: &str = "roc_builtins.num.atan"; diff --git a/compiler/gen/src/llvm/build.rs b/compiler/gen/src/llvm/build.rs index 46025e3a49..47e989006b 100644 --- a/compiler/gen/src/llvm/build.rs +++ b/compiler/gen/src/llvm/build.rs @@ -341,7 +341,9 @@ impl<'a, 'ctx, 'env> Env<'a, 'ctx, 'env> { } pub fn module_from_builtins<'ctx>(ctx: &'ctx Context, module_name: &str) -> Module<'ctx> { - let bitcode_bytes = bitcode::as_bytes(); + // In the build script for the builtins module, + // we compile the builtins into LLVM bitcode + let bitcode_bytes: &[u8] = include_bytes!("../../../builtins/bitcode/builtins.bc"); let memory_buffer = MemoryBuffer::create_from_memory_range(&bitcode_bytes, module_name); From 368448862987a0702c5841a76a0aed83deacaa1c Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Sun, 6 Jun 2021 00:55:10 -0400 Subject: [PATCH 39/52] Make sure BUILTINS_O gets set --- compiler/builtins/build.rs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/compiler/builtins/build.rs b/compiler/builtins/build.rs index e0d493457b..8b42e59835 100644 --- a/compiler/builtins/build.rs +++ b/compiler/builtins/build.rs @@ -8,15 +8,22 @@ use std::process::Command; use std::str; fn main() { + let out_dir = env::var_os("OUT_DIR").unwrap(); + let dest_obj_path = Path::new(&out_dir).join("builtins.o"); + let dest_obj = dest_obj_path.to_str().expect("Invalid dest object path"); + + println!("cargo:rerun-if-changed=build.rs"); + println!("cargo:rustc-env=BUILTINS_O={}", dest_obj); + // When we build on Netlify, zig is not installed (but also not used, // since all we're doing is generating docs), so we can skip the steps // that require having zig installed. if env::var_os("NO_ZIG_INSTALLED").is_some() { + // We still need to do the other things before this point, because + // setting the env vars is needed for other parts of the build. return; } - let out_dir = env::var_os("OUT_DIR").unwrap(); - let big_sur_path = "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/lib"; let use_build_script = Path::new(big_sur_path).exists(); @@ -41,8 +48,6 @@ fn main() { run_command(&bitcode_path, "zig", &["build", "ir", "-Drelease=true"]); } - let dest_obj_path = Path::new(&out_dir).join("builtins.o"); - let dest_obj = dest_obj_path.to_str().expect("Invalid dest object path"); println!("Moving zig object to: {}", dest_obj); run_command(&bitcode_path, "mv", &[src_obj, dest_obj]); @@ -57,8 +62,6 @@ fn main() { &[dest_ir, "-o", dest_bc], ); - println!("cargo:rerun-if-changed=build.rs"); - println!("cargo:rustc-env=BUILTINS_O={}", dest_obj); get_zig_files(bitcode_path.as_path(), &|path| { let path: &Path = path; println!( From d7b64b000dfbb8d2a23317b789398e30438679a6 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Sun, 6 Jun 2021 01:12:11 -0400 Subject: [PATCH 40/52] Netlify shouldn't build the editor ...and anyway it can't, because it's missing the xcb-shape and xcb-xfixes libraries. --- cli/Cargo.toml | 5 +++-- cli/src/main.rs | 16 +++++++++++++--- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 177f9783cf..0f1c5a8ccb 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -15,11 +15,12 @@ test = false bench = false [features] -default = ["target-x86", "llvm"] +default = ["target-x86", "llvm", "editor"] # This is a separate feature because when we generate docs on Netlify, # it doesn't have LLVM installed. (Also, it doesn't need to do code gen.) llvm = ["inkwell", "roc_gen", "roc_build/llvm"] +editor = ["roc_editor"] target-x86 = [] @@ -53,7 +54,7 @@ roc_gen = { path = "../compiler/gen", optional = true } roc_build = { path = "../compiler/build", default-features = false } roc_fmt = { path = "../compiler/fmt" } roc_reporting = { path = "../compiler/reporting" } -roc_editor = { path = "../editor" } +roc_editor = { path = "../editor", optional = true } # TODO switch to clap 3.0.0 once it's out. Tried adding clap = "~3.0.0-beta.1" and cargo wouldn't accept it clap = { git = "https://github.com/rtfeldman/clap", branch = "master" } const_format = "0.2.8" diff --git a/cli/src/main.rs b/cli/src/main.rs index bd38a5e56a..80acc15ada 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -19,7 +19,7 @@ fn main() -> io::Result<()> { let exit_code = match matches.subcommand_name() { None => { - roc_editor::launch(&[])?; + launch_editor(&[])?; // rustc couldn't infer the error type here Result::::Ok(0) @@ -52,14 +52,14 @@ fn main() -> io::Result<()> { .values_of_os(DIRECTORY_OR_FILES) { None => { - roc_editor::launch(&[])?; + launch_editor(&[])?; } Some(values) => { let paths = values .map(|os_str| Path::new(os_str)) .collect::>(); - roc_editor::launch(&paths)?; + launch_editor(&paths)?; } } @@ -86,3 +86,13 @@ fn main() -> io::Result<()> { std::process::exit(exit_code); } + +#[cfg(feature = "editor")] +fn launch_editor(filepaths: &[&Path]) -> io::Result<()> { + roc_editor::launch(filepaths) +} + +#[cfg(not(feature = "editor"))] +fn launch_editor(_filepaths: &[&Path]) -> io::Result<()> { + panic!("Cannot launch the editor because this build of roc did not include `feature = \"editor\"`!"); +} From 6ec8c7e94456639cf53deef9555aaf023b8bef86 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Sun, 6 Jun 2021 01:25:55 -0400 Subject: [PATCH 41/52] Give each generated builtin doc its own index.html --- www/build.sh | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/www/build.sh b/www/build.sh index 28d29a85b6..b5474bfd69 100755 --- a/www/build.sh +++ b/www/build.sh @@ -16,5 +16,17 @@ echo 'Generating docs...' # We run the CLI with --no-default-features because that way we don't have a LLVM # dependency. (Netlify's build servers have Rust installed, but not LLVM.) cargo run -p roc_cli --no-default-features docs compiler/builtins/docs/Bool.roc + mv generated-docs/ www/build/builtins + +pushd www/build/builtins + +for f in ./*.html; do + DIRNAME=$(echo "$f" | sed s/.html//) + mkdir "$DIRNAME" + mv "$f" "$DIRNAME"/index.html +done + +popd + popd From 1a63bd570f294a9b66d4fe6e4a15bf2419df7459 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Sun, 6 Jun 2021 01:27:57 -0400 Subject: [PATCH 42/52] Create index.html files in doc gen This way, even when previewing them locally you can see (for example) /Str instead of /Str.html --- docs/src/lib.rs | 9 +++++---- www/build.sh | 12 ------------ 2 files changed, 5 insertions(+), 16 deletions(-) diff --git a/docs/src/lib.rs b/docs/src/lib.rs index bfa9f7ffa1..d4de9c25d2 100644 --- a/docs/src/lib.rs +++ b/docs/src/lib.rs @@ -63,9 +63,10 @@ pub fn generate(filenames: Vec, std_lib: StdLib, build_dir: &Path) { // Write each package's module docs html file for (docs_by_id, interns) in package.modules.iter_mut() { for module in docs_by_id.values_mut() { - let mut filename = String::new(); - filename.push_str(module.name.as_str()); - filename.push_str(".html"); + let module_dir = build_dir.join(module.name.as_str()); + + fs::create_dir(&module_dir) + .expect("TODO gracefully handle not being able to create the module dir"); let rendered_module = template_html .replace( @@ -78,7 +79,7 @@ pub fn generate(filenames: Vec, std_lib: StdLib, build_dir: &Path) { render_main_content(interns, module).as_str(), ); - fs::write(build_dir.join(filename), rendered_module) + fs::write(module_dir.join("index.html"), rendered_module) .expect("TODO gracefully handle failing to write html"); } } diff --git a/www/build.sh b/www/build.sh index b5474bfd69..28d29a85b6 100755 --- a/www/build.sh +++ b/www/build.sh @@ -16,17 +16,5 @@ echo 'Generating docs...' # We run the CLI with --no-default-features because that way we don't have a LLVM # dependency. (Netlify's build servers have Rust installed, but not LLVM.) cargo run -p roc_cli --no-default-features docs compiler/builtins/docs/Bool.roc - mv generated-docs/ www/build/builtins - -pushd www/build/builtins - -for f in ./*.html; do - DIRNAME=$(echo "$f" | sed s/.html//) - mkdir "$DIRNAME" - mv "$f" "$DIRNAME"/index.html -done - -popd - popd From 5a6dc24abd255a5797ad043e1ce552bb888f026d Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Sun, 6 Jun 2021 01:41:18 -0400 Subject: [PATCH 43/52] Call init_arch separately from arch_str --- compiler/build/src/target.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/compiler/build/src/target.rs b/compiler/build/src/target.rs index f1a10a830f..4e171359d0 100644 --- a/compiler/build/src/target.rs +++ b/compiler/build/src/target.rs @@ -81,6 +81,8 @@ pub fn target_machine( ) -> Option { let arch = arch_str(target); + init_arch(target); + Target::from_name(arch).unwrap().create_target_machine( &TargetTriple::create(target_triple_str(target)), "generic", From 6fd8db7d2bbc4ac49d5339d39f2e22596abf52ad Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Sun, 6 Jun 2021 02:22:00 -0400 Subject: [PATCH 44/52] `roc docs` now accepts directories --- cli/src/main.rs | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/cli/src/main.rs b/cli/src/main.rs index 80acc15ada..fccf700c96 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -2,6 +2,7 @@ use roc_cli::{ build_app, docs, repl, BuildConfig, CMD_BUILD, CMD_DOCS, CMD_EDIT, CMD_REPL, CMD_RUN, DIRECTORY_OR_FILES, ROC_FILE, }; +use std::fs::{self, FileType}; use std::io; use std::path::{Path, PathBuf}; use target_lexicon::Triple; @@ -73,11 +74,16 @@ fn main() -> io::Result<()> { .values_of_os(DIRECTORY_OR_FILES) .unwrap(); - let paths = values - .map(|os_str| Path::new(os_str).to_path_buf()) - .collect::>(); + let mut roc_files = Vec::new(); - docs(paths); + // Populate roc_files + for os_str in values { + let metadata = fs::metadata(os_str)?; + + roc_files_recursive(os_str, metadata.file_type(), &mut roc_files)?; + } + + docs(roc_files); Ok(0) } @@ -87,6 +93,24 @@ fn main() -> io::Result<()> { std::process::exit(exit_code); } +fn roc_files_recursive>( + path: P, + file_type: FileType, + roc_files: &mut Vec, +) -> io::Result<()> { + if file_type.is_dir() { + for entry_res in fs::read_dir(path)? { + let entry = entry_res?; + + roc_files_recursive(entry.path(), entry.file_type()?, roc_files)?; + } + } else { + roc_files.push(path.as_ref().to_path_buf()); + } + + Ok(()) +} + #[cfg(feature = "editor")] fn launch_editor(filepaths: &[&Path]) -> io::Result<()> { roc_editor::launch(filepaths) From 4995bc2312940071f833de48adda840eba81afaf Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Sun, 6 Jun 2021 02:22:19 -0400 Subject: [PATCH 45/52] Fix some List docs --- compiler/builtins/docs/List.roc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/builtins/docs/List.roc b/compiler/builtins/docs/List.roc index 12b1ba7b3c..6f30d0043f 100644 --- a/compiler/builtins/docs/List.roc +++ b/compiler/builtins/docs/List.roc @@ -298,7 +298,7 @@ update : List elem, Nat, (elem -> elem) -> List elem ## A more flexible version of #List.update, which returns an "updater" function ## that lets you delay performing the update until later. -updater : List elem, Nat -> { elem, new : elem -> List elem } +updater : List elem, Nat -> { elem, new : (elem -> List elem) } ## If all the elements in the list are #Ok, return a new list containing the ## contents of those #Ok tags. If any elements are #Err, return #Err. @@ -648,7 +648,7 @@ walk : List elem, { start : state, step : (state, elem -> state) } -> state ## Note that in other languages, `walkBackwards` is sometimes called `reduceRight`, ## `fold`, `foldRight`, or `foldr`. -walkBackwards : List elem, { start : state, step : (state, elem -> state ]) } -> state +walkBackwards : List elem, { start : state, step : (state, elem -> state) } -> state ## Same as #List.walk, except you can stop walking early. ## From b2875ac7fc29c1cc9357d1df9a39495079702348 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Sun, 6 Jun 2021 07:43:51 -0400 Subject: [PATCH 46/52] Suppress warnings when generating www.roc-lang.org --- www/build.sh | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/www/build.sh b/www/build.sh index 28d29a85b6..0fc2d25909 100755 --- a/www/build.sh +++ b/www/build.sh @@ -13,8 +13,13 @@ cp -r public/ build/ pushd .. echo 'Generating docs...' -# We run the CLI with --no-default-features because that way we don't have a LLVM -# dependency. (Netlify's build servers have Rust installed, but not LLVM.) -cargo run -p roc_cli --no-default-features docs compiler/builtins/docs/Bool.roc +# We run the CLI with --no-default-features because that way we don't have the +# "llvm" feature and therefore don't depend on LLVM being installed on the +# system. (Netlify's build servers have Rust installed, but not LLVM.) +# +# We set RUSTFLAGS to -Awarnings to ignore warnings during this build, +# because when building without "the" llvm feature (which is only ever done +# for this exact use case), the result is lots of "unused" warnings! +RUSTFLAGS=-Awarnings cargo run -p roc_cli --no-default-features docs compiler/builtins/docs/Bool.roc mv generated-docs/ www/build/builtins popd From 57676057fafabcdc7a1a08137425ec4479ad0803 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Sun, 6 Jun 2021 07:51:18 -0400 Subject: [PATCH 47/52] Rename gen to gen_llvm This way, we have gen_dev and gen_llvm representing the two different compiler backends. --- Cargo.lock | 76 +++++++++---------- Cargo.toml | 2 +- cli/Cargo.toml | 4 +- cli/src/repl/eval.rs | 2 +- cli/src/repl/gen.rs | 14 ++-- cli/tests/repl_eval.rs | 5 +- compiler/build/Cargo.toml | 4 +- compiler/build/src/program.rs | 12 +-- compiler/{gen => gen_llvm}/Cargo.toml | 2 +- compiler/{gen => gen_llvm}/src/lib.rs | 0 .../{gen => gen_llvm}/src/llvm/bitcode.rs | 0 compiler/{gen => gen_llvm}/src/llvm/build.rs | 0 .../{gen => gen_llvm}/src/llvm/build_dict.rs | 0 .../{gen => gen_llvm}/src/llvm/build_hash.rs | 0 .../{gen => gen_llvm}/src/llvm/build_list.rs | 0 .../{gen => gen_llvm}/src/llvm/build_str.rs | 0 .../{gen => gen_llvm}/src/llvm/compare.rs | 0 .../{gen => gen_llvm}/src/llvm/convert.rs | 0 .../{gen => gen_llvm}/src/llvm/externs.rs | 0 compiler/{gen => gen_llvm}/src/llvm/mod.rs | 0 .../{gen => gen_llvm}/src/llvm/refcounting.rs | 0 compiler/{gen => gen_llvm}/src/run_roc.rs | 6 +- compiler/test_gen/Cargo.toml | 2 +- compiler/test_gen/src/helpers/eval.rs | 14 ++-- 24 files changed, 73 insertions(+), 70 deletions(-) rename compiler/{gen => gen_llvm}/Cargo.toml (98%) rename compiler/{gen => gen_llvm}/src/lib.rs (100%) rename compiler/{gen => gen_llvm}/src/llvm/bitcode.rs (100%) rename compiler/{gen => gen_llvm}/src/llvm/build.rs (100%) rename compiler/{gen => gen_llvm}/src/llvm/build_dict.rs (100%) rename compiler/{gen => gen_llvm}/src/llvm/build_hash.rs (100%) rename compiler/{gen => gen_llvm}/src/llvm/build_list.rs (100%) rename compiler/{gen => gen_llvm}/src/llvm/build_str.rs (100%) rename compiler/{gen => gen_llvm}/src/llvm/compare.rs (100%) rename compiler/{gen => gen_llvm}/src/llvm/convert.rs (100%) rename compiler/{gen => gen_llvm}/src/llvm/externs.rs (100%) rename compiler/{gen => gen_llvm}/src/llvm/mod.rs (100%) rename compiler/{gen => gen_llvm}/src/llvm/refcounting.rs (100%) rename compiler/{gen => gen_llvm}/src/run_roc.rs (95%) diff --git a/Cargo.lock b/Cargo.lock index 5b05e59e64..65fe5b05b0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2943,7 +2943,7 @@ dependencies = [ "roc_can", "roc_collections", "roc_constrain", - "roc_gen", + "roc_gen_llvm", "roc_load", "roc_module", "roc_mono", @@ -3025,7 +3025,7 @@ dependencies = [ "roc_docs", "roc_editor", "roc_fmt", - "roc_gen", + "roc_gen_llvm", "roc_load", "roc_module", "roc_mono", @@ -3158,41 +3158,6 @@ dependencies = [ "roc_region", ] -[[package]] -name = "roc_gen" -version = "0.1.0" -dependencies = [ - "bumpalo", - "either", - "im 14.3.0", - "im-rc 14.3.0", - "indoc 0.3.6", - "inkwell 0.1.0", - "inlinable_string", - "libc", - "maplit", - "pretty_assertions 0.5.1", - "quickcheck 0.8.5", - "quickcheck_macros 0.8.0", - "roc_build", - "roc_builtins", - "roc_can", - "roc_collections", - "roc_load", - "roc_module", - "roc_mono", - "roc_parse", - "roc_problem", - "roc_region", - "roc_reporting", - "roc_solve", - "roc_std", - "roc_types", - "roc_unify", - "target-lexicon", - "tokio", -] - [[package]] name = "roc_gen_dev" version = "0.1.0" @@ -3231,6 +3196,41 @@ dependencies = [ "tokio", ] +[[package]] +name = "roc_gen_llvm" +version = "0.1.0" +dependencies = [ + "bumpalo", + "either", + "im 14.3.0", + "im-rc 14.3.0", + "indoc 0.3.6", + "inkwell 0.1.0", + "inlinable_string", + "libc", + "maplit", + "pretty_assertions 0.5.1", + "quickcheck 0.8.5", + "quickcheck_macros 0.8.0", + "roc_build", + "roc_builtins", + "roc_can", + "roc_collections", + "roc_load", + "roc_module", + "roc_mono", + "roc_parse", + "roc_problem", + "roc_region", + "roc_reporting", + "roc_solve", + "roc_std", + "roc_types", + "roc_unify", + "target-lexicon", + "tokio", +] + [[package]] name = "roc_load" version = "0.1.0" @@ -3910,7 +3910,7 @@ dependencies = [ "roc_can", "roc_collections", "roc_constrain", - "roc_gen", + "roc_gen_llvm", "roc_load", "roc_module", "roc_mono", diff --git a/Cargo.toml b/Cargo.toml index 84016c05b1..40cc3a5e32 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,7 @@ members = [ "compiler/test_mono_macros", "compiler/test_mono", "compiler/load", - "compiler/gen", + "compiler/gen_llvm", "compiler/gen_dev", "compiler/build", "compiler/arena_pool", diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 0f1c5a8ccb..4e95a3398a 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -19,7 +19,7 @@ default = ["target-x86", "llvm", "editor"] # This is a separate feature because when we generate docs on Netlify, # it doesn't have LLVM installed. (Also, it doesn't need to do code gen.) -llvm = ["inkwell", "roc_gen", "roc_build/llvm"] +llvm = ["inkwell", "roc_gen_llvm", "roc_build/llvm"] editor = ["roc_editor"] target-x86 = [] @@ -50,7 +50,7 @@ roc_unify = { path = "../compiler/unify" } roc_solve = { path = "../compiler/solve" } roc_mono = { path = "../compiler/mono" } roc_load = { path = "../compiler/load" } -roc_gen = { path = "../compiler/gen", optional = true } +roc_gen_llvm = { path = "../compiler/gen_llvm", optional = true } roc_build = { path = "../compiler/build", default-features = false } roc_fmt = { path = "../compiler/fmt" } roc_reporting = { path = "../compiler/reporting" } diff --git a/cli/src/repl/eval.rs b/cli/src/repl/eval.rs index 34ed34df94..89fd30e74f 100644 --- a/cli/src/repl/eval.rs +++ b/cli/src/repl/eval.rs @@ -2,7 +2,7 @@ use bumpalo::collections::Vec; use bumpalo::Bump; use libloading::Library; use roc_collections::all::MutMap; -use roc_gen::{run_jit_function, run_jit_function_dynamic_type}; +use roc_gen_llvm::{run_jit_function, run_jit_function_dynamic_type}; use roc_module::ident::{Lowercase, TagName}; use roc_module::operator::CalledVia; use roc_module::symbol::{Interns, ModuleId, Symbol}; diff --git a/cli/src/repl/gen.rs b/cli/src/repl/gen.rs index b9bb9a2799..e6d699a683 100644 --- a/cli/src/repl/gen.rs +++ b/cli/src/repl/gen.rs @@ -8,7 +8,7 @@ use roc_can::builtins::builtin_defs_map; use roc_collections::all::{MutMap, MutSet}; use roc_fmt::annotation::Formattable; use roc_fmt::annotation::{Newlines, Parens}; -use roc_gen::llvm::externs::add_default_roc_externs; +use roc_gen_llvm::llvm::externs::add_default_roc_externs; use roc_load::file::LoadingProblem; use roc_mono::ir::OptLevel; use roc_parse::parser::SyntaxError; @@ -130,7 +130,9 @@ pub fn gen_and_eval<'a>( let context = Context::create(); let builder = context.create_builder(); let ptr_bytes = target.pointer_width().unwrap().bytes() as u32; - let module = arena.alloc(roc_gen::llvm::build::module_from_builtins(&context, "")); + let module = arena.alloc(roc_gen_llvm::llvm::build::module_from_builtins( + &context, "", + )); // Add roc_alloc, roc_realloc, and roc_dealloc, since the repl has no // platform to provide them. @@ -166,12 +168,12 @@ pub fn gen_and_eval<'a>( let module = arena.alloc(module); let (module_pass, function_pass) = - roc_gen::llvm::build::construct_optimization_passes(module, opt_level); + roc_gen_llvm::llvm::build::construct_optimization_passes(module, opt_level); - let (dibuilder, compile_unit) = roc_gen::llvm::build::Env::new_debug_info(module); + let (dibuilder, compile_unit) = roc_gen_llvm::llvm::build::Env::new_debug_info(module); // Compile and add all the Procs before adding main - let env = roc_gen::llvm::build::Env { + let env = roc_gen_llvm::llvm::build::Env { arena: &arena, builder: &builder, dibuilder: &dibuilder, @@ -185,7 +187,7 @@ pub fn gen_and_eval<'a>( exposed_to_host: MutSet::default(), }; - let (main_fn_name, main_fn) = roc_gen::llvm::build::build_procedures_return_main( + let (main_fn_name, main_fn) = roc_gen_llvm::llvm::build::build_procedures_return_main( &env, opt_level, procedures, diff --git a/cli/tests/repl_eval.rs b/cli/tests/repl_eval.rs index 77e84b10e2..87d53837a8 100644 --- a/cli/tests/repl_eval.rs +++ b/cli/tests/repl_eval.rs @@ -7,7 +7,7 @@ extern crate indoc; #[cfg(test)] mod repl_eval { use cli_utils::helpers; - use roc_gen::run_roc::RocCallResult; + use roc_gen_llvm::run_roc::RocCallResult; #[test] fn check_discriminant_size() { @@ -16,7 +16,8 @@ mod repl_eval { let value: i64 = 1234; assert_eq!( std::mem::size_of_val(&RocCallResult::Success(value)), - roc_gen::run_roc::ROC_CALL_RESULT_DISCRIMINANT_SIZE + std::mem::size_of_val(&value) + roc_gen_llvm::run_roc::ROC_CALL_RESULT_DISCRIMINANT_SIZE + + std::mem::size_of_val(&value) ) } diff --git a/compiler/build/Cargo.toml b/compiler/build/Cargo.toml index 11a5e9effb..77dcf1d8a6 100644 --- a/compiler/build/Cargo.toml +++ b/compiler/build/Cargo.toml @@ -19,7 +19,7 @@ roc_unify = { path = "../unify" } roc_solve = { path = "../solve" } roc_mono = { path = "../mono" } roc_load = { path = "../load" } -roc_gen = { path = "../gen", optional = true } +roc_gen_llvm = { path = "../gen_llvm", optional = true } roc_reporting = { path = "../reporting" } im = "14" # im and im-rc should always have the same version! im-rc = "14" # im and im-rc should always have the same version! @@ -45,4 +45,4 @@ target-aarch64 = [] target-webassembly = [] # This is a separate feature because when we generate docs on Netlify, # it doesn't have LLVM installed. (Also, it doesn't need to do code gen.) -llvm = ["inkwell", "roc_gen"] +llvm = ["inkwell", "roc_gen_llvm"] diff --git a/compiler/build/src/program.rs b/compiler/build/src/program.rs index 5d3b7a984a..28be0802f5 100644 --- a/compiler/build/src/program.rs +++ b/compiler/build/src/program.rs @@ -1,7 +1,7 @@ #[cfg(feature = "llvm")] -use roc_gen::llvm::build::module_from_builtins; +use roc_gen_llvm::llvm::build::module_from_builtins; #[cfg(feature = "llvm")] -pub use roc_gen::llvm::build::FunctionIterator; +pub use roc_gen_llvm::llvm::build::FunctionIterator; #[cfg(feature = "llvm")] use roc_load::file::MonomorphizedModule; #[cfg(feature = "llvm")] @@ -125,12 +125,12 @@ pub fn gen_from_mono_module( } let builder = context.create_builder(); - let (dibuilder, compile_unit) = roc_gen::llvm::build::Env::new_debug_info(module); - let (mpm, _fpm) = roc_gen::llvm::build::construct_optimization_passes(module, opt_level); + let (dibuilder, compile_unit) = roc_gen_llvm::llvm::build::Env::new_debug_info(module); + let (mpm, _fpm) = roc_gen_llvm::llvm::build::construct_optimization_passes(module, opt_level); // Compile and add all the Procs before adding main let ptr_bytes = target.pointer_width().unwrap().bytes() as u32; - let env = roc_gen::llvm::build::Env { + let env = roc_gen_llvm::llvm::build::Env { arena: &arena, builder: &builder, dibuilder: &dibuilder, @@ -143,7 +143,7 @@ pub fn gen_from_mono_module( exposed_to_host: loaded.exposed_to_host.keys().copied().collect(), }; - roc_gen::llvm::build::build_procedures(&env, opt_level, loaded.procedures); + roc_gen_llvm::llvm::build::build_procedures(&env, opt_level, loaded.procedures); env.dibuilder.finalize(); diff --git a/compiler/gen/Cargo.toml b/compiler/gen_llvm/Cargo.toml similarity index 98% rename from compiler/gen/Cargo.toml rename to compiler/gen_llvm/Cargo.toml index 685b00fa3a..270c8e9cc8 100644 --- a/compiler/gen/Cargo.toml +++ b/compiler/gen_llvm/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "roc_gen" +name = "roc_gen_llvm" version = "0.1.0" authors = ["The Roc Contributors"] license = "UPL-1.0" diff --git a/compiler/gen/src/lib.rs b/compiler/gen_llvm/src/lib.rs similarity index 100% rename from compiler/gen/src/lib.rs rename to compiler/gen_llvm/src/lib.rs diff --git a/compiler/gen/src/llvm/bitcode.rs b/compiler/gen_llvm/src/llvm/bitcode.rs similarity index 100% rename from compiler/gen/src/llvm/bitcode.rs rename to compiler/gen_llvm/src/llvm/bitcode.rs diff --git a/compiler/gen/src/llvm/build.rs b/compiler/gen_llvm/src/llvm/build.rs similarity index 100% rename from compiler/gen/src/llvm/build.rs rename to compiler/gen_llvm/src/llvm/build.rs diff --git a/compiler/gen/src/llvm/build_dict.rs b/compiler/gen_llvm/src/llvm/build_dict.rs similarity index 100% rename from compiler/gen/src/llvm/build_dict.rs rename to compiler/gen_llvm/src/llvm/build_dict.rs diff --git a/compiler/gen/src/llvm/build_hash.rs b/compiler/gen_llvm/src/llvm/build_hash.rs similarity index 100% rename from compiler/gen/src/llvm/build_hash.rs rename to compiler/gen_llvm/src/llvm/build_hash.rs diff --git a/compiler/gen/src/llvm/build_list.rs b/compiler/gen_llvm/src/llvm/build_list.rs similarity index 100% rename from compiler/gen/src/llvm/build_list.rs rename to compiler/gen_llvm/src/llvm/build_list.rs diff --git a/compiler/gen/src/llvm/build_str.rs b/compiler/gen_llvm/src/llvm/build_str.rs similarity index 100% rename from compiler/gen/src/llvm/build_str.rs rename to compiler/gen_llvm/src/llvm/build_str.rs diff --git a/compiler/gen/src/llvm/compare.rs b/compiler/gen_llvm/src/llvm/compare.rs similarity index 100% rename from compiler/gen/src/llvm/compare.rs rename to compiler/gen_llvm/src/llvm/compare.rs diff --git a/compiler/gen/src/llvm/convert.rs b/compiler/gen_llvm/src/llvm/convert.rs similarity index 100% rename from compiler/gen/src/llvm/convert.rs rename to compiler/gen_llvm/src/llvm/convert.rs diff --git a/compiler/gen/src/llvm/externs.rs b/compiler/gen_llvm/src/llvm/externs.rs similarity index 100% rename from compiler/gen/src/llvm/externs.rs rename to compiler/gen_llvm/src/llvm/externs.rs diff --git a/compiler/gen/src/llvm/mod.rs b/compiler/gen_llvm/src/llvm/mod.rs similarity index 100% rename from compiler/gen/src/llvm/mod.rs rename to compiler/gen_llvm/src/llvm/mod.rs diff --git a/compiler/gen/src/llvm/refcounting.rs b/compiler/gen_llvm/src/llvm/refcounting.rs similarity index 100% rename from compiler/gen/src/llvm/refcounting.rs rename to compiler/gen_llvm/src/llvm/refcounting.rs diff --git a/compiler/gen/src/run_roc.rs b/compiler/gen_llvm/src/run_roc.rs similarity index 95% rename from compiler/gen/src/run_roc.rs rename to compiler/gen_llvm/src/run_roc.rs index 1e1c28b9b2..884ef41fcc 100644 --- a/compiler/gen/src/run_roc.rs +++ b/compiler/gen_llvm/src/run_roc.rs @@ -38,7 +38,7 @@ macro_rules! run_jit_function { ($lib: expr, $main_fn_name: expr, $ty:ty, $transform:expr, $errors:expr) => {{ use inkwell::context::Context; - use roc_gen::run_roc::RocCallResult; + use roc_gen_llvm::run_roc::RocCallResult; use std::mem::MaybeUninit; unsafe { @@ -77,7 +77,7 @@ macro_rules! run_jit_function_dynamic_type { ($lib: expr, $main_fn_name: expr, $bytes:expr, $transform:expr, $errors:expr) => {{ use inkwell::context::Context; - use roc_gen::run_roc::RocCallResult; + use roc_gen_llvm::run_roc::RocCallResult; unsafe { let main: libloading::Symbol = $lib @@ -86,7 +86,7 @@ macro_rules! run_jit_function_dynamic_type { .ok_or(format!("Unable to JIT compile `{}`", $main_fn_name)) .expect("errored"); - let size = roc_gen::run_roc::ROC_CALL_RESULT_DISCRIMINANT_SIZE + $bytes; + let size = roc_gen_llvm::run_roc::ROC_CALL_RESULT_DISCRIMINANT_SIZE + $bytes; let layout = std::alloc::Layout::array::(size).unwrap(); let result = std::alloc::alloc(layout); main(result); diff --git a/compiler/test_gen/Cargo.toml b/compiler/test_gen/Cargo.toml index 7300d3ee57..c34a5c2a17 100644 --- a/compiler/test_gen/Cargo.toml +++ b/compiler/test_gen/Cargo.toml @@ -6,7 +6,7 @@ license = "UPL-1.0" edition = "2018" [dependencies] -roc_gen = { path = "../gen" } +roc_gen_llvm = { path = "../gen_llvm" } roc_collections = { path = "../collections" } roc_region = { path = "../region" } roc_module = { path = "../module" } diff --git a/compiler/test_gen/src/helpers/eval.rs b/compiler/test_gen/src/helpers/eval.rs index e8511b2586..91324d7dae 100644 --- a/compiler/test_gen/src/helpers/eval.rs +++ b/compiler/test_gen/src/helpers/eval.rs @@ -4,7 +4,7 @@ use roc_build::program::FunctionIterator; use roc_can::builtins::builtin_defs_map; use roc_can::def::Def; use roc_collections::all::{MutMap, MutSet}; -use roc_gen::llvm::externs::add_default_roc_externs; +use roc_gen_llvm::llvm::externs::add_default_roc_externs; use roc_module::symbol::Symbol; use roc_mono::ir::OptLevel; use roc_types::subs::VarStore; @@ -181,7 +181,7 @@ pub fn helper<'a>( }; let builder = context.create_builder(); - let module = roc_gen::llvm::build::module_from_builtins(context, "app"); + let module = roc_gen_llvm::llvm::build::module_from_builtins(context, "app"); // Add roc_alloc, roc_realloc, and roc_dealloc, since the repl has no // platform to provide them. @@ -198,9 +198,9 @@ pub fn helper<'a>( let module = arena.alloc(module); let (module_pass, function_pass) = - roc_gen::llvm::build::construct_optimization_passes(module, opt_level); + roc_gen_llvm::llvm::build::construct_optimization_passes(module, opt_level); - let (dibuilder, compile_unit) = roc_gen::llvm::build::Env::new_debug_info(module); + let (dibuilder, compile_unit) = roc_gen_llvm::llvm::build::Env::new_debug_info(module); // mark our zig-defined builtins as internal use inkwell::attributes::{Attribute, AttributeLoc}; @@ -222,7 +222,7 @@ pub fn helper<'a>( } // Compile and add all the Procs before adding main - let env = roc_gen::llvm::build::Env { + let env = roc_gen_llvm::llvm::build::Env { arena: &arena, builder: &builder, dibuilder: &dibuilder, @@ -236,7 +236,7 @@ pub fn helper<'a>( exposed_to_host: MutSet::default(), }; - let (main_fn_name, main_fn) = roc_gen::llvm::build::build_procedures_return_main( + let (main_fn_name, main_fn) = roc_gen_llvm::llvm::build::build_procedures_return_main( &env, opt_level, procedures, @@ -276,7 +276,7 @@ macro_rules! assert_llvm_evals_to { ($src:expr, $expected:expr, $ty:ty, $transform:expr, $leak:expr, $ignore_problems:expr) => { use bumpalo::Bump; use inkwell::context::Context; - use roc_gen::run_jit_function; + use roc_gen_llvm::run_jit_function; let arena = Bump::new(); let context = Context::create(); From 811ecd86363dc46c0de3029c2703b4c5247a424b Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Sun, 6 Jun 2021 07:53:48 -0400 Subject: [PATCH 48/52] Add descriptions to gen_dev and gen_llvm --- compiler/gen_dev/Cargo.toml | 1 + compiler/gen_llvm/Cargo.toml | 1 + 2 files changed, 2 insertions(+) diff --git a/compiler/gen_dev/Cargo.toml b/compiler/gen_dev/Cargo.toml index b960c7468e..8fb6646e26 100644 --- a/compiler/gen_dev/Cargo.toml +++ b/compiler/gen_dev/Cargo.toml @@ -1,5 +1,6 @@ [package] name = "roc_gen_dev" +description = "The development backend for the Roc compiler" version = "0.1.0" authors = ["The Roc Contributors"] license = "UPL-1.0" diff --git a/compiler/gen_llvm/Cargo.toml b/compiler/gen_llvm/Cargo.toml index 270c8e9cc8..ab07ce48e8 100644 --- a/compiler/gen_llvm/Cargo.toml +++ b/compiler/gen_llvm/Cargo.toml @@ -1,5 +1,6 @@ [package] name = "roc_gen_llvm" +description = "The LLVM backend for the Roc compiler" version = "0.1.0" authors = ["The Roc Contributors"] license = "UPL-1.0" From 18be90649e5e76e2259924c6d0c594a244583611 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Sun, 6 Jun 2021 09:59:46 -0400 Subject: [PATCH 49/52] Don't link to .html files anymore We now generate index.html files, so the .html suffix is no longer needed! --- docs/src/lib.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/src/lib.rs b/docs/src/lib.rs index d4de9c25d2..a7db7eb73e 100644 --- a/docs/src/lib.rs +++ b/docs/src/lib.rs @@ -229,7 +229,6 @@ fn render_sidebar<'a, I: Iterator>(modules: I) - let href = { let mut href_buf = String::new(); href_buf.push_str(name); - href_buf.push_str(".html"); href_buf }; @@ -568,7 +567,7 @@ fn make_doc_link(scope: &mut Scope, interns: &Interns, doc_item: &str) -> String let mut link = String::new(); link.push_str(module_str); - link.push_str(".html#"); + link.push_str("#"); link.push_str(ident_str); let mut buf = String::new(); From 53da2a2d14e149d347cc09b61761405a873fd65f Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Sun, 6 Jun 2021 10:10:51 -0400 Subject: [PATCH 50/52] clippy --- docs/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/lib.rs b/docs/src/lib.rs index a7db7eb73e..97ef19bba1 100644 --- a/docs/src/lib.rs +++ b/docs/src/lib.rs @@ -567,7 +567,7 @@ fn make_doc_link(scope: &mut Scope, interns: &Interns, doc_item: &str) -> String let mut link = String::new(); link.push_str(module_str); - link.push_str("#"); + link.push('#'); link.push_str(ident_str); let mut buf = String::new(); From ef74f50ae7bd7f6de5423598d8a6eed802a475e0 Mon Sep 17 00:00:00 2001 From: Chadtech Date: Mon, 7 Jun 2021 01:02:20 -0400 Subject: [PATCH 51/52] A module like Json.Decode will now have its docs at Json/Decode/index.html --- docs/src/lib.rs | 4 ++-- docs/src/static/index.html | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/src/lib.rs b/docs/src/lib.rs index 97ef19bba1..3ee9d75cd7 100644 --- a/docs/src/lib.rs +++ b/docs/src/lib.rs @@ -63,9 +63,9 @@ pub fn generate(filenames: Vec, std_lib: StdLib, build_dir: &Path) { // Write each package's module docs html file for (docs_by_id, interns) in package.modules.iter_mut() { for module in docs_by_id.values_mut() { - let module_dir = build_dir.join(module.name.as_str()); + let module_dir = build_dir.join(module.name.replace(".", "/").as_str()); - fs::create_dir(&module_dir) + fs::create_dir_all(&module_dir) .expect("TODO gracefully handle not being able to create the module dir"); let rendered_module = template_html diff --git a/docs/src/static/index.html b/docs/src/static/index.html index daad3246e6..5e358eea74 100644 --- a/docs/src/static/index.html +++ b/docs/src/static/index.html @@ -6,9 +6,9 @@ - - - + + + From 11ae7867a6521e773a79e9b11dd7ca012c48326b Mon Sep 17 00:00:00 2001 From: Anton-4 <17049058+Anton-4@users.noreply.github.com> Date: Mon, 7 Jun 2021 10:39:17 +0200 Subject: [PATCH 52/52] Added replit editor inspiration, thanks Richard! --- editor/editor-ideas.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/editor/editor-ideas.md b/editor/editor-ideas.md index f17adf94a3..d936a0214d 100644 --- a/editor/editor-ideas.md +++ b/editor/editor-ideas.md @@ -39,9 +39,11 @@ Nice collection of research on innovative editors, [link](https://futureofcoding * [godbolt.org Compiler Explorer](https://godbolt.org/) * [whitebox debug visualization](https://vimeo.com/483795097) * [Hest](https://ivanish.ca/hest-time-travel/) tool for making highly interactive simulations. +* [replit](https://replit.com/) collaborative browser based IDE. * Say you have a failing test that used to work, it would be very valuable to see all code that was changed that was used only by that test. e.g. you have a test `calculate_sum_test` that only uses the function `add`, when the test fails you should be able to see a diff showing only what changed for the function `add`. It would also be great to have a diff of [expression values](https://homepages.cwi.nl/~storm/livelit/images/bret.png) Bret Victor style. An ambitious project would be to suggest or automatically try fixes based on these diffs. * I think it could be possible to create a minimal reproduction of a program / block of code / code used by a single test. So for a failing unit test I would expect it to extract imports, the platform, types and functions that are necessary to run only that unit test and put them in a standalone roc project. This would be useful for sharing bugs with library+application authors and colleagues, for profiling or debugging with all "clutter" removed. +* Ability to share program state at a breakpoint with someone else. ### Cool regular editors