Add examples and move tests to the tests/ folder
This commit is contained in:
@@ -9,8 +9,8 @@ all: wl
|
|||||||
wl: wl.c wl.h main.c
|
wl: wl.c wl.h main.c
|
||||||
gcc main.c wl.c -o wl -g3 -O0
|
gcc main.c wl.c -o wl -g3 -O0
|
||||||
|
|
||||||
test: wl.c wl.h test.c
|
test: wl.c wl.h tests/test.c
|
||||||
gcc test.c wl.c -o test -g3 -O0
|
gcc tests/test.c wl.c -o test -g3 -O0
|
||||||
|
|
||||||
coverage:
|
coverage:
|
||||||
gcc main.c wl.c -o wl_cov -g3 -O0 --coverage -fprofile-arcs -ftest-coverage
|
gcc main.c wl.c -o wl_cov -g3 -O0 --coverage -fprofile-arcs -ftest-coverage
|
||||||
@@ -22,8 +22,8 @@ coverage_report:
|
|||||||
lcov --remove coverage.info '/usr/*' --output-file coverage_filtered.info
|
lcov --remove coverage.info '/usr/*' --output-file coverage_filtered.info
|
||||||
genhtml coverage_filtered.info --output-directory coverage_html --title "WL Template Engine Coverage"
|
genhtml coverage_filtered.info --output-directory coverage_html --title "WL Template Engine Coverage"
|
||||||
|
|
||||||
fuzz: fuzz.c wl.c wl.h
|
fuzz: tests/fuzz.c wl.c wl.h
|
||||||
$(AFL_CC) fuzz.c wl.c -o fuzz \
|
$(AFL_CC) tests/fuzz.c wl.c -o fuzz \
|
||||||
-g -O3 -Wall \
|
-g -O3 -Wall \
|
||||||
-fsanitize=address,undefined \
|
-fsanitize=address,undefined \
|
||||||
-fno-omit-frame-pointer
|
-fno-omit-frame-pointer
|
||||||
|
|||||||
@@ -1,2 +1,4 @@
|
|||||||
* Don't allow [] selections to go over newlines
|
* Don't allow [] selections to go over newlines
|
||||||
* Make sure maps and arrays can be keys of a map
|
* Make sure maps and arrays can't be keys of a map
|
||||||
|
* Decide and document how comments work
|
||||||
|
* Improve the formatting of the output
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
let items = ['Apple', 'Orange', 'Strawberry']
|
||||||
|
|
||||||
|
let list =
|
||||||
|
<ul>
|
||||||
|
\for item in items:
|
||||||
|
<li>\{escape item}</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Fruit List</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
My list:
|
||||||
|
\{list}
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
|
||||||
|
procedure my_page_template(title, content) {
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>\{escape title}</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
\{content}
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
}
|
||||||
|
|
||||||
|
my_page_template("Welcome to my webpage!", <article>Content of my page</article>)
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
|
||||||
|
let comments = [
|
||||||
|
{
|
||||||
|
'content': 'Cool post!',
|
||||||
|
'children': [
|
||||||
|
{
|
||||||
|
'content': 'True!',
|
||||||
|
'children': []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'content': 'I don\'t agree with the second section..',
|
||||||
|
'children': [
|
||||||
|
{
|
||||||
|
'content': 'You\'re wrong!',
|
||||||
|
'children': [
|
||||||
|
{
|
||||||
|
'content': 'No, YOU are wrong!',
|
||||||
|
'children' : []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
procedure render_comment_subtree(comment) {
|
||||||
|
<div class="comment">
|
||||||
|
<p>\{escape comment.content}</p>
|
||||||
|
<div class="comment-children">
|
||||||
|
\for child in comment.children:
|
||||||
|
render_comment_subtree(child)
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<style>
|
||||||
|
.comment {
|
||||||
|
border-left: 2px solid #ccc;
|
||||||
|
padding-left: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<article>
|
||||||
|
|
||||||
|
<h1>A Very Cool Post</h1>
|
||||||
|
|
||||||
|
<h2>Section 1</h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
This language is cool
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2>Section 2</h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
You should try it out
|
||||||
|
</p>
|
||||||
|
|
||||||
|
</article>
|
||||||
|
|
||||||
|
<div id="comments">
|
||||||
|
\for comment in comments:
|
||||||
|
render_comment_subtree(comment)
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
|
|
||||||
procedure page(title, lang)
|
|
||||||
<html lang="\{lang}">
|
|
||||||
\{title}
|
|
||||||
</html>
|
|
||||||
|
|
||||||
page("Hello, world!", "it")
|
|
||||||
+13
-13
@@ -2,7 +2,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include "wl.h"
|
#include "../wl.h"
|
||||||
|
|
||||||
#define MAX_INPUT_SIZE (64 * 1024) // 64KB max input
|
#define MAX_INPUT_SIZE (64 * 1024) // 64KB max input
|
||||||
#define ARENA_SIZE (1 << 20) // 1MB arena
|
#define ARENA_SIZE (1 << 20) // 1MB arena
|
||||||
@@ -29,33 +29,33 @@ int main(int argc, char **argv)
|
|||||||
// AFL persistent mode: loop up to 1000 times per process
|
// AFL persistent mode: loop up to 1000 times per process
|
||||||
while (__AFL_LOOP(1000)) {
|
while (__AFL_LOOP(1000)) {
|
||||||
int len = __AFL_FUZZ_TESTCASE_LEN;
|
int len = __AFL_FUZZ_TESTCASE_LEN;
|
||||||
|
|
||||||
// Limit input size
|
// Limit input size
|
||||||
if (len > MAX_INPUT_SIZE) {
|
if (len > MAX_INPUT_SIZE) {
|
||||||
len = MAX_INPUT_SIZE;
|
len = MAX_INPUT_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset arena for each iteration
|
// Reset arena for each iteration
|
||||||
WL_Arena arena = { mem, ARENA_SIZE, 0 };
|
WL_Arena arena = { mem, ARENA_SIZE, 0 };
|
||||||
|
|
||||||
// Initialize compiler
|
// Initialize compiler
|
||||||
WL_Compiler *c = wl_compiler_init(&arena);
|
WL_Compiler *c = wl_compiler_init(&arena);
|
||||||
if (c == NULL) {
|
if (c == NULL) {
|
||||||
continue; // Out of memory, skip this input
|
continue; // Out of memory, skip this input
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to compile the input
|
// Try to compile the input
|
||||||
WL_AddResult res = wl_compiler_add(
|
WL_AddResult res = wl_compiler_add(
|
||||||
c,
|
c,
|
||||||
(WL_String) { "", 0 }, // empty path
|
(WL_String) { "", 0 }, // empty path
|
||||||
(WL_String) { (char*)buf, len }
|
(WL_String) { (char*)buf, len }
|
||||||
);
|
);
|
||||||
|
|
||||||
// If compilation succeeded, try to link
|
// If compilation succeeded, try to link
|
||||||
if (res.type == WL_ADD_LINK) {
|
if (res.type == WL_ADD_LINK) {
|
||||||
WL_Program program;
|
WL_Program program;
|
||||||
int ret = wl_compiler_link(c, &program);
|
int ret = wl_compiler_link(c, &program);
|
||||||
|
|
||||||
// If linking succeeded, optionally execute (for deeper fuzzing)
|
// If linking succeeded, optionally execute (for deeper fuzzing)
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
WL_Runtime *rt = wl_runtime_init(&arena, program);
|
WL_Runtime *rt = wl_runtime_init(&arena, program);
|
||||||
@@ -63,12 +63,12 @@ int main(int argc, char **argv)
|
|||||||
// Execute up to 1000 steps to avoid infinite loops
|
// Execute up to 1000 steps to avoid infinite loops
|
||||||
for (int i = 0; i < 1000; i++) {
|
for (int i = 0; i < 1000; i++) {
|
||||||
WL_EvalResult eval_res = wl_runtime_eval(rt);
|
WL_EvalResult eval_res = wl_runtime_eval(rt);
|
||||||
|
|
||||||
if (eval_res.type == WL_EVAL_DONE ||
|
if (eval_res.type == WL_EVAL_DONE ||
|
||||||
eval_res.type == WL_EVAL_ERROR) {
|
eval_res.type == WL_EVAL_ERROR) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle syscalls/sysvars by pushing dummy values
|
// Handle syscalls/sysvars by pushing dummy values
|
||||||
if (eval_res.type == WL_EVAL_SYSVAR) {
|
if (eval_res.type == WL_EVAL_SYSVAR) {
|
||||||
wl_push_s64(rt, 42);
|
wl_push_s64(rt, 42);
|
||||||
@@ -79,10 +79,10 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Arena is automatically reset on next iteration
|
// Arena is automatically reset on next iteration
|
||||||
}
|
}
|
||||||
|
|
||||||
free(mem);
|
free(mem);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user