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

Use MYST_HOME environment variable for configuring load dirs. #194

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
23 changes: 23 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,29 @@ With that, `myst` should now be installed and ready to go!
Help with improving these installation instructions, making pre-built binaries, and/or managing releases would be greatly appreciated :)


# Embedding as a Shard

Myst can be embedded into any other Crystal program as a shard dependency. This could be useful for adding scripting support to your applications, or creating new tools for Myst that have full access to every part of the interpreter.

To add Myst as a shard for your project, simply add it as a dependency in your `shard.yml`:

```yml
dependencies:
myst:
github: myst-lang/myst
```

You can also specify an exact version to use by adding a `version` under the `github` entry.

After running `shards install`, you should be able to include Myst in your project with a simple `require`:

```crystal
require "myst"
```

Everything in Myst is namespaced under the `Myst` module, so there is very little concern of leaking behavior.


# Get Involved

If you have an idea for a new feature or find a bug in Myst, _please_ [file an issue for it!](https://github.com/myst-lang/myst/issues/new). Using the language and finding bugs are the best ways to help Myst improve. Any and all help here is appreciated, even if that just means trying out the language for a day.
Expand Down
9 changes: 6 additions & 3 deletions examples/require.mt
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
# Require statements function similarly to Ruby. They use the same syntax, but
# the behavior is slightly different. In Myst, any path starting with `./` or
# `../` is treated as a file-relative path (the equivalent of Ruby's
# `require_relative`). All other paths will be searched for in the directories
# defined in the `MYST_PATH` environment variable.
# `require_relative`). All other paths will be searched for in the defined
# "include directories" of the interpreter. This includes:
#
# - the current directory as determined by `pwd`.
# - the directory specified by the `MYST_HOME` environment variable.
#
# `require`s act as simple extensions to the current file. Their contents are
# essentially copy-pasted in place into the current file (most similar to the
Expand All @@ -18,7 +21,7 @@ require "./modules.mt"

# The `modules` file loaded above defines a `SampleIO` module, which is now
# available in the current scope.
SampleSTDOUT.puts("calling required module method")
SampleIO.puts("calling required module method")


# Requiring a file inside of a module will import the contents into that scope.
Expand Down
10 changes: 10 additions & 0 deletions spec/spec_helper.cr
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
require "spec"
require "../src/myst/**"


include Myst


# This should resolve to the root directory of this project. This file lives at
# ./spec/spec_helper.cr, so the root is the dirname of the dir of this file.
#
# This is probably not absolutely necessary, but should avoid any potential
# variance based on user's environments.
ENV["MYST_HOME"] = File.dirname(__DIR__)


# Run the Myst parser on the given source code, returning the AST that the
# parser generates for it.
def parse_program(source : String) : Expressions
Expand Down
26 changes: 4 additions & 22 deletions src/myst/interpreter/nodes/require.cr
Original file line number Diff line number Diff line change
Expand Up @@ -50,28 +50,10 @@ module Myst
# The set of directories that should be considered when performing lookups
# with bare paths (not explicitly relative).
def load_dirs
@load_dirs ||= begin
paths = [] of String
# Use any specified environment paths first.
if env_paths = ENV["MYST_PATH"]?
paths.concat(env_paths.split(':'))
end
paths.concat([
# Then add the current working directory.
Dir.current,
# Finally, the directory where the executable is installed. This is
# not _guaranteed_ on all systems, but support is good enough, so a
# non-nil assertion is made.
#
# This assumes that the executable exists under a `bin/` folder. The
# path added here will be the directory that contains `bin`.
#
# This is needed to locate the stdlib.
File.dirname(File.dirname(File.join(Process.executable_path.not_nil!)))
])

paths
end.as(Array(String))
@load_dirs ||= [
Dir.current,
ENV["MYST_HOME"]?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if MYST_HOME is empty? We just let it go? Who needs the stdlib anyways?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it definitely needs more discussion. Ideally load_dirs wouldn't even live here and we could have a more authoritative place for configurable things like this (probably with dependency injection as well? for embedded versions).

].compact.as(Array(String))
end


Expand Down