Separate enum & unions

This commit is contained in:
Araozu 2024-06-14 22:01:45 -05:00
parent 088ec3f867
commit c98122a260
7 changed files with 161 additions and 46 deletions

View File

@ -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";

View File

@ -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:

View File

@ -0,0 +1,6 @@
---
layout: ../../../../layouts/ApiLayout.astro
---
# Array.filter

View File

@ -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.

View 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]
```

View File

@ -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,

View File

@ -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
```