mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-02 11:22:19 +00:00
Merge branch 'main' into inline-imports
This commit is contained in:
commit
eb8ef6241e
24 changed files with 182 additions and 180 deletions
|
@ -949,15 +949,16 @@ mod cli_run {
|
|||
This roc file can print its own source code. The source is:
|
||||
|
||||
app "ingested-file"
|
||||
packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br" }
|
||||
packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.10.0/vNe6s9hWzoTZtFmNkvEICPErI9ptji_ySjicO6CkucY.tar.br" }
|
||||
imports [
|
||||
pf.Stdout,
|
||||
pf.Task,
|
||||
"ingested-file.roc" as ownCode : Str,
|
||||
]
|
||||
provides [main] to pf
|
||||
|
||||
main =
|
||||
Stdout.line "\nThis roc file can print its own source code. The source is:\n\n$(ownCode)"
|
||||
Stdout.line! "\nThis roc file can print its own source code. The source is:\n\n$(ownCode)"
|
||||
|
||||
"#
|
||||
),
|
||||
|
|
|
@ -1816,7 +1816,7 @@ fn roc_file_no_extension() {
|
|||
indoc!(
|
||||
r#"
|
||||
app "helloWorld"
|
||||
packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br" }
|
||||
packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.10.0/vNe6s9hWzoTZtFmNkvEICPErI9ptji_ySjicO6CkucY.tar.br" }
|
||||
imports [pf.Stdout]
|
||||
provides [main] to pf
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
app "hello"
|
||||
packages {
|
||||
pf:
|
||||
"https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br",
|
||||
"https://github.com/roc-lang/basic-cli/releases/download/0.10.0/vNe6s9hWzoTZtFmNkvEICPErI9ptji_ySjicO6CkucY.tar.br",
|
||||
}
|
||||
imports [pf.Stdout]
|
||||
provides [main] to pf
|
||||
|
|
|
@ -17,14 +17,14 @@ Full {
|
|||
after: [],
|
||||
},
|
||||
item: [
|
||||
@27-145 SpaceAfter(
|
||||
@27-146 SpaceAfter(
|
||||
PackageEntry {
|
||||
shorthand: "pf",
|
||||
spaces_after_shorthand: [
|
||||
Newline,
|
||||
],
|
||||
package_name: @31-145 PackageName(
|
||||
"https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br",
|
||||
package_name: @31-146 PackageName(
|
||||
"https://github.com/roc-lang/basic-cli/releases/download/0.10.0/vNe6s9hWzoTZtFmNkvEICPErI9ptji_ySjicO6CkucY.tar.br",
|
||||
),
|
||||
},
|
||||
[
|
||||
|
@ -44,7 +44,7 @@ Full {
|
|||
after: [],
|
||||
},
|
||||
item: [
|
||||
@161-170 Package(
|
||||
@162-171 Package(
|
||||
"pf",
|
||||
ModuleName(
|
||||
"Stdout",
|
||||
|
@ -63,7 +63,7 @@ Full {
|
|||
after: [],
|
||||
},
|
||||
entries: [
|
||||
@186-190 ExposedName(
|
||||
@187-191 ExposedName(
|
||||
"main",
|
||||
),
|
||||
],
|
||||
|
@ -73,7 +73,7 @@ Full {
|
|||
item: ToKeyword,
|
||||
after: [],
|
||||
},
|
||||
to: @195-197 ExistingPackage(
|
||||
to: @196-198 ExistingPackage(
|
||||
"pf",
|
||||
),
|
||||
},
|
||||
|
@ -85,7 +85,7 @@ Full {
|
|||
Index(2147483648),
|
||||
],
|
||||
regions: [
|
||||
@199-246,
|
||||
@200-247,
|
||||
],
|
||||
space_before: [
|
||||
Slice(start = 0, length = 2),
|
||||
|
@ -100,17 +100,17 @@ Full {
|
|||
type_defs: [],
|
||||
value_defs: [
|
||||
Body(
|
||||
@199-203 Identifier {
|
||||
@200-204 Identifier {
|
||||
ident: "main",
|
||||
},
|
||||
@210-246 SpaceBefore(
|
||||
@211-247 SpaceBefore(
|
||||
Apply(
|
||||
@210-221 Var {
|
||||
@211-222 Var {
|
||||
module_name: "Stdout",
|
||||
ident: "line",
|
||||
},
|
||||
[
|
||||
@222-246 Str(
|
||||
@223-247 Str(
|
||||
PlainLine(
|
||||
"I'm a Roc application!",
|
||||
),
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
app "hello"
|
||||
packages { pf:
|
||||
"https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br"
|
||||
"https://github.com/roc-lang/basic-cli/releases/download/0.10.0/vNe6s9hWzoTZtFmNkvEICPErI9ptji_ySjicO6CkucY.tar.br"
|
||||
}
|
||||
imports [pf.Stdout]
|
||||
provides [main] to pf
|
||||
|
|
|
@ -74,7 +74,8 @@ impl Registry {
|
|||
if &document.doc_info.url == updating_url {
|
||||
//Write the newly analysed document into the oncelock that any request requiring the latest document will be waiting on
|
||||
if let Some(a) = documents.get_mut(updating_url) {
|
||||
a.latest_document.set(document.clone()).unwrap()
|
||||
// We don't care if this fails because we expect the document to sometimes already be there
|
||||
a.latest_document.set(document.clone()).unwrap_or(())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ use analysis::HIGHLIGHT_TOKENS_LEGEND;
|
|||
use log::{debug, trace};
|
||||
use registry::{Registry, RegistryConfig};
|
||||
use std::future::Future;
|
||||
use std::panic::AssertUnwindSafe;
|
||||
use std::panic::{catch_unwind, AssertUnwindSafe};
|
||||
use std::time::Duration;
|
||||
|
||||
use tower_lsp::jsonrpc::{self, Result};
|
||||
|
@ -173,9 +173,24 @@ impl RocServerState {
|
|||
return Err("Not latest version skipping analysis".to_string());
|
||||
}
|
||||
|
||||
let results = match tokio::task::spawn_blocking(|| global_analysis(doc_info)).await {
|
||||
Err(e) => return Err(format!("Document analysis failed. reason:{:?}", e)),
|
||||
Ok(a) => a,
|
||||
let results = match tokio::time::timeout(
|
||||
Duration::from_secs(60),
|
||||
tokio::task::spawn_blocking(|| catch_unwind(|| global_analysis(doc_info))),
|
||||
)
|
||||
.await
|
||||
{
|
||||
Err(e) => {
|
||||
return Err(format!(
|
||||
"Document analysis thread timeout out after: {:?}",
|
||||
e
|
||||
))
|
||||
}
|
||||
Ok(Err(e)) => {
|
||||
return Err(format!("Document analysis thread failed. reason:{:?}", e))
|
||||
}
|
||||
Ok(Ok(res)) => {
|
||||
res.map_err(|err| format!("Document analysis panicked with: {:?}", err))?
|
||||
}
|
||||
};
|
||||
let latest_version = inner_ref.registry.get_latest_version(fi).await;
|
||||
|
||||
|
@ -230,8 +245,11 @@ impl LanguageServer for RocServer {
|
|||
|
||||
// NOTE: We specify that we expect full-content syncs in the server capabilities,
|
||||
// so here we assume the only change passed is a change of the entire document's content.
|
||||
let TextDocumentContentChangeEvent { text, .. } =
|
||||
params.content_changes.into_iter().next().unwrap();
|
||||
let TextDocumentContentChangeEvent { text, .. } = params
|
||||
.content_changes
|
||||
.into_iter()
|
||||
.last()
|
||||
.expect("textDocument change event had no changes ");
|
||||
|
||||
self.change(uri, text, version).await;
|
||||
}
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
app "args"
|
||||
packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br" }
|
||||
packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.10.0/vNe6s9hWzoTZtFmNkvEICPErI9ptji_ySjicO6CkucY.tar.br" }
|
||||
imports [pf.Stdout, pf.Arg, pf.Task.{ Task }]
|
||||
provides [main] to pf
|
||||
|
||||
main : Task {} I32
|
||||
main =
|
||||
args <- Arg.list |> Task.await
|
||||
args = Arg.list!
|
||||
parser =
|
||||
divCmd =
|
||||
Arg.succeed (\dividend -> \divisor -> Div (Num.toF64 dividend) (Num.toF64 divisor))
|
||||
|
@ -55,9 +54,8 @@ main =
|
|||
|> Num.toStr
|
||||
|> Stdout.line
|
||||
|
||||
Err helpMenu ->
|
||||
{} <- Stdout.line helpMenu |> Task.await
|
||||
Task.err 1
|
||||
Err helpMenuErr ->
|
||||
Task.err (Exit 1 "unable to parse args: $(Inspect.toStr helpMenuErr)")
|
||||
|
||||
runCmd = \cmd ->
|
||||
when cmd is
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
app "countdown"
|
||||
packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br" }
|
||||
packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.10.0/vNe6s9hWzoTZtFmNkvEICPErI9ptji_ySjicO6CkucY.tar.br" }
|
||||
imports [pf.Stdin, pf.Stdout, pf.Task.{ await, loop }]
|
||||
provides [main] to pf
|
||||
|
||||
|
|
|
@ -1,21 +1,19 @@
|
|||
app "echo"
|
||||
packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br" }
|
||||
packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.10.0/vNe6s9hWzoTZtFmNkvEICPErI9ptji_ySjicO6CkucY.tar.br" }
|
||||
imports [pf.Stdin, pf.Stdout, pf.Task.{ Task }]
|
||||
provides [main] to pf
|
||||
|
||||
main : Task {} I32
|
||||
main =
|
||||
_ <- Task.await (Stdout.line "🗣 Shout into this cave and hear the echo! 👂👂👂")
|
||||
|
||||
Task.loop {} tick
|
||||
|
||||
tick : {} -> Task [Step {}, Done {}] *
|
||||
tick : {} -> Task [Step {}, Done {}] _
|
||||
tick = \{} ->
|
||||
shout <- Task.await Stdin.line
|
||||
|
||||
when shout is
|
||||
Input s -> Stdout.line (echo s) |> Task.map Step
|
||||
End -> Stdout.line (echo "Received end of input (EOF).") |> Task.map Done
|
||||
when Stdin.line |> Task.result! is
|
||||
Ok str -> Stdout.line (echo str) |> Task.map Step
|
||||
Err (StdinErr EndOfFile) -> Stdout.line (echo "Received end of input (EOF).") |> Task.map Done
|
||||
Err (StdinErr err) -> Stdout.line (echo "Unable to read input $(Inspect.toStr err)") |> Task.map Done
|
||||
|
||||
echo : Str -> Str
|
||||
echo = \shout ->
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
app "env"
|
||||
packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br" }
|
||||
packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.10.0/vNe6s9hWzoTZtFmNkvEICPErI9ptji_ySjicO6CkucY.tar.br" }
|
||||
imports [pf.Stdout, pf.Stderr, pf.Env, pf.Task.{ Task }]
|
||||
provides [main] to pf
|
||||
|
||||
main : Task {} I32
|
||||
main =
|
||||
task =
|
||||
Env.decode "EDITOR"
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
app "file-io"
|
||||
packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br" }
|
||||
packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.10.0/vNe6s9hWzoTZtFmNkvEICPErI9ptji_ySjicO6CkucY.tar.br" }
|
||||
imports [
|
||||
pf.Stdout,
|
||||
pf.Stderr,
|
||||
pf.Task.{ Task },
|
||||
pf.File,
|
||||
pf.Path,
|
||||
|
@ -11,26 +10,23 @@ app "file-io"
|
|||
]
|
||||
provides [main] to pf
|
||||
|
||||
main : Task {} I32
|
||||
main : Task {} [Exit I32 Str]_
|
||||
main =
|
||||
path = Path.fromStr "out.txt"
|
||||
|
||||
task =
|
||||
cwd <- Env.cwd |> Task.await
|
||||
cwdStr = Path.display cwd
|
||||
|
||||
_ <- Stdout.line "cwd: $(cwdStr)" |> Task.await
|
||||
dirEntries <- Dir.list cwd |> Task.await
|
||||
cwd = Env.cwd!
|
||||
Stdout.line! "cwd: $(Path.display cwd)"
|
||||
dirEntries = Dir.list! cwd
|
||||
contentsStr = Str.joinWith (List.map dirEntries Path.display) "\n "
|
||||
Stdout.line! "Directory contents:\n $(contentsStr)\n"
|
||||
Stdout.line! "Writing a string to out.txt"
|
||||
File.writeUtf8! path "a string!"
|
||||
contents = File.readUtf8! path
|
||||
Stdout.line! "I read the file back. Its contents: \"$(contents)\""
|
||||
|
||||
_ <- Stdout.line "Directory contents:\n $(contentsStr)\n" |> Task.await
|
||||
_ <- Stdout.line "Writing a string to out.txt" |> Task.await
|
||||
_ <- File.writeUtf8 path "a string!" |> Task.await
|
||||
contents <- File.readUtf8 path |> Task.await
|
||||
Stdout.line "I read the file back. Its contents: \"$(contents)\""
|
||||
|
||||
Task.attempt task \result ->
|
||||
when result is
|
||||
Ok {} -> Stdout.line "Successfully wrote a string to out.txt"
|
||||
when Task.result! task is
|
||||
Ok {} -> Stdout.line! "Successfully wrote a string to out.txt"
|
||||
Err err ->
|
||||
msg =
|
||||
when err is
|
||||
|
@ -40,5 +36,4 @@ main =
|
|||
FileReadErr _ _ -> "Error reading file"
|
||||
_ -> "Uh oh, there was an error!"
|
||||
|
||||
{} <- Stderr.line msg |> Task.await
|
||||
Task.err 1
|
||||
Task.err (Exit 1 msg)
|
||||
|
|
|
@ -1,20 +1,12 @@
|
|||
app "form"
|
||||
packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br" }
|
||||
imports [pf.Stdin, pf.Stdout, pf.Task.{ await, Task }]
|
||||
packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.10.0/vNe6s9hWzoTZtFmNkvEICPErI9ptji_ySjicO6CkucY.tar.br" }
|
||||
imports [pf.Stdin, pf.Stdout, pf.Task]
|
||||
provides [main] to pf
|
||||
|
||||
main : Task {} I32
|
||||
main =
|
||||
_ <- await (Stdout.line "What's your first name?")
|
||||
firstName <- await Stdin.line
|
||||
Stdout.line! "What's your first name?"
|
||||
firstName = Stdin.line!
|
||||
Stdout.line! "What's your last name?"
|
||||
lastName = Stdin.line!
|
||||
|
||||
_ <- await (Stdout.line "What's your last name?")
|
||||
lastName <- await Stdin.line
|
||||
|
||||
Stdout.line "Hi, $(unwrap firstName) $(unwrap lastName)! 👋"
|
||||
|
||||
unwrap : [Input Str, End] -> Str
|
||||
unwrap = \input ->
|
||||
when input is
|
||||
Input line -> line
|
||||
End -> "Received end of input (EOF)."
|
||||
Stdout.line "Hi, $(firstName) $(lastName)! 👋"
|
||||
|
|
|
@ -1,31 +1,23 @@
|
|||
app "http-get"
|
||||
packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br" }
|
||||
imports [pf.Http, pf.Task.{ Task }, pf.Stdin, pf.Stdout]
|
||||
packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.10.0/vNe6s9hWzoTZtFmNkvEICPErI9ptji_ySjicO6CkucY.tar.br" }
|
||||
imports [pf.Http, pf.Task, pf.Stdout]
|
||||
provides [main] to pf
|
||||
|
||||
main : Task {} I32
|
||||
main =
|
||||
_ <- Task.await (Stdout.line "Enter a URL to fetch. It must contain a scheme like \"http://\" or \"https://\".")
|
||||
|
||||
input <- Task.await Stdin.line
|
||||
|
||||
when input is
|
||||
End ->
|
||||
Stdout.line "I received end-of-input (EOF) instead of a URL."
|
||||
|
||||
Input url ->
|
||||
request = {
|
||||
method: Get,
|
||||
headers: [],
|
||||
url,
|
||||
url: "http://www.example.com",
|
||||
mimeType: "",
|
||||
body: [],
|
||||
timeout: NoTimeout,
|
||||
timeout: TimeoutMilliseconds 5000,
|
||||
}
|
||||
|
||||
output <- Http.send request
|
||||
|> Task.await \resp -> resp |> Http.handleStringResponse |> Task.fromResult
|
||||
|> Task.onErr \err -> crash (Http.errorToString err)
|
||||
|> Task.await
|
||||
resp = Http.send! request
|
||||
|
||||
output =
|
||||
when resp |> Http.handleStringResponse is
|
||||
Err err -> crash (Http.errorToString err)
|
||||
Ok body -> body
|
||||
|
||||
Stdout.line output
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
app "ingested-file-bytes"
|
||||
packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br" }
|
||||
packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.10.0/vNe6s9hWzoTZtFmNkvEICPErI9ptji_ySjicO6CkucY.tar.br" }
|
||||
imports [
|
||||
pf.Stdout,
|
||||
pf.Task,
|
||||
"../../LICENSE" as license : _, # A type hole can also be used here.
|
||||
]
|
||||
provides [main] to pf
|
||||
|
@ -12,4 +13,4 @@ main =
|
|||
|> List.map Num.toU64
|
||||
|> List.sum
|
||||
|> Num.toStr
|
||||
|> Stdout.line
|
||||
|> Stdout.line!
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
app "ingested-file"
|
||||
packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br" }
|
||||
packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.10.0/vNe6s9hWzoTZtFmNkvEICPErI9ptji_ySjicO6CkucY.tar.br" }
|
||||
imports [
|
||||
pf.Stdout,
|
||||
pf.Task,
|
||||
"ingested-file.roc" as ownCode : Str,
|
||||
]
|
||||
provides [main] to pf
|
||||
|
||||
main =
|
||||
Stdout.line "\nThis roc file can print its own source code. The source is:\n\n$(ownCode)"
|
||||
Stdout.line! "\nThis roc file can print its own source code. The source is:\n\n$(ownCode)"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
app "helloWorld"
|
||||
packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br" }
|
||||
imports [pf.Stdout]
|
||||
packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.10.0/vNe6s9hWzoTZtFmNkvEICPErI9ptji_ySjicO6CkucY.tar.br" }
|
||||
imports [pf.Stdout, pf.Task]
|
||||
provides [main] to pf
|
||||
|
||||
main =
|
||||
Stdout.line "Hello, World!"
|
||||
Stdout.line! "Hello, World!"
|
||||
|
|
|
@ -2,9 +2,10 @@
|
|||
# Shows how Roc values can be logged
|
||||
#
|
||||
app "inspect-logging"
|
||||
packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br" }
|
||||
packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.10.0/vNe6s9hWzoTZtFmNkvEICPErI9ptji_ySjicO6CkucY.tar.br" }
|
||||
imports [
|
||||
pf.Stdout,
|
||||
pf.Task,
|
||||
Community,
|
||||
]
|
||||
provides [main] to pf
|
||||
|
@ -35,4 +36,4 @@ main =
|
|||
|> Community.addFriend 0 2
|
||||
|> Community.addFriend 1 2
|
||||
|> Inspect.toStr
|
||||
|> Stdout.line
|
||||
|> Stdout.line!
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
app "example"
|
||||
packages {
|
||||
cli: "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br",
|
||||
cli: "https://github.com/roc-lang/basic-cli/releases/download/0.10.0/vNe6s9hWzoTZtFmNkvEICPErI9ptji_ySjicO6CkucY.tar.br",
|
||||
parser: "https://github.com/lukewilliamboswell/roc-parser/releases/download/0.5.2/9VrPjwfQQ1QeSL3CfmWr2Pr9DESdDIXy97pwpuq84Ck.tar.br",
|
||||
}
|
||||
imports [
|
||||
cli.Stdout,
|
||||
cli.Stderr,
|
||||
cli.Task,
|
||||
parser.Core.{ Parser, buildPrimitiveParser, many },
|
||||
parser.String.{ parseStr },
|
||||
]
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
app "example"
|
||||
packages {
|
||||
pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br",
|
||||
pf: "https://github.com/roc-lang/basic-cli/releases/download/0.10.0/vNe6s9hWzoTZtFmNkvEICPErI9ptji_ySjicO6CkucY.tar.br",
|
||||
parser: "https://github.com/lukewilliamboswell/roc-parser/releases/download/0.5.2/9VrPjwfQQ1QeSL3CfmWr2Pr9DESdDIXy97pwpuq84Ck.tar.br",
|
||||
}
|
||||
imports [
|
||||
pf.Stdout,
|
||||
pf.Stderr,
|
||||
pf.Task.{ Task },
|
||||
pf.Task,
|
||||
parser.Core.{ Parser, map, keep },
|
||||
parser.String.{ strFromUtf8 },
|
||||
parser.CSV.{ CSV },
|
||||
|
@ -16,7 +16,6 @@ app "example"
|
|||
input : Str
|
||||
input = "Airplane!,1980,\"Robert Hays,Julie Hagerty\"\r\nCaddyshack,1980,\"Chevy Chase,Rodney Dangerfield,Ted Knight,Michael O'Keefe,Bill Murray\""
|
||||
|
||||
main : Task {} *
|
||||
main =
|
||||
when CSV.parseStr movieInfoParser input is
|
||||
Ok movies ->
|
||||
|
|
|
@ -70,9 +70,3 @@ These are planned changes to how things work, which should be backwards-compatib
|
|||
This doesn't come up a lot, but [the feature](https://github.com/roc-lang/roc/issues/5504) basically means you can match on some tags in a `when`, and then have an `other ->` branch which has the tags you already matched on removed from the union. That means if you later do another `when` on the `other` value, you won't have to match on (or use `_ ->` to ignore) the tags you already matched in the first `when`, like you do today.
|
||||
|
||||
This is planned but nobody is currently working on it. It's a quality of life improvement but doesn't unblock anything; today you can just add a `_ ->` branch to the inner `when`, which is undesirable but not a blocker.
|
||||
|
||||
### [`Inspect` Inference](#inspect-inference) {#inspect-inference}
|
||||
|
||||
When this lands, all Roc types will have a default `implements Inspect`, which you can override if desired. `dbg` will use it to display things, which in turn means you'll be able to customize `dbg` output. Also it will mean you can do things like turning any Roc type into a string and writing it to a log file.
|
||||
|
||||
Note that in this design, functions will have an `Inspect` implementation which essentially renders them as `"<function>"` with no other information, and opaque types will be `"<opaque>"` by default unless you customize them. This is important because neither functions nor opaque types should expose their internal details, so that you can safely refactor them without causing regressions in distant parts of the code base because something depended on an internal implementation detail.
|
||||
|
|
|
@ -8,8 +8,8 @@ Here is a Roc application that prints `"Hello, World!"` to the command line:
|
|||
|
||||
```roc
|
||||
app "hello"
|
||||
packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br" }
|
||||
imports [pf.Stdout]
|
||||
packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.10.0/vNe6s9hWzoTZtFmNkvEICPErI9ptji_ySjicO6CkucY.tar.br" }
|
||||
imports [pf.Stdout, pf.Task]
|
||||
provides [main] to pf
|
||||
|
||||
main =
|
||||
|
|
|
@ -155,8 +155,8 @@ Make a file named `main.roc` and put this in it:
|
|||
|
||||
```roc
|
||||
app "hello"
|
||||
packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br" }
|
||||
imports [pf.Stdout]
|
||||
packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.10.0/vNe6s9hWzoTZtFmNkvEICPErI9ptji_ySjicO6CkucY.tar.br" }
|
||||
imports [pf.Stdout, pf.Task]
|
||||
provides [main] to pf
|
||||
|
||||
main =
|
||||
|
@ -1455,7 +1455,7 @@ Let's take a closer look at the part of `main.roc` above the `main` def:
|
|||
|
||||
```roc
|
||||
app "hello"
|
||||
packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br" }
|
||||
packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.10.0/vNe6s9hWzoTZtFmNkvEICPErI9ptji_ySjicO6CkucY.tar.br" }
|
||||
imports [pf.Stdout]
|
||||
provides [main] to pf
|
||||
```
|
||||
|
@ -1467,7 +1467,7 @@ The line `app "hello"` shows that this module is a Roc application. The "hello"
|
|||
The remaining lines all involve the [platform](https://github.com/roc-lang/roc/wiki/Roc-concepts-explained#platform) this application is built on:
|
||||
|
||||
```roc
|
||||
packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br" }
|
||||
packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.10.0/vNe6s9hWzoTZtFmNkvEICPErI9ptji_ySjicO6CkucY.tar.br" }
|
||||
imports [pf.Stdout]
|
||||
provides [main] to pf
|
||||
```
|
||||
|
@ -1566,7 +1566,7 @@ Let's start with a basic "Hello World" program.
|
|||
|
||||
```roc
|
||||
app "cli-tutorial"
|
||||
packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br" }
|
||||
packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.10.0/vNe6s9hWzoTZtFmNkvEICPErI9ptji_ySjicO6CkucY.tar.br" }
|
||||
imports [pf.Stdout]
|
||||
provides [main] to pf
|
||||
|
||||
|
@ -1600,7 +1600,7 @@ Let's change `main` to read a line from `stdin`, and then print what we got:
|
|||
|
||||
```roc
|
||||
app "cli-tutorial"
|
||||
packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.9.1/y_Ww7a2_ZGjp0ZTt9Y_pNdSqqMRdMLzHMKfdN8LWidk.tar.br" }
|
||||
packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.10.0/vNe6s9hWzoTZtFmNkvEICPErI9ptji_ySjicO6CkucY.tar.br" }
|
||||
imports [pf.Stdout, pf.Stdin, pf.Task]
|
||||
provides [main] to pf
|
||||
|
||||
|
@ -1630,7 +1630,7 @@ high-quality programs handle errors gracefully. Fortunately, we can do this nice
|
|||
If we wanted to add the type annotation to `main` that Roc is inferring for it, we would add this annotation:
|
||||
|
||||
```roc
|
||||
main : Task {} [Exit I32, StdoutErr Stdout.Err, StinErr Stdin.Err]
|
||||
main : Task {} [Exit I32, StdoutErr Stdout.Err, StdinErr Stdin.Err]
|
||||
main =
|
||||
```
|
||||
|
||||
|
@ -1638,7 +1638,7 @@ Let's break down what this type is saying:
|
|||
|
||||
- `Task` tells us this is a `Task` type. Its two type parameters are just like the ones we saw in `Result` earlier: the first type tells us what this task will produce if it succeeds, and the other one tells us what it will produce if it fails.
|
||||
- `{}` tells us that this task always produces an empty record when it succeeds. (That is, it doesn't produce anything useful. Empty records don't have any information in them!) This is because the last task in `main` comes from `Stdout.line`, which doesn't produce anything. (In contrast, the `Stdin` task's first type parameter is a `Str`, because it produces a `Str` if it succeeds.)
|
||||
- `[Exit I32, StdoutErr Stdout.Err, StinErr Stdin.Err]` tells us the different ways this task can fail. The `StdoutErr` and `StdinErr` tags are there becase we used `Stdout.line` and `Stdin.line`. We'll talk about `Exit I32` more in a moment.
|
||||
- `[Exit I32, StdoutErr Stdout.Err, StdinErr Stdin.Err]` tells us the different ways this task can fail. The `StdoutErr` and `StdinErr` tags are there becase we used `Stdout.line` and `Stdin.line`. We'll talk about `Exit I32` more in a moment.
|
||||
|
||||
To understand what the `Exit I32 Str` error means, let's try temporarily commenting out our current `main` and replacing
|
||||
it with this one:
|
||||
|
@ -1666,7 +1666,7 @@ In summary:
|
|||
|
||||
### [Handling task failures](#handling-task-failures) {#handling-task-failures}
|
||||
|
||||
If the `main` task ends up failing with any other errors besides `Exit` (such as `StdoutErr` or `StdinErr`), then the `basic-cli` platform's automatic error handling will handle them by printing out words taken from the source code (such as "StdoutErr" and "StinErr"), which could lead to a bad experience for people using this program!
|
||||
If the `main` task ends up failing with any other errors besides `Exit` (such as `StdoutErr` or `StdinErr`), then the `basic-cli` platform's automatic error handling will handle them by printing out words taken from the source code (such as "StdoutErr" and "StdinErr"), which could lead to a bad experience for people using this program!
|
||||
|
||||
We can prevent that by gracefully handling the other error types, and then translating them into `Exit` errors so that they affect the program's exit code and don't result in the platform printing anything. A convenient way to make sure we've handled all the other errors is to keep our current type annotation for `main` but restore our old implementation:
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
--header-link-color: #1bbcb3;
|
||||
--header-link-hover: #222;
|
||||
--h1-color: #8055e4;
|
||||
--tutorial-h3-color: #8c5ce3; /* Slightly darker than --primary-1, which looks washed-out in <h3>s */
|
||||
}
|
||||
|
||||
html {
|
||||
|
@ -167,7 +168,7 @@ hr {
|
|||
}
|
||||
|
||||
#sponsor-logos .logo-decem .cls-1 {
|
||||
fill:#04021e;
|
||||
fill: #04021e;
|
||||
}
|
||||
|
||||
#sponsor-logos + p {
|
||||
|
@ -731,7 +732,8 @@ li {
|
|||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: url("/fonts/permanent-marker-v16-latin/permanent-marker-v16-latin-regular.woff2")
|
||||
src:
|
||||
url("/fonts/permanent-marker-v16-latin/permanent-marker-v16-latin-regular.woff2")
|
||||
format("woff2"),
|
||||
url("/fonts/permanent-marker-v16-latin/permanent-marker-v16-latin-regular.woff")
|
||||
format("woff");
|
||||
|
@ -746,7 +748,8 @@ li {
|
|||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: url("/fonts/lato-v23-latin-ext_latin/lato-v23-latin-ext_latin-regular.woff2")
|
||||
src:
|
||||
url("/fonts/lato-v23-latin-ext_latin/lato-v23-latin-ext_latin-regular.woff2")
|
||||
format("woff2"),
|
||||
url("/fonts/lato-v23-latin-ext_latin/lato-v23-latin-ext_latin-regular.woff")
|
||||
format("woff");
|
||||
|
@ -760,7 +763,8 @@ li {
|
|||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: url("/fonts/lato-v23-latin/lato-v23-latin-regular.woff2")
|
||||
src:
|
||||
url("/fonts/lato-v23-latin/lato-v23-latin-regular.woff2")
|
||||
format("woff2"),
|
||||
url("/fonts/lato-v23-latin/lato-v23-latin-regular.woff") format("woff");
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
|
||||
|
@ -774,7 +778,8 @@ li {
|
|||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: url("/fonts/source-code-pro-v22-latin-ext_latin/source-code-pro-v22-latin-ext_latin-regular.woff2")
|
||||
src:
|
||||
url("/fonts/source-code-pro-v22-latin-ext_latin/source-code-pro-v22-latin-ext_latin-regular.woff2")
|
||||
format("woff2"),
|
||||
url("/fonts/source-code-pro-v22-latin-ext_latin/source-code-pro-v22-latin-ext_latin-regular.woff")
|
||||
format("woff");
|
||||
|
@ -788,7 +793,8 @@ li {
|
|||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: url("/fonts/source-code-pro-v22-latin/source-code-pro-v22-latin-regular.woff2")
|
||||
src:
|
||||
url("/fonts/source-code-pro-v22-latin/source-code-pro-v22-latin-regular.woff2")
|
||||
format("woff2"),
|
||||
url("/fonts/source-code-pro-v22-latin/source-code-pro-v22-latin-regular.woff")
|
||||
format("woff");
|
||||
|
@ -825,6 +831,7 @@ li {
|
|||
--header-link-color: #9c7cea;
|
||||
--header-link-hover: #ddd;
|
||||
--h1-color: #1bc6bd;
|
||||
--tutorial-h3-color: var(--primary-1);
|
||||
}
|
||||
|
||||
.logo-dark {
|
||||
|
@ -1137,7 +1144,8 @@ code .dim {
|
|||
color: #7c38f5;
|
||||
}
|
||||
|
||||
.interactive-desc code, .interactive-desc pre {
|
||||
.interactive-desc code,
|
||||
.interactive-desc pre {
|
||||
background: none;
|
||||
color: inherit;
|
||||
}
|
||||
|
@ -1201,9 +1209,12 @@ code .dim {
|
|||
border: none;
|
||||
}
|
||||
|
||||
#tutorial-main h3 a {
|
||||
color: var(--tutorial-h3-color);
|
||||
}
|
||||
|
||||
#tutorial-main h1 a,
|
||||
#tutorial-main h2 a,
|
||||
#tutorial-main h3 a,
|
||||
#tutorial-main h4 a,
|
||||
#tutorial-main h5 a {
|
||||
color: var(--header-link-color);
|
||||
|
@ -1240,7 +1251,7 @@ code .dim {
|
|||
font-family: inherit;
|
||||
font-size: 1.65rem;
|
||||
line-height: 3rem;
|
||||
text-shadow: 1px 1px 1px #010101;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
#tutorial-main h4 {
|
||||
|
@ -1364,12 +1375,14 @@ code .dim {
|
|||
font-size: 18px;
|
||||
}
|
||||
|
||||
#homepage-repl-container #repl-prompt, #homepage-repl-container .input-line-prefix {
|
||||
#homepage-repl-container #repl-prompt,
|
||||
#homepage-repl-container .input-line-prefix {
|
||||
top: 1.25rem;
|
||||
color: var(--light-cyan);
|
||||
}
|
||||
|
||||
.input-line-prefix, #repl-prompt {
|
||||
.input-line-prefix,
|
||||
#repl-prompt {
|
||||
color: var(--cyan);
|
||||
color: var(--primary-2);
|
||||
}
|
||||
|
@ -1481,7 +1494,7 @@ code .dim {
|
|||
in a light color scheme, and only white in dark mode. The name could be better!
|
||||
*/
|
||||
#homepage-repl-container .color-white {
|
||||
color: #FFF;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
#repl-container .color-white {
|
||||
|
@ -1489,15 +1502,13 @@ code .dim {
|
|||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
|
||||
#homepage-repl-container .color-white {
|
||||
color: #FFF;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
#repl-container .color-white {
|
||||
color: #FFF;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.bold {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue