mirror of
https://github.com/Ed94/metadesk.git
synced 2026-06-21 19:34:59 -07:00
780 lines
24 KiB
C
780 lines
24 KiB
C
//~ Metadesk Library
|
|
|
|
// TODO List
|
|
//
|
|
// - Expression/Type helper
|
|
// - Parsing things as a type, getting basic type info
|
|
// - Radix for MD_I64FromString
|
|
// - Freeing calls, allow hooking the allocator with an arena or
|
|
// something so that someone can use this for work at an application/game's
|
|
// runtime
|
|
// - Outputting anything to MD or C code ideally would do something
|
|
// smart with auto-indentation, since some people have wanted readable
|
|
// layout (if they aren't using 4coder with virtual whitespace basically)
|
|
// - Building with Clang
|
|
// - Split out C-related stuff into helper language layers
|
|
// - Helpers for parsing NodeFlags, figuring out which nodes in a set are
|
|
// separated by a semicolon, something like MD_SeekNodeWithFlags(node) -> node ?
|
|
|
|
// NOTE(allen): "Plugin" functionality
|
|
//
|
|
// MD_b32 MD_IMPL_FileIterIncrement(MD_FileIter*, MD_String8, MD_FileInfo*) - optional
|
|
// void* MD_IMPL_Alloc(void*,MD_u64) - required
|
|
// void* MD_IMPL_GetCtx(void) - optional
|
|
//
|
|
// TODO(allen): Commentary about this system somewhere easy to discover when
|
|
// you go digging.
|
|
|
|
#ifndef MD_H
|
|
#define MD_H
|
|
|
|
// NOTE(rjf): Compiler cracking from the 4th dimension
|
|
|
|
#if defined(_MSC_VER)
|
|
|
|
# define MD_COMPILER_CL 1
|
|
|
|
# if defined(_WIN32)
|
|
# define MD_OS_WINDOWS 1
|
|
# else
|
|
# error This compiler/platform combo is not supported yet
|
|
# endif
|
|
|
|
# if defined(_M_AMD64)
|
|
# define MD_ARCH_X64 1
|
|
# elif defined(_M_IX86)
|
|
# define MD_ARCH_X86 1
|
|
# elif defined(_M_ARM64)
|
|
# define MD_ARCH_ARM64 1
|
|
# elif defined(_M_ARM)
|
|
# define MD_ARCH_ARM32 1
|
|
# else
|
|
# 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
|
|
|
|
#elif defined(__clang__)
|
|
|
|
# define MD_COMPILER_CLANG 1
|
|
|
|
# if defined(__APPLE__) && defined(__MACH__)
|
|
# define MD_OS_MAC 1
|
|
# elif defined(__gnu_linux__)
|
|
# define MD_OS_LINUX 1
|
|
# else
|
|
# error This compiler/platform combo is not supported yet
|
|
# endif
|
|
|
|
# if defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64)
|
|
# define MD_ARCH_X64 1
|
|
# elif defined(i386) || defined(__i386) || defined(__i386__)
|
|
# define MD_ARCH_X86 1
|
|
# elif defined(__aarch64__)
|
|
# define MD_ARCH_ARM64 1
|
|
# elif defined(__arm__)
|
|
# define MD_ARCH_ARM32 1
|
|
# else
|
|
# error architecture not supported yet
|
|
# endif
|
|
|
|
#elif defined(__GNUC__) || defined(__GNUG__)
|
|
|
|
# define MD_COMPILER_GCC 1
|
|
|
|
# if defined(__gnu_linux__)
|
|
# define MD_OS_LINUX 1
|
|
# else
|
|
# error This compiler/platform combo is not supported yet
|
|
# endif
|
|
|
|
# if defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64)
|
|
# define MD_ARCH_X64 1
|
|
# elif defined(i386) || defined(__i386) || defined(__i386__)
|
|
# define MD_ARCH_X86 1
|
|
# elif defined(__aarch64__)
|
|
# define MD_ARCH_ARM64 1
|
|
# elif defined(__arm__)
|
|
# define MD_ARCH_ARM32 1
|
|
# else
|
|
# error architecture not supported yet
|
|
# endif
|
|
|
|
#else
|
|
# error This compiler is not supported yet
|
|
#endif
|
|
|
|
#if defined(MD_ARCH_X64)
|
|
# define MD_ARCH_64BIT 1
|
|
#elif defined(MD_ARCH_X86)
|
|
# define MD_ARCH_32BIT 1
|
|
#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)
|
|
# define MD_LANG_CPP 1
|
|
#else
|
|
# define MD_LANG_C 1
|
|
#endif
|
|
|
|
// zeroify
|
|
|
|
#if !defined(MD_ARCH_32BIT)
|
|
#define MD_ARCH_32BIT 0
|
|
#endif
|
|
#if !defined(MD_ARCH_64BIT)
|
|
#define MD_ARCH_64BIT 0
|
|
#endif
|
|
#if !defined(MD_ARCH_X64)
|
|
#define MD_ARCH_X64 0
|
|
#endif
|
|
#if !defined(MD_ARCH_X86)
|
|
#define MD_ARCH_X86 0
|
|
#endif
|
|
#if !defined(MD_ARCH_ARM64)
|
|
#define MD_ARCH_ARM64 0
|
|
#endif
|
|
#if !defined(MD_ARCH_ARM32)
|
|
#define MD_ARCH_ARM32 0
|
|
#endif
|
|
#if !defined(MD_COMPILER_CL)
|
|
#define MD_COMPILER_CL 0
|
|
#endif
|
|
#if !defined(MD_COMPILER_GCC)
|
|
#define MD_COMPILER_GCC 0
|
|
#endif
|
|
#if !defined(MD_COMPILER_CLANG)
|
|
#define MD_COMPILER_CLANG 0
|
|
#endif
|
|
#if !defined(MD_OS_WINDOWS)
|
|
#define MD_OS_WINDOWS 0
|
|
#endif
|
|
#if !defined(MD_OS_LINUX)
|
|
#define MD_OS_LINUX 0
|
|
#endif
|
|
#if !defined(MD_OS_MAC)
|
|
#define MD_OS_MAC 0
|
|
#endif
|
|
#if !defined(MD_LANG_C)
|
|
#define MD_LANG_C 0
|
|
#endif
|
|
#if !defined(MD_LANG_CPP)
|
|
#define MD_LANG_CPP 0
|
|
#endif
|
|
|
|
#define MD_FUNCTION
|
|
#define MD_GLOBAL static
|
|
|
|
// 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
|
|
# define MD_C_LINKAGE_BEGIN
|
|
# define MD_C_LINKAGE_END
|
|
#else
|
|
# define MD_C_LINKAGE_BEGIN extern "C"{
|
|
# define MD_C_LINKAGE_END }
|
|
#endif
|
|
|
|
#include <stdint.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.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>
|
|
|
|
typedef int8_t MD_i8;
|
|
typedef int16_t MD_i16;
|
|
typedef int32_t MD_i32;
|
|
typedef int64_t MD_i64;
|
|
typedef uint8_t MD_u8;
|
|
typedef uint16_t MD_u16;
|
|
typedef uint32_t MD_u32;
|
|
typedef uint64_t MD_u64;
|
|
typedef int8_t MD_b8;
|
|
typedef int16_t MD_b16;
|
|
typedef int32_t MD_b32;
|
|
typedef int64_t MD_b64;
|
|
typedef float MD_f32;
|
|
typedef double MD_f64;
|
|
|
|
//~ Basic UTF-8 string types.
|
|
|
|
typedef struct MD_String8 MD_String8;
|
|
struct MD_String8
|
|
{
|
|
MD_u8 *str;
|
|
MD_u64 size;
|
|
};
|
|
|
|
typedef struct MD_String16 MD_String16;
|
|
struct MD_String16
|
|
{
|
|
MD_u16 *str;
|
|
MD_u64 size;
|
|
};
|
|
|
|
typedef struct MD_String32 MD_String32;
|
|
struct MD_String32
|
|
{
|
|
MD_u32 *str;
|
|
MD_u64 size;
|
|
};
|
|
|
|
typedef struct MD_String8Node MD_String8Node;
|
|
struct MD_String8Node
|
|
{
|
|
MD_String8Node *next;
|
|
MD_String8 string;
|
|
};
|
|
|
|
typedef struct MD_String8List MD_String8List;
|
|
struct MD_String8List
|
|
{
|
|
MD_u64 node_count;
|
|
MD_u64 total_size;
|
|
MD_String8Node *first;
|
|
MD_String8Node *last;
|
|
};
|
|
|
|
typedef MD_u32 MD_StringMatchFlags;
|
|
enum
|
|
{
|
|
MD_StringMatchFlag_CaseInsensitive = (1<<0),
|
|
MD_StringMatchFlag_RightSideSloppy = (1<<1),
|
|
MD_StringMatchFlag_FindLast = (1<<2),
|
|
MD_StringMatchFlag_SlashInsensitive = (1<<3),
|
|
};
|
|
|
|
typedef struct MD_UnicodeConsume MD_UnicodeConsume;
|
|
struct MD_UnicodeConsume
|
|
{
|
|
MD_u32 codepoint;
|
|
MD_u32 advance;
|
|
};
|
|
|
|
typedef enum MD_WordStyle
|
|
{
|
|
MD_WordStyle_UpperCamelCase,
|
|
MD_WordStyle_LowerCamelCase,
|
|
MD_WordStyle_UpperCase,
|
|
MD_WordStyle_LowerCase,
|
|
}
|
|
MD_WordStyle;
|
|
|
|
//~ Node types that are used to build all ASTs.
|
|
|
|
typedef enum MD_NodeKind
|
|
{
|
|
MD_NodeKind_Nil,
|
|
MD_NodeKind_File,
|
|
MD_NodeKind_Label,
|
|
MD_NodeKind_UnnamedSet,
|
|
MD_NodeKind_Tag,
|
|
MD_NodeKind_MAX,
|
|
}
|
|
MD_NodeKind;
|
|
|
|
typedef MD_u32 MD_NodeFlags;
|
|
enum
|
|
{
|
|
MD_NodeFlag_ParenLeft = (1<<0),
|
|
MD_NodeFlag_ParenRight = (1<<1),
|
|
MD_NodeFlag_BracketLeft = (1<<2),
|
|
MD_NodeFlag_BracketRight = (1<<3),
|
|
MD_NodeFlag_BraceLeft = (1<<4),
|
|
MD_NodeFlag_BraceRight = (1<<5),
|
|
|
|
MD_NodeFlag_BeforeSemicolon = (1<<6),
|
|
MD_NodeFlag_BeforeComma = (1<<7),
|
|
|
|
MD_NodeFlag_AfterSemicolon = (1<<8),
|
|
MD_NodeFlag_AfterComma = (1<<9),
|
|
|
|
MD_NodeFlag_Numeric = (1<<10),
|
|
MD_NodeFlag_Identifier = (1<<11),
|
|
MD_NodeFlag_StringLiteral = (1<<12),
|
|
MD_NodeFlag_CharLiteral = (1<<13),
|
|
};
|
|
|
|
typedef MD_u32 MD_NodeMatchFlags;
|
|
enum
|
|
{
|
|
MD_NodeMatchFlag_Tags = (1<<0),
|
|
MD_NodeMatchFlag_TagArguments = (1<<1),
|
|
};
|
|
|
|
typedef struct MD_Node MD_Node;
|
|
struct MD_Node
|
|
{
|
|
// Tree relationship data.
|
|
MD_Node *next;
|
|
MD_Node *prev;
|
|
MD_Node *parent;
|
|
MD_Node *first_child;
|
|
MD_Node *last_child;
|
|
|
|
// Tag list.
|
|
MD_Node *first_tag;
|
|
MD_Node *last_tag;
|
|
|
|
// Node info.
|
|
MD_NodeKind kind;
|
|
MD_NodeFlags flags;
|
|
MD_String8 string;
|
|
MD_String8 whole_string;
|
|
MD_u64 string_hash;
|
|
|
|
// Source code location information.
|
|
MD_String8 filename;
|
|
MD_u8 *file_contents;
|
|
MD_u8 *at;
|
|
};
|
|
|
|
//~ Code Location Info.
|
|
|
|
typedef struct MD_CodeLoc MD_CodeLoc;
|
|
struct MD_CodeLoc
|
|
{
|
|
MD_String8 filename;
|
|
int line;
|
|
int column;
|
|
};
|
|
|
|
//~ Warning Levels
|
|
|
|
typedef enum MD_MessageKind
|
|
{
|
|
MD_MessageKind_Error,
|
|
MD_MessageKind_Warning,
|
|
}
|
|
MD_MessageKind;
|
|
|
|
//~ String-To-Node table
|
|
|
|
typedef enum MD_NodeTableCollisionRule
|
|
{
|
|
MD_NodeTableCollisionRule_Chain,
|
|
MD_NodeTableCollisionRule_Overwrite,
|
|
}
|
|
MD_NodeTableCollisionRule;
|
|
|
|
typedef struct MD_NodeTableSlot MD_NodeTableSlot;
|
|
struct MD_NodeTableSlot
|
|
{
|
|
MD_NodeTableSlot *next;
|
|
MD_u64 hash;
|
|
MD_Node *node;
|
|
};
|
|
|
|
typedef struct MD_NodeTable MD_NodeTable;
|
|
struct MD_NodeTable
|
|
{
|
|
MD_u64 table_size;
|
|
MD_NodeTableSlot **table;
|
|
};
|
|
|
|
//~ Token kinds.
|
|
|
|
typedef enum MD_TokenKind
|
|
{
|
|
MD_TokenKind_Nil,
|
|
|
|
MD_TokenKind_RegularMin,
|
|
|
|
// A group of characters that begins with an underscore or alphabetic character,
|
|
// and consists of numbers, alphabetic characters, or underscores after that.
|
|
MD_TokenKind_Identifier,
|
|
|
|
// A group of characters beginning with a numeric character or a '-', and then
|
|
// consisting of only numbers, alphabetic characters, or '.'s after that.
|
|
MD_TokenKind_NumericLiteral,
|
|
|
|
// A group of arbitrary characters, grouped together by a " character, OR by a
|
|
// """ symbol at the beginning and end of the group. String literals beginning with
|
|
// " are to only be specified on a single line, but """ strings can exist across
|
|
// many lines.
|
|
MD_TokenKind_StringLiteral,
|
|
|
|
// A group of arbitrary characters, grouped together by a ' character at the beginning,
|
|
// and a ' character at the end.
|
|
MD_TokenKind_CharLiteral,
|
|
|
|
// A group of symbolic characters, where symbolic characters means any of the following:
|
|
// ~!@#$%^&*()-+=[{]}:;<>,./?|\
|
|
//
|
|
// Groups of multiple characters are only allowed in specific circumstances. Most of these
|
|
// are only 1 character long, but some groups are allowed:
|
|
//
|
|
// "<<", ">>", "<=", ">=", "+=", "-=", "*=", "/=", "::", ":=", "==", "&=", "|=", "->"
|
|
MD_TokenKind_Symbol,
|
|
|
|
MD_TokenKind_RegularMax,
|
|
|
|
MD_TokenKind_Comment,
|
|
|
|
MD_TokenKind_WhitespaceMin,
|
|
MD_TokenKind_Whitespace,
|
|
MD_TokenKind_Newline,
|
|
MD_TokenKind_WhitespaceMax,
|
|
|
|
MD_TokenKind_MAX,
|
|
}
|
|
MD_TokenKind;
|
|
|
|
//~ Token type.
|
|
typedef struct MD_Token MD_Token;
|
|
struct MD_Token
|
|
{
|
|
MD_TokenKind kind;
|
|
MD_String8 string;
|
|
MD_String8 outer_string;
|
|
};
|
|
|
|
//~ Token groups.
|
|
typedef MD_u32 MD_TokenGroups;
|
|
enum{
|
|
MD_TokenGroup_Comment = (1 << 0),
|
|
MD_TokenGroup_Whitespace = (1 << 1),
|
|
MD_TokenGroup_Regular = (1 << 2)
|
|
};
|
|
|
|
//~ Parsing State
|
|
|
|
typedef struct MD_Error MD_Error;
|
|
struct MD_Error
|
|
{
|
|
MD_Error *next;
|
|
MD_String8 string;
|
|
MD_String8 filename;
|
|
MD_Node *node;
|
|
};
|
|
|
|
typedef struct MD_ParseCtx MD_ParseCtx;
|
|
struct MD_ParseCtx
|
|
{
|
|
MD_Node *first_root;
|
|
MD_Node *last_root;
|
|
MD_Error *first_error;
|
|
MD_Error *last_error;
|
|
MD_u8 *at;
|
|
MD_String8 filename;
|
|
MD_String8 file_contents;
|
|
};
|
|
|
|
typedef struct MD_ParseResult MD_ParseResult;
|
|
struct MD_ParseResult
|
|
{
|
|
MD_Node *node;
|
|
MD_Error *first_error;
|
|
MD_u64 bytes_parsed;
|
|
};
|
|
|
|
//~ Expression and Type-Expression parser helper types.
|
|
|
|
typedef enum MD_ExprKind
|
|
{
|
|
// VERY_IMPORTANT_NOTE(rjf): If this enum is ever changed, ensure that
|
|
// it is kept in-sync with the MD_ExprPrecFromExprKind and the following
|
|
// functions:
|
|
//
|
|
// MD_BinaryExprKindFromNode
|
|
// MD_PreUnaryExprKindFromNode
|
|
// MD_PostUnaryExprKindFromNode
|
|
|
|
MD_ExprKind_Nil,
|
|
|
|
// NOTE(rjf): Atom
|
|
MD_ExprKind_Atom,
|
|
|
|
// NOTE(rjf): Access
|
|
MD_ExprKind_Dot,
|
|
MD_ExprKind_Arrow,
|
|
MD_ExprKind_Call,
|
|
MD_ExprKind_Subscript,
|
|
MD_ExprKind_Dereference,
|
|
MD_ExprKind_Reference,
|
|
|
|
// NOTE(rjf): Arithmetic
|
|
MD_ExprKind_Add,
|
|
MD_ExprKind_Subtract,
|
|
MD_ExprKind_Multiply,
|
|
MD_ExprKind_Divide,
|
|
MD_ExprKind_Mod,
|
|
|
|
// NOTE(rjf): Comparison
|
|
MD_ExprKind_IsEqual,
|
|
MD_ExprKind_IsNotEqual,
|
|
MD_ExprKind_LessThan,
|
|
MD_ExprKind_GreaterThan,
|
|
MD_ExprKind_LessThanEqualTo,
|
|
MD_ExprKind_GreaterThanEqualTo,
|
|
|
|
// NOTE(rjf): Bools
|
|
MD_ExprKind_BoolAnd,
|
|
MD_ExprKind_BoolOr,
|
|
MD_ExprKind_BoolNot,
|
|
|
|
// NOTE(rjf): Bitwise
|
|
MD_ExprKind_BitAnd,
|
|
MD_ExprKind_BitOr,
|
|
MD_ExprKind_BitNot,
|
|
MD_ExprKind_BitXor,
|
|
MD_ExprKind_LeftShift,
|
|
MD_ExprKind_RightShift,
|
|
|
|
// NOTE(rjf): Unary numeric
|
|
MD_ExprKind_Negative,
|
|
|
|
// NOTE(rjf): Type
|
|
MD_ExprKind_Pointer,
|
|
MD_ExprKind_Array,
|
|
|
|
MD_ExprKind_MAX,
|
|
}
|
|
MD_ExprKind;
|
|
|
|
typedef MD_i32 MD_ExprPrec;
|
|
|
|
typedef struct MD_Expr MD_Expr;
|
|
struct MD_Expr
|
|
{
|
|
MD_Node *node;
|
|
MD_ExprKind kind;
|
|
MD_Expr *parent;
|
|
MD_Expr *sub[2];
|
|
};
|
|
|
|
//~ Command line parsing helper types.
|
|
typedef struct MD_CommandLine MD_CommandLine;
|
|
struct MD_CommandLine
|
|
{
|
|
// TODO(rjf): Linked-list vs. array?
|
|
MD_String8 *arguments;
|
|
int argument_count;
|
|
};
|
|
|
|
//~ File system access types.
|
|
|
|
typedef MD_u32 MD_FileFlags;
|
|
enum
|
|
{
|
|
MD_FileFlag_Directory = (1<<0),
|
|
};
|
|
|
|
typedef struct MD_FileInfo MD_FileInfo;
|
|
struct MD_FileInfo
|
|
{
|
|
MD_FileFlags flags;
|
|
MD_String8 filename;
|
|
MD_u64 file_size;
|
|
};
|
|
|
|
typedef struct MD_FileIter MD_FileIter;
|
|
struct MD_FileIter
|
|
{
|
|
// This is opaque state to store OS-specific file-system iteration data.
|
|
MD_u64 state;
|
|
};
|
|
|
|
//~ Basic Utilities
|
|
#define MD_Assert(c) if (!(c)) { *(volatile MD_u64 *)0 = 0; }
|
|
#define MD_ArrayCount(a) (sizeof(a) / sizeof((a)[0]))
|
|
MD_FUNCTION MD_b32 MD_CharIsAlpha(MD_u8 c);
|
|
MD_FUNCTION MD_b32 MD_CharIsAlphaUpper(MD_u8 c);
|
|
MD_FUNCTION MD_b32 MD_CharIsAlphaLower(MD_u8 c);
|
|
MD_FUNCTION MD_b32 MD_CharIsDigit(MD_u8 c);
|
|
MD_FUNCTION MD_b32 MD_CharIsSymbol(MD_u8 c);
|
|
MD_FUNCTION MD_b32 MD_CharIsSpace(MD_u8 c);
|
|
MD_FUNCTION MD_u8 MD_CharToUpper(MD_u8 c);
|
|
MD_FUNCTION MD_u8 MD_CharToLower(MD_u8 c);
|
|
MD_FUNCTION MD_u8 MD_CorrectSlash(MD_u8 c);
|
|
|
|
//~ Strings
|
|
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}
|
|
#elif MD_LANG_CPP
|
|
#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);
|
|
|
|
MD_FUNCTION MD_String8 MD_StringSubstring(MD_String8 str, MD_u64 min, MD_u64 max);
|
|
MD_FUNCTION MD_String8 MD_StringSkip(MD_String8 str, MD_u64 min);
|
|
MD_FUNCTION MD_String8 MD_StringChop(MD_String8 str, MD_u64 nmax);
|
|
MD_FUNCTION MD_String8 MD_StringPrefix(MD_String8 str, MD_u64 size);
|
|
MD_FUNCTION MD_String8 MD_StringSuffix(MD_String8 str, MD_u64 size);
|
|
|
|
MD_FUNCTION MD_b32 MD_StringMatch(MD_String8 a, MD_String8 b, MD_StringMatchFlags flags);
|
|
MD_FUNCTION MD_u64 MD_FindSubstring(MD_String8 str, MD_String8 substring,
|
|
MD_u64 start_pos, MD_StringMatchFlags flags);
|
|
MD_FUNCTION MD_u64 MD_FindLastSubstring(MD_String8 str, MD_String8 substring, MD_StringMatchFlags flags);
|
|
|
|
MD_FUNCTION MD_String8 MD_TrimExtension(MD_String8 string);
|
|
MD_FUNCTION MD_String8 MD_TrimFolder(MD_String8 string);
|
|
MD_FUNCTION MD_String8 MD_ExtensionFromPath(MD_String8 string);
|
|
MD_FUNCTION MD_String8 MD_FolderFromPath(MD_String8 string);
|
|
|
|
MD_FUNCTION MD_String8 MD_PushStringCopy(MD_String8 string);
|
|
MD_FUNCTION MD_String8 MD_PushStringFV(char *fmt, va_list args);
|
|
MD_FUNCTION MD_String8 MD_PushStringF(char *fmt, ...);
|
|
|
|
#define MD_StringExpand(s) (int)(s).size, (s).str
|
|
|
|
MD_FUNCTION void MD_PushStringToList(MD_String8List *list, MD_String8 string);
|
|
MD_FUNCTION void MD_PushStringListToList(MD_String8List *list, MD_String8List *to_push);
|
|
// TODO(rjf): Just simplify to a single splitter
|
|
MD_FUNCTION MD_String8List MD_SplitString(MD_String8 string, int split_count, MD_String8 *splits);
|
|
MD_FUNCTION MD_String8List MD_SplitStringByString(MD_String8 string, MD_String8 split);
|
|
MD_FUNCTION MD_String8List MD_SplitStringByCharacter(MD_String8 string, MD_u8 character);
|
|
MD_FUNCTION MD_String8 MD_JoinStringList(MD_String8List list);
|
|
MD_FUNCTION MD_String8 MD_JoinStringListWithSeparator(MD_String8List list, MD_String8 separator);
|
|
// TODO(rjf): Radix
|
|
MD_FUNCTION MD_i64 MD_I64FromString(MD_String8 string);
|
|
MD_FUNCTION MD_f64 MD_F64FromString(MD_String8 string);
|
|
MD_FUNCTION MD_u64 MD_HashString(MD_String8 string);
|
|
MD_FUNCTION MD_u64 MD_CalculateCStringLength(char *cstr);
|
|
|
|
MD_FUNCTION MD_String8 MD_StyledStringFromString(MD_String8 string, MD_WordStyle word_style, MD_String8 separator);
|
|
|
|
//~ Enum/Flag Strings
|
|
MD_FUNCTION MD_String8 MD_StringFromNodeKind(MD_NodeKind kind);
|
|
MD_FUNCTION MD_String8List MD_StringListFromNodeFlags(MD_NodeFlags flags);
|
|
|
|
//~ Unicode Conversions
|
|
MD_FUNCTION MD_UnicodeConsume MD_CodepointFromUtf8(MD_u8 *str, MD_u64 max);
|
|
MD_FUNCTION MD_UnicodeConsume MD_CodepointFromUtf16(MD_u16 *str, MD_u64 max);
|
|
MD_FUNCTION MD_u32 MD_Utf8FromCodepoint(MD_u8 *out, MD_u32 codepoint);
|
|
MD_FUNCTION MD_u32 MD_Utf16FromCodepoint(MD_u16 *out, MD_u32 codepoint);
|
|
MD_FUNCTION MD_String8 MD_S8FromS16(MD_String16 str);
|
|
MD_FUNCTION MD_String16 MD_S16FromS8(MD_String8 str);
|
|
MD_FUNCTION MD_String8 MD_S8FromS32(MD_String32 str);
|
|
MD_FUNCTION MD_String32 MD_S32FromS8(MD_String8 str);
|
|
|
|
//~ String-To-Node-List Table
|
|
MD_FUNCTION MD_NodeTableSlot *MD_NodeTable_Lookup(MD_NodeTable *table, MD_String8 string);
|
|
MD_FUNCTION MD_b32 MD_NodeTable_Insert(MD_NodeTable *table, MD_NodeTableCollisionRule collision_rule, MD_String8 string, MD_Node *node);
|
|
|
|
//~ Parsing
|
|
MD_FUNCTION MD_Token MD_ZeroToken(void);
|
|
MD_FUNCTION MD_b32 MD_TokenKindIsWhitespace(MD_TokenKind kind);
|
|
MD_FUNCTION MD_b32 MD_TokenKindIsComment(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 void MD_Parse_Bump(MD_ParseCtx *ctx, MD_Token token);
|
|
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_PeekSkipSome(MD_ParseCtx *ctx, MD_TokenGroups skip_groups);
|
|
MD_FUNCTION MD_b32 MD_Parse_TokenMatch(MD_Token token, MD_String8 string, MD_StringMatchFlags flags);
|
|
MD_FUNCTION MD_b32 MD_Parse_Require(MD_ParseCtx *ctx, MD_String8 string);
|
|
MD_FUNCTION MD_b32 MD_Parse_RequireKind(MD_ParseCtx *ctx, MD_TokenKind kind, MD_Token *out_token);
|
|
MD_FUNCTION MD_ParseResult MD_ParseOneNode (MD_String8 filename, MD_String8 contents);
|
|
MD_FUNCTION MD_Node * MD_ParseWholeString (MD_String8 filename, MD_String8 contents);
|
|
MD_FUNCTION MD_Node * MD_ParseWholeFile (MD_String8 filename);
|
|
|
|
//~ Tree/List Building
|
|
MD_FUNCTION MD_b32 MD_NodeIsNil(MD_Node *node);
|
|
MD_FUNCTION MD_Node *MD_NilNode(void);
|
|
MD_FUNCTION MD_Node *MD_MakeNodeFromToken(MD_NodeKind kind, MD_String8 filename, MD_u8 *file, MD_u8 *at, MD_Token token);
|
|
MD_FUNCTION MD_Node *MD_MakeNodeFromString(MD_NodeKind kind, MD_String8 filename, MD_u8 *file, MD_u8 *at, MD_String8 string);
|
|
MD_FUNCTION void MD_PushSibling(MD_Node **first, MD_Node **last, MD_Node *parent, MD_Node *new_sibling);
|
|
MD_FUNCTION void MD_PushChild(MD_Node *parent, MD_Node *new_child);
|
|
MD_FUNCTION void MD_PushTag(MD_Node *node, MD_Node *tag);
|
|
|
|
//~ Introspection Helpers
|
|
MD_FUNCTION MD_Node * MD_NodeFromString(MD_Node *first, MD_Node *last, MD_String8 string);
|
|
MD_FUNCTION MD_Node * MD_NodeFromIndex(MD_Node *first, MD_Node *last, int n);
|
|
MD_FUNCTION int MD_IndexFromNode(MD_Node *node);
|
|
MD_FUNCTION MD_Node * MD_NextNodeSibling(MD_Node *last, MD_String8 string);
|
|
MD_FUNCTION MD_Node * MD_ChildFromString(MD_Node *node, MD_String8 child_string);
|
|
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_TagFromIndex(MD_Node *node, int n);
|
|
MD_FUNCTION MD_Node * MD_TagArgFromIndex(MD_Node *node, MD_String8 tag_string, int n);
|
|
MD_FUNCTION MD_b32 MD_NodeHasTag(MD_Node *node, MD_String8 tag_string);
|
|
MD_FUNCTION MD_CodeLoc MD_CodeLocFromNode(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_ChildCountFromNodeAndString(MD_Node *node, MD_String8 string, MD_StringMatchFlags flags);
|
|
MD_FUNCTION MD_i64 MD_TagCountFromNodeAndString(MD_Node *node, MD_String8 string, MD_StringMatchFlags flags);
|
|
// NOTE(rjf): For-Loop Helper
|
|
#define MD_EachNode(it, first) MD_Node *it = (first); !MD_NodeIsNil(it); it = it->next
|
|
|
|
//~ Error/Warning Helpers
|
|
MD_FUNCTION void MD_NodeMessage(MD_Node *node, MD_MessageKind kind, MD_String8 str);
|
|
MD_FUNCTION void MD_NodeError(MD_Node *node, MD_String8 str);
|
|
MD_FUNCTION void MD_NodeWarning(MD_Node *node, MD_String8 str);
|
|
MD_FUNCTION void MD_NodeMessageF(MD_Node *node, MD_MessageKind kind, char *fmt, ...);
|
|
MD_FUNCTION void MD_NodeErrorF(MD_Node *node, char *fmt, ...);
|
|
MD_FUNCTION void MD_NodeWarningF(MD_Node *node, char *fmt, ...);
|
|
|
|
//~ Tree Comparison/Verification
|
|
MD_FUNCTION MD_b32 MD_NodeMatch(MD_Node *a, MD_Node *b, MD_StringMatchFlags str_flags, MD_NodeMatchFlags node_flags);
|
|
MD_FUNCTION MD_b32 MD_NodeDeepMatch(MD_Node *a, MD_Node *b, MD_StringMatchFlags str_flags, MD_NodeMatchFlags 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_StringMatchFlags str_flags);
|
|
MD_FUNCTION MD_b32 MD_ExprDeepMatch(MD_Expr *a, MD_Expr *b, MD_StringMatchFlags str_flags);
|
|
|
|
//~ Generation
|
|
MD_FUNCTION void MD_OutputTree(FILE *file, MD_Node *node);
|
|
MD_FUNCTION void MD_OutputExpr(FILE *file, MD_Expr *expr);
|
|
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_OutputType_C_LHS(FILE *file, MD_Expr *type);
|
|
MD_FUNCTION void MD_OutputType_C_RHS(FILE *file, MD_Expr *type);
|
|
|
|
//~ Command Line Argument Helper
|
|
MD_FUNCTION MD_CommandLine MD_CommandLine_Start(int argument_count, char **arguments);
|
|
MD_FUNCTION MD_b32 MD_CommandLine_Flag(MD_CommandLine *cmdln, MD_String8 string);
|
|
MD_FUNCTION MD_b32 MD_CommandLine_FlagStrings(MD_CommandLine *cmdln, MD_String8 string, int out_count, MD_String8 *out);
|
|
MD_FUNCTION MD_b32 MD_CommandLine_FlagIntegers(MD_CommandLine *cmdln, MD_String8 string, int out_count, MD_i64 *out);
|
|
MD_FUNCTION MD_b32 MD_CommandLine_FlagString(MD_CommandLine *cmdln, MD_String8 string, MD_String8 *out);
|
|
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
|
|
MD_FUNCTION MD_String8 MD_LoadEntireFile(MD_String8 filename);
|
|
MD_FUNCTION MD_b32 MD_FileIterIncrement(MD_FileIter *it, MD_String8 path, MD_FileInfo *out_info);
|
|
|
|
#endif // MD_H
|