Separate enum & unions
This commit is contained in:
parent
088ec3f867
commit
c98122a260
@ -34,7 +34,7 @@ export function scan_identifier(input: string, starting_position: number, is_dat
|
|||||||
}
|
}
|
||||||
|
|
||||||
function check_keyword(value: string): string {
|
function check_keyword(value: string): string {
|
||||||
const keywords = ["throws", "extends", "constructor", "case", "static", "const", "enum", "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", "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)) {
|
if (keywords.includes(value)) {
|
||||||
return "keyword";
|
return "keyword";
|
||||||
|
@ -141,6 +141,16 @@ abstraction, as if all indexes were valid.
|
|||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
|
### Empty array
|
||||||
|
|
||||||
|
To create an empty array use square brackets.
|
||||||
|
If you create an empty array, you need to specify the datatype.
|
||||||
|
|
||||||
|
```thp
|
||||||
|
Array[Int] empty = []
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
### Creation
|
### Creation
|
||||||
|
|
||||||
To create an array use square brackets notation:
|
To create an array use square brackets notation:
|
||||||
@ -149,6 +159,8 @@ To create an array use square brackets notation:
|
|||||||
val numbers = [0, 1, 2, 3, 4, 5]
|
val numbers = [0, 1, 2, 3, 4, 5]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
When the array is not empty, you don't need to specify a datatype.
|
||||||
|
|
||||||
When the Array is declared over many lines, the last
|
When the Array is declared over many lines, the last
|
||||||
item should have a trailing comma:
|
item should have a trailing comma:
|
||||||
|
|
||||||
|
6
src/pages/api/std/Array/filter.md
Normal file
6
src/pages/api/std/Array/filter.md
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
layout: ../../../../layouts/ApiLayout.astro
|
||||||
|
---
|
||||||
|
|
||||||
|
# Array.filter
|
||||||
|
|
@ -3,10 +3,18 @@ layout: ../../../layouts/DocsLayout.astro
|
|||||||
title: Enums
|
title: Enums
|
||||||
---
|
---
|
||||||
|
|
||||||
# Enums (Tagged unions)
|
# Enums
|
||||||
|
|
||||||
|
From the [PHP documentation](https://www.php.net/manual/en/language.enumerations.overview.php):
|
||||||
|
|
||||||
|
Enums allow a developer to define a custom type that is limited to one of a discrete number of possible values.
|
||||||
|
|
||||||
|
THP enums are a 1 to 1 map of PHP enums, with a slightly different syntax.
|
||||||
|
|
||||||
## Basic enums
|
## Basic enums
|
||||||
|
|
||||||
|
Enums don't have a scalar value by default.
|
||||||
|
|
||||||
```thp
|
```thp
|
||||||
enum Suit
|
enum Suit
|
||||||
{
|
{
|
||||||
@ -19,38 +27,21 @@ enum Suit
|
|||||||
val suit = Suit::Hearts
|
val suit = Suit::Hearts
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Backed enums
|
||||||
|
|
||||||
## Enums with values
|
Backed enums can have a scalar for each case. The scalar values can only be
|
||||||
|
`String` or `Int`.
|
||||||
|
|
||||||
```thp
|
```thp
|
||||||
enum IpAddress
|
enum Suit(String)
|
||||||
{
|
{
|
||||||
V4(String),
|
Hearts = "H",
|
||||||
V6(String),
|
Diamonds = "D",
|
||||||
}
|
Clubs = "C",
|
||||||
|
Spades = "S",
|
||||||
val addr_1 = IpAddress::V4("192.168.0.1")
|
|
||||||
|
|
||||||
match addr_1
|
|
||||||
case IpAddress::V4(ip)
|
|
||||||
{
|
|
||||||
// code..
|
|
||||||
}
|
|
||||||
case IpAddress::V6(ip)
|
|
||||||
{
|
|
||||||
// more code..
|
|
||||||
}
|
|
||||||
|
|
||||||
// Without the full qualifier
|
|
||||||
match addr_1
|
|
||||||
case ::V4(ip)
|
|
||||||
{
|
|
||||||
// code...
|
|
||||||
}
|
|
||||||
case ::V6(ip)
|
|
||||||
{
|
|
||||||
// even more code...
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
All cases must explicitly define their value, there is no automatic generation.
|
||||||
|
|
||||||
|
|
||||||
|
58
src/pages/learn/data-structures/unions.md
Normal file
58
src/pages/learn/data-structures/unions.md
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
---
|
||||||
|
layout: ../../../layouts/DocsLayout.astro
|
||||||
|
title: Tagged unions
|
||||||
|
---
|
||||||
|
|
||||||
|
# Tagged unions
|
||||||
|
|
||||||
|
Tagged unions can hold a value from a fixed selection of types.
|
||||||
|
|
||||||
|
```thp
|
||||||
|
union Shape
|
||||||
|
{
|
||||||
|
Dot,
|
||||||
|
Square(Int),
|
||||||
|
Rectangle(Int, Int),
|
||||||
|
}
|
||||||
|
|
||||||
|
val dot = Shape::Dot
|
||||||
|
val square1 = Shape::Square(10)
|
||||||
|
val rectangle1 = Shape::Rectangle(5, 15)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Pattern matching
|
||||||
|
|
||||||
|
```thp
|
||||||
|
match shape_1
|
||||||
|
case ::Square(side)
|
||||||
|
{
|
||||||
|
print("Area of the square: {side * side}")
|
||||||
|
}
|
||||||
|
case ::Rectangle(length, height)
|
||||||
|
{
|
||||||
|
print("Area of the rectangle: {length * height}")
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Internal representation
|
||||||
|
|
||||||
|
When compiled down to PHP, tagged unions are a combination of an enum and an array.
|
||||||
|
|
||||||
|
THP creates an enum of the same name and with the same cases, and the values
|
||||||
|
are contained as part of an array.
|
||||||
|
|
||||||
|
|
||||||
|
```php
|
||||||
|
// The first snippet is compiled to:
|
||||||
|
enum Shape
|
||||||
|
{
|
||||||
|
case Dot;
|
||||||
|
case Square;
|
||||||
|
case Rectangle;
|
||||||
|
}
|
||||||
|
|
||||||
|
$dot = [Shape::Dot];
|
||||||
|
$square1 = [Shape::Square, 10];
|
||||||
|
$rectangle1 = [Shape::Rectangle, 5, 15]
|
||||||
|
```
|
||||||
|
|
@ -26,6 +26,7 @@ pagesLayout:
|
|||||||
- path: arrays
|
- path: arrays
|
||||||
- path: maps
|
- path: maps
|
||||||
- path: enums
|
- path: enums
|
||||||
|
- path: unions
|
||||||
- path: functions
|
- path: functions
|
||||||
title: Functions
|
title: Functions
|
||||||
children:
|
children:
|
||||||
@ -59,7 +60,7 @@ THP is a new programming language that compiles to PHP.
|
|||||||
![Accurate visual description of THP](/img/desc_thp.jpg)
|
![Accurate visual description of THP](/img/desc_thp.jpg)
|
||||||
|
|
||||||
|
|
||||||
This page discusses some of the design decitions of the language,
|
This page details the main design desitions of the language,
|
||||||
if you want to install THP go to the [installation guide](install)
|
if you want to install THP go to the [installation guide](install)
|
||||||
|
|
||||||
|
|
||||||
@ -135,32 +136,41 @@ that it is a different language, and has different semantics.
|
|||||||
|
|
||||||
## Some differences with PHP
|
## Some differences with PHP
|
||||||
|
|
||||||
```thp
|
```php
|
||||||
// PHP
|
// PHP
|
||||||
$has_key = str_contains($haystack, 'needle');
|
$has_key = str_contains($haystack, 'needle');
|
||||||
|
print("has key? " . $has_key);
|
||||||
|
```
|
||||||
|
|
||||||
|
```thp
|
||||||
// THP
|
// THP
|
||||||
val has_key = haystack.contains("needle")
|
val has_key = haystack.contains("needle")
|
||||||
|
print("has key? " + has_key)
|
||||||
```
|
```
|
||||||
|
|
||||||
- Explicit variable declaration
|
- Explicit variable declaration
|
||||||
- No `$` for variable names (and thus no `$$variable`)
|
- No `$` for variable names (and thus no `$$variable`, use a map instead)
|
||||||
- No semicolons
|
- No semicolons
|
||||||
- Use methods on common datatypes
|
- Use methods on common datatypes
|
||||||
- Strings use only double quotes
|
- Strings use only double quotes
|
||||||
|
- String concatenation with `+`
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
```thp
|
<br/>
|
||||||
|
<br/>
|
||||||
|
|
||||||
|
```php
|
||||||
// PHP
|
// PHP
|
||||||
[
|
$obj = [
|
||||||
'names' => ['Toni', 'Stark'],
|
'names' => ['Toni', 'Stark'],
|
||||||
'age' => 33,
|
'age' => 33,
|
||||||
'numbers' => [32, 64, 128]
|
'numbers' => [32, 64, 128]
|
||||||
]
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
```thp
|
||||||
// THP
|
// THP
|
||||||
.{
|
val obj = .{
|
||||||
names: #("Toni", "Stark"), // Tuple
|
names: #("Toni", "Stark"), // Tuple
|
||||||
age: 33,
|
age: 33,
|
||||||
numbers: [32, 64, 128]
|
numbers: [32, 64, 128]
|
||||||
@ -170,29 +180,36 @@ val has_key = haystack.contains("needle")
|
|||||||
- Tuples, Arrays, Sets, Maps are clearly different
|
- Tuples, Arrays, Sets, Maps are clearly different
|
||||||
- JSON-like object syntax
|
- JSON-like object syntax
|
||||||
|
|
||||||
---
|
<br/>
|
||||||
|
<br/>
|
||||||
|
|
||||||
```thp
|
```php
|
||||||
// PHP
|
// PHP
|
||||||
$cat = new Cat("Michifu", 7);
|
$cat = new Cat("Michifu", 7);
|
||||||
$cat->meow();
|
$cat->meow();
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
```thp
|
||||||
// THP
|
// THP
|
||||||
val cat = Cat("Michifu", 7)
|
val cat = Cat("Michifu", 7)
|
||||||
cat.meow();
|
cat.meow();
|
||||||
```
|
```
|
||||||
|
|
||||||
- No `new` for classes
|
- Instantiate classes without `new`
|
||||||
- Use dot `.` instead of arrow `->` syntax
|
- Use dot `.` instead of arrow `->` syntax
|
||||||
|
|
||||||
---
|
<br/>
|
||||||
|
<br/>
|
||||||
|
|
||||||
|
```php
|
||||||
```thp
|
|
||||||
// PHP
|
// PHP
|
||||||
use \Some\Deeply\Nested\Class
|
use \Some\Deeply\Nested\Class
|
||||||
use \Some\Deeply\Nested\Interface
|
use \Some\Deeply\Nested\Interface
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
```thp
|
||||||
// THP
|
// THP
|
||||||
use Some::Deeply::Nested::{Class, Interface}
|
use Some::Deeply::Nested::{Class, Interface}
|
||||||
```
|
```
|
||||||
@ -202,7 +219,9 @@ use Some::Deeply::Nested::{Class, Interface}
|
|||||||
- PSR-4 required
|
- PSR-4 required
|
||||||
- No `include`, `include_once`, `require` or `require_once`
|
- No `include`, `include_once`, `require` or `require_once`
|
||||||
|
|
||||||
---
|
<br/>
|
||||||
|
<br/>
|
||||||
|
|
||||||
|
|
||||||
Other things:
|
Other things:
|
||||||
|
|
||||||
@ -232,8 +251,9 @@ val greeting =
|
|||||||
{
|
{
|
||||||
"Nobody is here"
|
"Nobody is here"
|
||||||
}
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```php
|
||||||
// Would compile to:
|
// Would compile to:
|
||||||
$greeting = null;
|
$greeting = null;
|
||||||
$_person = get_person();
|
$_person = get_person();
|
||||||
@ -262,8 +282,9 @@ enum IpAddress {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val ip_1 = IpAddress::V4("255.255.0.0")
|
val ip_1 = IpAddress::V4("255.255.0.0")
|
||||||
|
```
|
||||||
|
|
||||||
|
```php
|
||||||
// Would possibly compile to:
|
// Would possibly compile to:
|
||||||
enum IpAddress {
|
enum IpAddress {
|
||||||
V4,
|
V4,
|
||||||
|
@ -31,6 +31,33 @@ Statement = VariableBinding
|
|||||||
|
|
||||||
See the Expression section
|
See the Expression section
|
||||||
|
|
||||||
|
## VariableBinding
|
||||||
|
|
||||||
|
```ebnf
|
||||||
|
VariableBinding = ImplicitBinding
|
||||||
|
| ExplicitBinding
|
||||||
|
|
||||||
|
ImplicitBinding = Datatype, Identifier, "=", Expression
|
||||||
|
ExplicitBinding = ("var" | "val"), Datatype?, Identifier, "=", Expression
|
||||||
|
```
|
||||||
|
|
||||||
|
## FunctionDeclaration
|
||||||
|
|
||||||
|
```ebnf
|
||||||
|
FunctionDeclaration = "fun", Identifier, ParameterList, ("->", Datatype)?, Block
|
||||||
|
|
||||||
|
ParameterList = "(", (Parameter, ",")*, ")"
|
||||||
|
|
||||||
|
Parameter = Datatype, Identifier
|
||||||
|
```
|
||||||
|
|
||||||
|
## Block
|
||||||
|
|
||||||
|
```ebnf
|
||||||
|
Block = "{", BlockMember*, "}"
|
||||||
|
|
||||||
|
BlockMember = Statement
|
||||||
|
| Expression
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user