mirror of
https://github.com/Ed94/metadesk.git
synced 2026-08-07 16:18:49 +00:00
[examples] filling in notes in the parse_check.c example; upgrading the datadesk_like_template a bit
This commit is contained in:
@@ -1851,7 +1851,6 @@ MD_ParseWholeFile:
|
|||||||
@doc("Prints a message to @code 'out', corresponding with the source code location encoded by @code 'loc'.")
|
@doc("Prints a message to @code 'out', corresponding with the source code location encoded by @code 'loc'.")
|
||||||
@see(MD_PrintMessageFmt)
|
@see(MD_PrintMessageFmt)
|
||||||
@see(MD_PrintNodeMessage)
|
@see(MD_PrintNodeMessage)
|
||||||
@see(MD_PrintNodeMessageFmt)
|
|
||||||
@func MD_PrintMessage: {
|
@func MD_PrintMessage: {
|
||||||
@doc("The file to print the message to.")
|
@doc("The file to print the message to.")
|
||||||
out: *FILE,
|
out: *FILE,
|
||||||
@@ -1867,7 +1866,6 @@ MD_ParseWholeFile:
|
|||||||
@doc("Prints a C format string message to @code 'out', corresponding with the source code location encoded by @code 'loc'.")
|
@doc("Prints a C format string message to @code 'out', corresponding with the source code location encoded by @code 'loc'.")
|
||||||
@see(MD_PrintMessage)
|
@see(MD_PrintMessage)
|
||||||
@see(MD_PrintNodeMessage)
|
@see(MD_PrintNodeMessage)
|
||||||
@see(MD_PrintNodeMessageFmt)
|
|
||||||
@func MD_PrintMessageFmt: {
|
@func MD_PrintMessageFmt: {
|
||||||
@doc("The file to print the message to.")
|
@doc("The file to print the message to.")
|
||||||
out: *FILE,
|
out: *FILE,
|
||||||
@@ -1883,7 +1881,6 @@ MD_ParseWholeFile:
|
|||||||
@send(Nodes)
|
@send(Nodes)
|
||||||
@see(MD_PrintMessage)
|
@see(MD_PrintMessage)
|
||||||
@see(MD_PrintMessageFmt)
|
@see(MD_PrintMessageFmt)
|
||||||
@see(MD_PrintNodeMessageFmt)
|
|
||||||
@doc("Prints a message to @code 'out', corresponding with the source code location of @code 'node'.")
|
@doc("Prints a message to @code 'out', corresponding with the source code location of @code 'node'.")
|
||||||
@func MD_PrintNodeMessage: {
|
@func MD_PrintNodeMessage: {
|
||||||
@doc("The file to print the message to.")
|
@doc("The file to print the message to.")
|
||||||
@@ -1896,23 +1893,6 @@ MD_ParseWholeFile:
|
|||||||
str: MD_String8,
|
str: MD_String8,
|
||||||
};
|
};
|
||||||
|
|
||||||
@send(Nodes)
|
|
||||||
@doc("Prints a C format string message to @code 'out', corresponding with the source code location of @code 'node'.")
|
|
||||||
@see(MD_PrintMessage)
|
|
||||||
@see(MD_PrintMessageFmt)
|
|
||||||
@see(MD_PrintNodeMessage)
|
|
||||||
@func MD_PrintNodeMessageFmt: {
|
|
||||||
@doc("The file to print the message to.")
|
|
||||||
out: *FILE,
|
|
||||||
@doc("The node for which the message is intended.")
|
|
||||||
node: *MD_Node,
|
|
||||||
@doc("The kind/severity of the message.")
|
|
||||||
kind: MD_MessageKind,
|
|
||||||
@doc("The format string to form the message contents.")
|
|
||||||
fmt: *char,
|
|
||||||
"..."
|
|
||||||
};
|
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ Tree Comparison/Verification
|
//~ Tree Comparison/Verification
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
** Example: datadesk-like-template
|
** Example: datadesk-like-template
|
||||||
**
|
**
|
||||||
** This example is setup as a copy-pastable template for creating metadesk
|
** This example is setup as a copy-pastable template for creating metadesk
|
||||||
** based metaprograms that have the same structure as datadesk.
|
** based metaprograms that have the same structure as datadesk metaprograms.
|
||||||
**
|
**
|
||||||
** Datadesk was a precursor language to metadesk. This example is mostly meant
|
** Datadesk was a precursor language to metadesk. This example is mostly meant
|
||||||
** to help datadesk users understand metadesk and migrate onto it.
|
** to help datadesk users understand metadesk and migrate onto it.
|
||||||
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
//~ Includes and globals //////////////////////////////////////////////////////
|
//~ Includes and globals //////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#define MD_ENABLE_PRINT_HELPERS 1
|
||||||
|
|
||||||
#include "md.h"
|
#include "md.h"
|
||||||
#include "md.c"
|
#include "md.c"
|
||||||
|
|
||||||
@@ -24,47 +26,67 @@ static MD_Arena *arena = 0;
|
|||||||
|
|
||||||
//~ Declare user defined functions (the datadesk "custom layer") //////////////
|
//~ Declare user defined functions (the datadesk "custom layer") //////////////
|
||||||
|
|
||||||
// Called when the program starts.
|
static void Initialize(void); // Runs at the beginning of generation.
|
||||||
static void Initialize(void);
|
static void TopLevel(MD_Node *node); // Runs once for each top-level node from each file.
|
||||||
// Called for every top-level node that is parsed from passed files.
|
static void CleanUp(void); // Runs at the end of generation.
|
||||||
static void TopLevel(MD_Node *node);
|
|
||||||
// Runs before the program ends.
|
|
||||||
static void CleanUp(void);
|
|
||||||
|
|
||||||
|
|
||||||
//~ main //////////////////////////////////////////////////////////////////////
|
//~ main //////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
int main(int argument_count, char **arguments)
|
int main(int argument_count, char **arguments)
|
||||||
{
|
{
|
||||||
// simple single-threaded one-run memory management setup
|
// setup the global arena
|
||||||
arena = MD_ArenaAlloc(1ull << 40);
|
arena = MD_ArenaAlloc(1ull << 40);
|
||||||
|
|
||||||
// parse all files passed to the command line
|
// parse all files passed to the command line
|
||||||
|
MD_b32 failed_parse = 0;
|
||||||
MD_Node *list = MD_MakeList(arena);
|
MD_Node *list = MD_MakeList(arena);
|
||||||
for(int i = 1; i < argument_count; i += 1)
|
for(int i = 1; i < argument_count; i += 1)
|
||||||
{
|
{
|
||||||
MD_Node *root = MD_ParseWholeFile(arena, MD_S8CString(arguments[i])).node;
|
|
||||||
MD_PushNewReference(arena, list, root);
|
// parse the file
|
||||||
}
|
MD_String8 file_name = MD_S8CString(arguments[i]);
|
||||||
|
MD_ParseResult parse_result = MD_ParseWholeFile(arena, file_name);
|
||||||
// calls to the "custom layer"
|
|
||||||
Initialize();
|
// print metadesk errors
|
||||||
for(MD_EachNode(ref, list->first_child))
|
for (MD_Message *message = parse_result.errors.first;
|
||||||
{
|
message != 0;
|
||||||
MD_Node *root = MD_NodeFromReference(ref);
|
message = message->next)
|
||||||
for(MD_EachNode(node, root->first_child))
|
|
||||||
{
|
{
|
||||||
TopLevel(node);
|
MD_CodeLoc code_loc = MD_CodeLocFromNode(message->node);
|
||||||
|
MD_PrintMessage(stdout, code_loc, message->kind, message->string);
|
||||||
|
}
|
||||||
|
|
||||||
|
// save to parse results list
|
||||||
|
MD_PushNewReference(arena, list, parse_result.node);
|
||||||
|
|
||||||
|
// mark failure state
|
||||||
|
if (parse_result.errors.max_message_kind >= MD_MessageKind_Error)
|
||||||
|
{
|
||||||
|
failed_parse = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CleanUp();
|
|
||||||
|
// call the "custom layer"
|
||||||
|
if (!failed_parse)
|
||||||
|
{
|
||||||
|
Initialize();
|
||||||
|
for(MD_EachNode(ref, list->first_child))
|
||||||
|
{
|
||||||
|
MD_Node *root = MD_NodeFromReference(ref);
|
||||||
|
for(MD_EachNode(node, root->first_child))
|
||||||
|
{
|
||||||
|
TopLevel(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CleanUp();
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//~ The "custom layer" definitions ////////////////////////////////////////////
|
//~ The "custom layer" ////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
Initialize(void)
|
Initialize(void)
|
||||||
|
|||||||
+65
-4
@@ -1,26 +1,87 @@
|
|||||||
|
/*
|
||||||
|
** Example: parse-check
|
||||||
|
**
|
||||||
|
** This example shows how to use the metadesk library to parse metadesk files,
|
||||||
|
** print errors, and dump verbose feedback on the resulting metadesk trees.
|
||||||
|
** This is also a nice utility for checking and inspecting your metadesk files.
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
|
||||||
|
//~ Includes and globals //////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// @notes Print helpers will make it easier to print the errors. This brings in
|
||||||
|
// C's stdio.h. It is possible to use error messages without print helpers,
|
||||||
|
// but a dependency on stdio.h is fine here so we will use it.
|
||||||
|
#define MD_ENABLE_PRINT_HELPERS 1
|
||||||
|
|
||||||
#include "md.h"
|
#include "md.h"
|
||||||
#include "md.c"
|
#include "md.c"
|
||||||
|
|
||||||
|
// @notes For simple single-threaded memory management in a run-once-and-exit
|
||||||
|
// utility, a single global arena is our prefered setup.
|
||||||
static MD_Arena *arena = 0;
|
static MD_Arena *arena = 0;
|
||||||
|
|
||||||
|
|
||||||
|
//~ main //////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
int main(int argument_count, char **arguments)
|
int main(int argument_count, char **arguments)
|
||||||
{
|
{
|
||||||
|
// setup the global arena
|
||||||
|
// @notes Metadesk arenas do linear reserve-and-commit allocation. This
|
||||||
|
// code makes an arena with a 1 terabyte reserve which works quite nicely,
|
||||||
|
// so long as we aren't doing more than a few of them.
|
||||||
arena = MD_ArenaAlloc(1ull << 40);
|
arena = MD_ArenaAlloc(1ull << 40);
|
||||||
|
|
||||||
|
|
||||||
|
// parse all files passed to the command line
|
||||||
MD_Node *list = MD_MakeList(arena);
|
MD_Node *list = MD_MakeList(arena);
|
||||||
for(int i = 1; i < argument_count; i += 1)
|
for(int i = 1; i < argument_count; i += 1)
|
||||||
{
|
{
|
||||||
MD_Node *root = MD_ParseWholeFile(arena, MD_S8CString(arguments[i])).node;
|
|
||||||
MD_PushNewReference(arena, list, root);
|
// parse the file
|
||||||
|
// @notes Here we rely on MD_ParseWholeFile which loads the file itself
|
||||||
|
// and then does the whole parse. In a simple utility program like
|
||||||
|
// this metadesk's default implementations for the overrides make
|
||||||
|
// this work.
|
||||||
|
MD_String8 file_name = MD_S8CString(arguments[i]);
|
||||||
|
MD_ParseResult parse_result = MD_ParseWholeFile(arena, file_name);
|
||||||
|
|
||||||
|
// print metadesk errors
|
||||||
|
for (MD_Message *message = parse_result.errors.first;
|
||||||
|
message != 0;
|
||||||
|
message = message->next)
|
||||||
|
{
|
||||||
|
// @notes To print a message from the parse, technically we can do
|
||||||
|
// whatever we want. But we'll use the message format suggested
|
||||||
|
// by the metadesk library. First we get the code location - which
|
||||||
|
// means the file name and line number - for the node on this
|
||||||
|
// message. Then we pass the details of this message to the
|
||||||
|
// MD_PrintMessage helper function.
|
||||||
|
MD_CodeLoc code_loc = MD_CodeLocFromNode(message->node);
|
||||||
|
MD_PrintMessage(stdout, code_loc, message->kind, message->string);
|
||||||
|
}
|
||||||
|
|
||||||
|
// save to parse results list
|
||||||
|
// @notes Metadesk message kinds are sorted in order of severity. So we
|
||||||
|
// can easily check the severity of a entire parse by looking at the
|
||||||
|
// `max_message_kind` field on the errors from the parse result. Here
|
||||||
|
// only push the parse result onto our list if there were no errors.
|
||||||
|
if (parse_result.errors.max_message_kind >= MD_MessageKind_Error)
|
||||||
|
{
|
||||||
|
MD_PushNewReference(arena, list, parse_result.node);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// print the verbose parse results
|
||||||
for(MD_EachNodeRef(root, list->first_child))
|
for(MD_EachNodeRef(root, list->first_child))
|
||||||
{
|
{
|
||||||
for(MD_EachNode(node, root->first_child))
|
for(MD_EachNode(node, root->first_child))
|
||||||
{
|
{
|
||||||
MD_String8List strs = MD_DebugStringListFromNode(arena, node, 0, MD_S8Lit(" "), MD_GenerateFlags_Tree);
|
MD_String8List strs =
|
||||||
|
MD_DebugStringListFromNode(arena, node, 0, MD_S8Lit(" "), MD_GenerateFlags_Tree);
|
||||||
MD_String8 str = MD_S8ListJoin(arena, strs, 0);
|
MD_String8 str = MD_S8ListJoin(arena, strs, 0);
|
||||||
fprintf(stdout, "%.*s\n", MD_S8VArg(str));
|
fwrite(str.str, str.size, 1, stdout);
|
||||||
|
fwrite("\n", 1, 1, stdout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -5,8 +5,8 @@ immutable tree model
|
|||||||
nil
|
nil
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
|
[ ] Metadesk hello world
|
||||||
[ ] Metadesk parse checker
|
[ ] Metadesk parse checker
|
||||||
[ ] Metadesk reprinter
|
|
||||||
[ ] Example of helpers: string helpers, linked lists, map type
|
[ ] Example of helpers: string helpers, linked lists, map type
|
||||||
printing errors, cmd line, file iter
|
printing errors, cmd line, file iter
|
||||||
[x] Datadesk-like setup
|
[x] Datadesk-like setup
|
||||||
|
|||||||
-13
@@ -2903,19 +2903,6 @@ MD_PrintMessageFmt(FILE *file, MD_CodeLoc code_loc, MD_MessageKind kind, char *f
|
|||||||
MD_ReleaseScratch(scratch);
|
MD_ReleaseScratch(scratch);
|
||||||
}
|
}
|
||||||
|
|
||||||
MD_FUNCTION void
|
|
||||||
MD_PrintNodeMessageFmt(FILE *file, MD_Node *node, MD_MessageKind kind, char *fmt, ...){
|
|
||||||
MD_ArenaTemp scratch = MD_GetScratch(0, 0);
|
|
||||||
va_list args;
|
|
||||||
va_start(args, fmt);
|
|
||||||
MD_String8 string = MD_S8FmtV(scratch.arena, fmt, args);
|
|
||||||
va_end(args);
|
|
||||||
MD_CodeLoc code_loc = MD_CodeLocFromNode(node);
|
|
||||||
MD_String8 message = MD_FormatMessage(scratch.arena, code_loc, kind, string);
|
|
||||||
fwrite(message.str, message.size, 1, file);
|
|
||||||
MD_ReleaseScratch(scratch);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//~ Tree Comparison/Verification
|
//~ Tree Comparison/Verification
|
||||||
|
|||||||
+2
-2
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
//~ Metadesk Library
|
//~ Metadesk Library
|
||||||
|
|
||||||
|
// TODO(allen): Welcome & user directory comment here
|
||||||
|
|
||||||
#ifndef MD_H
|
#ifndef MD_H
|
||||||
#define MD_H
|
#define MD_H
|
||||||
|
|
||||||
@@ -1117,8 +1119,6 @@ MD_FUNCTION void MD_PrintMessage(FILE *file, MD_CodeLoc loc, MD_MessageKind kind
|
|||||||
MD_String8 string);
|
MD_String8 string);
|
||||||
MD_FUNCTION void MD_PrintMessageFmt(FILE *file, MD_CodeLoc code_loc, MD_MessageKind kind,
|
MD_FUNCTION void MD_PrintMessageFmt(FILE *file, MD_CodeLoc code_loc, MD_MessageKind kind,
|
||||||
char *fmt, ...);
|
char *fmt, ...);
|
||||||
MD_FUNCTION void MD_PrintNodeMessageFmt(FILE *file, MD_Node *node, MD_MessageKind kind,
|
|
||||||
char *fmt, ...);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//~ Tree Comparison/Verification
|
//~ Tree Comparison/Verification
|
||||||
|
|||||||
Reference in New Issue
Block a user