# Tutorial: provide run commands Now that your language is installed you need to tell Riju how to run it. Here's an example for Dart: ```yaml main: "main.dart" template: | void main() { print('Hello, world!'); } run: | dart main.dart ``` Note: * The contents of `template` are put into the `main` filename, and `run` is expected to run that file. * The `main` filename should follow existing conventions for your language, typically `main.foo` where `foo` is a standard file extension. If there's no standard file extension you can pick a reasonable-sounding one, like `main.beatnik` for Beatnik. You can use subdirectories (e.g. `src/main.foo`) if needed, but this is pretty rare. * The `template` code should print exactly the text `Hello, world!` with a trailing newline to stdout, or as close to that as possible. ## Compiled languages If your language has a separate compilation step that produces a binary or other intermediate artifact, you can add a separate `compile` command; for example: ```yaml main: "Main.java" template: | public class Main { public static void main(String[] args) { System.out.println("Hello, world!"); } } compile: | javac Main.java run: | java Main ``` There is no hard requirement on the names of intermediate files. In the case of Java, the intermediate file is named `Main.class`, with the `java` command appending the `.class` part implicitly. ## Languages with REPLs If your language has the ability to run an interactive session, you can expose that functionality via the `repl` key. Here is the desired behavior for languages with REPLs: * The `repl` command will start an interactive session *without* any user code loaded * The `run` command will execute the user code in `main`, like before, and will *then* start an interactive session, preferably in the same environment (so variables are still in scope, for example) Here is an example for Python (`-u` is to prevent output buffering): ```yaml repl: | python3 -u main: "main.py" template: | print("Hello, world!") run: | python3 -u -i main.py ``` ## Preserving variable scope In the Python example above, passing `-i main.py` to `python3` starts an interactive session where `main.py` is executed, and then any variables defined in `main.py` can be inspected at the REPL. This is the desired state of operation. Many interactive languages provide some command-line option(s) to achieve a similar effect, although they may be a bit obscure. For example, in Node.js, you have to pass the program as a string: ```yaml repl: | node main: "main.js" template: | console.log("Hello, world!"); run: | node -e "$(< main.js)" -i ``` Or you may be able to abuse a "startup" or "rc" file that is loaded at startup in a special way. For example, Haskell's interpreter evaluates `.ghci` specially at startup: ```yaml repl: | rm -f .ghci ghci main: "Main.hs" template: | module Main where main :: IO () main = putStrLn "Hello, world!" run: | (echo ':load Main' && echo 'main') > .ghci && ghci ``` In the case of shells, we often want to put the code itself into the startup file: ```yaml repl: | SHELL=/usr/bin/zsh HOME="$PWD" zsh input: | expr 123 \* 234 main: ".zshrc" template: | echo "Hello, world!" createEmpty: "" run: | SHELL=/usr/bin/zsh HOME="$PWD" zsh ``` In the above example, we passed `createEmpty: ""`. To explain, the default behavior is for user code to be written into `main` immediately, even before the user has clicked Run. This is so that certain language servers will work correctly. However, in cases where we're abusing a startup file, it may not be appropriate. After all, `zsh` will load `.zshrc` no matter what (note that `repl` and `run` are identical here). By passing `createEmpty: ""`, we make it so that Riju will write the provided string (i.e. `""`) into `main` before executing `repl`. This ensures that user code is *not* run when starting a REPL, but only when actually running. Sometimes it's simply not possible to preserve variable scope from user code when starting an interactive session. In that case, we just start the interactive session separately. It's important to start the interactive session regardless of whether or not the user code had an error (so use `;` instead of `&&`): ```yaml repl: | zoem main: "main.azm" template: | \inform{Hello, world!} run: | zoem -I main.azm; zoem ``` ## Required input Sometimes languages really don't want to provide a way to run code noninteractively. In this case, you can include instructions about how the user can manually run the code: ``` repl: | hhvm -a input: | print 123 * 234 main: "main.hack" template: | <<__EntryPoint>> function main(): void { echo "Hello, world!\n"; } run: | echo "Type 'r' at the debugger prompt to run the code" && hhvm -a main.hack ```