Compare commits

..

No commits in common. "771a4b70447b3e2357d4e58394ad534a45c7eb7d" and "aa357101fb179a0c42de95bfc7dc874fc2cf0135" have entirely different histories.

10 changed files with 142 additions and 345 deletions

View File

@ -16,8 +16,6 @@ pipeline {
}
stage('Build bundle') {
steps {
sh 'rm .env || true'
sh 'echo "THP_BINARY=/var/lib/jenkins/bin/thp" > .env'
sh 'pnpm build'
}
}

View File

@ -86,11 +86,7 @@ export async function native_highlighter(code: string): Promise<string> {
}
function translate_token_type(tt: TokenType, value: string): string {
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", "protected", "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"];
switch (tt) {
case "Datatype":

View File

@ -1,9 +0,0 @@
---
layout: ../../../layouts/DocsLayout.astro
title: Abstract
---
import Code from "../../../components/Code.astro"
# Abstract

View File

@ -1,163 +0,0 @@
---
layout: ../../../layouts/DocsLayout.astro
title: Constructor/Destructor
---
import Code from "../../../components/Code.astro"
# Constructor/Destructor
## Constructor
The constructor syntax in THP is inspired by Kotlin.
Constructors are declared like function definitions:
<Code thpcode={`
// |this is the constructor |
class Animal(String fullname, Int age)
// Creating an instance
val cat = Animal("Michi", 3)
`} />
A constructor declared that way is public.
Note that the parameters in the constructor (`fullname`,
`age` above) are not properties, and cannot be used
inside the class methods, only in the
[`init` block](#init-block) and properties declaration.
To declare properties in the constructor see
[Constructor promotion](#constructor-promotion).
### Constructor visibility
If you want to declare a constructor as protected
or private you need to add the `constructor`
keyword, after the visibility modifier:
<Code thpcode={`
// Cow has a protected constructor
class Cow
protected constructor(String color)
// Bat has a private constructor
class Bat
private constructor(Int height)
`} />
### Init block
The `init` block allow us to run code during the
construction of the instance:
<Code thpcode={`
class Dog(String name)
{
pub String name = name
Int name_len = name.length
init
{
print("Dog created: {name}")
}
}
`} />
### Constructor promotion
Constructor parameters can serve as class properties.
This is done by adding a modifier and `var`/`val`.
<Code thpcode={`
class Parrot(
// A public property
pub val String name,
// A protected property
protected var Int age,
// A private property
var String last_name,
)
`} />
By using this syntax you are declaring properties and assigning them
at the same time.
The contructor parameters can also have default values.
### Derived properties
You can declare properties whose values depend on values
on the constructor.
<Code thpcode={`
class Animal(
val String fullname,
)
{
// A property whose value depends on \`fullname\`
// This is executed after the contructor
pub val Int name_length = fullname.length
}
val a2 = Animal("Doa")
print(a2.name_length) //: 3
`} />
### Constructor that may fail
TBD
Proposal 1:
<Code thpcode={`
class PrayingMantis(String name) -> self!Error
`} />
Proposal 2:
<Code thpcode={`
class PrayingMantis(String name)
throws Error
`} />
Proposal 3:
<Code thpcode={`
class PrayingMantis(String name)
{
init -> self!Error
{
// Something that may fail
}
}
`} />
## Destructor
The destructor in THP is the same as PHP.
<Code thpcode={`
class Owl
{
pub fun __destruct()
{
// Cleanup
print("Destroying Owl...")
}
}
`} />

View File

@ -1,6 +1,6 @@
---
layout: ../../../layouts/DocsLayout.astro
title: Basics
title: Classes
---
import Code from "../../../components/Code.astro"
@ -8,34 +8,30 @@ import Code from "../../../components/Code.astro"
Syntax and semantics heavily inspired by Kotlin.
Classes in THP are significantly different than PHP.
## Definition
## Create a new instance of a class
A class is defined as follows:
<Code thpcode={`
class Animal
`} />
The name of the class **MUST** begin with an uppercase letter.
## Instanciation
To create an instance of a class call it as if it was a function,
To create an instance of a class call it as if it were a function,
without `new`.
<Code thpcode={`
val animal = Animal()
`} />
## Simple class
Classes are declared with the `class` keyword.
<Code thpcode={`
class Animal
val instance = Animal()
`} />
## Properties
Properties are declared with `var`/`val` inside a block.
They **must** explicitly declare their datatype.
Properties are declared with `var`/`val`.
They **must** declare their datatype.
<Code thpcode={`
class Person
@ -46,13 +42,11 @@ class Person
// This is correct
val String name = "Jane Doe"
// This is also okay
String name = "Jane Doe"
}
`} />
**Properties are private by default**, but can be made public with `pub`.
Properties are private by default,
but can be made public with `pub`.
<Code thpcode={`
class Person
@ -63,22 +57,10 @@ class Person
// To make a property public use \`pub\`
pub var Int age = 30
}
val p = Person()
print(p.name) // Compile error: \`name\` is private
print(p.age) // 30
`} />
Unlike PHP, to access properties and methods use dot notation `.`
instead of an arrow `->`.
Static properties are explained in the Static page.
Readonly properties are explained in the Readonly page.
The interaction between properties and the constructor is explained
in the Constructor page.
More information about how properties interact with the constructor
is found in the contructor section.
## Methods
@ -95,7 +77,7 @@ class Person
}
`} />
**Methods are private by default**, and are made public with `pub`.
Methods are private by default, and are made public with `pub`.
<Code thpcode={`
class Person
@ -118,27 +100,10 @@ p.greet() //: Hello from greet
p.private_greet() // Compile time error. Private method.
`} />
[Unlike PHP](https://www.php.net/manual/en/language.oop5.basic.php#language.oop5.basic.properties-methods),
in THP a method cannot have the same name as a property and viceversa.
Doing so is a compile error.
<Code thpcode={`
class Person
{
String name = "Rose"
// This is a compile error
fun name() -> String {
"Rose"
}
}
`} />
## This
THP uses the dollar sign `$` as this inside classes.
It is **required** when using a class property/method.
THP uses the dollar sign `$` as this. It is **required** when
using a class property/method.
<Code thpcode={`
class Person
@ -158,6 +123,126 @@ class Person
}
`} />
## Static members
Static members are detailed in their own page.
## Constructor
(for now) THP's constructors are inspired by Kotlin.
PHP only allows a single constructor, and so does THP.
The basic constructor has the syntax of function parameters.
<Code thpcode={`
// |this is the constructor |
class Animal(String fullname, Int age)
val a1 = Animal("Nal", 4)
`} />
The class properties can be declared in the constructor,
using the keywords `pub`, `var`, `val`:
<Code thpcode={`
class Animal(
// Since we are using val/var, these are promoted to class properties
val String fullname,
var Int age,
)
{
pub fun say()
{
// Here we are using the properties declared in the constructor
print("My name is {$fullname} and i'm {$age} years old")
}
}
val a1 = Animal("Nal", 4)
a1.say() //: My name is Nal and i'm 4 years old
`} />
By using this syntax you are declaring properties and assigning them
at the same time.
The contructor parameters can also have default values.
### Constructor visibility
The constructor is public by default. It can be made private/protected
like this:
<Code thpcode={`
class Animal
private constructor(
val String fullname,
var Int age,
)
{...}
`} />
### Derived properties
You can declare properties whose values depend on values
on the constructor.
<Code thpcode={`
class Animal(
val String fullname,
)
{
// A property whose value depends on \`fullname\`
// This is executed after the contructor
pub val Int name_length = $fullname.length
}
val a2 = Animal("Doa")
print(a2.name_length) //: 3
`} />
### Init block
If you need to additional logic in the constructor you can
use a `init` block.
<Code thpcode={`
class Animal(
val String fullname,
)
{
init
{
print("{$fullname} in contruction...")
}
}
val a3 = Animal("Lola") //: Lola in construction
`} />
## Inheritance
<Code thpcode={`
// Base class
class Animal(var String name)
{
pub fun say_name()
{
print($name)
}
}
// Child class
class Cat(String name, Int lives)
extends Animal(name)
Cat("Michi", 9).say_name()
`} />
## Mutable methods

View File

@ -1,26 +0,0 @@
---
layout: ../../../layouts/DocsLayout.astro
title: Inheritance
---
import Code from "../../../components/Code.astro"
# Inheritance
<Code thpcode={`
// Base class
class Animal(var String name)
{
pub fun say_name()
{
print($name)
}
}
// Child class
class Cat(String name, Int lives)
extends Animal(name)
Cat("Michi", 9).say_name()
`} />

View File

@ -1,7 +0,0 @@
---
layout: ../../../layouts/DocsLayout.astro
title: Readonly
---
import Code from "../../../components/Code.astro"
# Readonly

View File

@ -1,7 +0,0 @@
---
layout: ../../../layouts/DocsLayout.astro
title: Visibility
---
import Code from "../../../components/Code.astro"
# Visibility

View File

@ -44,12 +44,7 @@ pagesLayout:
title: Classes
children:
- path: definition
- path: constructor
- path: inheritance
- path: static
- path: visibility
- path: readonly
- path: abstract
- path: interfaces
- path: anonymous
- path: magic

View File

@ -7,68 +7,3 @@ import Info from "../../../components/docs/Info.astro"
# Control flow
## If expressions
Use `@if`, `@else if` and `@else` to branch during the template
creation.
<Code thpcode={`
fun User(User user) -> HTML
{
<div>
@if user.verified
{
<p>Hello {user.name}</p>
}
@else
{
<p>Verify your account to continue</p>
}
</div>
}
`} />
## Loops
Use `@for`:
<Code thpcode={`
fun Users() -> HTML
{
val users = User::get_all()
<div>
@for user in users
{
<User user={user} />
}
</div>
}
`} />
## Match
Use `@match` for pattern matching:
<Code thpcode={`
fun UserDetail(User user) -> HTML
{
<div>
@match user.type
case ::Admin
{
<button>Delete resource</button>
}
case ::User
{
<button disable>Not allowed</button>
}
</div>
}
`} />