diff --git a/src/components/InteractiveCode.astro b/src/components/InteractiveCode.astro
index 4d650ae..3b62e89 100644
--- a/src/components/InteractiveCode.astro
+++ b/src/components/InteractiveCode.astro
@@ -2,77 +2,9 @@
import { lex } from "../lexer/lexer";
import type { Instruction } from "../thp_machine/machine_parser";
import { parse_str } from "../thp_machine/machine_parser";
+import { trimAndDedent } from "./utils";
const {code, steps} = Astro.props;
-/**
- * Performs the following:
- * - Removes the first & last line, if they are empty
- * - Picks the indentation level from the first non-white line
- * - Dedents the following lines
-*/
-function trimAndDedent(input: string): Array {
- let lines = input.split("\n");
-
- // Remove empty lines at the start
- while (lines[0] === "") {
- lines = lines.slice(1);
- }
-
- // Get indentation level
- let indentationLevel = 0;
- for (const char of lines[0]!) {
- if (char === " ") {
- indentationLevel += 1;
- } else {
- break;
- }
- }
-
- // Enforce indentation, or trim
- for (let i = 0; i < lines.length; i += 1) {
- // If the line is empty, continue
- const characters = lines[i]!.split("");
- if (characters.length === 0) {
- continue;
- }
-
- // If all characters are whitespace, append just a newline
- const nonWhitespace = characters.find((x) => x !== " ");
- if (nonWhitespace === undefined) {
- lines[i] = "";
- continue;
- }
-
- // Enforce indentation
- if (characters.length < indentationLevel) {
- throw new Error("Invalid indentation while parsing THP code: " + lines[i]);
- }
- let currentIndentation = 0;
- for (const c of characters) {
- if (c === " ") { currentIndentation += 1 }
- else {break;}
- }
- if (currentIndentation < indentationLevel) {
- throw new Error("Invalid indentation while parsing THP code: " + lines[i]);
- }
-
- lines[i] = characters.slice(4).join("");
- }
-
-
- // Remove empty lines at the end
- let endPosition = lines.length - 1;
- while (true) {
- if (lines[endPosition] === "") {
- lines = lines.slice(0, -1);
- endPosition -= 1;
- } else {
- break;
- }
- }
-
- return lines;
-}
function highlightCode(lines: Array): string {
let outLines: Array = [];
diff --git a/src/components/utils.ts b/src/components/utils.ts
new file mode 100644
index 0000000..d7548f7
--- /dev/null
+++ b/src/components/utils.ts
@@ -0,0 +1,70 @@
+
+/**
+ * Performs the following:
+ * - Removes the first & last line, if they are empty
+ * - Picks the indentation level from the first non-white line
+ * - Dedents the following lines
+*/
+export function trimAndDedent(input: string): Array {
+ let lines = input.split("\n");
+
+ // Remove empty lines at the start
+ while (lines[0] === "") {
+ lines = lines.slice(1);
+ }
+
+ // Get indentation level
+ let indentationLevel = 0;
+ for (const char of lines[0]!) {
+ if (char === " ") {
+ indentationLevel += 1;
+ } else {
+ break;
+ }
+ }
+
+ // Enforce indentation, or trim
+ for (let i = 0; i < lines.length; i += 1) {
+ // If the line is empty, continue
+ const characters = lines[i]!.split("");
+ if (characters.length === 0) {
+ continue;
+ }
+
+ // If all characters are whitespace, append just a newline
+ const nonWhitespace = characters.find((x) => x !== " ");
+ if (nonWhitespace === undefined) {
+ lines[i] = "";
+ continue;
+ }
+
+ // Enforce indentation
+ if (characters.length < indentationLevel) {
+ throw new Error("Invalid indentation while parsing THP code: " + lines[i]);
+ }
+ let currentIndentation = 0;
+ for (const c of characters) {
+ if (c === " ") { currentIndentation += 1 }
+ else {break;}
+ }
+ if (currentIndentation < indentationLevel) {
+ throw new Error("Invalid indentation while parsing THP code: " + lines[i]);
+ }
+
+ lines[i] = characters.slice(4).join("");
+ }
+
+
+ // Remove empty lines at the end
+ let endPosition = lines.length - 1;
+ while (true) {
+ if (lines[endPosition] === "") {
+ lines = lines.slice(0, -1);
+ endPosition -= 1;
+ } else {
+ break;
+ }
+ }
+
+ return lines;
+}
\ No newline at end of file
diff --git a/src/lexer/identifier_lexer.ts b/src/lexer/identifier_lexer.ts
index 773e9d4..a531c52 100644
--- a/src/lexer/identifier_lexer.ts
+++ b/src/lexer/identifier_lexer.ts
@@ -34,7 +34,7 @@ export function scan_identifier(input: string, starting_position: number, is_dat
}
function check_keyword(value: string): string {
- const keywords = ["throws", "extends", "constructor", "case", "static", "const", "enum", "union", "loop", "use", "break", "catch", "continue", "do", "else", "finally", "for", "fun", "if", "in", "fn", "nil", "return", "throw", "try", "while", "type", "match", "with", "of", "abstract", "class", "interface", "private", "pub", "override", "open", "init", "val", "var", "mut", "clone"];
+ const keywords = ["throws", "extends", "constructor", "case", "static", "const", "enum", "union", "loop", "use", "break", "catch", "continue", "as", "do", "else", "finally", "for", "fun", "if", "in", "fn", "nil", "return", "throw", "try", "while", "type", "match", "with", "of", "abstract", "class", "interface", "private", "pub", "override", "open", "init", "val", "var", "mut", "clone"];
if (keywords.includes(value)) {
return "keyword";
diff --git a/src/pages/index.astro b/src/pages/index.astro
index 7fe69e9..3a55630 100644
--- a/src/pages/index.astro
+++ b/src/pages/index.astro
@@ -1,13 +1,14 @@
---
import BaseLayout from "../layouts/BaseLayout.astro";
import Navbar from "../components/Navbar.astro";
+import CodeEditor from "../components/CodeEditor.astro";
---
@@ -21,7 +22,7 @@ import Navbar from "../components/Navbar.astro";
compiled to PHP
- Inspired by Rust, Zig and Swift, THP has a modern syntax,
+ Inspired by Rust, Zig and Kotlin, THP has a modern syntax,
semantics, type system and stdlib.
@@ -46,49 +47,99 @@ import Navbar from "../components/Navbar.astro";
-
-
-
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+ THP is actually typed
+
+
+
+
+
+
+ THP enforces type safety at compile time and, at the programmer's
+ request, at runtime.
+
+
+ Everything has a type.
+ There are generics.
+ No implicit type conversions. No mixed.
+ No client Any .Type inference included.
+
+
+ All possible checks are made at compile time. Runtime checks
+ have a small performance penalty.
+
+
+
+ Any { ... }
+
+ // Compile error: Cannot use \`Any\` without an explicit cast
+ val result = mock()
+ // Ok
+ val result = mock() as String
+ `} />
+