Compare commits

..

No commits in common. "733921a2ff2282436a7f0f6adc301ecda275c091" and "1714d7ee767010fda65cee42b891f08f934d53a9" have entirely different histories.

2 changed files with 135 additions and 218 deletions

View File

@ -1,36 +0,0 @@
---
import CodeEditor from "./CodeEditor.astro";
const { title, thpcode, subtitle } = Astro.props;
if (!subtitle) {
throw new Error("subtitle is required");
}
if (!thpcode) {
throw new Error("thpcode is required");
}
if (!title) {
throw new Error("title is required");
}
---
<div>
<div class="bg-c-thp text-c-bg">
<h1 class="container mx-auto font-medium py-8 text-3xl">
{subtitle} <span class="font-black">{title}</span>
</h1>
</div>
<div class="container mx-auto lg:grid lg:grid-cols-2 gap-4">
<div class="px-8 py-12 flex h-full items-center">
<div>
<slot />
</div>
</div>
<div>
<CodeEditor thpcode={thpcode} />
</div>
</div>
</div>

View File

@ -2,203 +2,156 @@
import BaseLayout from "../layouts/BaseLayout.astro"; import BaseLayout from "../layouts/BaseLayout.astro";
import Navbar from "../components/Navbar.astro"; import Navbar from "../components/Navbar.astro";
import CodeEditor from "../components/CodeEditor.astro"; import CodeEditor from "../components/CodeEditor.astro";
import HeroSection from "../components/HeroSection.astro";
--- ---
<BaseLayout> <BaseLayout>
<Navbar showSidebarButton={false} /> <Navbar showSidebarButton={false} />
<div <div
class="container mx-auto lg:py-16 pb-2 pt-20 lg:grid 2xl:grid-cols-[auto_32rem] lg:grid-cols-[auto_36rem] gap-4 lg:px-10 px-2 min-h-[85vh]" class="container mx-auto lg:py-16 pb-2 pt-20 lg:grid 2xl:grid-cols-[auto_32rem] lg:grid-cols-[auto_36rem] gap-4 lg:px-10 px-2 min-h-[85vh]"
> >
<div class="lg:pl-10 table"> <div class="lg:pl-10 table">
<div class="table-cell align-middle"> <div class="table-cell align-middle">
<h1 <h1
class="font-display font-bold text-c-text-2 lg:text-5xl text-3xl lg:text-left text-center leading-tight" class="font-display font-bold text-c-text-2 lg:text-5xl text-3xl lg:text-left text-center leading-tight"
> >
A modern, type safe, A modern, type safe,
<br class="hidden lg:inline-block" /> <br class="hidden lg:inline-block" />
secure language secure language
<br class="hidden lg:inline-block" /> <br class="hidden lg:inline-block" />
compiled to PHP compiled to PHP
</h1> </h1>
<p class="font-display text-c-text text-xl pt-6 lg:pr-12"> <p class="font-display text-c-text text-xl pt-6 lg:pr-12">
Inspired by Rust, Zig and Kotlin, THP has a modern syntax, Inspired by Rust, Zig and Kotlin, THP has a modern syntax,
semantics, type system and stdlib. semantics, type system and stdlib.
</p> </p>
<br /> <br />
<br /> <br />
<div class="text-center"> <div class="text-center">
<a <a
class="inline-block font-display text-lg rounded-full border-2 border-pink-400 py-2 px-8 class="inline-block font-display text-lg rounded-full border-2 border-pink-400 py-2 px-8
transition-colors hover:text-black hover:bg-pink-400" transition-colors hover:text-black hover:bg-pink-400"
href="/learn/" href="/learn/"
> >
Tutorial Tutorial
</a> </a>
<a <a
class="inline-block font-display text-lg border-2 border-sky-400 py-2 px-8 mx-6 rounded-full class="inline-block font-display text-lg border-2 border-sky-400 py-2 px-8 mx-6 rounded-full
transition-colors hover:text-black hover:bg-sky-400" transition-colors hover:text-black hover:bg-sky-400"
href="/install/" href="/install/"
> >
Install Install
</a> </a>
</div> </div>
</div> </div>
</div> </div>
<div class="table"> <div class="table">
<div class="table-cell align-middle"> <div class="table-cell align-middle">
<div <div
class="bg-[var(--code-theme-bg-color)] lg:p-6 p-2 rounded-lg relative w-full" class="bg-[var(--code-theme-bg-color)] lg:p-6 p-2 rounded-lg relative w-full"
> >
<span <span
class="absolute lg:inline-block hidden h-[35rem] w-[35rem] -z-10 top-1/2 left-1/2 rounded-full class="absolute lg:inline-block hidden h-[35rem] w-[35rem] -z-10 top-1/2 left-1/2 rounded-full
transform -translate-x-1/2 -translate-y-1/2" transform -translate-x-1/2 -translate-y-1/2"
style="background-image: conic-gradient(from 180deg at 50% 50%,#5BCEFA 0deg,#a853ba 180deg,#F5A9B8 1turn); style="background-image: conic-gradient(from 180deg at 50% 50%,#5BCEFA 0deg,#a853ba 180deg,#F5A9B8 1turn);
filter: blur(75px); opacity: 0.75;" filter: blur(75px); opacity: 0.75;"
> >
</span> </span>
<svg <svg
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
width="54" width="54"
height="14" height="14"
viewBox="0 0 54 14" viewBox="0 0 54 14"
> >
<g <g fill="none" fill-rule="evenodd" transform="translate(1 1)">
fill="none" <circle
fill-rule="evenodd" cx="6"
transform="translate(1 1)" cy="6"
> r="6"
<circle fill="#FF5F56"
cx="6" stroke="#E0443E"
cy="6" stroke-width=".5"></circle>
r="6" <circle
fill="#FF5F56" cx="26"
stroke="#E0443E" cy="6"
stroke-width=".5"></circle> r="6"
<circle fill="#FFBD2E"
cx="26" stroke="#DEA123"
cy="6" stroke-width=".5"></circle>
r="6" <circle
fill="#FFBD2E" cx="46"
stroke="#DEA123" cy="6"
stroke-width=".5"></circle> r="6"
<circle fill="#27C93F"
cx="46" stroke="#1AAB29"
cy="6" stroke-width=".5"></circle>
r="6" </g>
fill="#27C93F" </svg>
stroke="#1AAB29" <div class="h-1"></div>
stroke-width=".5"></circle> <div id="editor" class="font-mono language-thp"></div>
</g> </div>
</svg> </div>
<div class="h-1"></div> </div>
<div id="editor" class="font-mono language-thp"></div> </div>
</div>
</div>
</div>
</div>
<HeroSection <div>
subtitle="We've got" <div class="bg-c-thp text-c-bg">
title="generics" <h1 class="container mx-auto font-medium py-8 text-3xl">
thpcode={` THP is <span class="font-black">actually typed</span>
Array[Int] numbers = [0, 1, 2, 3, 4, 5] </h1>
</div>
numbers.push("7") // Compile error: expected an Int, found a String <div class="container mx-auto lg:grid lg:grid-cols-2 gap-4">
<div class="px-8 py-12 flex h-full items-center">
<div>
THP enforces type safety at compile time and, at the programmer's
request, at runtime.
<br>
<br>
Everything has a type.
There are generics.
No implicit type conversions. No <code>mixed</code>.
No client <code>Any</code> .Type inference included.
<br>
<br>
All possible checks are made at compile time. Runtime checks
have a small performance penalty.
</div>
</div>
<div>
<CodeEditor thpcode={`
Array[Int] numbers = [0, 1, 2, 3, 4, 5]
// Runtime type checking numbers.push("7") // Compile error: expected an Int, found a String
val object = try JSON::decode(data)
val name = try object.get[String]("name")
// Any is available, but it's not usable without an explicit cast // Runtime type checking
fun mock() -> Any { ... } val object = try JSON::decode(data)
val name = try object.get[String]("name")
// Compile error: Cannot use \`Any\` without an explicit cast // Any is available, but it's not usable without an explicit cast
val result = mock() fun mock() -> Any { ... }
// Ok
val result = mock() as String
`}
>
THP enforces type safety at compile time and, at the programmer's
request, at runtime.
<br />
<br />
Everything has a type. There are generics. No implicit type conversions.
No <code>mixed</code>. No client <code>Any</code> .Type inference included.
<br />
<br />
All possible checks are made at compile time. Runtime checks have a small
performance penalty.
</HeroSection>
<HeroSection // Compile error: Cannot use \`Any\` without an explicit cast
subtitle="We've got" val result = mock()
title="tagged unions" // Ok
thpcode={` val result = mock() as String
union DirEntry { `} />
File(String), </div>
Dir(String), </div>
} </div>
val root = DirEntry::Dir("/") <script>
`} import { thp_highlighter, CodeJar } from "../lexer/highlighter";
>
Make invalid state irrepresentable.
<br>
Model data in a type-safe way.
<br>
Ensure all cases are handled.
</HeroSection>
<HeroSection let jar = CodeJar(document.getElementById("editor")!, thp_highlighter, {
subtitle="We've got" tab: " ",
title="pattern matching" });
thpcode={`
match test_file
case DirEntry::File(filename)
if !filename.starts_with(".")
{
print(filename)
}
else
{
print("A valid file was not found")
}
`}
>
Match on values, tuples, enums, unions, types etc.
<br>
Guards available!
</HeroSection>
<HeroSection jar.updateCode(
subtitle="We've got" `union Animal {
title="null safety"
thpcode={`
String? username = Globals::Post::get("username")
if username? {
// username is a \`String\` here
print("Hello, {username}")
}
`}
>
Nulls are explicit and require handling.
</HeroSection>
<script>
import { thp_highlighter, CodeJar } from "../lexer/highlighter";
let jar = CodeJar(document.getElementById("editor")!, thp_highlighter, {
tab: " ",
});
jar.updateCode(
`union Animal {
Dog(String), Dog(String),
Cat(String, Int), Cat(String, Int),
} }
@ -216,10 +169,10 @@ case Dog(name)
case Cat(name, lives) { case Cat(name, lives) {
print("{name} has {lives}") print("{name} has {lives}")
}`, }`,
); );
</script> </script>
<script> <script>
import { highlightOnDom } from "../layouts/thpHighlighter"; import {highlightOnDom} from "../layouts/thpHighlighter";
document.addEventListener("DOMContentLoaded", highlightOnDom); document.addEventListener("DOMContentLoaded", highlightOnDom);
</script> </script>
</BaseLayout> </BaseLayout>