mirror of
https://github.com/Ed94/metadesk.git
synced 2026-08-04 22:58:44 +00:00
merge
This commit is contained in:
@@ -8,6 +8,7 @@ pushd build
|
|||||||
echo.
|
echo.
|
||||||
echo ~~~ Build All Samples ~~~
|
echo ~~~ Build All Samples ~~~
|
||||||
cl %compile_flags% ..\samples\old_style_custom_layer.c
|
cl %compile_flags% ..\samples\old_style_custom_layer.c
|
||||||
|
cl %compile_flags% ..\samples\toy_language\toy_language.c
|
||||||
cl %compile_flags% ..\samples\static_site_generator\static_site_generator.c
|
cl %compile_flags% ..\samples\static_site_generator\static_site_generator.c
|
||||||
cl %compile_flags% ..\samples\output_parse\output_parse.c
|
cl %compile_flags% ..\samples\output_parse\output_parse.c
|
||||||
cl %compile_flags% ..\samples\c_code_generation.c
|
cl %compile_flags% ..\samples\c_code_generation.c
|
||||||
@@ -34,7 +35,7 @@ pushd static_site_generator
|
|||||||
pushd example_site
|
pushd example_site
|
||||||
if not exist generated mkdir generated
|
if not exist generated mkdir generated
|
||||||
pushd generated
|
pushd generated
|
||||||
..\..\..\..\build\static_site_generator.exe --siteinfo ..\site_info.md --pagedir ..\
|
..\..\..\..\build\static_site_generator.exe --siteinfo:..\site_info.md --pagedir:..\
|
||||||
popd
|
popd
|
||||||
popd
|
popd
|
||||||
popd
|
popd
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
|
||||||
|
@proc foo:(x, y, z)
|
||||||
|
{
|
||||||
|
(x + y) * z
|
||||||
|
}
|
||||||
|
|
||||||
|
@proc main:()
|
||||||
|
{
|
||||||
|
foo(10, 20, 30);
|
||||||
|
}
|
||||||
@@ -0,0 +1,243 @@
|
|||||||
|
#include "md.h"
|
||||||
|
#include "md_c_helpers.h"
|
||||||
|
#include "md.c"
|
||||||
|
#include "md_c_helpers.c"
|
||||||
|
|
||||||
|
typedef struct NamespaceNode NamespaceNode;
|
||||||
|
struct NamespaceNode
|
||||||
|
{
|
||||||
|
NamespaceNode *parent;
|
||||||
|
MD_Map symbol_map;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef enum ValueKind
|
||||||
|
{
|
||||||
|
ValueKind_Null,
|
||||||
|
ValueKind_Number,
|
||||||
|
ValueKind_Procedure,
|
||||||
|
}
|
||||||
|
ValueKind;
|
||||||
|
|
||||||
|
typedef struct Value Value;
|
||||||
|
struct Value
|
||||||
|
{
|
||||||
|
ValueKind kind;
|
||||||
|
MD_f64 number;
|
||||||
|
MD_Node *node;
|
||||||
|
};
|
||||||
|
|
||||||
|
static Value
|
||||||
|
MakeValue_Number(MD_f64 v)
|
||||||
|
{
|
||||||
|
Value value = {0};
|
||||||
|
value.kind = ValueKind_Number;
|
||||||
|
value.number = v;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Value
|
||||||
|
MakeValue_Procedure(MD_Node *node)
|
||||||
|
{
|
||||||
|
Value value = {0};
|
||||||
|
value.kind = ValueKind_Procedure;
|
||||||
|
value.node = node;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
InsertValueToNamespace(NamespaceNode *ns, MD_String8 string, Value v)
|
||||||
|
{
|
||||||
|
Value *v_store = malloc(sizeof(*v_store));
|
||||||
|
*v_store = v;
|
||||||
|
MD_StringMap_Insert(&ns->symbol_map, MD_MapCollisionRule_Overwrite, string, v_store);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Value
|
||||||
|
ValueFromString(NamespaceNode *ns, MD_String8 string)
|
||||||
|
{
|
||||||
|
Value v = {0};
|
||||||
|
for(NamespaceNode *n = ns; n; n = n->parent)
|
||||||
|
{
|
||||||
|
MD_MapSlot *slot = MD_StringMap_Lookup(&n->symbol_map, string);
|
||||||
|
if(slot && slot->value)
|
||||||
|
{
|
||||||
|
v = *(Value *)slot->value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Value EvaluateScope(NamespaceNode *ns, MD_Node *code);
|
||||||
|
static Value EvaluateExpr(NamespaceNode *ns, MD_C_Expr *expr);
|
||||||
|
|
||||||
|
static Value
|
||||||
|
EvaluateExpr(NamespaceNode *ns, MD_C_Expr *expr)
|
||||||
|
{
|
||||||
|
Value result = {0};
|
||||||
|
switch(expr->kind)
|
||||||
|
{
|
||||||
|
|
||||||
|
#define BinaryOp(name, op) \
|
||||||
|
case MD_C_ExprKind_##name:\
|
||||||
|
{\
|
||||||
|
Value left = EvaluateExpr(ns, expr->sub[0]);\
|
||||||
|
Value right = EvaluateExpr(ns, expr->sub[1]);\
|
||||||
|
result = MakeValue_Number(left.number op right.number);\
|
||||||
|
}break
|
||||||
|
|
||||||
|
BinaryOp(Add, +);
|
||||||
|
BinaryOp(Subtract, -);
|
||||||
|
BinaryOp(Multiply, *);
|
||||||
|
BinaryOp(Divide, /);
|
||||||
|
|
||||||
|
#undef BinaryOp
|
||||||
|
|
||||||
|
case MD_C_ExprKind_Call:
|
||||||
|
{
|
||||||
|
MD_Node *call = expr->node;
|
||||||
|
Value callee = ValueFromString(ns, expr->sub[0]->node->string);
|
||||||
|
if(!MD_NodeIsNil(callee.node))
|
||||||
|
{
|
||||||
|
//- rjf: find top-level namespace
|
||||||
|
NamespaceNode *top_level_ns = ns;
|
||||||
|
for(NamespaceNode *n = ns; n; n = n->parent)
|
||||||
|
{
|
||||||
|
top_level_ns = n;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- rjf: build namespace for function
|
||||||
|
NamespaceNode args_ns = {0};
|
||||||
|
MD_Node *param = callee.node->first_child;
|
||||||
|
for(MD_Node *arg_first = call->first_child; !MD_NodeIsNil(arg_first); param = param->next)
|
||||||
|
{
|
||||||
|
MD_Node *arg_last = MD_SeekNodeWithFlags(arg_first, MD_NodeFlag_AfterComma|MD_NodeFlag_AfterSemicolon);
|
||||||
|
MD_C_Expr *expr = MD_C_ParseAsExpr(arg_first, arg_last);
|
||||||
|
InsertValueToNamespace(&args_ns, param->string, EvaluateExpr(ns, expr));
|
||||||
|
arg_first = arg_last->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
args_ns.parent = top_level_ns;
|
||||||
|
result = EvaluateScope(&args_ns, callee.node->next);
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case MD_C_ExprKind_Atom:
|
||||||
|
{
|
||||||
|
if(expr->node->flags & MD_NodeFlag_Identifier)
|
||||||
|
{
|
||||||
|
result = ValueFromString(ns, expr->node->string);
|
||||||
|
}
|
||||||
|
else if(expr->node->flags & MD_NodeFlag_Numeric)
|
||||||
|
{
|
||||||
|
result = MakeValue_Number(MD_F64FromString(expr->node->string));
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Value
|
||||||
|
EvaluateScope(NamespaceNode *ns, MD_Node *code)
|
||||||
|
{
|
||||||
|
Value result = {0};
|
||||||
|
|
||||||
|
NamespaceNode local_namespace = {0};
|
||||||
|
local_namespace.parent = ns;
|
||||||
|
|
||||||
|
for(MD_Node *first = code->first_child; !MD_NodeIsNil(first);)
|
||||||
|
{
|
||||||
|
MD_Node *last = MD_SeekNodeWithFlags(first, MD_NodeFlag_AfterSemicolon|MD_NodeFlag_AfterComma);
|
||||||
|
|
||||||
|
//- rjf: declaration
|
||||||
|
if(first == last && first->string.size != 0 && !MD_NodeIsNil(first->first_child))
|
||||||
|
{
|
||||||
|
MD_C_Expr *expr = MD_C_ParseAsExpr(first->first_child, first->last_child);
|
||||||
|
InsertValueToNamespace(&local_namespace, first->string, EvaluateExpr(&local_namespace, expr));
|
||||||
|
}
|
||||||
|
//- rjf: expr
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MD_C_Expr *expr = MD_C_ParseAsExpr(first, last);
|
||||||
|
if(!MD_C_ExprIsNil(expr))
|
||||||
|
{
|
||||||
|
result = EvaluateExpr(&local_namespace, expr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//- rjf: bump
|
||||||
|
first = last->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argument_count, char **arguments)
|
||||||
|
{
|
||||||
|
//- rjf: parse command line
|
||||||
|
MD_CommandLine cmdln = MD_CommandLineFromOptions(MD_StringListFromArgCV(argument_count, arguments));
|
||||||
|
|
||||||
|
//- rjf: parse all input files
|
||||||
|
MD_Node *first_file = MD_NilNode();
|
||||||
|
MD_Node *last_file = MD_NilNode();
|
||||||
|
for(MD_String8Node *n = cmdln.inputs.first; n; n = n->next)
|
||||||
|
{
|
||||||
|
MD_ParseResult parse = MD_ParseWholeFile(n->string);
|
||||||
|
MD_PushSibling(&first_file, &last_file, parse.node);
|
||||||
|
}
|
||||||
|
|
||||||
|
//- rjf: gather top-level symbol map
|
||||||
|
NamespaceNode global_ns_node = {0};
|
||||||
|
for(MD_EachNode(file, first_file))
|
||||||
|
{
|
||||||
|
for(MD_EachNode(top_level, file->first_child))
|
||||||
|
{
|
||||||
|
if(MD_NodeHasTag(top_level, MD_S8Lit("proc")))
|
||||||
|
{
|
||||||
|
InsertValueToNamespace(&global_ns_node, top_level->string, MakeValue_Procedure(top_level));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//- rjf: find `main` procedure
|
||||||
|
Value main_proc = ValueFromString(&global_ns_node, MD_S8Lit("main"));
|
||||||
|
MD_Node *main_code = main_proc.node->next;
|
||||||
|
if(MD_NodeIsNil(main_proc.node))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "no `main` procedure found");
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- rjf: validate that we got `main` code
|
||||||
|
if(MD_NodeIsNil(main_code))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "`main` requires an implementation");
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- rjf: start interpreting at `main`
|
||||||
|
Value result = EvaluateScope(&global_ns_node, main_code);
|
||||||
|
switch(result.kind)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case ValueKind_Null:
|
||||||
|
{
|
||||||
|
printf("[null]\n");
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case ValueKind_Number:
|
||||||
|
{
|
||||||
|
printf("[number] %f\n", result.number);
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case ValueKind_Procedure:
|
||||||
|
{
|
||||||
|
printf("[proc] %.*s\n", MD_StringExpand(result.node->string));
|
||||||
|
}break;
|
||||||
|
}
|
||||||
|
|
||||||
|
end:;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
+31
-26
@@ -18,8 +18,7 @@
|
|||||||
// [x] MD_StringMap_Next, for iterating matching slots in an MD_Map, that all
|
// [x] MD_StringMap_Next, for iterating matching slots in an MD_Map, that all
|
||||||
// share the same key (important in the case of hash collisions)
|
// share the same key (important in the case of hash collisions)
|
||||||
// [x] Helper for making a reference for a node, e.g. MD_ReferenceFromNode
|
// [x] Helper for making a reference for a node, e.g. MD_ReferenceFromNode
|
||||||
// [ ] Organization decision for C generator helpers: splitting from md.h? file name? folder?
|
// [x] Organization decision for C generator helpers: splitting from md.h? file name? folder?
|
||||||
|
|
||||||
|
|
||||||
// NOTE(allen): "Plugin" functionality
|
// NOTE(allen): "Plugin" functionality
|
||||||
//
|
//
|
||||||
@@ -132,9 +131,6 @@
|
|||||||
# define MD_ARCH_32BIT 1
|
# define MD_ARCH_32BIT 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// NOTE(allen): Review @rjf; Building in C++
|
|
||||||
// Added language cracking. Handy for a few pesky problems that can't be solved
|
|
||||||
// strictly within the intersection of C & C++
|
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
# define MD_LANG_CPP 1
|
# define MD_LANG_CPP 1
|
||||||
#else
|
#else
|
||||||
@@ -195,12 +191,6 @@
|
|||||||
# define MD_ZERO_STRUCT {0}
|
# define MD_ZERO_STRUCT {0}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// NOTE(allen): Review @rjf; Building in C++
|
|
||||||
// In order to link to C functions from C++ code, we need to mark them as using
|
|
||||||
// C linkage. In particular I mean FindFirstFileA, FindNextFileA right now.
|
|
||||||
// We don't necessarily need to apply this to the DD functions if the user is
|
|
||||||
// building from source, so I haven't done that.
|
|
||||||
|
|
||||||
#if MD_LANG_C
|
#if MD_LANG_C
|
||||||
# define MD_C_LINKAGE_BEGIN
|
# define MD_C_LINKAGE_BEGIN
|
||||||
# define MD_C_LINKAGE_END
|
# define MD_C_LINKAGE_END
|
||||||
@@ -213,8 +203,6 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
// NOTE(allen): Review @rjf; Building in C++
|
|
||||||
// In C++ compiler I have to include this to get memset and memcpy to compile
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
typedef int8_t MD_i8;
|
typedef int8_t MD_i8;
|
||||||
@@ -525,12 +513,22 @@ struct MD_ParseResult
|
|||||||
};
|
};
|
||||||
|
|
||||||
//~ Command line parsing helper types.
|
//~ Command line parsing helper types.
|
||||||
|
|
||||||
|
typedef struct MD_CommandLineOption MD_CommandLineOption;
|
||||||
|
struct MD_CommandLineOption
|
||||||
|
{
|
||||||
|
MD_CommandLineOption *next;
|
||||||
|
MD_String8 name;
|
||||||
|
MD_String8List values;
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct MD_CommandLine MD_CommandLine;
|
typedef struct MD_CommandLine MD_CommandLine;
|
||||||
struct MD_CommandLine
|
struct MD_CommandLine
|
||||||
{
|
{
|
||||||
// TODO(rjf): Linked-list vs. array?
|
MD_String8List arguments;
|
||||||
MD_String8 *arguments;
|
MD_String8List inputs;
|
||||||
int argument_count;
|
MD_CommandLineOption *first_option;
|
||||||
|
MD_CommandLineOption *last_option;
|
||||||
};
|
};
|
||||||
|
|
||||||
//~ File system access types.
|
//~ File system access types.
|
||||||
@@ -649,21 +647,27 @@ MD_FUNCTION MD_MapSlot* MD_MapNextString(MD_MapSlot *slot, MD_String8 key);
|
|||||||
MD_FUNCTION MD_MapSlot* MD_MapNextPtr(MD_MapSlot *slot, void *key);
|
MD_FUNCTION MD_MapSlot* MD_MapNextPtr(MD_MapSlot *slot, void *key);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//~ String-To-Pointer Table
|
|
||||||
|
//~ Map Table Data Structure
|
||||||
|
|
||||||
|
MD_FUNCTION MD_u64 MD_HashPointer(void *p);
|
||||||
|
|
||||||
|
//- String-To-Pointer Table
|
||||||
MD_FUNCTION MD_MapSlot * MD_StringMap_Lookup(MD_Map *table, MD_String8 string);
|
MD_FUNCTION MD_MapSlot * MD_StringMap_Lookup(MD_Map *table, MD_String8 string);
|
||||||
MD_FUNCTION MD_b32 MD_StringMap_Insert(MD_Map *table, MD_MapCollisionRule collision_rule, MD_String8 string, void *value);
|
MD_FUNCTION MD_b32 MD_StringMap_Insert(MD_Map *table, MD_MapCollisionRule collision_rule, MD_String8 string, void *value);
|
||||||
MD_FUNCTION MD_MapSlot * MD_StringMap_Next(MD_MapSlot *slot, MD_String8 key);
|
MD_FUNCTION MD_MapSlot * MD_StringMap_Next(MD_MapSlot *slot, MD_String8 key);
|
||||||
|
|
||||||
//~ Pointer-To-Pointer Table
|
//- Pointer-To-Pointer Table
|
||||||
MD_FUNCTION MD_MapSlot *MD_PtrMap_Lookup(MD_Map *map, void *key);
|
MD_FUNCTION MD_MapSlot *MD_PtrMap_Lookup(MD_Map *map, void *key);
|
||||||
MD_FUNCTION MD_b32 MD_PtrMap_Insert(MD_Map *map, MD_MapCollisionRule collision_rule, void *key, void *value);
|
MD_FUNCTION MD_b32 MD_PtrMap_Insert(MD_Map *map, MD_MapCollisionRule collision_rule, void *key, void *value);
|
||||||
|
|
||||||
//~ Parsing
|
//~ Parsing
|
||||||
|
|
||||||
MD_FUNCTION MD_b32 MD_TokenKindIsWhitespace(MD_TokenKind kind);
|
MD_FUNCTION MD_b32 MD_TokenKindIsWhitespace(MD_TokenKind kind);
|
||||||
MD_FUNCTION MD_b32 MD_TokenKindIsComment(MD_TokenKind kind);
|
MD_FUNCTION MD_b32 MD_TokenKindIsComment(MD_TokenKind kind);
|
||||||
MD_FUNCTION MD_b32 MD_TokenKindIsRegular(MD_TokenKind kind);
|
MD_FUNCTION MD_b32 MD_TokenKindIsRegular(MD_TokenKind kind);
|
||||||
MD_FUNCTION MD_ParseCtx MD_Parse_InitializeCtx(MD_String8 filename, MD_String8 contents);
|
|
||||||
|
|
||||||
|
MD_FUNCTION MD_ParseCtx MD_Parse_InitializeCtx(MD_String8 filename, MD_String8 contents);
|
||||||
MD_FUNCTION void MD_Parse_Bump(MD_ParseCtx *ctx, MD_Token token);
|
MD_FUNCTION void MD_Parse_Bump(MD_ParseCtx *ctx, MD_Token token);
|
||||||
MD_FUNCTION void MD_Parse_BumpNext(MD_ParseCtx *ctx);
|
MD_FUNCTION void MD_Parse_BumpNext(MD_ParseCtx *ctx);
|
||||||
MD_FUNCTION MD_Token MD_Parse_LexNext(MD_ParseCtx *ctx);
|
MD_FUNCTION MD_Token MD_Parse_LexNext(MD_ParseCtx *ctx);
|
||||||
@@ -709,10 +713,13 @@ MD_FUNCTION MD_Node * MD_TagFromString(MD_Node *node, MD_String8 tag_string);
|
|||||||
MD_FUNCTION MD_Node * MD_ChildFromIndex(MD_Node *node, int n);
|
MD_FUNCTION MD_Node * MD_ChildFromIndex(MD_Node *node, int n);
|
||||||
MD_FUNCTION MD_Node * MD_TagFromIndex(MD_Node *node, int n);
|
MD_FUNCTION MD_Node * MD_TagFromIndex(MD_Node *node, int n);
|
||||||
MD_FUNCTION MD_Node * MD_TagArgFromIndex(MD_Node *node, MD_String8 tag_string, int n);
|
MD_FUNCTION MD_Node * MD_TagArgFromIndex(MD_Node *node, MD_String8 tag_string, int n);
|
||||||
|
MD_FUNCTION MD_Node * MD_TagArgFromString(MD_Node *node, MD_String8 tag_string, MD_String8 arg_string);
|
||||||
MD_FUNCTION MD_b32 MD_NodeHasTag(MD_Node *node, MD_String8 tag_string);
|
MD_FUNCTION MD_b32 MD_NodeHasTag(MD_Node *node, MD_String8 tag_string);
|
||||||
MD_FUNCTION MD_i64 MD_ChildCountFromNode(MD_Node *node);
|
MD_FUNCTION MD_i64 MD_ChildCountFromNode(MD_Node *node);
|
||||||
MD_FUNCTION MD_i64 MD_TagCountFromNode(MD_Node *node);
|
MD_FUNCTION MD_i64 MD_TagCountFromNode(MD_Node *node);
|
||||||
MD_FUNCTION MD_Node * MD_Deref(MD_Node *node);
|
MD_FUNCTION MD_Node * MD_Deref(MD_Node *node);
|
||||||
|
MD_FUNCTION MD_Node * MD_SeekNodeWithFlags(MD_Node *start, MD_NodeFlags one_past_last_flags);
|
||||||
|
|
||||||
// NOTE(rjf): For-Loop Helpers
|
// NOTE(rjf): For-Loop Helpers
|
||||||
#define MD_EachNode(it, first) MD_Node *it = (first); !MD_NodeIsNil(it); it = it->next
|
#define MD_EachNode(it, first) MD_Node *it = (first); !MD_NodeIsNil(it); it = it->next
|
||||||
#define MD_EachNodeRef(it, first) MD_Node *it##_r = (first), *it = MD_Deref(it##_r); \
|
#define MD_EachNodeRef(it, first) MD_Node *it##_r = (first), *it = MD_Deref(it##_r); \
|
||||||
@@ -731,13 +738,11 @@ MD_FUNCTION MD_b32 MD_NodeDeepMatch(MD_Node *a, MD_Node *b, MD_MatchFlags node_f
|
|||||||
MD_FUNCTION void MD_OutputTree(FILE *file, MD_Node *node);
|
MD_FUNCTION void MD_OutputTree(FILE *file, MD_Node *node);
|
||||||
|
|
||||||
//~ Command Line Argument Helper
|
//~ Command Line Argument Helper
|
||||||
MD_FUNCTION MD_CommandLine MD_CommandLine_Start(int argument_count, char **arguments);
|
MD_FUNCTION MD_String8List MD_StringListFromArgCV(int argument_count, char **arguments);
|
||||||
MD_FUNCTION MD_b32 MD_CommandLine_Flag(MD_CommandLine *cmdln, MD_String8 string);
|
MD_FUNCTION MD_CommandLine MD_CommandLineFromOptions(MD_String8List options);
|
||||||
MD_FUNCTION MD_b32 MD_CommandLine_FlagStrings(MD_CommandLine *cmdln, MD_String8 string, int out_count, MD_String8 *out);
|
MD_FUNCTION MD_String8List MD_CommandLineOptionValues(MD_CommandLine cmdln, MD_String8 name);
|
||||||
MD_FUNCTION MD_b32 MD_CommandLine_FlagIntegers(MD_CommandLine *cmdln, MD_String8 string, int out_count, MD_i64 *out);
|
MD_FUNCTION MD_b32 MD_CommandLineOptionPassed(MD_CommandLine cmdln, MD_String8 name);
|
||||||
MD_FUNCTION MD_b32 MD_CommandLine_FlagString(MD_CommandLine *cmdln, MD_String8 string, MD_String8 *out);
|
MD_FUNCTION MD_i64 MD_CommandLineOptionI64(MD_CommandLine cmdln, MD_String8 name);
|
||||||
MD_FUNCTION MD_b32 MD_CommandLine_FlagInteger(MD_CommandLine *cmdln, MD_String8 string, MD_i64 *out);
|
|
||||||
MD_FUNCTION MD_b32 MD_CommandLine_Increment(MD_CommandLine *cmdln, MD_String8 **string_ptr);
|
|
||||||
|
|
||||||
//~ File System
|
//~ File System
|
||||||
MD_FUNCTION MD_String8 MD_LoadEntireFile(MD_String8 filename);
|
MD_FUNCTION MD_String8 MD_LoadEntireFile(MD_String8 filename);
|
||||||
|
|||||||
+21
-2
@@ -212,7 +212,13 @@ MD_PRIVATE_FUNCTION_IMPL MD_b32
|
|||||||
_MD_NodeParse_ConsumeSet(_MD_NodeParseCtx *ctx, MD_Node **out)
|
_MD_NodeParse_ConsumeSet(_MD_NodeParseCtx *ctx, MD_Node **out)
|
||||||
{
|
{
|
||||||
MD_b32 result = 0;
|
MD_b32 result = 0;
|
||||||
if(!MD_NodeIsNil(ctx->at->first_child))
|
if(!MD_NodeIsNil(ctx->at->first_child) ||
|
||||||
|
ctx->at->flags & MD_NodeFlag_ParenLeft ||
|
||||||
|
ctx->at->flags & MD_NodeFlag_ParenRight ||
|
||||||
|
ctx->at->flags & MD_NodeFlag_BracketLeft ||
|
||||||
|
ctx->at->flags & MD_NodeFlag_BracketRight ||
|
||||||
|
ctx->at->flags & MD_NodeFlag_BraceLeft ||
|
||||||
|
ctx->at->flags & MD_NodeFlag_BraceRight)
|
||||||
{
|
{
|
||||||
if(out)
|
if(out)
|
||||||
{
|
{
|
||||||
@@ -313,6 +319,19 @@ _MD_ParseUnaryExpr(_MD_NodeParseCtx *ctx)
|
|||||||
result = MD_C_MakeExpr(node, MD_C_ExprKind_BoolNot, 0, _MD_ParseExpr(ctx));
|
result = MD_C_MakeExpr(node, MD_C_ExprKind_BoolNot, 0, _MD_ParseExpr(ctx));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE(rjf): Post-Unary Sets (calls and subscripts)
|
||||||
|
if(_MD_NodeParse_ConsumeSet(ctx, &set))
|
||||||
|
{
|
||||||
|
if(set->flags & MD_NodeFlag_ParenLeft && set->flags & MD_NodeFlag_ParenRight)
|
||||||
|
{
|
||||||
|
result = MD_C_MakeExpr(set, MD_C_ExprKind_Call, result, 0);
|
||||||
|
}
|
||||||
|
else if(set->flags & MD_NodeFlag_BracketLeft && set->flags & MD_NodeFlag_BracketRight)
|
||||||
|
{
|
||||||
|
result = MD_C_MakeExpr(set, MD_C_ExprKind_Subscript, result, MD_C_ParseAsExpr(set->first_child, set->last_child));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -456,7 +475,7 @@ MD_C_EvaluateExpr_F64(MD_C_Expr *expr)
|
|||||||
MD_f64 result = 0;
|
MD_f64 result = 0;
|
||||||
switch(expr->kind)
|
switch(expr->kind)
|
||||||
{
|
{
|
||||||
#define _MD_BinaryOp(name, op) case MD_C_ExprKind_##name: { result = MD_C_EvaluateExpr_I64(expr->sub[0]) op MD_C_EvaluateExpr_F64(expr->sub[1]); }break
|
#define _MD_BinaryOp(name, op) case MD_C_ExprKind_##name: { result = MD_C_EvaluateExpr_F64(expr->sub[0]) op MD_C_EvaluateExpr_F64(expr->sub[1]); }break
|
||||||
_MD_BinaryOp(Add, +);
|
_MD_BinaryOp(Add, +);
|
||||||
_MD_BinaryOp(Subtract, -);
|
_MD_BinaryOp(Subtract, -);
|
||||||
_MD_BinaryOp(Multiply, *);
|
_MD_BinaryOp(Multiply, *);
|
||||||
|
|||||||
+585
-445
File diff suppressed because it is too large
Load Diff
@@ -593,5 +593,53 @@ int main(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Test("Node-With-Flags Seeking")
|
||||||
|
{
|
||||||
|
|
||||||
|
{
|
||||||
|
MD_ParseResult parse = MD_ParseOneNode(MD_S8Lit(""), MD_S8Lit("foo:{x y z; a b c}"));
|
||||||
|
MD_Node *node = parse.node;
|
||||||
|
MD_Node *group_first = node->first_child;
|
||||||
|
MD_Node *group_last = MD_SeekNodeWithFlags(group_first, MD_NodeFlag_AfterSemicolon);
|
||||||
|
|
||||||
|
TestResult(MD_StringMatch(group_first->string, MD_S8Lit("x"), 0));
|
||||||
|
TestResult(MD_StringMatch(group_first->next->string, MD_S8Lit("y"), 0));
|
||||||
|
TestResult(MD_StringMatch(group_last->string, MD_S8Lit("z"), 0));
|
||||||
|
|
||||||
|
group_first = group_last->next;
|
||||||
|
group_last = MD_SeekNodeWithFlags(group_first, MD_NodeFlag_AfterSemicolon);
|
||||||
|
|
||||||
|
TestResult(MD_StringMatch(group_first->string, MD_S8Lit("a"), 0));
|
||||||
|
TestResult(MD_StringMatch(group_first->next->string, MD_S8Lit("b"), 0));
|
||||||
|
TestResult(MD_StringMatch(group_last->string, MD_S8Lit("c"), 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
MD_ParseResult parse = MD_ParseOneNode(MD_S8Lit(""), MD_S8Lit("foo:{a b c , d e f , g h i}"));
|
||||||
|
MD_Node *node = parse.node;
|
||||||
|
MD_Node *group_first = 0;
|
||||||
|
MD_Node *group_last = 0;
|
||||||
|
|
||||||
|
group_first = node->first_child;
|
||||||
|
group_last = MD_SeekNodeWithFlags(group_first, MD_NodeFlag_AfterComma);
|
||||||
|
TestResult(MD_StringMatch(group_first->string, MD_S8Lit("a"), 0));
|
||||||
|
TestResult(MD_StringMatch(group_first->next->string, MD_S8Lit("b"), 0));
|
||||||
|
TestResult(MD_StringMatch(group_last->string, MD_S8Lit("c"), 0));
|
||||||
|
|
||||||
|
group_first = group_last->next;
|
||||||
|
group_last = MD_SeekNodeWithFlags(group_first, MD_NodeFlag_AfterComma);
|
||||||
|
TestResult(MD_StringMatch(group_first->string, MD_S8Lit("d"), 0));
|
||||||
|
TestResult(MD_StringMatch(group_first->next->string, MD_S8Lit("e"), 0));
|
||||||
|
TestResult(MD_StringMatch(group_last->string, MD_S8Lit("f"), 0));
|
||||||
|
|
||||||
|
group_first = group_last->next;
|
||||||
|
group_last = MD_SeekNodeWithFlags(group_first, MD_NodeFlag_AfterComma);
|
||||||
|
TestResult(MD_StringMatch(group_first->string, MD_S8Lit("g"), 0));
|
||||||
|
TestResult(MD_StringMatch(group_first->next->string, MD_S8Lit("h"), 0));
|
||||||
|
TestResult(MD_StringMatch(group_last->string, MD_S8Lit("i"), 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user