Files
sols.dev/docs/print.html
2026-05-10 16:35:17 +10:00

1357 lines
66 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE HTML>
<html lang="en" class="light sidebar-visible" dir="ltr">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Solstice Docs</title>
<meta name="robots" content="noindex">
<!-- Custom HTML head -->
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff">
<link rel="icon" href="favicon-97ae436f.svg">
<link rel="shortcut icon" href="favicon-9392e324.png">
<link rel="stylesheet" href="css/variables-16ac1224.css">
<link rel="stylesheet" href="css/general-e4fbb323.css">
<link rel="stylesheet" href="css/chrome-ae938929.css">
<link rel="stylesheet" href="css/print-9e4910d8.css" media="print">
<!-- Fonts -->
<link rel="stylesheet" href="fonts/fonts-6d524047.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" id="mdbook-highlight-css" href="highlight-493f70e1.css">
<link rel="stylesheet" id="mdbook-tomorrow-night-css" href="tomorrow-night-4c0ae647.css">
<link rel="stylesheet" id="mdbook-ayu-highlight-css" href="ayu-highlight-3fdfc3ac.css">
<!-- Custom theme stylesheets -->
<!-- Provide site root and default themes to javascript -->
<script>
const path_to_root = "";
const default_light_theme = "light";
const default_dark_theme = "navy";
window.path_to_searchindex_js = "searchindex-c4fb8585.js";
</script>
<!-- Start loading toc.js asap -->
<script src="toc-1ef53d19.js"></script>
</head>
<body>
<div id="mdbook-help-container">
<div id="mdbook-help-popup">
<h2 class="mdbook-help-title">Keyboard shortcuts</h2>
<div>
<p>Press <kbd></kbd> or <kbd></kbd> to navigate between chapters</p>
<p>Press <kbd>S</kbd> or <kbd>/</kbd> to search in the book</p>
<p>Press <kbd>?</kbd> to show this help</p>
<p>Press <kbd>Esc</kbd> to hide this help</p>
</div>
</div>
</div>
<div id="mdbook-body-container">
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script>
try {
let theme = localStorage.getItem('mdbook-theme');
let sidebar = localStorage.getItem('mdbook-sidebar');
if (theme.startsWith('"') && theme.endsWith('"')) {
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
}
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
}
} catch (e) { }
</script>
<!-- Set the theme before any content is loaded, prevents flash -->
<script>
const default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? default_dark_theme : default_light_theme;
let theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
if (theme === null || theme === undefined) { theme = default_theme; }
const html = document.documentElement;
html.classList.remove('light')
html.classList.add(theme);
html.classList.add("js");
</script>
<input type="checkbox" id="mdbook-sidebar-toggle-anchor" class="hidden">
<!-- Hide / unhide sidebar before it is displayed -->
<script>
let sidebar = null;
const sidebar_toggle = document.getElementById("mdbook-sidebar-toggle-anchor");
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
} else {
sidebar = 'hidden';
sidebar_toggle.checked = false;
}
if (sidebar === 'visible') {
sidebar_toggle.checked = true;
} else {
html.classList.remove('sidebar-visible');
}
</script>
<nav id="mdbook-sidebar" class="sidebar" aria-label="Table of contents">
<!-- populated by js -->
<mdbook-sidebar-scrollbox class="sidebar-scrollbox"></mdbook-sidebar-scrollbox>
<noscript>
<iframe class="sidebar-iframe-outer" src="toc.html"></iframe>
</noscript>
<div id="mdbook-sidebar-resize-handle" class="sidebar-resize-handle">
<div class="sidebar-resize-indicator"></div>
</div>
</nav>
<div id="mdbook-page-wrapper" class="page-wrapper">
<div class="page">
<div id="mdbook-menu-bar-hover-placeholder"></div>
<div id="mdbook-menu-bar" class="menu-bar sticky">
<div class="left-buttons">
<label id="mdbook-sidebar-toggle" class="icon-button" for="mdbook-sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="mdbook-sidebar">
<span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M0 96C0 78.3 14.3 64 32 64H416c17.7 0 32 14.3 32 32s-14.3 32-32 32H32C14.3 128 0 113.7 0 96zM0 256c0-17.7 14.3-32 32-32H416c17.7 0 32 14.3 32 32s-14.3 32-32 32H32c-17.7 0-32-14.3-32-32zM448 416c0 17.7-14.3 32-32 32H32c-17.7 0-32-14.3-32-32s14.3-32 32-32H416c17.7 0 32 14.3 32 32z"/></svg></span>
</label>
<button id="mdbook-theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="mdbook-theme-list">
<span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M371.3 367.1c27.3-3.9 51.9-19.4 67.2-42.9L600.2 74.1c12.6-19.5 9.4-45.3-7.6-61.2S549.7-4.4 531.1 9.6L294.4 187.2c-24 18-38.2 46.1-38.4 76.1L371.3 367.1zm-19.6 25.4l-116-104.4C175.9 290.3 128 339.6 128 400c0 3.9 .2 7.8 .6 11.6c1.8 17.5-10.2 36.4-27.8 36.4H96c-17.7 0-32 14.3-32 32s14.3 32 32 32H240c61.9 0 112-50.1 112-112c0-2.5-.1-5-.2-7.5z"/></svg></span>
</button>
<ul id="mdbook-theme-list" class="theme-popup" aria-label="Themes" role="menu">
<li role="none"><button role="menuitem" class="theme" id="mdbook-theme-default_theme">Auto</button></li>
<li role="none"><button role="menuitem" class="theme" id="mdbook-theme-light">Light</button></li>
<li role="none"><button role="menuitem" class="theme" id="mdbook-theme-rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="mdbook-theme-coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="mdbook-theme-navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="mdbook-theme-ayu">Ayu</button></li>
</ul>
<button id="mdbook-search-toggle" class="icon-button" type="button" title="Search (`/`)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="/ s" aria-controls="mdbook-searchbar">
<span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M416 208c0 45.9-14.9 88.3-40 122.7L502.6 457.4c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0L330.7 376c-34.4 25.2-76.8 40-122.7 40C93.1 416 0 322.9 0 208S93.1 0 208 0S416 93.1 416 208zM208 352c79.5 0 144-64.5 144-144s-64.5-144-144-144S64 128.5 64 208s64.5 144 144 144z"/></svg></span>
</button>
</div>
<h1 class="menu-title">Solstice Docs</h1>
<div class="right-buttons">
<a href="print.html" title="Print this book" aria-label="Print this book">
<span class=fa-svg id="print-button"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M128 0C92.7 0 64 28.7 64 64v96h64V64H354.7L384 93.3V160h64V93.3c0-17-6.7-33.3-18.7-45.3L400 18.7C388 6.7 371.7 0 354.7 0H128zM384 352v32 64H128V384 368 352H384zm64 32h32c17.7 0 32-14.3 32-32V256c0-35.3-28.7-64-64-64H64c-35.3 0-64 28.7-64 64v96c0 17.7 14.3 32 32 32H64v64c0 35.3 28.7 64 64 64H384c35.3 0 64-28.7 64-64V384zm-16-88c-13.3 0-24-10.7-24-24s10.7-24 24-24s24 10.7 24 24s-10.7 24-24 24z"/></svg></span>
</a>
</div>
</div>
<div id="mdbook-search-wrapper" class="hidden">
<form id="mdbook-searchbar-outer" class="searchbar-outer">
<div class="search-wrapper">
<input type="search" id="mdbook-searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="mdbook-searchresults-outer" aria-describedby="searchresults-header">
<div class="spinner-wrapper">
<span class=fa-svg id="fa-spin"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M304 48c0-26.5-21.5-48-48-48s-48 21.5-48 48s21.5 48 48 48s48-21.5 48-48zm0 416c0-26.5-21.5-48-48-48s-48 21.5-48 48s21.5 48 48 48s48-21.5 48-48zM48 304c26.5 0 48-21.5 48-48s-21.5-48-48-48s-48 21.5-48 48s21.5 48 48 48zm464-48c0-26.5-21.5-48-48-48s-48 21.5-48 48s21.5 48 48 48s48-21.5 48-48zM142.9 437c18.7-18.7 18.7-49.1 0-67.9s-49.1-18.7-67.9 0s-18.7 49.1 0 67.9s49.1 18.7 67.9 0zm0-294.2c18.7-18.7 18.7-49.1 0-67.9S93.7 56.2 75 75s-18.7 49.1 0 67.9s49.1 18.7 67.9 0zM369.1 437c18.7 18.7 49.1 18.7 67.9 0s18.7-49.1 0-67.9s-49.1-18.7-67.9 0s-18.7 49.1 0 67.9z"/></svg></span>
</div>
</div>
</form>
<div id="mdbook-searchresults-outer" class="searchresults-outer hidden">
<div id="mdbook-searchresults-header" class="searchresults-header"></div>
<ul id="mdbook-searchresults">
</ul>
</div>
</div>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script>
document.getElementById('mdbook-sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
document.getElementById('mdbook-sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
Array.from(document.querySelectorAll('#mdbook-sidebar a')).forEach(function(link) {
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
});
</script>
<div id="mdbook-content" class="content">
<main>
<h1 id="introduction"><a class="header" href="#introduction">Introduction</a></h1>
<p>Welcome to the Solstice documentation! Here we have a tutorial (starting <a href="#installation">here</a>) and a specification for the Solstice programming language.</p>
<p>If youre new to Solstice, Id recommend starting the tutorial, at the <a href="#installation">installation</a> page. If youve already installed Solstice, start at the <a href="#basics">Basics</a> page.</p>
<p>Docs generated by mdBook.</p>
<div style="break-before: page; page-break-before: always;"></div>
<h1 id="installation"><a class="header" href="#installation">Installation</a></h1>
<p>Solstice is fully supported and tested on Linux, however should work on most UNIX-like environments. Windows support is theoretically possible, however not all features are avaliable, so use WSL, MSys, or Cygwin instead.</p>
<h2 id="which-method-is-for-you"><a class="header" href="#which-method-is-for-you">Which method is for you?</a></h2>
<p>Use a <a href="#prebuilt-binaries">prebuilt binary</a> if youre in a rush, or you cant get a compiler on your system.</p>
<p>Use the <a href="#automated-build-script">automated build script</a> for a full install of Solstice and Ground, with maximum flexibility.</p>
<p>Do a <a href="#building-manually">manual build</a> if you intend to contribute to the Solstice source code.</p>
<div style="break-before: page; page-break-before: always;"></div>
<h1 id="prebuilt-binaries"><a class="header" href="#prebuilt-binaries">Prebuilt Binaries</a></h1>
<p>Solstice binaries statically linked with Ground are avaliable from the <a href="https://chookspace.com/solstice/solstice/releases">Solstice releases page</a>. For now, these are only for Linux x86_64, but more options may be avaliable in future.</p>
<p>Download the latest release, copy it into a folder in your path (such as <code>/usr/local/bin</code>) and enjoy!</p>
<h2 id="producing-release-binaries"><a class="header" href="#producing-release-binaries">Producing release binaries</a></h2>
<p>There is a script <a href="https://chookspace.com/solstice/builder">on Chookspace</a> which builds Solstice and Ground in a container. Use this script for building production releases, and determining whether bugs are setup-specific or affect all people.</p>
<p>Use this script to produce prebuilt binaries for the releases page.</p>
<div style="break-before: page; page-break-before: always;"></div>
<h1 id="build-dependencies"><a class="header" href="#build-dependencies">Build dependencies</a></h1>
<h2 id="macos"><a class="header" href="#macos">macOS</a></h2>
<pre><code class="language-sh">xcode-select --install
</code></pre>
<p>Then, download UTHash <a href="https://github.com/troydhanson/uthash/archive/master.zip">here</a>, and copy the contents of the <code>include</code> folder to <code>/usr/local/include</code>:</p>
<pre><code class="language-sh">sudo cp (/path/to/uthash-master)/include/* /usr/local/include
</code></pre>
<h2 id="ubuntudebian"><a class="header" href="#ubuntudebian">Ubuntu/Debian</a></h2>
<pre><code class="language-sh">sudo apt install gcc git make uthash-dev
</code></pre>
<h2 id="arch-linux"><a class="header" href="#arch-linux">Arch Linux</a></h2>
<pre><code class="language-sh">sudo pacman -S --needed gcc git make uthash
</code></pre>
<div style="break-before: page; page-break-before: always;"></div>
<h1 id="automated-build-script"><a class="header" href="#automated-build-script">Automated Build Script</a></h1>
<p>This method requires the following installed:</p>
<ul>
<li>uthash (in <code>/usr/include</code> or similar)</li>
<li>A gcc-compatible C compiler linked to <code>cc</code>
<ul>
<li>GCC and Clang are both tested and will yield similar results.</li>
</ul>
</li>
<li>Git (to get source code)</li>
<li>Make (to organise building the code)</li>
</ul>
<p>Refer to <a href="#build-dependencies">Build Dependencies</a> for instructions on how to install dependencies.</p>
<h2 id="running-the-installer"><a class="header" href="#running-the-installer">Running the installer</a></h2>
<p>Run this command in your terminal:</p>
<pre><code class="language-sh">bash -c "$(curl -fsSL https://sols.dev/install.sh)"
</code></pre>
<p>This will:</p>
<ul>
<li>Download a shell script from <code>https://sols.dev/install.sh</code></li>
<li>Run the contents of the shell script in the <code>bash</code> command interpreter</li>
</ul>
<p>The script does the following:</p>
<ul>
<li>Checks if Ground and Solstice are installed on your system.</li>
<li>If either Ground or Solstice arent avaliable, it will download, build, and install the source code.</li>
<li>If Ground or Solstice are installed, it will update them to the latest version.</li>
</ul>
<div style="break-before: page; page-break-before: always;"></div>
<h1 id="building-manually"><a class="header" href="#building-manually">Building Manually</a></h1>
<p>Refer to <a href="#build-dependencies">Build Dependencies</a> for instructions on how to install dependencies.</p>
<p>Build and install Ground:</p>
<pre><code class="language-sh">git clone https://chookspace.com/ground/ground
cd ground
make
sudo make install
cd ..
</code></pre>
<p>After this, build and install Solstice:</p>
<pre><code class="language-sh">git clone https://chookspace.com/solstice/solstice
cd solstice
make
sudo make install
cd ..
</code></pre>
<div style="break-before: page; page-break-before: always;"></div>
<h1 id="command-usage"><a class="header" href="#command-usage">Command Usage</a></h1>
<pre><code>Solstice programming language
Usage: solstice &lt;file&gt; [-h] [--help] [-p] [--print] [-b &lt;file&gt;] [--bytecode &lt;file&gt;] [-c &lt;file&gt;] [--compile &lt;file&gt;]
Args:
&lt;file&gt;: Solstice source file
-h or --help: Prints this help message and exits
-p or --print: Prints textual version of Ground bytecode to console
-b &lt;file&gt; or --bytecode &lt;file&gt;: Generates Ground bytecode (.grbc) and saves it to the provided filename
-c &lt;file&gt; or --compile &lt;file&gt;: Compiles Ground to Linux x86_64 assembly, outputs a binary to the provided filename (experimental)
If no extra arguments are provided, the generated Ground bytecode will be executed.
</code></pre>
<h2 id="arguments"><a class="header" href="#arguments">Arguments:</a></h2>
<h3 id="file"><a class="header" href="#file"><code>&lt;file&gt;</code></a></h3>
<p>The Solstice source file to run.</p>
<p>There should never be more than one file, as Solstice allows files to import each other, rather than compiling multiple files into one manually.</p>
<h3 id="-h-or---help"><a class="header" href="#-h-or---help"><code>-h</code> or <code>--help</code></a></h3>
<p>Shows the help message above.</p>
<h3 id="-p-or---print"><a class="header" href="#-p-or---print"><code>-p</code> or <code>--print</code></a></h3>
<p>Prints the textual version of the generated Ground bytecode to the console.</p>
<p>This is useful for debugging the compiler, and ensuring the correct output is produced for the GroundVM.</p>
<h3 id="-b-file-or---bytecode-file"><a class="header" href="#-b-file-or---bytecode-file"><code>-b &lt;file&gt;</code> or <code>--bytecode &lt;file&gt;</code></a></h3>
<p>Outputs Ground bytecode (in <code>grbc</code> format) and saves it in the file <code>&lt;file&gt;</code>.</p>
<p>Ground bytecode is useful for distributing software in a format where the target machine does not need Solstice installed, only the Ground VM.</p>
<p>Run the compiled bytecode with:</p>
<pre><code class="language-sh">ground -b &lt;file&gt;
</code></pre>
<h3 id="-c-file-or---compile-file"><a class="header" href="#-c-file-or---compile-file"><code>-c &lt;file&gt;</code> or <code>--compile &lt;file&gt;</code></a></h3>
<p>Compiles the Ground bytecode to assembly using the <a href="https://chookspace.com/tram/tram">Tram</a> backend, outputting a binary named <code>&lt;file&gt;</code>.</p>
<p>Requires Ground to be built with Tram support, and Tram to be installed on your system.</p>
<p>This backend is experimental and does not support all features.</p>
<div style="break-before: page; page-break-before: always;"></div>
<h1 id="basics"><a class="header" href="#basics">Basics</a></h1>
<p>This part of the tutorial shows you the basics of using Solstice. Click next to see the “Hello, World!” program!</p>
<div style="break-before: page; page-break-before: always;"></div>
<h1 id="hello-world"><a class="header" href="#hello-world">Hello, World!</a></h1>
<p>Create a new file on your computer (preferably in a new folder) named <code>main.sols</code>. In the file, write the following:</p>
<pre><code class="language-solstice">puts "Hello, World!"
</code></pre>
<p>Save the file, then run in your terminal:</p>
<pre><code class="language-sh">solstice main.sols
</code></pre>
<p>Solstice will run the file for you, which should print <code>Hello, World!</code> to the console.</p>
<p>Heres what it does:</p>
<ul>
<li><code>puts</code>: Stands for “put something”. Its Solstices built in “please print out this things current state” operator.</li>
<li><code>"Hello, World!"</code>: A string. A string is a collection of characters. In Solstice, you denote a string by surrounding your text with double quotes (<code>"</code>).</li>
</ul>
<p>Next up: using variables!</p>
<div style="break-before: page; page-break-before: always;"></div>
<h1 id="variables"><a class="header" href="#variables">Variables</a></h1>
<h2 id="creating-variables"><a class="header" href="#creating-variables">Creating Variables</a></h2>
<p>In Solstice, you can initialize a variable using the syntax:</p>
<pre><code class="language-solstice">name = value
</code></pre>
<p>where:</p>
<ul>
<li><code>name</code> is the name of your variable. You can use all letters in variable names, as well as underscores and numbers.
<ul>
<li>The standard way to name your variables in Solstice is with <code>camelCase</code>.</li>
</ul>
</li>
<li><code>value</code> is some sort of value. This value can be:
<ul>
<li>an integer (number with no decimal place)</li>
<li>a double (number with a decimal place)</li>
<li>a string (collection of characters, as seen before)</li>
<li>a character (a single letter)</li>
<li>a boolean (either <code>true</code> or <code>false</code>)</li>
</ul>
</li>
</ul>
<p>Well look at types of values in the next part.</p>
<h2 id="recalling-variables"><a class="header" href="#recalling-variables">Recalling Variables</a></h2>
<p>Recall a variables content by using its name:</p>
<pre><code class="language-solstice">puts name
</code></pre>
<p>where <code>name</code> is the name of your variable.</p>
<div style="break-before: page; page-break-before: always;"></div>
<h1 id="comments"><a class="header" href="#comments">Comments</a></h1>
<p>In Solstice, there are 3 ways to do comments:</p>
<h2 id="-single-line-comment"><a class="header" href="#-single-line-comment"><code>//</code> (Single-Line Comment)</a></h2>
<p>Writing <code>//</code> tells Solstice to ignore the rest of the line.</p>
<p>Some examples:</p>
<pre><code class="language-solstice">puts 2 + 2 // should be 4
// This variable holds the status code from checkStatus()
statusCode = checkStatus("file.txt")
</code></pre>
<p>This comment should be used when writing your codes logic in Solstice.</p>
<h2 id="--multiline-comment"><a class="header" href="#--multiline-comment"><code>/* */</code> (Multiline Comment)</a></h2>
<p>Any text in between <code>/*</code> and <code>*/</code> will be ignored. These comments should be used to document functions and structs (well get to those later.)</p>
<p>Example:</p>
<pre><code class="language-solstice">/*
Adds two numbers together.
*/
def add(int a, int b) int {
return a + b
}
</code></pre>
<h2 id="-shebang-comment"><a class="header" href="#-shebang-comment"><code>#</code> (Shebang Comment)</a></h2>
<p>Use this comment only for using Solstice as a script interpreter in a shebang. Effectively the same as <code>//</code>, but we recommend using <code>//</code> over <code>#</code>.</p>
<div style="break-before: page; page-break-before: always;"></div>
<h1 id="values-and-types"><a class="header" href="#values-and-types">Values and Types</a></h1>
<p>In Solstice, everything is a value, and every value has a type. Values can be moved around and passed to different functions, however to pass them around their type must be confirmed.</p>
<h2 id="int"><a class="header" href="#int"><code>int</code></a></h2>
<p>An <code>int</code> is a signed (meaning either positive or negative) 8-byte integer (meaning no decimal place).</p>
<p>Using this size, Solstice can accurately process numbers between <code>-9,223,372,036,854,775,807</code> and <code>9,223,372,036,854,775,807</code>.</p>
<p>Integers are represented as a collection of digits not seperated by anything, such as:</p>
<pre><code class="language-solstice">123
7483
423843269
</code></pre>
<h2 id="double"><a class="header" href="#double"><code>double</code></a></h2>
<p>A <code>double</code> is a signed 8-byte floating-point (meaning with a decimal place) number.</p>
<p>Using this size, Solstice can accurately process numbers between 15 and 17 digits long.</p>
<p>Doubles are represented as a collection of digits, with a dot (<code>.</code>) seperating the ones and tenths positions, such as:</p>
<pre><code class="language-solstice">3.14
432.543
5907432.432
</code></pre>
<h2 id="string"><a class="header" href="#string"><code>string</code></a></h2>
<p>A <code>string</code> is a collection of characters which end with a null byte (handled by Solstice).</p>
<p>Solstice can accurately process strings of any size, provided your computer has enough memory.</p>
<p>Strings are represented as a collection of characters surrounded by double quotes (<code>""</code>), such as:</p>
<pre><code class="language-solstice">"Hello, World!"
"Solstice is cool"
"Rust kinda mid"
</code></pre>
<h2 id="char"><a class="header" href="#char"><code>char</code></a></h2>
<p>A <code>char</code> is a signed 1-byte integer, represented as an ASCII character, however can also be used to represent a single byte in a stream.</p>
<p>Solstice can accurately process any ASCII character.</p>
<p>Characters are represented as a single character surrounded by single quotes (<code>''</code>), such as:</p>
<pre><code class="language-solstice">'a'
'b'
'c'
</code></pre>
<h2 id="bool"><a class="header" href="#bool"><code>bool</code></a></h2>
<p>A <code>bool</code> is a variable which can either be <code>true</code> or <code>false</code>.</p>
<pre><code class="language-solstice">true
false
</code></pre>
<h2 id="other-types"><a class="header" href="#other-types">Other Types</a></h2>
<p>Solstice has three other types: <code>fun</code>, <code>template</code>, and <code>object</code>, but well cover these in the <a href="#functions">Functions</a> and <a href="#structures">Structures</a> pages.</p>
<div style="break-before: page; page-break-before: always;"></div>
<h1 id="functions"><a class="header" href="#functions">Functions</a></h1>
<div style="break-before: page; page-break-before: always;"></div>
<h1 id="structures"><a class="header" href="#structures">Structures</a></h1>
<div style="break-before: page; page-break-before: always;"></div>
<h1 id="naming-conventions"><a class="header" href="#naming-conventions">Naming Conventions</a></h1>
<div style="break-before: page; page-break-before: always;"></div>
<h1 id="comment-conventions"><a class="header" href="#comment-conventions">Comment Conventions</a></h1>
<div style="break-before: page; page-break-before: always;"></div>
<h1 id="code-layout"><a class="header" href="#code-layout">Code Layout</a></h1>
<div style="break-before: page; page-break-before: always;"></div>
<h1 id="reserved-words"><a class="header" href="#reserved-words">Reserved Words</a></h1>
<p>This is a list of all reserved words in Solstice, seperated by new lines. These words may not be used as identifiers.</p>
<p>After <code>//</code>, notes may be provided which detail exceptions to the reserved word, however, the word should still be treated as reserved regardless.</p>
<pre><code class="language-solstice">puts
if
while
def
lambda
return
use
struct
enum
constructor
destructor
duplicator
private
protected
ground // Only when targeting GroundVM
new
as
sizeof
pragma
</code></pre>
<div style="break-before: page; page-break-before: always;"></div>
<h1 id="comments-1"><a class="header" href="#comments-1">Comments</a></h1>
<p>Comments in Solstice can be done in 3 ways:</p>
<h2 id="-single-line-comment-1"><a class="header" href="#-single-line-comment-1"><code>//</code> (Single-Line Comment)</a></h2>
<p>Use <code>//</code> to tell Solstice to ignore text until the end of the line.</p>
<p>This kind of comment should be used inside code to explain how parts of code work.</p>
<h2 id="--multiline-comment-1"><a class="header" href="#--multiline-comment-1"><code>/* */</code> (Multiline Comment)</a></h2>
<p>Use <code>/*</code> and <code>*/</code> to tell Solstice to ignore text in between the two markers.</p>
<p>This kind of comment should be used for explainations of how functions and structs work, placed above the definition.</p>
<h2 id="-shebang-comment-1"><a class="header" href="#-shebang-comment-1"><code>#</code> (Shebang Comment)</a></h2>
<p>Use <code>#</code> to tell Solstice to ignore text until the end of the line.</p>
<p>This kind of comment should be used in a shebang (writing <code>#!/usr/bin/env solstice</code> at the top of your entry point source file), not in the middle.</p>
<h2 id="example"><a class="header" href="#example">Example</a></h2>
<pre><code class="language-solstice">#!/usr/bin/env solstice
/*
This function does something.
Input:
funnyNumber: A funny number
Returns: Another funny number
*/
def doSomething(int funnyNumber) int {
// Tell the user the number is funny
puts "The number" funnyNumber "is very funny"
// Now give them another funny number
return 532
}
</code></pre>
<div style="break-before: page; page-break-before: always;"></div>
<h1 id="expressions"><a class="header" href="#expressions">Expressions</a></h1>
<p>An expression in Solstice is a combination of operators and values (whether literal or stored in a variable).;</p>
<h2 id="expression-types"><a class="header" href="#expression-types">Expression Types</a></h2>
<p>“Precedence” is a number which dictates the order of execution. The higher the precedence, the sooner an expression will be evaluated.</p>
<h3 id="binary-mathematical"><a class="header" href="#binary-mathematical">Binary Mathematical</a></h3>
<ul>
<li><code>+</code>: Adds two numbers on either side, or concatenates two strings
<ul>
<li>Accepts:
<ul>
<li>Two integers either side</li>
<li>Two doubles either side</li>
<li>Two strings either side</li>
<li>An integer and a double on either side (order not significant)</li>
</ul>
</li>
<li>Returns:
<ul>
<li>The sum of both values as an integer if both values are integers</li>
<li>The sum of both values as a double if one value is a double and the other is an int, or both values are doubles</li>
<li>The concatenated string when both values are strings</li>
</ul>
</li>
<li>Precedence: 5</li>
</ul>
</li>
<li><code>-</code>: Subtracts two numbers on either side
<ul>
<li>Accepts:
<ul>
<li>Two integers either side</li>
<li>Two doubles either side</li>
<li>An integer and a double on either side (order not significant)</li>
</ul>
</li>
<li>Returns:
<ul>
<li>The difference of both values as an integer if both values are integers</li>
<li>The difference of both values as a double if one value is a double and the other is an int, or both values are doubles</li>
</ul>
</li>
<li>Precedence: 5</li>
</ul>
</li>
<li><code>*</code>: Multiplies two numbers on either side
<ul>
<li>Accepts:
<ul>
<li>Two integers either side</li>
<li>Two doubles either side</li>
<li>An integer and a double on either side (order not significant)</li>
</ul>
</li>
<li>Returns:
<ul>
<li>The product of both values as an integer if both values are integers</li>
<li>The product of both values as a double if one value is a double and the other is an int, or both values are doubles</li>
</ul>
</li>
<li>Precedence: 6</li>
</ul>
</li>
<li><code>/</code>: Divides two numbers on either side
<ul>
<li>Accepts:
<ul>
<li>Two integers either side
<ul>
<li>Two doubles either side
<ul>
<li>An integer and a double on either side (order not significant)</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>Returns:
<ul>
<li>The quotient of both values as an integer if both values are integers</li>
<li>The quotient of both values as a double if one value is a double and the other is an int, or both values are doubles</li>
</ul>
</li>
<li>Precedence: 6</li>
</ul>
</li>
</ul>
<h3 id="binary-comparative"><a class="header" href="#binary-comparative">Binary Comparative</a></h3>
<ul>
<li><code>==</code>: Checks two values to determine if they are equal
<ul>
<li>Accepts:
<ul>
<li>Any two values either side which are of the same type</li>
<li>An integer and a double on either side (order not significant)</li>
</ul>
</li>
<li>Returns:
<ul>
<li><code>true</code> if both provided values are exactly the same. </li>
<li><code>false</code> otherwise.</li>
</ul>
</li>
<li>Precedence: 2</li>
</ul>
</li>
<li><code>!=</code>: Checks two values to determine if they are not equal
<ul>
<li>Accepts:
<ul>
<li>Any two values either side which are of the same type</li>
<li>An integer and a double on either side (order not significant)</li>
</ul>
</li>
<li>Returns:
<ul>
<li><code>true</code> if both provided values are not exactly the same. </li>
<li><code>false</code> otherwise.</li>
</ul>
</li>
<li>Precedence: 2</li>
</ul>
</li>
<li><code>&gt;</code>: Checks two numbers to determine which is greater
<ul>
<li>Accepts:
<ul>
<li>Any two numbers (int or double) either side</li>
</ul>
</li>
<li>Returns:
<ul>
<li><code>true</code> if the number provided on the left is greater than the number provided on the right.</li>
<li><code>false</code> otherwise.</li>
</ul>
</li>
<li>Precedence: 2</li>
</ul>
</li>
<li><code>&lt;</code>: Checks two numbers to determine which is lesser
<ul>
<li>Accepts:
<ul>
<li>Any two numbers (int or double) either side</li>
</ul>
</li>
<li>Returns:
<ul>
<li><code>true</code> if the number provided on the left is lesser than the number provided on the right.</li>
<li><code>false</code> otherwise.</li>
</ul>
</li>
<li>Precedence: 2</li>
</ul>
</li>
<li><code>&gt;=</code>: Checks two numbers to determine which is greater, or whether both are equal
<ul>
<li>Accepts:
<ul>
<li>Any two numbers (int or double) either side</li>
</ul>
</li>
<li>Returns:
<ul>
<li><code>true</code> if the number provided on the left is greater than the number provided on the right, or if both numbers are equal.</li>
<li><code>false</code> otherwise.</li>
</ul>
</li>
<li>Precedence: 2</li>
</ul>
</li>
<li><code>&lt;=</code>: Checks two numbers to determine which is lesser, or whether both are equal
<ul>
<li>Accepts:
<ul>
<li>Any two numbers (int or double) either side</li>
</ul>
</li>
<li>Returns:
<ul>
<li><code>true</code> if the number provided on the left is lesser than the number provided on the right, or if both numbers are equal.</li>
<li><code>false</code> otherwise.</li>
</ul>
</li>
<li>Precedence: 2</li>
</ul>
</li>
</ul>
<h3 id="binary-misc"><a class="header" href="#binary-misc">Binary Misc</a></h3>
<ul>
<li><code>as</code>: Converts between types.
<ul>
<li>Accepts:
<ul>
<li>Any object on the left, and a type which has an applicable conversion defined by the object on the right</li>
</ul>
</li>
<li>Returns:
<ul>
<li>The object turned into the type on the right, in the way defined by the as-method</li>
</ul>
</li>
</ul>
</li>
<li><code>.</code>: Accesses object fields
<ul>
<li>Accepts:
<ul>
<li>An object on the left, and an identifier on the right which corresponds to a field or method in the object</li>
</ul>
</li>
<li>Returns:
<ul>
<li>The object field or method the identifier corresponds to</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="brackets"><a class="header" href="#brackets">Brackets</a></h3>
<ul>
<li><code>(...)</code>: Evaluates an expression inside the brackets before outside expressions.
<ul>
<li>Accepts:
<ul>
<li>Any expression inside the brackets (in place of <code>...</code>)</li>
</ul>
</li>
<li>Returns:
<ul>
<li>The result of the expression in the brackets</li>
</ul>
</li>
<li>Precedence: 7</li>
</ul>
</li>
</ul>
<h3 id="function-call"><a class="header" href="#function-call">Function Call</a></h3>
<ul>
<li><code>(...)</code>: Calls the specified function.
<ul>
<li>Accepts:
<ul>
<li>An identifier for the function before the brackets, then comma-seperated expressions corresponding to the function type signature (see <a href="#fun">Types -&gt; Combined Types -&gt; fun</a>) inside the brackets (in place of <code>...</code>)</li>
</ul>
</li>
<li>Returns:
<ul>
<li>The functions return type as specified by the function type signature (see <a href="#fun">Types -&gt; Combined Types -&gt; fun</a>)</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="unary-misc"><a class="header" href="#unary-misc">Unary Misc</a></h3>
<ul>
<li><code>new</code>: Creates a new object from a template.
<ul>
<li>Accepts:
<ul>
<li>A template after the <code>new</code> keyword.</li>
<li>A core type identifier</li>
</ul>
</li>
<li>Returns:
<ul>
<li>An object based on the provided template, if provided with a template.</li>
<li>The empty version of the core type, if provided with a core type, which is:
<ul>
<li><code>int</code>: <code>0</code></li>
<li><code>double</code>: <code>0.0</code></li>
<li><code>string</code>: <code>""</code></li>
<li><code>char</code>: <code>'\0'</code></li>
<li><code>bool</code>: <code>false</code></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><code>sizeof</code>: Gets the size of something.
<ul>
<li>Accepts:
<ul>
<li>A string</li>
<li>An object with an <code>int size</code> field</li>
</ul>
</li>
<li>Returns:
<ul>
<li>The string length if provided a string</li>
<li>The <code>int size</code> field of the object if provided an object</li>
</ul>
</li>
</ul>
</li>
</ul>
<div style="break-before: page; page-break-before: always;"></div>
<h1 id="types"><a class="header" href="#types">Types</a></h1>
<p>Solstice is statically typed, meaning all values must have a known type before any code can be executed.</p>
<h2 id="core-types"><a class="header" href="#core-types">Core Types</a></h2>
<p>These core types are automatically avaliable in Solstice. The words to identify them are reserved and cannot be reassigned.</p>
<h3 id="int-1"><a class="header" href="#int-1"><code>int</code></a></h3>
<p>8-byte signed integer, equivalent to C <code>int64_t</code> or Ground <code>-int</code>.</p>
<p>Examples: <code>32</code>, <code>121</code>, <code>-5</code></p>
<h3 id="double-1"><a class="header" href="#double-1"><code>double</code></a></h3>
<p>8-byte double prescision floating point number, equivalent to C <code>double</code> or Ground <code>-double</code>.</p>
<p>Examples: <code>3.14</code>, <code>-2.7</code></p>
<h3 id="string-1"><a class="header" href="#string-1"><code>string</code></a></h3>
<p>C-style null-terminated array of characters. Equivalent to C <code>char*</code> or Ground <code>-string</code>.</p>
<h3 id="char-1"><a class="header" href="#char-1"><code>char</code></a></h3>
<p>1-byte signed integer, usually used to store a character, however can also be used to store bytes. Equivalent to C <code>char</code> or Ground <code>-char</code>.</p>
<h3 id="bool-1"><a class="header" href="#bool-1"><code>bool</code></a></h3>
<p>1-byte unsigned integer, either 1 or 0. Represented by the reserved words <code>true</code> and <code>false</code>. Equivalent to C <code>char</code> (no stdbool.h) or <code>bool</code> (with stdbool.h) or Ground <code>-bool</code>.</p>
<h2 id="combined-types"><a class="header" href="#combined-types">Combined Types</a></h2>
<p>These types utilise core types to create new combinations. They take type arguments.</p>
<h3 id="fun"><a class="header" href="#fun"><code>fun</code></a></h3>
<p>Represents a function. Equivalent to Ground <code>-function</code>, or a C function pointer.</p>
<p><strong>Syntax</strong>:</p>
<pre><code class="language-solstice">fun(...) type
</code></pre>
<p>where:</p>
<ul>
<li><code>type</code> is a type identifier, which will be the return type</li>
<li><code>...</code> is multiple type identifiers, seperated by commas, which are the argument types</li>
</ul>
<p><strong>Example</strong>:</p>
<pre><code class="language-solstice">fun(int, string) bool
</code></pre>
<p>This represents a function which takes an <code>int</code> and <code>string</code> as arguments, and returns a <code>bool</code>.</p>
<h3 id="template"><a class="header" href="#template"><code>template</code></a></h3>
<p>Represents an uninitialized object. Equivalent to Ground <code>-struct</code>.</p>
<p><strong>Syntax</strong>:</p>
<pre><code class="language-solstice">template(...)
</code></pre>
<p>where <code>...</code> is multiple pairs of:</p>
<ul>
<li>a type identifier for the field, and</li>
<li>an identifier (representing the field name)</li>
</ul>
<p>seperated by commas.</p>
<p><strong>Example</strong>:</p>
<pre><code class="language-solstice">template(int x, string y)
</code></pre>
<p>This represents a template which, when initialized, has fields x (with integer) and y (with string).</p>
<h3 id="object"><a class="header" href="#object"><code>object</code></a></h3>
<p>Represents an initialized object.</p>
<p><strong>Syntax</strong>:</p>
<pre><code class="language-solstice">object(...)
</code></pre>
<p>where <code>...</code> is multiple pairs of:</p>
<ul>
<li>a type identifier for the field, and</li>
<li>an identifier (representing the field name)</li>
</ul>
<p>seperated by commas.</p>
<p><strong>Example</strong>:</p>
<pre><code class="language-solstice">object(int x, string y)
</code></pre>
<p>This represents a object which has fields x (with integer) and y (with string).</p>
<div style="break-before: page; page-break-before: always;"></div>
<h1 id="variables-1"><a class="header" href="#variables-1">Variables</a></h1>
<p>Variables are defined and modified with the syntax:</p>
<pre><code class="language-solstice">name = value
</code></pre>
<p>where:</p>
<ul>
<li><code>name</code> is an identifier, and</li>
<li><code>value</code> is a literal, expression, or identifier previously assigned to a variable.</li>
</ul>
<p>All variables must have a known type and value at definition time. When updating a variable, the type may not change.</p>
<div style="break-before: page; page-break-before: always;"></div>
<h1 id="scoping-and-lifetimes"><a class="header" href="#scoping-and-lifetimes">Scoping and Lifetimes</a></h1>
<h2 id="subscoping"><a class="header" href="#subscoping">Subscoping</a></h2>
<p>A “subscope” is a scope contained inside a function, created inside curly braces (<code>{}</code>).</p>
<p>Subscopes can view and modify variables avaliable in their parent scope.</p>
<p>Subscopes may also create their own variables, however these will be destroyed when the subscope ends.</p>
<h2 id="function-scoping"><a class="header" href="#function-scoping">Function Scoping</a></h2>
<p>A function scope is a scope created inside a function.</p>
<p>Function scopes are created from a functions attached closure, which is a snapshot of all variables at the time of function definition.</p>
<p>The functions attached closure cannot be modified.</p>
<p>Function scopes also contain all arguments provided to a function.</p>
<p>When the function finishes running (with a <code>return</code>), all variables are destroyed.</p>
<h2 id="destructors"><a class="header" href="#destructors">Destructors</a></h2>
<p>Objects (see <a href="#struct-definition">here</a>) can contain a destructor which specifies custom behaviour for destroying itself. This is useful for:</p>
<ul>
<li>Freeing heap-allocated memory</li>
<li>Closing a connection</li>
<li>Closing a file</li>
</ul>
<p>The destructor will always be in the field <code>destructor</code> with type signature <code>fun() int</code>. It should be automatically called when the variable goes out of scope.</p>
<h2 id="duplicators"><a class="header" href="#duplicators">Duplicators</a></h2>
<p>Objects (see <a href="#struct-definition">here</a>) can contain a duplicator which specifies custom behaviour for copying itself. This is useful for:</p>
<ul>
<li>Duplicating heap-allocated memory</li>
</ul>
<p>The duplicator will always be in the field <code>duplicator</code> with type signature <code>fun((self) old) (self)</code>. It should be automatically called when the variable is:</p>
<ul>
<li>Copied into a new variable</li>
<li>Put inside a closure</li>
<li>Passed to a function</li>
</ul>
<div style="break-before: page; page-break-before: always;"></div>
<h1 id="operators"><a class="header" href="#operators">Operators</a></h1>
<p>Operators are bits of code intended to control how the program runs.</p>
<h2 id="puts"><a class="header" href="#puts"><code>puts</code></a></h2>
<p>Stands for “put something”. Prints debug info to the console, followed by a new line.</p>
<h3 id="formatting"><a class="header" href="#formatting">Formatting</a></h3>
<ul>
<li>
<p>int: The literal number, as formatted by C <code>printf("%" PRId64)</code>.</p>
</li>
<li>
<p>double: The literal number, as formatted by C <code>printf("%f")</code>.</p>
</li>
<li>
<p>string: All characters in the string, as formatted by C <code>printf("%s")</code>.</p>
</li>
<li>
<p>char: The ASCII character corresponding to the number held, as formatted by C <code>printf("%c")</code>.</p>
</li>
<li>
<p>bool: If <code>true</code> or <code>1</code>, print <code>true</code>. Otherwise, print <code>false</code>.</p>
</li>
<li>
<p>fun: Print <code>&lt;function&gt;</code>.</p>
</li>
<li>
<p>template: Print <code>&lt;struct fields: { ... }&gt;</code>, where:</p>
<ul>
<li><code>...</code> is a comma-seperated sequence of <code>key: value</code>, where:
<ul>
<li><code>key</code> is the identifier of the field.</li>
<li><code>value</code> is the properly formatted value in the field.</li>
</ul>
</li>
</ul>
</li>
<li>
<p>object: Print <code>&lt;object fields: { ... }&gt;</code>, where:</p>
<ul>
<li><code>...</code> is a comma-seperated sequence of <code>key: value</code>, where:
<ul>
<li><code>key</code> is the identifier of the field.</li>
<li><code>value</code> is the properly formatted value in the field.</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2 id="if"><a class="header" href="#if"><code>if</code></a></h2>
<p>Runs a block of code only if the provided condition is true.</p>
<p>Syntax:</p>
<pre><code class="language-solstice">if condition {
...
}
</code></pre>
<p>where:</p>
<ul>
<li><code>condition</code> is an expression which evaluates to a boolean.
<ul>
<li>If this expression evaluates to <code>true</code>, the code block will be run.</li>
<li>Brackets surrounding the condition are optional.</li>
</ul>
</li>
<li><code>...</code> is the code to run if the condition is true.</li>
</ul>
<p>Example:</p>
<pre><code class="language-solstice">if 2 + 2 == 4 {
puts "phew!"
}
</code></pre>
<h2 id="while"><a class="header" href="#while"><code>while</code></a></h2>
<p>Runs a block of code until the provided condition is false.</p>
<p>Syntax:</p>
<pre><code class="language-solstice">while condition {
...
}
</code></pre>
<p>where:</p>
<ul>
<li><code>condition</code> is an expression which evaluates to a boolean.
<ul>
<li>If this expression evaluates to <code>false</code>, the code block will not be run anymore.</li>
<li>Brackets surrounding the condition are optional.</li>
</ul>
</li>
<li><code>...</code> is the code to run while the condition is true.</li>
</ul>
<p>Example:</p>
<pre><code class="language-solstice">while true {
puts "To infinity and beyond!"
}
</code></pre>
<h2 id="return"><a class="header" href="#return"><code>return</code></a></h2>
<p>Returns a value from a function.</p>
<p>Syntax:</p>
<pre><code class="language-solstice">return value
</code></pre>
<p>where <code>value</code> is a value with the same type as the functions return type.</p>
<h2 id="ground"><a class="header" href="#ground"><code>ground</code></a></h2>
<p><strong>Inline Ground is potentially dangerous. Only use if you know what youre doing!</strong></p>
<p>Inserts inline Ground code into the generated program.</p>
<p>Syntax:</p>
<pre><code class="language-solstice">ground {
...
}
</code></pre>
<p>where <code>...</code> is the Ground code to insert.</p>
<p>See <a href="https://chookspace.com/ground/ground">here</a> for details about Ground.</p>
<p>Note: <strong>Solstice cannot keep track of state inside <code>ground</code> blocks!</strong> Ground will allow you to do things without the overhead of the Solstice type checker.</p>
<p>To extract a value from a Ground block, do something like this:</p>
<pre><code class="language-solstice">x = 0
ground {
set &amp;x 10
}
puts x
</code></pre>
<p>so the type checker can know what <code>x</code> is.</p>
<h2 id="use"><a class="header" href="#use"><code>use</code></a></h2>
<p>The <code>use</code> operator lets you import code from libraries, either from in the local folder or installed in the <code>$SOLSTICE_LIBS</code> directory, which defaults to <code>/usr/lib/solstice</code>.</p>
<p>When using <code>use</code>, Solstice will insert the selected files contents at that position.</p>
<h3 id="local-use"><a class="header" href="#local-use">Local <code>use</code></a></h3>
<p>Supply a string after <code>use</code> which is the path to the file to import, without the <code>.sols</code> extension.</p>
<pre><code class="language-solstice">use "parser/Node"
use "parser/parser"
</code></pre>
<h3 id="global-use"><a class="header" href="#global-use">Global <code>use</code></a></h3>
<p>Supply an identifier after <code>use</code> which is the name of the library to import, without the <code>.sols</code> extension.</p>
<pre><code class="language-solstice">use io
</code></pre>
<div style="break-before: page; page-break-before: always;"></div>
<h1 id="function-definition"><a class="header" href="#function-definition">Function Definition</a></h1>
<h2 id="named-functions"><a class="header" href="#named-functions">Named Functions</a></h2>
<p>Define a named function with the following syntax:</p>
<pre><code class="language-solstice">def functionName(args) type {
...
}
</code></pre>
<p>where:</p>
<ul>
<li><code>functionName</code> is the name of the function.
<ul>
<li>If <code>functionName</code> is already defined as a function or other value, it will only be overwritten if the type does not change.</li>
</ul>
</li>
<li><code>args</code> is multiple comma-seperated pairs of:
<ul>
<li>a type identifier for the parameter, and</li>
<li>an identifier (representing the parameter name)</li>
</ul>
</li>
<li><code>type</code> is the type of value which the function will return</li>
<li><code>...</code> is the code inside the function (the function body).
<ul>
<li>The function body will have access to previously set variables through a closure. The closure is a copy of all variables in their current state at function definition time.</li>
<li>The function body will also have access to the parameters defined in <code>args</code>.</li>
</ul>
</li>
</ul>
<p>Example:</p>
<pre><code class="language-solstice">def add(int a, int b) int {
return a + b
}
</code></pre>
<h2 id="anonymouslambda-functions"><a class="header" href="#anonymouslambda-functions">Anonymous/Lambda functions</a></h2>
<p>Define a lambda function with the following syntax:</p>
<pre><code class="language-solstice">lambda(args) type {
...
}
</code></pre>
<p>where:</p>
<ul>
<li><code>args</code> is multiple comma-seperated pairs of:
<ul>
<li>a type identifier for the parameter, and</li>
<li>an identifier (representing the parameter name)</li>
</ul>
</li>
<li><code>type</code> is the type of value which the function will return</li>
<li><code>...</code> is the code inside the function (the function body).
<ul>
<li>The function body will have access to previously set variables through a closure. The closure is a copy of all variables in their current state at function definition time.</li>
<li>The function body will also have access to the parameters defined in <code>args</code>.</li>
</ul>
</li>
</ul>
<p>Example:</p>
<pre><code class="language-solstice">add = lambda(int a, int b) int {
return a + b
}
</code></pre>
<p>Lambda functions are most useful when passed as arguments to other functions.</p>
<div style="break-before: page; page-break-before: always;"></div>
<h1 id="struct-definition"><a class="header" href="#struct-definition">Struct Definition</a></h1>
<p>Define a struct with the <code>struct</code> keyword.</p>
<p>Syntax:</p>
<pre><code class="language-solstice">struct StructName {
...
}
</code></pre>
<p>where:</p>
<ul>
<li><code>StructName</code> is the name of your struct</li>
<li><code>...</code> is the body of your struct</li>
</ul>
<h2 id="struct-body"><a class="header" href="#struct-body">Struct Body</a></h2>
<p>Inside the struct body, you can:</p>
<ul>
<li>Define fields</li>
<li>Define methods</li>
<li>Define special methods (<code>constructor</code>, <code>destructor</code>, <code>duplicator</code>, <code>as</code>)</li>
</ul>
<h2 id="defining-fields"><a class="header" href="#defining-fields">Defining fields</a></h2>
<p>A field in a struct is defined in the same way as a variable.</p>
<pre><code class="language-solstice">struct MyStruct {
x = 5
}
</code></pre>
<p>This creates a field named <code>x</code> with a default value of <code>5</code>.</p>
<h2 id="defining-methods"><a class="header" href="#defining-methods">Defining methods</a></h2>
<p>A method in a struct is defined in the same way as a named function.</p>
<pre><code class="language-solstice">struct MyStruct {
def myMethod() int {
return 0
}
}
</code></pre>
<p>Methods have access to the structs members through the <code>self</code> object, which is implicitly passed.</p>
<pre><code class="language-solstice">struct MyStruct {
x = 10
def myMethod() int {
return self.x * 2
}
}
</code></pre>
<h2 id="private-and-protected-fields"><a class="header" href="#private-and-protected-fields">Private and protected fields</a></h2>
<p>A private field is a field which only methods inside the object can read and write.</p>
<p>A protected field is a field which only methods inside the object can write to, however anywhere else in the program the field can be read.</p>
<p>All other fields are public, meaning anywhere in the program can read or write these fields.</p>
<p>Methods and special methods are by default protected, however can be made private.</p>
<pre><code class="language-solstice">struct MyStruct {
private x = 10
protected y = "Hi"
private doSomething() int {
return 14
}
}
</code></pre>
<h2 id="defining-special-methods"><a class="header" href="#defining-special-methods">Defining special methods</a></h2>
<p>In Solstice, objects have some special methods which provide ease of use while handling these objects.</p>
<h3 id="constructor"><a class="header" href="#constructor">Constructor</a></h3>
<p>A constructor is used to initialize an object with user-provided fields.</p>
<p>Define a constructor like this:</p>
<pre><code class="language-solstice">struct MyStruct {
constructor(args) {
...
}
}
</code></pre>
<p>where:</p>
<ul>
<li><code>args</code> is multiple comma-seperated pairs of:
<ul>
<li>a type identifier for the parameter, and</li>
<li>an identifier (representing the parameter name)</li>
</ul>
</li>
<li><code>...</code> is the constructor body
<ul>
<li>The constructor body has access to the <code>self</code> object, which is how it can modify the newly created object.</li>
<li>The <code>self</code> object is automatically returned at the end of the constructor, however can be returned manually if required.</li>
</ul>
</li>
</ul>
<p>Use a constructor like this:</p>
<pre><code class="language-solstice">MyStruct(args)
</code></pre>
<p>where:</p>
<ul>
<li>args is many comma-seperated expressions corresponding to the signature of the defined constructor</li>
</ul>
<h3 id="destructor"><a class="header" href="#destructor">Destructor</a></h3>
<p>A destructor is used to destroy an object once it goes out of scope.</p>
<p>Define a destructor like this:</p>
<pre><code class="language-solstice">struct MyStruct {
destructor {
...
}
}
</code></pre>
<p>where:</p>
<ul>
<li><code>...</code> is the destructor body
<ul>
<li>The destructor body has access to the <code>self</code> object, which is how it can access and modify the object which is being destroyed.</li>
<li>There is no need to return a value from the destructor.</li>
</ul>
</li>
</ul>
<p>Note how the destructor does not take any arguments.</p>
<h3 id="duplicator"><a class="header" href="#duplicator">Duplicator</a></h3>
<p>A duplicator is used to copy an object when it is assigned to a new name, or passed to a function.</p>
<p>Define a duplicator like this:</p>
<pre><code class="language-solstice">struct MyStruct {
duplicator {
...
}
}
</code></pre>
<p>where:</p>
<ul>
<li><code>...</code> is the duplicator body
<ul>
<li>The destructor body has access to the <code>self</code> and <code>old</code> objects.
<ul>
<li>The <code>self</code> object is the new duplication and will be automatically returned</li>
<li>The <code>old</code> object is the old object and will not be copied out</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>Note how the duplicator does not take any arguments.</p>
<h3 id="as-methods"><a class="header" href="#as-methods">As methods</a></h3>
<p>As methods allow easy conversion between different types.</p>
<p>Define an as method like this:</p>
<pre><code class="language-solstice">struct MyStruct {
as type {
...
}
}
</code></pre>
<p>where:</p>
<ul>
<li><code>type</code> is the type which the object will be converted to</li>
<li><code>...</code> is the as method body
<ul>
<li>The <code>self</code> object is avaliable inside the as method</li>
<li>You will need to initialize and return a new value with the specified type</li>
</ul>
</li>
</ul>
<p>Use an as method like this:</p>
<pre><code class="language-solstice">myobj as type
</code></pre>
<p>where:</p>
<ul>
<li><code>myobj</code> is an object with an as method which provides a conversion to <code>type</code></li>
<li><code>type</code> is the target type</li>
</ul>
<div style="break-before: page; page-break-before: always;"></div>
<h1 id="vela-0xx"><a class="header" href="#vela-0xx">“Vela” 0.x.x</a></h1>
<p>Vela is the codename for the 0.x.x releases of Solstice. It is named after the <a href="https://en.wikipedia.org/wiki/Vela_(constellation)">Vela constellation</a>.</p>
<h2 id="changes"><a class="header" href="#changes">Changes</a></h2>
<p>Vela is the prerelease version of Solstice, and is the phase where core compiler features are added. Here are some features added in Vela to the compiler:</p>
<ul>
<li><code>puts</code></li>
<li>Variables</li>
<li>Values</li>
<li>Static type system</li>
<li><code>if</code>, <code>while</code> control flow</li>
<li>Functions
<ul>
<li>Lambda/Anonymous Functions</li>
<li>Named Functions</li>
<li>Closures attached to functions</li>
</ul>
</li>
<li>Structs
<ul>
<li>Fields</li>
<li>Methods</li>
<li><code>private</code> and <code>protected</code></li>
<li><code>as</code>-methods</li>
<li>Constructors, destructors, duplicators</li>
</ul>
</li>
<li>Generics (in progress)</li>
<li><code>pragma</code> directives (in progress)</li>
<li>Libraries with <code>use</code></li>
</ul>
<div style="break-before: page; page-break-before: always;"></div>
<h1 id="vela-010"><a class="header" href="#vela-010">“Vela” 0.1.0</a></h1>
<p>This is the very first release of Solstice! Not much to see here.</p>
<p>This release contains:</p>
<ul>
<li><code>puts</code></li>
<li>Variables</li>
<li>Values</li>
<li>Static type system</li>
<li><code>if</code>, <code>while</code> control flow</li>
<li>Functions
<ul>
<li>Lambda/Anonymous Functions</li>
<li>Named Functions</li>
<li>Closures attached to functions</li>
</ul>
</li>
<li>Structs
<ul>
<li>Fields</li>
<li>Methods</li>
<li><code>private</code> and <code>protected</code></li>
<li><code>as</code>-methods</li>
<li>Constructors, destructors, duplicators</li>
</ul>
</li>
<li>Generics (partially, there are many bugs)</li>
<li><code>pragma</code> directives in the parser</li>
<li>Libraries with <code>use</code></li>
</ul>
<div style="break-before: page; page-break-before: always;"></div>
<h1 id="fornax-1xx"><a class="header" href="#fornax-1xx">“Fornax” 1.x.x</a></h1>
<p>Fornax will be the codename for the 1.x.x releases of Solstice. It is named after the <a href="https://en.wikipedia.org/wiki/Fornax">Fornax constellation</a>.</p>
<h2 id="release-target"><a class="header" href="#release-target">Release Target</a></h2>
<p>Fornax will release when:</p>
<ul>
<li>The compiler core is stable enough to host moderately sized projects</li>
<li>The standard library is capable enough for many programming projects</li>
</ul>
<p>Fornax is not currently released.</p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
</nav>
</div>
<template id=fa-eye><span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M288 32c-80.8 0-145.5 36.8-192.6 80.6C48.6 156 17.3 208 2.5 243.7c-3.3 7.9-3.3 16.7 0 24.6C17.3 304 48.6 356 95.4 399.4C142.5 443.2 207.2 480 288 480s145.5-36.8 192.6-80.6c46.8-43.5 78.1-95.4 93-131.1c3.3-7.9 3.3-16.7 0-24.6c-14.9-35.7-46.2-87.7-93-131.1C433.5 68.8 368.8 32 288 32zM432 256c0 79.5-64.5 144-144 144s-144-64.5-144-144s64.5-144 144-144s144 64.5 144 144zM288 192c0 35.3-28.7 64-64 64c-11.5 0-22.3-3-31.6-8.4c-.2 2.8-.4 5.5-.4 8.4c0 53 43 96 96 96s96-43 96-96s-43-96-96-96c-2.8 0-5.6 .1-8.4 .4c5.3 9.3 8.4 20.1 8.4 31.6z"/></svg></span></template>
<template id=fa-eye-slash><span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M38.8 5.1C28.4-3.1 13.3-1.2 5.1 9.2S-1.2 34.7 9.2 42.9l592 464c10.4 8.2 25.5 6.3 33.7-4.1s6.3-25.5-4.1-33.7L525.6 386.7c39.6-40.6 66.4-86.1 79.9-118.4c3.3-7.9 3.3-16.7 0-24.6c-14.9-35.7-46.2-87.7-93-131.1C465.5 68.8 400.8 32 320 32c-68.2 0-125 26.3-169.3 60.8L38.8 5.1zM223.1 149.5C248.6 126.2 282.7 112 320 112c79.5 0 144 64.5 144 144c0 24.9-6.3 48.3-17.4 68.7L408 294.5c5.2-11.8 8-24.8 8-38.5c0-53-43-96-96-96c-2.8 0-5.6 .1-8.4 .4c5.3 9.3 8.4 20.1 8.4 31.6c0 10.2-2.4 19.8-6.6 28.3l-90.3-70.8zm223.1 298L373 389.9c-16.4 6.5-34.3 10.1-53 10.1c-79.5 0-144-64.5-144-144c0-6.9 .5-13.6 1.4-20.2L83.1 161.5C60.3 191.2 44 220.8 34.5 243.7c-3.3 7.9-3.3 16.7 0 24.6c14.9 35.7 46.2 87.7 93 131.1C174.5 443.2 239.2 480 320 480c47.8 0 89.9-12.9 126.2-32.5z"/></svg></span></template>
<template id=fa-copy><span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M502.6 70.63l-61.25-61.25C435.4 3.371 427.2 0 418.7 0H255.1c-35.35 0-64 28.66-64 64l.0195 256C192 355.4 220.7 384 256 384h192c35.2 0 64-28.8 64-64V93.25C512 84.77 508.6 76.63 502.6 70.63zM464 320c0 8.836-7.164 16-16 16H255.1c-8.838 0-16-7.164-16-16L239.1 64.13c0-8.836 7.164-16 16-16h128L384 96c0 17.67 14.33 32 32 32h47.1V320zM272 448c0 8.836-7.164 16-16 16H63.1c-8.838 0-16-7.164-16-16L47.98 192.1c0-8.836 7.164-16 16-16H160V128H63.99c-35.35 0-64 28.65-64 64l.0098 256C.002 483.3 28.66 512 64 512h192c35.2 0 64-28.8 64-64v-32h-47.1L272 448z"/></svg></span></template>
<template id=fa-play><span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M73 39c-14.8-9.1-33.4-9.4-48.5-.9S0 62.6 0 80V432c0 17.4 9.4 33.4 24.5 41.9s33.7 8.1 48.5-.9L361 297c14.3-8.7 23-24.2 23-41s-8.7-32.2-23-41L73 39z"/></svg></span></template>
<template id=fa-clock-rotate-left><span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M75 75L41 41C25.9 25.9 0 36.6 0 57.9V168c0 13.3 10.7 24 24 24H134.1c21.4 0 32.1-25.9 17-41l-30.8-30.8C155 85.5 203 64 256 64c106 0 192 86 192 192s-86 192-192 192c-40.8 0-78.6-12.7-109.7-34.4c-14.5-10.1-34.4-6.6-44.6 7.9s-6.6 34.4 7.9 44.6C151.2 495 201.7 512 256 512c141.4 0 256-114.6 256-256S397.4 0 256 0C185.3 0 121.3 28.7 75 75zm181 53c-13.3 0-24 10.7-24 24V256c0 6.4 2.5 12.5 7 17l72 72c9.4 9.4 24.6 9.4 33.9 0s9.4-24.6 0-33.9l-65-65V152c0-13.3-10.7-24-24-24z"/></svg></span></template>
<!-- Livereload script (if served using the cli tool) -->
<script>
const wsProtocol = location.protocol === 'https:' ? 'wss:' : 'ws:';
const wsAddress = wsProtocol + "//" + location.host + "/" + "__livereload";
const socket = new WebSocket(wsAddress);
socket.onmessage = function (event) {
if (event.data === "reload") {
socket.close();
location.reload();
}
};
window.onbeforeunload = function() {
socket.close();
}
</script>
<script>
window.playground_copyable = true;
</script>
<script src="elasticlunr-ef4e11c1.min.js"></script>
<script src="mark-09e88c2c.min.js"></script>
<script src="searcher-c2a407aa.js"></script>
<script src="clipboard-1626706a.min.js"></script>
<script src="highlight-d9401a48.js"></script>
<script src="book-a0b12cfe.js"></script>
<!-- Custom JS scripts -->
<script>
window.addEventListener('load', function() {
window.setTimeout(window.print, 100);
});
</script>
</div>
</body>
</html>