From 549244e299a9df255a93dc67309c6ffda3cf6869 Mon Sep 17 00:00:00 2001 From: Garrit Franke Date: Mon, 22 Feb 2021 13:00:29 +0100 Subject: [PATCH] docs: document modules --- docs/SUMMARY.md | 3 +- docs/modules/SUMMARY.md | 66 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 docs/modules/SUMMARY.md diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md index 0eca749..b718d39 100644 --- a/docs/SUMMARY.md +++ b/docs/SUMMARY.md @@ -9,7 +9,8 @@ - [Functions](./concepts/functions.md) - [Comments](./concepts/comments.md) - [Control Flow](./concepts/control-flow.md) - - [Structured data](./concepts/structured-data.md) + - [Structured Data](./concepts/structured-data.md) +- [Modules and Imports](./modules/SUMMARY.md) - [Developer Resources](./developers/SUMMARY.md) - [Contributing to Sabre](./developers/contributing.md) - [Compiler Backends](./developers/backends.md) diff --git a/docs/modules/SUMMARY.md b/docs/modules/SUMMARY.md new file mode 100644 index 0000000..fefa0fe --- /dev/null +++ b/docs/modules/SUMMARY.md @@ -0,0 +1,66 @@ +# Modules and Imports + +Projects naturally grow over time, and digging through 10.000 lines of code in a single file can be cumbersome. By grouping related functionality and separating code with distinct features, you’ll clarify where to find code that implements a particular feature and where to go to change how a feature works. + +The programs we've written so far have been in one file. As a project grows, you can organize code by splitting it into multiple modules with a clear name. + +In Sabre, every file is also a module. Let's take a look at a project structure and identify its modules. + +``` +. +├── foo +│   ├── bar.sb +│   └── baz +│   └── module.sb +├── main.sb +└── some_logic.sb +``` + +As per convention, the entrypoint for this project is the `main.sb` file in the root directory. + +There is a child-module called `some_logic` at the same directory-level. + +Below it, there is a directory called `foo`, containing the submodule `bar`. To address the `bar` module from our entrypoint, we'd import the following: + +``` +import "foo/bar" +``` + +> **Note**: File extensions in imports are optional. Importing `foo/bar.sb` would yield the same result as importing `foo/bar`. + +## Module entrypoints + +In the `foo` directory, there is another directory called `baz`, containing a single file named `module.sb`. This file is treated as a special file, since it serves as the entrypoint for that module. So, instead of importing the file explicitely: + +``` +// main.sb +import "foo/baz/module" +``` + +we can simply import the module containing this file, and Sabre will import the contained `module.sb` instead. + +``` +// main.sb +import "foo/baz" +``` + +## Using imported modules + +To use code defined in a separate module, we first need to import it. This is usually done at the top of the file, but it technically doesn't make a difference where in the document the import is defined. Once the module is imported, we can use the code inside it, as if it were in the current file. + +Let's say we have a module named `math.sb` in the same directory as out `main.sb`, and it defines the function `add(x: int, y: int): int`. To call it in our `main.sb`, we'd do the following: + +``` +import "math" + +fn main() { + println(add(1, 2)) +} +``` + +If we run `main.sb`, we should see the expected output. Sabre has imported the `add` function from the `math` module. + +``` +$ sabre run main.sb +3 +```