Improve landing page

This commit is contained in:
Araozu 2023-10-01 20:41:38 -05:00
parent 5f5ae25060
commit cb5b87488a
29 changed files with 852 additions and 510 deletions

View File

@ -0,0 +1,51 @@
# Union types
## Basic enums
```thp
enum Suit
{
Hearts,
Diamonds,
Clubs,
Spades,
}
val suit = Suit::Hearts
```
## Enums with values
```thp
enum IpAddress
{
V4(String),
V6(String),
}
val addr_1 = IpAddress::V4("192.168.0.1")
match addr_1
| IpAddress::V4(ip)
{
// code..
}
| IpAddress::V6(ip)
{
// more code..
}
// Without the full qualifier
match addr_1
| ::V4(ip)
{
// code...
}
| ::V6(ip)
{
// even more code...
}
```

View File

@ -1,80 +1,28 @@
# Comments
You may have noticed that in some code examples there are some
lines of text explaining the code:
Only these two:
```thp
// This is the variable
val person = "John"
```
Comments are used to explain what the code does. Anything written
in a comment is ignored by THP.
## Single line comments
As the name says, these comments span only 1 line. To create one write
two slashes together `//`. Everything after the slashes and before
the newline will be ignored.
## Single line
```thp
// This is a single line comment
// You can write anything you want here, although it's usually
// used to describe the code
// The commend ends where the line ends,
so this line will not be ignored by THP, and will throw an error
```
## Multi line comments
As the name says, these comments can span multiple lines.
They have 2 components: a start and a end. To start a multiline comment
write a slash and asterisk `/*`, and to end the comment, the inverse `*/`
## Multi line
```thp
/*
This is a multiline comment.
I can write whatever I want here, and across multiple
lines, as long as I'm before the closing characters (* /)
This is a
multiline comment
*/
```
```thp
/*
Multiline comments
can be /* nested */
*/
```
## Using comments to prevent code execution
Since comments are ignored by THP, we can use them to prevent certain
parts of the code from running.
Let's say we have this script:
```thp
print("Hello John")
print("How's your day going?")
```
If I wanted the 2nd line not to execute, I can use a comment:
```thp
print("Hello John")
// print("How's your day going?")
```
Now the second line is ignored, and the message is not printed.
The same can be done with multiline comments.
```thp
print("Hello John")
/*
print("How's your day going?")
*/
```

View File

@ -1,127 +1,45 @@
# Datatypes
Programming is comprised of 2 basic things: instructions and data.
Datatypes's first character are always uppercase.
If we compare a program to a cake recipe, the instructions are the steps
(**pour** flour, **add** water, **add** egg, **mix**) and the data are the ingredients
themselves (flour, water, egg).
## Int
![Image](Image)
Then, we can describe the recipe in terms of instructions and data. For example,
"mix flour and egg to produce dough".
![Image](Image)
All code is like a recipe: A list of instructions and data that, when combined
correctly, are able to transform a input to an output. Many advanced concepts
are just ways to organize and abstract those instructions and data.
## Classifying datatypes
As with food, datatypes can be classified. Just like there are fruits, vegetables,
oils, there are `numbers`, `text`, `"booleans"`.
### Int
Int is an abbreviation for "integer numbers", which are numbers without a fractional component.
They can be positive or negative.
In code, they are written just like numbers:
Same as php int
```thp
val age = 33
val children = 0
val money = -15000
```
You can use underscores to help you differentiate thousands, millions, etc.
However, there cannot be spaces in between
```thp
val studentDebt = 3_500_000_000_000 // Valid
val invalid = 3 500 000 000 000 // Invalid, will throw an error
```
The common operations can be done as in math:
```thp
val result1 = 10 + 20
val result2 = 1779 * 2 - (55 / 5)
Int age = 32
Int red = 0xff0000
Int char_code = 0b01000110
```
### Float
## Float
Float is an abbreviation for "floating point numbers". In simplified terms, these are numbers
**with** a fractional component.
They are written with a dot `.` to separate the whole part and the fraction.
```thp
val pi = 3.141592
val epsilon = 2.775557
```
Underscore can also be used:
```thp
val reallyLongNumber = 23_870_000.443_879
```
Common operations can be performed the same way:
```thp
val value1 = 552.23 - 32
val value2 = 3.2 * (-0.22 + 23.334) / 0.5
// etc.
```
### String
A string of letters (technically, characters). Strings are used to represent text,
and are wrapped in quotation marks.
```thp
val name = "John"
val lastName = "Doe"
val greeting = "Hello"
```
#### Concatenation
Strings cannot be added, substracted, multiplied, divided.
They have another operation, called "concatenation".
Concatenation "joins" two strings, for example, the concatenation of
`"human"` and `"kind"` is `"humankind"`.
As it is a common operation, string concatenation reuses the operation
for addition `+`.
```thp
val string = "human" + "kind"
```
### Boolean
A boolean represents something that can only be in one of two states.
Booleans are useful in conditionals, which will be explained later.
Same as php float
```thp
val condition = true
val isSunny = false
if isSunny {
doSomething()
}
Float pi = 3.141592
```
## String
Same as php string
```thp
String name = "Rose"
```
## Bool
Same as php bool
```thp
Bool is_true = true
```

View File

@ -1,60 +1,9 @@
# Hello, world!
This pages shows you how to write and run your first THP script.
## Prerequisites
You will need to have PHP and THP installed. If you haven't already, see the
install page.
## Writing the program
Create a new file called `hello.thp`, and inside write the following (you can
copy and paste):
Create a file named `hello.thp` with the contents:
```thp
print("Hello, world!")
```
Then, save the code.
## Running the program
Open a terminal in the folder where you created the file `hello.thp`.
Then write the following command and press enter:
```sh
thp hello.thp
```
This will run the program, and produce the following result:
```sh
Hello, world!
```
Congratulations! You just wrote your first THP program!
## Explaining the program
Now let's understand the code.
```thp
print("Hello, world!")
```
There are 2 essential components:
- `print` - print is a "function", it takes some value and performs some action with it.
In this case, it takes a text and displays it in the terminal.
- `"Hello, world!"` - Is the text that the function `print` takes, and displays in
the terminal. Note that it is enclosed in quotation marks.
## What to do next
You can now experiment with the program you wrote. What happens if you change the text?
What if you don't put quotation marks? And what are the parenthesis for?
To continue learning about THP, continue to the next page, where you'll learn
about "datatypes".
Then run `thp hello.thp`

View File

@ -1,64 +0,0 @@
# Input & Output
At the end of the day, a program takes some input,
and transform it to some output. We will explore how to
receive data, and also present it.
## Output
There are many ways to show the result of our programs.
One of them is called `standard output`, which in simplified
terms, is the terminal from where we run our program.
### `print`
Create an empty file, and name it `hello.php`. We will create
a program that shows a result to our screen.
Inside `hello.php` write the following code:
```thp
print("Hello")
```
Then, open a terminal and run the program with the `thp` command.
After you press ENTER, you will see in the terminal the text "Hello".
```sh
$ thp hello.thp # Copy this command and run it
Hello # This is the output of our program
```
The thp function `print` allows us to display something in the terminal.
If you change the `hello.php` file, and run it, you'll see how it changes.
```thp
print(322)
```
```sh
$ thp hello.php
322
```
Or, if you copy `print` multiple times, each will show something in the screen.
```thp
print("Hello")
print("This is an example")
print("of having many prints")
```
```sh
$ thp hello.php
Hello
This is an example
of having many prints
```
### Using `print` in a larger program

View File

@ -1,72 +0,0 @@
# The compiler
The compiler is the program that takes your THP code and converts it
into something that the computer can run (in this case, PHP code).
The compiler reads your code and tries to understand it.
When it can't understand some part, it will ask you to clarify what
you meant, with an error.
## Compile time vs runtime
Compile time is when you build your program.
Runtime is when you run your program.
To make an analogy with cars, compile time would be the factory,
while runtime would be using the finished car.
The compiler is very strict. If it finds any errors during compile time
it will refuse to build the program.
### Compile time errors
Compile time errors are errors that happen while the compiler is
building your program. In the car analogy, a compile error would happen
if there's an error in the "blueprint"
### Runtime errors
These are errors that happen to the built program, or in this case,
the finished car. It would be like the car blowing up while on the highway.
To minimize the amount of runtime errors the compiler tries to catch them all
during compile time. It's better if it fails in the factory than in the
real world.
## The compiler and datatypes
The first measure the compiler takes is to check that all the datatypes
match. If an operation requires a number, you can't just give it a string.
For example, if we wanted to add a number to a string, we would get an
error:
```thp
50 + "hello" // Error: The `+` operator expects two Numbers,
// but an String was found.
```
This way, we can assure that many errors are avoided (since it doesn't
really make sense to add a number to a text).

View File

@ -1,138 +1,55 @@
# Variables
Variables allows us to store values under a name, so that we can use them
later.
thp distinguishes between mutable and immutable variables.
For example, in a program we could have the name of our user, and use it
multiple times:
## Mutable variables
Defined with `var`, followed by a variable name and a value.
```thp
print("Hello, where's Joe?")
print("How old is Joe?")
print("Do you know if Joe has kids?")
var name = "John"
var age = 32
```
We are using the same value `Joe` many times. Each time we use it we have
to type `Joe`. But what happens if we needed to use a different name?
We'd have to change the name everywhere in our code!
### Datatype annotation
Written after the `var` keyword but before the variable name.
```thp
print("Hello, where's Jane?")
print("How old is Jane?")
print("Do you know if Jane has kids?")
var String name = "John"
var Int age = 32
```
## Variables to the rescue
When annotating a mutable variable the keyword `var` is _required_.
With a variable we can store values so we can use them later, or use them
in multiple times.
In the previous code, we can use a variable to store the person's name,
and then use it everywhere.
## Immutable variables
Defined with `val`, followed by a variable name and a value.
```thp
// This is the variable
val person = "John"
print("Hello, where's {person}?")
print("How old is {person}?")
print("Do you know if Joe has {person}?")
val surname = "Doe"
val year_of_birth = 1984
```
Now, instead of writing `"John"` every time, we write the name of the
variable instead.
### Datatype annotation
If we wanted to change the person's name to "Jane", we just need to change
it in one place: the variable
Same as mutable variables
```thp
// We change this
val person = "Jane"
// And all these lines will use the new value
print("Hello, where's {person}?")
print("How old is {person}?")
print("Do you know if Joe has {person}?")
val String surname = "Doe"
val Int year_of_birth = 1984
```
## Variable rules
To use a variable we do the following:
- Write the special word `val`
- Write the name of our variable
- Write the equal sign `=`
- Write the value of our variable
When annotating an immutable variable the `val` keyword is optional
```thp
val person = "Jane"
/* --- ------ - ------
| | | +- The value of our variable
| | +----- The equal sign
| +---------- The name of our variable
+--------------- The special word (keyword) val
*/
// Equivalent to the previous code
String surname = "Doe"
Int year_of_birth = 1984
```
The value can be anything: ints, floats, string, bools, even other variables and operations!
```thp
val variable_1 = 322
val variable_2 = 123.456
val variable_3 = "a text"
val variable_4 = false
val variable_5 = variable_1 + variable 2
```
## Variable name rules
- Starts with a lowercase letter (a-z) or underscore (`_`)
- Then can have any letter (a-zA-Z), underscore (`_`) or number (0-9)
- Cannot have spaces
- Cannot have the same name as a keyword (for example, the `val` keyword)
Some examples of valid variable names:
```thp
val name = ...
val age = ...
val my_name = ...
val many_words_joined_by_underscores = ...
val person_2 = ...
val person_3 = ...
```
Some invalid variables and why they are invalid:
```thp
val 1name = ... // Invalid: starts with a number
val 123_person = ... // Invalid: starts with a number
val val = ... // Invalid: same name as a keyword (val)
val Person = ... // Invalid: starts with an uppercase letter
val person name = ... // Invalid: contains whitespace
val +@name = ... // Invalid: contains non-letters (+@)
val name🫠 = ... // Invalid: contains emoji (🫠)
```
## Variable reassignment
When you create a new variable with the same name of an old variable,
the old is "replaced" with the new one.
```thp
val person_name = "John"
print(person_name) // Will print "John"
val person_name = "Jane"
print(person_name) // Will print "Jane"
```
This will have some implications on the future, but for now you should
now that you will always use the value of the last variable you define.
This means that if a variable has only a datatype, it is immutable.

View File

@ -0,0 +1,94 @@
# Classes
Basically kotlin syntax.
Methods have to have a first parameter `$`.
## Create a new instance of a class
`new` not required, in fact, forbidden.
```thp
val dog = Dog()
```
## Simple class
Why'd you do this tho?
```thp
class SimpleClass
val instance = SimpleClass()
```
## Properties & methods
```thp
class SimpleClass
{
// Properties are private by default
var String? name;
// Made public with `public`
public var String? surname;
// Methods are private by default
fun display_name($)
{
// `$` is used instead of $this
print($name)
}
public fun get_name($) -> String?
{
$name
}
}
```
## Static members
no
## Constructor
Kotlin style
```thp
class Cat(val String name)
{
public fun get_name($) -> String
{
$name
}
}
val michifu = Cat("Michifu")
print(michifu.get_name())
```
## Inheritance
Kotlin style
```thp
class Animal(val String name)
{
public fun say_name($)
{
print($name)
}
}
class Cat(String name, Int lives) -> Animal(name)
Cat("Michi", 9).say_name()
```

View File

@ -0,0 +1,48 @@
# Static in classes
## Class constants
```thp
static Cat {
const CONSTANT = "constant value"
}
print(Cat::CONSTANT)
```
## Static methods
aka. plain, old functions
```thp
static Cat {
fun static_method() -> Int {
// ...
}
}
Cat::static_method()
```
## Static properties
aka. global variables
```thp
static Cat {
public var access_count = 0
}
print(Cat::access_count) // 0
Cat::access_count += 1
print(Cat::access_count) // 1
```

View File

@ -0,0 +1,35 @@
# Arrays
No destructuring (for now?). There's no `[]` syntax
for constructing arrays
## Usage
```thp
val fruits = Array("apple", "banana", "cherry")
val apple = fruits.[0]
print(apple)
var numbers = Array(0, 1, 2, 3)
// Note the dot
numbers.[3] = 5
print(numbers.[3]) // 5
```
## Type signature
```thp
Array[String]
Array[Int]
```

View File

@ -0,0 +1,43 @@
# Maps
Also known as Associative Arrays
## Usage without a declaration
```thp
var person = Obj {
name: "John",
surname: "Doe",
age: 33,
}
print("Hello {person.name}")
person.age += 1
print("You just turned {person.age}")
```
## Usage with a declaration
```thp
obj Person = {
String name,
String surname,
Int age,
}
val john_doe = Person {
name: "John",
surname: "Doe",
age: 33,
}
```

View File

@ -0,0 +1,11 @@
# Sets
```thp
// Set[Int]
val ages = Set(30, 31, 33, 35)
for age in ages {
print("{age}")
}
```

View File

@ -0,0 +1,22 @@
# Tuples
Uses `#()` just to avoid confusion with function
calls (`()`).
## Definition
```thp
val person = #("John", "Doe", 32)
val #(name, surname, age) = person
```
## Signature
```thp
#(String, String, Int)
```

View File

@ -1,3 +1,57 @@
# Conditionals
- Only `Bool` are accepted. No truthy/falsy.
- Conditionals are expressions.
- Braces are required
- Paretheses for the condition are not required.
- There's no ternary operator
```thp
if condition
{
// code
}
else if condition2
{
// more code
}
else
{
// even more code
}
val result = if condition { value1 } else { value2 }
```
## Check for datatypes
```thp
if variable is Datatype
{
// code using variable
}
```
## If variable is of enum
```thp
val user_id = POST::get("user_id")
if Some(user_id) = user_id
{
print("user_id exists: {user_id}")
}
if Some(user_id) = user_id && user_id > 0
{
print("user_id is greater than 0: {user_id}")
}
```

View File

@ -0,0 +1,82 @@
# Loops
## For loop
Braces are required.
```thp
val numbers = Array(0, 1, 2, 3)
for number in numbers
{
print(number)
}
for #(index, number) in numbers.entries()
{
print("{index} => {number}")
}
```
```thp
val dict = Obj {
"apple": 10,
"banana": 7,
"cherries": 3,
}
for #(key, value) in dict
{
print("{key} => {value}")
}
```
```thp
for value in collection
{
if condition
{
break
}
}
```
## While loop
```thp
val colors = Array("red", "green", "blue")
var index = 0
while index < colors.size()
{
print("{colors.[index]}")
index += 1
}
```
## Infinite loop
Basically Rust's loop.
```thp
loop
{
print("looping")
if condition
{
break
}
}
```

View File

@ -0,0 +1,56 @@
# Match
## Most likely syntax
```thp
val user_id = POST::get("user_id")
match user_id
| Some(id){ print("user_id exists: {id}") }
| None { print("user_id doesn't exist") }
match user_id
| Some(id)
{
print("user_id exists: {id}")
}
| None
{
print("user_id doesn't exist")
}
match user_id
| Some(id) if id > 0
{
print("user_id exists: {id}")
}
| _
{
print("user_id has other values ")
}
```
## Alternative syntax?
```thp
// Alternative syntax?
match user_id {
Some(id) { print("user_id exists: {id}") }
None { print("user_id doesn't exist") }
}
match user_id {
Some(id) {
print("user_id exists: {id}")
}
None {
print("user_id doesn't exist")
}
}
```

View File

@ -0,0 +1,70 @@
# Declaration
## No parameters, no return
```thp
fun say_hello()
{
print("Hello")
}
say_hello()
```
## With return type
```thp
fun get_random_number() -> Int
{
Random::get(0, 35_222)
}
val number = get_random_number()
```
## With parameters and return type
```thp
fun get_secure_random_number(Int min, Int max) -> Int
{
Random::get_secure(min, max)
}
val number = get_secure_random_number(0, 65535)
```
## Generic types
```thp
fun get_first_item[T](Array[T] array) -> T
{
array.[0]
}
val first = get_first_item[Int](numbers)
// The type annotation is optional if the compiler can infer the type
val first = get_first_item(numbers)
```
## Signature
```thp
() -> ()
() -> Int
(Int, Int) -> Int
[T](Array[T]) -> T
```

View File

@ -0,0 +1,28 @@
# Higher Order functions
## Function as parameter
```thp
fun map[A, B](Array[A] input, (A) -> B function) -> Array[B]
{
// implementation
}
```
## Function as return
```thp
fun generate_generator() -> () -> Int
{
// code...
}
val generator = generate_generator() // A function
val value = generate_generator()() // An Int
```

View File

@ -0,0 +1,70 @@
# Lambdas / Anonymous functions
## Anonymous function
```thp
fun(Int x, Int y) -> Int {
x + y
}
numbers.map(fun(x) {
x * 2
})
```
## Closure types
By default closures **always** capture variables as **references**.
```thp
var x = 20
val f = fun() {
print(x)
}
f() // 20
x = 30
f() // 30
```
You can force a closure to capture variables by value.
```thp
fun(parameters) clone(variables) {
// code
}
```
```thp
var x = 20
val f = fun() clone(x) {
print(x)
}
f() // 20
x = 30
f() // 20
```
## Lambdas
```thp
numbers.map {
it * 2
}
```

View File

@ -24,21 +24,21 @@ fun count(Array[Int] numbers) -> Int {
## Mutable reference
```thp
fun add_25(&Array[Int] numbers) {
fun push_25(&Array[Int] numbers) {
numbers.push(25) // Ok, will also mutate the original array
}
```
Placing a `&` before the type makes the parameter a mutable
reference. Mutable methods can be used, and the original
data **will** be mutated.
data **can** be mutated.
The callee *must* also use `&`.
The caller *must* also use `&`.
```thp
val numbers = Array(1, 2, 3, 4)
val numbers = Array(0, 1, 2, 3)
add_25(&numbers) // Pass `numbers` as reference.
push_25(&numbers) // Pass `numbers` as reference.
print(numbers(4)) // `Some(25)`
```
@ -54,13 +54,13 @@ fun add_25(clone Array[Int] numbers) {
```
Using the `clone` keyword before the type creates a mutable copy
of the parameter. The original data will **not** be mutated.
of the parameter (CoW). The original data will **not** be mutated.
```thp
val numbers = Array(1, 2, 3, 4)
add_25(&numbers) // Pass `numbers` as reference.
add_25(numbers) // Pass `numbers` as clone.
print(numbers(4)) // None
```

View File

@ -1,3 +1,6 @@
![Accurate visual description of THP](/img/desc_thp.jpg)
# Welcome
Welcome to the documentation of the THP programming languague.
@ -7,7 +10,7 @@ THP is a new programming language that compiles to PHP.
<br>
This page discusses some of the design decitions of the language,
if you want to install THP go to the installation guide](/installation-guide)
if you want to install THP go to the [installation guide](/installation-guide)
If you want to learn the language, go to the learn section.

View File

@ -11,14 +11,10 @@ children:
children:
- path: hello-world
name: Hello, world!
- path: datatypes
name: Datatypes
- path: the-compiler
name: The compiler
- name: Variables
path: variables
- path: io
name: Input & Output
- path: datatypes
name: Datatypes
- path: comments
name: Comments
- name: Flow control
@ -26,3 +22,41 @@ children:
children:
- name: Conditionals
path: conditionals
- name: Loops
path: loops
- name: Match
path: match
- name: Collections
path: collections
children:
- name: Tuples
path: tuples
- name: Arrays
path: arrays
- name: Maps
path: maps
- name: Sets
path: sets
- name: Functions
path: functions
children:
- name: Declaration
path: declaration
- name: Parameter references
path: parameters
- name: Higher-order functions
path: higher-order
- name: Lambdas
path: lambdas
- name: ADTs
path: adts
children:
- name: Union types
path: union-types
- name: Classes
path: classes
children:
- name: Definition
path: definition
- name: Static
path: static

BIN
static/img/desc_thp.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

View File

@ -16,12 +16,23 @@
<link href="https://fonts.googleapis.com/css2?family=Fira+Code&family=Josefin+Sans:ital,wght@0,400;1,700&display=swap" rel="stylesheet">
</head>
<body class="bg-c-bg text-c-text">
<nav class="sticky top-0 h-16 border-b border-gray-400 bg-[rgba(18,18,18,0.5)] backdrop-blur-md z-20">
<div class="max-w-[70rem] mx-auto h-full w-full flex items-center">
<button class="font-display font-bold italic text-4xl">
<span
class="text-[#F5A9B8]"
>t</span><span>h</span><span class="text-[#5BCEFA]">p</span>
</button>
</div>
</nav>
<div
class="max-w-[70rem] mx-auto py-28 grid grid-cols-2 gap-4"
class="max-w-[70rem] mx-auto py-16 grid grid-cols-2 gap-4"
>
<div>
<h1 class="font-display font-bold italic text-[6rem] leading-tight">
<h1
class="font-display font-bold italic text-[6rem] leading-tight"
>
Typed
<br>
Hypertext
@ -33,32 +44,34 @@
</p>
</div>
<div>
<div
class="bg-[var(--code-theme-bg-color)] p-8 rounded-lg"
class="bg-[var(--code-theme-bg-color)] p-8 rounded-lg relative"
>
<span class="absolute inline-block h-[40rem] w-[40rem] -z-10 top-1/2 left-1/2 rounded-full
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);
filter: blur(75px); opacity: 0.75;"
>
</span>
<svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg>
<br>
<pre
class="rounded-md bg-c-bg language-misti"
style="padding: 0 !important;"
><span class="token keyword">use</span> <span class="token class-name">Globals</span>::<span class="token class-name">POST</span>
<span class="token keyword">use</span> <span class="token class-name">JSON</span>
<span class="token keyword">val</span> person_id = <span class="token class-name">POST</span>::get(<span class="token string">"person_id"</span>) ?: <span class="token keyword">die</span>
<span class="token keyword">match</span> <span class="token class-name">Person</span>::find_by_id(person_id) {
<span class="token class-name">Ok</span>(person) => {
<span class="token class-name">JSON</span>::encode(person)
}
<span class="token class-name">Err</span>(e) => {
<span class="token class-name">JSON</span>::encode(Obj {<span class="token string">"error"</span>: e})
}
}
</pre>
<pre style="padding: 0 !important;">
<code class="language-thp">
val person_id = POST::get("person_id") ?: die
match Person::find_by_id(person_id)
| Ok(person)
{
JSON::encode(person)
}
| Err(e)
{
JSON::encode(Obj {"error": e})
}
</code>
</pre>
</div>
</div>
</div>
<div
@ -78,5 +91,8 @@
Install
</a>
</div>
<script src="/js/prism.min.js"></script>
<script src="/js/prism.thp.js"></script>
</body>
</html>

4
static/js/prism.min.js vendored Normal file

File diff suppressed because one or more lines are too long

25
static/js/prism.thp.js Normal file
View File

@ -0,0 +1,25 @@
Prism.languages.thp = {
"comment": [
{
pattern: /(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,
lookbehind: true,
greedy: true,
},
{
pattern: /(^|[^\\:])\/\/.*/,
lookbehind: true,
greedy: true,
},
],
"string": {
pattern: /(["])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,
greedy: true,
},
"keyword": /\b(?:break|catch|continue|do|else|elif|finally|for|fun|if|in|fn|nil|return|throw|try|while|val|var|type|match|with|of|abstract|class|interface|private|public|override|open)\b/,
"number": /\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,
"operator": /[<>]=?|[!=]=?=?|--?|\$|\+\+?|&&?|\|\|?|[?*/~^%]/,
"punctuation": /[{}[\];(),.]/,
"boolean": /\b(?:false|true)\b/,
"class-name": /\b[A-Z][a-zA-Z_0-9]+\b/,
"variable": /\b[a-z_0-9][a-zA-Z_0-9]+:/,
};