Skip to content

Commit b1f3ce5

Browse files
migrate Env and File effects, examples and tests
1 parent 6ba1155 commit b1f3ce5

13 files changed

Lines changed: 416 additions & 98 deletions

File tree

.gitignore

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,8 @@ ci/check_cargo_versions_match
7676
# build script artifacts
7777
build
7878

79-
# Platform prebuilt binaries - these SHOULD be tracked
80-
# The platform/targets/ directory contains prebuilt static libraries
81-
# that need to be committed for distribution
82-
!platform/targets/
79+
# Platform host libraries (we manually add things to track like crt1.o, libc.a, libunwind.a)
80+
platform/targets/*/libhost.a
8381

8482
# Cargo lock for reproducible builds
8583
!Cargo.lock

ci/expect_scripts/env-test.exp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#!/usr/bin/expect
2+
3+
# uncomment line below for debugging
4+
# exp_internal 1
5+
6+
set timeout 7
7+
8+
source ./ci/expect_scripts/shared-code.exp
9+
10+
set env(EDITOR) vim
11+
12+
spawn $env(EXAMPLES_DIR)env-test
13+
14+
expect "Your editor is: vim\r\n" {
15+
expect -re "Current directory: .+\r\n" {
16+
expect -re "Executable: .+\r\n" {
17+
expect eof {
18+
check_exit_and_segfault
19+
}
20+
}
21+
}
22+
}
23+
24+
puts stderr "\nExpect script failed: output was different from expected value. uncomment `exp_internal 1` to debug."
25+
exit 1

ci/expect_scripts/file-test.exp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#!/usr/bin/expect
2+
3+
# uncomment line below for debugging
4+
# exp_internal 1
5+
6+
set timeout 7
7+
8+
source ./ci/expect_scripts/shared-code.exp
9+
10+
spawn $env(EXAMPLES_DIR)file-test
11+
12+
expect "Read: Hello, Roc!\r\n" {
13+
expect "Bytes: 5\r\n" {
14+
expect "Cleaned up!\r\n" {
15+
expect eof {
16+
check_exit_and_segfault
17+
}
18+
}
19+
}
20+
}
21+
22+
puts stderr "\nExpect script failed: output was different from expected value. uncomment `exp_internal 1` to debug."
23+
exit 1

examples/env-test.roc

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
app [main!] { pf: platform "../platform/main.roc" }
2+
3+
import pf.Env
4+
import pf.Stdout
5+
6+
main! : List(Str) => Try({}, [Exit(I32)])
7+
main! = |_args| {
8+
editor = Env.var!("EDITOR")
9+
Stdout.line!("Your editor is: ${editor}")
10+
11+
cwd = Env.cwd!({})
12+
Stdout.line!("Current directory: ${cwd}")
13+
14+
exe = Env.exe_path!({})
15+
Stdout.line!("Executable: ${exe}")
16+
17+
Ok({})
18+
}

examples/file-test.roc

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
app [main!] { pf: platform "../platform/main.roc" }
2+
3+
import pf.File
4+
import pf.Stdout
5+
6+
main! : List(Str) => Try({}, [Exit(I32)])
7+
main! = |_args| {
8+
# Test write and read UTF-8
9+
File.write_utf8!("test-file.txt", "Hello, Roc!")
10+
content = File.read_utf8!("test-file.txt")
11+
Stdout.line!("Read: ${content}")
12+
13+
# Test write and read bytes
14+
File.write_bytes!("test-bytes.bin", [1, 2, 3, 4, 5])
15+
bytes = File.read_bytes!("test-bytes.bin")
16+
Stdout.line!("Bytes: ${bytes.len().to_str()}")
17+
18+
# Clean up
19+
File.delete!("test-file.txt")
20+
File.delete!("test-bytes.bin")
21+
Stdout.line!("Cleaned up!")
22+
23+
Ok({})
24+
}

examples/hello-world.roc

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
app [main!] { pf: platform "../platform/main.roc" }
22

33
import pf.Stdout
4-
import pf.Arg exposing [Arg]
54

6-
# To run this example: check the README.md in this folder
7-
8-
main! : List Arg => Result {} _
9-
main! = |_args|
5+
main! : List(Str) => Try({}, [Exit(I32)])
6+
main! = |_args| {
107
Stdout.line!("Hello, World!")
8+
Ok({})
9+
}

examples/stdin-basic.roc

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,15 @@ app [main!] { pf: platform "../platform/main.roc" }
22

33
import pf.Stdin
44
import pf.Stdout
5-
import pf.Arg exposing [Arg]
65

7-
# To run this example: check the README.md in this folder
6+
main! : List(Str) => Try({}, [Exit(I32)])
7+
main! = |_args| {
8+
Stdout.line!("What's your first name?")
9+
first = Stdin.line!({})
810
9-
# Reading text from stdin.
10-
# If you want to read Stdin from a pipe, check out examples/stdin-pipe.roc
11+
Stdout.line!("What's your last name?")
12+
last = Stdin.line!({})
1113
12-
main! : List Arg => Result {} _
13-
main! = |_args|
14-
15-
Stdout.line!("What's your first name?")?
16-
17-
first = Stdin.line!({})?
18-
19-
Stdout.line!("What's your last name?")?
20-
21-
last = Stdin.line!({})?
22-
23-
Stdout.line!("Hi, ${first} ${last}! 👋")
14+
Stdout.line!("Hi, ${first} ${last}! \u(1F44B)")
15+
Ok({})
16+
}

platform/Env.roc

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
Env := [].{
2+
## Reads the given environment variable.
3+
##
4+
## If the value is invalid Unicode, the invalid parts will be replaced with the
5+
## [Unicode replacement character](https://unicode.org/glossary/#replacement_character).
6+
##
7+
## Returns an empty string if the variable is not found.
8+
var! : Str => Str
9+
10+
## Reads the [current working directory](https://en.wikipedia.org/wiki/Working_directory)
11+
## from the environment.
12+
##
13+
## Returns an empty string if the cwd is unavailable.
14+
cwd! : {} => Str
15+
16+
## Gets the path to the currently-running executable.
17+
##
18+
## Returns an empty string if the path is unavailable.
19+
exe_path! : {} => Str
20+
}

platform/File.roc

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
File := [].{
2+
## **NotFound** - An entity was not found, often a file.
3+
##
4+
## **PermissionDenied** - The operation lacked the necessary privileges to complete.
5+
##
6+
## **BrokenPipe** - The operation failed because a pipe was closed.
7+
##
8+
## **AlreadyExists** - An entity already exists, often a file.
9+
##
10+
## **Interrupted** - This operation was interrupted. Interrupted operations can typically be retried.
11+
##
12+
## **Unsupported** - This operation is unsupported on this platform. This means that the operation can never succeed.
13+
##
14+
## **OutOfMemory** - An operation could not be completed, because it failed to allocate enough memory.
15+
##
16+
## **Other** - A custom error that does not fall under any other I/O error kind.
17+
IOErr := [
18+
NotFound,
19+
PermissionDenied,
20+
BrokenPipe,
21+
AlreadyExists,
22+
Interrupted,
23+
Unsupported,
24+
OutOfMemory,
25+
Other(Str),
26+
]
27+
28+
## Read all bytes from a file.
29+
read_bytes! : Str => List(U8)
30+
31+
## Write bytes to a file, replacing any existing contents.
32+
write_bytes! : Str, List(U8) => {}
33+
34+
## Read a file's contents as a UTF-8 string.
35+
##
36+
## If the file contains invalid UTF-8, the invalid parts will be replaced with the
37+
## [Unicode replacement character](https://unicode.org/glossary/#replacement_character).
38+
read_utf8! : Str => Str
39+
40+
## Write a UTF-8 string to a file, replacing any existing contents.
41+
write_utf8! : Str, Str => {}
42+
43+
## Delete a file.
44+
delete! : Str => {}
45+
}

platform/Stdin.roc

Lines changed: 47 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,47 @@
1-
# Stdin := [].{
2-
# ## **NotFound** - An entity was not found, often a file.
3-
# ##
4-
# ## **PermissionDenied** - The operation lacked the necessary privileges to complete.
5-
# ##
6-
# ## **BrokenPipe** - The operation failed because a pipe was closed.
7-
# ##
8-
# ## **AlreadyExists** - An entity already exists, often a file.
9-
# ##
10-
# ## **Interrupted** - This operation was interrupted. Interrupted operations can typically be retried.
11-
# ##
12-
# ## **Unsupported** - This operation is unsupported on this platform. This means that the operation can never succeed.
13-
# ##
14-
# ## **OutOfMemory** - An operation could not be completed, because it failed to allocate enough memory.
15-
# ##
16-
# ## **Other** - A custom error that does not fall under any other I/O error kind.
17-
# IOErr := [
18-
# NotFound,
19-
# PermissionDenied,
20-
# BrokenPipe,
21-
# AlreadyExists,
22-
# Interrupted,
23-
# Unsupported,
24-
# OutOfMemory,
25-
# Other(Str),
26-
# ]
27-
#
28-
# ## Read a line from [standard input](https://en.wikipedia.org/wiki/Standard_streams#Standard_input_(stdin)).
29-
# ##
30-
# ## > This task will block the program from continuing until `stdin` receives a newline character
31-
# ## (e.g. because the user pressed Enter in the terminal), so using it can result in the appearance of the
32-
# ## programming having gotten stuck. It's often helpful to print a prompt first, so
33-
# ## the user knows it's necessary to enter something before the program will continue.
34-
# line! : () => Str
35-
#
36-
# ## Read bytes from [standard input](https://en.wikipedia.org/wiki/Standard_streams#Standard_input_(stdin)).
37-
# ## This function can read no more than 16,384 bytes at a time. Use [read_to_end!] if you need more.
38-
# ##
39-
# ## > This is typically used in combintation with [Tty.enable_raw_mode!],
40-
# ## which disables defaults terminal bevahiour and allows reading input
41-
# ## without buffering until Enter key is pressed.
42-
# bytes! : () => List(U8)
43-
#
44-
# ## Read all bytes from [standard input](https://en.wikipedia.org/wiki/Standard_streams#Standard_input_(stdin))
45-
# ## until [EOF](https://en.wikipedia.org/wiki/End-of-file) in this source.
46-
# read_to_end! : () => List(U8)
47-
# }
1+
Stdin := [].{
2+
## **NotFound** - An entity was not found, often a file.
3+
##
4+
## **PermissionDenied** - The operation lacked the necessary privileges to complete.
5+
##
6+
## **BrokenPipe** - The operation failed because a pipe was closed.
7+
##
8+
## **AlreadyExists** - An entity already exists, often a file.
9+
##
10+
## **Interrupted** - This operation was interrupted. Interrupted operations can typically be retried.
11+
##
12+
## **Unsupported** - This operation is unsupported on this platform. This means that the operation can never succeed.
13+
##
14+
## **OutOfMemory** - An operation could not be completed, because it failed to allocate enough memory.
15+
##
16+
## **Other** - A custom error that does not fall under any other I/O error kind.
17+
IOErr := [
18+
NotFound,
19+
PermissionDenied,
20+
BrokenPipe,
21+
AlreadyExists,
22+
Interrupted,
23+
Unsupported,
24+
OutOfMemory,
25+
Other(Str),
26+
]
27+
28+
## Read a line from [standard input](https://en.wikipedia.org/wiki/Standard_streams#Standard_input_(stdin)).
29+
##
30+
## > This task will block the program from continuing until `stdin` receives a newline character
31+
## (e.g. because the user pressed Enter in the terminal), so using it can result in the appearance of the
32+
## program having gotten stuck. It's often helpful to print a prompt first, so
33+
## the user knows it's necessary to enter something before the program will continue.
34+
line! : {} => Str
35+
36+
# ## Read bytes from [standard input](https://en.wikipedia.org/wiki/Standard_streams#Standard_input_(stdin)).
37+
# ## This function can read no more than 16,384 bytes at a time. Use [read_to_end!] if you need more.
38+
# ##
39+
# ## > This is typically used in combintation with [Tty.enable_raw_mode!],
40+
# ## which disables defaults terminal bevahiour and allows reading input
41+
# ## without buffering until Enter key is pressed.
42+
# bytes! : {} => List(U8)
43+
44+
# ## Read all bytes from [standard input](https://en.wikipedia.org/wiki/Standard_streams#Standard_input_(stdin))
45+
# ## until [EOF](https://en.wikipedia.org/wiki/End-of-file) in this source.
46+
# read_to_end! : {} => List(U8)
47+
}

0 commit comments

Comments
 (0)