feat: Add docs

This commit is contained in:
Araozu 2024-09-28 07:21:56 -05:00
parent 3f388b8e22
commit e6df715955
11 changed files with 282 additions and 110 deletions

View File

@ -9,8 +9,7 @@ const [native_html, error_type, error_message] = await native_highlighter(thpcod
---
<pre
class="language-thp"><code class="language-thp" set:html={native_html} /><span class="absolute top-2 right-2 inline-block text-sm select-none opacity-75">thp
</span></pre>
class="language-thp"><code class="language-thp" set:html={native_html} /><span class="absolute top-1 right-1 text-right inline-block text-sm select-none opacity-75">thp</span></pre>
{
no_warnings !== true && error_message !== null && (
<CodeError error_type={error_type} error_message={error_message} />

View File

@ -30,18 +30,24 @@ const { showSidebarButton = true } = Astro.props;
>
Learn
</a>
<a
href="/api/std/"
class="hidden sm:inline-block px-4 font-display font-bold-text-xl hover:underline"
>
Standard Library
</a>
<a
href="/api/help/"
class="hidden sm:inline-block px-4 font-display font-bold-text-xl hover:underline"
>
Help
</a>
<a
href="/spec/"
class="hidden sm:inline-block px-4 font-display font-bold-text-xl hover:underline"
>
Language spec
</a>
<a
href="/api/std/"
class="hidden sm:inline-block px-4 font-display font-bold-text-xl hover:underline"
>
std reference
</a>
</div>
</nav>

View File

@ -1,3 +1,8 @@
<div class="two-column grid grid-cols-[10rem_auto]">
---
const {cols} = Astro.props;
const grid_cols = cols ?? "grid-cols-[10rem_auto]";
---
<div class={`two-column grid ${grid_cols}`}>
<slot />
</div>

View File

@ -13,6 +13,7 @@ const indexSubpath = `/learn/index.mdx`;
posts={posts}
indexSubpath={indexSubpath}
basePath="/learn/"
disable_container={!!frontmatter.disable_container}
>
<slot />
</PagesLayout>

View File

@ -10,6 +10,7 @@ const {
posts: _posts,
indexSubpath,
basePath,
disable_container,
} = Astro.props;
const posts: Record<string, any>[] = _posts;
@ -78,7 +79,7 @@ for (const entry of pagesIndex) {
<Navbar />
<div
class="lg:grid lg:grid-cols-[14rem_auto_12rem] lg:container mx-auto font-display"
class={`lg:grid lg:grid-cols-[14rem_auto_12rem] ${disable_container? "": "lg:container"} mx-auto font-display`}
>
<div
id="sidebar"
@ -95,7 +96,7 @@ for (const entry of pagesIndex) {
</div>
<main
class="py-[3.5rem] lg:pl-12 lg:pr-4 markdown min-w-0 small-container mx-auto"
class="pt-[3.5rem] pb-[10rem] lg:pl-12 lg:pr-4 markdown min-w-0 small-container mx-auto"
>
<slot />
</main>

View File

@ -1,7 +1,7 @@
import { spawn } from "node:child_process";
import { leftTrimDedent } from "../components/utils";
import { HighlightLevel } from "./types";
import type { LexError, SyntaxError, Token, TokenizeResult, TokenType } from "./types";
import type { MistiErr, Token, TokenizeResult, TokenType } from "./types";
const error_classes = "underline underline-offset-4 decoration-wavy decoration-red-500";
@ -12,7 +12,7 @@ export async function native_highlighter(code: string, level = HighlightLevel.Sy
let result = await native_lex(formatted_code);
return highlight_syntax(formatted_code, result, level);
} catch (error) {
return compiler_error(formatted_code, error as Error);
return compiler_error(formatted_code, error as MistiErr);
}
}
@ -23,7 +23,7 @@ function highlight_syntax(code: string, result: TokenizeResult, level: Highlight
const [tokens, semanticError] = result.SemanticError;
if (level === HighlightLevel.Semantic) {
return semantic_error_highlighter(code, tokens, semanticError.Semantic!);
return semantic_error_highlighter(code, tokens, semanticError);
} else {
tokens_final = tokens;
}
@ -31,13 +31,13 @@ function highlight_syntax(code: string, result: TokenizeResult, level: Highlight
const [tokens, syntaxError] = result.SyntaxError;
if (level === HighlightLevel.Semantic || level === HighlightLevel.Syntactic) {
return syntax_error_highlighter(code, tokens, syntaxError.Syntax!);
return syntax_error_highlighter(code, tokens, syntaxError);
} else {
tokens_final = tokens;
}
} else if (result.LexError) {
// There is no error level that bypasses a lex error
return lex_error_highlighter(code, result.LexError!.Lex!);
return lex_error_highlighter(code, result.LexError!);
} else if (result.Ok) {
tokens_final = result.Ok;
} else {
@ -56,7 +56,7 @@ function highlight_syntax(code: string, result: TokenizeResult, level: Highlight
/**
* Highlights code that has a lexic error
*/
function lex_error_highlighter(code: string, error: LexError): [string, string, string] {
function lex_error_highlighter(code: string, error: MistiErr): [string, string, string] {
// Create a single error token
const err_pos = error.position;
@ -73,7 +73,7 @@ function lex_error_highlighter(code: string, error: LexError): [string, string,
return [all, "Lexical", error.reason + ` at line ${error_line}:${error_column} `]
}
function syntax_error_highlighter(code: string, tokens: Array<Token>, error: SyntaxError): [string, string, string] {
function syntax_error_highlighter(code: string, tokens: Array<Token>, error: MistiErr): [string, string, string] {
const highlighted = highlight_tokens(code, tokens, error.error_start, error.error_end);
const [error_line, error_column] = absolute_to_line_column(code, error.error_start);
@ -81,7 +81,7 @@ function syntax_error_highlighter(code: string, tokens: Array<Token>, error: Syn
return [highlighted, "Syntax", error_message];
}
function semantic_error_highlighter(code: string, tokens: Array<Token>, error: SyntaxError): [string, string, string] {
function semantic_error_highlighter(code: string, tokens: Array<Token>, error: MistiErr): [string, string, string] {
const highlighted = highlight_tokens(code, tokens, error.error_start, error.error_end);
const [error_line, error_column] = absolute_to_line_column(code, error.error_start);
@ -89,7 +89,7 @@ function semantic_error_highlighter(code: string, tokens: Array<Token>, error: S
return [highlighted, "Semantic", error_message];
}
function compiler_error(code: string, error: Error): [string, string, string] {
function compiler_error(code: string, error: MistiErr): [string, string, string] {
return [code, "Fatal Compiler", error.message];
}
@ -225,7 +225,6 @@ function translate_token_type(tt: TokenType, value: string): string {
case "FOR":
case "IN":
case "WHILE":
case "LOOP":
case "MATCH":
case "CASE":
return "keyword";

View File

@ -43,38 +43,29 @@ export type TokenType =
| "CASE"
;
export interface Err {
Lex?: LexError
Syntax?: SyntaxError
Semantic?: SemanticError
export interface MistiErr {
error_code: number
error_offset: number
labels: Array<ErrorLabel>
note: string | null,
help: string | null,
}
export interface LexError {
position: number
reason: string
}
export interface SyntaxError {
error_start: number
error_end: number
reason: string
}
export interface SemanticError {
error_start: number
error_end: number
reason: string
export interface ErrorLabel {
message: string
start: number
end: number
}
export interface TokenizeResult {
/** All checks passed */
Ok?: Array<Token>,
/** There were semantic errors */
SemanticError?: [Array<Token>, Err],
SemanticError?: [Array<Token>, MistiErr],
/** There were syntax errors */
SyntaxError?: [Array<Token>, Err],
SyntaxError?: [Array<Token>, MistiErr],
/** No checks passed */
LexError?: Err,
LexError?: MistiErr,
}
export enum HighlightLevel {

View File

@ -1,62 +0,0 @@
---
layout: ../../layouts/DocsLayout.astro
title: Cheatsheet
---
# Language cheatsheet
Comparisons to PHP are noted.
```thp
// THP code is written directly, it's not enclosed in any ?php tag
// Single line comments are written with two slashes
/*
Multiline comments use slash-asterisk
and can be /* nested */
*/
// print writes input to stdout in terminal mode
print("Hello world")
```
## Types and variables
```thp
// Variables are always declared
// Variables don't start with a dollar sign ($)
// Variables are declared with `var`
var age = 32
// Immutable variables are declared with `val`,
// and can't be reassigned
val name = "John"
// A variable name starts with either a:
// - lowercase letter
// - underscore
// and then may contain any letter, underscore or number
val my_variable = "my value"
// Datatypes' names start with an uppercase letter, always
// A declaration may optionally specifiy its datatype, after
// the var/val keyword
var String lastname = "Doe"
//
// Bool
//
// Booleans are only `true` and `false`, case sensitive
val condition = true
val accepted = false
//
// Int
//
```

View File

@ -0,0 +1,230 @@
---
layout: ../../layouts/DocsLayout.astro
title: Cheatsheet
disable_container: true
---
import TwoColumn from "../../components/TwoColumn.astro"
import Code from "../../components/Code.astro"
# Language cheatsheet
Comparisons to PHP are noted.
<TwoColumn cols="grid-cols-[1fr_1fr] gap-2">
<Code thpcode={`
// THP code is written directly, it's not enclosed in any ?php tag
// Single line comments are written with two slashes
/*
Multiline comments use slash-asterisk
and can be /* nested */
*/
// there is no echo, only print
// Unlike PHP, parenthesis are required
print("Hello world")
`} />
```php
<?php
// PHP requires a <?php opening tag
/*
PHP cannot nest multiline comments
/* this would be an error * /
*/
# PHP also has hash comments. THP doesn't
print "Hello world";
```
</TwoColumn>
## Variables
<TwoColumn cols="grid-cols-[1fr_1fr] gap-2">
<Code no_warnings={true} thpcode={`
// THP has explicit variable declaration
// Variables don't start with a dollar sign ($)
// Variables are declared with \`var\`
var age = 32
// Immutable variables are declared with \`val\`,
// and can't be reassigned
val name = "John"
// Variables may have a datatype declaration
// This is an immutable variable with a type
String road = "Abbey road"
// This is a mutable variable with a type
var String name = "The Beatles"
`} />
```php
<?php
$age = 32;
// There is no PHP equivalent
$name = "John";
// You can't annotate the type of a variable in PHP
$road = "Abbey road";
$name = "The Beatles";
```
</TwoColumn>
## Datatypes
<TwoColumn cols="grid-cols-[1fr_1fr] gap-2">
<Code no_warnings={true} thpcode={`
// Only double quotes, never single quotes
String name = "Jane"
// Interpolation
String full_name = "{name} Doe"
Int age = 25
Float interest = 3.22
// An integer with a leading zero is an error,
// you must use \`0o\` for octal
// Int invalid = 0755
Int valid = 0o755
// Case sensitive, only \`true\` or \`false\`
Bool has_a_cute_dress = true
`} />
```php
$name = 'Jane';
$full_name = "$name Doe";
$age = 25;
$interest = 3.22;
$invalid = 0755;
$valid = 0o755;
// PHP allows true/false in any case, for some reason
$has_a_cute_dress = TrUe;
```
</TwoColumn>
<TwoColumn cols="grid-cols-[1fr_1fr] gap-2">
<Code no_warnings={true} thpcode={`
// String concatenation uses \`++\`
print("Hello " ++ "world")
// Basic operators
var res = 1 + 2 - 3 * 4 % 5
res += 2
res -= 2
res *= 2
res /= 2
res %= 2
// There are no prefix/postfix increment/decrement
//
//
`} />
```php
print("Hello " . "world");
$res = 1 + 2 - 3 * 4 % 5;
res += 2;
res -= 2;
res *= 2;
res /= 2;
res %= 2;
++res;
res--;
```
</TwoColumn>
## Flow control
<TwoColumn cols="grid-cols-[1fr_1fr] gap-2">
<Code no_warnings={true} thpcode={`
// Parenthesis not required, braces required
if age < 18
{
print("Not allowed")
}
else if age == 18
{
print("Allowed, barely")
}
else
{
print("Allowed")
}
// Conditionals are expressions
val gift = if prefers_silver
{
"silver necklace"
}
else
{
"gold necklace"
}
`} />
```php
if (age < 18) {
print("Not allowed");
} else if (age === 18) {
print("Allowed, barely");
} else {
print("Allowed");
}
$gift = "";
if (prefers_silver) {
$gift = "silver necklace";
} else {
$gift = "gold necklace";
}
```
</TwoColumn>
<TwoColumn cols="grid-cols-[1fr_1fr] gap-2">
<Code no_warnings={true} thpcode={`
`} />
```php
```
</TwoColumn>

View File

@ -152,7 +152,7 @@ and plugins for major editors like VSCode and Neovim.
## Not goals
These are **not** aspects that THP looks to solve or implement.
These are **not** things that THP wants to solve or implement
- Be what TypeScript is for JavaScript (PHP with types).
- Strictly adhere to PHP syntax/conventions.

View File

@ -7,11 +7,13 @@ title: Install
**THP is not available for public use. These are goals.**
## From scratch
## Binary
Goal: Install THP with a single binary. Assumes that php and composer is
available.
Also install php (through XAMPP in windows/mac, php in linux) and Composer.
## With composer
TBD, the user should be able to just run `composer require thp` and
the proper binary should be intalled.
TBD: Install THP with `composer require thp`