feat: begin to cascade folders

This commit is contained in:
Araozu 2024-11-21 20:31:09 -05:00
parent eded324a43
commit 86ef6f8c09
7 changed files with 449 additions and 14 deletions

View File

@ -49,6 +49,40 @@ const posts_2 = posts
}))
.sort((p1, p2) => p1.frontmatter.order > p2.frontmatter.order? 1 : -1);
// build a hierarchy of the files
const second_level: Record<string, Array<AstroFile>> = {
"_": [],
};
for (const post of posts_2) {
const fragments = post.path.split("/");
if (fragments.length === 3) {
const folder_name = fragments[1];
// create if not exists
if (second_level[folder_name] === undefined) {
second_level[folder_name] = [];
}
second_level[folder_name].push(post);
}
else if (fragments.length === 2) {
// add to root folder
second_level["_"].push(post);
}
}
console.log(JSON.stringify(second_level, null, 4));
// transform to the layout that the sidebar expects
const entries = [];
for (const levels_key in second_level) {
if (levels_key === "_") {
// top level
const posts = second_level[levels_key];
entries.push(...posts)
}
}
const index_page = posts_2.find(post => post.relative_file === "/index.md" || post.relative_file === "/index.mdx");
const basePath = index_page.url;
@ -68,7 +102,7 @@ const pagesIndex = posts_2;
>
<nav class="py-4 pr-2 overflow-x-scroll h-[calc(100vh-3rem)]">
{
pagesIndex.map((entry) => (
entries.map((entry) => (
<Sidebar entry={entry} basePath={basePath} />
))
}

View File

@ -1,13 +0,0 @@
---
layout: "./_wrapper.astro"
title: Basics
order: 2
---
import InteractiveCode from "@/components/InteractiveCode.astro";
import Code from "@/components/Code.astro"
# Hello!
Hi

View File

@ -0,0 +1,62 @@
---
layout: "../_wrapper.astro"
title: Comments
order: 2
---
import Code from "@/components/Code.astro"
# Comments
THP supports single and multi line comments:
## Single line
Begin with double slash `//` and continue until the end of the line.
<Code thpcode={`
// This is a single line comment
print("hello!")
print("the result is {5 + 5}") // This will print 10
`} />
## Multi line
These begin with `/*` and end with `*/`. Everything in between is ignored.
Multi line comments can be nested in THP.
<Code thpcode={`
/*
This is a
multiline comment
*/
`} />
<Code thpcode={`
/*
Multiline comments
can be /* nested */
*/
`} />
## Documentation comments
Documentation comments use triple slashes `///`.
These use [CommonMark Markdown](https://commonmark.org/) syntax.
<Code thpcode={`
/// Transforms the format from A to B...
///
/// ## Errors
///
/// This function will error if condition
/// X or Y is met...
fun transform() {
// ...
}
`} />

View File

@ -0,0 +1,87 @@
---
layout: "../_wrapper.astro"
title: Datatypes
order: 4
---
import Code from "@/components/Code.astro"
# Datatypes
THP requires that all datatypes start their name with an
uppercase letter.
The following are basic datatypes.
## Int
Same as php int
<Code thpcode={`
Int age = 32
// Hexadecimal numbers start with 0x
Int red = 0xff0000
// Octal numbers start with 0o
Int permissions = 0o775
// Binary numbers start with 0b
Int char_code = 0b01000110
// IMPORTANT!
// Since Octal starts with \`0o\`, using just a leading 0
// will result in a decimal!
Int not_octal = 032 // This is 32, not 26
`} />
// TODO: Make it a compile error to have leading zeroes,
and force users to use `0o` for octal
## Float
Same as php float
<Code thpcode={`
Float pi = 3.141592
Float light = 2.99e+8
`} />
## String
THP strings use **only** double quotes. Single quotes are
used elsewhere.
<Code thpcode={`
String name = "Rose"
`} />
Strings have interpolation with `{}`.
<Code thpcode={`
print("Hello, {name}") // Hello, Rose
`} />
Unlike PHP, THP strings are concatenated with `++`, not with `.`.
This new operator implicitly converts any operator into a string.
<Code thpcode={`
val name = "John" ++ " " ++ "Doe"
val greeting = "My name is " ++ name ++ " and I'm " ++ 32 ++ " years old"
`} />
The plus operator `+` is reserved for numbers.
## Bool
THP booleans are `true` and `false`. They are case sensitive,
**only lowercase.**
<Code thpcode={`
Bool is_true = true
Bool is_false = false
// This is a compile error
val invalid = TRUE
`} />

View File

@ -0,0 +1,46 @@
---
layout: "../_wrapper.astro"
title: Hello world
order: 1
---
import InteractiveCode from "@/components/InteractiveCode.astro";
import Code from "@/components/Code.astro"
# Hello, world!
## THP source code
Unlike PHP, THP code is written directly. There is no need to use any `<?php` tags,
just write the code like any other programming language.
As a consequence of this, HTML templates are defined in other ways, which will be
detailed later on.
To write a hello world program write the following code in a file:
<Code thpcode={`
print("Hello, world!")
`} />
Then run `thp hello.thp` from your terminal.
## Instruction separation
THP uses whitespace to determine when a statement is over. In short,
where PHP uses a semicolon `;`, THP uses a newline.
```php
echo("A");
echo("B");
echo("C");
```
<Code thpcode={`
print("A")
print("B")
print("C")
`} />
As a consequence of this, there can only be 1 statement per line.

View File

@ -0,0 +1,121 @@
---
layout: "../_wrapper.astro"
title: Operators
order: 5
---
import Code from "@/components/Code.astro"
# Operators
Most of the PHP operators are present in THP.
## Numbers
<Code thpcode={`
var number = 322
number + 1
number - 1
number * 1
number / 1
number % 2
number += 1
number -= 1
number *= 1
number /= 1
number %= 2
`} />
**There are no prefix/postfix increment operators** (`++`, `--`),
use `+=` or `-=` instead.
<Code thpcode={`
// Use
number += 1
// instead of
number++ // This is a compile error
`} />
### Comparison
These operators will not do implicit type conversion. They can
only be used with same datatypes.
<Code thpcode={`
v1 < v2
v1 <= v2
v1 > v2
v1 >= v2
`} />
There is only `==` and `!=`. They are equivalent to `===` and `!==`.
<Code thpcode={`
v1 == v2
v1 != v2
`} />
### Bitwise
TBD
<Code thpcode={`
number and 1
number or 2
number xor 1
number xand 1
`} />
## Strings
Strings **do not use `.`** for concatenation. They use `++`.
<Code thpcode={`
"Hello " ++ "world."
`} />
This new operator **implicitly converts** types to string
<Code thpcode={`
"Hello " ++ 322 // 322 will be converted to "322"
`} />
## Boolean
These operators work **only with booleans**, they do not perform
type coercion.
<Code thpcode={`
c1 && c2
c1 || c2
`} />
## Ternary
There is no ternary operator. See [Conditionals](/learn/flow-control/conditionals) for alternatives.
## Null
These are detailed in their section: [Nullable types](/learn/error-handling/null)
<Code thpcode={`
val person = some_fun()
person?.name
person?.name ?? "Jane"
person?.greet?.()
if person?
{
person.name
}
`} />

View File

@ -0,0 +1,98 @@
---
layout: "../_wrapper.astro"
title: Variables
order: 3
---
import Code from "@/components/Code.astro"
# Variables
THP distinguishes between mutable and immutable variables.
Variables must be declared in THP to avoid issues with scoping and
to know if they are mutable/immutable.
It's a compile error to use undeclared variables.
Variable names **don't** start with a dollar sign `$`.
Variable names **must** begin with a lowercase letter or an underscore.
Then they may contain lowercase/uppercase letters, numbers and underscores.
As a regex: `[a-z_][a-zA-Z0-9_]*`
## Immutable variables
Defined with `val`, followed by a variable name and a value.
<Code level={2} thpcode={`
val surname = "Doe"
val year_of_birth = 1984
`} />
It's a compile error to attempt to modify it
<Code level={2} thpcode={`
val surname = "Doe"
surname = "Dane" // Error
`} />
### Datatype annotation
Written after the `val` keyword but before the variable name.
<Code level={2} thpcode={`
val String surname = "Doe"
val Int year_of_birth = 1984
`} />
When annotating an immutable variable the `val` keyword is optional
<Code level={2} thpcode={`
// Equivalent to the previous code
String surname = "Doe"
Int year_of_birth = 1984
`} />
This means that if a variable only has a datatype, it is immutable.
It is a compile error to declare a variable of a datatype,
but use another.
<Code level={2} thpcode={`
// Declare the variable as a String, but use a Float as its value
String capital = 123.456
`} />
## Mutable variables
Defined with `var`, followed by a variable name and a value.
<Code level={2} thpcode={`
var name = "John"
var age = 32
age = 33
`} />
### Datatype annotation
Written after the `var` keywords but before the variable name.
<Code level={2} thpcode={`
var String name = "John"
var Int age = 32
`} />
When annotating a mutable variable the keyword `var` is still **required**.
<Code level={2} thpcode={`
// Equivalent to the previous code
var String name = "John"
var Int age = 32
`} />