From 7d82d4f0ef774af0b11aa733720f56a9a9de1fcf Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Thu, 16 Sep 2021 22:52:29 -0700 Subject: [PATCH] [examples] custom user errors --- bin/build_examples.sh | 2 +- bin/run_examples.sh | 17 +----- examples/mdesk_files/node_errors.mdesk | 12 ---- examples/mdesk_files/user_errors.mdesk | 14 +++++ examples/metaprograms/hello_world.c | 13 +--- examples/metaprograms/node_errors.c | 33 ---------- examples/metaprograms/parse_check.c | 10 ++- examples/metaprograms/user_errors.c | 84 ++++++++++++++++++++++++++ intro_notes.txt | 3 +- project.4coder | 16 ++++- source/md.c | 2 +- 11 files changed, 123 insertions(+), 83 deletions(-) delete mode 100644 examples/mdesk_files/node_errors.mdesk create mode 100644 examples/mdesk_files/user_errors.mdesk delete mode 100644 examples/metaprograms/node_errors.c create mode 100644 examples/metaprograms/user_errors.c diff --git a/bin/build_examples.sh b/bin/build_examples.sh index 79cbe0a..56cbe14 100755 --- a/bin/build_examples.sh +++ b/bin/build_examples.sh @@ -12,7 +12,7 @@ bin/bld_core.sh show_ctx metasrc="examples/metaprograms" bin/bld_core.sh unit datadesk_like $metasrc/datadesk_like_template.c -bin/bld_core.sh unit node_errors $metasrc/node_errors.c +bin/bld_core.sh unit user_errors $metasrc/user_errors.c bin/bld_core.sh unit parse_check $metasrc/parse_check.c echo diff --git a/bin/run_examples.sh b/bin/run_examples.sh index 0b1e0da..d1cbd9a 100755 --- a/bin/run_examples.sh +++ b/bin/run_examples.sh @@ -8,24 +8,9 @@ cd .. build_path=$root_path/build examples_path=$root_path/examples -echo ~~~ Running Output Parse Example ~~~ -cd $examples_path -if [ -d "output_parse/examples" ]; then - cd output_parse/examples - mkdir -p output - cd output - $build_path/output_parse.exe ../example.mdesk ../example2.mdesk -fi -echo - echo ~~~ Running Error Generation Example ~~~ cd $build_path -./node_errors.exe $examples_path/node_errors/node_errors.mdesk -echo - -echo ~~~ Running C++ Example ~~~ -cd $build_path -./cpp_build_test.exe +./user_errors.exe $examples_path/mdesk_files/user_errors.mdesk echo ###### Restore Path ########################################################### diff --git a/examples/mdesk_files/node_errors.mdesk b/examples/mdesk_files/node_errors.mdesk deleted file mode 100644 index 0183733..0000000 --- a/examples/mdesk_files/node_errors.mdesk +++ /dev/null @@ -1,12 +0,0 @@ - -@foo @bar Foo: -{ - x, y, z, - a, b, c, - 1, 2, 3, -} - -@baz Blah: -{ - x100 y200 z300 -} diff --git a/examples/mdesk_files/user_errors.mdesk b/examples/mdesk_files/user_errors.mdesk new file mode 100644 index 0000000..48cbef3 --- /dev/null +++ b/examples/mdesk_files/user_errors.mdesk @@ -0,0 +1,14 @@ + +@foo @bar Foo: +{ + x, y, z, + a, b, c, + 1, 2, 3, +} + +@baz Blah: +{ + x100 y200 z300 +} + +Example: [100 + 200] diff --git a/examples/metaprograms/hello_world.c b/examples/metaprograms/hello_world.c index 9333a9d..da23570 100644 --- a/examples/metaprograms/hello_world.c +++ b/examples/metaprograms/hello_world.c @@ -1,20 +1,12 @@ /* ** Example: hello world -** - ** -** */ -//~ Includes and globals ////////////////////////////////////////////////////// - -// @notes Metadesk is a source-include library. So we include the -// file "md.c" into the usage code directly. The library +//~ includes and globals ////////////////////////////////////////////////////// #include "md.h" #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; //~ main ////////////////////////////////////////////////////////////////////// @@ -22,9 +14,6 @@ static MD_Arena *arena = 0; int main(int argc, char **argv){ // 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 so long as - // we're only doing one or a few arenas. arena = MD_ArenaAlloc(1ull << 40); // parse a string diff --git a/examples/metaprograms/node_errors.c b/examples/metaprograms/node_errors.c deleted file mode 100644 index 018ffa4..0000000 --- a/examples/metaprograms/node_errors.c +++ /dev/null @@ -1,33 +0,0 @@ -// Sample code to demonstrate errors being reported for certain nodes. - -#define MD_ENABLE_PRINT_HELPERS 1 - -#include "md.h" -#include "md.c" - -static MD_Arena *arena = 0; - -int main(int argument_count, char **arguments) -{ - arena = MD_ArenaAlloc(1ull << 40); - - // NOTE(rjf): Parse all the files passed in via command line. - MD_Node *list = MD_MakeList(arena); - 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); - } - - // NOTE(rjf): Print errors on every single node. - for(MD_EachNode(ref, list->first_child)) - { - MD_Node *root = MD_ResolveNodeFromReference(ref); - for(MD_EachNode(node, root->first_child)) - { - MD_PrintNodeMessageFmt(stderr, node, MD_MessageKind_Error, "This node has an error!"); - } - } - - return 0; -} diff --git a/examples/metaprograms/parse_check.c b/examples/metaprograms/parse_check.c index 20550f2..7d6c649 100644 --- a/examples/metaprograms/parse_check.c +++ b/examples/metaprograms/parse_check.c @@ -7,7 +7,7 @@ ** */ -//~ Includes and globals ////////////////////////////////////////////////////// +//~ includes and globals ////////////////////////////////////////////////////// #include "md.h" #include "md.c" @@ -22,12 +22,10 @@ static MD_Arena *arena = 0; int main(int argc, char **argv) { // 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 so long as - // we're only doing one or a few arenas. + // @notes This code makes an arena with a 1 terabyte reserve which works as + // long as we only have one or a few arenas. arena = MD_ArenaAlloc(1ull << 40); - // parse all files passed to the command line MD_Node *list = MD_MakeList(arena); for (int i = 1; i < argc; i += 1) @@ -94,7 +92,7 @@ int main(int argc, char **argv) // When the string needs to be finalized into a single contiguous // block a user can just call `MD_S8ListJoin` as shown here. MD_String8List stream = {0}; - MD_DebugStringListFromNode(arena, &stream, node, 0, MD_S8Lit(" "), MD_GenerateFlags_Tree); + MD_DebugDumpFromNode(arena, &stream, node, 0, MD_S8Lit(" "), MD_GenerateFlags_Tree); MD_String8 str = MD_S8ListJoin(arena, stream, 0); fwrite(str.str, str.size, 1, stdout); fwrite("\n", 1, 1, stdout); diff --git a/examples/metaprograms/user_errors.c b/examples/metaprograms/user_errors.c new file mode 100644 index 0000000..a564a81 --- /dev/null +++ b/examples/metaprograms/user_errors.c @@ -0,0 +1,84 @@ +/* +** Example: user-errors +** +** This example shows how to print custom error messages. +** +*/ + +//~ includes and globals ////////////////////////////////////////////////////// + +#include "md.h" +#include "md.c" + +// @notes For simple single-threaded memory management in a run-once-and-exit +// utility, a single global arena is our recommended approach. +static MD_Arena *arena = 0; + + +//~ main ////////////////////////////////////////////////////////////////////// + +int main(int argc, char **argv) +{ + char *argv_dummy[] = { + 0, + "W:/metadesk/examples/mdesk_files/user_errors.mdesk" + }; + argc = 2; + argv = argv_dummy; + + // setup the global arena + arena = MD_ArenaAlloc(1ull << 40); + + // parse all files passed to the command line + MD_Node *list = MD_MakeList(arena); + for(int i = 1; i < argc; i += 1) + { + // parse the file + MD_String8 file_name = MD_S8CString(argv[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) + { + MD_CodeLoc code_loc = MD_CodeLocFromNode(message->node); + MD_PrintMessage(stderr, code_loc, message->kind, message->string); + } + + // save to parse results list + MD_PushNewReference(arena, list, parse_result.node); + } + + // check for custom errors + for(MD_EachNode(ref, list->first_child)) + { + MD_Node *root = MD_ResolveNodeFromReference(ref); + for(MD_EachNode(node, root->first_child)) + { + // top level node should have one or zero tags. + MD_Node *tag_2 = MD_TagFromIndex(node, 1); + if (!MD_NodeIsNil(tag_2)) + { + MD_CodeLoc loc = MD_CodeLocFromNode(tag_2); + MD_PrintMessage(stderr, loc, MD_MessageKind_Error, + MD_S8Lit("Not supposed to have multiple tags.")); + } + + // top level sets with brackets should not have names + if ((node->flags & MD_NodeFlag_HasBracketLeft) || + (node->flags & MD_NodeFlag_HasBracketRight)) + { + if (node->string.size > 0) + { + MD_CodeLoc loc = MD_CodeLocFromNode(node); + MD_PrintMessage(stderr, loc, MD_MessageKind_Error, + MD_S8Lit("Nodes with brackets should not have names.")); + } + } + + } + } + + return 0; +} diff --git a/intro_notes.txt b/intro_notes.txt index 8690534..9c9025f 100644 --- a/intro_notes.txt +++ b/intro_notes.txt @@ -5,8 +5,9 @@ immutable tree model nil Example Programs: -[ ] Metadesk hello world +[x] Metadesk hello world [x] Metadesk parse checker +[x] User error checking [ ] Example of helpers: string helpers, linked lists, map type printing errors, cmd line, file iter [x] Datadesk-like setup diff --git a/project.4coder b/project.4coder index 45781af..f925ce6 100644 --- a/project.4coder +++ b/project.4coder @@ -80,8 +80,22 @@ command_list = { "bin/build_tests.sh", .os = "mac" }, }, }, + { + .name = "run_examples", + .out = "*compilation*", + .footer_panel = true, + .save_dirty_files = true, + .cursor_at_end = false, + .cmd = + { + { "git_bash bin\\run_examples.sh", .os = "win" }, + { "bin/build_tests.sh", .os = "linux" }, + { "bin/build_tests.sh", .os = "mac" }, + }, + }, }; fkey_command[1] = "build_tests"; fkey_command[2] = "run_tests"; -fkey_command[3] = "build_examples"; \ No newline at end of file +fkey_command[3] = "build_examples"; +fkey_command[4] = "run_examples"; diff --git a/source/md.c b/source/md.c index f7469d3..36342d1 100644 --- a/source/md.c +++ b/source/md.c @@ -2784,7 +2784,7 @@ MD_ChildFromIndex(MD_Node *node, int n) MD_FUNCTION MD_Node * MD_TagFromIndex(MD_Node *node, int n) { - return MD_NodeFromIndex(node->first_child, MD_NilNode(), n); + return MD_NodeFromIndex(node->first_tag, MD_NilNode(), n); } MD_FUNCTION MD_Node *