Compare commits

...
4 Commits
Author SHA1 Message Date
Riyyi 74d571c10f Put all binaries in git 2025-04-09 00:02:54 +02:00
Riyyi 9bbbb80e75 Implement sitemap.xml and robots.txt 2025-04-08 23:36:17 +02:00
Riyyi f610edf22c Prepend baseURL to favicon.ico 2025-04-07 20:35:53 +02:00
Riyyi 5aa314e40e Finish blaze lisp article 2025-04-07 19:59:24 +02:00
19 changed files with 376 additions and 33 deletions
+4 -1
View File
@@ -1,11 +1,13 @@
import { defineContentConfig, defineCollection, z } from '@nuxt/content'
import { asSitemapCollection } from "@nuxtjs/sitemap/content"
// Lookup resolved from path: rootDir/content
// see: https://github.com/nuxt/content/issues/3161
export default defineContentConfig({
collections: {
content: defineCollection({
content: defineCollection(
asSitemapCollection({
type: "page",
source: "**/*.md",
schema: z.object({
@@ -14,5 +16,6 @@ export default defineContentConfig({
tags: z.array(z.string()),
})
})
)
}
});
+1 -1
View File
@@ -25,7 +25,7 @@ for the presentation that I gave at Hogeschool Rotterdam.
Korte video waarin de meeste functionaliteit van de bank ATM wordt getoond.
::VideoLazy{:src="https://riyyi.com/media/bank-atm-demo.webm"}
::VideoLazy{:src="/img/bank-atm/demo.webm"}
::
## Overzicht componenten
+75 -2
View File
@@ -3,7 +3,7 @@ title: "blaze lisp"
description: "An implementation of the MAL (Make a Lisp) project."
navigation: false
date: "2023-03-18"
img: "/img/.png"
img: "/img/mal-steps.png"
tags:
- C++20
- CMake
@@ -17,4 +17,77 @@ Repository at
[Gitea](https://git.riyyi.com/riyyi/blaze){target="_blank"}.
</small>
TODO
After having implemented the JSON serializer for my [utility
library](/articles/utility-library), I became interested in interpreters. The
utility library just has the `tokenization` step of an interpreter, so my tought
was, what's next? That's right, `parsing`.
Having used Emacs quite a bit, I wasn't shy of Lisp. Then, I came across the MAL
([Make a Lisp](https://github.com/kanaka/mal){target="_blank"}) project, and
decided to look into it. The project lays out the implementation steps of making
a Lisp programming language in 10 or so steps and also provides you with unit
tests that have to pass to proceed to the next step. There are also a bunch of
reference implementations to refer to, in case you get stuck.
Feeling like implementing a fully interpreted language was a bit of an
undertaking and realizing that in a Lisp `parsing` and `interpreting` is
basically combined into one step, it seemed achievable and I decided to give the
MAL project a go.
The final architechture that has to be implemented is pictured below.
<div class="row">
<div class="col-lg-9 col-xl-6">
![](/img/mal-steps.png "")
</div>
</div>
I managed to do a full implementation, including `variables`, `if` statements,
`loops`, `functions`, `try/catch` exceptions, `lists`, `arrays`, `hash-maps` and
even `macros`.
With the REPL you can try things out and play around easily.
```
./repl
Blaze [C++]
user>
```
```elisp
user> 123
123
user> (+ 1 2.5)
3.5
user> (- 10 (- 5 3))
8
user> "hello world"
"hello world"
user> (= 2 3)
true
user> (if (> 2 4) "yes" "no")
"no"
user> (count (list 3 6 2 9))
4
user> (count '(3 6 2 9)) ; list shorthand
4
user> (list? [2.1 nil "text"]) ; array / vector
false
user> {:a (+ 7 8)} ; hash-map
{"a" 15}
user> (def! mul (fn* [x y] (* x y))) ; defining a function
#<user-function>(0x5f35f38815d0)
user> (mul 4 5)
20
```
This project was really interesting and the language is quite powerful, powerful
enough to accomplish self-hosting! This means that an interpreter (or rather,
eval+apply) _for_ this language, can be written _in_ the language.
If you're curious about reading more examples, a good place is probably the
testsuite for the project, those have a bunch of unit tests and are available
[here](https://github.com/kanaka/mal/tree/master/impls/tests).
+1 -1
View File
@@ -32,5 +32,5 @@ Preview.
Demo showcasing translation, rotation, scaling and textures working. You can
also fly around, which is not shown in the video.
::VideoLazy{:src="https://riyyi.com/media/opengl-test-demo.webm"}
::VideoLazy{:src="/img/opengl-test-demo.webm"}
::
+1 -1
View File
@@ -76,5 +76,5 @@ Completed assembly.
Domoticz is used as a controller, which completes the smart outlet project. View
the demo below.
::VideoLazy{:src="https://riyyi.com/media/smart-outlet-demo.webm"}
::VideoLazy{:src="/img/smart-outlet/demo.webm"}
::
+9 -2
View File
@@ -15,7 +15,7 @@ export default defineNuxtConfig({
},
langs: [
// https://github.com/shikijs/shiki/blob/main/packages/langs/package.json
"c", "cpp", "css", "html", "js", "json", "lua", "md", "mdc", "php", "python", "shell", "ts", "vue", "yaml"
"c", "cpp", "css", "elisp", "html", "js", "json", "lua", "md", "mdc", "php", "python", "shell", "ts", "vue", "yaml"
]
},
toc: {
@@ -36,7 +36,9 @@ export default defineNuxtConfig({
public: "../public"
},
modules: [
"@nuxt/content",
"@nuxtjs/robots",
"@nuxtjs/sitemap",
"@nuxt/content", // NOTE: @nuxt/content after robots and sitemap
"@nuxt/eslint",
"@pinia/nuxt",
"pinia-plugin-persistedstate/nuxt",
@@ -52,6 +54,11 @@ export default defineNuxtConfig({
secure: process.env.NODE_ENV !== "development" // only send over HTTPS
}
},
routeRules: {
// Dont add to the sitemap.xml
"/__nuxt_content/**": { robots: false },
},
site: { url: "https://riyyi.com", name: "Personal Website" },
srcDir: "src/",
ssr: false,
typescript: {
+268 -1
View File
@@ -22,6 +22,8 @@
"@iconify-json/fa-solid": "^1.2.1",
"@nuxt/content": "^3.4.0",
"@nuxt/eslint": "^1.2.0",
"@nuxtjs/robots": "^5.2.9",
"@nuxtjs/sitemap": "^7.2.10",
"@types/bootstrap": "^5.2.10",
"@vue/language-server": "^2.1.10",
"@vue/typescript-plugin": "^2.1.10",
@@ -1642,6 +1644,136 @@
"vfile": "^6.0.3"
}
},
"node_modules/@nuxtjs/robots": {
"version": "5.2.9",
"resolved": "https://registry.npmjs.org/@nuxtjs/robots/-/robots-5.2.9.tgz",
"integrity": "sha512-JJykE1llIByw8vqhrn4abSPyAcEFnfVOkIaD2/XLwkhNeZHzAQT2/p+ZhqwtaSMyWq8pnW1y0ei7gQYdCqOu+g==",
"dev": true,
"license": "MIT",
"dependencies": {
"@nuxt/kit": "^3.16.2",
"consola": "^3.4.2",
"defu": "^6.1.4",
"nuxt-site-config": "^3.1.9",
"pathe": "^2.0.3",
"pkg-types": "^2.1.0",
"sirv": "^3.0.1",
"std-env": "^3.9.0",
"ufo": "^1.5.4"
},
"funding": {
"url": "https://github.com/sponsors/harlan-zw"
}
},
"node_modules/@nuxtjs/robots/node_modules/@nuxt/kit": {
"version": "3.16.2",
"resolved": "https://registry.npmjs.org/@nuxt/kit/-/kit-3.16.2.tgz",
"integrity": "sha512-K1SAUo2vweTfudKZzjKsZ5YJoxPLTspR5qz5+G61xtZreLpsdpDYfBseqsIAl5VFLJuszeRpWQ01jP9LfQ6Ksw==",
"dev": true,
"license": "MIT",
"dependencies": {
"c12": "^3.0.2",
"consola": "^3.4.2",
"defu": "^6.1.4",
"destr": "^2.0.3",
"errx": "^0.1.0",
"exsolve": "^1.0.4",
"globby": "^14.1.0",
"ignore": "^7.0.3",
"jiti": "^2.4.2",
"klona": "^2.0.6",
"knitwork": "^1.2.0",
"mlly": "^1.7.4",
"ohash": "^2.0.11",
"pathe": "^2.0.3",
"pkg-types": "^2.1.0",
"scule": "^1.3.0",
"semver": "^7.7.1",
"std-env": "^3.8.1",
"ufo": "^1.5.4",
"unctx": "^2.4.1",
"unimport": "^4.1.3",
"untyped": "^2.0.0"
},
"engines": {
"node": ">=18.12.0"
}
},
"node_modules/@nuxtjs/sitemap": {
"version": "7.2.10",
"resolved": "https://registry.npmjs.org/@nuxtjs/sitemap/-/sitemap-7.2.10.tgz",
"integrity": "sha512-7w1Ys2XIE/QVTJn5dbt2p/hrmDoGO9Ay1S3o6LI5M/MDRzKPvnXi5ByRUcc7Sfa3LUpLad5/w4IOQ4lyxhq9Hw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@nuxt/devtools-kit": "^2.3.2",
"@nuxt/kit": "^3.16.2",
"chalk": "^5.4.1",
"defu": "^6.1.4",
"h3-compression": "^0.3.2",
"nuxt-site-config": "^3.1.9",
"ofetch": "^1.4.1",
"pathe": "^2.0.3",
"pkg-types": "^2.1.0",
"radix3": "^1.1.2",
"semver": "^7.7.1",
"sirv": "^3.0.1",
"ufo": "^1.5.4"
},
"engines": {
"node": ">=18.0.0"
},
"funding": {
"url": "https://github.com/sponsors/harlan-zw"
}
},
"node_modules/@nuxtjs/sitemap/node_modules/@nuxt/kit": {
"version": "3.16.2",
"resolved": "https://registry.npmjs.org/@nuxt/kit/-/kit-3.16.2.tgz",
"integrity": "sha512-K1SAUo2vweTfudKZzjKsZ5YJoxPLTspR5qz5+G61xtZreLpsdpDYfBseqsIAl5VFLJuszeRpWQ01jP9LfQ6Ksw==",
"dev": true,
"license": "MIT",
"dependencies": {
"c12": "^3.0.2",
"consola": "^3.4.2",
"defu": "^6.1.4",
"destr": "^2.0.3",
"errx": "^0.1.0",
"exsolve": "^1.0.4",
"globby": "^14.1.0",
"ignore": "^7.0.3",
"jiti": "^2.4.2",
"klona": "^2.0.6",
"knitwork": "^1.2.0",
"mlly": "^1.7.4",
"ohash": "^2.0.11",
"pathe": "^2.0.3",
"pkg-types": "^2.1.0",
"scule": "^1.3.0",
"semver": "^7.7.1",
"std-env": "^3.8.1",
"ufo": "^1.5.4",
"unctx": "^2.4.1",
"unimport": "^4.1.3",
"untyped": "^2.0.0"
},
"engines": {
"node": ">=18.12.0"
}
},
"node_modules/@nuxtjs/sitemap/node_modules/chalk": {
"version": "5.4.1",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz",
"integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==",
"dev": true,
"license": "MIT",
"engines": {
"node": "^12.17.0 || ^14.13 || >=16.0.0"
},
"funding": {
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
"node_modules/@oxc-parser/binding-linux-x64-gnu": {
"version": "0.56.5",
"cpu": [
@@ -5873,6 +6005,19 @@
"uncrypto": "^0.1.3"
}
},
"node_modules/h3-compression": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/h3-compression/-/h3-compression-0.3.2.tgz",
"integrity": "sha512-B+yCKyDRnO0BXSfjAP4tCXJgJwmnKp3GyH5Yh66mY9KuOCrrGQSPk/gBFG2TgH7OyB/6mvqNZ1X0XNVuy0qRsw==",
"dev": true,
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/codedredd"
},
"peerDependencies": {
"h3": "^1.6.0"
}
},
"node_modules/h3/node_modules/cookie-es": {
"version": "1.2.2",
"dev": true,
@@ -8425,6 +8570,110 @@
"nuxt-component-meta": "bin/nuxt-component-meta.mjs"
}
},
"node_modules/nuxt-site-config": {
"version": "3.1.9",
"resolved": "https://registry.npmjs.org/nuxt-site-config/-/nuxt-site-config-3.1.9.tgz",
"integrity": "sha512-YB69GX0st8drv1d5xypweseiEWeR22tfGdyVH3U4R+mpUSz8paBx48ArKC6MgV22DKItoQm51LVoapF5pl5bEQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@nuxt/kit": "^3.16.2",
"nuxt-site-config-kit": "3.1.9",
"pathe": "^2.0.3",
"pkg-types": "^2.1.0",
"sirv": "^3.0.1",
"site-config-stack": "3.1.9",
"ufo": "^1.5.4"
},
"funding": {
"url": "https://github.com/sponsors/harlan-zw"
}
},
"node_modules/nuxt-site-config-kit": {
"version": "3.1.9",
"resolved": "https://registry.npmjs.org/nuxt-site-config-kit/-/nuxt-site-config-kit-3.1.9.tgz",
"integrity": "sha512-bcmpajYJgkNzA0jTq6CmmhKF2wHZUUKeVx/CIGI8lwWuAD81EBUZN0T4iKvVDo54g9UBrUUl8/5GhD65YBBG0A==",
"dev": true,
"license": "MIT",
"dependencies": {
"@nuxt/kit": "^3.16.2",
"pkg-types": "^2.1.0",
"site-config-stack": "3.1.9",
"std-env": "^3.9.0",
"ufo": "^1.5.4"
},
"funding": {
"url": "https://github.com/sponsors/harlan-zw"
}
},
"node_modules/nuxt-site-config-kit/node_modules/@nuxt/kit": {
"version": "3.16.2",
"resolved": "https://registry.npmjs.org/@nuxt/kit/-/kit-3.16.2.tgz",
"integrity": "sha512-K1SAUo2vweTfudKZzjKsZ5YJoxPLTspR5qz5+G61xtZreLpsdpDYfBseqsIAl5VFLJuszeRpWQ01jP9LfQ6Ksw==",
"dev": true,
"license": "MIT",
"dependencies": {
"c12": "^3.0.2",
"consola": "^3.4.2",
"defu": "^6.1.4",
"destr": "^2.0.3",
"errx": "^0.1.0",
"exsolve": "^1.0.4",
"globby": "^14.1.0",
"ignore": "^7.0.3",
"jiti": "^2.4.2",
"klona": "^2.0.6",
"knitwork": "^1.2.0",
"mlly": "^1.7.4",
"ohash": "^2.0.11",
"pathe": "^2.0.3",
"pkg-types": "^2.1.0",
"scule": "^1.3.0",
"semver": "^7.7.1",
"std-env": "^3.8.1",
"ufo": "^1.5.4",
"unctx": "^2.4.1",
"unimport": "^4.1.3",
"untyped": "^2.0.0"
},
"engines": {
"node": ">=18.12.0"
}
},
"node_modules/nuxt-site-config/node_modules/@nuxt/kit": {
"version": "3.16.2",
"resolved": "https://registry.npmjs.org/@nuxt/kit/-/kit-3.16.2.tgz",
"integrity": "sha512-K1SAUo2vweTfudKZzjKsZ5YJoxPLTspR5qz5+G61xtZreLpsdpDYfBseqsIAl5VFLJuszeRpWQ01jP9LfQ6Ksw==",
"dev": true,
"license": "MIT",
"dependencies": {
"c12": "^3.0.2",
"consola": "^3.4.2",
"defu": "^6.1.4",
"destr": "^2.0.3",
"errx": "^0.1.0",
"exsolve": "^1.0.4",
"globby": "^14.1.0",
"ignore": "^7.0.3",
"jiti": "^2.4.2",
"klona": "^2.0.6",
"knitwork": "^1.2.0",
"mlly": "^1.7.4",
"ohash": "^2.0.11",
"pathe": "^2.0.3",
"pkg-types": "^2.1.0",
"scule": "^1.3.0",
"semver": "^7.7.1",
"std-env": "^3.8.1",
"ufo": "^1.5.4",
"unctx": "^2.4.1",
"unimport": "^4.1.3",
"untyped": "^2.0.0"
},
"engines": {
"node": ">=18.12.0"
}
},
"node_modules/nuxt/node_modules/estree-walker": {
"version": "3.0.3",
"dev": true,
@@ -10419,6 +10668,22 @@
"dev": true,
"license": "MIT"
},
"node_modules/site-config-stack": {
"version": "3.1.9",
"resolved": "https://registry.npmjs.org/site-config-stack/-/site-config-stack-3.1.9.tgz",
"integrity": "sha512-ed53+wLi+36SGqidU+YUpl7f1OHClPLmvUJ/aYZny1dCBnXvOsuFottrMkXDIK2N5UaMED9mz8KrRZTk94ARCg==",
"dev": true,
"license": "MIT",
"dependencies": {
"ufo": "^1.5.4"
},
"funding": {
"url": "https://github.com/sponsors/harlan-zw"
},
"peerDependencies": {
"vue": "^3"
}
},
"node_modules/skin-tone": {
"version": "2.0.0",
"dev": true,
@@ -10620,7 +10885,9 @@
}
},
"node_modules/std-env": {
"version": "3.8.1",
"version": "3.9.0",
"resolved": "https://registry.npmjs.org/std-env/-/std-env-3.9.0.tgz",
"integrity": "sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==",
"license": "MIT"
},
"node_modules/streamx": {
+2
View File
@@ -25,6 +25,8 @@
"@iconify-json/fa-solid": "^1.2.1",
"@nuxt/content": "^3.4.0",
"@nuxt/eslint": "^1.2.0",
"@nuxtjs/robots": "^5.2.9",
"@nuxtjs/sitemap": "^7.2.10",
"@types/bootstrap": "^5.2.10",
"@vue/language-server": "^2.1.10",
"@vue/typescript-plugin": "^2.1.10",
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 405 KiB

Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
-1
View File
@@ -1 +0,0 @@
+4 -1
View File
@@ -16,8 +16,11 @@ const store = useStateStore();
store.applyColorMode();
useHead({
link: [
{ rel: "icon", type: "image/x-icon", href: getPublicPath("/favicon.ico") },
],
titleTemplate: (titleChunk: string | undefined): string | null => {
return titleChunk ? `${titleChunk} - website-vue` : 'website-vue';
return titleChunk ? `${titleChunk} - Rick van Vonderen` : 'Rick van Vonderen';
}
})
-8
View File
@@ -8,25 +8,17 @@ export {}
/* prettier-ignore */
declare module 'vue' {
export interface GlobalComponents {
IBi0Circle: typeof import('~icons/bi/0-circle')['default']
IBiActivity: typeof import('~icons/bi/activity')['default']
IFaAdjust: typeof import('~icons/fa/adjust')['default']
IFaAngellist: typeof import('~icons/fa/angellist')['default']
IFaCheck: typeof import('~icons/fa/check')['default']
IFaClone: typeof import('~icons/fa/clone')['default']
IFaCoffee: typeof import('~icons/fa/coffee')['default']
IFaCope: typeof import('~icons/fa/cope')['default']
IFaCopy: typeof import('~icons/fa/copy')['default']
IFaGithub: typeof import('~icons/fa/github')['default']
IFaGitlab: typeof import('~icons/fa/gitlab')['default']
IFaHome: typeof import('~icons/fa/home')['default']
IFaImage: typeof import('~icons/fa/image')['default']
IFaLink: typeof import('~icons/fa/link')['default']
IFaLinkedinSquare: typeof import('~icons/fa/linkedin-square')['default']
IFaMoonO: typeof import('~icons/fa/moon-o')['default']
IFaSolidMoon: typeof import('~icons/fa-solid/moon')['default']
IFaSolidSun: typeof import('~icons/fa-solid/sun')['default']
IMdiAccountBox: typeof import('~icons/mdi/account-box')['default']
RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView']
}
+3 -3
View File
@@ -2,10 +2,10 @@
<h2>CV</h2>
<p>
Download the PDF here:
<a href="https://riyyi.com/media/cv-en-rick-van-vonderen.pdf">English</a>,&nbsp;
<a href="https://riyyi.com/media/cv-rick-van-vonderen.pdf">Nederlands</a>
<a :href="getPublicPath('/pdf/cv-en-rick-van-vonderen.pdf')" target="_blank">English</a>,&nbsp;
<a :href="getPublicPath('/pdf/cv-rick-van-vonderen.pdf')" target="_blank">Nederlands</a>
</p>
<object data="https://riyyi.com/media/cv-en-rick-van-vonderen.pdf" type="application/pdf"
<object :data="getPublicPath('/pdf/cv-en-rick-van-vonderen.pdf')" type="application/pdf"
style="width: 100%; height: calc(100vh - 280px)"></object>
</template>
+1 -4
View File
@@ -69,8 +69,5 @@ const { data: article } = await useAsyncData<ContentCollectionItem | null>(
() => queryCollection("content").path("/articles/" + params.slug).first()
);
useSeoMeta({
title: article.value?.title,
description: article.value?.description
})
useSeoMeta(article.value?.seo || {});
</script>