mirror of
https://github.com/Ed94/metadesk.git
synced 2026-07-09 11:21:37 -07:00
organize out C helpers
This commit is contained in:
@@ -2,7 +2,10 @@
|
||||
// and generates valid C code from it.
|
||||
|
||||
#include "md.h"
|
||||
#include "md_c_helpers.h"
|
||||
|
||||
#include "md.c"
|
||||
#include "md_c_helpers.c"
|
||||
|
||||
int main(int argument_count, char **arguments)
|
||||
{
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
#include "md.h"
|
||||
#include "md_c_helpers.h"
|
||||
|
||||
#include "md.c"
|
||||
#include "md_c_helpers.c"
|
||||
|
||||
static MD_Map MapFromChildren(MD_Node *node)
|
||||
{
|
||||
|
||||
@@ -26,15 +26,18 @@
|
||||
<div class="page_content">
|
||||
<div class="standalone_link_container"><a class="link" href="blog_main.html">← Back</a></div><h1 class="title">Test Blog #1</h1><h2 class="subtitle">This is my test blog.</h2><h3 class="date">30 November 2020</h3><h2 class="subtitle">Section 1</h2>
|
||||
<p class="paragraph">
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse ut ornare neque, vitae finibus leo. Praesent pulvinar, urna id lobortis iaculis, velit turpis luctus tortor, quis malesuada neque neque vitae turpis. Phasellus id molestie elit. Sed elementum ipsum a ligula semper, at varius augue rutrum. Pellentesque fringilla, orci nec fringilla finibus, turpis lacus vehicula elit, nec bibendum magna est quis massa. Aliquam efficitur facilisis nibh, ut sodales sapien scelerisque nec. Integer justo sem, pellentesque et ante imperdiet, interdum placerat sem.</p>
|
||||
<p class="paragraph">Nunc hendrerit lobortis commodo. Morbi felis quam, fermentum vitae libero vitae, fermentum sodales quam. Nulla bibendum tellus quis lorem sollicitudin pretium. Etiam commodo ex eget aliquet porta. In sit amet dui eleifend, mattis sem nec, tristique erat. Morbi malesuada fringilla bibendum. Integer odio ex, cursus a sodales quis, vehicula non dolor.</p>
|
||||
<p class="paragraph">Praesent vitae pharetra felis. Curabitur non ex non nunc pretium feugiat eu sit amet turpis. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aenean blandit ante leo. Vivamus iaculis mi vel sem tincidunt maximus. Aenean elementum ipsum non laoreet semper. Morbi non felis interdum lectus pulvinar mollis id non purus. Nullam eu ipsum ut turpis aliquam feugiat at non tellus. Suspendisse ornare erat quis enim ullamcorper, at rhoncus nulla suscipit.
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse ut ornare neque, vitae finibus leo. Praesent pulvinar, urna id lobortis iaculis, velit turpis luctus tortor, quis malesuada neque neque vitae turpis. Phasellus id molestie elit. Sed elementum ipsum a ligula semper, at varius augue rutrum. Pellentesque fringilla, orci nec fringilla finibus, turpis lacus vehicula elit, nec bibendum magna est quis massa. Aliquam efficitur facilisis nibh, ut sodales sapien scelerisque nec. Integer justo sem, pellentesque et ante imperdiet, interdum placerat sem.
|
||||
|
||||
Nunc hendrerit lobortis commodo. Morbi felis quam, fermentum vitae libero vitae, fermentum sodales quam. Nulla bibendum tellus quis lorem sollicitudin pretium. Etiam commodo ex eget aliquet porta. In sit amet dui eleifend, mattis sem nec, tristique erat. Morbi malesuada fringilla bibendum. Integer odio ex, cursus a sodales quis, vehicula non dolor.
|
||||
|
||||
Praesent vitae pharetra felis. Curabitur non ex non nunc pretium feugiat eu sit amet turpis. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aenean blandit ante leo. Vivamus iaculis mi vel sem tincidunt maximus. Aenean elementum ipsum non laoreet semper. Morbi non felis interdum lectus pulvinar mollis id non purus. Nullam eu ipsum ut turpis aliquam feugiat at non tellus. Suspendisse ornare erat quis enim ullamcorper, at rhoncus nulla suscipit.
|
||||
</p>
|
||||
<div class="img_container"><img class="img" src="test.png"></img></div>
|
||||
<h2 class="subtitle">Section 2</h2>
|
||||
<p class="paragraph">
|
||||
Aliquam quis diam at sem interdum imperdiet. Nunc imperdiet ligula tempus nibh semper mattis. Suspendisse fringilla molestie semper. Sed felis dolor, vehicula et tempus sed, porttitor finibus lacus. Pellentesque egestas ex finibus, facilisis tellus suscipit, accumsan turpis. Ut imperdiet vitae nisl eget vestibulum. Donec eu bibendum erat, id maximus magna. Vivamus quis rhoncus justo. Morbi eget commodo lorem, vulputate varius ipsum. Interdum et malesuada fames ac ante ipsum primis in faucibus. Integer accumsan, sem vel rutrum cursus, odio enim sodales leo, sit amet rutrum odio purus at nisi. Fusce iaculis ante id nunc volutpat tincidunt. Duis nec tincidunt ipsum. Fusce vitae odio ac velit sollicitudin maximus. Vestibulum ante dui, varius auctor ante eu, gravida laoreet justo.</p>
|
||||
<p class="paragraph">Vivamus dignissim mauris nec turpis convallis, vitae pellentesque sapien faucibus. Phasellus eu euismod elit, sit amet vehicula diam. Curabitur sit amet leo magna. In est erat, congue vel euismod id, venenatis vitae mauris. Vestibulum sit amet leo eget leo ornare feugiat. Interdum et malesuada fames ac ante ipsum primis in faucibus. Vivamus at efficitur ex, a mattis lorem. Maecenas blandit tincidunt tortor vel cursus. In in purus a nisi pretium venenatis in ut lacus. Maecenas venenatis rutrum laoreet. Donec aliquam leo vel risus cursus, placerat pretium lacus fringilla. Suspendisse ut porttitor mauris.
|
||||
Aliquam quis diam at sem interdum imperdiet. Nunc imperdiet ligula tempus nibh semper mattis. Suspendisse fringilla molestie semper. Sed felis dolor, vehicula et tempus sed, porttitor finibus lacus. Pellentesque egestas ex finibus, facilisis tellus suscipit, accumsan turpis. Ut imperdiet vitae nisl eget vestibulum. Donec eu bibendum erat, id maximus magna. Vivamus quis rhoncus justo. Morbi eget commodo lorem, vulputate varius ipsum. Interdum et malesuada fames ac ante ipsum primis in faucibus. Integer accumsan, sem vel rutrum cursus, odio enim sodales leo, sit amet rutrum odio purus at nisi. Fusce iaculis ante id nunc volutpat tincidunt. Duis nec tincidunt ipsum. Fusce vitae odio ac velit sollicitudin maximus. Vestibulum ante dui, varius auctor ante eu, gravida laoreet justo.
|
||||
|
||||
Vivamus dignissim mauris nec turpis convallis, vitae pellentesque sapien faucibus. Phasellus eu euismod elit, sit amet vehicula diam. Curabitur sit amet leo magna. In est erat, congue vel euismod id, venenatis vitae mauris. Vestibulum sit amet leo eget leo ornare feugiat. Interdum et malesuada fames ac ante ipsum primis in faucibus. Vivamus at efficitur ex, a mattis lorem. Maecenas blandit tincidunt tortor vel cursus. In in purus a nisi pretium venenatis in ut lacus. Maecenas venenatis rutrum laoreet. Donec aliquam leo vel risus cursus, placerat pretium lacus fringilla. Suspendisse ut porttitor mauris.
|
||||
</p>
|
||||
<iframe width="560" height="315" src="https://www.youtube.com/embed/BjdY1eXB6cY" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
|
||||
<h2 class="subtitle">Section 3</h2>
|
||||
|
||||
@@ -26,9 +26,11 @@
|
||||
<div class="page_content">
|
||||
<div class="standalone_link_container"><a class="link" href="blog_main.html">← Back</a></div><h1 class="title">Hello, Again!</h1><h2 class="subtitle">This is another test blog.</h2><h3 class="date">28 November 2020</h3><h2 class="subtitle">Section 1</h2>
|
||||
<p class="paragraph">
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse ut ornare neque, vitae finibus leo. Praesent pulvinar, urna id lobortis iaculis, velit turpis luctus tortor, quis malesuada neque neque vitae turpis. Phasellus id molestie elit. Sed elementum ipsum a ligula semper, at varius augue rutrum. Pellentesque fringilla, orci nec fringilla finibus, turpis lacus vehicula elit, nec bibendum magna est quis massa. Aliquam efficitur facilisis nibh, ut sodales sapien scelerisque nec. Integer justo sem, pellentesque et ante imperdiet, interdum placerat sem.</p>
|
||||
<p class="paragraph">Nunc hendrerit lobortis commodo. Morbi felis quam, fermentum vitae libero vitae, fermentum sodales quam. Nulla bibendum tellus quis lorem sollicitudin pretium. Etiam commodo ex eget aliquet porta. In sit amet dui eleifend, mattis sem nec, tristique erat. Morbi malesuada fringilla bibendum. Integer odio ex, cursus a sodales quis, vehicula non dolor.</p>
|
||||
<p class="paragraph">Praesent vitae pharetra felis. Curabitur non ex non nunc pretium feugiat eu sit amet turpis. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aenean blandit ante leo. Vivamus iaculis mi vel sem tincidunt maximus. Aenean elementum ipsum non laoreet semper. Morbi non felis interdum lectus pulvinar mollis id non purus. Nullam eu ipsum ut turpis aliquam feugiat at non tellus. Suspendisse ornare erat quis enim ullamcorper, at rhoncus nulla suscipit.
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse ut ornare neque, vitae finibus leo. Praesent pulvinar, urna id lobortis iaculis, velit turpis luctus tortor, quis malesuada neque neque vitae turpis. Phasellus id molestie elit. Sed elementum ipsum a ligula semper, at varius augue rutrum. Pellentesque fringilla, orci nec fringilla finibus, turpis lacus vehicula elit, nec bibendum magna est quis massa. Aliquam efficitur facilisis nibh, ut sodales sapien scelerisque nec. Integer justo sem, pellentesque et ante imperdiet, interdum placerat sem.
|
||||
|
||||
Nunc hendrerit lobortis commodo. Morbi felis quam, fermentum vitae libero vitae, fermentum sodales quam. Nulla bibendum tellus quis lorem sollicitudin pretium. Etiam commodo ex eget aliquet porta. In sit amet dui eleifend, mattis sem nec, tristique erat. Morbi malesuada fringilla bibendum. Integer odio ex, cursus a sodales quis, vehicula non dolor.
|
||||
|
||||
Praesent vitae pharetra felis. Curabitur non ex non nunc pretium feugiat eu sit amet turpis. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aenean blandit ante leo. Vivamus iaculis mi vel sem tincidunt maximus. Aenean elementum ipsum non laoreet semper. Morbi non felis interdum lectus pulvinar mollis id non purus. Nullam eu ipsum ut turpis aliquam feugiat at non tellus. Suspendisse ornare erat quis enim ullamcorper, at rhoncus nulla suscipit.
|
||||
</p>
|
||||
<div class="img_container"><img class="img" src="test.png"></img></div>
|
||||
</div>
|
||||
|
||||
+35
-60
@@ -54,25 +54,25 @@
|
||||
# error architecture not supported yet
|
||||
# endif
|
||||
|
||||
#if _MSC_VER >= 1920
|
||||
#define MD_COMPILER_CL_YEAR 2019
|
||||
#elif _MSC_VER >= 1910
|
||||
#define MD_COMPILER_CL_YEAR 2017
|
||||
#elif _MSC_VER >= 1900
|
||||
#define MD_COMPILER_CL_YEAR 2015
|
||||
#elif _MSC_VER >= 1800
|
||||
#define MD_COMPILER_CL_YEAR 2013
|
||||
#elif _MSC_VER >= 1700
|
||||
#define MD_COMPILER_CL_YEAR 2012
|
||||
#elif _MSC_VER >= 1600
|
||||
#define MD_COMPILER_CL_YEAR 2010
|
||||
#elif _MSC_VER >= 1500
|
||||
#define MD_COMPILER_CL_YEAR 2008
|
||||
#elif _MSC_VER >= 1400
|
||||
#define MD_COMPILER_CL_YEAR 2005
|
||||
#else
|
||||
#define MD_COMPILER_CL_YEAR 0
|
||||
#endif
|
||||
# if _MSC_VER >= 1920
|
||||
# define MD_COMPILER_CL_YEAR 2019
|
||||
# elif _MSC_VER >= 1910
|
||||
# define MD_COMPILER_CL_YEAR 2017
|
||||
# elif _MSC_VER >= 1900
|
||||
# define MD_COMPILER_CL_YEAR 2015
|
||||
# elif _MSC_VER >= 1800
|
||||
# define MD_COMPILER_CL_YEAR 2013
|
||||
# elif _MSC_VER >= 1700
|
||||
# define MD_COMPILER_CL_YEAR 2012
|
||||
# elif _MSC_VER >= 1600
|
||||
# define MD_COMPILER_CL_YEAR 2010
|
||||
# elif _MSC_VER >= 1500
|
||||
# define MD_COMPILER_CL_YEAR 2008
|
||||
# elif _MSC_VER >= 1400
|
||||
# define MD_COMPILER_CL_YEAR 2005
|
||||
# else
|
||||
# define MD_COMPILER_CL_YEAR 0
|
||||
# endif
|
||||
|
||||
#elif defined(__clang__)
|
||||
|
||||
@@ -142,46 +142,46 @@
|
||||
// zeroify
|
||||
|
||||
#if !defined(MD_ARCH_32BIT)
|
||||
#define MD_ARCH_32BIT 0
|
||||
# define MD_ARCH_32BIT 0
|
||||
#endif
|
||||
#if !defined(MD_ARCH_64BIT)
|
||||
#define MD_ARCH_64BIT 0
|
||||
# define MD_ARCH_64BIT 0
|
||||
#endif
|
||||
#if !defined(MD_ARCH_X64)
|
||||
#define MD_ARCH_X64 0
|
||||
# define MD_ARCH_X64 0
|
||||
#endif
|
||||
#if !defined(MD_ARCH_X86)
|
||||
#define MD_ARCH_X86 0
|
||||
# define MD_ARCH_X86 0
|
||||
#endif
|
||||
#if !defined(MD_ARCH_ARM64)
|
||||
#define MD_ARCH_ARM64 0
|
||||
# define MD_ARCH_ARM64 0
|
||||
#endif
|
||||
#if !defined(MD_ARCH_ARM32)
|
||||
#define MD_ARCH_ARM32 0
|
||||
# define MD_ARCH_ARM32 0
|
||||
#endif
|
||||
#if !defined(MD_COMPILER_CL)
|
||||
#define MD_COMPILER_CL 0
|
||||
# define MD_COMPILER_CL 0
|
||||
#endif
|
||||
#if !defined(MD_COMPILER_GCC)
|
||||
#define MD_COMPILER_GCC 0
|
||||
# define MD_COMPILER_GCC 0
|
||||
#endif
|
||||
#if !defined(MD_COMPILER_CLANG)
|
||||
#define MD_COMPILER_CLANG 0
|
||||
# define MD_COMPILER_CLANG 0
|
||||
#endif
|
||||
#if !defined(MD_OS_WINDOWS)
|
||||
#define MD_OS_WINDOWS 0
|
||||
# define MD_OS_WINDOWS 0
|
||||
#endif
|
||||
#if !defined(MD_OS_LINUX)
|
||||
#define MD_OS_LINUX 0
|
||||
# define MD_OS_LINUX 0
|
||||
#endif
|
||||
#if !defined(MD_OS_MAC)
|
||||
#define MD_OS_MAC 0
|
||||
# define MD_OS_MAC 0
|
||||
#endif
|
||||
#if !defined(MD_LANG_C)
|
||||
#define MD_LANG_C 0
|
||||
# define MD_LANG_C 0
|
||||
#endif
|
||||
#if !defined(MD_LANG_CPP)
|
||||
#define MD_LANG_CPP 0
|
||||
# define MD_LANG_CPP 0
|
||||
#endif
|
||||
|
||||
#define MD_FUNCTION
|
||||
@@ -638,9 +638,9 @@ MD_FUNCTION MD_String8 MD_S8(MD_u8 *str, MD_u64 size);
|
||||
#define MD_S8CString(s) MD_S8((MD_u8 *)(s), MD_CalculateCStringLength(s))
|
||||
|
||||
#if MD_LANG_C
|
||||
#define MD_S8Lit(s) (MD_String8){(MD_u8 *)(s), sizeof(s)-1}
|
||||
# define MD_S8Lit(s) (MD_String8){(MD_u8 *)(s), sizeof(s)-1}
|
||||
#elif MD_LANG_CPP
|
||||
#define MD_S8Lit(s) MD_S8((MD_u8*)(s), sizeof(s) - 1)
|
||||
# define MD_S8Lit(s) MD_S8((MD_u8*)(s), sizeof(s) - 1)
|
||||
#endif
|
||||
|
||||
MD_FUNCTION MD_String8 MD_S8Range(MD_u8 *str, MD_u8 *opl);
|
||||
@@ -760,34 +760,9 @@ MD_FUNCTION void MD_NodeMessageF(MD_Node *node, MD_MessageKind kind, char *fmt,
|
||||
MD_FUNCTION MD_b32 MD_NodeMatch(MD_Node *a, MD_Node *b, MD_MatchFlags flags);
|
||||
MD_FUNCTION MD_b32 MD_NodeDeepMatch(MD_Node *a, MD_Node *b, MD_MatchFlags node_flags);
|
||||
|
||||
//~ Expression and Type-Expression Helper
|
||||
MD_FUNCTION MD_Expr * MD_NilExpr(void);
|
||||
MD_FUNCTION MD_b32 MD_ExprIsNil(MD_Expr *expr);
|
||||
MD_FUNCTION MD_ExprKind MD_PreUnaryExprKindFromNode(MD_Node *node);
|
||||
MD_FUNCTION MD_ExprKind MD_BinaryExprKindFromNode(MD_Node *node);
|
||||
MD_FUNCTION MD_ExprPrec MD_ExprPrecFromExprKind(MD_ExprKind kind);
|
||||
MD_FUNCTION MD_Expr * MD_MakeExpr(MD_Node *node, MD_ExprKind kind, MD_Expr *left, MD_Expr *right);
|
||||
MD_FUNCTION MD_Expr * MD_ParseAsExpr(MD_Node *first, MD_Node *last);
|
||||
MD_FUNCTION MD_Expr * MD_ParseAsType(MD_Node *first, MD_Node *last);
|
||||
MD_FUNCTION MD_i64 MD_EvaluateExpr_I64(MD_Expr *expr);
|
||||
MD_FUNCTION MD_f64 MD_EvaluateExpr_F64(MD_Expr *expr);
|
||||
MD_FUNCTION MD_b32 MD_ExprMatch(MD_Expr *a, MD_Expr *b, MD_MatchFlags flags);
|
||||
MD_FUNCTION MD_b32 MD_ExprDeepMatch(MD_Expr *a, MD_Expr *b, MD_MatchFlags flags);
|
||||
|
||||
//~ Generation
|
||||
MD_FUNCTION void MD_OutputTree(FILE *file, MD_Node *node);
|
||||
|
||||
//~ C Language Generation
|
||||
MD_FUNCTION void MD_OutputTree_C_String(FILE *file, MD_Node *node);
|
||||
MD_FUNCTION void MD_OutputTree_C_Struct(FILE *file, MD_Node *node);
|
||||
MD_FUNCTION void MD_OutputTree_C_Decl(FILE *file, MD_Node *node);
|
||||
MD_FUNCTION void MD_Output_C_DeclByNameAndType(FILE *file, MD_String8 name, MD_Expr *type);
|
||||
MD_FUNCTION void MD_OutputExpr(FILE *file, MD_Expr *expr);
|
||||
MD_FUNCTION void MD_OutputExpr_C(FILE *file, MD_Expr *expr);
|
||||
MD_FUNCTION void MD_OutputType(FILE *file, MD_Expr *expr);
|
||||
MD_FUNCTION void MD_OutputType_C_LHS(FILE *file, MD_Expr *type);
|
||||
MD_FUNCTION void MD_OutputType_C_RHS(FILE *file, MD_Expr *type);
|
||||
|
||||
// TODO(allen): needs another pass
|
||||
//~ Command Line Argument Helper
|
||||
MD_FUNCTION MD_CommandLine MD_CommandLine_Start(int argument_count, char **arguments);
|
||||
|
||||
@@ -0,0 +1,688 @@
|
||||
//~ Expression and Type-Expression Helper
|
||||
|
||||
MD_FUNCTION_IMPL MD_Expr *
|
||||
MD_NilExpr(void)
|
||||
{
|
||||
return &_md_nil_expr;
|
||||
}
|
||||
|
||||
MD_FUNCTION_IMPL MD_b32
|
||||
MD_ExprIsNil(MD_Expr *expr)
|
||||
{
|
||||
return expr == 0 || expr == &_md_nil_expr || expr->kind == MD_ExprKind_Nil;
|
||||
}
|
||||
|
||||
typedef enum _MD_ExprKindGroup
|
||||
{
|
||||
_MD_ExprKindGroup_Nil,
|
||||
_MD_ExprKindGroup_Atom,
|
||||
_MD_ExprKindGroup_Binary,
|
||||
_MD_ExprKindGroup_PreUnary,
|
||||
_MD_ExprKindGroup_PostUnary,
|
||||
_MD_ExprKindGroup_Type,
|
||||
}
|
||||
_MD_ExprKindGroup;
|
||||
|
||||
typedef struct _MD_ExprKindMetadata _MD_ExprKindMetadata;
|
||||
struct _MD_ExprKindMetadata
|
||||
{
|
||||
_MD_ExprKindGroup group;
|
||||
MD_ExprPrec prec;
|
||||
char *symbol;
|
||||
char *pre_symbol;
|
||||
char *post_symbol;
|
||||
};
|
||||
|
||||
MD_FUNCTION_IMPL _MD_ExprKindMetadata *
|
||||
_MD_MetadataFromExprKind(MD_ExprKind kind)
|
||||
{
|
||||
// 0: Invalid
|
||||
// 12: (unary) - ~ !
|
||||
// 11: . -> () []
|
||||
// 10: * / %
|
||||
// 9: + -
|
||||
// 8: << >>
|
||||
// 7: < <= > >=
|
||||
// 6: == !=
|
||||
// 5: (bitwise) &
|
||||
// 4: ^
|
||||
// 3: |
|
||||
// 2: &&
|
||||
// 1: ||
|
||||
static _MD_ExprKindMetadata metadata[] =
|
||||
{
|
||||
{_MD_ExprKindGroup_Nil, +0, "NIL", "", "" }, // MD_ExprKind_Nil
|
||||
{_MD_ExprKindGroup_Atom, +0, "NIL", "", "" }, // MD_ExprKind_Atom
|
||||
{_MD_ExprKindGroup_Binary, +11, ".", "", "" }, // MD_ExprKind_Dot
|
||||
{_MD_ExprKindGroup_Binary, +11, "->", "", "" }, // MD_ExprKind_Arrow
|
||||
{_MD_ExprKindGroup_PostUnary, +11, "", "(", ")"}, // MD_ExprKind_Call
|
||||
{_MD_ExprKindGroup_PostUnary, +11, "", "[", "]"}, // MD_ExprKind_Subscript
|
||||
{_MD_ExprKindGroup_PreUnary, +12, "", "*", "" }, // MD_ExprKind_Dereference
|
||||
{_MD_ExprKindGroup_PreUnary, +12, "", "&", "" }, // MD_ExprKind_Reference
|
||||
{_MD_ExprKindGroup_Binary, +9, "+", "", "" }, // MD_ExprKind_Add
|
||||
{_MD_ExprKindGroup_Binary, +9, "-", "", "" }, // MD_ExprKind_Subtract
|
||||
{_MD_ExprKindGroup_Binary, +10, "*", "", "" }, // MD_ExprKind_Multiply
|
||||
{_MD_ExprKindGroup_Binary, +10, "/", "", "" }, // MD_ExprKind_Divide
|
||||
{_MD_ExprKindGroup_Binary, +10, "%", "", "" }, // MD_ExprKind_Mod
|
||||
{_MD_ExprKindGroup_Binary, +6, "==", "", "" }, // MD_ExprKind_IsEqual
|
||||
{_MD_ExprKindGroup_Binary, +6, "!=", "", "" }, // MD_ExprKind_IsNotEqual
|
||||
{_MD_ExprKindGroup_Binary, +7, "<", "", "" }, // MD_ExprKind_LessThan
|
||||
{_MD_ExprKindGroup_Binary, +7, ">", "", "" }, // MD_ExprKind_GreaterThan
|
||||
{_MD_ExprKindGroup_Binary, +7, "<=", "", "" }, // MD_ExprKind_LessThanEqualTo
|
||||
{_MD_ExprKindGroup_Binary, +7, ">=", "", "" }, // MD_ExprKind_GreaterThanEqualTo
|
||||
{_MD_ExprKindGroup_Binary, +2, "&&", "", "" }, // MD_ExprKind_BoolAnd
|
||||
{_MD_ExprKindGroup_Binary, +1, "||", "", "" }, // MD_ExprKind_BoolOr
|
||||
{_MD_ExprKindGroup_PreUnary, +12, "", "!", "" }, // MD_ExprKind_BoolNot
|
||||
{_MD_ExprKindGroup_Binary, +5, "&", "", "" }, // MD_ExprKind_BitAnd
|
||||
{_MD_ExprKindGroup_Binary, +3, "|", "", "" }, // MD_ExprKind_BitOr
|
||||
{_MD_ExprKindGroup_PreUnary, +12, "", "~", "" }, // MD_ExprKind_BitNot
|
||||
{_MD_ExprKindGroup_Binary, +4, "^", "", "" }, // MD_ExprKind_BitXor
|
||||
{_MD_ExprKindGroup_Binary, +8, "<<", "", "" }, // MD_ExprKind_LeftShift
|
||||
{_MD_ExprKindGroup_Binary, +8, ">>", "", "" }, // MD_ExprKind_RightShift
|
||||
{_MD_ExprKindGroup_PreUnary, +12, "", "-", "" }, // MD_ExprKind_Negative
|
||||
{_MD_ExprKindGroup_Type, +0, "*", "", "" }, // MD_ExprKind_Pointer
|
||||
{_MD_ExprKindGroup_Type, +0, "", "[", "]"}, // MD_ExprKind_Array
|
||||
};
|
||||
return &metadata[kind];
|
||||
}
|
||||
|
||||
MD_FUNCTION_IMPL MD_ExprKind
|
||||
MD_PreUnaryExprKindFromNode(MD_Node *node)
|
||||
{
|
||||
MD_ExprKind kind = MD_ExprKind_Nil;
|
||||
// NOTE(rjf): Special-cases for calls/subscripts.
|
||||
if(!MD_NodeIsNil(node->first_child))
|
||||
{
|
||||
if(node->flags & MD_NodeFlag_ParenLeft &&
|
||||
node->flags & MD_NodeFlag_ParenRight)
|
||||
{
|
||||
kind = MD_ExprKind_Call;
|
||||
}
|
||||
else if(node->flags & MD_NodeFlag_BracketLeft &&
|
||||
node->flags & MD_NodeFlag_BracketRight)
|
||||
{
|
||||
kind = MD_ExprKind_Subscript;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(MD_ExprKind kind_it = (MD_ExprKind)0; kind_it < MD_ExprKind_MAX;
|
||||
kind_it = (MD_ExprKind)((int)kind_it + 1))
|
||||
{
|
||||
_MD_ExprKindMetadata *metadata = _MD_MetadataFromExprKind(kind_it);
|
||||
if(metadata->group == _MD_ExprKindGroup_PreUnary)
|
||||
{
|
||||
if(MD_StringMatch(node->string, MD_S8CString(metadata->pre_symbol), 0))
|
||||
{
|
||||
kind = kind_it;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return kind;
|
||||
}
|
||||
|
||||
MD_FUNCTION_IMPL MD_ExprKind
|
||||
MD_BinaryExprKindFromNode(MD_Node *node)
|
||||
{
|
||||
MD_ExprKind kind = MD_ExprKind_Nil;
|
||||
if(node->kind == MD_NodeKind_Label && MD_NodeIsNil(node->first_child))
|
||||
{
|
||||
for(MD_ExprKind kind_it = (MD_ExprKind)0; kind_it < MD_ExprKind_MAX;
|
||||
kind_it = (MD_ExprKind)((int)kind_it + 1))
|
||||
{
|
||||
_MD_ExprKindMetadata *metadata = _MD_MetadataFromExprKind(kind_it);
|
||||
if(metadata->group == _MD_ExprKindGroup_Binary)
|
||||
{
|
||||
if(MD_StringMatch(node->string, MD_S8CString(metadata->symbol), 0))
|
||||
{
|
||||
kind = kind_it;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return kind;
|
||||
}
|
||||
|
||||
MD_FUNCTION_IMPL MD_ExprPrec
|
||||
MD_ExprPrecFromExprKind(MD_ExprKind kind)
|
||||
{
|
||||
_MD_ExprKindMetadata *metadata = _MD_MetadataFromExprKind(kind);
|
||||
return metadata->prec;
|
||||
}
|
||||
|
||||
MD_FUNCTION_IMPL MD_Expr *
|
||||
MD_MakeExpr(MD_Node *node, MD_ExprKind kind, MD_Expr *left, MD_Expr *right)
|
||||
{
|
||||
MD_Expr *expr = _MD_PushArray(MD_Expr, 1);
|
||||
if(expr)
|
||||
{
|
||||
if(left == 0) left = MD_NilExpr();
|
||||
if(right == 0) right = MD_NilExpr();
|
||||
expr->node = node;
|
||||
expr->kind = kind;
|
||||
expr->sub[0] = left;
|
||||
expr->sub[1] = right;
|
||||
}
|
||||
else
|
||||
{
|
||||
expr = MD_NilExpr();
|
||||
}
|
||||
return expr;
|
||||
}
|
||||
|
||||
typedef struct _MD_NodeParseCtx _MD_NodeParseCtx;
|
||||
struct _MD_NodeParseCtx
|
||||
{
|
||||
MD_Node *at;
|
||||
MD_Node *last;
|
||||
MD_Node *one_past_last;
|
||||
};
|
||||
|
||||
MD_PRIVATE_FUNCTION_IMPL MD_b32
|
||||
_MD_NodeParse_ConsumeAtom(_MD_NodeParseCtx *ctx, MD_Node **out)
|
||||
{
|
||||
MD_b32 result = 0;
|
||||
if(ctx->at->kind == MD_NodeKind_Label &&
|
||||
MD_NodeIsNil(ctx->at->first_child))
|
||||
{
|
||||
result = 1;
|
||||
if(out)
|
||||
{
|
||||
*out = ctx->at;
|
||||
}
|
||||
ctx->at = ctx->at->next;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
MD_PRIVATE_FUNCTION_IMPL MD_b32
|
||||
_MD_NodeParse_ConsumeSet(_MD_NodeParseCtx *ctx, MD_Node **out)
|
||||
{
|
||||
MD_b32 result = 0;
|
||||
if(!MD_NodeIsNil(ctx->at->first_child))
|
||||
{
|
||||
if(out)
|
||||
{
|
||||
*out = ctx->at;
|
||||
}
|
||||
ctx->at = ctx->at->next;
|
||||
result = 1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
MD_PRIVATE_FUNCTION_IMPL MD_b32
|
||||
_MD_NodeParse_ConsumeLiteral(_MD_NodeParseCtx *ctx, MD_Node **out)
|
||||
{
|
||||
MD_b32 result = 0;
|
||||
if(ctx->at->flags & MD_NodeFlag_StringLiteral ||
|
||||
ctx->at->flags & MD_NodeFlag_CharLiteral ||
|
||||
ctx->at->flags & MD_NodeFlag_Numeric)
|
||||
{
|
||||
result = 1;
|
||||
if(out)
|
||||
{
|
||||
*out = ctx->at;
|
||||
}
|
||||
ctx->at = ctx->at->next;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
MD_PRIVATE_FUNCTION_IMPL MD_b32
|
||||
_MD_NodeParse_Consume(_MD_NodeParseCtx *ctx, MD_String8 string, MD_Node **out)
|
||||
{
|
||||
MD_b32 result = 0;
|
||||
if(MD_StringMatch(ctx->at->string, string, 0))
|
||||
{
|
||||
result = 1;
|
||||
if(out)
|
||||
{
|
||||
*out = ctx->at;
|
||||
}
|
||||
ctx->at = ctx->at->next;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
MD_PRIVATE_FUNCTION_IMPL void
|
||||
_MD_NodeParse_Next(_MD_NodeParseCtx *ctx)
|
||||
{
|
||||
ctx->at = ctx->at->next;
|
||||
}
|
||||
|
||||
MD_PRIVATE_FUNCTION_IMPL MD_Expr *
|
||||
_MD_ParseExpr_(_MD_NodeParseCtx *ctx, int precedence_in);
|
||||
|
||||
MD_PRIVATE_FUNCTION_IMPL MD_Expr *
|
||||
_MD_ParseExpr(_MD_NodeParseCtx *ctx);
|
||||
|
||||
MD_PRIVATE_FUNCTION_IMPL MD_Expr *
|
||||
_MD_ParseUnaryExpr(_MD_NodeParseCtx *ctx)
|
||||
{
|
||||
MD_Expr *result = MD_NilExpr();
|
||||
MD_Node *set = 0;
|
||||
MD_Node *node = 0;
|
||||
|
||||
// NOTE(rjf): Sub-expression
|
||||
if(_MD_NodeParse_ConsumeSet(ctx, &set))
|
||||
{
|
||||
result = MD_ParseAsExpr(set->first_child, set->last_child);
|
||||
}
|
||||
|
||||
// NOTE(rjf): Literal
|
||||
else if(_MD_NodeParse_ConsumeLiteral(ctx, &node))
|
||||
{
|
||||
result = MD_MakeExpr(node, MD_ExprKind_Atom, 0, 0);
|
||||
}
|
||||
|
||||
// NOTE(rjf): Literal
|
||||
else if(_MD_NodeParse_ConsumeAtom(ctx, &node))
|
||||
{
|
||||
result = MD_MakeExpr(node, MD_ExprKind_Atom, 0, 0);
|
||||
}
|
||||
|
||||
// NOTE(rjf): Negative
|
||||
else if(_MD_NodeParse_Consume(ctx, MD_S8Lit("-"), &node))
|
||||
{
|
||||
result = MD_MakeExpr(node, MD_ExprKind_Negative, 0, _MD_ParseExpr(ctx));
|
||||
}
|
||||
|
||||
// NOTE(rjf): Bitwise Negate
|
||||
else if(_MD_NodeParse_Consume(ctx, MD_S8Lit("~"), &node))
|
||||
{
|
||||
result = MD_MakeExpr(node, MD_ExprKind_BitNot, 0, _MD_ParseExpr(ctx));
|
||||
}
|
||||
|
||||
// NOTE(rjf): Boolean Negate
|
||||
else if(_MD_NodeParse_Consume(ctx, MD_S8Lit("!"), &node))
|
||||
{
|
||||
result = MD_MakeExpr(node, MD_ExprKind_BoolNot, 0, _MD_ParseExpr(ctx));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
MD_PRIVATE_FUNCTION_IMPL MD_Expr *
|
||||
_MD_ParseExpr_(_MD_NodeParseCtx *ctx, int precedence_in)
|
||||
{
|
||||
MD_Expr *expr = _MD_ParseUnaryExpr(ctx);
|
||||
MD_ExprKind expr_kind;
|
||||
if(MD_ExprIsNil(expr))
|
||||
{
|
||||
goto end_parse;
|
||||
}
|
||||
|
||||
expr_kind = MD_BinaryExprKindFromNode(ctx->at);
|
||||
if(expr_kind != MD_ExprKind_Nil)
|
||||
{
|
||||
for(int precedence = MD_ExprPrecFromExprKind(expr_kind);
|
||||
precedence >= precedence_in;
|
||||
precedence -= 1)
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
MD_Node *op_node = ctx->at;
|
||||
expr_kind = MD_BinaryExprKindFromNode(ctx->at);
|
||||
int operator_precedence = MD_ExprPrecFromExprKind(expr_kind);
|
||||
if(operator_precedence != precedence)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if(expr_kind == MD_ExprKind_Nil)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
_MD_NodeParse_Next(ctx);
|
||||
|
||||
MD_Expr *right = _MD_ParseExpr_(ctx, precedence+1);
|
||||
if(MD_ExprIsNil(right))
|
||||
{
|
||||
// TODO(rjf): Error: "Expected right-hand-side of binary expression."
|
||||
goto end_parse;
|
||||
}
|
||||
|
||||
MD_Expr *left = expr;
|
||||
expr = MD_MakeExpr(op_node, expr_kind, left, right);
|
||||
expr->sub[0] = left;
|
||||
expr->sub[1] = right;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
end_parse:;
|
||||
return expr;
|
||||
}
|
||||
|
||||
MD_PRIVATE_FUNCTION_IMPL MD_Expr *
|
||||
_MD_ParseExpr(_MD_NodeParseCtx *ctx)
|
||||
{
|
||||
return _MD_ParseExpr_(ctx, 1);
|
||||
}
|
||||
|
||||
MD_FUNCTION_IMPL MD_Expr *
|
||||
MD_ParseAsExpr(MD_Node *first, MD_Node *last)
|
||||
{
|
||||
_MD_NodeParseCtx ctx_ = { first, last, last->next };
|
||||
_MD_NodeParseCtx *ctx = &ctx_;
|
||||
return _MD_ParseExpr(ctx);
|
||||
}
|
||||
|
||||
MD_FUNCTION_IMPL MD_Expr *
|
||||
MD_ParseAsType(MD_Node *first, MD_Node *last)
|
||||
{
|
||||
MD_Expr *expr = MD_NilExpr();
|
||||
MD_Expr *last_expr = expr;
|
||||
_MD_NodeParseCtx ctx_ = { first, last, last->next };
|
||||
_MD_NodeParseCtx *ctx = &ctx_;
|
||||
#define _MD_PushType(x) if(MD_ExprIsNil(last_expr)) { expr = last_expr = x; } else { last_expr = last_expr->sub[0] = x; }
|
||||
MD_Node *set = 0;
|
||||
MD_Node *ptr = 0;
|
||||
MD_Node *base_type = 0;
|
||||
MD_Node *node = 0;
|
||||
for(;;)
|
||||
{
|
||||
if(_MD_NodeParse_Consume(ctx, MD_S8Lit("*"), &ptr))
|
||||
{
|
||||
MD_Expr *t = MD_MakeExpr(ptr, MD_ExprKind_Pointer, MD_NilExpr(), MD_NilExpr());
|
||||
_MD_PushType(t);
|
||||
}
|
||||
else if(_MD_NodeParse_Consume(ctx, MD_S8Lit("volatile"), &node))
|
||||
{
|
||||
MD_Expr *t = MD_MakeExpr(node, MD_ExprKind_Volatile, MD_NilExpr(), MD_NilExpr());
|
||||
_MD_PushType(t);
|
||||
}
|
||||
else if(_MD_NodeParse_Consume(ctx, MD_S8Lit("const"), &node))
|
||||
{
|
||||
MD_Expr *t = MD_MakeExpr(node, MD_ExprKind_Const, MD_NilExpr(), MD_NilExpr());
|
||||
_MD_PushType(t);
|
||||
}
|
||||
else if(_MD_NodeParse_ConsumeSet(ctx, &set))
|
||||
{
|
||||
MD_Expr *t = MD_MakeExpr(set, MD_ExprKind_Array, MD_NilExpr(), MD_NilExpr());
|
||||
t->sub[1] = MD_ParseAsExpr(set->first_child, set->last_child);
|
||||
_MD_PushType(t);
|
||||
}
|
||||
else if(_MD_NodeParse_ConsumeAtom(ctx, &base_type))
|
||||
{
|
||||
MD_Expr *t = MD_MakeExpr(base_type, MD_ExprKind_Atom, MD_NilExpr(), MD_NilExpr());
|
||||
_MD_PushType(t);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
#undef _MD_PushType
|
||||
return expr;
|
||||
}
|
||||
|
||||
MD_FUNCTION_IMPL MD_i64
|
||||
MD_EvaluateExpr_I64(MD_Expr *expr)
|
||||
{
|
||||
MD_i64 result = 0;
|
||||
switch(expr->kind)
|
||||
{
|
||||
#define _MD_BinaryOp(name, op) case MD_ExprKind_##name: { result = MD_EvaluateExpr_I64(expr->sub[0]) op MD_EvaluateExpr_I64(expr->sub[1]); }break
|
||||
_MD_BinaryOp(Add, +);
|
||||
_MD_BinaryOp(Subtract, -);
|
||||
_MD_BinaryOp(Multiply, *);
|
||||
_MD_BinaryOp(Divide, /);
|
||||
#undef _MD_BinaryOp
|
||||
case MD_ExprKind_Atom: { result = MD_I64FromString(expr->node->string, 10); }break;
|
||||
default: break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
MD_FUNCTION_IMPL MD_f64
|
||||
MD_EvaluateExpr_F64(MD_Expr *expr)
|
||||
{
|
||||
MD_f64 result = 0;
|
||||
switch(expr->kind)
|
||||
{
|
||||
#define _MD_BinaryOp(name, op) case MD_ExprKind_##name: { result = MD_EvaluateExpr_I64(expr->sub[0]) op MD_EvaluateExpr_F64(expr->sub[1]); }break
|
||||
_MD_BinaryOp(Add, +);
|
||||
_MD_BinaryOp(Subtract, -);
|
||||
_MD_BinaryOp(Multiply, *);
|
||||
_MD_BinaryOp(Divide, /);
|
||||
#undef _MD_BinaryOp
|
||||
case MD_ExprKind_Atom: { result = MD_F64FromString(expr->node->string); }break;
|
||||
default: break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
MD_FUNCTION_IMPL MD_b32
|
||||
MD_ExprMatch(MD_Expr *a, MD_Expr *b, MD_MatchFlags flags)
|
||||
{
|
||||
MD_b32 result = 0;
|
||||
if(a->kind == b->kind)
|
||||
{
|
||||
result = 1;
|
||||
if(a->kind == MD_ExprKind_Atom)
|
||||
{
|
||||
result = MD_StringMatch(a->node->string, b->node->string, flags);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
MD_FUNCTION_IMPL MD_b32
|
||||
MD_ExprDeepMatch(MD_Expr *a, MD_Expr *b, MD_MatchFlags flags)
|
||||
{
|
||||
MD_b32 result = MD_ExprMatch(a, b, flags);
|
||||
if(result && !MD_ExprIsNil(a) && !MD_ExprIsNil(b))
|
||||
{
|
||||
result = (MD_ExprDeepMatch(a->sub[0], b->sub[0], flags) &&
|
||||
MD_ExprDeepMatch(a->sub[1], b->sub[1], flags));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//~ C Language Generation
|
||||
|
||||
MD_FUNCTION_IMPL void
|
||||
MD_OutputTree_C_String(FILE *file, MD_Node *node)
|
||||
{
|
||||
fprintf(file, "\"");
|
||||
for(MD_u64 i = 0; i < node->string.size; i += 1)
|
||||
{
|
||||
if(node->string.str[i] == '\n')
|
||||
{
|
||||
fprintf(file, "\\n\"\n\"");
|
||||
}
|
||||
else if(node->string.str[i] == '\r' &&
|
||||
i+1 < node->string.size && node->string.str[i+1] == '\n')
|
||||
{
|
||||
// NOTE(mal): Step over CR when quoting CRLF newlines
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(file, "%c", node->string.str[i]);
|
||||
}
|
||||
}
|
||||
fprintf(file, "\"");
|
||||
}
|
||||
|
||||
MD_FUNCTION_IMPL void
|
||||
MD_OutputTree_C_Struct(FILE *file, MD_Node *node)
|
||||
{
|
||||
if(node)
|
||||
{
|
||||
fprintf(file, "typedef struct %.*s %.*s;\n",
|
||||
MD_StringExpand(node->string),
|
||||
MD_StringExpand(node->string));
|
||||
fprintf(file, "struct %.*s\n{\n", MD_StringExpand(node->string));
|
||||
for(MD_Node *child = node->first_child; !MD_NodeIsNil(child); child = child->next)
|
||||
{
|
||||
MD_OutputTree_C_Decl(file, child);
|
||||
fprintf(file, ";\n");
|
||||
}
|
||||
fprintf(file, "};\n\n");
|
||||
}
|
||||
}
|
||||
|
||||
MD_FUNCTION_IMPL void
|
||||
MD_OutputTree_C_Decl(FILE *file, MD_Node *node)
|
||||
{
|
||||
if(node)
|
||||
{
|
||||
MD_Expr *type = MD_ParseAsType(node->first_child, node->last_child);
|
||||
MD_Output_C_DeclByNameAndType(file, node->string, type);
|
||||
}
|
||||
}
|
||||
|
||||
MD_FUNCTION_IMPL void
|
||||
MD_Output_C_DeclByNameAndType(FILE *file, MD_String8 name, MD_Expr *type)
|
||||
{
|
||||
MD_OutputType_C_LHS(file, type);
|
||||
fprintf(file, " %.*s", MD_StringExpand(name));
|
||||
MD_OutputType_C_RHS(file, type);
|
||||
}
|
||||
|
||||
MD_FUNCTION_IMPL void
|
||||
MD_OutputExpr(FILE *file, MD_Expr *expr)
|
||||
{
|
||||
if(!MD_NodeIsNil(expr->node))
|
||||
{
|
||||
_MD_ExprKindMetadata *metadata = _MD_MetadataFromExprKind(expr->kind);
|
||||
switch(metadata->group)
|
||||
{
|
||||
case _MD_ExprKindGroup_Atom:
|
||||
{
|
||||
fprintf(file, "%.*s", MD_StringExpand(expr->node->string));
|
||||
}break;
|
||||
|
||||
case _MD_ExprKindGroup_Binary:
|
||||
{
|
||||
fprintf(file, "(");
|
||||
MD_OutputExpr(file, expr->sub[0]);
|
||||
fprintf(file, " %s ", metadata->symbol);
|
||||
MD_OutputExpr(file, expr->sub[1]);
|
||||
fprintf(file, ")");
|
||||
}break;
|
||||
|
||||
case _MD_ExprKindGroup_PreUnary:
|
||||
{
|
||||
fprintf(file, "%s", metadata->pre_symbol);
|
||||
fprintf(file, "(");
|
||||
MD_OutputExpr(file, expr->sub[0]);
|
||||
fprintf(file, ")");
|
||||
}break;
|
||||
|
||||
case _MD_ExprKindGroup_PostUnary:
|
||||
{
|
||||
fprintf(file, "(");
|
||||
MD_OutputExpr(file, expr->sub[0]);
|
||||
fprintf(file, ")");
|
||||
fprintf(file, "%s", metadata->post_symbol);
|
||||
}break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MD_FUNCTION_IMPL void
|
||||
MD_OutputExpr_C(FILE *file, MD_Expr *expr)
|
||||
{
|
||||
MD_OutputExpr(file, expr);
|
||||
}
|
||||
|
||||
MD_PRIVATE_FUNCTION_IMPL MD_b32
|
||||
_MD_OutputType_C_NeedsParens(MD_Expr *type)
|
||||
{
|
||||
MD_b32 result = 0;
|
||||
if (type->kind == MD_ExprKind_Pointer &&
|
||||
type->sub[0]->kind == MD_ExprKind_Array)
|
||||
{
|
||||
result = 1;
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
MD_FUNCTION_IMPL void
|
||||
MD_OutputType_C_LHS(FILE *file, MD_Expr *type)
|
||||
{
|
||||
switch (type->kind)
|
||||
{
|
||||
case MD_ExprKind_Atom:
|
||||
{
|
||||
MD_Node *node = type->node;
|
||||
fprintf(file, "%.*s", MD_StringExpand(node->whole_string));
|
||||
}break;
|
||||
|
||||
case MD_ExprKind_Pointer:
|
||||
{
|
||||
MD_OutputType_C_LHS(file, type->sub[0]);
|
||||
if (_MD_OutputType_C_NeedsParens(type))
|
||||
{
|
||||
fprintf(file, "(");
|
||||
}
|
||||
fprintf(file, "*");
|
||||
}break;
|
||||
|
||||
case MD_ExprKind_Array:
|
||||
{
|
||||
MD_OutputType_C_LHS(file, type->sub[0]);
|
||||
if (_MD_OutputType_C_NeedsParens(type))
|
||||
{
|
||||
fprintf(file, "(");
|
||||
}
|
||||
}break;
|
||||
|
||||
case MD_ExprKind_Volatile: { fprintf(file, "volatile "); }break;
|
||||
case MD_ExprKind_Const: { fprintf(file, "const "); }break;
|
||||
|
||||
default:
|
||||
{
|
||||
fprintf(file, "{ unexpected MD_ExprKind (%i) in type info for node \"%.*s\" }",
|
||||
type->kind,
|
||||
MD_StringExpand(type->node->whole_string));
|
||||
}break;
|
||||
}
|
||||
}
|
||||
|
||||
MD_FUNCTION_IMPL void
|
||||
MD_OutputType_C_RHS(FILE *file, MD_Expr *type)
|
||||
{
|
||||
switch (type->kind)
|
||||
{
|
||||
case MD_ExprKind_Atom:
|
||||
{}break;
|
||||
|
||||
case MD_ExprKind_Pointer:
|
||||
{
|
||||
if (_MD_OutputType_C_NeedsParens(type))
|
||||
{
|
||||
fprintf(file, ")");
|
||||
}
|
||||
MD_OutputType_C_RHS(file, type->sub[0]);
|
||||
}break;
|
||||
|
||||
case MD_ExprKind_Array:
|
||||
{
|
||||
if (_MD_OutputType_C_NeedsParens(type))
|
||||
{
|
||||
fprintf(file, ")");
|
||||
}
|
||||
fprintf(file, "[");
|
||||
MD_OutputExpr_C(file, type->sub[1]);
|
||||
fprintf(file, "]");
|
||||
MD_OutputType_C_RHS(file, type->sub[0]);
|
||||
}break;
|
||||
|
||||
case MD_ExprKind_Volatile: { fprintf(file, "volatile "); }break;
|
||||
case MD_ExprKind_Const: { fprintf(file, "const "); }break;
|
||||
|
||||
default:
|
||||
{}break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/* date = April 16th 2021 6:05 pm */
|
||||
|
||||
#ifndef MD_C_HELPERS_H
|
||||
#define MD_C_HELPERS_H
|
||||
|
||||
//~ Expression and Type-Expression Helper
|
||||
MD_FUNCTION MD_Expr * MD_NilExpr(void);
|
||||
MD_FUNCTION MD_b32 MD_ExprIsNil(MD_Expr *expr);
|
||||
MD_FUNCTION MD_ExprKind MD_PreUnaryExprKindFromNode(MD_Node *node);
|
||||
MD_FUNCTION MD_ExprKind MD_BinaryExprKindFromNode(MD_Node *node);
|
||||
MD_FUNCTION MD_ExprPrec MD_ExprPrecFromExprKind(MD_ExprKind kind);
|
||||
MD_FUNCTION MD_Expr * MD_MakeExpr(MD_Node *node, MD_ExprKind kind, MD_Expr *left, MD_Expr *right);
|
||||
MD_FUNCTION MD_Expr * MD_ParseAsExpr(MD_Node *first, MD_Node *last);
|
||||
MD_FUNCTION MD_Expr * MD_ParseAsType(MD_Node *first, MD_Node *last);
|
||||
MD_FUNCTION MD_i64 MD_EvaluateExpr_I64(MD_Expr *expr);
|
||||
MD_FUNCTION MD_f64 MD_EvaluateExpr_F64(MD_Expr *expr);
|
||||
MD_FUNCTION MD_b32 MD_ExprMatch(MD_Expr *a, MD_Expr *b, MD_MatchFlags flags);
|
||||
MD_FUNCTION MD_b32 MD_ExprDeepMatch(MD_Expr *a, MD_Expr *b, MD_MatchFlags flags);
|
||||
|
||||
//~ C Language Generation
|
||||
MD_FUNCTION void MD_OutputTree_C_String(FILE *file, MD_Node *node);
|
||||
MD_FUNCTION void MD_OutputTree_C_Struct(FILE *file, MD_Node *node);
|
||||
MD_FUNCTION void MD_OutputTree_C_Decl(FILE *file, MD_Node *node);
|
||||
MD_FUNCTION void MD_Output_C_DeclByNameAndType(FILE *file, MD_String8 name, MD_Expr *type);
|
||||
MD_FUNCTION void MD_OutputExpr(FILE *file, MD_Expr *expr);
|
||||
MD_FUNCTION void MD_OutputExpr_C(FILE *file, MD_Expr *expr);
|
||||
MD_FUNCTION void MD_OutputType(FILE *file, MD_Expr *expr);
|
||||
MD_FUNCTION void MD_OutputType_C_LHS(FILE *file, MD_Expr *type);
|
||||
MD_FUNCTION void MD_OutputType_C_RHS(FILE *file, MD_Expr *type);
|
||||
|
||||
#endif //MD_C_HELPERS_H
|
||||
@@ -2473,129 +2473,6 @@ MD_GLOBAL MD_Expr _md_nil_expr =
|
||||
{&_md_nil_expr, &_md_nil_expr },
|
||||
};
|
||||
|
||||
MD_FUNCTION_IMPL MD_Expr *
|
||||
MD_NilExpr(void)
|
||||
{
|
||||
return &_md_nil_expr;
|
||||
}
|
||||
|
||||
MD_FUNCTION_IMPL MD_b32
|
||||
MD_ExprIsNil(MD_Expr *expr)
|
||||
{
|
||||
return expr == 0 || expr == &_md_nil_expr || expr->kind == MD_ExprKind_Nil;
|
||||
}
|
||||
|
||||
typedef enum _MD_ExprKindGroup
|
||||
{
|
||||
_MD_ExprKindGroup_Nil,
|
||||
_MD_ExprKindGroup_Atom,
|
||||
_MD_ExprKindGroup_Binary,
|
||||
_MD_ExprKindGroup_PreUnary,
|
||||
_MD_ExprKindGroup_PostUnary,
|
||||
_MD_ExprKindGroup_Type,
|
||||
}
|
||||
_MD_ExprKindGroup;
|
||||
|
||||
typedef struct _MD_ExprKindMetadata _MD_ExprKindMetadata;
|
||||
struct _MD_ExprKindMetadata
|
||||
{
|
||||
_MD_ExprKindGroup group;
|
||||
MD_ExprPrec prec;
|
||||
char *symbol;
|
||||
char *pre_symbol;
|
||||
char *post_symbol;
|
||||
};
|
||||
|
||||
MD_FUNCTION_IMPL _MD_ExprKindMetadata *
|
||||
_MD_MetadataFromExprKind(MD_ExprKind kind)
|
||||
{
|
||||
// 0: Invalid
|
||||
// 12: (unary) - ~ !
|
||||
// 11: . -> () []
|
||||
// 10: * / %
|
||||
// 9: + -
|
||||
// 8: << >>
|
||||
// 7: < <= > >=
|
||||
// 6: == !=
|
||||
// 5: (bitwise) &
|
||||
// 4: ^
|
||||
// 3: |
|
||||
// 2: &&
|
||||
// 1: ||
|
||||
static _MD_ExprKindMetadata metadata[] =
|
||||
{
|
||||
{_MD_ExprKindGroup_Nil, +0, "NIL", "", "" }, // MD_ExprKind_Nil
|
||||
{_MD_ExprKindGroup_Atom, +0, "NIL", "", "" }, // MD_ExprKind_Atom
|
||||
{_MD_ExprKindGroup_Binary, +11, ".", "", "" }, // MD_ExprKind_Dot
|
||||
{_MD_ExprKindGroup_Binary, +11, "->", "", "" }, // MD_ExprKind_Arrow
|
||||
{_MD_ExprKindGroup_PostUnary, +11, "", "(", ")"}, // MD_ExprKind_Call
|
||||
{_MD_ExprKindGroup_PostUnary, +11, "", "[", "]"}, // MD_ExprKind_Subscript
|
||||
{_MD_ExprKindGroup_PreUnary, +12, "", "*", "" }, // MD_ExprKind_Dereference
|
||||
{_MD_ExprKindGroup_PreUnary, +12, "", "&", "" }, // MD_ExprKind_Reference
|
||||
{_MD_ExprKindGroup_Binary, +9, "+", "", "" }, // MD_ExprKind_Add
|
||||
{_MD_ExprKindGroup_Binary, +9, "-", "", "" }, // MD_ExprKind_Subtract
|
||||
{_MD_ExprKindGroup_Binary, +10, "*", "", "" }, // MD_ExprKind_Multiply
|
||||
{_MD_ExprKindGroup_Binary, +10, "/", "", "" }, // MD_ExprKind_Divide
|
||||
{_MD_ExprKindGroup_Binary, +10, "%", "", "" }, // MD_ExprKind_Mod
|
||||
{_MD_ExprKindGroup_Binary, +6, "==", "", "" }, // MD_ExprKind_IsEqual
|
||||
{_MD_ExprKindGroup_Binary, +6, "!=", "", "" }, // MD_ExprKind_IsNotEqual
|
||||
{_MD_ExprKindGroup_Binary, +7, "<", "", "" }, // MD_ExprKind_LessThan
|
||||
{_MD_ExprKindGroup_Binary, +7, ">", "", "" }, // MD_ExprKind_GreaterThan
|
||||
{_MD_ExprKindGroup_Binary, +7, "<=", "", "" }, // MD_ExprKind_LessThanEqualTo
|
||||
{_MD_ExprKindGroup_Binary, +7, ">=", "", "" }, // MD_ExprKind_GreaterThanEqualTo
|
||||
{_MD_ExprKindGroup_Binary, +2, "&&", "", "" }, // MD_ExprKind_BoolAnd
|
||||
{_MD_ExprKindGroup_Binary, +1, "||", "", "" }, // MD_ExprKind_BoolOr
|
||||
{_MD_ExprKindGroup_PreUnary, +12, "", "!", "" }, // MD_ExprKind_BoolNot
|
||||
{_MD_ExprKindGroup_Binary, +5, "&", "", "" }, // MD_ExprKind_BitAnd
|
||||
{_MD_ExprKindGroup_Binary, +3, "|", "", "" }, // MD_ExprKind_BitOr
|
||||
{_MD_ExprKindGroup_PreUnary, +12, "", "~", "" }, // MD_ExprKind_BitNot
|
||||
{_MD_ExprKindGroup_Binary, +4, "^", "", "" }, // MD_ExprKind_BitXor
|
||||
{_MD_ExprKindGroup_Binary, +8, "<<", "", "" }, // MD_ExprKind_LeftShift
|
||||
{_MD_ExprKindGroup_Binary, +8, ">>", "", "" }, // MD_ExprKind_RightShift
|
||||
{_MD_ExprKindGroup_PreUnary, +12, "", "-", "" }, // MD_ExprKind_Negative
|
||||
{_MD_ExprKindGroup_Type, +0, "*", "", "" }, // MD_ExprKind_Pointer
|
||||
{_MD_ExprKindGroup_Type, +0, "", "[", "]"}, // MD_ExprKind_Array
|
||||
};
|
||||
return &metadata[kind];
|
||||
}
|
||||
|
||||
MD_FUNCTION_IMPL MD_ExprKind
|
||||
MD_PreUnaryExprKindFromNode(MD_Node *node)
|
||||
{
|
||||
MD_ExprKind kind = MD_ExprKind_Nil;
|
||||
// NOTE(rjf): Special-cases for calls/subscripts.
|
||||
if(!MD_NodeIsNil(node->first_child))
|
||||
{
|
||||
if(node->flags & MD_NodeFlag_ParenLeft &&
|
||||
node->flags & MD_NodeFlag_ParenRight)
|
||||
{
|
||||
kind = MD_ExprKind_Call;
|
||||
}
|
||||
else if(node->flags & MD_NodeFlag_BracketLeft &&
|
||||
node->flags & MD_NodeFlag_BracketRight)
|
||||
{
|
||||
kind = MD_ExprKind_Subscript;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(MD_ExprKind kind_it = (MD_ExprKind)0; kind_it < MD_ExprKind_MAX;
|
||||
kind_it = (MD_ExprKind)((int)kind_it + 1))
|
||||
{
|
||||
_MD_ExprKindMetadata *metadata = _MD_MetadataFromExprKind(kind_it);
|
||||
if(metadata->group == _MD_ExprKindGroup_PreUnary)
|
||||
{
|
||||
if(MD_StringMatch(node->string, MD_S8CString(metadata->pre_symbol), 0))
|
||||
{
|
||||
kind = kind_it;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return kind;
|
||||
}
|
||||
|
||||
MD_FUNCTION_IMPL MD_ExprKind
|
||||
MD_PostUnaryExprKindFromNode(MD_Node *node)
|
||||
{
|
||||
@@ -2616,368 +2493,6 @@ MD_PostUnaryExprKindFromNode(MD_Node *node)
|
||||
return kind;
|
||||
}
|
||||
|
||||
MD_FUNCTION_IMPL MD_ExprKind
|
||||
MD_BinaryExprKindFromNode(MD_Node *node)
|
||||
{
|
||||
MD_ExprKind kind = MD_ExprKind_Nil;
|
||||
if(node->kind == MD_NodeKind_Label && MD_NodeIsNil(node->first_child))
|
||||
{
|
||||
for(MD_ExprKind kind_it = (MD_ExprKind)0; kind_it < MD_ExprKind_MAX;
|
||||
kind_it = (MD_ExprKind)((int)kind_it + 1))
|
||||
{
|
||||
_MD_ExprKindMetadata *metadata = _MD_MetadataFromExprKind(kind_it);
|
||||
if(metadata->group == _MD_ExprKindGroup_Binary)
|
||||
{
|
||||
if(MD_StringMatch(node->string, MD_S8CString(metadata->symbol), 0))
|
||||
{
|
||||
kind = kind_it;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return kind;
|
||||
}
|
||||
|
||||
MD_FUNCTION_IMPL MD_ExprPrec
|
||||
MD_ExprPrecFromExprKind(MD_ExprKind kind)
|
||||
{
|
||||
_MD_ExprKindMetadata *metadata = _MD_MetadataFromExprKind(kind);
|
||||
return metadata->prec;
|
||||
}
|
||||
|
||||
MD_FUNCTION_IMPL MD_Expr *
|
||||
MD_MakeExpr(MD_Node *node, MD_ExprKind kind, MD_Expr *left, MD_Expr *right)
|
||||
{
|
||||
MD_Expr *expr = _MD_PushArray(MD_Expr, 1);
|
||||
if(expr)
|
||||
{
|
||||
if(left == 0) left = MD_NilExpr();
|
||||
if(right == 0) right = MD_NilExpr();
|
||||
expr->node = node;
|
||||
expr->kind = kind;
|
||||
expr->sub[0] = left;
|
||||
expr->sub[1] = right;
|
||||
}
|
||||
else
|
||||
{
|
||||
expr = MD_NilExpr();
|
||||
}
|
||||
return expr;
|
||||
}
|
||||
|
||||
typedef struct _MD_NodeParseCtx _MD_NodeParseCtx;
|
||||
struct _MD_NodeParseCtx
|
||||
{
|
||||
MD_Node *at;
|
||||
MD_Node *last;
|
||||
MD_Node *one_past_last;
|
||||
};
|
||||
|
||||
MD_PRIVATE_FUNCTION_IMPL MD_b32
|
||||
_MD_NodeParse_ConsumeAtom(_MD_NodeParseCtx *ctx, MD_Node **out)
|
||||
{
|
||||
MD_b32 result = 0;
|
||||
if(ctx->at->kind == MD_NodeKind_Label &&
|
||||
MD_NodeIsNil(ctx->at->first_child))
|
||||
{
|
||||
result = 1;
|
||||
if(out)
|
||||
{
|
||||
*out = ctx->at;
|
||||
}
|
||||
ctx->at = ctx->at->next;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
MD_PRIVATE_FUNCTION_IMPL MD_b32
|
||||
_MD_NodeParse_ConsumeSet(_MD_NodeParseCtx *ctx, MD_Node **out)
|
||||
{
|
||||
MD_b32 result = 0;
|
||||
if(!MD_NodeIsNil(ctx->at->first_child))
|
||||
{
|
||||
if(out)
|
||||
{
|
||||
*out = ctx->at;
|
||||
}
|
||||
ctx->at = ctx->at->next;
|
||||
result = 1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
MD_PRIVATE_FUNCTION_IMPL MD_b32
|
||||
_MD_NodeParse_ConsumeLiteral(_MD_NodeParseCtx *ctx, MD_Node **out)
|
||||
{
|
||||
MD_b32 result = 0;
|
||||
if(ctx->at->flags & MD_NodeFlag_StringLiteral ||
|
||||
ctx->at->flags & MD_NodeFlag_CharLiteral ||
|
||||
ctx->at->flags & MD_NodeFlag_Numeric)
|
||||
{
|
||||
result = 1;
|
||||
if(out)
|
||||
{
|
||||
*out = ctx->at;
|
||||
}
|
||||
ctx->at = ctx->at->next;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
MD_PRIVATE_FUNCTION_IMPL MD_b32
|
||||
_MD_NodeParse_Consume(_MD_NodeParseCtx *ctx, MD_String8 string, MD_Node **out)
|
||||
{
|
||||
MD_b32 result = 0;
|
||||
if(MD_StringMatch(ctx->at->string, string, 0))
|
||||
{
|
||||
result = 1;
|
||||
if(out)
|
||||
{
|
||||
*out = ctx->at;
|
||||
}
|
||||
ctx->at = ctx->at->next;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
MD_PRIVATE_FUNCTION_IMPL void
|
||||
_MD_NodeParse_Next(_MD_NodeParseCtx *ctx)
|
||||
{
|
||||
ctx->at = ctx->at->next;
|
||||
}
|
||||
|
||||
MD_PRIVATE_FUNCTION_IMPL MD_Expr *
|
||||
_MD_ParseExpr_(_MD_NodeParseCtx *ctx, int precedence_in);
|
||||
|
||||
MD_PRIVATE_FUNCTION_IMPL MD_Expr *
|
||||
_MD_ParseExpr(_MD_NodeParseCtx *ctx);
|
||||
|
||||
MD_PRIVATE_FUNCTION_IMPL MD_Expr *
|
||||
_MD_ParseUnaryExpr(_MD_NodeParseCtx *ctx)
|
||||
{
|
||||
MD_Expr *result = MD_NilExpr();
|
||||
MD_Node *set = 0;
|
||||
MD_Node *node = 0;
|
||||
|
||||
// NOTE(rjf): Sub-expression
|
||||
if(_MD_NodeParse_ConsumeSet(ctx, &set))
|
||||
{
|
||||
result = MD_ParseAsExpr(set->first_child, set->last_child);
|
||||
}
|
||||
|
||||
// NOTE(rjf): Literal
|
||||
else if(_MD_NodeParse_ConsumeLiteral(ctx, &node))
|
||||
{
|
||||
result = MD_MakeExpr(node, MD_ExprKind_Atom, 0, 0);
|
||||
}
|
||||
|
||||
// NOTE(rjf): Literal
|
||||
else if(_MD_NodeParse_ConsumeAtom(ctx, &node))
|
||||
{
|
||||
result = MD_MakeExpr(node, MD_ExprKind_Atom, 0, 0);
|
||||
}
|
||||
|
||||
// NOTE(rjf): Negative
|
||||
else if(_MD_NodeParse_Consume(ctx, MD_S8Lit("-"), &node))
|
||||
{
|
||||
result = MD_MakeExpr(node, MD_ExprKind_Negative, 0, _MD_ParseExpr(ctx));
|
||||
}
|
||||
|
||||
// NOTE(rjf): Bitwise Negate
|
||||
else if(_MD_NodeParse_Consume(ctx, MD_S8Lit("~"), &node))
|
||||
{
|
||||
result = MD_MakeExpr(node, MD_ExprKind_BitNot, 0, _MD_ParseExpr(ctx));
|
||||
}
|
||||
|
||||
// NOTE(rjf): Boolean Negate
|
||||
else if(_MD_NodeParse_Consume(ctx, MD_S8Lit("!"), &node))
|
||||
{
|
||||
result = MD_MakeExpr(node, MD_ExprKind_BoolNot, 0, _MD_ParseExpr(ctx));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
MD_PRIVATE_FUNCTION_IMPL MD_Expr *
|
||||
_MD_ParseExpr_(_MD_NodeParseCtx *ctx, int precedence_in)
|
||||
{
|
||||
MD_Expr *expr = _MD_ParseUnaryExpr(ctx);
|
||||
MD_ExprKind expr_kind;
|
||||
if(MD_ExprIsNil(expr))
|
||||
{
|
||||
goto end_parse;
|
||||
}
|
||||
|
||||
expr_kind = MD_BinaryExprKindFromNode(ctx->at);
|
||||
if(expr_kind != MD_ExprKind_Nil)
|
||||
{
|
||||
for(int precedence = MD_ExprPrecFromExprKind(expr_kind);
|
||||
precedence >= precedence_in;
|
||||
precedence -= 1)
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
MD_Node *op_node = ctx->at;
|
||||
expr_kind = MD_BinaryExprKindFromNode(ctx->at);
|
||||
int operator_precedence = MD_ExprPrecFromExprKind(expr_kind);
|
||||
if(operator_precedence != precedence)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if(expr_kind == MD_ExprKind_Nil)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
_MD_NodeParse_Next(ctx);
|
||||
|
||||
MD_Expr *right = _MD_ParseExpr_(ctx, precedence+1);
|
||||
if(MD_ExprIsNil(right))
|
||||
{
|
||||
// TODO(rjf): Error: "Expected right-hand-side of binary expression."
|
||||
goto end_parse;
|
||||
}
|
||||
|
||||
MD_Expr *left = expr;
|
||||
expr = MD_MakeExpr(op_node, expr_kind, left, right);
|
||||
expr->sub[0] = left;
|
||||
expr->sub[1] = right;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
end_parse:;
|
||||
return expr;
|
||||
}
|
||||
|
||||
MD_PRIVATE_FUNCTION_IMPL MD_Expr *
|
||||
_MD_ParseExpr(_MD_NodeParseCtx *ctx)
|
||||
{
|
||||
return _MD_ParseExpr_(ctx, 1);
|
||||
}
|
||||
|
||||
MD_FUNCTION_IMPL MD_Expr *
|
||||
MD_ParseAsExpr(MD_Node *first, MD_Node *last)
|
||||
{
|
||||
_MD_NodeParseCtx ctx_ = { first, last, last->next };
|
||||
_MD_NodeParseCtx *ctx = &ctx_;
|
||||
return _MD_ParseExpr(ctx);
|
||||
}
|
||||
|
||||
MD_FUNCTION_IMPL MD_Expr *
|
||||
MD_ParseAsType(MD_Node *first, MD_Node *last)
|
||||
{
|
||||
MD_Expr *expr = MD_NilExpr();
|
||||
MD_Expr *last_expr = expr;
|
||||
_MD_NodeParseCtx ctx_ = { first, last, last->next };
|
||||
_MD_NodeParseCtx *ctx = &ctx_;
|
||||
#define _MD_PushType(x) if(MD_ExprIsNil(last_expr)) { expr = last_expr = x; } else { last_expr = last_expr->sub[0] = x; }
|
||||
MD_Node *set = 0;
|
||||
MD_Node *ptr = 0;
|
||||
MD_Node *base_type = 0;
|
||||
MD_Node *node = 0;
|
||||
for(;;)
|
||||
{
|
||||
if(_MD_NodeParse_Consume(ctx, MD_S8Lit("*"), &ptr))
|
||||
{
|
||||
MD_Expr *t = MD_MakeExpr(ptr, MD_ExprKind_Pointer, MD_NilExpr(), MD_NilExpr());
|
||||
_MD_PushType(t);
|
||||
}
|
||||
else if(_MD_NodeParse_Consume(ctx, MD_S8Lit("volatile"), &node))
|
||||
{
|
||||
MD_Expr *t = MD_MakeExpr(node, MD_ExprKind_Volatile, MD_NilExpr(), MD_NilExpr());
|
||||
_MD_PushType(t);
|
||||
}
|
||||
else if(_MD_NodeParse_Consume(ctx, MD_S8Lit("const"), &node))
|
||||
{
|
||||
MD_Expr *t = MD_MakeExpr(node, MD_ExprKind_Const, MD_NilExpr(), MD_NilExpr());
|
||||
_MD_PushType(t);
|
||||
}
|
||||
else if(_MD_NodeParse_ConsumeSet(ctx, &set))
|
||||
{
|
||||
MD_Expr *t = MD_MakeExpr(set, MD_ExprKind_Array, MD_NilExpr(), MD_NilExpr());
|
||||
t->sub[1] = MD_ParseAsExpr(set->first_child, set->last_child);
|
||||
_MD_PushType(t);
|
||||
}
|
||||
else if(_MD_NodeParse_ConsumeAtom(ctx, &base_type))
|
||||
{
|
||||
MD_Expr *t = MD_MakeExpr(base_type, MD_ExprKind_Atom, MD_NilExpr(), MD_NilExpr());
|
||||
_MD_PushType(t);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
#undef _MD_PushType
|
||||
return expr;
|
||||
}
|
||||
|
||||
MD_FUNCTION_IMPL MD_i64
|
||||
MD_EvaluateExpr_I64(MD_Expr *expr)
|
||||
{
|
||||
MD_i64 result = 0;
|
||||
switch(expr->kind)
|
||||
{
|
||||
#define _MD_BinaryOp(name, op) case MD_ExprKind_##name: { result = MD_EvaluateExpr_I64(expr->sub[0]) op MD_EvaluateExpr_I64(expr->sub[1]); }break
|
||||
_MD_BinaryOp(Add, +);
|
||||
_MD_BinaryOp(Subtract, -);
|
||||
_MD_BinaryOp(Multiply, *);
|
||||
_MD_BinaryOp(Divide, /);
|
||||
#undef _MD_BinaryOp
|
||||
case MD_ExprKind_Atom: { result = MD_I64FromString(expr->node->string, 10); }break;
|
||||
default: break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
MD_FUNCTION_IMPL MD_f64
|
||||
MD_EvaluateExpr_F64(MD_Expr *expr)
|
||||
{
|
||||
MD_f64 result = 0;
|
||||
switch(expr->kind)
|
||||
{
|
||||
#define _MD_BinaryOp(name, op) case MD_ExprKind_##name: { result = MD_EvaluateExpr_I64(expr->sub[0]) op MD_EvaluateExpr_F64(expr->sub[1]); }break
|
||||
_MD_BinaryOp(Add, +);
|
||||
_MD_BinaryOp(Subtract, -);
|
||||
_MD_BinaryOp(Multiply, *);
|
||||
_MD_BinaryOp(Divide, /);
|
||||
#undef _MD_BinaryOp
|
||||
case MD_ExprKind_Atom: { result = MD_F64FromString(expr->node->string); }break;
|
||||
default: break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
MD_FUNCTION_IMPL MD_b32
|
||||
MD_ExprMatch(MD_Expr *a, MD_Expr *b, MD_MatchFlags flags)
|
||||
{
|
||||
MD_b32 result = 0;
|
||||
if(a->kind == b->kind)
|
||||
{
|
||||
result = 1;
|
||||
if(a->kind == MD_ExprKind_Atom)
|
||||
{
|
||||
result = MD_StringMatch(a->node->string, b->node->string, flags);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
MD_FUNCTION_IMPL MD_b32
|
||||
MD_ExprDeepMatch(MD_Expr *a, MD_Expr *b, MD_MatchFlags flags)
|
||||
{
|
||||
MD_b32 result = MD_ExprMatch(a, b, flags);
|
||||
if(result && !MD_ExprIsNil(a) && !MD_ExprIsNil(b))
|
||||
{
|
||||
result = (MD_ExprDeepMatch(a->sub[0], b->sub[0], flags) &&
|
||||
MD_ExprDeepMatch(a->sub[1], b->sub[1], flags));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
MD_FUNCTION_IMPL void
|
||||
MD_OutputTree(FILE *file, MD_Node *node)
|
||||
{
|
||||
@@ -3017,205 +2532,6 @@ MD_OutputTree(FILE *file, MD_Node *node)
|
||||
}
|
||||
}
|
||||
|
||||
MD_FUNCTION_IMPL void
|
||||
MD_OutputTree_C_String(FILE *file, MD_Node *node)
|
||||
{
|
||||
fprintf(file, "\"");
|
||||
for(MD_u64 i = 0; i < node->string.size; i += 1)
|
||||
{
|
||||
if(node->string.str[i] == '\n')
|
||||
{
|
||||
fprintf(file, "\\n\"\n\"");
|
||||
}
|
||||
else if(node->string.str[i] == '\r' &&
|
||||
i+1 < node->string.size && node->string.str[i+1] == '\n')
|
||||
{
|
||||
// NOTE(mal): Step over CR when quoting CRLF newlines
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(file, "%c", node->string.str[i]);
|
||||
}
|
||||
}
|
||||
fprintf(file, "\"");
|
||||
}
|
||||
|
||||
MD_FUNCTION_IMPL void
|
||||
MD_OutputTree_C_Struct(FILE *file, MD_Node *node)
|
||||
{
|
||||
if(node)
|
||||
{
|
||||
fprintf(file, "typedef struct %.*s %.*s;\n",
|
||||
MD_StringExpand(node->string),
|
||||
MD_StringExpand(node->string));
|
||||
fprintf(file, "struct %.*s\n{\n", MD_StringExpand(node->string));
|
||||
for(MD_Node *child = node->first_child; !MD_NodeIsNil(child); child = child->next)
|
||||
{
|
||||
MD_OutputTree_C_Decl(file, child);
|
||||
fprintf(file, ";\n");
|
||||
}
|
||||
fprintf(file, "};\n\n");
|
||||
}
|
||||
}
|
||||
|
||||
MD_FUNCTION_IMPL void
|
||||
MD_OutputTree_C_Decl(FILE *file, MD_Node *node)
|
||||
{
|
||||
if(node)
|
||||
{
|
||||
MD_Expr *type = MD_ParseAsType(node->first_child, node->last_child);
|
||||
MD_Output_C_DeclByNameAndType(file, node->string, type);
|
||||
}
|
||||
}
|
||||
|
||||
MD_FUNCTION_IMPL void
|
||||
MD_Output_C_DeclByNameAndType(FILE *file, MD_String8 name, MD_Expr *type)
|
||||
{
|
||||
MD_OutputType_C_LHS(file, type);
|
||||
fprintf(file, " %.*s", MD_StringExpand(name));
|
||||
MD_OutputType_C_RHS(file, type);
|
||||
}
|
||||
|
||||
MD_FUNCTION_IMPL void
|
||||
MD_OutputExpr(FILE *file, MD_Expr *expr)
|
||||
{
|
||||
if(!MD_NodeIsNil(expr->node))
|
||||
{
|
||||
_MD_ExprKindMetadata *metadata = _MD_MetadataFromExprKind(expr->kind);
|
||||
switch(metadata->group)
|
||||
{
|
||||
case _MD_ExprKindGroup_Atom:
|
||||
{
|
||||
fprintf(file, "%.*s", MD_StringExpand(expr->node->string));
|
||||
}break;
|
||||
|
||||
case _MD_ExprKindGroup_Binary:
|
||||
{
|
||||
fprintf(file, "(");
|
||||
MD_OutputExpr(file, expr->sub[0]);
|
||||
fprintf(file, " %s ", metadata->symbol);
|
||||
MD_OutputExpr(file, expr->sub[1]);
|
||||
fprintf(file, ")");
|
||||
}break;
|
||||
|
||||
case _MD_ExprKindGroup_PreUnary:
|
||||
{
|
||||
fprintf(file, "%s", metadata->pre_symbol);
|
||||
fprintf(file, "(");
|
||||
MD_OutputExpr(file, expr->sub[0]);
|
||||
fprintf(file, ")");
|
||||
}break;
|
||||
|
||||
case _MD_ExprKindGroup_PostUnary:
|
||||
{
|
||||
fprintf(file, "(");
|
||||
MD_OutputExpr(file, expr->sub[0]);
|
||||
fprintf(file, ")");
|
||||
fprintf(file, "%s", metadata->post_symbol);
|
||||
}break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MD_FUNCTION_IMPL void
|
||||
MD_OutputExpr_C(FILE *file, MD_Expr *expr)
|
||||
{
|
||||
MD_OutputExpr(file, expr);
|
||||
}
|
||||
|
||||
MD_PRIVATE_FUNCTION_IMPL MD_b32
|
||||
_MD_OutputType_C_NeedsParens(MD_Expr *type)
|
||||
{
|
||||
MD_b32 result = 0;
|
||||
if (type->kind == MD_ExprKind_Pointer &&
|
||||
type->sub[0]->kind == MD_ExprKind_Array)
|
||||
{
|
||||
result = 1;
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
MD_FUNCTION_IMPL void
|
||||
MD_OutputType_C_LHS(FILE *file, MD_Expr *type)
|
||||
{
|
||||
switch (type->kind)
|
||||
{
|
||||
case MD_ExprKind_Atom:
|
||||
{
|
||||
MD_Node *node = type->node;
|
||||
fprintf(file, "%.*s", MD_StringExpand(node->whole_string));
|
||||
}break;
|
||||
|
||||
case MD_ExprKind_Pointer:
|
||||
{
|
||||
MD_OutputType_C_LHS(file, type->sub[0]);
|
||||
if (_MD_OutputType_C_NeedsParens(type))
|
||||
{
|
||||
fprintf(file, "(");
|
||||
}
|
||||
fprintf(file, "*");
|
||||
}break;
|
||||
|
||||
case MD_ExprKind_Array:
|
||||
{
|
||||
MD_OutputType_C_LHS(file, type->sub[0]);
|
||||
if (_MD_OutputType_C_NeedsParens(type))
|
||||
{
|
||||
fprintf(file, "(");
|
||||
}
|
||||
}break;
|
||||
|
||||
case MD_ExprKind_Volatile: { fprintf(file, "volatile "); }break;
|
||||
case MD_ExprKind_Const: { fprintf(file, "const "); }break;
|
||||
|
||||
default:
|
||||
{
|
||||
fprintf(file, "{ unexpected MD_ExprKind (%i) in type info for node \"%.*s\" }",
|
||||
type->kind,
|
||||
MD_StringExpand(type->node->whole_string));
|
||||
}break;
|
||||
}
|
||||
}
|
||||
|
||||
MD_FUNCTION_IMPL void
|
||||
MD_OutputType_C_RHS(FILE *file, MD_Expr *type)
|
||||
{
|
||||
switch (type->kind)
|
||||
{
|
||||
case MD_ExprKind_Atom:
|
||||
{}break;
|
||||
|
||||
case MD_ExprKind_Pointer:
|
||||
{
|
||||
if (_MD_OutputType_C_NeedsParens(type))
|
||||
{
|
||||
fprintf(file, ")");
|
||||
}
|
||||
MD_OutputType_C_RHS(file, type->sub[0]);
|
||||
}break;
|
||||
|
||||
case MD_ExprKind_Array:
|
||||
{
|
||||
if (_MD_OutputType_C_NeedsParens(type))
|
||||
{
|
||||
fprintf(file, ")");
|
||||
}
|
||||
fprintf(file, "[");
|
||||
MD_OutputExpr_C(file, type->sub[1]);
|
||||
fprintf(file, "]");
|
||||
MD_OutputType_C_RHS(file, type->sub[0]);
|
||||
}break;
|
||||
|
||||
case MD_ExprKind_Volatile: { fprintf(file, "volatile "); }break;
|
||||
case MD_ExprKind_Const: { fprintf(file, "const "); }break;
|
||||
|
||||
default:
|
||||
{}break;
|
||||
}
|
||||
}
|
||||
|
||||
MD_FUNCTION_IMPL MD_CommandLine
|
||||
MD_CommandLine_Start(int argument_count, char **arguments)
|
||||
{
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
#include "md.h"
|
||||
#include "md_c_helpers.h"
|
||||
|
||||
#include "md.c"
|
||||
#include "md_c_helpers.c"
|
||||
|
||||
static struct
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user