[examples] write overrides example; tidy up overrides overrview comment; tidy up misc notes files

This commit is contained in:
Allen Webster
2021-10-07 22:35:31 -07:00
parent 343b239fa1
commit 5d51cf478c
7 changed files with 213 additions and 88 deletions
+1
View File
@@ -21,6 +21,7 @@ if [ -d $examps/type_metadata/generated/type_info_meta.h ]; then
bin/bld_core.sh unit type_info $examps/type_metadata/type_info_final_program.c
fi
bin/bld_core.sh unit overrides $examps/advanced_usages/overrides.c
echo
+1 -4
View File
@@ -9,13 +9,10 @@ cd ..
echo "~~~ Build All Tests ~~~"
bin/bld_core.sh show_ctx
bin/bld_core.sh unit expression_tests tests/expression_tests.c
exit
bin/bld_core.sh unit sanity_tests tests/sanity_tests.c
bin/bld_core.sh unit unicode_test tests/unicode_test.c
bin/bld_core.sh unit cpp_build_test tests/cpp_build_test.cpp
bin/bld_core.sh unit expression_tests tests/expression_tests.c
echo
+170
View File
@@ -0,0 +1,170 @@
/*
** Example: overrides
**
** TODO full commentary
**
*/
//~ example allocator /////////////////////////////////////////////////////////
typedef struct ExampleAllocatorNode{
struct ExampleAllocatorNode *next;
struct ExampleAllocatorNode *prev;
int size_after_node;
} ExampleAllocatorNode;
typedef struct ExampleAllocator{
ExampleAllocatorNode *first;
ExampleAllocatorNode *last;
} ExampleAllocator;
void* examp_alloc(ExampleAllocator *a, int size);
void examp_free(ExampleAllocator *a, void *ptr);
//~ include metadesk header ///////////////////////////////////////////////////
#include "md.h"
//~ set metadesk overrides ////////////////////////////////////////////////////
// override memory to use malloc/free
ExampleAllocator* md_example_allocator = 0;
void* md_reserve_by_example_allocator(unsigned long long size);
void md_release_by_example_allocator(void *ptr, unsigned long long ignore);
#define MD_IMPL_Reserve md_reserve_by_example_allocator
#define MD_IMPL_Commit(p,z) (1)
#define MD_IMPL_Decommit(p,z) ((void)0)
#define MD_IMPL_Release(p,z) md_release_by_example_allocator
// override file loading
MD_String8 md_load_entire_file_by_stdio(MD_Arena *arena, MD_String8 filename);
#define MD_IMPL_LoadEntireFile md_load_entire_file_by_stdio
//~ metadesk source, global arena /////////////////////////////////////////////
#include "md.c"
static MD_Arena *arena = 0;
//~ implement overrides ///////////////////////////////////////////////////////
// override memory to use malloc/free
#include <stdlib.h>
#include <assert.h>
void*
md_reserve_by_example_allocator(unsigned long long size)
{
assert(md_example_allocator != 0);
void *result = examp_alloc(md_example_allocator, (int)size);
return(result);
}
void
md_release_by_example_allocator(void *ptr, unsigned long long ignore)
{
assert(md_example_allocator != 0);
examp_free(md_example_allocator, ptr);
}
// override file loading
MD_String8
md_load_entire_file_by_stdio(MD_Arena *arena, MD_String8 filename)
{
MD_String8 result = {0};
MD_ArenaTemp scratch = MD_GetScratch(&arena, 1);
MD_String8 filename_copy = MD_S8Copy(scratch.arena, filename);
char *filename_cstr = (char*)filename_copy.str;
FILE *file = fopen(filename_cstr, "rb");
if (file != 0)
{
fseek(file, 0, SEEK_END);
result.size = ftell(file);
fseek(file, 0, SEEK_SET);
fread(result.str, result.size, 1, file);
fclose(file);
}
MD_ReleaseScratch(scratch);
return(result);
}
//~ main //////////////////////////////////////////////////////////////////////
int main(int argc, char **argv)
{
// initialize the example allocator
ExampleAllocator allocator = {0};
// configure the allocator context
md_example_allocator = &allocator;
// setup the global arena
arena = MD_ArenaAlloc();
// ... any normal metadesk usage may go here ...
return 0;
}
//~ implement the example allocator ///////////////////////////////////////////
void*
examp_alloc(ExampleAllocator *a, int size)
{
ExampleAllocatorNode *node = (ExampleAllocatorNode*)malloc(size + sizeof(*node));
node->size_after_node = size;
if (a->first == 0)
{
a->first = a->last = node;
node->next = node->prev = 0;
}
else
{
node->prev = a->last;
node->next = 0;
a->last->next = node;
a->last = node;
}
void *result = (node + 1);
return(result);
}
void
examp_free(ExampleAllocator *a, void *ptr)
{
ExampleAllocatorNode *node = ((ExampleAllocatorNode*)ptr) - 1;
if (node->next != 0)
{
node->next->prev = node->prev;
}
if (node->prev != 0)
{
node->prev->next = node->next;
}
if (a->first == node)
{
a->first = node->next;
}
if (a->last == node)
{
a->last = node->prev;
}
free(node);
}
+1 -1
View File
@@ -69,7 +69,7 @@ int main(int argc, char **argv)
// MD_Node pointer in the for loop that iterates through each node in the
// list. The second parameter is a pointer to the first node of the list.
// Generally we past the `first_child` of a list or parent MD_Node, but we
// don't always have to.
// don't always have to.
for (MD_EachNode(root_it, list->first_child))
{
+2 -6
View File
@@ -1,9 +1,3 @@
Intro Materials Should Cover:
arena
string helpers
immutable tree model
nil
Example Programs:
[x] Metadesk hello world
[x] Metadesk parse checker
@@ -16,6 +10,8 @@ Example Programs:
[ ] Example of simple expression parser
[ ] Example of C-like expression parser (with value and type expressions)
[ ] Example(s) of using overrides
[x] Write
[ ] Commentary
[ ] Example memory clearing in long-running program
[ ] Example multi-threaded parsing
-37
View File
@@ -1,37 +0,0 @@
It looks like there was some confusion around the [] and {} handling.
1. I don't think these should be allowed as prefix operators at all.
Here for example I find it weird and ambiguous `[1, 100] * n`
Is this two prefix operators on `n` or is `*` a binary operator?
I want to read it as a binary operator, which makes `[1, 100]` a leaf
not a prefix. Yet the test sets up "[]" as a prefix and if I remove
the "[]" prefix operator the test fails
'Example 12 : "[1, 100] * n". Unexpected Expr parsing error: "Unexpected set."'
This is a good test but I think it should work *all the time*. Any set
with "[]" "{}" "[)" or "(]" should just always be allowed.
I would like to:
a. Always accept the kinds of sets I just listed as leafs when they appear
in a location expecting a leaf
b. Emit an error when the user tries to create a binary or prefix operator with
"[]" "()" or any other set type; allowing "[]" and "()" should be a special
case of postfix operators only
2. When a set type is allowed as a postfix operator, let's do the same thing no
matter what kind of set it is. Right now the "[]" postfix has it's children
parsed but the "()" does not. I think we should just treat all sets-as-postfix
operators the way we're doing "()". Then it's just a matter of checking if a
node is a particular set type that matches an existing postfix set.
3. We should emit errors whenever an operator string does not parse to a single
metadesk token - with the exception of the special cases for sets "()" and
"[]" Also they should be restricted to the "label" making tokens:
identifiers, numbers, string literals and symbols. We could make this easier
by allowing even fewer kinds. At the limit it could be just symbols, but
that cuts out the clever 'sizeof' from the test... Maybe symbols and
identifers only? If that's not too difficult to pull off let's go with that.
If an issue comes up with this one we can discuss more because it's not
exactly clear to me what's best.
+38 -40
View File
@@ -3,44 +3,44 @@
#if !defined(MD_C)
#define MD_C
/* NOTE(allen): Notes on overrides/macro options:
/* NOTE(allen): Overrides & Options Macros:
**
** Overridable :
** "memset" ** REQUIRED (default crt-based implementation available)
** #define MD_IMPL_Memset (void*, int, MD_u64) -> void*
** #define MD_IMPL_Memmove (void*, void*, MD_u64) -> void*
** Overridable
** "memset" ** REQUIRED (default crt-based implementation)
** #define MD_IMPL_Memset (void*, int, uint64) -> void*
** #define MD_IMPL_Memmove (void*, void*, uint64) -> void*
**
** "file iteration" ** OPTIONAL
** #define MD_IMPL_FileIterBegin (MD_FileIter*, MD_String8) -> MD_b32
** "file iteration" ** OPTIONAL (default for win32 and linux)
** #define MD_IMPL_FileIterBegin (MD_FileIter*, MD_String8) -> Boolean
** #define MD_IMPL_FileIterNext (MD_Arena*, MD_FileIter*) -> MD_FileInfo
** #define MD_IMPL_FileIterEnd (MD_FileIter*) -> void
**
** "file load" ** OPTIONAL
** "file load" ** OPTIONAL (default for win32 and linux)
** #define MD_IMPL_LoadEntireFile (MD_Arena*, MD_String8 filename) -> MD_String8
**
** "low level memory" ** OPTIONAL (required for default arena)
** #define MD_IMPL_Reserve (MD_u64) -> void*
** #define MD_IMPL_Commit (void*, MD_u64) -> MD_b32
** #define MD_IMPL_Decommit (void*, MD_u64) -> void
** #define MD_IMPL_Release (void*, MD_u64) -> void
** "low level memory" ** OPTIONAL (required for default arena) (default for win32 and linux)
** #define MD_IMPL_Reserve (uint64) -> void*
** #define MD_IMPL_Commit (void*, uint64) -> MD_b32
** #define MD_IMPL_Decommit (void*, uint64) -> void
** #define MD_IMPL_Release (void*, uint64) -> void
**
** "arena" ** REQUIRED (default implementation available)
** "arena" ** REQUIRED (default available)
** #define MD_IMPL_Arena <type>
** #define MD_IMPL_ArenaAlloc () -> MD_IMPL_Arena*
** #define MD_IMPL_ArenaRelease (MD_IMPL_Arena*) -> void
** #define MD_IMPL_ArenaGetPos (MD_IMPL_Arena*) -> MD_u64
** #define MD_IMPL_ArenaPush (MD_IMPL_Arena*, MD_u64) -> void*
** #define MD_IMPL_ArenaPopTo (MD_IMPL_Arena*, MD_u64) -> void
** #define MD_IMPL_ArenaSetAutoAlign (MD_IMPL_Arena*, MD_u64) -> void
** #define MD_IMPL_ArenaHeaderSize MD_u64
** #define MD_IMPL_ArenaGetPos (MD_IMPL_Arena*) -> uint64
** #define MD_IMPL_ArenaPush (MD_IMPL_Arena*, uint64) -> void*
** #define MD_IMPL_ArenaPopTo (MD_IMPL_Arena*, uint64) -> void
** #define MD_IMPL_ArenaSetAutoAlign (MD_IMPL_Arena*, uint64) -> void
** #define MD_IMPL_ArenaHeaderSize uint64
**
** "scratch" ** REQUIRED (default implementation available)
** #define MD_IMPL_GetScratch (MD_IMPL_Arena**, MD_u64) -> MD_IMPL_Arena*
** "scratch" ** REQUIRED (default available)
** #define MD_IMPL_GetScratch (MD_IMPL_Arena**, uint64) -> MD_IMPL_Arena*
** "scratch constants" ** OPTIONAL (required for default scratch)
** #define MD_IMPL_ScratchCount MD_u64 / default 2
** #define MD_IMPL_ScratchCount uint64 [default 2]
**
** "sprintf" ** OPTIONAL (default implementation available)
** #define MD_IMPL_Vsnprintf (char * buf, int count, char const * fmt, va_list va) -> int
** "sprintf" ** OPTIONAL (default available)
** #define MD_IMPL_Vsnprintf (char*, uint64, char const*, va_list) -> uint64
**
** Default Implementation Controls
** These controls default to '1' i.e. 'enabled'
@@ -667,8 +667,6 @@ MD_GetScratchDefault(MD_Arena **conflicts, MD_u64 count)
//////////////////////// MD Library Implementation /////////////////////////////
////////////////////////////////////////////////////////////////////////////////
#define MD_UNTERMINATED_TOKEN_LEN_CAP 20
#if MD_DEFAULT_SPRINTF
#define STB_SPRINTF_IMPLEMENTATION
#define STB_SPRINTF_DECORATE(name) md_stbsp_##name
@@ -3372,14 +3370,14 @@ MD_ExprBakeOperatorTableFromList(MD_Arena *arena, MD_ExprOprList *list)
// error checking
MD_String8 error_str = MD_ZERO_STRUCT;
MD_Token op_token = MD_TokenFromString(op_s);
MD_b32 is_setlike_op =
(op_s.size == 2 &&
(MD_S8Match(op_s, MD_S8Lit("[]"), 0) || MD_S8Match(op_s, MD_S8Lit("()"), 0) ||
MD_S8Match(op_s, MD_S8Lit("[)"), 0) || MD_S8Match(op_s, MD_S8Lit("(]"), 0) ||
MD_S8Match(op_s, MD_S8Lit("{}"), 0)));
(op_s.size == 2 &&
(MD_S8Match(op_s, MD_S8Lit("[]"), 0) || MD_S8Match(op_s, MD_S8Lit("()"), 0) ||
MD_S8Match(op_s, MD_S8Lit("[)"), 0) || MD_S8Match(op_s, MD_S8Lit("(]"), 0) ||
MD_S8Match(op_s, MD_S8Lit("{}"), 0)));
if(op_kind != MD_ExprOprKind_Prefix && op_kind != MD_ExprOprKind_Postfix &&
op_kind != MD_ExprOprKind_Binary && op_kind != MD_ExprOprKind_BinaryRightAssociative)
{
@@ -3545,19 +3543,19 @@ MD_ExprParse_MakeContext(MD_ExprOprTable *op_table)
{
MD_ExprParseCtx result = MD_ZERO_STRUCT;
result.op_table = op_table;
result.accel.postfix_set_ops[0] = MD_ExprOprFromKindString(op_table, MD_ExprOprKind_Postfix, MD_S8Lit("()"));
result.accel.postfix_set_flags[0] = MD_NodeFlag_HasParenLeft | MD_NodeFlag_HasParenRight;
result.accel.postfix_set_ops[1] = MD_ExprOprFromKindString(op_table, MD_ExprOprKind_Postfix, MD_S8Lit("[]"));
result.accel.postfix_set_flags[1] = MD_NodeFlag_HasBracketLeft | MD_NodeFlag_HasBracketRight;
result.accel.postfix_set_ops[2] = MD_ExprOprFromKindString(op_table, MD_ExprOprKind_Postfix, MD_S8Lit("{}"));
result.accel.postfix_set_flags[2] = MD_NodeFlag_HasBraceLeft | MD_NodeFlag_HasBraceRight;
result.accel.postfix_set_ops[3] = MD_ExprOprFromKindString(op_table, MD_ExprOprKind_Postfix, MD_S8Lit("[)"));
result.accel.postfix_set_flags[3] = MD_NodeFlag_HasBracketLeft | MD_NodeFlag_HasParenRight;
result.accel.postfix_set_ops[4] = MD_ExprOprFromKindString(op_table, MD_ExprOprKind_Postfix, MD_S8Lit("(]"));
result.accel.postfix_set_flags[4] = MD_NodeFlag_HasParenLeft | MD_NodeFlag_HasBracketRight;
@@ -3713,7 +3711,7 @@ MD_ExprParse_MinPrecedence(MD_Arena *arena, MD_ExprParseCtx *ctx,
break;
}
}
else
{
MD_b32 found_postfix_setlike_operator = 0;
@@ -3731,7 +3729,7 @@ MD_ExprParse_MinPrecedence(MD_Arena *arena, MD_ExprParseCtx *ctx,
break;
}
}
if(!found_postfix_setlike_operator)
{
if(MD_ExprParse_OprConsume(ctx, iter, opl, MD_ExprOprKind_Postfix,
@@ -3744,7 +3742,7 @@ MD_ExprParse_MinPrecedence(MD_Arena *arena, MD_ExprParseCtx *ctx,
break; // NOTE: Due to lack of progress
}
}
}
}