16 KiB
//////////////////////////////// //~ Basic Unicode string types.
@struct MD_String8: { str: *MD_u8, size: MD_u64, };
@struct MD_String16: { str: *MD_u16, size: MD_u64, };
@struct MD_String32: { str: *MD_u32, size: MD_u64, };
@struct MD_String8Node: { next: MD_String8Node, string: MD_String8, };
@struct MD_String8List: { node_count: MD_u64, total_size: MD_u64, first: *MD_String8Node, last: *MD_String8Node, };
@prefix(MD_StringMatchFlag) @base_type(MD_u32) @flags MD_StringMatchFlags: { CaseInsensitive, RightSideSloppy, FindLast, SlashInsensitive, };
@struct MD_UnicodeConsume: { codepoint: MD_u32, advance: MD_u32, };
@enum MD_WordStyle: { UpperCamelCase, LowerCamelCase, UpperCase, LowerCase, };
//////////////////////////////// //~ Node types that are used to build all ASTs.
@enum MD_NodeKind: { Nil, File, Namespace, Label, Tag, MAX, };
@prefix(MD_NodeFlag) @base_type(MD_u32) @flags MD_NodeFlags: { ParenLeft, ParenRight, BracketLeft, BracketRight, BraceLeft, BraceRight,
BeforeSemicolon, BeforeComma,
AfterSemicolon, AfterComma,
Numeric, Identifier, StringLiteral, CharLiteral, };
@prefix(MD_NodeMatchFlag) @base_type(MD_u32) @flags MD_NodeMatchFlags: { MD_NodeMatchFlag_Tags, MD_NodeMatchFlag_TagArguments, };
@struct MD_Node: { next: *MD_Node, prev: *MD_Node, parent: *MD_Node, first_child: *MD_Node, last_child: *MD_Node,
// Tag list. first_tag: *MD_Node, last_tag: *MD_Node,
// Node info. kind: MD_NodeKind, flags: MD_NodeFlags, string: MD_String8, whole_string: MD_String8, string_hash: MD_u64,
// Comments. comment_before: MD_String8, comment_after: MD_String8,
// Source code location information. filename: MD_String8, file_contents: *MD_u8, at: *MD_u8, };
//////////////////////////////// //~ Code Location Info.
@struct MD_CodeLoc: { filename: MD_String8, line: MD_u32, column: MD_u32, };
//////////////////////////////// //~ Message Levels
@enum MD_MessageKind: { None, Warning, Error, }
//////////////////////////////// //~ String-To-Node table
@enum MD_MapCollisionRule: { Chain, Overwrite, }
@struct MD_MapSlot: { next: *MD_MapSlot, hash: MD_u64, key: *void; value: *void; };
@struct MD_Map: { table_size: MD_u64, table: **MD_MapSlot, };
//////////////////////////////// //~ Tokens
@enum MD_TokenKind: { Nil,
RegularMin,
// A group of characters that begins with an underscore or alphabetic character, // and consists of numbers, alphabetic characters, or underscores after that. Identifier,
// A group of characters beginning with a numeric character or a '-', and then // consisting of only numbers, alphabetic characters, or '.'s after that. 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. StringLiteral,
// A group of arbitrary characters, grouped together by a ' character at the // beginning, and a ' character at the end. CharLiteral,
// A group of symbolic characters. The symbolic characters are:
// ~!@#$%^&()-+=[{]}:;<>,./?|
//
// Groups of multiple characters are only allowed in specific circumstances. Most of these
// are only 1 character long, but some groups are allowed:
//
// "<<", ">>", "<=", ">=", "+=", "-=", "=", "/=", "::", ":=", "==", "&=", "|=", "->"
Symbol,
RegularMax,
Comment,
WhitespaceMin, Whitespace, Newline, WhitespaceMax,
MD_TokenKind_BadCharacter,
MAX, };
@struct MD_Token: { kind: MD_TokenKind, string: MD_String8, outer_string: MD_String8, };
@prefix(MD_TokenGroup) @base_type(MD_u32) @flags MD_TokenGroups: { Comment, Whitespace, Regular, };
//////////////////////////////// //~ Parsing State
@struct MD_Error: { next: *MD_Error, string: MD_String8, filename: MD_String8, node: *MD_Node, catastrophic: MD_b32, location: MD_CodeLoc, };
@struct MD_ParseCtx: { first_root: *MD_Node, last_root: *MD_Node, first_error: *MD_Error, last_error: *MD_Error, at: *MD_u8, filename: MD_String8, file_contents: MD_String8, namespace_table: MD_Map, selected_namespace: *MD_Node, catastrophic_error: MD_b32, };
@struct MD_ParseResult: { node: *MD_Node; first_error: *MD_Error; bytes_parse: MD_u64; };
//////////////////////////////// //~ Expression and Type-Expression parser helper types.
// VERY_IMPORTANT_NOTE(rjf): If this enum is ever changed, ensure that // it is kept in-sync with the MD_ExprPrecFromExprKind function.
@enum MD_ExprKind: { Nil,
// NOTE(rjf): Atom Atom,
// NOTE(rjf): Access Dot, Arrow, Call, Subscript, Dereference, Reference,
// NOTE(rjf): Arithmetic Add, Subtract, Multiply, Divide, Mod,
// NOTE(rjf): Comparison IsEqual, IsNotEqual, LessThan, GreaterThan, LessThanEqualTo, GreaterThanEqualTo,
// NOTE(rjf): Bools BoolAnd, BoolOr, BoolNot,
// NOTE(rjf): Bitwise BitAnd, BitOr, BitNot, BitXor, LeftShift, RightShift,
// NOTE(rjf): Unary numeric Negative,
// NOTE(rjf): Type Pointer, Array, Volatile, Const,
MAX, };
@typedef(MD_i32) MD_ExprPrec;
@struct MD_Expr: { node: *MD_Node, kind: MD_ExprKind, parent: *MD_Expr, sub: [2]*MD_Expr, };
//////////////////////////////// //~ Command line parsing helper types.
@struct MD_CommandLine: { arguments: *MD_String8; argument_count: MD_u32; };
//////////////////////////////// //~ File system access types.
@prefix(MD_FileFlag) @base_type(MD_u32) @flags MD_FileFlags: { Directory, };
@struct MD_FileInfo: { flags: MD_FileFlags; filename: MD_String8; file_size: MD_u64; };
@opaque @struct MD_FileIter: {};
//////////////////////////////// //~ Basic Utilities
@macro MD_Assert: { c, };
@macro MD_StaticAssert: { c, };
@macro MD_ArrayCount: { a, };
//////////////////////////////// //~ Characters
@func MD_CharIsAlpha: { c: MD_u8, return: MD_b32, };
@func MD_CharIsAlphaUpper: { c: MD_u8, return: MD_b32, };
@func MD_CharIsAlphaLower: { c: MD_u8, return: MD_b32, };
@func MD_CharIsDigit: { c: MD_u8, return: MD_b32, };
@func MD_CharIsSymbol: { c: MD_u8, return: MD_b32, };
@func MD_CharIsReservedSymbol: { c: MD_u8, return: MD_b32, };
@func MD_CharIsSpace: { c: MD_u8, return: MD_b32, };
@func MD_CharToUpper: { c: MD_u8, return: MD_u8, };
@func MD_CharToLower: { c: MD_u8, return: MD_u8, };
@func MD_CorrectSlash: { c: MD_u8, return: MD_u8, };
//////////////////////////////// //~ Strings
@func MD_S8: { str: *MD_u8, size: MD_u64, return: MD_String8, };
@macro MD_S8CString: { s, };
@macro MD_S8Lit: { s, };
@func MD_S8Range: { str: *MD_u8, opl: *MD_u8, return: MD_String8, };
@func MD_StringSubstring: { str: MD_String8, min: MD_u64, max: MD_u64 return: MD_String8, };
@func MD_StringSkip: { str: MD_String8, min: MD_u64, return: MD_String8, };
@func MD_StringChop: { str: MD_String8, nmax: MD_u64, return: MD_String8, };
@func MD_StringPrefix: { str: MD_String8, size: MD_u64, return: MD_String8, };
@func MD_StringSuffix: { str: MD_String8, size: MD_u64, return: MD_String8, };
@func MD_StringMatch: { a: MD_String8, b: MD_String8, flags: MD_StringMatchFlags, return: MD_b32, };
@func MD_FindSubstring: { str: MD_String8, substring: MD_String8, start_pos: MD_u64, flags: MD_StringMatchFlags, return: MD_u64, };
@func MD_FindLastSubstring: { str: MD_String8, substring: MD_String8, flags: MD_StringMatchFlags, return: MD_u64, };
@func MD_ChopExtension: { string: MD_String8, return: MD_String8, };
@func MD_SkipFolder: { string: MD_String8, return: MD_String8, };
@func MD_ExtensionFromPath: { string: MD_String8, return: MD_String8, };
@func MD_FolderFromPath: { string: MD_String8, return: MD_String8, };
@func MD_PushStringCopy: { string: MD_String8, return: MD_String8, };
@func MD_PushStringFV: { fmt: *char, args: va_list, return: MD_String8, };
@func MD_PushStringF: { fmt: *char, "...", return: MD_String8, };
@macro MD_StringExpand: { s, }
@func MD_PushStringToList: { list: *MD_String8List, string: MD_String8, };
@func MD_PushStringListToList: { list: *MD_String8List, to_push: *MD_String8List, };
@func MD_SplitString: { string: MD_String8, split_count: MD_u32, splits: *MD_String8, return: MD_String8List };
@func MD_JoinStringList: { list: MD_String8List, return: MD_String8, };
@func MD_JoinStringListWithSeparator: { list: MD_String8List, separator: MD_String8 return: MD_String8, };
@func MD_I64FromString: { string: MD_String8, radix: MD_u32, return: MD_i64, };
@func MD_F64FromString: { string: MD_String8, return: MD_f64, };
@func MD_HashString: { string: MD_String8, return: MD_u64, };
@func MD_CalculateCStringLength: { cstr: *char, return: MD_u64, };
@func MD_StyledStringFromString: { string: MD_String8, word_style: MD_WordStyle, separator: MD_String8, return: MD_String8 };
//////////////////////////////// //~ Enum/Flag Strings
@func MD_StringFromNodeKind: { kind: MD_NodeKind, return: MD_String8, };
@func MD_StringListFromNodeFlags: { flags: MD_NodeFlags, return: MD_String8List, };
//////////////////////////////// //~ Unicode Conversions
@func MD_CodepointFromUtf8: { str: MD_u8, max: MD_u64, return: MD_UnicodeConsume, };
@func MD_CodepointFromUtf16: { str: *MD_u16, max: MD_u64, return: MD_UnicodeConsume, };
@func MD_Utf8FromCodepoint: { out: *MD_u8, codepoint: MD_u32, return: MD_u32, };
@func MD_Utf16FromCodepoint: { out: *MD_u16, codepoint: MD_u32, return: MD_u32, };
@func MD_S8FromS16: { str: MD_String16, return: MD_String8, };
@func MD_S16FromS8: { str: MD_String8, return: MD_String16, };
@func MD_S8FromS32: { str: MD_String32, return: MD_String8, };
@func MD_S32FromS8: { str: MD_String8, return: MD_String32, };
//////////////////////////////// //~ String-To-Node-List Table
@func MD_Map_Lookup: { table: *MD_Map, string: MD_String8, return: *MD_MapSlot, };
@func MD_Map_Insert: { table: *MD_Map, collision_rule: MD_MapCollisionRule, string: MD_String8, node: *MD_Node, return: MD_b32, };
//////////////////////////////// //~ Parsing
@func MD_TokenKindIsWhitespace: { kind: MD_TokenKind, return: MD_b32, };
@func MD_TokenKindIsComment: { kind: MD_TokenKind, return: MD_b32, };
@func MD_TokenKindIsRegular: { kind: MD_TokenKind, return: MD_b32, };
@func MD_Parse_InitializeCtx: { filename: MD_String8, contents: MD_String8, return: MD_ParseCtx, };
@func MD_Parse_Bump: { ctx: *MD_ParseCtx, token: MD_Token, };
@func MD_Parse_BumpNext: { ctx: *MD_ParseCtx, };
@func MD_Parse_LexNext: { ctx: *MD_ParseCtx, return: MD_Token, };
@func MD_Parse_PeekSkipSome: { ctx: *MD_ParseCtx, skip_groups: MD_TokenGroups, return: MD_Token, };
@func MD_Parse_TokenMatch: { token: MD_Token, string: MD_String8, flags: MD_StringMatchFlags, return: MD_b32, };
@func MD_Parse_Require: { ctx: *MD_ParseCtx, string: MD_String8, return: MD_b32, };
@func MD_Parse_RequireKind: { ctx: *MD_ParseCtx, kind: MD_TokenKind, out_token: *MD_Token, return: MD_b32, };
@func MD_ParseOneNode: { filename: MD_String8, contents: MD_String8, return: MD_ParseResult, };
@func MD_ParseWholeString: { filename: MD_String8, contents: MD_String8, return: MD_ParseResult, };
@func MD_ParseWholeFile: { filename: MD_String8, return: MD_ParseResult, };
//////////////////////////////// //~ Tree/List Building
@func MD_NodeIsNil: { node: *MD_Node, return: MD_b32, };
@func MD_NilNode: { return: *MD_Node, };
@func MD_MakeNodeFromToken: { kind: MD_NodeKind, filename: MD_String8, file: *MD_u8, at: *MD_u8, token: MD_Token, return: *MD_Node, };
@func MD_MakeNodeFromString: { kind: MD_NodeKind, filename: MD_String8, file: *MD_u8, at: *MD_u8, string: MD_String8 return: *MD_Node, };
@func MD_PushSibling: { first: **MD_Node, last: **MD_Node, parent: *MD_Node, new_sibling: *MD_Node, };
@func MD_PushChild: { parent: *MD_Node, new_child: *MD_Node, };
@func MD_PushTag: { node: *MD_Node, tag: *MD_Node, };
//////////////////////////////// //~ Introspection Helpers
@func MD_NodeFromString: { first: *MD_Node, last: *MD_Node, string: MD_String8, return: *MD_Node, };
@func MD_NodeFromIndex: { first: *MD_Node, last: *MD_Node, n: int, return: *MD_Node, };
@func MD_IndexFromNode: { node: *MD_Node, return: int, };
@func MD_NextNodeSibling: { last: *MD_Node, string: MD_String8, return: *MD_Node, };
@func MD_ChildFromString: { node: *MD_Node, child_string: MD_String8, return: *MD_Node, };
@func MD_TagFromString: { node: *MD_Node, tag_string: MD_String8, return: *MD_Node, };
@func MD_ChildFromIndex: { node: *MD_Node, n: int, return: *MD_Node, };
@func MD_TagFromIndex: { node: *MD_Node, n: int, return: *MD_Node, };
@func MD_TagArgFromIndex: { node: *MD_Node, tag_string: MD_String8, n: int, return: *MD_Node, };
@func MD_NodeHasTag: { node: *MD_Node, tag_string: MD_String8, return: MD_b32, };
@func MD_CodeLocFromNode: { node: *MD_Node, return: MD_CodeLoc, };
@func MD_ChildCountFromNode: { node: *MD_Node, return: MD_i64, };
@func MD_TagCountFromNode: { node: *MD_Node, return: MD_i64, };
@macro MD_EachNode: { it, first, };
//////////////////////////////// //~ Error/Warning Helpers
@func MD_NodeMessage: { node: *MD_Node, kind: MD_MessageKind, str: MD_String8, };
@func MD_NodeMessageF: { node: *MD_Node, kind: MD_MessageKind, fmt: *char, "..." };
//////////////////////////////// //~ Tree Comparison/Verification
@func MD_NodeMatch: { a: *MD_Node, b: *MD_Node, str_flags: MD_StringMatchFlags, node_flags: MD_NodeMatchFlags, return: MD_b32, };
@func MD_NodeDeepMatch: { a: *MD_Node, b: *MD_Node, str_flags: MD_StringMatchFlags, node_flags: MD_NodeMatchFlags, return: MD_b32, };
//////////////////////////////// //~ Expression and Type-Expression Helper
@func MD_NilExpr: { return: *MD_Expr, };
@func MD_ExprIsNil: { expr: *MD_Expr, return: MD_b32, };
@func MD_PreUnaryExprKindFromNode: { node: *MD_Node, return: MD_ExprKind, };
@func MD_BinaryExprKindFromNode: { node: *MD_Node, return: MD_ExprKind, };
@func MD_ExprPrecFromExprKind: { kind: MD_ExprKind, return: MD_ExprPrec, };
@func MD_MakeExpr: { node: *MD_Node, kind: MD_ExprKind, left: *MD_Expr, right: *MD_Expr, return: *MD_Expr, };
@func MD_ParseAsExpr: { first: *MD_Node, last: *MD_Node, return: *MD_Expr, };
@func MD_ParseAsType: { first: *MD_Node, last: *MD_Node, return: *MD_Expr, };
@func MD_EvaluateExpr_I64: { expr: *MD_Expr, return: MD_i64, };
@func MD_EvaluateExpr_F64: { expr: *MD_Expr, return: MD_f64, };
@func MD_ExprMatch: { a: *MD_Expr, b: *MD_Expr, str_flags: MD_StringMatchFlags, return: MD_b32, };
@func MD_ExprDeepMatch: { a: *MD_Expr, b: *MD_Expr, str_flags: MD_StringMatchFlags, return: MD_b32, };
//////////////////////////////// //~ Generation
@func MD_OutputTree: { file: *FILE, node: *MD_Node, };
//////////////////////////////// //~ C Language Generation
@func MD_OutputTree_C_String: { file: *FILE, node: *MD_Node, };
@func MD_OutputTree_C_Struct: { file: *FILE, node: *MD_Node, };
@func MD_OutputTree_C_Decl: { file: *FILE, node: *MD_Node, };
@func MD_Output_C_DeclByNameAndType: { file: *FILE, name: MD_String8, type: *MD_Expr, };
@func MD_OutputExpr: { file: *FILE, expr: *MD_Expr, };
@func MD_OutputExpr_C: { file: *FILE, expr: *MD_Expr, };
@func MD_OutputType: { file: *FILE, type: *MD_Expr, };
@func MD_OutputType_C_LHS: { file: *FILE, type: *MD_Expr, };
@func MD_OutputType_C_RHS: { file: *FILE, type: *MD_Expr, };
//////////////////////////////// //~ Command Line Argument Helper
@func MD_CommandLine_Start: { argument_count: int, arguments: **char, return: MD_CommandLine, };
@func MD_CommandLine_Flag: { cmdln: *MD_CommandLine, string: MD_String8, return: MD_b32, };
@func MD_CommandLine_FlagStrings: { cmdln: *MD_CommandLine, string: MD_String8, out_count: int, out: *MD_String8, return: MD_b32, };
@func MD_CommandLine_FlagIntegers: { cmdln: *MD_CommandLine, string: MD_String8, out_count: int, out: *MD_i64, return: MD_b32, };
@func MD_CommandLine_FlagString: { cmdln: *MD_CommandLine, string: MD_String8, out: *MD_String8, return: MD_b32, };
@func MD_CommandLine_FlagInteger: { cmdln: *MD_CommandLine, string: MD_String8, out: *MD_i64, return: MD_b32, };
@func MD_CommandLine_Increment: { cmdln: *MD_CommandLine, string_ptr: **MD_String8, return: MD_b32, };
//////////////////////////////// //~ File System
@func MD_LoadEntireFile: { filename: MD_String8, return: MD_String8, };
@func MD_FileIterIncrement: { it: *MD_FileIter, path: MD_String8, out_info: *MD_FileInfo, return: MD_b32, };