Compare commits
5 Commits
49faed4fcb
...
2eb6e13d32
Author | SHA1 | Date | |
---|---|---|---|
2eb6e13d32 | |||
bfeb065c68 | |||
3584c6d798 | |||
07ff7ede1e | |||
a542071af9 |
1
.env.example
Normal file
1
.env.example
Normal file
@ -0,0 +1 @@
|
||||
THP_BINARY=/path/to/rust/thp/binary
|
@ -4,9 +4,9 @@
|
||||
line-height: 2.5rem;
|
||||
margin-bottom: 1rem;
|
||||
margin-top: 2rem;
|
||||
font-family: Inter, sans-serif;
|
||||
font-family: Outfit, Inter, sans-serif;
|
||||
opacity: 0.9;
|
||||
font-weight: 900;
|
||||
font-weight: 700;
|
||||
color: var(--c-text-2);
|
||||
}
|
||||
|
||||
@ -16,23 +16,41 @@
|
||||
line-height: 2rem;
|
||||
margin-bottom: 1rem;
|
||||
margin-top: 2.5rem;
|
||||
font-family: Inter, sans-serif;
|
||||
font-family: Outfit, Inter, sans-serif;
|
||||
opacity: 0.9;
|
||||
font-weight: 700;
|
||||
font-weight: 600;
|
||||
color: var(--c-text-2);
|
||||
}
|
||||
|
||||
.markdown h2::before {
|
||||
content: "#";
|
||||
display: block;
|
||||
height: 0;
|
||||
position: relative;
|
||||
right: 1.5rem;
|
||||
opacity: 0.2;
|
||||
}
|
||||
|
||||
.markdown h3 {
|
||||
font-size: 1.35rem;
|
||||
line-height: 1.75rem;
|
||||
margin-bottom: 1rem;
|
||||
margin-top: 1.75rem;
|
||||
font-family: Inter, sans-serif;
|
||||
font-family: Outfit, Inter, sans-serif;
|
||||
opacity: 0.9;
|
||||
font-weight: 600;
|
||||
font-weight: 400;
|
||||
color: var(--c-text-2);
|
||||
}
|
||||
|
||||
.markdown h3::before {
|
||||
content: "##";
|
||||
display: block;
|
||||
height: 0;
|
||||
position: relative;
|
||||
right: 2.25rem;
|
||||
opacity: 0.1;
|
||||
}
|
||||
|
||||
.markdown ul {
|
||||
list-style-type: disc;
|
||||
list-style-position: inside;
|
||||
@ -49,7 +67,11 @@
|
||||
background: var(--code-theme-bg-color);
|
||||
}
|
||||
|
||||
.markdown a {
|
||||
.markdown > p > a {
|
||||
color: var(--c-link);
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.markdown blockquote {
|
||||
color: red
|
||||
}
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 4.9 KiB |
@ -2,31 +2,52 @@
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="76.347305mm"
|
||||
width="76.347313mm"
|
||||
height="76.400658mm"
|
||||
viewBox="0 0 76.347306 76.400657"
|
||||
viewBox="0 0 76.347314 76.400657"
|
||||
version="1.1"
|
||||
id="svg1"
|
||||
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25, custom)"
|
||||
sodipodi:docname="thp_2_logo.svg"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview1"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#000000"
|
||||
borderopacity="0.25"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:document-units="mm"
|
||||
showguides="true"
|
||||
inkscape:zoom="2"
|
||||
inkscape:cx="157"
|
||||
inkscape:cy="166"
|
||||
inkscape:window-width="1906"
|
||||
inkscape:window-height="1040"
|
||||
inkscape:window-x="3"
|
||||
inkscape:window-y="29"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="layer1" />
|
||||
<defs
|
||||
id="defs1">
|
||||
<clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath2">
|
||||
<path
|
||||
d="m 26.237336,46.619443 v 4.907545 h -3.808557 v 9.796139 q 0,1.648482 1.686376,1.648482 0.341065,0 0.947402,-0.07579 0.625286,-0.09474 0.890559,-0.151585 l 0.852663,4.812802 q -1.117936,0.322117 -2.160079,0.435806 -1.042142,0.113689 -1.970596,0.113689 -3.372753,0 -5.115973,-1.572689 -1.74322,-1.591635 -1.74322,-4.623321 V 51.526988 H 13.0116 v -4.907545 h 2.804311 v -5.04018 h 6.612868 v 5.04018 z m 10.156152,9.095063 v 12.088855 h -6.612866 v -28.23259 h 6.48023 v 11.25514 q 0.852662,-2.046391 2.425351,-3.259064 1.591635,-1.212675 4.054882,-1.212675 3.315907,0 5.324401,2.179026 2.008492,2.179024 2.008492,5.779154 V 67.803361 H 43.461112 V 55.600817 q 0,-1.781114 -0.909508,-2.785361 -0.909505,-1.023194 -2.539037,-1.023194 -1.610585,0 -2.614832,1.04214 -1.004247,1.023197 -1.004247,2.880104 z m 18.03854,20.009138 V 46.619443 h 6.537076 v 3.638026 h 0.227378 q 0.397909,-0.947401 1.155832,-1.837962 0.75792,-0.909506 1.951649,-1.477947 1.193726,-0.587388 2.880103,-0.587388 2.235867,0 4.149622,1.174779 1.932699,1.174779 3.107478,3.58118 1.193726,2.406402 1.193726,6.12022 0,3.600128 -1.155829,6.025478 -1.136883,2.406402 -3.069585,3.638024 -1.913752,1.212675 -4.263308,1.212675 -2.425351,0 -3.884351,-1.136883 -1.44005,-1.155829 -2.065337,-2.59588 H 61.044897 V 75.723644 Z M 64.891351,62.952659 q 1.913753,0 2.918,-1.572686 1.023194,-1.572689 1.023194,-4.149622 0,-2.576936 -1.023194,-4.130675 -1.004247,-1.572688 -2.918,-1.572688 -1.894805,0 -2.955896,1.534792 -1.042143,1.534792 -1.042143,4.168571 0,2.59588 1.042143,4.168569 1.061091,1.553739 2.955896,1.553739 z"
|
||||
id="path2"
|
||||
style="font-weight:800;font-size:38.8056px;font-family:Inter;-inkscape-font-specification:'Inter Ultra-Bold';display:none;fill:#ffffff;stroke:#f472b6;stroke-width:0"
|
||||
aria-label="thp" />
|
||||
<path
|
||||
id="lpe_path-effect2"
|
||||
style="font-weight:800;font-size:38.8056px;font-family:Inter;-inkscape-font-specification:'Inter Ultra-Bold';fill:#ffffff;stroke:#f472b6;stroke-width:0"
|
||||
class="powerclip"
|
||||
d="M -4.9871546,-4.9877447 H 81.335912 V 81.335322 H -4.9871546 Z M 26.237336,46.619443 h -3.808557 v -5.04018 h -6.612868 v 5.04018 H 13.0116 v 4.907545 h 2.804311 v 10.383533 q 0,3.031686 1.74322,4.623321 1.74322,1.572689 5.115973,1.572689 0.928454,0 1.970596,-0.113689 1.042143,-0.113689 2.160079,-0.435806 l -0.852663,-4.812802 q -0.265273,0.05685 -0.890559,0.151585 -0.606337,0.07579 -0.947402,0.07579 -1.686376,0 -1.686376,-1.648482 v -9.796139 h 3.808557 z m 10.156152,9.095063 q 0,-1.856907 1.004247,-2.880104 1.004247,-1.04214 2.614832,-1.04214 1.629532,0 2.539037,1.023194 0.909508,1.004247 0.909508,2.785361 v 12.202544 h 6.612866 V 54.312352 q 0,-3.60013 -2.008492,-5.779154 -2.008494,-2.179026 -5.324401,-2.179026 -2.463247,0 -4.054882,1.212675 -1.572689,1.212673 -2.425351,3.259064 v -11.25514 h -6.48023 v 28.23259 h 6.612866 z m 18.03854,20.009138 h 6.612869 V 64.373765 h 0.151585 q 0.625287,1.440051 2.065337,2.59588 1.459,1.136883 3.884351,1.136883 2.349556,0 4.263308,-1.212675 1.932702,-1.231622 3.069585,-3.638024 1.155829,-2.42535 1.155829,-6.025478 0,-3.713818 -1.193726,-6.12022 -1.174779,-2.406401 -3.107478,-3.58118 -1.913755,-1.174779 -4.149622,-1.174779 -1.686377,0 -2.880103,0.587388 -1.193729,0.568441 -1.951649,1.477947 -0.757923,0.890561 -1.155832,1.837962 H 60.969104 V 46.619443 H 54.432028 Z M 64.891351,62.952659 q 1.913753,0 2.918,-1.572686 1.023194,-1.572689 1.023194,-4.149622 0,-2.576936 -1.023194,-4.130675 -1.004247,-1.572688 -2.918,-1.572688 -1.894805,0 -2.955896,1.534792 -1.042143,1.534792 -1.042143,4.168571 0,2.59588 1.042143,4.168569 1.061091,1.553739 2.955896,1.553739 z" />
|
||||
</clipPath>
|
||||
<inkscape:path-effect
|
||||
effect="powerclip"
|
||||
id="path-effect2"
|
||||
is_visible="true"
|
||||
lpeversion="1"
|
||||
inverse="true"
|
||||
flatten="false"
|
||||
hide_clip="false"
|
||||
message="Use fill-rule evenodd on <b>fill and stroke</b> dialog if no flatten result after convert clip to paths." />
|
||||
</defs>
|
||||
<g
|
||||
inkscape:label="Calque 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<rect
|
||||
style="display:none;fill:#1a1a1a;fill-opacity:1;stroke:#f472b6;stroke-width:0;stroke-dasharray:none;stroke-opacity:1"
|
||||
@ -36,15 +57,9 @@
|
||||
x="0.001250195"
|
||||
y="0.0017838299" />
|
||||
<path
|
||||
style="fill:#f472b6;fill-opacity:1;stroke:#f472b6;stroke-width:0;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect1"
|
||||
width="76.323067"
|
||||
height="76.323067"
|
||||
x="0.01284539"
|
||||
y="0.012255264"
|
||||
rx="5.2916665"
|
||||
ry="5.2916665"
|
||||
clip-path="url(#clipPath2)"
|
||||
d="M 5.3045119,0.01225526 H 71.044246 c 2.931583,0 5.291666,2.36008324 5.291666,5.29166654 V 71.043655 c 0,2.931584 -2.360083,5.291667 -5.291666,5.291667 H 5.3045119 c -2.9315832,0 -5.29166651,-2.360083 -5.29166651,-5.291667 V 5.3039218 c 0,-2.9315833 2.36008331,-5.29166654 5.29166651,-5.29166654 z" />
|
||||
clip-path="none"
|
||||
style="fill:#f472b6;fill-opacity:1;stroke:#f472b6;stroke-width:0;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 5.3045858 0.012402344 C 2.3730055 0.012402344 0.012919108 2.3724887 0.012919108 5.304069 L 0.012919108 71.043726 C 0.012919108 73.975306 2.3730055 76.335392 5.3045858 76.335392 L 71.044242 76.335392 C 73.975823 76.335392 76.335909 73.975306 76.335909 71.043726 L 76.335909 5.304069 C 76.335909 2.3724887 73.975823 0.012402344 71.044242 0.012402344 L 5.3045858 0.012402344 z M 33.009355 39.365039 L 38.94646 39.365039 L 38.94646 50.102368 C 39.321997 49.768449 39.728897 49.467499 40.188245 49.221802 C 41.300671 48.600912 42.581646 48.290592 44.030387 48.290592 C 45.504999 48.290592 46.798344 48.600912 47.910771 49.221802 C 49.023196 49.81682 49.876836 50.657573 50.471855 51.744128 C 51.092743 52.804813 51.403064 54.046612 51.403064 55.469482 L 51.403064 67.537996 L 45.465959 67.537996 L 45.465959 56.788782 C 45.465959 55.805707 45.155639 55.01702 44.534749 54.422001 C 43.939731 53.801112 43.1763 53.490275 42.244967 53.490275 C 41.598207 53.490275 41.029114 53.632549 40.537577 53.917122 C 40.04604 54.175826 39.657881 54.563985 39.373307 55.081392 C 39.088733 55.57293 38.94646 56.142022 38.94646 56.788782 L 38.94646 67.537996 L 33.009355 67.537996 L 33.009355 39.365039 z M 20.203418 40.878642 L 26.14104 40.878642 L 26.14104 48.678682 L 30.409513 48.678682 L 30.409513 53.723336 L 26.14104 53.723336 L 26.14104 67.537996 L 20.203418 67.537996 L 20.203418 53.723336 L 15.934945 53.723336 L 15.934945 48.678682 L 20.203418 48.678682 L 20.203418 40.878642 z M 66.071936 48.290592 C 67.856992 48.290592 69.434885 48.717412 70.806014 49.571134 C 72.203015 50.424857 73.289652 51.588817 74.065763 53.063428 C 74.867745 54.538039 75.268791 56.219544 75.268791 58.108081 C 75.268791 59.996618 74.867745 61.67864 74.065763 63.153251 C 73.289652 64.627862 72.203015 65.791822 70.806014 66.645544 C 69.434885 67.499267 67.856992 67.926086 66.071936 67.926086 C 64.804288 67.926086 63.639812 67.680201 62.579126 67.188664 C 62.019518 66.929333 61.517632 66.616566 61.06604 66.256421 L 61.06604 75.493066 L 55.206449 75.493066 L 55.206449 48.678682 L 61.143555 48.678682 L 61.143555 49.980929 C 61.574458 49.628464 62.0526 49.323615 62.579126 49.066772 C 63.639812 48.549365 64.804288 48.290592 66.071936 48.290592 z M 65.023938 53.645821 C 64.196086 53.645821 63.458946 53.839642 62.812187 54.227698 C 62.191298 54.589883 61.699527 55.107428 61.337341 55.780058 C 60.975156 56.452688 60.794222 57.228489 60.794222 58.108081 C 60.794222 58.961804 60.962269 59.725234 61.298584 60.397864 C 61.660769 61.070494 62.165427 61.600926 62.812187 61.988981 C 63.458946 62.377037 64.183199 62.570858 64.985181 62.570858 C 65.838902 62.570858 66.576043 62.377037 67.196932 61.988981 C 67.843691 61.600926 68.34835 61.070494 68.710535 60.397864 C 69.07272 59.725234 69.253654 58.961804 69.253654 58.108081 C 69.253654 57.228489 69.07272 56.452688 68.710535 55.780058 C 68.34835 55.107428 67.843691 54.589883 67.196932 54.227698 C 66.576043 53.839642 65.85179 53.645821 65.023938 53.645821 z " />
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 4.9 KiB |
@ -1,10 +1,10 @@
|
||||
---
|
||||
import { leftTrimDedent } from "./utils";
|
||||
import { thp_highlighter } from "../lexer/highlighter";
|
||||
import { native_highlighter } from "../lexer/highlighter";
|
||||
|
||||
const { thpcode } = Astro.props;
|
||||
const html_code = thp_highlighter(leftTrimDedent(thpcode).join("\n"));
|
||||
|
||||
const native_html = await native_highlighter(thpcode);
|
||||
---
|
||||
|
||||
<pre
|
||||
class="language-thp"><code class="language-thp" set:html={html_code} /><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-2 right-2 inline-block text-sm select-none opacity-75">thp</span></pre>
|
||||
|
@ -18,7 +18,7 @@ if (!title) {
|
||||
|
||||
<div>
|
||||
<div class="bg-c-thp text-c-bg">
|
||||
<h1 class="container mx-auto font-medium py-8 text-3xl">
|
||||
<h1 class="container mx-auto font-medium py-8 text-3xl font-display">
|
||||
{subtitle} <span class="font-black">{title}</span>
|
||||
</h1>
|
||||
</div>
|
||||
|
@ -16,9 +16,12 @@ function buildHierarchy(headings: any) {
|
||||
const heading = { ...h, subheadings: [] };
|
||||
parentHeadings.set(heading.depth, heading);
|
||||
// Change 2 to 1 if your markdown includes your <h1>
|
||||
if (heading.depth === 1) {
|
||||
if (heading.depth === 2) {
|
||||
toc.push(heading);
|
||||
} else {
|
||||
} else if (heading.depth === 1) {
|
||||
/** empty */
|
||||
}
|
||||
else {
|
||||
parentHeadings.get(heading.depth - 1).subheadings.push(heading);
|
||||
}
|
||||
});
|
||||
|
9
src/components/docs/CodeMin.astro
Normal file
9
src/components/docs/CodeMin.astro
Normal file
@ -0,0 +1,9 @@
|
||||
---
|
||||
import { native_highlighter } from "../../lexer/highlighter";
|
||||
|
||||
const { thpcode, href } = Astro.props;
|
||||
|
||||
const native_html = await native_highlighter(thpcode);
|
||||
---
|
||||
|
||||
<a href={href} class="inline-block w-full py-2 font-mono whitespace-pre" set:html={native_html} />
|
4
src/components/docs/Warning.astro
Normal file
4
src/components/docs/Warning.astro
Normal file
@ -0,0 +1,4 @@
|
||||
<div class="my-6 px-4 py-2 rounded bg-red-200 dark:bg-red-950">
|
||||
<div class="font-bold pt-2">Warning</div>
|
||||
<slot />
|
||||
</div>
|
@ -24,6 +24,7 @@ const { headings } = Astro.props;
|
||||
class="py-[3.5rem] lg:pl-12 lg:pr-4 markdown min-w-0 small-container mx-auto"
|
||||
>
|
||||
<slot />
|
||||
<div class="h-32"></div>
|
||||
</main>
|
||||
|
||||
<div
|
||||
@ -38,6 +39,4 @@ const { headings } = Astro.props;
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="h-32"></div>
|
||||
</BaseLayout>
|
||||
|
@ -24,11 +24,7 @@ const { title } = Astro.props;
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Fira+Sans:wght@400;500;600;700;800;900&family=Fira+Code&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap"
|
||||
href="https://fonts.googleapis.com/css2?family=Inter:wght@100..900&family=Outfit:wght@100..900&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
</head>
|
||||
@ -37,5 +33,9 @@ const { title } = Astro.props;
|
||||
<slot />
|
||||
|
||||
<script src="/js/alpine-3.14.0.min.js" defer></script>
|
||||
<script>
|
||||
import { highlightOnDom } from "./thpHighlighter";
|
||||
document.addEventListener("DOMContentLoaded", highlightOnDom);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -7,7 +7,7 @@ export function highlightOnDom() {
|
||||
|
||||
// Create a visual indicador
|
||||
const indicator = document.createElement("span");
|
||||
indicator.className = "absolute top-2 right-2 inline-block text-sm select-none opacity-75";
|
||||
indicator.className = `absolute top-1 right-0 inline-block text-sm select-none opacity-75 ${language === "php" ? "bg-[#4f5b93]" : ""} px-2 rounded-full`;
|
||||
indicator.innerText = language;
|
||||
pre_el.appendChild(indicator);
|
||||
}
|
||||
|
@ -1,13 +1,148 @@
|
||||
import { lex } from "./lexer";
|
||||
import { spawn } from "node:child_process";
|
||||
import { leftTrimDedent } from "../components/utils";
|
||||
|
||||
export function thp_highlighter(code: string) {
|
||||
let tokens = lex(code);
|
||||
export interface LexResult {
|
||||
Ok?: Token[]
|
||||
Err?: Err
|
||||
}
|
||||
|
||||
let highlighted_code = "";
|
||||
export interface Token {
|
||||
token_type: TokenType
|
||||
value: string
|
||||
position: number
|
||||
}
|
||||
|
||||
for (let token of tokens) {
|
||||
highlighted_code += `<span class="token ${token.token_type}">${token.v}</span>`;
|
||||
type TokenType =
|
||||
"Identifier" |
|
||||
"Datatype" |
|
||||
"Int" |
|
||||
"Float" |
|
||||
"String" |
|
||||
"Operator" |
|
||||
"LeftParen" |
|
||||
"RightParen" |
|
||||
"LeftBracket" |
|
||||
"RightBracket" |
|
||||
"LeftBrace" |
|
||||
"RightBrace" |
|
||||
"NewLine" |
|
||||
"Comment" |
|
||||
"Comma" |
|
||||
"INDENT" |
|
||||
"DEDENT" |
|
||||
"VAL" |
|
||||
"VAR" |
|
||||
"EOF" |
|
||||
"FUN";
|
||||
|
||||
export interface Err {
|
||||
Lex: LexError
|
||||
}
|
||||
|
||||
export interface LexError {
|
||||
position: number
|
||||
reason: string
|
||||
}
|
||||
|
||||
|
||||
export async function native_highlighter(code: string): Promise<string> {
|
||||
let formatted_code = leftTrimDedent(code).join("\n");
|
||||
|
||||
const result = await native_lex(formatted_code);
|
||||
|
||||
if (result.Err) {
|
||||
throw new Error(JSON.stringify(result.Err.Lex) + "\n" + code);
|
||||
}
|
||||
|
||||
return highlighted_code;
|
||||
const tokens = result.Ok!;
|
||||
|
||||
const input_chars = formatted_code.split("");
|
||||
let output = "";
|
||||
|
||||
let current_pos = 0;
|
||||
|
||||
for (let i = 0; i < tokens.length; i += 1) {
|
||||
const t = tokens[i]!;
|
||||
const token_start = t.position;
|
||||
const token_end = t.position + t.value.length;
|
||||
|
||||
// There are some tokens that are empty, ignore them
|
||||
if (t.value == "") {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Append all characters before the token
|
||||
output += input_chars.slice(current_pos, token_start).join("");
|
||||
|
||||
// Append the token
|
||||
const token_value = t.value.replaceAll(/</g, "<").replaceAll(/>/g, ">");
|
||||
const token_type = translate_token_type(t.token_type, token_value);
|
||||
output += `<span class="token ${token_type}">${token_value}</span>`;
|
||||
|
||||
current_pos = token_end;
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
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", "pub", "override", "open", "init", "val", "var", "mut", "clone"];
|
||||
|
||||
switch (tt) {
|
||||
case "Datatype":
|
||||
return "class-name";
|
||||
case "Identifier": {
|
||||
if (keywords.includes(value)) {
|
||||
return "keyword";
|
||||
}
|
||||
|
||||
return "identifier";
|
||||
}
|
||||
case "Int":
|
||||
return "number";
|
||||
case "Float":
|
||||
return "number";
|
||||
case "String":
|
||||
return "string";
|
||||
case "Comment":
|
||||
return "comment";
|
||||
// keywords:
|
||||
case "VAL":
|
||||
case "VAR":
|
||||
case "FUN":
|
||||
return "keyword";
|
||||
default:
|
||||
return tt;
|
||||
}
|
||||
}
|
||||
|
||||
const native_lex = (code: string) => new Promise<LexResult>((resolve, reject) => {
|
||||
// Get binary path from .env
|
||||
const binary = import.meta.env.THP_BINARY;
|
||||
if (!binary) {
|
||||
throw new Error("THP_BINARY not set in .env");
|
||||
}
|
||||
|
||||
const subprocess = spawn(binary, ["tokenize"]);
|
||||
let response = "";
|
||||
let error = "";
|
||||
|
||||
subprocess.stdin.write(code);
|
||||
subprocess.stdin.end();
|
||||
|
||||
subprocess.stdout.on("data", (data) => {
|
||||
response += data.toString();
|
||||
});
|
||||
|
||||
subprocess.stderr.on("data", (data) => {
|
||||
error += data.toString();
|
||||
});
|
||||
|
||||
subprocess.on("close", (code) => {
|
||||
if (code === 0) {
|
||||
resolve(JSON.parse(response));
|
||||
} else {
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
})
|
||||
|
@ -2,6 +2,9 @@
|
||||
layout: ../../../layouts/ApiLayout.astro
|
||||
---
|
||||
import TwoColumn from "../../../components/TwoColumn.astro"
|
||||
import Code from "../../../components/Code.astro"
|
||||
import CodeMin from "../../../components/docs/CodeMin.astro"
|
||||
import Warning from "../../../components/docs/Warning.astro"
|
||||
|
||||
# Array
|
||||
|
||||
@ -16,39 +19,38 @@ THP arrays are 0-indexed.
|
||||
|
||||
## Signature
|
||||
|
||||
```thp
|
||||
<Code thpcode={`
|
||||
type Array[T] = Map[Int, T]
|
||||
```
|
||||
`} />
|
||||
|
||||
Where `T` is the datatype that the Array stores. For example:
|
||||
|
||||
```thp
|
||||
<Code thpcode={`
|
||||
Array[Int] // An array of integers
|
||||
Array[Float] // An array of floats
|
||||
Array[Array[String]] // A 2-dimensional array of strings
|
||||
```
|
||||
`} />
|
||||
|
||||
## PHP array internals
|
||||
|
||||
<Warning>
|
||||
TL;DR: **Never** assign to an array using an invalid index. If you do
|
||||
the program will not crash, but it will not behaved as expected
|
||||
the program will not crash, instead it will not behaved as expected
|
||||
[(this is a common problem in PHP)](https://eev.ee/blog/2012/04/09/php-a-fractal-of-bad-design/).
|
||||
THP tries its best to solve such behavior.
|
||||
|
||||
---
|
||||
</Warning>
|
||||
|
||||
|
||||
Since THP compiles down to PHP, it's important to understand how PHP
|
||||
represents arrays internally.
|
||||
|
||||
PHP doesn't have arrays. Instead, PHP has ordered maps and syntax sugar
|
||||
to make them look like arrays.
|
||||
|
||||
When declaring an array like:
|
||||
|
||||
```thp
|
||||
<Code thpcode={`
|
||||
var arr = ["a", "b", "c"]
|
||||
```
|
||||
`} />
|
||||
|
||||
in reality what goes into memory is a map with numbers as keys:
|
||||
|
||||
@ -75,7 +77,7 @@ Invalid indexes are:
|
||||
PHP maps preserve insertion order. This means that when iterating over
|
||||
a PHP map, values are processed in FIFO.
|
||||
|
||||
```thp
|
||||
<Code thpcode={`
|
||||
var numbers = ["a", "b", "c"]
|
||||
numbers[-10] = "?" // Assign to a negative index
|
||||
|
||||
@ -127,7 +129,7 @@ numbers.push("/") // This will be at position 8
|
||||
// -4: "???",
|
||||
// 8: "/",
|
||||
// }
|
||||
```
|
||||
`} />
|
||||
|
||||
This is one of many fundamental flaws with PHP. The only way to solve it
|
||||
would be to check every insertion at runtime, and this would have a
|
||||
@ -146,59 +148,59 @@ abstraction, as if all indexes were valid.
|
||||
To create an empty array use square brackets.
|
||||
If you create an empty array, you need to specify the datatype.
|
||||
|
||||
```thp
|
||||
<Code thpcode={`
|
||||
Array[Int] empty = []
|
||||
```
|
||||
`} />
|
||||
|
||||
|
||||
### Creation
|
||||
|
||||
To create an array use square brackets notation:
|
||||
|
||||
```thp
|
||||
<Code thpcode={`
|
||||
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
|
||||
item should have a trailing comma:
|
||||
|
||||
```thp
|
||||
<Code thpcode={`
|
||||
val colors = [
|
||||
"red",
|
||||
"blue",
|
||||
"green", // trailing comma
|
||||
]
|
||||
```
|
||||
`} />
|
||||
|
||||
If it doesn't, the code formatter will automatically
|
||||
insert one for you.
|
||||
|
||||
### Assignment
|
||||
### Assignment to elements
|
||||
|
||||
Use square brackets notation to insert into an array or modify it:
|
||||
|
||||
To modify an array it must be mutable, that is, assigned to a `var`
|
||||
instead of a `val`.
|
||||
|
||||
```thp
|
||||
// This array cannot be modified, as it's declared with `val`
|
||||
<Code thpcode={`
|
||||
// This array cannot be modified, as it's declared with \`val\`
|
||||
val immutable = [1, 2, 3]
|
||||
// This is a compile time error
|
||||
immutable[0] = 322
|
||||
|
||||
// This array can be modified, as it's declared with `var`
|
||||
// This array can be modified, as it's declared with \`var\`
|
||||
var mutable = [1, 2, 3]
|
||||
// Ok
|
||||
mutable[0] = 322
|
||||
```
|
||||
`} />
|
||||
|
||||
To append an element to an array, use the method `push()`:
|
||||
|
||||
```thp
|
||||
<Code thpcode={`
|
||||
mutable.push(4)
|
||||
```
|
||||
`} />
|
||||
|
||||
Do not insert into an invalid index. See [PHP array internals](#php-array-internals) to learn why.
|
||||
|
||||
@ -207,28 +209,58 @@ Do not insert into an invalid index. See [PHP array internals](#php-array-intern
|
||||
|
||||
Use a `for` loop to iterate over the elements of an array:
|
||||
|
||||
```thp
|
||||
<Code thpcode={`
|
||||
val colors = ["red", "green", "blue"]
|
||||
|
||||
for #(_index, c) in colors
|
||||
for c in colors
|
||||
{
|
||||
print("{c} ")
|
||||
}
|
||||
```
|
||||
`} />
|
||||
|
||||
```sh
|
||||
red green blue
|
||||
```
|
||||
|
||||
A for loop automatically declares new immutable variables. It is a compile
|
||||
error to attempt to modify those, as in the following snippet:
|
||||
|
||||
<Code thpcode={`
|
||||
val colors = ["red", "green", "blue"]
|
||||
|
||||
for c in colors
|
||||
{
|
||||
c = "orange" // Compile error: Can't assign to an immutable variable
|
||||
print("{c} ")
|
||||
}
|
||||
`} />
|
||||
|
||||
|
||||
You can also declare an index along with the value:
|
||||
|
||||
<Code thpcode={`
|
||||
val colors = ["red", "green", "blue"]
|
||||
|
||||
for index, color in colors
|
||||
{
|
||||
println("item {index}: {c}")
|
||||
}
|
||||
`} />
|
||||
|
||||
```sh
|
||||
item 0: red
|
||||
item 1: green
|
||||
item 2: blue
|
||||
```
|
||||
|
||||
|
||||
### Access
|
||||
|
||||
To access a value of the array use square brackets notation:
|
||||
|
||||
```thp
|
||||
<Code thpcode={`
|
||||
print(colors[0])
|
||||
```
|
||||
`} />
|
||||
|
||||
Since the index might not exist, this will return a
|
||||
[nullable type](/learn/error-handling/null/) that you have to handle.
|
||||
@ -240,6 +272,17 @@ THP arrays don't have destructuring, since the values can all be `null`.
|
||||
If you know that the number of elements is fixed and valid, use Tuples instead.
|
||||
|
||||
|
||||
### Operators
|
||||
|
||||
While PHP allows using certain operators with arrays, THP disallows that.
|
||||
Methods that perform comparisons should be used instead.
|
||||
|
||||
|
||||
### Assignment
|
||||
|
||||
// TODO: Detail that assignment of arrays is copy on write
|
||||
|
||||
|
||||
## Methods
|
||||
|
||||
In the parameters, <code class="token keyword">self</code> is the array to operate on.
|
||||
@ -253,25 +296,26 @@ In the parameters, <code class="token keyword">self</code> is the array to opera
|
||||
<tbody>
|
||||
<tr class="dark:odd:bg-zinc-900 odd:bg-stone-200">
|
||||
<td class="px-2">
|
||||
<p class="font-mono whitespace-pre">
|
||||
<span class="token keyword">fun </span>
|
||||
<span class="token function">filter</span>
|
||||
<span>[</span>
|
||||
<span class="token class">T</span>
|
||||
<span>]</span>
|
||||
<span>(</span>
|
||||
<br/>
|
||||
<span class="token keyword"> self</span>
|
||||
<span>,</span>
|
||||
<br />
|
||||
<span> (T) -> Bool callback,</span>
|
||||
<br />
|
||||
<span>)-> </span>
|
||||
<span class="token class">Array</span>
|
||||
<span>[</span>
|
||||
<span class="token class">T</span>
|
||||
<span>]</span>
|
||||
</p>
|
||||
<CodeMin href="./concat" thpcode={`
|
||||
fun concat[T](
|
||||
self,
|
||||
Array[T]... arrays,
|
||||
) -> Array[T]
|
||||
`} />
|
||||
</td>
|
||||
<td>
|
||||
Concatenate with other arrays, and return the result
|
||||
as a new array.
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="dark:odd:bg-zinc-900 odd:bg-stone-200">
|
||||
<td class="px-2">
|
||||
<CodeMin thpcode={`
|
||||
fun filter[T](
|
||||
self,
|
||||
(T) -> (Bool) callback,
|
||||
) -> Array[T]
|
||||
`} />
|
||||
</td>
|
||||
<td>
|
||||
Filters elements using a callback function, and returns
|
||||
@ -280,17 +324,7 @@ In the parameters, <code class="token keyword">self</code> is the array to opera
|
||||
</tr>
|
||||
<tr class="dark:odd:bg-zinc-900 odd:bg-stone-200">
|
||||
<td class="px-2">
|
||||
<p class="font-mono">
|
||||
<span class="token keyword">fun </span>
|
||||
<span class="token function">push</span>
|
||||
<span>[</span>
|
||||
<span class="token class">T</span>
|
||||
<span>]</span>
|
||||
<span>(</span>
|
||||
<span class="token keyword">self</span>
|
||||
<span>, T ...elements) -> </span>
|
||||
<span class="token class">Int</span>
|
||||
</p>
|
||||
<CodeMin thpcode="fun push[T](self, T... elements) -> Int" />
|
||||
</td>
|
||||
<td>
|
||||
Appends one or more elements to the end of the array.
|
||||
@ -299,17 +333,7 @@ In the parameters, <code class="token keyword">self</code> is the array to opera
|
||||
</tr>
|
||||
<tr class="dark:odd:bg-zinc-900 odd:bg-stone-200">
|
||||
<td class="px-2">
|
||||
<p class="font-mono">
|
||||
<span class="token keyword">fun </span>
|
||||
<span class="token function">pop</span>
|
||||
<span>[</span>
|
||||
<span class="token class">T</span>
|
||||
<span>]</span>
|
||||
<span>(</span>
|
||||
<span class="token keyword">self</span>
|
||||
<span>) -> </span>
|
||||
<span class="token class">T</span>
|
||||
</p>
|
||||
<CodeMin thpcode="fun pop[T](self) -> T" />
|
||||
</td>
|
||||
<td>
|
||||
Removes the last value of the array, and returns it.
|
||||
@ -319,4 +343,3 @@ In the parameters, <code class="token keyword">self</code> is the array to opera
|
||||
</table>
|
||||
|
||||
|
||||
|
||||
|
112
src/pages/api/std/Array/concat.mdx
Normal file
112
src/pages/api/std/Array/concat.mdx
Normal file
@ -0,0 +1,112 @@
|
||||
---
|
||||
layout: ../../../../layouts/ApiLayout.astro
|
||||
---
|
||||
import Code from "../../../../components/Code.astro"
|
||||
|
||||
# `Array.concat`
|
||||
|
||||
Concatenate with other arrays, and return the result as a new array.
|
||||
|
||||
## Signature
|
||||
|
||||
<Code thpcode={`
|
||||
fun concat[T](
|
||||
self,
|
||||
Array[T]... arrays,
|
||||
) -> Array[T]
|
||||
`} />
|
||||
|
||||
## Parameters
|
||||
|
||||
- `self`: The callee.
|
||||
- `Array[T]... arrays`: Multiple arrays to concatenate the current one to.
|
||||
|
||||
## Return value
|
||||
|
||||
`Array[T]`: A new array that contains the elements from all arrays.
|
||||
|
||||
|
||||
## Description
|
||||
|
||||
Concatenates the elements of the callee and the elements of each array in the
|
||||
variable `array`. These values are returned in a new array.
|
||||
|
||||
If called without any aditional array it returns a new array with the elements
|
||||
of `self`.
|
||||
|
||||
The returned array is a new one. However, if the elements of the callee and the
|
||||
parameters are references, the returned array will contain references that point
|
||||
to the same memory. This is important if, for example, the arrays contain other
|
||||
arrays or objects.
|
||||
|
||||
## Examples
|
||||
|
||||
Example concatenating 2 arrays:
|
||||
|
||||
<Code thpcode={`
|
||||
val first = [1, 2, 3]
|
||||
val second = [4, 5, 6]
|
||||
|
||||
val result = first.concat(second)
|
||||
assert_eq(result, [1, 2, 3, 4, 5, 6])
|
||||
`} />
|
||||
|
||||
Example concatenating 3 arrays:
|
||||
|
||||
<Code thpcode={`
|
||||
val first = ["a", "b"]
|
||||
val second = ["c", "d"]
|
||||
val third = ["e", "f"]
|
||||
|
||||
val result = first.concat(second, third)
|
||||
assert_eq(result, ["a", "b", "c", "d", "e", "f"])
|
||||
`} />
|
||||
|
||||
Example concatenating without any other array. In this case
|
||||
`first` and `result` are different arrays:
|
||||
|
||||
<Code thpcode={`
|
||||
val first = [1, 2, 3]
|
||||
|
||||
val result = first.concat()
|
||||
assert_eq(result, [1, 2, 3])
|
||||
`} />
|
||||
|
||||
Example concatenating an empty array with a filled array:
|
||||
|
||||
<Code thpcode={`
|
||||
val first = []
|
||||
val second = [10, 20, 30]
|
||||
|
||||
val result = first.concat(second)
|
||||
assert_eq(result, [10, 20, 30])
|
||||
`} />
|
||||
|
||||
|
||||
## PHP interop
|
||||
|
||||
This method is directly compiled to `array_merge`. Since THP guarantees that
|
||||
arrays only have numbers as keys, this will never produce invalid values due
|
||||
to merging with an array with string keys.
|
||||
|
||||
If the arrays contain invalid keys (negative values, out of bounds) the merge
|
||||
is performed based on the insertion order, not the keys order, and the resulting
|
||||
array will have correct keys.
|
||||
|
||||
```php
|
||||
$array_1 = [2 => "a", 0 => "b"];
|
||||
$array_2 = [1 => "c"];
|
||||
|
||||
var_dump(array_merge($array_1, $array_2));
|
||||
```
|
||||
|
||||
```out
|
||||
array(3) {
|
||||
[0]=> string(1) "a"
|
||||
[1]=> string(1) "b"
|
||||
[2]=> string(1) "c"
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
@ -1,6 +0,0 @@
|
||||
---
|
||||
layout: ../../../../layouts/ApiLayout.astro
|
||||
---
|
||||
|
||||
# Array.filter
|
||||
|
@ -2,7 +2,7 @@
|
||||
import BaseLayout from "../layouts/BaseLayout.astro";
|
||||
import Navbar from "../components/Navbar.astro";
|
||||
import HeroSection from "../components/HeroSection.astro";
|
||||
import { thp_highlighter } from "../lexer/highlighter";
|
||||
import { native_highlighter } from "../lexer/highlighter";
|
||||
import { leftTrimDedent } from "../components/utils";
|
||||
|
||||
const thpcode = `union Animal {
|
||||
@ -118,7 +118,7 @@ case Cat(name, lives)
|
||||
</svg>
|
||||
<div class="h-1"></div>
|
||||
<div id="editor" class="font-mono language-thp">
|
||||
<pre set:html={thp_highlighter(leftTrimDedent(thpcode).join("\n"))}></pre>
|
||||
<pre set:html={native_highlighter(leftTrimDedent(thpcode).join("\n"))}></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -196,7 +196,7 @@ $cat->meow();
|
||||
<Code thpcode={`
|
||||
// THP
|
||||
val cat = Cat("Michifu", 7)
|
||||
cat.meow();
|
||||
cat.meow()
|
||||
`} />
|
||||
|
||||
- Instantiate classes without `new`
|
||||
|
@ -21,7 +21,7 @@ export default {
|
||||
},
|
||||
fontFamily: {
|
||||
"mono": ["'Iosevka Fixed Web'", "Iosevka", "'Iosevka Nerd Font'", "monospace"],
|
||||
"display": ["Inter", "'Josefin Sans'", "'Fugaz One'", "sans-serif"],
|
||||
"display": ["Outfit", "Inter", "sans-serif"],
|
||||
"body": ["Inter", "sans-serif"],
|
||||
},
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user