From f4a6a63d3fa967559420298fe881d7c9d898c152 Mon Sep 17 00:00:00 2001 From: Jon Date: Mon, 28 May 2018 15:54:03 -0400 Subject: [PATCH 1/2] [interpreter] Use `MYST_HOME` environment variable for load_dirs. The old `MYST_PATH` that allows multiple paths similar to `$PATH` has been removed in favor of `MYST_HOME`, which _should_ always point to the install location of the currently-active version of Myst. This should correspond with changes coming in `mtenv` that will set `MYST_HOME` in the shim before running `myst`. For now, users who do not use `mtenv` will have to set this manually, though we can probably check and ensure it is set as part of the VM setup. --- examples/require.mt | 9 ++++++--- spec/spec_helper.cr | 10 ++++++++++ src/myst/interpreter/nodes/require.cr | 26 ++++---------------------- 3 files changed, 20 insertions(+), 25 deletions(-) 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 From f6182893cc582698c9965444e06b51a060d27b4d Mon Sep 17 00:00:00 2001 From: Jon Date: Mon, 28 May 2018 16:18:41 -0400 Subject: [PATCH 2/2] [readme] Add Embedding instructions to README --- README.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) 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.