Early work on an Include block.

This commit is contained in:
Joshua Bemenderfer 2023-02-22 21:58:54 -05:00
parent 3b7077e761
commit 31bb42e985
16 changed files with 1097 additions and 1015 deletions

1
docs/.eleventyignore Normal file
View File

@ -0,0 +1 @@
/**/*.inc.tce

View File

@ -0,0 +1,7 @@
{% from "./Node.njk" import Node %}
{% macro render(node, page) %}
{% for child in node.children %}
{{ Node(child.type, child, page) }}
{% endfor %}
{% endmacro %}

View File

@ -1,435 +0,0 @@
layout layout.njk
title C Documentation - Terrace
description
C language documentation for the Terrace programming language
Section light
class flex flex-col md:flex-row gap-16
Block
class w-full lg:w-1/3
TableOfContents
Block
Heading 1 Terrace C Documentation
class -ml-2
Markdown
Documentation is available for the following languages:
- [C](/docs/c/) - 75% Complete
- [JavaScript](/docs/javascript/) - 75% Complete
- [Python](/docs/python/) - 0% Complete
Heading 2 Getting Started
class mt-12 mb-6
Markdown
The terrace parser is distributed as a set of C header files.<br/>
To use it, download and include the following files in your project tree:
- [parser.h](https://git.thederf.com/thederf/Terrace/src/branch/main/packages/c/parser.h) - Core terrace parser
- [document.h](https://git.thederf.com/thederf/Terrace/src/branch/main/packages/c/document.h) - (optional) Convenience functions for parsing of documents
A simple example program using to read each line from stdin and output parser information, looking for a "title" key:
CodeBlock c
// Provides getline() for reading from stdin
#include <stdio.h>
// Provides free() for deallocating the lines from getline()
#include <stdlib.h>
// Provides document API for interacting with Terrace files
#include "document.h"
// Custom userData struct. Stores information needed
// by read_line below.
typedef struct read_line_container_s {
size_t bufsize;
} read_line_container_t;
// A user-supplied function to read lines from stdin (or whichever data source you choose)
int read_line_from_stdin(char** line, void* userData) {
read_line_container_t* lineContainer = (read_line_container_t*) userData;
// Uses getline from the C stdlib to read the next line from stdin.
int num_chars_read = getline(line, &lineContainer->bufsize, stdin);
// Change trailing newline to null char. Terrace doesn't use trailing newlines
if (num_chars_read > 0) (*line)[num_chars_read - 1] = '\0';
// Return the number of charaters read to the document parser.
return num_chars_read;
}
int main(int argc, char *argv[]) {
read_line_container_t read_line_information = { .bufsize = 64 };
// Initialize the terrace document with the line reader function created above.
terrace_document_t doc = terrace_create_document(' ', &read_line_from_stdin, &read_line_information);
// Loop over every line in the document.
while(terrace_next(&doc, -1)) {
// > Replace with your custom line handling code.
// Print the line and level to demonstrate the terrace_level and terrace_line functions.
printf("| level %u | line %s |", terrace_level(&doc), terrace_line(&doc, -1));
// If one of the lines starts with "title", output it.
if (terrace_match(&doc, "title")) {
printf("Title: %s |", terrace_tail(&doc));
}
};
// Free allocated line memory
free(line);
return 0;
}
Markdown
Heading 2 Core API
class mt-12
Markdown
**Note:** The Core API is designed for maximum portability and is not intended to be directly consumed.
For most projects you'll want to use the [Document API](#document-api) instead.
It provides an ergonomic wrapper around the Core API and lets you focus on parsing
your documents.
Heading 3 terrace_linedata_t
class mb-4 mt-12
Markdown
This struct holds information about each line as it is parsed. Mutated each time [terrace_parse_line()](#terrace-parse-line) is called. Not intended to be used directly.
Use the relevant `terrace_` functions from the [Document API](#document-api) instead.
CodeBlock c
// Holds the parsed information from each line.
typedef struct terrace_linedata_s {
// Which character is being used for indentation. Avoids having to specify it on each terrace_parse_line call.
char indent;
// How many indent characters are present in the current line before the first non-indent character.
unsigned int level;
// The number of characters before the start of the line's "head" section.
// (Normally the same as `level`)
unsigned int offsetHead;
// The number of characters before the start of the line's "tail" section.
unsigned int offsetTail;
} terrace_linedata_t;
Heading 3 terrace_create_linedata()
class mb-4 mt-12
Markdown
| Parameter | Type | Description
| -------------- | --------------------- | -----------------------------------------------------------------------
| indent | const char | The character used for indentation in the document. Only a single character is permitted.
| **@returns** | [terrace_linedata_t](#terrace-linedatat) | A terrace_linedata_t struct with the specified indent character and all other values initialized to 0.
Initialize a [terrace_linedata](#terrace-linedatat) struct with default values to pass to [terrace_parse_line()](#terrace-parse-line).
CodeBlock c
// Call Signature
terrace_linedata_t terrace_create_linedata(const char indent)
Heading 3 terrace_parse_line()
class mb-4 mt-12
Markdown
| Parameter | Type | Description
| -------------- | --------------------- | -----------------------------------------------------------------------
| line | char* | A pointer to the line to parse as a C-style string. Shouldn't end with a newline.
| lineData | [terrace_linedata_t](#terrace-linedatat)* | A pointer to the terrace_linedata_t struct to store information about the current line in.
Core Terrace parser function, sets `level`, `offsetHead`, and `offsetTail` in a [terrace_linedata](#terrace-linedatat) struct based on the current line.
CodeBlock c
// Call Signature
void terrace_parse_line(const char* line, terrace_linedata_t* lineData)
Heading 2 Document API
class mt-12
Heading 3 terrace_document_t
class mb-4 mt-12
Markdown
Tracks state of a document while being parsed.
Obtained from [terrace_create_document()](#terrace-create-document) below
CodeBlock c
// Type Definition
typedef struct terrace_document_s {
// == Internal State == //
unsigned int _repeatCurrentLine;
// Current line being read
char* _currentLine;
// == External Information == //
// Embedded line data struct. Holds information about the current parsed line
terrace_linedata_t lineData;
// Custom data passed to the readline function
void* userData;
/**
* Line reader function, provided by the user
* Needed to get the next line inside of `terrace_next(doc)`
* @param {char**} line First argument is a pointer to `_currentLine`, above
* @param {void*} userData Second argument is `userData`, above
* @returns {int} The number of characters read, or -1 if no characters were read.
*/
int (*reader)(char** line, void* userData);
} terrace_document_t;
Heading 3 terrace_create_document()
class mb-4 mt-12
Markdown
| Parameter | Type | Description
| -------------- | --------------------- | -----------------------------------------------------------------------
| indent | const char | The indent character to use. Generally a single space character.
| reader | int (\*reader)(char** line, void* userData) | A function pointer to a function that reads lines sequentially from a user-provided source. Receives a pointer to `lineData->_currLine`, and `userData`, supplied in the next argument.
| userData | void * | A user-supplied pointer to any state information needed by their reader function. Passed to `reader`each time it is called.
| **@returns** | [terrace_document_t](#terrace-documentt) | A state struct needed by the convenience functions below.
Initializes the state needed for the convenience functions below. Takes a user-supplied `reader` function to read each line from a user-determined source.
CodeBlock c
// Call Signature
terrace_document_t terrace_create_document(const char indent, int (*reader)(char** line, void* userData), void* userData)
Heading 3 terrace_next()
class mb-4 mt-12
Markdown
| Parameter | Type | Description
| -------------- | --------------------- | -----------------------------------------------------------------------
| doc | [terrace_document_t*](#terrace-documentt) | A pointer to the current document state struct.
| levelScope | int | If set above -1, `next()` will return `0` when it encounters a line with a level at or below `levelScope`
| **@returns** | char | Returns `1` after parsing a line, or `0` if the document has ended or a line at or below `levelScope` has been encountered.
Advances the current position in the terrace document and populates lineData
with the parsed information from that line.
Returns `1` after parsing the next line, or `0` upon reaching the end of the document.
If the `levelScope` parameter is not -1, `terrace_next()` will also return `0` when it encounters a line
with a level at or below `levelScope`. This allows you to iterate through subsections of a document.
If a lower-level line was encountered, the following call to `terrace_next()` will repeat this line again.
This allows a child loop to look forward, determine that the next line will be outside its purview,
and return control to the calling loop transparently without additional logic.
Intended to be used inside a while loop to parse a section of a Terrace document.
CodeBlock c
// Call Signature
char terrace_next(terrace_document_t* doc, int levelScope)
// Usage
while(terrace_next(doc, -1)) {
// Do something with each line.
}
Heading 3 terrace_level()
class mb-4 mt-12
Markdown
| Parameter | Type | Description
| -------------- | --------------------- | -----------------------------------------------------------------------
| doc | [terrace_document_t*](#terrace-documentt) | A pointer to the current document state struct.
| **@returns** | unsigned int | The indent level of the current line
Returns the number of indent characters of the current line.
Given the following document, `terrace_level(doc)` would return 0, 1, 2, and 5 respectively for each line.
CodeBlock terrace
block
block
block
block
CodeBlock c
// Call Signature
unsigned int terrace_level(terrace_document_t* doc)
// Usage
while(terrace_next(doc, -1)) {
printf("Indent Level: %u", terrace_level(doc));
}
Heading 3 terrace_line()
class mb-4 mt-12
Markdown
| Parameter | Type | Description
| -------------- | --------------------- | -----------------------------------------------------------------------
| doc | [terrace_document_t*](#terrace-documentt) | A pointer to the current document state struct.
| startOffset | int | How many indent characters to skip before outputting the line contents. If set to -1, uses the current indent level.
| **@returns** | char* | The line contents starting from `startOffset`
Get a string with the current line contents.
If `startOffset` is -1, skips all indent characters by default. Otherwise only skips the amount specified.
Given the following document
CodeBlock terrace
root
sub-line
Markdown
- Calling `terrace_line(doc, -1)` on the second line returns "sub-line", trimming off the leading indent characters.
- Calling `terrace_line(doc, 0)` however, returns "&nbsp;&nbsp;&nbsp;&nbsp;sub-line", with all four leading spaces.
`startOffset`s other than `-1` are primarily used for parsing blocks that have literal indented multi-line text
CodeBlock c
// Call Signature
char* terrace_line(terrace_document_t* doc, int startOffset)
// Usage
while(terrace_next(doc, -1)) {
printf("Line with indent characters: %s", terrace_line(doc, 0));
printf("Line without indent characters: %s", terrace_line(doc, -1));
}
Heading 3 terrace_head_length()
class mb-4 mt-12
Markdown
| Parameter | Type | Description
| -------------- | --------------------- | -----------------------------------------------------------------------
| doc | [terrace_document_t*](#terrace-documentt) | A pointer to the current document state struct.
| **@returns** | unsigned int | The length of the `head` portion (first word) of a line
Get the *length* of the first "word" of a line,
starting from the first non-indent character to the first space or end of the line
Often used for deciding how to parse a block.
Because C uses NULL-terminated strings, we cannot easily slice a string to return something out of the middle.
Instead, `terrace_head_length()` provides the length of the head portion.
In combination with `doc->lineData.offsetHead`, you can copy the head section into a new string,
or use any number of `strn*` C stdlib functions to work with the head section without copying it.
Terrace DSLs do not *need* to use head-tail line structure, but support for them is built into the parser
Given the following line, `terrace_head_length(doc)` returns `5`
CodeBlock terrace
title An Important Document
CodeBlock c
// Call Signature
unsigned int terrace_head_length(terrace_document_t* doc)
// Usage
while(terrace_next(doc, -1)) {
printf("Head length: %u", terrace_head_length(doc));
}
Heading 3 terrace_tail()
class mb-4 mt-12
Markdown
| Parameter | Type | Description
| -------------- | --------------------- | -----------------------------------------------------------------------
| doc | [terrace_document_t*](#terrace-documentt) | A pointer to the current document state struct.
| **@returns** | char* | The remainder of the line following the `head` portion, with no leading space.
Get a char pointer to everything following the first "word" of a line,
starting from the first character after the space at the end of `head`.
Terrace DSLs do not *need* to use head-tail line structure, but support for them is built into the parser
Given the following line, `terrace_tail(doc)` returns "An Important Document"
CodeBlock terrace
title An Important Document
CodeBlock c
// Call Signature
char* terrace_tail(terrace_document_t* doc)
// Usage
while(terrace_next(doc, -1)) {
printf("Line tail: %s", terrace_tail(doc));
}
Heading 3 terrace_match()
class mb-4 mt-12
Markdown
| Parameter | Type | Description
| -------------- | --------------------- | -----------------------------------------------------------------------
| doc | [terrace_document_t*](#terrace-documentt) | A pointer to the current document state struct.
| matchValue | const char* | A string to check against the line `head` for equality.
| **@returns** | char | A byte set to `0` if the head does not match, or `1`if it does match.
Quickly check if the current line head matches a specified value. Useful in many document-parsing situations.
Given the following line:
CodeBlock terrace
title An Important Document
Markdown
- `terrace_match(doc, "title")` returns `1`
- `terrace_match(doc, "somethingElse")` returns `0`
CodeBlock c
// Call Signature
char terrace_match(terrace_document_t* doc, const char* matchHead)
// Usage
while(terrace_next(doc, -1)) {
printf("Does the line start with 'title': %d", terrace_match(doc, "title"));
}
Heading 2 Recipes
class mt-12
Heading 3 Parse a single line
Markdown
Parses a single line into `line_data`, the prints the information from `line_data`.
CodeBlock c
#include "parser.h"
int main(int argc, char *argv[]) {
char* line = "example line";
// Create the line_data struct
terrace_linedata_t line_data;
// Set the indent character to a space
line_data.indent = ' ';
// Populates line_data level, offsetHead, and offsetTail from line
terrace_parse_line(line, &line_data);
printf(
"level %u | indent %c | offsetHead %u | offsetTail %u\n",
line_data.level,
line_data.indent,
line_data.offsetHead,
line_data.offsetTail
);
return 0;
}
Heading 3 Parse all lines from stdin
Markdown
Reads lines from stdin one-by-one and prints each line's `line_data`.
CodeBlock c
#include "parser.h"
// Depends on several cstdlib functions
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
int main(int argc, char *argv[]) {
// Pointer to start of line
char *line = NULL;
// Initial size of the buffer to read into
// getline() will resize as needed
size_t bufsize = 128;
// How many characters have been read
ssize_t chars_read = 0;
// Create the line_data struct
terrace_linedata_t line_data;
// Set the indent character to a space
line_data.indent = ' ';
while (chars_read = getline(&line, &bufsize, stdin)) {
// If chars_read is -1, we've reached end of file.
if (chars_read == -1) break;
// getline returns lines with a trailing newline
// terrace_parse_line expects no trailing newline
// strip it off using strtok()
// (An odd solution, probably leaks memory)
char *terrace_line = strtok(line, "\n");
terrace_parse_line(terrace_line, &line_data);
printf(
"level %u | indent %c | offsetHead %u | offsetTail %u\n",
line_data.level,
line_data.indent,
line_data.offsetHead,
line_data.offsetTail
);
};
// Free the buffer allocated by getline().
free(line);
}
Heading 2 Contributing
class mt-12
Section dark
Footer
class w-full

View File

@ -0,0 +1,52 @@
Heading 2 Core API
class mt-12
Markdown
**Note:** The Core API is designed for maximum portability and is not intended to be directly consumed.
For most projects you'll want to use the [Document API](#document-api) instead.
It provides an ergonomic wrapper around the Core API and lets you focus on parsing
your documents.
Heading 3 terrace_linedata_t
class mb-4 mt-12
Markdown
This struct holds information about each line as it is parsed. Mutated each time [terrace_parse_line()](#terrace-parse-line) is called. Not intended to be used directly.
Use the relevant `terrace_` functions from the [Document API](#document-api) instead.
CodeBlock c
// Holds the parsed information from each line.
typedef struct terrace_linedata_s {
// Which character is being used for indentation. Avoids having to specify it on each terrace_parse_line call.
char indent;
// How many indent characters are present in the current line before the first non-indent character.
unsigned int level;
// The number of characters before the start of the line's "head" section.
// (Normally the same as `level`)
unsigned int offsetHead;
// The number of characters before the start of the line's "tail" section.
unsigned int offsetTail;
} terrace_linedata_t;
Heading 3 terrace_create_linedata()
class mb-4 mt-12
Markdown
| Parameter | Type | Description
| -------------- | --------------------- | -----------------------------------------------------------------------
| indent | const char | The character used for indentation in the document. Only a single character is permitted.
| **@returns** | [terrace_linedata_t](#terrace-linedatat) | A terrace_linedata_t struct with the specified indent character and all other values initialized to 0.
Initialize a [terrace_linedata](#terrace-linedatat) struct with default values to pass to [terrace_parse_line()](#terrace-parse-line).
CodeBlock c
// Call Signature
terrace_linedata_t terrace_create_linedata(const char indent)
Heading 3 terrace_parse_line()
class mb-4 mt-12
Markdown
| Parameter | Type | Description
| -------------- | --------------------- | -----------------------------------------------------------------------
| line | char* | A pointer to the line to parse as a C-style string. Shouldn't end with a newline.
| lineData | [terrace_linedata_t](#terrace-linedatat)* | A pointer to the terrace_linedata_t struct to store information about the current line in.
Core Terrace parser function, sets `level`, `offsetHead`, and `offsetTail` in a [terrace_linedata](#terrace-linedatat) struct based on the current line.
CodeBlock c
// Call Signature
void terrace_parse_line(const char* line, terrace_linedata_t* lineData)

View File

@ -0,0 +1,294 @@
Heading 2 Document API
class mt-12
Heading 3 terrace_document_t
class mb-4 mt-12
Markdown
Tracks state of a document while being parsed.
Obtained from [terrace_create_document()](#terrace-create-document) below
CodeBlock c
// Type Definition
typedef struct terrace_document_s {
// == Internal State == //
unsigned int _repeatCurrentLine;
// Current line being read
char* _currentLine;
// == External Information == //
// Embedded line data struct. Holds information about the current parsed line
terrace_linedata_t lineData;
// Custom data passed to the readline function
void* userData;
/**
* Line reader function, provided by the user
* Needed to get the next line inside of `terrace_next(doc)`
* @param {char**} line First argument is a pointer to `_currentLine`, above
* @param {void*} userData Second argument is `userData`, above
* @returns {int} The number of characters read, or -1 if no characters were read.
*/
int (*reader)(char** line, void* userData);
} terrace_document_t;
Heading 3 terrace_create_document()
class mb-4 mt-12
Markdown
| Parameter | Type | Description
| -------------- | --------------------- | -----------------------------------------------------------------------
| indent | const char | The indent character to use. Generally a single space character.
| reader | int (\*reader)(char** line, void* userData) | A function pointer to a function that reads lines sequentially from a user-provided source. Receives a pointer to `lineData->_currLine`, and `userData`, supplied in the next argument.
| userData | void * | A user-supplied pointer to any state information needed by their reader function. Passed to `reader`each time it is called.
| **@returns** | [terrace_document_t](#terrace-documentt) | A state struct needed by the convenience functions below.
Initializes the state needed for the convenience functions below. Takes a user-supplied `reader` function to read each line from a user-determined source.
CodeBlock c
// Call Signature
terrace_document_t terrace_create_document(const char indent, int (*reader)(char** line, void* userData), void* userData)
Heading 3 terrace_next()
class mb-4 mt-12
Markdown
| Parameter | Type | Description
| -------------- | --------------------- | -----------------------------------------------------------------------
| doc | [terrace_document_t*](#terrace-documentt) | A pointer to the current document state struct.
| levelScope | int | If set above -1, `next()` will return `0` when it encounters a line with a level at or below `levelScope`
| **@returns** | char | Returns `1` after parsing a line, or `0` if the document has ended or a line at or below `levelScope` has been encountered.
Advances the current position in the terrace document and populates lineData
with the parsed information from that line.
Returns `1` after parsing the next line, or `0` upon reaching the end of the document.
If the `levelScope` parameter is not -1, `terrace_next()` will also return `0` when it encounters a line
with a level at or below `levelScope`. This allows you to iterate through subsections of a document.
If a lower-level line was encountered, the following call to `terrace_next()` will repeat this line again.
This allows a child loop to look forward, determine that the next line will be outside its purview,
and return control to the calling loop transparently without additional logic.
Intended to be used inside a while loop to parse a section of a Terrace document.
CodeBlock c
// Call Signature
char terrace_next(terrace_document_t* doc, int levelScope)
// Usage
while(terrace_next(doc, -1)) {
// Do something with each line.
}
Heading 3 terrace_level()
class mb-4 mt-12
Markdown
| Parameter | Type | Description
| -------------- | --------------------- | -----------------------------------------------------------------------
| doc | [terrace_document_t*](#terrace-documentt) | A pointer to the current document state struct.
| **@returns** | unsigned int | The indent level of the current line
Returns the number of indent characters of the current line.
Given the following document, `terrace_level(doc)` would return 0, 1, 2, and 5 respectively for each line.
CodeBlock terrace
block
block
block
block
CodeBlock c
// Call Signature
unsigned int terrace_level(terrace_document_t* doc)
// Usage
while(terrace_next(doc, -1)) {
printf("Indent Level: %u", terrace_level(doc));
}
Heading 3 terrace_line()
class mb-4 mt-12
Markdown
| Parameter | Type | Description
| -------------- | --------------------- | -----------------------------------------------------------------------
| doc | [terrace_document_t*](#terrace-documentt) | A pointer to the current document state struct.
| startOffset | int | How many indent characters to skip before outputting the line contents. If set to -1, uses the current indent level.
| **@returns** | char* | The line contents starting from `startOffset`
Get a string with the current line contents.
If `startOffset` is -1, skips all indent characters by default. Otherwise only skips the amount specified.
Given the following document
CodeBlock terrace
root
sub-line
Markdown
- Calling `terrace_line(doc, -1)` on the second line returns "sub-line", trimming off the leading indent characters.
- Calling `terrace_line(doc, 0)` however, returns "&nbsp;&nbsp;&nbsp;&nbsp;sub-line", with all four leading spaces.
`startOffset`s other than `-1` are primarily used for parsing blocks that have literal indented multi-line text
CodeBlock c
// Call Signature
char* terrace_line(terrace_document_t* doc, int startOffset)
// Usage
while(terrace_next(doc, -1)) {
printf("Line with indent characters: %s", terrace_line(doc, 0));
printf("Line without indent characters: %s", terrace_line(doc, -1));
}
Heading 3 terrace_head_length()
class mb-4 mt-12
Markdown
| Parameter | Type | Description
| -------------- | --------------------- | -----------------------------------------------------------------------
| doc | [terrace_document_t*](#terrace-documentt) | A pointer to the current document state struct.
| **@returns** | unsigned int | The length of the `head` portion (first word) of a line
Get the *length* of the first "word" of a line,
starting from the first non-indent character to the first space or end of the line
Often used for deciding how to parse a block.
Because C uses NULL-terminated strings, we cannot easily slice a string to return something out of the middle.
Instead, `terrace_head_length()` provides the length of the head portion.
In combination with `doc->lineData.offsetHead`, you can copy the head section into a new string,
or use any number of `strn*` C stdlib functions to work with the head section without copying it.
Terrace DSLs do not *need* to use head-tail line structure, but support for them is built into the parser
Given the following line, `terrace_head_length(doc)` returns `5`
CodeBlock terrace
title An Important Document
CodeBlock c
// Call Signature
unsigned int terrace_head_length(terrace_document_t* doc)
// Usage
while(terrace_next(doc, -1)) {
printf("Head length: %u", terrace_head_length(doc));
}
Heading 3 terrace_tail()
class mb-4 mt-12
Markdown
| Parameter | Type | Description
| -------------- | --------------------- | -----------------------------------------------------------------------
| doc | [terrace_document_t*](#terrace-documentt) | A pointer to the current document state struct.
| **@returns** | char* | The remainder of the line following the `head` portion, with no leading space.
Get a char pointer to everything following the first "word" of a line,
starting from the first character after the space at the end of `head`.
Terrace DSLs do not *need* to use head-tail line structure, but support for them is built into the parser
Given the following line, `terrace_tail(doc)` returns "An Important Document"
CodeBlock terrace
title An Important Document
CodeBlock c
// Call Signature
char* terrace_tail(terrace_document_t* doc)
// Usage
while(terrace_next(doc, -1)) {
printf("Line tail: %s", terrace_tail(doc));
}
Heading 3 terrace_match()
class mb-4 mt-12
Markdown
| Parameter | Type | Description
| -------------- | --------------------- | -----------------------------------------------------------------------
| doc | [terrace_document_t*](#terrace-documentt) | A pointer to the current document state struct.
| matchValue | const char* | A string to check against the line `head` for equality.
| **@returns** | char | A byte set to `0` if the head does not match, or `1`if it does match.
Quickly check if the current line head matches a specified value. Useful in many document-parsing situations.
Given the following line:
CodeBlock terrace
title An Important Document
Markdown
- `terrace_match(doc, "title")` returns `1`
- `terrace_match(doc, "somethingElse")` returns `0`
CodeBlock c
// Call Signature
char terrace_match(terrace_document_t* doc, const char* matchHead)
// Usage
while(terrace_next(doc, -1)) {
printf("Does the line start with 'title': %d", terrace_match(doc, "title"));
}
Heading 2 Recipes
class mt-12
Heading 3 Parse a single line
Markdown
Parses a single line into `line_data`, the prints the information from `line_data`.
CodeBlock c
#include "parser.h"
int main(int argc, char *argv[]) {
char* line = "example line";
// Create the line_data struct
terrace_linedata_t line_data;
// Set the indent character to a space
line_data.indent = ' ';
// Populates line_data level, offsetHead, and offsetTail from line
terrace_parse_line(line, &line_data);
printf(
"level %u | indent %c | offsetHead %u | offsetTail %u\n",
line_data.level,
line_data.indent,
line_data.offsetHead,
line_data.offsetTail
);
return 0;
}
Heading 3 Parse all lines from stdin
Markdown
Reads lines from stdin one-by-one and prints each line's `line_data`.
CodeBlock c
#include "parser.h"
// Depends on several cstdlib functions
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
int main(int argc, char *argv[]) {
// Pointer to start of line
char *line = NULL;
// Initial size of the buffer to read into
// getline() will resize as needed
size_t bufsize = 128;
// How many characters have been read
ssize_t chars_read = 0;
// Create the line_data struct
terrace_linedata_t line_data;
// Set the indent character to a space
line_data.indent = ' ';
while (chars_read = getline(&line, &bufsize, stdin)) {
// If chars_read is -1, we've reached end of file.
if (chars_read == -1) break;
// getline returns lines with a trailing newline
// terrace_parse_line expects no trailing newline
// strip it off using strtok()
// (An odd solution, probably leaks memory)
char *terrace_line = strtok(line, "\n");
terrace_parse_line(terrace_line, &line_data);
printf(
"level %u | indent %c | offsetHead %u | offsetTail %u\n",
line_data.level,
line_data.indent,
line_data.offsetHead,
line_data.offsetTail
);
};
// Free the buffer allocated by getline().
free(line);
}

88
docs/src/docs/c/index.tce Normal file
View File

@ -0,0 +1,88 @@
layout layout.njk
title C Documentation - Terrace
description
C language documentation for the Terrace programming language
Section light
class flex flex-col md:flex-row gap-16
Block
class w-full lg:w-1/3
TableOfContents
Block
Heading 1 Terrace C Documentation
class -ml-2
Markdown
Documentation is available for the following languages:
- [C](/docs/c/) - 75% Complete
- [JavaScript](/docs/javascript/) - 75% Complete
- [Python](/docs/python/) - 0% Complete
Heading 2 Getting Started
class mt-12 mb-6
Markdown
The terrace parser is distributed as a set of C header files.<br/>
To use it, download and include the following files in your project tree:
- [parser.h](https://git.thederf.com/thederf/Terrace/src/branch/main/packages/c/parser.h) - Core terrace parser
- [document.h](https://git.thederf.com/thederf/Terrace/src/branch/main/packages/c/document.h) - (optional) Convenience functions for parsing of documents
A simple example program using to read each line from stdin and output parser information, looking for a "title" key:
CodeBlock c
// Provides getline() for reading from stdin
#include <stdio.h>
// Provides free() for deallocating the lines from getline()
#include <stdlib.h>
// Provides document API for interacting with Terrace files
#include "document.h"
// Custom userData struct. Stores information needed
// by read_line below.
typedef struct read_line_container_s {
size_t bufsize;
} read_line_container_t;
// A user-supplied function to read lines from stdin (or whichever data source you choose)
int read_line_from_stdin(char** line, void* userData) {
read_line_container_t* lineContainer = (read_line_container_t*) userData;
// Uses getline from the C stdlib to read the next line from stdin.
int num_chars_read = getline(line, &lineContainer->bufsize, stdin);
// Change trailing newline to null char. Terrace doesn't use trailing newlines
if (num_chars_read > 0) (*line)[num_chars_read - 1] = '\0';
// Return the number of charaters read to the document parser.
return num_chars_read;
}
int main(int argc, char *argv[]) {
read_line_container_t read_line_information = { .bufsize = 64 };
// Initialize the terrace document with the line reader function created above.
terrace_document_t doc = terrace_create_document(' ', &read_line_from_stdin, &read_line_information);
// Loop over every line in the document.
while(terrace_next(&doc, -1)) {
// > Replace with your custom line handling code.
// Print the line and level to demonstrate the terrace_level and terrace_line functions.
printf("| level %u | line %s |", terrace_level(&doc), terrace_line(&doc, -1));
// If one of the lines starts with "title", output it.
if (terrace_match(&doc, "title")) {
printf("Title: %s |", terrace_tail(&doc));
}
};
// Free allocated line memory
free(line);
return 0;
}
Include ./src/docs/c/core-api.inc.tce
Include ./src/docs/c/document-api.inc.tce
Heading 2 Contributing
class mt-12
Section dark
Footer
class w-full

View File

@ -1,579 +0,0 @@
layout layout.njk
title JavaScript Documentation - Terrace
description
JavaScript language documentation for the Terrace programming language
Section light
class flex flex-col md:flex-row gap-16
Block
class w-full lg:w-1/3
TableOfContents
Block
Heading 1 Terrace JavaScript Documentation
class -ml-2
Markdown
Documentation is available for the following languages:
- [C](/docs/c/) - 75% Complete
- [JavaScript](/docs/javascript/) - 75% Complete
- [Python](/docs/python/) - 0% Complete
Heading 2 Getting Started
class mt-12 mb-6
Markdown
Install Terrace using [NPM](https://www.npmjs.com/):
CodeBlock bash
# NPM (https://npmjs.com)
$ npm install @terrace-lang/js
# PNPM (https://pnpm.io/)
$ pnpm install @terrace-lang/js
# Yarn (https://yarnpkg.com/)
$ yarn add @terrace-lang/js
Heading 2 Core API
class mt-12
Markdown
**Note:** The Core API uses C-style conventions to optimize memory management
and improve portability to other environments and languages.
It is unwieldy and does not follow JavaScript best practices.
For most projects you'll want to use the [Document API](#document-api) instead.
It provides an ergonomic wrapper around the Core API and lets you focus on parsing
your documents.
Heading 3 LineData
class mb-4 mt-12
CodeBlock typescript
// Type Definition
// Holds the parsed information from each line.
type LineData = {
// Which character is being used for indentation. Avoids having to specify it on each parseLine call.
indent: string;
// How many indent characters are present in the current line before the first non-indent character.
level: number;
// The number of characters before the start of the line's "head" section.
// (Normally the same as `level`)
offsetHead: number;
// The number of characters before the start of the line's "tail" section.
offsetTail: number;
}
Heading 3 createLineData()
class mb-4 mt-12
Markdown
| Parameter | Type | Description
| -------------- | --------------------- | -----------------------------------------------------------------------
| indent | string | The character used for indentation in the document. Only a single character is permitted.
| **@returns** | [LineData](#line-data) | A LineData instance with the specified indent character and all other values initialized to 0.
Initialize a LineData instance with default values to pass to [parseLine()](#parse-line).
CodeBlock typescript
// Type Definition
function createLineData(indent: string = ' '): LineData
// Import Path
import { createLineData } from '@terrace-lang/js/parser'
// Usage
const lineData = createLineData(' ')
console.dir(lineData)
// { indent: ' ', level: 0, offsetHead: 0, offsetTail: 0 }
// Use the same lineData object for all calls to parseLine in the same document.
Heading 3 parseLine()
class mb-4 mt-12
Markdown
| Parameter | Type | Description
| -------------- | --------------------- | -----------------------------------------------------------------------
| line | string | A string containing a line to parse. Shouldn't end with a newline.
| lineData | [LineData](#line-data) | A LineData object to store information about the current line, from [createLineData()](#create-line-data).<br/>**Mutated in-place!**
Core Terrace parser function, sets `level`, `offsetHead`, and `offsetTail` in a [LineData](#line-data) object based on the passed line.
Note that this is a C-style function, `lineData` is treated as a reference and mutated in-place.
CodeBlock typescript
// Type Definition
function parseLine(lineData: LineData): LineData
// Import Path
import { createLineData, parseLine } from '@terrace-lang/js/parser'
// Usage
const lineData = createLineData(' ')
parseLine('title Example Title', lineData)
console.dir(lineData)
// { indent: ' ', level: 0, offsetHead: 0, offsetTail: 5 }
Heading 2 Document API
class mt-12
Heading 3 useDocument()
class mb-4 mt-12
Markdown
| Parameter | Type | Description
| -------------- | --------------------- | -----------------------------------------------------------------------
| reader | [Reader](#reader) | When called, resolves to a string containing the next line in the document.
| indent | string | The character used for indentation in the document. Only a single character is permitted.
| **@returns** | [Document](#document) | A set of convenience functions for iterating through and parsing a document line by line.
Provides a simple set of convenience functions around parseLine for more ergonomic parsing of Terrace documents.
CodeBlock typescript
// Type Definition
function useDocument (reader: Reader, indent: string = ' '): Document
// Import Path
import { useDocument } from '@terrace-lang/js/document'
Heading 3 Document
class mb-4 mt-12
Markdown
Container for a handful of convenience functions for parsing documents.
Obtained from [useDocument()](#usedocument) above
CodeBlock typescript
// Type Definition
type Document = {
next: (levelScope?: number) => Promise<boolean>
level: () => number,
line: (startOffset?: number) => string,
head: () => string,
tail: () => string,
match: (matchHead: string) => boolean
}
Heading 3 Document.next()
class mb-4 mt-12
Markdown
| Parameter | Type | Description
| -------------- | --------------------- | -----------------------------------------------------------------------
| levelScope | number = -1 | If specified, `next()` will return `false` when it encounters a line with a level at or below `levelScope`
| **@returns** | Promise<boolean> | Returns `true` after parsing a line, or `false` if the document has ended or a line at or below `levelScope` has been encountered.
Advances the current position in the terrace document and populates lineData
with the parsed information from that line.
Returns `true` after parsing the next line, or `false` upon reaching the end of the document.
If the `levelScope` parameter is provided, `next()` will return `false` when it encounters a line
with a level at or below `levelScope`. This allows you to iterate through subsections of a document.
If a lower-level line was encountered, the following call to `next()` will repeat this line again.
This allows a child loop to look forward, determine that the next line will be outside its purview,
and return control to the calling loop transparently without additional logic.
Intended to be used inside a while loop to parse a section of a Terrace document.
CodeBlock typescript
// Type Definition
next: (levelScope?: number) => Promise<boolean>
// Import Path
import { useDocument } from '@terrace-lang/js/document'
// Usage
const { next } = useDocument(...)
while (await next()) {
// Do something with each line.
}
Heading 3 Document.level()
class mb-4 mt-12
Markdown
| Parameter | Type | Description
| -------------- | --------------------- | -----------------------------------------------------------------------
| **@returns** | number | The indent level of the current line
Returns the number of indent characters of the current line.
Given the following document, `level()` would return 0, 1, 2, and 5 respectively for each line.
CodeBlock terrace
block
block
block
block
CodeBlock typescript
// Type Definition
level: () => number
// Usage
import { useDocument } from '@terrace-lang/js/document'
const { level } = useDocument(...)
Heading 3 Document.line()
class mb-4 mt-12
Markdown
| Parameter | Type | Description
| -------------- | --------------------- | -----------------------------------------------------------------------
| levelScope | startOffset = [level()](#document-level) | How many indent characters to skip before outputting the line contents. Defaults to the current indent level
| **@returns** | string | The line contents starting from `startOffset`
Get a string with the current line contents. Skips all indent characters by default, but this can be configured with `startOffset`
Given the following document
CodeBlock terrace
root
sub-line
Markdown
- Calling `line()` on the second line returns "sub-line", trimming off the leading indent characters.
- Calling `line(0)` however, returns "&nbsp;&nbsp;&nbsp;&nbsp;sub-line", with all four leading spaces.
`startOffset` is primarily used for parsing blocks that have literal indented multi-line text, such as markdown.
CodeBlock typescript
// Type Definition
line: (startOffset?: number) => string
// Usage
import { useDocument } from '@terrace-lang/js/document'
const { line } = useDocument(...)
Heading 3 Document.head()
class mb-4 mt-12
Markdown
| Parameter | Type | Description
| -------------- | --------------------- | -----------------------------------------------------------------------
| **@returns** | string | The `head` portion (first word) of a line
Get the first "word" of a line, starting from the first non-indent character to the first space or end of the line.
Often used for deciding how to parse a block.
Terrace DSLs do not *need* to use head-tail line structure, but support for them is built into the parser
Given the following line, [head()](#document-head) returns "title"
CodeBlock terrace
title An Important Document
CodeBlock typescript
// Type Definition
head: () => string
// Usage
import { useDocument } from '@terrace-lang/js/document'
const { head } = useDocument(...)
Heading 3 Document.tail()
class mb-4 mt-12
Markdown
| Parameter | Type | Description
| -------------- | --------------------- | -----------------------------------------------------------------------
| **@returns** | string | The remainder of the line following the [head()](#document-head) portion, with no leading space
Get all text following the first "word" of a line, starting from the first character after the space at the end of [head()](#document-head)
Terrace DSLs do not *need* to use head-tail line structure, but support for them is built into the parser
Given the following line, [tail()](#document-tail) returns "An Important Document"
CodeBlock terrace
title An Important Document
CodeBlock typescript
// Type Definition
tail: () => string
// Usage
import { useDocument } from '@terrace-lang/js/document'
const { tail } = useDocument(...)
Heading 3 Document.match()
class mb-4 mt-12
Markdown
| Parameter | Type | Description
| -------------- | --------------------- | -----------------------------------------------------------------------
| matchValue | string | A string to check against [head()](#document-head) for equality
| **@returns** | boolean | Whether the current [head()](#document-head) matches the passed value
Quickly check if the current line head matches a specified value
Shorthand for `matchValue === head()`
Given the following line
CodeBlock terrace
title An Important Document
Markdown
- `match('title')` returns `true`
- `match('somethingElse`) returns `false`
CodeBlock typescript
// Type Definition
match: (matchValue: string) => boolean
// Usage
import { useDocument } from '@terrace-lang/js/document'
const { match } = useDocument(...)
Heading 2 Reader API
class mt-12
Markdown
The [Document API](#document-api) requires `Reader` functions to iterate through lines
in a document. A reader function simply returns a string (or a promise resolving to a string).
Each time it is called, it returns the next line from whichever source it is pulling them.
Terrace provides a few built-in readers, but you are welcome to build your own instead.
Heading 3 Reader
class mb-4 mt-12
Markdown
Any function (async included) that returns the next line in a document when called and null when the end of the document has been reached.
CodeBlock typescript
// Type Definition
type Reader = () => string|null|Promise<string|null>
Heading 3 createStringReader()
class mb-4 mt-12
Markdown
| Parameter | Type | Description
| -------------- | --------------------- | -----------------------------------------------------------------------
| source | string\|string[] | The lines to iterate over, as a multiline string or an array of line strings.
| index | number | Optional - which line to start from.
| **@returns** | [Reader](#reader) | A reader function that returns each line from the source document when called sequentially.
Get a simple [Reader](#reader) function that always returns the next line from a mutliline string or an array of line strings.
CodeBlock typescript
// Type Definition
function createStringReader(source: string|string[], index: number = 0): Reader
// Import Path
import { createStringReader } from '@terrace-lang/js/readers/js-string'
Markdown
**Usage**
CodeBlock typescript
import { createStringReader, useDocument } from '@terrace-lang/js'
// Create a string reader with two lines
const reader = createStringReader('title Example Title\n line2')
// Also permitted:
// const reader = createStringReader(['title Example Title', ' line 2'])
const { next, level, line } = useDocument(reader)
await next()
console.log(level(), line())
// 0 title Example Title
await next()
console.log(level(), line())
// 1 line 2
Heading 3 createFileReader()
class mb-4 mt-12
Markdown
| Parameter | Type | Description
| -------------- | --------------------- | -----------------------------------------------------------------------
| path | string | A path to the file to read.
| **@returns** | [Reader](#reader) | A reader function that returns each line from the file when called sequentially
**Note:** Only available in Node.js environments.<br/>
Get a [Reader](#reader) function that returns the next line from the specified file when called sequentially.
CodeBlock typescript
// Type Definition
function createFileReader(path: string): Reader
// Import Path
import { createFileReader } from '@terrace-lang/js/readers/node-readline'
Markdown
**Usage**
CodeExample
summary-class mb-[300px]
pre-class max-h-[300px]
javascript main.js
import { createFileReader, useDocument } from '@terrace-lang/js'
// Read the file ./example.tce
const { next, level, line } = useDocument(createFileReader('./example.tce'))
await next()
console.log(level(), line())
// 0 title Example Title
await next()
console.log(level(), line())
// 1 line 2
terrace example.tce
title Example Title
line 2
Heading 3 createStdinReader()
class mb-4 mt-12
Markdown
| Parameter | Type | Description
| -------------- | --------------------- | -----------------------------------------------------------------------
| **@returns** | [Reader](#reader) | A reader function that returns each line from `stdin` when called sequentially
**Note:** Only available in Node.js environments.<br/>
Get a [Reader](#reader) function that returns the next line from standard input when called sequentially. Does not block stdin to wait for input. If no input is present it returns null immediately.
CodeBlock typescript
// Type Definition
function createStdinReader(): Reader
// Import Path
import { createStdinReader } from '@terrace-lang/js/readers/node-readline'
Markdown
**Usage**
CodeExample
summary-class mb-[250px]
pre-class max-h-[250px]
javascript main.js
import { createStdinReader, useDocument } from '@terrace-lang/js'
// Read the contents of standard input
const { next, level, line } = useDocument(createStdinReader())
while(await next()) {
console.log(level(), line())
// See `shell` panel above for output
}
terrace example.tce
title Example Title
line 2
sh
# Run main.js with the contents of example.tce piped to stdin
$ cat example.tce > node ./main.js
0 title Example Title
1 line 2
Heading 3 createStreamReader()
class mb-4 mt-12
Markdown
| Parameter | Type | Description
| -------------- | --------------------- | -----------------------------------------------------------------------
| stream | NodeJS.ReadStream|fs.ReadStream | A ReadStream compatible with Node.js `readline` APIs
| **@returns** | [Reader](#reader) | A reader function that returns each line from `stdin` when called sequentially
**Note:** Only available in Node.js environments.<br/>
Get a [Reader](#reader) function that always returns the next line from a passed read stream when called sequentially.
CodeBlock typescript
// Type Definition
function createStreamReader(): Reader
// Import Path
import { createStreamReader } from '@terrace-lang/js/readers/node-readline'
Markdown
**Usage**
CodeExample
summary-class mb-[320px]
pre-class max-h-[320px]
javascript main.js
import fs from 'node:fs'
import { createStreamReader, useDocument } from '@terrace-lang/js'
// Read the file ./example.tce - equivalent to the `createFileReader` example above.
const reader = createStreamReader(fs.createReadStream('./example.tce'))
const { next, level, line } = useDocument(reader)
await next()
console.log(level(), line())
// 0 title Example Title
await next()
console.log(level(), line())
// 1 line 2
terrace example.tce
title Example Title
line 2
Heading 2 Recipes
class mt-12
Heading 3 Read object properties
class mb-2
Markdown
Read known properties from a Terrace block and write them to an object.
CodeBlock javascript
// Provides simple convenience functions over the core parser
// CommonJS: const { useDocument } = require('@terrace-lang/js/document')
import { useDocument } from '@terrace-lang/js/document'
// A helper for iterating over a string line-by-line
// CommonJS: const { createStringReader } = require('@terrace-lang/js/readers/js-string')
import { createStringReader } from '@terrace-lang/js/readers/js-string'
const input = `
object
string_property An example string
numeric_property 4
`
const output = {
string_property: null,
numeric_property: null
}
// useDocument returns convenience functions
const { next, level, head, tail, match } = useDocument(createStringReader(input))
// next() parses the next line in the document
while (await next()) {
// match('object') is equivalent to head() === 'object'
// Essentially: "If the current line starts with 'object'"
if (match('object')) {
const objectLevel = level()
// When we call next with a parent level it,
// only iterates over lines inside the parent block
while (await next(objectLevel)) {
// tail() returns the part of the current line after the first space
if (match('string_property')) output.string_property = tail()
// parseFloat() here the string tail() to a numeric float value
if (match('numeric_property')) output.numeric_property = parseFloat(tail())
}
}
}
console.dir(output)
// { string_property: 'An example string', numeric_property: 4 }
Markdown
Read *all* properties as strings from a Terrace block and write them to an object.
CodeBlock javascript
// Provides simple convenience functions over the core parser
// CommonJS: const { useDocument } = require('@terrace-lang/js/document')
import { useDocument } from '@terrace-lang/js/document'
// A helper for iterating over a string line-by-line
// CommonJS: const { createStringReader } = require('@terrace-lang/js/readers/js-string')
import { createStringReader } from '@terrace-lang/js/readers/js-string'
const input = `
object
property1 Value 1
property2 Value 2
random_property igazi3ii4quaC5OdoB5quohnah1beeNg
`
const output = {}
// useDocument returns convenience functions
const { next, level, head, tail, match } = useDocument(createStringReader(input))
// next() parses the next line in the document
while (await next()) {
// match('object') is equivalent to head() === 'object'
// Essentially: "If the current line starts with 'object'"
if (match('object')) {
const objectLevel = level()
// When we call next with a parent level,
// it only iterates over lines inside the parent block
while (await next(objectLevel)) {
// Skip empty lines
if (!line()) continue
// Add any properties to the object as strings using the
// line head() as the key and tail() as the value
output[head()] = tail()
}
}
}
console.dir(output)
// { property1: 'Value 1', property2: 'Value 2', random_property: 'igazi3ii4quaC5OdoB5quohnah1beeNg' }
Heading 2 Contributing
class mt-12
Section dark
Footer
class w-full

View File

@ -0,0 +1,74 @@
Heading 2 Core API
class mt-12
Markdown
**Note:** The Core API uses C-style conventions to optimize memory management
and improve portability to other environments and languages.
It is unwieldy and does not follow JavaScript best practices.
For most projects you'll want to use the [Document API](#document-api) instead.
It provides an ergonomic wrapper around the Core API and lets you focus on parsing
your documents.
Heading 3 LineData
class mb-4 mt-12
CodeBlock typescript
// Type Definition
// Holds the parsed information from each line.
type LineData = {
// Which character is being used for indentation. Avoids having to specify it on each parseLine call.
indent: string;
// How many indent characters are present in the current line before the first non-indent character.
level: number;
// The number of characters before the start of the line's "head" section.
// (Normally the same as `level`)
offsetHead: number;
// The number of characters before the start of the line's "tail" section.
offsetTail: number;
}
Heading 3 createLineData()
class mb-4 mt-12
Markdown
| Parameter | Type | Description
| -------------- | --------------------- | -----------------------------------------------------------------------
| indent | string | The character used for indentation in the document. Only a single character is permitted.
| **@returns** | [LineData](#line-data) | A LineData instance with the specified indent character and all other values initialized to 0.
Initialize a LineData instance with default values to pass to [parseLine()](#parse-line).
CodeBlock typescript
// Type Definition
function createLineData(indent: string = ' '): LineData
// Import Path
import { createLineData } from '@terrace-lang/js/parser'
// Usage
const lineData = createLineData(' ')
console.dir(lineData)
// { indent: ' ', level: 0, offsetHead: 0, offsetTail: 0 }
// Use the same lineData object for all calls to parseLine in the same document.
Heading 3 parseLine()
class mb-4 mt-12
Markdown
| Parameter | Type | Description
| -------------- | --------------------- | -----------------------------------------------------------------------
| line | string | A string containing a line to parse. Shouldn't end with a newline.
| lineData | [LineData](#line-data) | A LineData object to store information about the current line, from [createLineData()](#create-line-data).<br/>**Mutated in-place!**
Core Terrace parser function, sets `level`, `offsetHead`, and `offsetTail` in a [LineData](#line-data) object based on the passed line.
Note that this is a C-style function, `lineData` is treated as a reference and mutated in-place.
CodeBlock typescript
// Type Definition
function parseLine(lineData: LineData): LineData
// Import Path
import { createLineData, parseLine } from '@terrace-lang/js/parser'
// Usage
const lineData = createLineData(' ')
parseLine('title Example Title', lineData)
console.dir(lineData)
// { indent: ' ', level: 0, offsetHead: 0, offsetTail: 5 }

View File

@ -0,0 +1,193 @@
Heading 2 Document API
class mt-12
Heading 3 useDocument()
class mb-4 mt-12
Markdown
| Parameter | Type | Description
| -------------- | --------------------- | -----------------------------------------------------------------------
| reader | [Reader](#reader) | When called, resolves to a string containing the next line in the document.
| indent | string | The character used for indentation in the document. Only a single character is permitted.
| **@returns** | [Document](#document) | A set of convenience functions for iterating through and parsing a document line by line.
Provides a simple set of convenience functions around parseLine for more ergonomic parsing of Terrace documents.
CodeBlock typescript
// Type Definition
function useDocument (reader: Reader, indent: string = ' '): Document
// Import Path
import { useDocument } from '@terrace-lang/js/document'
Heading 3 Document
class mb-4 mt-12
Markdown
Container for a handful of convenience functions for parsing documents.
Obtained from [useDocument()](#usedocument) above
CodeBlock typescript
// Type Definition
type Document = {
next: (levelScope?: number) => Promise<boolean>
level: () => number,
line: (startOffset?: number) => string,
head: () => string,
tail: () => string,
match: (matchHead: string) => boolean
}
Heading 3 Document.next()
class mb-4 mt-12
Markdown
| Parameter | Type | Description
| -------------- | --------------------- | -----------------------------------------------------------------------
| levelScope | number = -1 | If specified, `next()` will return `false` when it encounters a line with a level at or below `levelScope`
| **@returns** | Promise<boolean> | Returns `true` after parsing a line, or `false` if the document has ended or a line at or below `levelScope` has been encountered.
Advances the current position in the terrace document and populates lineData
with the parsed information from that line.
Returns `true` after parsing the next line, or `false` upon reaching the end of the document.
If the `levelScope` parameter is provided, `next()` will return `false` when it encounters a line
with a level at or below `levelScope`. This allows you to iterate through subsections of a document.
If a lower-level line was encountered, the following call to `next()` will repeat this line again.
This allows a child loop to look forward, determine that the next line will be outside its purview,
and return control to the calling loop transparently without additional logic.
Intended to be used inside a while loop to parse a section of a Terrace document.
CodeBlock typescript
// Type Definition
next: (levelScope?: number) => Promise<boolean>
// Import Path
import { useDocument } from '@terrace-lang/js/document'
// Usage
const { next } = useDocument(...)
while (await next()) {
// Do something with each line.
}
Heading 3 Document.level()
class mb-4 mt-12
Markdown
| Parameter | Type | Description
| -------------- | --------------------- | -----------------------------------------------------------------------
| **@returns** | number | The indent level of the current line
Returns the number of indent characters of the current line.
Given the following document, `level()` would return 0, 1, 2, and 5 respectively for each line.
CodeBlock terrace
block
block
block
block
CodeBlock typescript
// Type Definition
level: () => number
// Usage
import { useDocument } from '@terrace-lang/js/document'
const { level } = useDocument(...)
Heading 3 Document.line()
class mb-4 mt-12
Markdown
| Parameter | Type | Description
| -------------- | --------------------- | -----------------------------------------------------------------------
| levelScope | startOffset = [level()](#document-level) | How many indent characters to skip before outputting the line contents. Defaults to the current indent level
| **@returns** | string | The line contents starting from `startOffset`
Get a string with the current line contents. Skips all indent characters by default, but this can be configured with `startOffset`
Given the following document
CodeBlock terrace
root
sub-line
Markdown
- Calling `line()` on the second line returns "sub-line", trimming off the leading indent characters.
- Calling `line(0)` however, returns "&nbsp;&nbsp;&nbsp;&nbsp;sub-line", with all four leading spaces.
`startOffset` is primarily used for parsing blocks that have literal indented multi-line text, such as markdown.
CodeBlock typescript
// Type Definition
line: (startOffset?: number) => string
// Usage
import { useDocument } from '@terrace-lang/js/document'
const { line } = useDocument(...)
Heading 3 Document.head()
class mb-4 mt-12
Markdown
| Parameter | Type | Description
| -------------- | --------------------- | -----------------------------------------------------------------------
| **@returns** | string | The `head` portion (first word) of a line
Get the first "word" of a line, starting from the first non-indent character to the first space or end of the line.
Often used for deciding how to parse a block.
Terrace DSLs do not *need* to use head-tail line structure, but support for them is built into the parser
Given the following line, [head()](#document-head) returns "title"
CodeBlock terrace
title An Important Document
CodeBlock typescript
// Type Definition
head: () => string
// Usage
import { useDocument } from '@terrace-lang/js/document'
const { head } = useDocument(...)
Heading 3 Document.tail()
class mb-4 mt-12
Markdown
| Parameter | Type | Description
| -------------- | --------------------- | -----------------------------------------------------------------------
| **@returns** | string | The remainder of the line following the [head()](#document-head) portion, with no leading space
Get all text following the first "word" of a line, starting from the first character after the space at the end of [head()](#document-head)
Terrace DSLs do not *need* to use head-tail line structure, but support for them is built into the parser
Given the following line, [tail()](#document-tail) returns "An Important Document"
CodeBlock terrace
title An Important Document
CodeBlock typescript
// Type Definition
tail: () => string
// Usage
import { useDocument } from '@terrace-lang/js/document'
const { tail } = useDocument(...)
Heading 3 Document.match()
class mb-4 mt-12
Markdown
| Parameter | Type | Description
| -------------- | --------------------- | -----------------------------------------------------------------------
| matchValue | string | A string to check against [head()](#document-head) for equality
| **@returns** | boolean | Whether the current [head()](#document-head) matches the passed value
Quickly check if the current line head matches a specified value
Shorthand for `matchValue === head()`
Given the following line
CodeBlock terrace
title An Important Document
Markdown
- `match('title')` returns `true`
- `match('somethingElse`) returns `false`
CodeBlock typescript
// Type Definition
match: (matchValue: string) => boolean
// Usage
import { useDocument } from '@terrace-lang/js/document'
const { match } = useDocument(...)

View File

@ -0,0 +1,48 @@
layout layout.njk
title JavaScript Documentation - Terrace
description
JavaScript language documentation for the Terrace programming language
Section light
class flex flex-col md:flex-row gap-16
Block
class w-full lg:w-1/3
TableOfContents
Block
Heading 1 Terrace JavaScript Documentation
class -ml-2
Markdown
Documentation is available for the following languages:
- [C](/docs/c/) - 75% Complete
- [JavaScript](/docs/javascript/) - 75% Complete
- [Python](/docs/python/) - 0% Complete
Heading 2 Getting Started
class mt-12 mb-6
Markdown
Install Terrace using [NPM](https://www.npmjs.com/):
CodeBlock bash
# NPM (https://npmjs.com)
$ npm install @terrace-lang/js
# PNPM (https://pnpm.io/)
$ pnpm install @terrace-lang/js
# Yarn (https://yarnpkg.com/)
$ yarn add @terrace-lang/js
Include ./src/docs/javascript/core-api.inc.tce
Include ./src/docs/javascript/document-api.inc.tce
Include ./src/docs/javascript/reader-api.inc.tce
Include ./src/docs/javascript/recipes.inc.tce
Heading 2 Contributing
class mt-12
Section dark
Footer
class w-full

View File

@ -0,0 +1,173 @@
Heading 2 Reader API
class mt-12
Markdown
The [Document API](#document-api) requires `Reader` functions to iterate through lines
in a document. A reader function simply returns a string (or a promise resolving to a string).
Each time it is called, it returns the next line from whichever source it is pulling them.
Terrace provides a few built-in readers, but you are welcome to build your own instead.
Heading 3 Reader
class mb-4 mt-12
Markdown
Any function (async included) that returns the next line in a document when called and null when the end of the document has been reached.
CodeBlock typescript
// Type Definition
type Reader = () => string|null|Promise<string|null>
Heading 3 createStringReader()
class mb-4 mt-12
Markdown
| Parameter | Type | Description
| -------------- | --------------------- | -----------------------------------------------------------------------
| source | string\|string[] | The lines to iterate over, as a multiline string or an array of line strings.
| index | number | Optional - which line to start from.
| **@returns** | [Reader](#reader) | A reader function that returns each line from the source document when called sequentially.
Get a simple [Reader](#reader) function that always returns the next line from a mutliline string or an array of line strings.
CodeBlock typescript
// Type Definition
function createStringReader(source: string|string[], index: number = 0): Reader
// Import Path
import { createStringReader } from '@terrace-lang/js/readers/js-string'
Markdown
**Usage**
CodeBlock typescript
import { createStringReader, useDocument } from '@terrace-lang/js'
// Create a string reader with two lines
const reader = createStringReader('title Example Title\n line2')
// Also permitted:
// const reader = createStringReader(['title Example Title', ' line 2'])
const { next, level, line } = useDocument(reader)
await next()
console.log(level(), line())
// 0 title Example Title
await next()
console.log(level(), line())
// 1 line 2
Heading 3 createFileReader()
class mb-4 mt-12
Markdown
| Parameter | Type | Description
| -------------- | --------------------- | -----------------------------------------------------------------------
| path | string | A path to the file to read.
| **@returns** | [Reader](#reader) | A reader function that returns each line from the file when called sequentially
**Note:** Only available in Node.js environments.<br/>
Get a [Reader](#reader) function that returns the next line from the specified file when called sequentially.
CodeBlock typescript
// Type Definition
function createFileReader(path: string): Reader
// Import Path
import { createFileReader } from '@terrace-lang/js/readers/node-readline'
Markdown
**Usage**
CodeExample
summary-class mb-[300px]
pre-class max-h-[300px]
javascript main.js
import { createFileReader, useDocument } from '@terrace-lang/js'
// Read the file ./example.tce
const { next, level, line } = useDocument(createFileReader('./example.tce'))
await next()
console.log(level(), line())
// 0 title Example Title
await next()
console.log(level(), line())
// 1 line 2
terrace example.tce
title Example Title
line 2
Heading 3 createStdinReader()
class mb-4 mt-12
Markdown
| Parameter | Type | Description
| -------------- | --------------------- | -----------------------------------------------------------------------
| **@returns** | [Reader](#reader) | A reader function that returns each line from `stdin` when called sequentially
**Note:** Only available in Node.js environments.<br/>
Get a [Reader](#reader) function that returns the next line from standard input when called sequentially. Does not block stdin to wait for input. If no input is present it returns null immediately.
CodeBlock typescript
// Type Definition
function createStdinReader(): Reader
// Import Path
import { createStdinReader } from '@terrace-lang/js/readers/node-readline'
Markdown
**Usage**
CodeExample
summary-class mb-[250px]
pre-class max-h-[250px]
javascript main.js
import { createStdinReader, useDocument } from '@terrace-lang/js'
// Read the contents of standard input
const { next, level, line } = useDocument(createStdinReader())
while(await next()) {
console.log(level(), line())
// See `shell` panel above for output
}
terrace example.tce
title Example Title
line 2
sh
# Run main.js with the contents of example.tce piped to stdin
$ cat example.tce > node ./main.js
0 title Example Title
1 line 2
Heading 3 createStreamReader()
class mb-4 mt-12
Markdown
| Parameter | Type | Description
| -------------- | --------------------- | -----------------------------------------------------------------------
| stream | NodeJS.ReadStream|fs.ReadStream | A ReadStream compatible with Node.js `readline` APIs
| **@returns** | [Reader](#reader) | A reader function that returns each line from `stdin` when called sequentially
**Note:** Only available in Node.js environments.<br/>
Get a [Reader](#reader) function that always returns the next line from a passed read stream when called sequentially.
CodeBlock typescript
// Type Definition
function createStreamReader(): Reader
// Import Path
import { createStreamReader } from '@terrace-lang/js/readers/node-readline'
Markdown
**Usage**
CodeExample
summary-class mb-[320px]
pre-class max-h-[320px]
javascript main.js
import fs from 'node:fs'
import { createStreamReader, useDocument } from '@terrace-lang/js'
// Read the file ./example.tce - equivalent to the `createFileReader` example above.
const reader = createStreamReader(fs.createReadStream('./example.tce'))
const { next, level, line } = useDocument(reader)
await next()
console.log(level(), line())
// 0 title Example Title
await next()
console.log(level(), line())
// 1 line 2
terrace example.tce
title Example Title
line 2

View File

@ -0,0 +1,91 @@
Heading 2 Recipes
class mt-12
Heading 3 Read object properties
class mb-2
Markdown
Read known properties from a Terrace block and write them to an object.
CodeBlock javascript
// Provides simple convenience functions over the core parser
// CommonJS: const { useDocument } = require('@terrace-lang/js/document')
import { useDocument } from '@terrace-lang/js/document'
// A helper for iterating over a string line-by-line
// CommonJS: const { createStringReader } = require('@terrace-lang/js/readers/js-string')
import { createStringReader } from '@terrace-lang/js/readers/js-string'
const input = `
object
string_property An example string
numeric_property 4
`
const output = {
string_property: null,
numeric_property: null
}
// useDocument returns convenience functions
const { next, level, head, tail, match } = useDocument(createStringReader(input))
// next() parses the next line in the document
while (await next()) {
// match('object') is equivalent to head() === 'object'
// Essentially: "If the current line starts with 'object'"
if (match('object')) {
const objectLevel = level()
// When we call next with a parent level it,
// only iterates over lines inside the parent block
while (await next(objectLevel)) {
// tail() returns the part of the current line after the first space
if (match('string_property')) output.string_property = tail()
// parseFloat() here the string tail() to a numeric float value
if (match('numeric_property')) output.numeric_property = parseFloat(tail())
}
}
}
console.dir(output)
// { string_property: 'An example string', numeric_property: 4 }
Markdown
Read *all* properties as strings from a Terrace block and write them to an object.
CodeBlock javascript
// Provides simple convenience functions over the core parser
// CommonJS: const { useDocument } = require('@terrace-lang/js/document')
import { useDocument } from '@terrace-lang/js/document'
// A helper for iterating over a string line-by-line
// CommonJS: const { createStringReader } = require('@terrace-lang/js/readers/js-string')
import { createStringReader } from '@terrace-lang/js/readers/js-string'
const input = `
object
property1 Value 1
property2 Value 2
random_property igazi3ii4quaC5OdoB5quohnah1beeNg
`
const output = {}
// useDocument returns convenience functions
const { next, level, head, tail, match } = useDocument(createStringReader(input))
// next() parses the next line in the document
while (await next()) {
// match('object') is equivalent to head() === 'object'
// Essentially: "If the current line starts with 'object'"
if (match('object')) {
const objectLevel = level()
// When we call next with a parent level,
// it only iterates over lines inside the parent block
while (await next(objectLevel)) {
// Skip empty lines
if (!line()) continue
// Add any properties to the object as strings using the
// line head() as the key and tail() as the value
output[head()] = tail()
}
}
}
console.dir(output)
// { property1: 'Value 1', property2: 'Value 2', random_property: 'igazi3ii4quaC5OdoB5quohnah1beeNg' }

View File

@ -0,0 +1,26 @@
const { useDocument } = require('@terrace-lang/js/document')
const { createFileReader } = require('@terrace-lang/js/readers/node-readline')
const fs = require('fs/promises')
const path = require('path')
const knownNodes = require('./index.js')
module.exports = async function (originalDoc, rootLevel, ...args) {
const includedDoc = useDocument(createFileReader(originalDoc.tail()))
const { next, head, tail, level } = includedDoc
const node = {
type: originalDoc.head(),
class: '',
children: []
}
while (await next()) {
if (!head()) continue
const block = head()
if (!knownNodes[block]) continue
node.children.push(await knownNodes[block](includedDoc, level(), ...args))
}
return node
}

View File

@ -1,5 +1,6 @@
const parseNode = require('./Node.js') const parseNode = require('./Node.js')
module.exports.Include = require('./Include.js')
module.exports.Block = parseNode module.exports.Block = parseNode
module.exports.Section = async (doc, rootLevel, ...args) => { module.exports.Section = async (doc, rootLevel, ...args) => {
const variant = doc.tail() const variant = doc.tail()

45
pnpm-lock.yaml generated
View File

@ -61,10 +61,13 @@ importers:
'@terrace-lang/c': workspace:* '@terrace-lang/c': workspace:*
'@terrace-lang/js': workspace:* '@terrace-lang/js': workspace:*
'@terrace-lang/python': workspace:* '@terrace-lang/python': workspace:*
chai: ^4.3.7
dependencies: dependencies:
'@terrace-lang/c': link:../packages/c '@terrace-lang/c': link:../packages/c
'@terrace-lang/js': link:../packages/js '@terrace-lang/js': link:../packages/js
'@terrace-lang/python': link:../packages/python '@terrace-lang/python': link:../packages/python
devDependencies:
chai: 4.3.7
packages: packages:
@ -1361,6 +1364,10 @@ packages:
resolution: {integrity: sha512-TaTivMB6pYI1kXwrFlEhLeGfOqoDNdTxjCdwRfFFkEA30Eu+k48W34nlok2EYWJfFFzqaEmichdNM7th6M5HNw==} resolution: {integrity: sha512-TaTivMB6pYI1kXwrFlEhLeGfOqoDNdTxjCdwRfFFkEA30Eu+k48W34nlok2EYWJfFFzqaEmichdNM7th6M5HNw==}
dev: true dev: true
/assertion-error/1.1.0:
resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==}
dev: true
/async-each-series/0.1.1: /async-each-series/0.1.1:
resolution: {integrity: sha512-p4jj6Fws4Iy2m0iCmI2am2ZNZCgbdgE+P8F/8csmn2vx7ixXrO2zGcuNsD46X5uZSVecmkEy/M06X2vG8KD6dQ==} resolution: {integrity: sha512-p4jj6Fws4Iy2m0iCmI2am2ZNZCgbdgE+P8F/8csmn2vx7ixXrO2zGcuNsD46X5uZSVecmkEy/M06X2vG8KD6dQ==}
engines: {node: '>=0.8.0'} engines: {node: '>=0.8.0'}
@ -1673,6 +1680,19 @@ packages:
resolution: {integrity: sha512-qMBmvmQmFXaSxexkjjfMvD5rnDL0+m+dUMZKoDYsGG8iZN29RuYh9eRoMvKsT6uMAWlyUUGDEQGJJYjzCIO9ew==} resolution: {integrity: sha512-qMBmvmQmFXaSxexkjjfMvD5rnDL0+m+dUMZKoDYsGG8iZN29RuYh9eRoMvKsT6uMAWlyUUGDEQGJJYjzCIO9ew==}
dev: true dev: true
/chai/4.3.7:
resolution: {integrity: sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==}
engines: {node: '>=4'}
dependencies:
assertion-error: 1.1.0
check-error: 1.0.2
deep-eql: 4.1.3
get-func-name: 2.0.0
loupe: 2.3.6
pathval: 1.1.1
type-detect: 4.0.8
dev: true
/chalk/1.1.3: /chalk/1.1.3:
resolution: {integrity: sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==} resolution: {integrity: sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
@ -1712,6 +1732,10 @@ packages:
is-regex: 1.1.4 is-regex: 1.1.4
dev: true dev: true
/check-error/1.0.2:
resolution: {integrity: sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==}
dev: true
/chokidar/3.5.3: /chokidar/3.5.3:
resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==}
engines: {node: '>= 8.10.0'} engines: {node: '>= 8.10.0'}
@ -1931,6 +1955,13 @@ packages:
resolution: {integrity: sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==} resolution: {integrity: sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==}
dev: true dev: true
/deep-eql/4.1.3:
resolution: {integrity: sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==}
engines: {node: '>=6'}
dependencies:
type-detect: 4.0.8
dev: true
/deepmerge/4.3.0: /deepmerge/4.3.0:
resolution: {integrity: sha512-z2wJZXrmeHdvYJp/Ux55wIjqo81G5Bp4c+oELTW+7ar6SogWHajt5a9gO3s3IDaGSAXjDk0vlQKN3rms8ab3og==} resolution: {integrity: sha512-z2wJZXrmeHdvYJp/Ux55wIjqo81G5Bp4c+oELTW+7ar6SogWHajt5a9gO3s3IDaGSAXjDk0vlQKN3rms8ab3og==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
@ -2705,6 +2736,10 @@ packages:
engines: {node: 6.* || 8.* || >= 10.*} engines: {node: 6.* || 8.* || >= 10.*}
dev: true dev: true
/get-func-name/2.0.0:
resolution: {integrity: sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==}
dev: true
/get-intrinsic/1.2.0: /get-intrinsic/1.2.0:
resolution: {integrity: sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==} resolution: {integrity: sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==}
dependencies: dependencies:
@ -3893,6 +3928,12 @@ packages:
resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
dev: true dev: true
/loupe/2.3.6:
resolution: {integrity: sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==}
dependencies:
get-func-name: 2.0.0
dev: true
/lru-cache/4.1.5: /lru-cache/4.1.5:
resolution: {integrity: sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==} resolution: {integrity: sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==}
dependencies: dependencies:
@ -4347,6 +4388,10 @@ packages:
pify: 3.0.0 pify: 3.0.0
dev: true dev: true
/pathval/1.1.1:
resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==}
dev: true
/picocolors/1.0.0: /picocolors/1.0.0:
resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==}
dev: true dev: true

View File

@ -5,8 +5,11 @@
"test": "NODE_OPTIONS=--experimental-vm-modules NODE_NO_WARNINGS=1 jest" "test": "NODE_OPTIONS=--experimental-vm-modules NODE_NO_WARNINGS=1 jest"
}, },
"dependencies": { "dependencies": {
"@terrace-lang/js": "workspace:*",
"@terrace-lang/c": "workspace:*", "@terrace-lang/c": "workspace:*",
"@terrace-lang/js": "workspace:*",
"@terrace-lang/python": "workspace:*" "@terrace-lang/python": "workspace:*"
},
"devDependencies": {
"chai": "^4.3.7"
} }
} }