diff --git a/README.md b/README.md index 08fb136..e741b68 100644 --- a/README.md +++ b/README.md @@ -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. diff --git a/examples/require.mt b/examples/require.mt index d0d2b95..b6f129b 100644 --- a/examples/require.mt +++ b/examples/require.mt @@ -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 @@ -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. diff --git a/spec/spec_helper.cr b/spec/spec_helper.cr index 6f23fb3..8a84e13 100644 --- a/spec/spec_helper.cr +++ b/spec/spec_helper.cr @@ -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 diff --git a/src/myst/interpreter/nodes/require.cr b/src/myst/interpreter/nodes/require.cr index f706a40..709a2e3 100644 --- a/src/myst/interpreter/nodes/require.cr +++ b/src/myst/interpreter/nodes/require.cr @@ -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"]? + ].compact.as(Array(String)) end