Add highlighter
This commit is contained in:
118
docs/highlight.js
Normal file
118
docs/highlight.js
Normal file
@@ -0,0 +1,118 @@
|
||||
// Solstice Syntax Highlighter
|
||||
// Add this script to your HTML file before the closing </body> tag
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
highlightAllCode();
|
||||
});
|
||||
|
||||
function highlightAllCode() {
|
||||
const codeElements = document.querySelectorAll('pre.code code');
|
||||
codeElements.forEach(element => {
|
||||
// Get the text content (this automatically decodes HTML entities)
|
||||
const code = element.textContent;
|
||||
element.innerHTML = highlightSolstice(code);
|
||||
});
|
||||
}
|
||||
|
||||
function highlightSolstice(code) {
|
||||
let result = '';
|
||||
let i = 0;
|
||||
|
||||
// Tokenize the code
|
||||
while (i < code.length) {
|
||||
let matched = false;
|
||||
|
||||
// Check for comments
|
||||
if (code.substr(i, 2) === '//') {
|
||||
let end = code.indexOf('\n', i);
|
||||
if (end === -1) end = code.length;
|
||||
result += `<span class="comment">${escapeHtml(code.substring(i, end))}</span>`;
|
||||
i = end;
|
||||
matched = true;
|
||||
}
|
||||
|
||||
// Check for strings
|
||||
else if (code[i] === '"') {
|
||||
let end = i + 1;
|
||||
while (end < code.length && code[end] !== '"') {
|
||||
if (code[end] === '\\') end++; // Skip escaped characters
|
||||
end++;
|
||||
}
|
||||
end++; // Include closing quote
|
||||
result += `<span class="string">${escapeHtml(code.substring(i, end))}</span>`;
|
||||
i = end;
|
||||
matched = true;
|
||||
}
|
||||
|
||||
// Check for numbers
|
||||
else if (/\d/.test(code[i])) {
|
||||
let end = i;
|
||||
while (end < code.length && /[\d.]/.test(code[end])) {
|
||||
end++;
|
||||
}
|
||||
result += `<span class="number">${code.substring(i, end)}</span>`;
|
||||
i = end;
|
||||
matched = true;
|
||||
}
|
||||
|
||||
// Check for keywords, types, built-ins, and identifiers
|
||||
else if (/[a-zA-Z_]/.test(code[i])) {
|
||||
let end = i;
|
||||
while (end < code.length && /[a-zA-Z0-9_]/.test(code[end])) {
|
||||
end++;
|
||||
}
|
||||
const word = code.substring(i, end);
|
||||
|
||||
// Check what type of word it is
|
||||
if (['def', 'if', 'while', 'return', 'ground', 'puts'].includes(word)) {
|
||||
result += `<span class="keyword">${word}</span>`;
|
||||
} else if (['input', 'print', 'println'].includes(word)) {
|
||||
result += `<span class="builtin">${word}</span>`;
|
||||
} else if (['int', 'double', 'string', 'char', 'bool'].includes(word)) {
|
||||
result += `<span class="type">${word}</span>`;
|
||||
} else if (['true', 'false'].includes(word)) {
|
||||
result += `<span class="boolean">${word}</span>`;
|
||||
} else {
|
||||
// Check if it's a function call (followed by '(')
|
||||
let j = end;
|
||||
while (j < code.length && /\s/.test(code[j])) j++;
|
||||
if (code[j] === '(') {
|
||||
result += `<span class="function">${word}</span>`;
|
||||
} else {
|
||||
result += word;
|
||||
}
|
||||
}
|
||||
i = end;
|
||||
matched = true;
|
||||
}
|
||||
|
||||
// Check for operators
|
||||
else if ('+-*/=!<>'.includes(code[i])) {
|
||||
let op = code[i];
|
||||
if (i + 1 < code.length && '='.includes(code[i + 1])) {
|
||||
op += code[i + 1];
|
||||
i++;
|
||||
}
|
||||
result += `<span class="operator">${escapeHtml(op)}</span>`;
|
||||
i++;
|
||||
matched = true;
|
||||
}
|
||||
|
||||
// Everything else (whitespace, braces, etc.)
|
||||
if (!matched) {
|
||||
result += escapeHtml(code[i]);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function escapeHtml(text) {
|
||||
return text
|
||||
.replace(/&/g, '&')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
.replace(/"/g, '"')
|
||||
.replace(/'/g, ''');
|
||||
}
|
||||
@@ -78,3 +78,42 @@ h2 {
|
||||
h3 {
|
||||
font-size: 25px;
|
||||
}
|
||||
|
||||
/* Syntax highlighting styles for Solstice */
|
||||
.comment {
|
||||
color: #6c757d;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.string {
|
||||
color: #98c379;
|
||||
}
|
||||
|
||||
.number {
|
||||
color: #d19a66;
|
||||
}
|
||||
|
||||
.keyword {
|
||||
color: #c678dd;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.builtin {
|
||||
color: #61afef;
|
||||
}
|
||||
|
||||
.type {
|
||||
color: #e5c07b;
|
||||
}
|
||||
|
||||
.boolean {
|
||||
color: #d19a66;
|
||||
}
|
||||
|
||||
.operator {
|
||||
color: #56b6c2;
|
||||
}
|
||||
|
||||
.function {
|
||||
color: #61afef;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
<title>Solstice Docs</title>
|
||||
<link rel="stylesheet" href="https://sols.dev/index.css">
|
||||
<link rel="stylesheet" href="index.css">
|
||||
<script src="highlight.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="box">
|
||||
@@ -36,7 +37,8 @@
|
||||
<p>Solstice's compiler is invoked via the <code>solstice</code> command. It provides some options:</p>
|
||||
<ul>
|
||||
<li><code>-o</code> or <code>--output</code>: Tells Solstice where to output a compiled file.</li>
|
||||
<li><code>-t</code> or <code>--type</code>: Tells Solstice the type of file to output.<br>At present, Solstice only supports Ground source files as an output type, but more types may be added in future.</li>
|
||||
<li><code>-t</code> or <code>--type</code>: Tells Solstice the type of file to output.
|
||||
At present, Solstice only supports Ground source files as an output type, but more types may be added in future.</li>
|
||||
</ul>
|
||||
<p>Example usage:</p>
|
||||
<pre class="code"><code>solstice fib.sols -o fib.grnd</code></pre>
|
||||
@@ -60,16 +62,20 @@ puts true
|
||||
puts "You can print out anything with puts!"</code></pre>
|
||||
<h3>Variables</h3>
|
||||
<p>Solstice variables are quite simple. Assign values with <code>=</code>, and read them with the variable name.</p>
|
||||
<pre class="code"><code>x = 5<br>puts x</code></pre>
|
||||
<pre class="code"><code>x = 5
|
||||
puts x</code></pre>
|
||||
<p>Types are automatically inferred by Solstice.</p>
|
||||
<h3>Maths</h3>
|
||||
<p>You can use <code>+</code> (add), <code>-</code> (subtract), <code>*</code> (multiply), and <code>/</code> (divide) to do math.</p>
|
||||
<p>Math operations take two values on either side, and perform the operation. Order of operations is supported.</p>
|
||||
<pre class="code"><code>x = 5 + 3<br>y = 10<br>puts x + y</code></pre>
|
||||
<pre class="code"><code>x = 5 + 3
|
||||
y = 10
|
||||
puts x + y</code></pre>
|
||||
<h3>Control Flow and Equalities</h3>
|
||||
<p>Solstice supports <code>if</code> and <code>while</code> statements, as well as the <code>==</code>, <code>!=</code>, <code>></code>, <code>>=</code>, <code><</code>, and <code><=</code> operations.</p>
|
||||
<p>Conditionals work just like maths: two values on either side, check whether the condition is correct or not based on those values, and output a boolean.</p>
|
||||
<pre class="code"><code>puts 5 == 5<br>puts 5 != 5</code></pre>
|
||||
<pre class="code"><code>puts 5 == 5
|
||||
puts 5 != 5</code></pre>
|
||||
<p><code>if</code> and <code>while</code> statements take a conditional, and then a code block afterwards. See these examples:</p>
|
||||
<pre class="code"><code>x = 5
|
||||
if x > 10 {
|
||||
@@ -91,7 +97,9 @@ while number < 10 {
|
||||
</code>
|
||||
<h3>Functions</h3>
|
||||
<p><strong>Note:</strong> Functions in Solstice are currently in beta. Type checking for functions is currently experimental, and arguments may not work as intended. Be warned!</p>
|
||||
<p>In Solstice, function definitions have a syntax like this: <pre class="code"><code>def functionName(type arg1, type arg2, type arg3) returnType {<br> // code goes here<br>}</code></pre></p>
|
||||
<p>In Solstice, function definitions have a syntax like this: <pre class="code"><code>def functionName(type arg1, type arg2, type arg3) returnType {
|
||||
// code goes here
|
||||
}</code></pre></p>
|
||||
<p>Your types can be <code>int</code>, <code>double</code>, <code>string</code>, <code>bool</code>, or <code>char</code> (see the "Type System" section for more details)</p>
|
||||
<p>Return a value (which must be the same type as your <code>returnType</code>) with <code>return value</code>.</p>
|
||||
<p>Here's an example function:</p>
|
||||
@@ -134,14 +142,20 @@ while number < 10 {
|
||||
<p>Inline Ground is not vetted by the type checker. <strong>Be careful when modifying existing variables with inline ground!</strong> The type checker is not aware of any values created inside inline Ground.</p>
|
||||
<p>If you would like the Solstice type checker to be aware of values created by Ground, initialise a variable with a blank of whatever type is made by Ground.</p>
|
||||
<p>Variable names are the same inside inline Ground as they are in Solstice. Read Ground's syntax guide for an understanding on how it should work <a href="https://chookspace.com/ground/cground/src/branch/master/docs/syntax.md">here</a>.</p>
|
||||
<pre class="code"><code>ground {<br> set &x 5<br> println $x<br>}</code></pre>
|
||||
<pre class="code"><code>ground {
|
||||
set &x 5
|
||||
println $x
|
||||
}</code></pre>
|
||||
</div>
|
||||
<div id="builtins">
|
||||
<h2>Built In Functions</h2>
|
||||
<div id="input_string_msg__string">
|
||||
<h3>input(string msg) string</h3>
|
||||
<p>Gets user input from the console until the next line. The msg is used as a prompt for the user. Returns inputted characters from the console.</p>
|
||||
<pre class="code"><code>guess = input("What is the password? ")<br>if guess == "password123" {<br> puts "Good job!"<br>}</code></pre>
|
||||
<pre class="code"><code>guess = input("What is the password? ")
|
||||
if guess == "password123" {
|
||||
puts "Good job!"
|
||||
}</code></pre>
|
||||
</div>
|
||||
<div id="print_string_msg__string">
|
||||
<h3>print(string msg) string</h3>
|
||||
|
||||
Reference in New Issue
Block a user