From 012b7b1d25d1c52d7db7dfd71b1042f132579a17 Mon Sep 17 00:00:00 2001
From: Francesco Cozzuto
Date: Tue, 14 Oct 2025 11:23:51 +0200
Subject: [PATCH] Make include paths relative to their file and update README
---
README.md | 271 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
main.c | 2 +-
test.c | 13 +--
3 files changed, 266 insertions(+), 20 deletions(-)
diff --git a/README.md b/README.md
index d5de21d..628c8cb 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,265 @@
# WL
-WL is an HTML templating engine written in and for C.
+WL is a powerful and flexible, yet experimental scripting language for templating with first-class support for HTML.
-It supports:
-1. Zero dependencies
-2. Single-file implementation
-3. HTML-first design
-4. Complete scripting language
-5. Easy integration
-6. Performs no I/O or dynamic allocations
\ No newline at end of file
+## Features
+1. *Zero dependencies* - It only uses pure C and the standard library
+2. *Single-file implementation* - Everything is inside `wl.c` and `wl.h`
+3. *HTML-first design* - Native HTML syntax with embedded scripting
+4. *Complete scripting language* - Variables, functions, loops, conditional branches, arrays, maps. We've got it all!
+5. Built-in XSS protection - `escape()` function to sanitize dynamic HTML
+6. *No I/O or dynamic allocations* - Any I/O or memory management is left to the user
+7. *Include system* - Modular template composition over multiple files
+
+## Language
+
+WL is designed to be extremely powerful and flexible, but realistically you will use a small number of features most of the time. For instance, I expect most templates to look something like this:
+
+```
+let title = "Title of my webpage"
+let items = ["A", "B", "C"]
+
+let navigator =
+
+
+
+ \title
+
+
+ \navigator
+ \for item in items:
+ item
+
+
+```
+
+But really, WL is a full fledged scripting languages, so let's start from the beginning...
+
+### Expressions
+
+WL supports integer, floats, booleans, strings, arrays, and maps values
+
+```
+100
+4.5
+true
+false
+"Hello, world!"
+[1, 2, 3]
++{'name': 'Francesco', 'greeting': 'sup'}
+```
+
+Evaluating expressions in the global scope will automatically write them to output. One thing you may not expect is that when arrays are printed out, their contents are just concatenated and printed out. This is useful for doing lazy string manipulation. Map on the other hand, are not considered as printable objects and will only output `
+```
+
+Since HTML literals are just expressions, you can also assign them to variables:
+
+```
+let links = {
+ "home": "home.html",
+ "about": "about.html",
+ "contacts": "contacts.html"
+}
+let navigator =
+
+```
+
+### File inclusion
+
+You can include files using the `include` keyword.
+
+Say you have a file `file_A.wl` containing some symbol definitions or outputs:
+
+```
+let myvar = 100
+
+"Some output here"
+```
+
+You can import the symbols and generate the output from another file by including the first one
+
+```
+include "file_A.wl"
+
+"myvar is accessible here: "
+myvar
+```
\ No newline at end of file
diff --git a/main.c b/main.c
index ca1fbf6..fccfb3f 100644
--- a/main.c
+++ b/main.c
@@ -96,7 +96,7 @@ int main(int argc, char **argv)
*file_tail = file;
file_tail = &file->next;
- WL_AddResult res = wl_compiler_add(c, (WL_String) { file->data, file->size });
+ WL_AddResult res = wl_compiler_add(c, path, (WL_String) { file->data, file->size });
if (res.type == WL_ADD_ERROR) {
fprintf(stderr, "Error: %s\n", wl_compiler_error(c).ptr);
return -1;
diff --git a/test.c b/test.c
index 420fd66..4357dde 100644
--- a/test.c
+++ b/test.c
@@ -138,7 +138,7 @@ int run_test(char *in, char *out, void *mem, int cap, int test_line)
return -1;
}
- WL_AddResult res = wl_compiler_add(c, (WL_String) { in, strlen(in) });
+ WL_AddResult res = wl_compiler_add(c, (WL_String) { NULL, 0 }, (WL_String) { in, strlen(in) });
if (res.type == WL_ADD_ERROR) {
fprintf(stderr, "Error: %s\n", wl_compiler_error(c).ptr);
return -1;
@@ -205,16 +205,7 @@ int run_test(char *in, char *out, void *mem, int cap, int test_line)
fprintf(stderr, " Expected: [%s]\n", out);
#if 1
fprintf(stderr, " Program:\n");
- char buf[1<<10];
- int len = wl_dump_program(program, buf, sizeof(buf));
- if (len < 0)
- fprintf(stderr, " (Invalid program)\n");
- else if (len >= sizeof(buf)) {
- fprintf(stderr, " (Program disassembly is too big)\n");
- } else {
- buf[len] = '\0';
- fprintf(stderr, "%s", buf);
- }
+ wl_dump_program(program);
#endif
return 0;
}