Files
sols.dev/docs/print.html

1029 lines
47 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-c698e2a6.js";
</script>
<!-- Start loading toc.js asap -->
<script src="toc-cb4e10de.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 docs! For now, the documentation is in the format of a specification, which instructs you on how Solstice should behave. In future, a tutorial (similar to the Rust book) will be written which shows you each part of the language, instead of declaring it like the spec.</p>
<p>Docs generated by mdBook.</p>
<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"><a class="header" href="#comments">Comments</a></h1>
<p>Comments in Solstice can be done in 3 ways:</p>
<h2 id="-single-line-comment"><a class="header" href="#-single-line-comment"><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"><a class="header" href="#--multiline-comment"><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"><a class="header" href="#-shebang-comment"><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"><a class="header" href="#int"><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"><a class="header" href="#double"><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"><a class="header" href="#string"><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"><a class="header" href="#char"><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"><a class="header" href="#bool"><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"><a class="header" href="#variables">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>
<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>
</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>
<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>