Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Towards a full-blown builtins DSL (part 3) #3471

Merged
merged 20 commits into from
Jun 13, 2022
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@
builtins from method signatures][3454]
- [Avoid needless concatenations of warning/error messages][3465]
- [Lazy evaluation of RHS argument for || and &&][3492]
- [Towards full-blown DSL for builtins][3471]

[3227]: https://github.com/enso-org/enso/pull/3227
[3248]: https://github.com/enso-org/enso/pull/3248
Expand All @@ -252,6 +253,7 @@
[3454]: https://github.com/enso-org/enso/pull/3454
[3461]: https://github.com/enso-org/enso/pull/3461
[3465]: https://github.com/enso-org/enso/pull/3465
[3471]: https://github.com/enso-org/enso/pull/3471
[3492]: https://github.com/enso-org/enso/pull/3492
[3493]: https://github.com/enso-org/enso/pull/3493
[3505]: https://github.com/enso-org/enso/pull/3505
Expand Down
3 changes: 2 additions & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -991,7 +991,8 @@ lazy val `interpreter-dsl` = (project in file("lib/scala/interpreter-dsl"))
Seq("-processor", "org.netbeans.modules.openide.util.ServiceProviderProcessor")),
libraryDependencies ++= Seq(
"org.apache.commons" % "commons-lang3" % commonsLangVersion,
"org.netbeans.api" % "org-openide-util-lookup" % "RELEASE130"
"org.netbeans.api" % "org-openide-util-lookup" % "RELEASE130",
"com.google.guava" % "guava" % guavaVersion exclude ("com.google.code.findbugs", "jsr305"),
)
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@

Forces flattening of a text value.
optimize : Text
optimize = @Builtin_Method "Prim_Text_Helpers.optimize"
optimize = @Builtin_Method "Prim_Text_Helper.optimize"
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ type Project_Description

Enso_Project.root
root : File.File
root = File.new this.prim_root_file.getPath
root = File.new this.prim_root_file

## Returns the root data directory of the project.

Expand Down
2 changes: 1 addition & 1 deletion distribution/lib/Standard/Base/0.0.0-dev/src/System.enso
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ create_process command arguments input redirect_in redirect_out redirect_err = @
- code: The numerical exit code for the Enso program.

> Example
Exit the enso program with a failure.
Exit the Enso program with a failure.

System.exit 42
exit : Integer -> Nothing
Expand Down
146 changes: 79 additions & 67 deletions distribution/lib/Standard/Base/0.0.0-dev/src/System/File.enso
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,12 @@ polyglot java import java.nio.file.Path

example_new = File.new Examples.csv_path
new : (Text | File) -> File
new path = case path of
Text -> File (here.get_file path)
_ -> path
new path =
file = case path of
Text -> here.get_file path
File -> path
_ -> Error.throw (Illegal_Argument_Error "new file should be either a File or a Text")
file
hubertp marked this conversation as resolved.
Show resolved Hide resolved

## Open and reads all bytes in the file at the provided `path` into a byte vector.

Expand All @@ -50,10 +53,7 @@ new path = case path of
example_read_bytes = File.read_bytes Examples.csv
read_bytes : (Text | File) -> Vector.Vector ! File_Error
read_bytes path =
file = case path of
Text -> (here.new path)
File _ -> path
_ -> Error.throw (Illegal_Argument_Error "path should be either a File or a Text")
file = here.new path
file.read_bytes

## Open and read the file at the provided `path`.
Expand Down Expand Up @@ -83,10 +83,7 @@ read_bytes path =
example_read = File.read_text Examples.csv_path
read_text : (Text | File) -> Encoding -> Problem_Behavior -> Text
read_text path (encoding=Encoding.utf_8) (on_problems=Report_Warning) =
file = case path of
Text -> (here.new path)
File _ -> path
_ -> Error.throw (Illegal_Argument_Error "path should be either a File or a Text")
file = here.new path
file.read_text encoding on_problems

## ALIAS Write Text File
Expand All @@ -113,10 +110,7 @@ read_text path (encoding=Encoding.utf_8) (on_problems=Report_Warning) =
example_read = File.read_text Examples.csv_path
write_text : (Text | File) -> Text -> Encoding -> Text
write_text path contents (encoding=Encoding.utf_8) =
file = case path of
Text -> (here.new path)
File _ -> path
_ -> Error.throw (Illegal_Argument_Error "path should be either a File or a Text")
file = here.new path
file.write_text contents encoding

## ALIAS Current Directory
Expand All @@ -130,7 +124,7 @@ write_text path contents (encoding=Encoding.utf_8) =

example_cwd = File.current_directory
current_directory : File
current_directory = File (here.get_cwd)
current_directory = here.get_cwd

## ALIAS Home Directory

Expand All @@ -143,7 +137,7 @@ current_directory = File (here.get_cwd)

example_home = File.home
home : File
home = here.new (here.get_user_home)
home = @Builtin_Method "File.home"

## Lists files contained in the provided directory.

Expand Down Expand Up @@ -204,10 +198,8 @@ type File
## PRIVATE

A type representing a file.

Arguments:
- prim_file: The internal representation of the file.
type File prim_file
@Builtin_Type
type File

## Creates a new output stream for this file and runs the specified action
on it.
Expand Down Expand Up @@ -235,6 +227,28 @@ type File
with_output_stream open_options action =
Resource.bracket (this.new_output_stream open_options) (_.close) action

## PRIVATE

## Creates a new output stream for this file. Recommended to use
`File.with_output_stream` instead, which does resource management.

Arguments:
- options: A vector of `File.Option` objects determining how to open
the stream. These options set the access properties of the stream.
output_stream : Vector.Vector -> Output_Stream
output_stream options = @Builtin_Method "File.output_stream"

JaroslavTulach marked this conversation as resolved.
Show resolved Hide resolved
## PRIVATE

## Creates a new input stream for this file. Recommended to use
`File.with_input_stream` instead, which does resource management.

Arguments:
- open_options: A vector of `File.Option` objects determining how to open
the stream. These options set the access properties of the stream.
input_stream : Vector.Vector -> Input_Stream
input_stream options = @Builtin_Method "File.input_stream"

## Creates a new input stream for this file and runs the specified action
on it.

Expand Down Expand Up @@ -377,20 +391,10 @@ type File

example_append = Examples.data_dir / "scratch_file"
/ : (Text | File) -> File
/ subpath = case subpath of
File prim -> File (this.prim_file.resolve prim)
_ -> File (this.prim_file.resolve subpath)
/ subpath = this.resolve subpath

## A text representation of this file.

> Example
Get a textual representation of a file.

import Standard.Examples

example_to_text = Examples.csv.to_text
to_text : Text
to_text = this.prim_file.to_text
resolve : (Text | File) -> File
resolve = @Builtin_Method "File.resolve"

## A File to JSON conversion.

Expand All @@ -412,7 +416,7 @@ type File

example_exists = Examples.csv.exists
exists : Boolean
exists = this.prim_file.exists
exists = @Builtin_Method "File.exists"

## Checks whether the file exists and is a directory.

Expand All @@ -423,7 +427,7 @@ type File

example_is_directory = Examples.csv.is_directory
is_directory : Boolean
is_directory = this.prim_file.isDirectory
is_directory = @Builtin_Method "File.is_directory"

## Creates the directory represented by this file if it did not exist.

Expand All @@ -437,7 +441,7 @@ type File
example_is_directory =
(Examples.data_dir / "my_directory") . create_directory
create_directory : Nothing
create_directory = this.prim_file.createDirectories
create_directory = @Builtin_Method "File.create_directory"

## Checks whether the file exists and is a regular file.

Expand All @@ -453,7 +457,7 @@ type File

example_is_regular_file = Examples.csv.is_regular_file
is_regular_file : Boolean
is_regular_file = this.prim_file.isRegularFile
is_regular_file = @Builtin_Method "File.is_regular_file"

## Resolves the parent filesystem node of this file.

Expand All @@ -464,7 +468,7 @@ type File

example_parent = Examples.csv.parent
parent : File
parent = File this.prim_file.getParent
parent = @Builtin_Method "File.parent"

## Returns the path of this file.

Expand All @@ -475,7 +479,7 @@ type File

example_path = Examples.csv.path
path : Text
path = this.prim_file.getPath
path = @Builtin_Method "File.path"

## Returns the name of this file.

Expand All @@ -486,7 +490,7 @@ type File

example_name = Examples.csv.name
name : Text
name = this.prim_file.getName
name = @Builtin_Method "File.name"

## Returns the extension of the file.

Expand Down Expand Up @@ -514,7 +518,7 @@ type File

example_absolute = Examples.csv.absolute
absolute : File
absolute = File this.prim_file.getAbsoluteFile
absolute = @Builtin_Method "File.absolute"

## Checks is this file's path is absolute.

Expand All @@ -525,7 +529,7 @@ type File

example_is_absolute = Examples.csv.is_absolute
is_absolute : Boolean
is_absolute = this.prim_file.isAbsolute
is_absolute = @Builtin_Method "File.is_absolute"

## Normalizes the filepath.

Expand All @@ -536,7 +540,7 @@ type File

example_normalize = Examples.csv.normalize
normalize : File
normalize = File this.prim_file.normalize
normalize = @Builtin_Method "File.normalize"

## Checks if this file has the same `path` as `that`.

Expand All @@ -547,7 +551,7 @@ type File

example_eq = Examples.csv == Examples.scratch_file
== : File -> Boolean
== that = this.prim_file.isEqual that.prim_file
== that = @Builtin_Method "File.=="

## Deletes the file.

Expand All @@ -565,7 +569,14 @@ type File
file.delete
delete : Nothing ! File_Error
delete =
here.handle_java_exceptions this this.prim_file.delete
here.handle_java_exceptions this this.delete_builtin

## PRIVATE

Builtin method that deletes the file.
Recommended to use `File.delete` instead which handles potential exceptions.
delete_builtin : Nothing
delete_builtin = @Builtin_Method "File.delete"

## Deletes the file if it exists on disk.

Expand Down Expand Up @@ -594,7 +605,7 @@ type File
new_input_stream : Vector.Vector -> Input_Stream ! File_Error
new_input_stream open_options =
opts = open_options . map (_.to_java) . to_array
stream = here.handle_java_exceptions this (this.prim_file.newInputStream opts)
stream = here.handle_java_exceptions this (this.input_stream opts)
resource = Managed_Resource.register stream here.close_stream
Input_Stream this resource

Expand All @@ -612,7 +623,7 @@ type File
new_output_stream open_options =
opts = open_options . map (_.to_java) . to_array
stream = here.handle_java_exceptions this <|
this.prim_file.newOutputStream opts
this.output_stream opts
resource = Managed_Resource.register stream here.close_stream
Output_Stream this resource

Expand Down Expand Up @@ -672,26 +683,41 @@ type File
list name_filter=Nothing recursive=False =
all_files = case recursive of
True -> here.list_descendants this
False -> here.list_immediate_children this
False -> Vector.Vector (this.list_immediate_children)
filtered = case name_filter of
Nothing -> all_files
_ ->
fs = FileSystems.getDefault
matcher = fs.getPathMatcher "glob:"+name_filter
all_files.filter file->
pathStr = this.prim_file.relativize file.prim_file . getPath
pathStr = this.relativize file . path
matcher.matches (Path.of pathStr)
filtered

## UNSTABLE

Checks if `this` is a child path of `other`.
is_child_of other = this.prim_file.startsWith other.prim_file
is_child_of : File -> Boolean
is_child_of other = this.starts_with other

## UNSTABLE

Transforms `child` to a relative path with respect to `this`.
relativize child = File (this.prim_file.relativize child.prim_file)
relativize : File -> Boolean
relativize child = @Builtin_Method "File.relativize"


## PRIVATE

Utility function that lists immediate children of a directory.
list_immediate_children : File -> Array File
list_immediate_children directory = @Builtin_Method "File.list_immediate_children"

## PRIVATE

Return the absolute path of this File
to_text : Text
to_text = this.absolute . path
hubertp marked this conversation as resolved.
Show resolved Hide resolved

## An output stream, allowing for interactive writing of contents into an
open file.
Expand Down Expand Up @@ -927,14 +953,6 @@ type File_Error
Io_Error file msg -> msg.to_text + " (" + file.path + ")."


## PRIVATE

Utility function that lists immediate children of a directory.
list_immediate_children : File -> Vector.Vector File
list_immediate_children directory =
arr = directory.prim_file.list
Vector.new (Polyglot.get_array_size arr) ix->
File (arr.at ix)
hubertp marked this conversation as resolved.
Show resolved Hide resolved

## PRIVATE

Expand All @@ -948,7 +966,7 @@ list_descendants file =
builder.append file
case file.is_directory of
True ->
children = here.list_immediate_children file
children = Vector.Vector (file.list_immediate_children)
children.each go
False -> Nothing
go file
Expand All @@ -969,9 +987,3 @@ get_cwd = @Builtin_Method "File.get_cwd"
- path: The path to obtain a file at.
get_file : Text -> File
get_file path = @Builtin_Method "File.get_file"

## PRIVATE

Gets the textual path to the user's system-defined home directory.
user_home : Text
user_home = @Builtin_Method "File.user_home"
Loading