diff --git a/docs/metadesk_reference.md b/docs/metadesk_reference.md index 583a326..f7e269f 100644 --- a/docs/metadesk_reference.md +++ b/docs/metadesk_reference.md @@ -96,9 +96,9 @@ main: @send(Strings) @doc("This type is implemented as a singly linked list with an MD_String8 at each node.") -@see(MD_PushStringToList) -@see(MD_SplitString) -@see(MD_JoinStringList) +@see(MD_S8ListPush) +@see(MD_S8Split) +@see(MD_S8ListJoin) @struct MD_String8List: { @doc("The number of nodes in the list.") node_count: MD_u64, @@ -156,9 +156,9 @@ main: @send(Strings) @doc("This type is used to report the results of consuming one character from a unicode encoded stream.") -@see(MD_CodepointFromUtf8) -@see(MD_CodepointFromUtf16) -@struct MD_UnicodeConsume: { +@see(MD_DecodeCodepointFromUtf8) +@see(MD_DecodeCodepointFromUtf16) +@struct MD_DecodedCodepoint: { @doc("The codepoint of the consumed character.") codepoint: MD_u32, @@ -167,8 +167,8 @@ main: }; @send(Strings) -@doc("These constants control how MD_StyledStringFromString forms strings.") -@enum MD_WordStyle: { +@doc("These constants control how MD_S8Stylize forms strings.") +@enum MD_IdentifierStyle: { @doc("Also known as @code 'PascalCase'. Creates identifiers that look like: @code `ExampleIdentifier`") UpperCamelCase, @doc("Creates identifiers that look like: @code `exampleIdentifier`") @@ -284,14 +284,14 @@ main: @doc("The string of the token labeling this node, after processing. Processing removing quote marks that delimits string literals and character literals") string: MD_String8, @doc("The raw string of the token labeling this node.") - whole_string: MD_String8, + raw_string: MD_String8, @doc("A hash of the string field using the metadesk built in hash function.") string_hash: MD_u64, @doc("The raw string of the comment token before this node, if there is one.") - comment_before: MD_String8, + prev_comment: MD_String8, @doc("The raw string of the comment token after this node, if there is one.") - comment_after: MD_String8, + next_comment: MD_String8, @doc("The byte-offset into the string from which this node was parsed. Used for producing data for an MD_CodeLoc.") offset: MD_u64, @@ -404,7 +404,7 @@ main: @doc("The contents of this token, not including any boundary characters.") string: MD_String8; @doc("The full contents of the string used to form this token, including all boundary characters.") - outer_string: MD_String8; + raw_string: MD_String8; }; //////////////////////////////// @@ -425,9 +425,9 @@ main: @send(Parsing) @doc("This type encodes information about messages.") -@struct MD_Error: { +@struct MD_Message: { @doc("A pointer to the next error, in a chain of errors. This is @code '0' when it is the last error in a chain.") - next: *MD_Error, + next: *MD_Message, @doc("The node that this message refers to.") node: *MD_Node, @doc("This message's kind.") @@ -438,22 +438,22 @@ main: @send(Parsing) @doc("This type is for a chain of error messages, with data about the entire list.") -@struct MD_ErrorList: +@struct MD_MessageList: { @doc("""The "worst" message kind in this chain, where a message kind is "worse" than another if it has a higher numeric value (if it is defined later in MD_MessageKind) than another.""") - max_error_kind: MD_MessageKind; + max_message_kind: MD_MessageKind; @doc("The number of errors in this list.") node_count: MD_u64; @doc("The first error in the list.") - first: *MD_Error; + first: *MD_Message; @doc("The last error in the list.") - last: *MD_Error; + last: *MD_Message; } @send(Parsing) @struct MD_ParseResult: { node: *MD_Node; - first_error: *MD_Error; + first_error: *MD_Message; bytes_parse: MD_u64; }; @@ -482,9 +482,9 @@ main: @doc("The last node, in a chain, produced by the parser, when the parsing call is capable of returning many nodes.") last_node: *MD_Node; @doc("The number of bytes processed by the parser. Any bytes after this number, in the string that was passed to the parser, were not considered.") - bytes_parsed: MD_u64; + string_advance: MD_u64; @doc("The list of errors produced by the parser when parsing the provided string.") - errors: MD_ErrorList; + errors: MD_MessageList; } //////////////////////////////// @@ -492,12 +492,12 @@ main: @send(CommandLineHelper) @doc("A type used to encode parsed command line options, that can have values associated with them.") -@see(MD_CommandLine) -@see(MD_CommandLineFromOptions) -@struct MD_CommandLineOption: +@see(MD_CmdLine) +@see(MD_MakeCmdLineFromOptions) +@struct MD_CmdLineOption: { @doc("A pointer to the next option, if this is within a chain of options. Will be @code '0' if this is the last option in a chain.") - next: *MD_CommandLineOption; + next: *MD_CmdLineOption; @doc("The name of this option.") name: MD_String8; @doc("The values associated with this option.") @@ -506,17 +506,17 @@ main: @send(CommandLineHelper) @doc("The type encoding a fully parsed set of command line options.") -@see(MD_CommandLineFromOptions) -@struct MD_CommandLine: +@see(MD_MakeCmdLineFromOptions) +@struct MD_CmdLine: { @doc("The list of all command line arguments, as an unstructured list of strings.") arguments: MD_String8List; @doc("The list of arguments that were not parsed as structured options (which are a name, with an optional set of values).") - inputs: MD_String8List; + raw_arguments: MD_String8List; @doc("The first option that was parsed, forming the head of a chain of options.") - first_option: *MD_CommandLineOption; + first_option: *MD_CmdLineOption; @doc("The last option that was parsed.") - last_option: *MD_CommandLineOption; + last_option: *MD_CmdLineOption; }; //////////////////////////////// @@ -758,7 +758,7 @@ main: @send(Characters) @doc("Return a @code '/' if @code '\\' is passed in, otherwise just returns the passed character.") -@func MD_CorrectSlash: { +@func MD_CharToForwardSlash: { c: MD_u8, return: MD_u8, }; @@ -791,14 +791,14 @@ main: @send(Strings) @doc("Constructs an MD_String8 from two pointers into the same buffer, corresponding to the beginning and one past the last byte of a string.") @func MD_S8Range: { - str: *MD_u8, + first: *MD_u8, opl: *MD_u8, return: MD_String8, }; @send(Strings) @doc("Returns an MD_String8 encoding a sub-range of the passed MD_String8.") -@func MD_StringSubstring: { +@func MD_S8Substring: { @doc("The string for which the substring is returned.") str: MD_String8, @doc("The offset, from the passed string's base, of the first character of the returned substring.") @@ -810,7 +810,7 @@ main: @send(Strings) @doc("Returns a sub-range of the passed MD_String8, skipping the first @code 'min' bytes.") -@func MD_StringSkip: { +@func MD_S8Skip: { @doc("The string for which the substring is returned.") str: MD_String8, @doc("The new minimum offset, relative to the base of @code 'str'. Also the number of bytes to skip at the beginning of @code 'str'.") @@ -820,7 +820,7 @@ main: @send(Strings) @doc("Returns a sub-range of the passed MD_String8, chopping off the last @code 'min' bytes.") -@func MD_StringChop: { +@func MD_S8Chop: { @doc("The string for which the substring is returned.") str: MD_String8, @doc("The number of bytes to chop off at the end of @code 'str'.") @@ -830,7 +830,7 @@ main: @send(Strings) @doc("Returns a prefix of the passed MD_String8.") -@func MD_StringPrefix: { +@func MD_S8Prefix: { @doc("The string for which the substring is returned.") str: MD_String8, @doc("The desired size of the returned prefix.") @@ -840,7 +840,7 @@ main: @send(Strings) @doc("Returns a suffix of the passed MD_String8.") -@func MD_StringSuffix: { +@func MD_S8Suffix: { @doc("The string for which the substring is returned.") str: MD_String8, @doc("The desired size of the returned suffix.") @@ -850,7 +850,7 @@ main: @send(Strings) @doc("Compares the passed strings @code 'a' and @code 'b', and determines whether or not the two strings match. The passed MD_MatchFlags argument will modify the string matching algorithm; for example, allowing case insensitivity. Return @code '1' if the strings are found to match, and @code '0' otherwise.") -@func MD_StringMatch: { +@func MD_S8Match: { @doc("The first string to compare.") a: MD_String8, @doc("The second string to compare.") @@ -863,7 +863,7 @@ main: @send(Strings) @doc("Searches @code 'str' for an occurrence of @code 'substring'. The passed @code 'flags' can be used to modify the matching rules. Returns the position at which the search ended; if the return value is equivalent to @code 'str.size', then the substring was not found.") -@func MD_FindSubstring: { +@func MD_S8FindSubstring: { @doc("The string to search within for the substring.") str: MD_String8, @doc("The 'needle' string to find within @code 'str'.") @@ -878,64 +878,64 @@ main: @send(Strings) @doc("Searches @code 'string' for the last @code '.' character occurring in the string, and chops the @code '.' and anything following after it off of the returned string.") -@see(MD_StringChop) -@func MD_ChopExtension: { +@see(MD_S8Chop) +@func MD_PathChopLastPeriod: { string: MD_String8, return: MD_String8, }; @send(Strings) @doc("Searches @code 'string' for the last @code '/' or @code '\' character occurring in the string, and skips it and anything before it in the returned string.") -@see(MD_StringSkip) -@func MD_SkipFolder: { +@see(MD_S8Skip) +@func MD_PathSkipLastSlash: { string: MD_String8, return: MD_String8, }; @send(Strings) @doc("Searches @code 'string' for the last @code '.' character, and returns the substring starting at the character after it, to the end of the string. For usual file naming schemes where the extension of a file is encoded by any characters following the last @code '.' of a filename, this will return the extension.") -@see(MD_FolderFromPath) -@see(MD_StringSuffix) -@see(MD_StringSubstring) -@see(MD_StringChop) -@func MD_ExtensionFromPath: { +@see(MD_PathChopLastSlash) +@see(MD_S8Suffix) +@see(MD_S8Substring) +@see(MD_S8Chop) +@func MD_PathSkipLastPeriod: { string: MD_String8, return: MD_String8, }; @send(Strings) @doc("Searches @code 'string' for the last @code '/' or @code '\\' character, and returns the substring that ends with that character. For usual file naming schemes where folders are encoded with @code '/' or @code '\\' characters, this will return the entire path to the passed filename, not including the filename itself.") -@see(MD_ExtensionFromPath) -@see(MD_StringPrefix) -@see(MD_StringSubstring) -@see(MD_StringSkip) -@func MD_FolderFromPath: { +@see(MD_PathSkipLastPeriod) +@see(MD_S8Prefix) +@see(MD_S8Substring) +@see(MD_S8Skip) +@func MD_PathChopLastSlash: { string: MD_String8, return: MD_String8, }; @send(Strings) @doc("Copies @code 'string' by allocating an entirely new portion of memory and copying the passed string's memory to the newly allocated memory. Returns the copy of @code 'string' using the new memory.") -@func MD_PushStringCopy: { +@func MD_S8Copy: { string: MD_String8, return: MD_String8, }; @send(Strings) -@doc("Allocates a new string, with the contents of the string being determined by a mostly-standard C formatting string passed in @code 'fmt', with a variable-argument list being passed in @code 'args'. Used when composing variable argument lists at multiple levels, and when you need to pass a @code 'va_list'. The format string is non-standard because it allows @code '%S' as a specifier for MD_String8 arguments. Before this call, it is expected that you call @code 'va_start' on the passed @code 'va_list', and also that you call @code 'va_end' after the function returns. If you just want to pass variable arguments yourself (instead of a @code 'va_list'), then see MD_PushStringF.") -@see(MD_PushStringF) -@see(MD_PushStringCopy) -@func MD_PushStringFV: { +@doc("Allocates a new string, with the contents of the string being determined by a mostly-standard C formatting string passed in @code 'fmt', with a variable-argument list being passed in @code 'args'. Used when composing variable argument lists at multiple levels, and when you need to pass a @code 'va_list'. The format string is non-standard because it allows @code '%S' as a specifier for MD_String8 arguments. Before this call, it is expected that you call @code 'va_start' on the passed @code 'va_list', and also that you call @code 'va_end' after the function returns. If you just want to pass variable arguments yourself (instead of a @code 'va_list'), then see MD_S8Fmt.") +@see(MD_S8Fmt) +@see(MD_S8Copy) +@func MD_S8FmtV: { fmt: *char, args: va_list, return: MD_String8, }; @send(Strings) -@doc("Allocates a new string, with the contents of the string being determined by a mostly-standard C formatting string passed in @code 'fmt', with variable arguments fitting the expected ones in @code 'fmt' being passed in after. The format string is non-standard because it allows @code '%S' as a specifier for MD_String8 arguments. If you are composing this with your own variable-arguments call, use MD_PushStringFV instead.") -@see(MD_PushStringFV) -@see(MD_PushStringCopy) -@func MD_PushStringF: { +@doc("Allocates a new string, with the contents of the string being determined by a mostly-standard C formatting string passed in @code 'fmt', with variable arguments fitting the expected ones in @code 'fmt' being passed in after. The format string is non-standard because it allows @code '%S' as a specifier for MD_String8 arguments. If you are composing this with your own variable-arguments call, use MD_S8FmtV instead.") +@see(MD_S8FmtV) +@see(MD_S8Copy) +@func MD_S8Fmt: { fmt: *char, "...", return: MD_String8, @@ -944,14 +944,14 @@ main: @send(Strings) @doc("This is a helper macro that is normally used with passing an MD_String8 into a @code 'printf' like function, usually used in combination with the @code '%.*s' format specifier. Metadesk uses length-based strings, not null-terminated (like many C functions expect), so this is often convenient when interacting with C-like APIs. This will expand to passing the size of the passed string first, a comma, and the pointer to the base of the string being passed immediately after.") @see(MD_String8) -@macro MD_StringExpand: { s, } +@macro MD_S8VArg: { s, } @send(Strings) @doc("Pushes a new MD_String8 to an MD_String8List by allocating a new MD_String8Node, filling it with @code 'string', and modifying the existing list elements in @code 'list' to end with the newly allocated node.") @see(MD_String8List) @see(MD_String8Node) @see(MD_String8) -@func MD_PushStringToList: { +@func MD_S8ListPush: { list: *MD_String8List, string: MD_String8, }; @@ -961,8 +961,8 @@ main: @see(MD_String8List) @see(MD_String8Node) @see(MD_String8) -@see(MD_PushStringToList) -@func MD_PushStringListToList: { +@see(MD_S8ListPush) +@func MD_S8ListConcat: { list: *MD_String8List, to_push: *MD_String8List, }; @@ -972,8 +972,8 @@ main: @see(MD_String8) @see(MD_String8List) @see(MD_String8Node) -@see(MD_JoinStringList) -@func MD_SplitString: { +@see(MD_S8ListJoin) +@func MD_S8Split: { @doc("The string to search for splitting strings, and to subdivide.") string: MD_String8, @doc("The number of splitting strings to search for.") @@ -989,8 +989,8 @@ main: @see(MD_String8) @see(MD_String8List) @see(MD_String8Node) -@see(MD_SplitString) -@func MD_JoinStringList: { +@see(MD_S8Split) +@func MD_S8ListJoin: { list: MD_String8List, separator: MD_String8, return: MD_String8, @@ -1003,9 +1003,9 @@ main: }; @send(Strings) -@func MD_StyledStringFromString: { +@func MD_S8Stylize: { string: MD_String8, - word_style: MD_WordStyle, + word_style: MD_IdentifierStyle, separator: MD_String8, return: MD_String8 }; @@ -1056,17 +1056,17 @@ main: //~ Unicode Conversions @send(Strings) -@func MD_CodepointFromUtf8: { +@func MD_DecodeCodepointFromUtf8: { str: MD_u8, max: MD_u64, - return: MD_UnicodeConsume, + return: MD_DecodedCodepoint, }; @send(Strings) -@func MD_CodepointFromUtf16: { +@func MD_DecodeCodepointFromUtf16: { str: *MD_u16, max: MD_u64, - return: MD_UnicodeConsume, + return: MD_DecodedCodepoint, }; @send(Strings) @@ -1111,13 +1111,13 @@ main: //~ Map Table Data Structure @send(Map) -@func MD_HashString: { +@func MD_HashStr: { string: MD_String8, return: MD_u64, }; @send(Map) -@func MD_HashPointer: { +@func MD_HashPtr: { p: *void, }; @@ -1199,8 +1199,8 @@ MD_LexAdvanceFromSkips: } @send(Parsing) @func -@doc("Allocates and initializes an MD_Error associated with a particular MD_Node.") -@see(MD_Error) +@doc("Allocates and initializes an MD_Message associated with a particular MD_Node.") +@see(MD_Message) MD_MakeNodeError: { @doc("The node associated with the message.") @@ -1209,12 +1209,12 @@ MD_MakeNodeError: kind: MD_MessageKind; @doc("The string for the message.") str: MD_String8; - return: *MD_Error + return: *MD_Message } @send(Parsing) @func -@doc("Allocates and initializes an MD_Error associated with a particular MD_Token.") -@see(MD_Error) +@doc("Allocates and initializes an MD_Message associated with a particular MD_Token.") +@see(MD_Message) MD_MakeTokenError: { @doc("The entire string that is being parsed. The parser used a substring of this string to form @code 'token'.") @@ -1225,27 +1225,27 @@ MD_MakeTokenError: kind: MD_MessageKind; @doc("The string for the message.") str: MD_String8; - return: *MD_Error; + return: *MD_Message; } @send(Parsing) @func -@doc("Pushes a constructed MD_Error into an MD_ErrorList.") -@see(MD_Error) -@see(MD_ErrorList) -MD_PushErrorToList: +@doc("Pushes a constructed MD_Message into an MD_MessageList.") +@see(MD_Message) +@see(MD_MessageList) +MD_MessageListPush: { - list: *MD_ErrorList; - error: *MD_Error; + list: *MD_MessageList; + error: *MD_Message; } @send(Parsing) @func -@see(MD_Error) -@see(MD_ErrorList) +@see(MD_Message) +@see(MD_MessageList) @doc("Pushes the contents of @code 'to_push' into @code 'list'. Zeroes @code 'to_push'; the memory used in forming @code 'to_push' will be used in @code 'list', and nothing will be copied.") -MD_PushErrorListToList: +MD_MessageListConcat: { - list: *MD_ErrorList; - to_push: *MD_ErrorList; + list: *MD_MessageList; + to_push: *MD_MessageList; } @send(Parsing) @func @@ -1321,7 +1321,7 @@ MD_ParseWholeFile: @send(CodeLoc) @doc("Calculates a position in a source code file in filename/line/column coordinates, provided a filename, a base pointer for the file's contents, and an offset into the file's contents.") @see(MD_CodeLocFromNode) -@func MD_CodeLocFromFileBaseOffset: +@func MD_CodeLocFromFileOffset: { filename: MD_String8, base: *MD_u8, @@ -1331,7 +1331,7 @@ MD_ParseWholeFile: @send(CodeLoc) @doc("Calculates a position in a source code file in filename/line/column coordinates, provided a parsed MD_Node.") -@see(MD_CodeLocFromFileBaseOffset) +@see(MD_CodeLocFromFileOffset) @func MD_CodeLocFromNode: { node: *MD_Node, @@ -1372,7 +1372,7 @@ MD_ParseWholeFile: @send(Nodes) @doc("Creates a new reference node, pointing at @code 'target', and links it up as a child of @code 'list'.") -@func MD_PushReference: { +@func MD_PushNewReference: { list: *MD_Node, target: *MD_Node, return: *MD_Node, @@ -1384,7 +1384,7 @@ MD_ParseWholeFile: @send(Nodes) @doc("Finds a node in the range defined by @code 'first' and @code 'one_past_last', with the string matching @code 'string' in accordance with @code 'flags', or returns a nil node pointer if it is not found.") @see(MD_NodeFromIndex) -@see(MD_StringMatch) +@see(MD_S8Match) @func MD_NodeFromString: { @doc("The first node in the range to search.") first: *MD_Node, @@ -1573,10 +1573,10 @@ MD_ParseWholeFile: @send(Nodes) @doc("Prints a message to @code 'out', corresponding with the source code location encoded by @code 'loc'.") -@see(MD_MessageF) -@see(MD_NodeMessage) -@see(MD_NodeMessageF) -@func MD_Message: { +@see(MD_PrintMessageFmt) +@see(MD_PrintNodeMessage) +@see(MD_PrintNodeMessageFmt) +@func MD_PrintMessage: { @doc("The file to print the message to.") out: *FILE, @doc("The source code location for which the message is intended.") @@ -1589,10 +1589,10 @@ MD_ParseWholeFile: @send(Nodes) @doc("Prints a C format string message to @code 'out', corresponding with the source code location encoded by @code 'loc'.") -@see(MD_Message) -@see(MD_NodeMessage) -@see(MD_NodeMessageF) -@func MD_MessageF: { +@see(MD_PrintMessage) +@see(MD_PrintNodeMessage) +@see(MD_PrintNodeMessageFmt) +@func MD_PrintMessageFmt: { @doc("The file to print the message to.") out: *FILE, @doc("The source code location for which the message is intended.") @@ -1605,11 +1605,11 @@ MD_ParseWholeFile: }; @send(Nodes) -@see(MD_Message) -@see(MD_MessageF) -@see(MD_NodeMessageF) +@see(MD_PrintMessage) +@see(MD_PrintMessageFmt) +@see(MD_PrintNodeMessageFmt) @doc("Prints a message to @code 'out', corresponding with the source code location of @code 'node'.") -@func MD_NodeMessage: { +@func MD_PrintNodeMessage: { @doc("The file to print the message to.") out: *FILE, @doc("The node for which the message is intended.") @@ -1622,10 +1622,10 @@ MD_ParseWholeFile: @send(Nodes) @doc("Prints a C format string message to @code 'out', corresponding with the source code location of @code 'node'.") -@see(MD_Message) -@see(MD_MessageF) -@see(MD_NodeMessage) -@func MD_NodeMessageF: { +@see(MD_PrintMessage) +@see(MD_PrintMessageFmt) +@see(MD_PrintNodeMessage) +@func MD_PrintNodeMessageFmt: { @doc("The file to print the message to.") out: *FILE, @doc("The node for which the message is intended.") @@ -1642,7 +1642,7 @@ MD_ParseWholeFile: @send(Nodes) @doc("Compares the passed MD_Node nodes @code 'a' and @code 'b', and determines whether or not they match. @code 'flags' determines the rules used in the matching algorithm, including tag-sensitivity and case-sensitivity.") -@see(MD_StringMatch) +@see(MD_S8Match) @see(MD_MatchFlags) @func MD_NodeMatch: { a: *MD_Node, @@ -1665,7 +1665,7 @@ MD_ParseWholeFile: @send(Output) @doc("Outputs a textual representation of the tree with @code 'node' as its root to @code 'file'.") -@func MD_OutputTree: { +@func MD_DebugOutputTree: { file: *FILE, node: *MD_Node, }; @@ -1675,7 +1675,7 @@ MD_ParseWholeFile: @send(CommandLineHelper) @doc("Converts a traditional C-style @code 'argc, argv' pair into an MD_String8List.") -@see(MD_CommandLineFromOptions) +@see(MD_MakeCmdLineFromOptions) @func MD_StringListFromArgCV: { @doc("The number of command line arguments. Traditionally referred to as @code 'argc'.") @@ -1688,46 +1688,46 @@ MD_ParseWholeFile: @send(CommandLineHelper) @doc("Parses an MD_String8List as a set of command line options.") @see(MD_StringListFromArgCV) -@see(MD_CommandLineOptionValues) -@see(MD_CommandLineOptionPassed) -@func MD_CommandLineFromOptions: +@see(MD_CmdLineValuesFromString) +@see(MD_CmdLineB32FromString) +@func MD_MakeCmdLineFromOptions: { options: MD_String8List; - return: MD_CommandLine; + return: MD_CmdLine; } @send(CommandLineHelper) @doc("Gets the list of values associated with @code 'name' in the parsed command line arguments.") -@see(MD_CommandLineFromOptions) -@see(MD_CommandLineOptionPassed) -@see(MD_CommandLineOptionI64) -@func MD_CommandLineOptionValues: +@see(MD_MakeCmdLineFromOptions) +@see(MD_CmdLineB32FromString) +@see(MD_CmdLineI64FromString) +@func MD_CmdLineValuesFromString: { - cmdln: MD_CommandLine; + cmdln: MD_CmdLine; name: MD_String8; return: MD_String8List; } @send(CommandLineHelper) @doc("Determines whether a command line argument explicitly passed an option matching @code 'name'.") -@see(MD_CommandLineFromOptions) -@see(MD_CommandLineOptionPassed) -@see(MD_CommandLineOptionValues) -@func MD_CommandLineOptionPassed: +@see(MD_MakeCmdLineFromOptions) +@see(MD_CmdLineB32FromString) +@see(MD_CmdLineValuesFromString) +@func MD_CmdLineB32FromString: { - cmdln: MD_CommandLine; + cmdln: MD_CmdLine; name: MD_String8; return: MD_b32; } @send(CommandLineHelper) -@see(MD_CommandLineFromOptions) -@see(MD_CommandLineOptionValues) -@see(MD_CommandLineOptionPassed) +@see(MD_MakeCmdLineFromOptions) +@see(MD_CmdLineValuesFromString) +@see(MD_CmdLineB32FromString) @doc("Gets the list of values associated with @code 'name' in the parsed command line arguments, treats them as a string representation of a 64-bit signed integer value, and returns that integer value.") -@func MD_CommandLineOptionI64: +@func MD_CmdLineI64FromString: { - cmdln: MD_CommandLine; + cmdln: MD_CmdLine; name: MD_String8; return: MD_i64; } diff --git a/intro_notes.txt b/intro_notes.txt index 8dc1d18..ab9a536 100644 --- a/intro_notes.txt +++ b/intro_notes.txt @@ -1,5 +1,5 @@ inspecting error information -MD_CodeLocFromNode, (MD_Node from MD_Error) +MD_CodeLocFromNode, (MD_Node from MD_Message) nil nodes tips on generating C concat diff --git a/samples/c_code_generation.c b/samples/c_code_generation.c index 63053df..e91b2de 100644 --- a/samples/c_code_generation.c +++ b/samples/c_code_generation.c @@ -22,7 +22,7 @@ int main(int argument_count, char **arguments) MD_Node *code = MD_ParseWholeString(MD_S8Lit("Generated Test Code"), example_code).node; printf("Source Metadesk Code:\n"); - printf("%.*s\n\n", MD_StringExpand(example_code)); + printf("%.*s\n\n", MD_S8VArg(example_code)); printf("Generated C Code:\n"); for(MD_EachNode(node, code->first_child)) diff --git a/samples/node_errors/node_errors.c b/samples/node_errors/node_errors.c index 3cb929e..5b37f38 100644 --- a/samples/node_errors/node_errors.c +++ b/samples/node_errors/node_errors.c @@ -10,16 +10,16 @@ int main(int argument_count, char **arguments) for(int i = 1; i < argument_count; i += 1) { MD_Node *root = MD_ParseWholeFile(MD_S8CString(arguments[i])).node; - MD_PushReference(list, root); + MD_PushNewReference(list, root); } // NOTE(rjf): Print errors on every single node. for(MD_EachNode(ref, list->first_child)) { - MD_Node *root = MD_Deref(ref); + MD_Node *root = MD_NodeFromReference(ref); for(MD_EachNode(node, root->first_child)) { - MD_NodeMessageF(stderr, node, MD_MessageKind_Error, "This node has an error!"); + MD_PrintNodeMessageFmt(stderr, node, MD_MessageKind_Error, "This node has an error!"); } } diff --git a/samples/old_style_custom_layer.c b/samples/old_style_custom_layer.c index 94bf130..b49e365 100644 --- a/samples/old_style_custom_layer.c +++ b/samples/old_style_custom_layer.c @@ -28,14 +28,14 @@ int main(int argument_count, char **arguments) for(int i = 1; i < argument_count; i += 1) { MD_Node *root = MD_ParseWholeFile(MD_S8CString(arguments[i])).node; - MD_PushReference(list, root); + MD_PushNewReference(list, root); } // NOTE(rjf): Call "custom layer" back. Initialize(); for(MD_EachNode(ref, list->first_child)) { - MD_Node *root = MD_Deref(ref); + MD_Node *root = MD_NodeFromReference(ref); for(MD_EachNode(node, root->first_child)) { TopLevel(node); diff --git a/samples/output_parse/examples/output/parsed_example.txt b/samples/output_parse/examples/output/parsed_example.txt index f6824a5..f8180fc 100644 --- a/samples/output_parse/examples/output/parsed_example.txt +++ b/samples/output_parse/examples/output/parsed_example.txt @@ -1,22 +1,22 @@ Node { - Kind: Label, + Kind: Main, Flags: 0000110000000001000000000000000000000000000000000000000000000000, - Flag Names: BraceLeft, BraceRight, Identifier, + Flag Names: HasBraceLeft, HasBraceRight, Identifier, String: foo, Whole String: foo, Tag: @struct Node { - Kind: Label, + Kind: Main, Flags: 1100000010000001000000000000000000000000000000000000000000000000, - Flag Names: ParenLeft, ParenRight, BeforeComma, Identifier, + Flag Names: HasParenLeft, HasParenRight, IsBeforeComma, Identifier, String: x, Whole String: x, Node { - Kind: Label, + Kind: Main, Flags: 0011000000000000000000000000000000000000000000000000000000000000, - Flag Names: BracketLeft, BracketRight, + Flag Names: HasBracketLeft, HasBracketRight, Node { - Kind: Label, + Kind: Main, Flags: 0000000000000001000000000000000000000000000000000000000000000000, Flag Names: Identifier, String: MAX_PATH, @@ -24,7 +24,7 @@ Node { } } Node { - Kind: Label, + Kind: Main, Flags: 0000000000000001000000000000000000000000000000000000000000000000, Flag Names: Identifier, String: char, @@ -34,21 +34,21 @@ Node { } Node { - Kind: Label, + Kind: Main, Flags: 0000110000000001000000000000000000000000000000000000000000000000, - Flag Names: BraceLeft, BraceRight, Identifier, + Flag Names: HasBraceLeft, HasBraceRight, Identifier, String: bar, Whole String: bar, Tag: @struct Tag: @test_tag Node { - Kind: Label, + Kind: Main, Flags: 0000000000000001000000000000000000000000000000000000000000000000, Flag Names: Identifier, String: y, Whole String: y, Node { - Kind: Label, + Kind: Main, Flags: 0000000000000001000000000000000000000000000000000000000000000000, Flag Names: Identifier, String: float, @@ -56,13 +56,13 @@ Node { } } Node { - Kind: Label, + Kind: Main, Flags: 0000000000000001000000000000000000000000000000000000000000000000, Flag Names: Identifier, String: z, Whole String: z, Node { - Kind: Label, + Kind: Main, Flags: 0000000000000001000000000000000000000000000000000000000000000000, Flag Names: Identifier, String: i32, diff --git a/samples/output_parse/examples/output/parsed_example2.txt b/samples/output_parse/examples/output/parsed_example2.txt index 2aa89b4..7c82c01 100644 --- a/samples/output_parse/examples/output/parsed_example2.txt +++ b/samples/output_parse/examples/output/parsed_example2.txt @@ -1,138 +1,138 @@ Node { - Kind: Label, + Kind: Main, Flags: 0000110000000001000000000000000000000000000000000000000000000000, - Flag Names: BraceLeft, BraceRight, Identifier, + Flag Names: HasBraceLeft, HasBraceRight, Identifier, String: a_set, Whole String: a_set, Tag: @sets Node { - Kind: Label, + Kind: Main, Flags: 0000110010000001000000000000000000000000000000000000000000000000, - Flag Names: BraceLeft, BraceRight, BeforeComma, Identifier, + Flag Names: HasBraceLeft, HasBraceRight, IsBeforeComma, Identifier, String: named_set, Whole String: named_set, Node { - Kind: Label, + Kind: Main, Flags: 0000000010000010000000000000000000000000000000000000000000000000, - Flag Names: BeforeComma, Numeric, + Flag Names: IsBeforeComma, Numeric, String: 1, Whole String: 1, } Node { - Kind: Label, + Kind: Main, Flags: 0000000011000010000000000000000000000000000000000000000000000000, - Flag Names: BeforeComma, AfterComma, Numeric, + Flag Names: IsBeforeComma, IsAfterComma, Numeric, String: 3, Whole String: 3, } Node { - Kind: Label, + Kind: Main, Flags: 0000000001000010000000000000000000000000000000000000000000000000, - Flag Names: AfterComma, Numeric, + Flag Names: IsAfterComma, Numeric, String: 7, Whole String: 7, } } Node { - Kind: Label, + Kind: Main, Flags: 0000110011000000000000000000000000000000000000000000000000000000, - Flag Names: BraceLeft, BraceRight, BeforeComma, AfterComma, + Flag Names: HasBraceLeft, HasBraceRight, IsBeforeComma, IsAfterComma, Node { - Kind: Label, + Kind: Main, Flags: 0000000010000001000000000000000000000000000000000000000000000000, - Flag Names: BeforeComma, Identifier, + Flag Names: IsBeforeComma, Identifier, String: not, Whole String: not, } Node { - Kind: Label, + Kind: Main, Flags: 0000000011000001000000000000000000000000000000000000000000000000, - Flag Names: BeforeComma, AfterComma, Identifier, + Flag Names: IsBeforeComma, IsAfterComma, Identifier, String: named, Whole String: named, } Node { - Kind: Label, + Kind: Main, Flags: 0000000001000001000000000000000000000000000000000000000000000000, - Flag Names: AfterComma, Identifier, + Flag Names: IsAfterComma, Identifier, String: set, Whole String: set, } } Node { - Kind: Label, + Kind: Main, Flags: 0000110011000000000000000000000000000000000000000000000000000000, - Flag Names: BraceLeft, BraceRight, BeforeComma, AfterComma, + Flag Names: HasBraceLeft, HasBraceRight, IsBeforeComma, IsAfterComma, Tag: @tag_with_params Tag Children{ Node { - Kind: Label, + Kind: Main, Flags: 0000000010000001000000000000000000000000000000000000000000000000, - Flag Names: BeforeComma, Identifier, + Flag Names: IsBeforeComma, Identifier, String: p1, Whole String: p1, } Node { - Kind: Label, + Kind: Main, Flags: 0000000011000001000000000000000000000000000000000000000000000000, - Flag Names: BeforeComma, AfterComma, Identifier, + Flag Names: IsBeforeComma, IsAfterComma, Identifier, String: p2, Whole String: p2, } Node { - Kind: Label, + Kind: Main, Flags: 0000000001000001000000000000000000000000000000000000000000000000, - Flag Names: AfterComma, Identifier, + Flag Names: IsAfterComma, Identifier, String: p3, Whole String: p3, } } Node { - Kind: Label, + Kind: Main, Flags: 0000000010000001000000000000000000000000000000000000000000000000, - Flag Names: BeforeComma, Identifier, + Flag Names: IsBeforeComma, Identifier, String: e1, Whole String: e1, } Node { - Kind: Label, + Kind: Main, Flags: 0000000011000001000000000000000000000000000000000000000000000000, - Flag Names: BeforeComma, AfterComma, Identifier, + Flag Names: IsBeforeComma, IsAfterComma, Identifier, String: e2, Whole String: e2, } Node { - Kind: Label, + Kind: Main, Flags: 0000000001000001000000000000000000000000000000000000000000000000, - Flag Names: AfterComma, Identifier, + Flag Names: IsAfterComma, Identifier, String: e3, Whole String: e3, } } Node { - Kind: Label, + Kind: Main, Flags: 0000110011000000000000000000000000000000000000000000000000000000, - Flag Names: BraceLeft, BraceRight, BeforeComma, AfterComma, + Flag Names: HasBraceLeft, HasBraceRight, IsBeforeComma, IsAfterComma, Tag: @tag_with_params Tag Children{ Node { - Kind: Label, + Kind: Main, Flags: 0000000010000001000000000000000000000000000000000000000000000000, - Flag Names: BeforeComma, Identifier, + Flag Names: IsBeforeComma, Identifier, String: p1, Whole String: p1, } Node { - Kind: Label, + Kind: Main, Flags: 0000000011000001000000000000000000000000000000000000000000000000, - Flag Names: BeforeComma, AfterComma, Identifier, + Flag Names: IsBeforeComma, IsAfterComma, Identifier, String: p2, Whole String: p2, } Node { - Kind: Label, + Kind: Main, Flags: 0000000001000001000000000000000000000000000000000000000000000000, - Flag Names: AfterComma, Identifier, + Flag Names: IsAfterComma, Identifier, String: p3, Whole String: p3, } @@ -140,45 +140,45 @@ Node { Tag: @tag2_with_params Tag Children{ Node { - Kind: Label, + Kind: Main, Flags: 0000000010000001000000000000000000000000000000000000000000000000, - Flag Names: BeforeComma, Identifier, + Flag Names: IsBeforeComma, Identifier, String: p, Whole String: p, } Node { - Kind: Label, + Kind: Main, Flags: 0000000011000001000000000000000000000000000000000000000000000000, - Flag Names: BeforeComma, AfterComma, Identifier, + Flag Names: IsBeforeComma, IsAfterComma, Identifier, String: pp, Whole String: pp, } Node { - Kind: Label, + Kind: Main, Flags: 0000000001000001000000000000000000000000000000000000000000000000, - Flag Names: AfterComma, Identifier, + Flag Names: IsAfterComma, Identifier, String: ppp, Whole String: ppp, } } Node { - Kind: Label, + Kind: Main, Flags: 0000000010000001000000000000000000000000000000000000000000000000, - Flag Names: BeforeComma, Identifier, + Flag Names: IsBeforeComma, Identifier, String: e1, Whole String: e1, } Node { - Kind: Label, + Kind: Main, Flags: 0000000011000001000000000000000000000000000000000000000000000000, - Flag Names: BeforeComma, AfterComma, Identifier, + Flag Names: IsBeforeComma, IsAfterComma, Identifier, String: e2, Whole String: e2, } Node { - Kind: Label, + Kind: Main, Flags: 0000000001000001000000000000000000000000000000000000000000000000, - Flag Names: AfterComma, Identifier, + Flag Names: IsAfterComma, Identifier, String: e3, Whole String: e3, } @@ -186,27 +186,27 @@ Node { } Node { - Kind: Label, + Kind: Main, Flags: 0000110000000001000000000000000000000000000000000000000000000000, - Flag Names: BraceLeft, BraceRight, Identifier, + Flag Names: HasBraceLeft, HasBraceRight, Identifier, String: empty, Whole String: empty, Tag: @empty_set } Node { - Kind: Label, + Kind: Main, Flags: 0000110000000000000000000000000000000000000000000000000000000000, - Flag Names: BraceLeft, BraceRight, + Flag Names: HasBraceLeft, HasBraceRight, Tag: @tagged_unnamed_set Node { - Kind: Label, + Kind: Main, Flags: 0000110000000001000000000000000000000000000000000000000000000000, - Flag Names: BraceLeft, BraceRight, Identifier, + Flag Names: HasBraceLeft, HasBraceRight, Identifier, String: a_label, Whole String: a_label, Node { - Kind: Label, + Kind: Main, Flags: 0000000000000001000000000000000000000000000000000000000000000000, Flag Names: Identifier, String: unnamed_set_element, @@ -216,33 +216,33 @@ Node { } Node { - Kind: Label, + Kind: Main, Flags: 0000110000000000000000000000000000000000000000000000000000000000, - Flag Names: BraceLeft, BraceRight, + Flag Names: HasBraceLeft, HasBraceRight, Tag: @showcase_mixed_set_scoping Node { - Kind: Label, + Kind: Main, Flags: 1001000010000000000000000000000000000000000000000000000000000000, - Flag Names: ParenLeft, BracketRight, BeforeComma, + Flag Names: HasParenLeft, HasBracketRight, IsBeforeComma, String: +, Whole String: +, Tag: @symbol_label Node { - Kind: Label, + Kind: Main, Flags: 0000000000000010000000000000000000000000000000000000000000000000, Flag Names: Numeric, String: 1, Whole String: 1, } Node { - Kind: Label, + Kind: Main, Flags: 0000000000000010000000000000000000000000000000000000000000000000, Flag Names: Numeric, String: 2, Whole String: 2, } Node { - Kind: Label, + Kind: Main, Flags: 0000000000000010000000000000000000000000000000000000000000000000, Flag Names: Numeric, String: 3, @@ -250,28 +250,28 @@ Node { } } Node { - Kind: Label, + Kind: Main, Flags: 0110000011000000000000000000000000000000000000000000000000000000, - Flag Names: ParenRight, BracketLeft, BeforeComma, AfterComma, + Flag Names: HasParenRight, HasBracketLeft, IsBeforeComma, IsAfterComma, String: *, Whole String: *, Tag: @symbol_label Node { - Kind: Label, + Kind: Main, Flags: 0000000000000001000000000000000000000000000000000000000000000000, Flag Names: Identifier, String: x, Whole String: x, } Node { - Kind: Label, + Kind: Main, Flags: 0000000000000001000000000000000000000000000000000000000000000000, Flag Names: Identifier, String: y, Whole String: y, } Node { - Kind: Label, + Kind: Main, Flags: 0000000000000001000000000000000000000000000000000000000000000000, Flag Names: Identifier, String: z, diff --git a/samples/output_parse/output_parse.c b/samples/output_parse/output_parse.c index 95dd903..5136b71 100644 --- a/samples/output_parse/output_parse.c +++ b/samples/output_parse/output_parse.c @@ -16,7 +16,7 @@ static void Print(FILE* file, int indent_count, char* fmt, ...) { static void PrintNode(MD_Node* node, FILE* file, int indent_count) { Print(file, indent_count, "Node {\n"); - Print(file, indent_count+1, "Kind: %.*s,\n", MD_StringExpand(MD_StringFromNodeKind(node->kind))); + Print(file, indent_count+1, "Kind: %.*s,\n", MD_S8VArg(MD_StringFromNodeKind(node->kind))); int flags_bits = sizeof(node->flags)*8; char binary_flags[sizeof(node->flags)*8+1]; @@ -32,14 +32,14 @@ static void PrintNode(MD_Node* node, FILE* file, int indent_count) { Print(file, indent_count+1, "Flags: %s,\n", binary_flags); Print(file, indent_count+1, "Flag Names: ", binary_flags); MD_String8List flags_list = MD_StringListFromNodeFlags(node->flags); - MD_String8 flag_names = MD_JoinStringList(flags_list, MD_S8CString(", ")); - fprintf(file, "%.*s,\n", MD_StringExpand(flag_names)); + MD_String8 flag_names = MD_S8ListJoin(flags_list, MD_S8CString(", ")); + fprintf(file, "%.*s,\n", MD_S8VArg(flag_names)); - if(node->string.size > 0) Print(file, indent_count+1, "String: %.*s,\n", MD_StringExpand(node->string)); - if(node->whole_string.size > 0) Print(file, indent_count+1, "Whole String: %.*s,\n", MD_StringExpand(node->whole_string)); + if(node->string.size > 0) Print(file, indent_count+1, "String: %.*s,\n", MD_S8VArg(node->string)); + if(node->raw_string.size > 0) Print(file, indent_count+1, "Whole String: %.*s,\n", MD_S8VArg(node->raw_string)); if (node->first_tag->kind != MD_NodeKind_Nil) { for (MD_EachNode(tag, node->first_tag)) { - Print(file, indent_count+1, "Tag: @%.*s\n", MD_StringExpand(tag->string)); + Print(file, indent_count+1, "Tag: @%.*s\n", MD_S8VArg(tag->string)); if (tag->first_child->kind != MD_NodeKind_Nil) { Print(file, indent_count+2, "Tag Children{\n"); for (MD_EachNode(arg, tag->first_child)) { @@ -63,15 +63,15 @@ int main(int argument_count, char **arguments) for(int i = 1; i < argument_count; i += 1) { MD_Node *root = MD_ParseWholeFile(MD_S8CString(arguments[i])).node; - MD_PushReference(list, root); + MD_PushNewReference(list, root); } for(MD_EachNode(ref, list->first_child)) { - MD_Node *root = MD_Deref(ref); - MD_String8 code_filename = MD_ChopExtension(MD_SkipFolder(root->string)); - MD_String8 info_filename = MD_PushStringF("parsed_%.*s.txt", MD_StringExpand(code_filename)); - printf("Parse Input -> Output: %.*s -> %.*s\n", MD_StringExpand(code_filename), MD_StringExpand(info_filename)); + MD_Node *root = MD_NodeFromReference(ref); + MD_String8 code_filename = MD_PathChopLastPeriod(MD_PathSkipLastSlash(root->string)); + MD_String8 info_filename = MD_S8Fmt("parsed_%.*s.txt", MD_S8VArg(code_filename)); + printf("Parse Input -> Output: %.*s -> %.*s\n", MD_S8VArg(code_filename), MD_S8VArg(info_filename)); FILE* file = fopen((char *)info_filename.str, "wb"); for(MD_EachNode(node, root->first_child)) diff --git a/samples/parse_check.c b/samples/parse_check.c index b9386c7..e8c2d78 100644 --- a/samples/parse_check.c +++ b/samples/parse_check.c @@ -7,14 +7,14 @@ int main(int argument_count, char **arguments) for(int i = 1; i < argument_count; i += 1) { MD_Node *root = MD_ParseWholeFile(MD_S8CString(arguments[i])).node; - MD_PushReference(list, root); + MD_PushNewReference(list, root); } for(MD_EachNodeRef(root, list->first_child)) { for(MD_EachNode(node, root->first_child)) { - MD_OutputTree(stdout, node, 0); + MD_DebugOutputTree(stdout, node, 0); } } diff --git a/samples/static_site_generator/example_site/generated/blog1.html b/samples/static_site_generator/example_site/generated/blog1.html index ec66352..ea7006b 100644 --- a/samples/static_site_generator/example_site/generated/blog1.html +++ b/samples/static_site_generator/example_site/generated/blog1.html @@ -26,18 +26,15 @@

Test Blog #1

This is my test blog.

30 November 2020

Section 1

-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. +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.

Section 2

-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. +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.

Section 3

diff --git a/samples/static_site_generator/example_site/generated/blog2.html b/samples/static_site_generator/example_site/generated/blog2.html index 312a5fc..55a3c73 100644 --- a/samples/static_site_generator/example_site/generated/blog2.html +++ b/samples/static_site_generator/example_site/generated/blog2.html @@ -26,11 +26,9 @@

Hello, Again!

This is another test blog.

28 November 2020

Section 1

-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. +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.

diff --git a/samples/static_site_generator/static_site_generator.c b/samples/static_site_generator/static_site_generator.c index 262b27f..6308c17 100644 --- a/samples/static_site_generator/static_site_generator.c +++ b/samples/static_site_generator/static_site_generator.c @@ -34,23 +34,23 @@ int main(int argument_count, char **arguments) { //~ NOTE(rjf): Parse command line arguments. - MD_CommandLine cmdln = MD_CommandLineFromOptions(MD_StringListFromArgCV(argument_count, arguments)); - MD_String8 site_info_path = MD_JoinStringList(MD_CommandLineOptionValues(cmdln, MD_S8Lit("siteinfo")), MD_S8Lit("")); - MD_String8 page_dir_path = MD_JoinStringList(MD_CommandLineOptionValues(cmdln, MD_S8Lit("pagedir")), MD_S8Lit("")); - if(!MD_CommandLineOptionPassed(cmdln, MD_S8Lit("siteinfo")) || - !MD_CommandLineOptionPassed(cmdln, MD_S8Lit("pagedir"))) + MD_CmdLine cmdln = MD_MakeCmdLineFromOptions(MD_StringListFromArgCV(argument_count, arguments)); + MD_String8 site_info_path = MD_S8ListJoin(MD_CmdLineValuesFromString(cmdln, MD_S8Lit("siteinfo")), MD_S8Lit("")); + MD_String8 page_dir_path = MD_S8ListJoin(MD_CmdLineValuesFromString(cmdln, MD_S8Lit("pagedir")), MD_S8Lit("")); + if(!MD_CmdLineB32FromString(cmdln, MD_S8Lit("siteinfo")) || + !MD_CmdLineB32FromString(cmdln, MD_S8Lit("pagedir"))) { fprintf(stderr, "USAGE: %s --siteinfo --pagedir ...\n", arguments[0]); goto end; } //~ NOTE(rjf): Load JS. - MD_String8 js_string = MD_LoadEntireFile(MD_PushStringF("%.*s/site.js", MD_StringExpand(page_dir_path))); + MD_String8 js_string = MD_LoadEntireFile(MD_S8Fmt("%.*s/site.js", MD_S8VArg(page_dir_path))); //~ NOTE(rjf): Parse site info. SiteInfo site_info = {0}; { - printf("Parsing site metadata at \"%.*s\"...\n", MD_StringExpand(site_info_path)); + printf("Parsing site metadata at \"%.*s\"...\n", MD_S8VArg(site_info_path)); MD_Node *site_info_file = MD_ParseWholeFile(site_info_path).node; site_info = ParseSiteInfo(site_info_file); } @@ -58,23 +58,23 @@ int main(int argument_count, char **arguments) //~ NOTE(rjf): Parse pages. MD_Node *root_list = MD_MakeList(); { - printf("Searching for site pages at \"%.*s\"...\n", MD_StringExpand(page_dir_path)); + printf("Searching for site pages at \"%.*s\"...\n", MD_S8VArg(page_dir_path)); MD_FileInfo file_info = {0}; for(MD_FileIter it = {0}; MD_FileIterIncrement(&it, page_dir_path, &file_info);) { - if(MD_StringMatch(MD_ExtensionFromPath(file_info.filename), MD_S8Lit("md"), MD_MatchFlag_CaseInsensitive) && - !MD_StringMatch(MD_SkipFolder(MD_ChopExtension(file_info.filename)), - MD_SkipFolder(MD_ChopExtension(site_info_path)), - MD_MatchFlag_CaseInsensitive | - MD_MatchFlag_SlashInsensitive)) + if(MD_S8Match(MD_PathSkipLastPeriod(file_info.filename), MD_S8Lit("md"), MD_StringMatchFlag_CaseInsensitive) && + !MD_S8Match(MD_PathSkipLastSlash(MD_PathChopLastPeriod(file_info.filename)), + MD_PathSkipLastSlash(MD_PathChopLastPeriod(site_info_path)), + MD_StringMatchFlag_CaseInsensitive | + MD_StringMatchFlag_SlashInsensitive)) { - printf("Processing site page at \"%.*s\"...\n", MD_StringExpand(file_info.filename)); - MD_String8 folder = MD_FolderFromPath(page_dir_path); - MD_String8 path = MD_PushStringF("%.*s/%.*s", - MD_StringExpand(folder), - MD_StringExpand(file_info.filename)); + printf("Processing site page at \"%.*s\"...\n", MD_S8VArg(file_info.filename)); + MD_String8 folder = MD_PathChopLastSlash(page_dir_path); + MD_String8 path = MD_S8Fmt("%.*s/%.*s", + MD_S8VArg(folder), + MD_S8VArg(file_info.filename)); MD_Node *node = MD_ParseWholeFile(path).node; - MD_PushReference(root_list, node); + MD_PushNewReference(root_list, node); } } } @@ -84,10 +84,10 @@ int main(int argument_count, char **arguments) { for(MD_EachNode(ref, root_list->first_child)) { - MD_Node *root = MD_Deref(ref); + MD_Node *root = MD_NodeFromReference(ref); for(MD_EachNode(node, root->first_child)) { - if(!MD_NodeIsNil(node->first_child) && MD_StringMatch(node->string, MD_S8Lit("index"), MD_MatchFlag_CaseInsensitive)) + if(!MD_NodeIsNil(node->first_child) && MD_S8Match(node->string, MD_S8Lit("index"), MD_StringMatchFlag_CaseInsensitive)) { for(MD_EachNode(index_string, node->first_child)) { @@ -106,7 +106,7 @@ int main(int argument_count, char **arguments) FILE *file = fopen("style.css", "wb"); if(file) { - fprintf(file, "%.*s", MD_StringExpand(site_info.style->string)); + fprintf(file, "%.*s", MD_S8VArg(site_info.style->string)); fclose(file); } } @@ -116,7 +116,7 @@ int main(int argument_count, char **arguments) FILE *file = fopen("site.js", "wb"); if(file) { - fprintf(file, "%.*s", MD_StringExpand(js_string)); + fprintf(file, "%.*s", MD_S8VArg(js_string)); fclose(file); } } @@ -124,11 +124,11 @@ int main(int argument_count, char **arguments) //~ NOTE(rjf): Generate files for all roots. for(MD_EachNode(ref, root_list->first_child)) { - MD_Node *root = MD_Deref(ref); + MD_Node *root = MD_NodeFromReference(ref); PageInfo page_info = ParsePageInfo(root); - MD_String8 name_without_extension = MD_SkipFolder(MD_ChopExtension(root->string)); - FILE *file = fopen(MD_PushStringF("%.*s.html", MD_StringExpand(name_without_extension)).str, "wb"); + MD_String8 name_without_extension = MD_PathSkipLastSlash(MD_PathChopLastPeriod(root->string)); + FILE *file = fopen(MD_S8Fmt("%.*s.html", MD_S8VArg(name_without_extension)).str, "wb"); if(file) { fprintf(file, "\n"); @@ -144,31 +144,31 @@ int main(int argument_count, char **arguments) { fprintf(file, "\n"); fprintf(file, "\n"); - fprintf(file, "\n", MD_StringExpand(author)); - fprintf(file, "\n", MD_StringExpand(title)); - fprintf(file, "\n", MD_StringExpand(title)); - fprintf(file, "\n", MD_StringExpand(url)); + fprintf(file, "\n", MD_S8VArg(author)); + fprintf(file, "\n", MD_S8VArg(title)); + fprintf(file, "\n", MD_S8VArg(title)); + fprintf(file, "\n", MD_S8VArg(url)); fprintf(file, "\n"); - fprintf(file, "\n", MD_StringExpand(url)); - fprintf(file, "\n", MD_StringExpand(site_title)); + fprintf(file, "\n", MD_S8VArg(url)); + fprintf(file, "\n", MD_S8VArg(site_title)); fprintf(file, "\n"); - fprintf(file, "\n", MD_StringExpand(twitter_handle)); + fprintf(file, "\n", MD_S8VArg(twitter_handle)); fprintf(file, "\n"); fprintf(file, "\n"); if(title.size > 0) { if(site_title.size > 0) { - fprintf(file, "%.*s | %.*s\n", MD_StringExpand(title), MD_StringExpand(site_title)); + fprintf(file, "%.*s | %.*s\n", MD_S8VArg(title), MD_S8VArg(site_title)); } else { - fprintf(file, "%.*s\n", MD_StringExpand(title)); + fprintf(file, "%.*s\n", MD_S8VArg(title)); } } else if(site_title.size > 0) { - fprintf(file, "%.*s\n", MD_StringExpand(site_title)); + fprintf(file, "%.*s\n", MD_S8VArg(site_title)); } fprintf(file, "\n"); } @@ -180,7 +180,7 @@ int main(int argument_count, char **arguments) // NOTE(rjf): Generate header. if(site_info.header) { - fprintf(file, "%.*s", MD_StringExpand(site_info.header->string)); + fprintf(file, "%.*s", MD_S8VArg(site_info.header->string)); } fprintf(file, "
\n"); @@ -188,26 +188,26 @@ int main(int argument_count, char **arguments) // NOTE(rjf): Parent page back button. if(page_info.parent) { - fprintf(file, "", MD_StringExpand(page_info.parent->string)); + fprintf(file, "", MD_S8VArg(page_info.parent->string)); } // NOTE(rjf): Banner. if(page_info.header_image) { fprintf(file, "
", - MD_StringExpand(page_info.header_image->string)); + MD_S8VArg(page_info.header_image->string)); } // NOTE(rjf): Title. if(title.size > 0) { - fprintf(file, "

%.*s

", MD_StringExpand(title)); + fprintf(file, "

%.*s

", MD_S8VArg(title)); } // NOTE(rjf): Main description/subtitle. if(page_info.desc) { - fprintf(file, "

%.*s

", MD_StringExpand(page_info.desc->string)); + fprintf(file, "

%.*s

", MD_S8VArg(page_info.desc->string)); } // NOTE(rjf): Date. @@ -216,7 +216,7 @@ int main(int argument_count, char **arguments) MD_String8 date_string = MakeDateString(page_info.date); if(date_string.size > 0) { - fprintf(file, "

%.*s

", MD_StringExpand(date_string)); + fprintf(file, "

%.*s

", MD_S8VArg(date_string)); } } @@ -231,7 +231,7 @@ int main(int argument_count, char **arguments) // NOTE(rjf): Generate footer. if(site_info.footer) { - fprintf(file, "%.*s", MD_StringExpand(site_info.footer->string)); + fprintf(file, "%.*s", MD_S8VArg(site_info.footer->string)); } fprintf(file, "\n"); @@ -254,23 +254,23 @@ ParsePageInfo(MD_Node *page) { if(!MD_NodeIsNil(node->first_child)) { - if(MD_StringMatch(node->string, MD_S8Lit("title"), MD_MatchFlag_CaseInsensitive)) + if(MD_S8Match(node->string, MD_S8Lit("title"), MD_StringMatchFlag_CaseInsensitive)) { info.title = node->first_child; } - else if(MD_StringMatch(node->string, MD_S8Lit("desc"), MD_MatchFlag_CaseInsensitive)) + else if(MD_S8Match(node->string, MD_S8Lit("desc"), MD_StringMatchFlag_CaseInsensitive)) { info.desc = node->first_child; } - else if(MD_StringMatch(node->string, MD_S8Lit("date"), MD_MatchFlag_CaseInsensitive)) + else if(MD_S8Match(node->string, MD_S8Lit("date"), MD_StringMatchFlag_CaseInsensitive)) { info.date = node; } - else if(MD_StringMatch(node->string, MD_S8Lit("parent"), MD_MatchFlag_CaseInsensitive)) + else if(MD_S8Match(node->string, MD_S8Lit("parent"), MD_StringMatchFlag_CaseInsensitive)) { info.parent = node->first_child; } - else if(MD_StringMatch(node->string, MD_S8Lit("header_image"), MD_MatchFlag_CaseInsensitive)) + else if(MD_S8Match(node->string, MD_S8Lit("header_image"), MD_StringMatchFlag_CaseInsensitive)) { info.header_image = node->first_child; } @@ -287,39 +287,39 @@ ParseSiteInfo(MD_Node *site) { if(!MD_NodeIsNil(node->first_child)) { - if(MD_StringMatch(node->string, MD_S8Lit("title"), MD_MatchFlag_CaseInsensitive)) + if(MD_S8Match(node->string, MD_S8Lit("title"), MD_StringMatchFlag_CaseInsensitive)) { info.title = node->first_child; } - else if(MD_StringMatch(node->string, MD_S8Lit("desc"), MD_MatchFlag_CaseInsensitive)) + else if(MD_S8Match(node->string, MD_S8Lit("desc"), MD_StringMatchFlag_CaseInsensitive)) { info.desc = node->first_child; } - else if(MD_StringMatch(node->string, MD_S8Lit("canonical_url"), MD_MatchFlag_CaseInsensitive)) + else if(MD_S8Match(node->string, MD_S8Lit("canonical_url"), MD_StringMatchFlag_CaseInsensitive)) { info.canonical_url = node->first_child; } - else if(MD_StringMatch(node->string, MD_S8Lit("author"), MD_MatchFlag_CaseInsensitive)) + else if(MD_S8Match(node->string, MD_S8Lit("author"), MD_StringMatchFlag_CaseInsensitive)) { info.author = node->first_child; } - else if(MD_StringMatch(node->string, MD_S8Lit("twitter_handle"), MD_MatchFlag_CaseInsensitive)) + else if(MD_S8Match(node->string, MD_S8Lit("twitter_handle"), MD_StringMatchFlag_CaseInsensitive)) { info.twitter_handle = node->first_child; } - else if(MD_StringMatch(node->string, MD_S8Lit("link_dictionary"), MD_MatchFlag_CaseInsensitive)) + else if(MD_S8Match(node->string, MD_S8Lit("link_dictionary"), MD_StringMatchFlag_CaseInsensitive)) { info.link_dictionary = node; } - else if(MD_StringMatch(node->string, MD_S8Lit("header"), MD_MatchFlag_CaseInsensitive)) + else if(MD_S8Match(node->string, MD_S8Lit("header"), MD_StringMatchFlag_CaseInsensitive)) { info.header = node->first_child; } - else if(MD_StringMatch(node->string, MD_S8Lit("footer"), MD_MatchFlag_CaseInsensitive)) + else if(MD_S8Match(node->string, MD_S8Lit("footer"), MD_StringMatchFlag_CaseInsensitive)) { info.footer = node->first_child; } - else if(MD_StringMatch(node->string, MD_S8Lit("style"), MD_MatchFlag_CaseInsensitive)) + else if(MD_S8Match(node->string, MD_S8Lit("style"), MD_StringMatchFlag_CaseInsensitive)) { info.style = node->first_child; } @@ -362,10 +362,10 @@ MakeDateString(MD_Node *date) MD_u64 month_idx = MD_U64FromString(month->string, 10) - 1; if(month_idx >= 0 && month_idx < sizeof(month_names)/sizeof(month_names[0])) { - result = MD_PushStringF("%.*s %s %.*s", - MD_StringExpand(day->string), - month_names[month_idx], - MD_StringExpand(year->string)); + result = MD_S8Fmt("%.*s %s %.*s", + MD_S8VArg(day->string), + month_names[month_idx], + MD_S8VArg(year->string)); } } } @@ -402,7 +402,7 @@ GeneratePageContent(MD_Map *index_table, SiteInfo *site_info, PageInfo *page_inf { MD_S8Lit("\n\n"), }; - MD_String8List strlist = MD_SplitString(node->string, sizeof(splits)/sizeof(splits[0]), splits); + MD_String8List strlist = MD_S8Split(node->string, sizeof(splits)/sizeof(splits[0]), splits); for(MD_String8Node *strnode = strlist.first; strnode; strnode = strnode->next) { @@ -411,31 +411,31 @@ GeneratePageContent(MD_Map *index_table, SiteInfo *site_info, PageInfo *page_inf { if(strnode->string.str[i] == '@') { - MD_ParseResult parse = MD_ParseOneNode(MD_StringSubstring(strnode->string, i, strnode->string.size), 0); + MD_ParseResult parse = MD_ParseOneNode(MD_S8Substring(strnode->string, i, strnode->string.size), 0); if(!MD_NodeIsNil(parse.node)) { if(MD_NodeHasTag(node, MD_S8Lit("i"), 0)) { - fprintf(file, "%.*s", MD_StringExpand(parse.node->string)); + fprintf(file, "%.*s", MD_S8VArg(parse.node->string)); } else if(MD_NodeHasTag(node, MD_S8Lit("b"), 0)) { - fprintf(file, "%.*s", MD_StringExpand(parse.node->string)); + fprintf(file, "%.*s", MD_S8VArg(parse.node->string)); } else if(MD_NodeHasTag(node, MD_S8Lit("code"), 0)) { - fprintf(file, "%.*s", MD_StringExpand(parse.node->string)); + fprintf(file, "%.*s", MD_S8VArg(parse.node->string)); } else if(MD_NodeHasTag(node, MD_S8Lit("link"), 0)) { MD_Node *text = MD_ChildFromIndex(parse.node, 0); MD_Node *link = MD_ChildFromIndex(parse.node, 1); fprintf(file, "%.*s", - MD_StringExpand(link->string), - MD_StringExpand(text->string)); + MD_S8VArg(link->string), + MD_S8VArg(text->string)); } } - i += parse.bytes_parsed - 1; + i += parse.string_advance - 1; } else { @@ -449,12 +449,12 @@ GeneratePageContent(MD_Map *index_table, SiteInfo *site_info, PageInfo *page_inf { text = MD_ChildFromIndex(dict_link, 0); link = MD_ChildFromIndex(dict_link, 1); - MD_String8 substring = MD_StringSubstring(strnode->string, i, i+text->string.size); - if(MD_StringMatch(substring, text->string, 0)) + MD_String8 substring = MD_S8Substring(strnode->string, i, i+text->string.size); + if(MD_S8Match(substring, text->string, 0)) { fprintf(file, "%.*s", - MD_StringExpand(link->string), - MD_StringExpand(text->string)); + MD_S8VArg(link->string), + MD_S8VArg(text->string)); dict_word = 1; i += text->string.size-1; break; @@ -495,13 +495,13 @@ GeneratePageContent(MD_Map *index_table, SiteInfo *site_info, PageInfo *page_inf { MD_Node *src = MD_ChildFromIndex(node, 0); MD_Node *alt = MD_ChildFromIndex(node, 1); - fprintf(file, "
\n", MD_StringExpand(src->string)); + fprintf(file, "
\n", MD_S8VArg(src->string)); } else if(MD_NodeHasTag(node, MD_S8Lit("youtube"), 0)) { MD_Node *id = MD_ChildFromIndex(node, 0); fprintf(file, "\n", - MD_StringExpand(id->string)); + MD_S8VArg(id->string)); } else if(MD_NodeHasTag(node, MD_S8Lit("lister"), 0)) { @@ -523,36 +523,36 @@ GeneratePageContent(MD_Map *index_table, SiteInfo *site_info, PageInfo *page_inf PageInfo info = ParsePageInfo(node); MD_String8 filename = root->string; - MD_String8 filename_no_ext = MD_ChopExtension(MD_SkipFolder(filename)); - MD_String8 link = MD_PushStringF("%.*s.html", MD_StringExpand(filename_no_ext)); + MD_String8 filename_no_ext = MD_PathChopLastPeriod(MD_PathSkipLastSlash(filename)); + MD_String8 link = MD_S8Fmt("%.*s.html", MD_S8VArg(filename_no_ext)); MD_String8 name = info.title->string; MD_String8 date = MakeDateString(info.date); - fprintf(file, "\n", MD_StringExpand(link)); + fprintf(file, "\n", MD_S8VArg(link)); fprintf(file, "
  • \n"); if(info.header_image) { fprintf(file, "
    ", - MD_StringExpand(info.header_image->string)); + MD_S8VArg(info.header_image->string)); } fprintf(file, "
    \n"); fprintf(file, "
    \n"); - fprintf(file, "%.*s\n", MD_StringExpand(name)); + fprintf(file, "%.*s\n", MD_S8VArg(name)); fprintf(file, "
    \n"); if(date.size > 0) { fprintf(file, "
    \n"); - fprintf(file, "%.*s\n", MD_StringExpand(date)); + fprintf(file, "%.*s\n", MD_S8VArg(date)); fprintf(file, "
    \n"); } if(info.desc) { fprintf(file, "
    \n"); - fprintf(file, "%.*s\n", MD_StringExpand(info.desc->string)); + fprintf(file, "%.*s\n", MD_S8VArg(info.desc->string)); fprintf(file, "
    \n"); } if(info.header_image) diff --git a/samples/toy_language/toy_language.c b/samples/toy_language/toy_language.c index 49d1fbf..fb867ea 100644 --- a/samples/toy_language/toy_language.c +++ b/samples/toy_language/toy_language.c @@ -111,10 +111,12 @@ result = MakeValue_Number(left.number op right.number);\ MD_Node *param = callee.node->first_child; for(MD_Node *arg_first = call->first_child; !MD_NodeIsNil(arg_first); param = param->next) { - MD_Node *arg_last = MD_SeekNodeWithFlags(arg_first, MD_NodeFlag_AfterComma|MD_NodeFlag_AfterSemicolon); +#if 0 + MD_Node *arg_last = MD_SeekNodeWithFlags(arg_first, MD_NodeFlag_IsAfterComma|MD_NodeFlag_IsAfterSemicolon); MD_C_Expr *expr = MD_C_ParseAsExpr(arg_first, arg_last); InsertValueToNamespace(&args_ns, param->string, EvaluateExpr(ns, expr)); arg_first = arg_last->next; +#endif } args_ns.parent = top_level_ns; @@ -147,9 +149,11 @@ EvaluateScope(NamespaceNode *ns, MD_Node *code) NamespaceNode local_namespace = {0}; local_namespace.parent = ns; + // TODO(rjf): fix this, using last instead of opl + for(MD_Node *first = code->first_child; !MD_NodeIsNil(first);) { - MD_Node *last = MD_SeekNodeWithFlags(first, MD_NodeFlag_AfterSemicolon|MD_NodeFlag_AfterComma); + MD_Node *opl = MD_NodeFromFlags(first->next, MD_NilNode(), MD_NodeFlag_IsAfterSemicolon|MD_NodeFlag_IsAfterComma); //- rjf: declaration if(first == last && first->string.size != 0 && !MD_NodeIsNil(first->first_child)) @@ -177,21 +181,21 @@ EvaluateScope(NamespaceNode *ns, MD_Node *code) int main(int argument_count, char **arguments) { //- rjf: parse command line - MD_CommandLine cmdln = MD_CommandLineFromOptions(MD_StringListFromArgCV(argument_count, arguments)); + MD_CmdLine cmdln = MD_MakeCmdLineFromOptions(MD_StringListFromArgCV(argument_count, arguments)); //- rjf: parse all input files MD_Node *file_list = MD_MakeList(); for(MD_String8Node *n = cmdln.inputs.first; n; n = n->next) { MD_ParseResult parse = MD_ParseWholeFile(n->string); - MD_PushReference(file_list, parse.node); + MD_PushNewReference(file_list, parse.node); } //- rjf: gather top-level symbol map NamespaceNode global_ns_node = {0}; for(MD_EachNode(file_ref, file_list->first_child)) { - MD_Node *file = MD_Deref(file_ref); + MD_Node *file = MD_NodeFromReference(file_ref); for(MD_EachNode(top_level, file->first_child)) { if(MD_NodeHasTag(top_level, MD_S8Lit("proc"), 0)) @@ -234,7 +238,7 @@ int main(int argument_count, char **arguments) case ValueKind_Procedure: { - printf("[proc] %.*s\n", MD_StringExpand(result.node->string)); + printf("[proc] %.*s\n", MD_S8VArg(result.node->string)); }break; } diff --git a/source/md.h b/source/md.h index f8043b6..08d37e8 100644 --- a/source/md.h +++ b/source/md.h @@ -259,49 +259,62 @@ struct MD_String8List MD_String8Node *last; }; +// NOTE(rjf): @maintenance These three enums must not overlap, and must share a flag space. typedef MD_u32 MD_MatchFlags; +typedef MD_u32 MD_StringMatchFlags; +typedef MD_u32 MD_NodeMatchFlags; enum { - MD_MatchFlag_CaseInsensitive = (1<<0), - MD_MatchFlag_RightSideSloppy = (1<<1), - MD_MatchFlag_FindLast = (1<<2), - MD_MatchFlag_SlashInsensitive = (1<<3), - MD_MatchFlag_Tags = (1<<4), - MD_MatchFlag_TagArguments = (1<<5), + MD_MatchFlag_FindLast = (1<<0), +}; +enum +{ + MD_StringMatchFlag_CaseInsensitive = (1<<4), + MD_StringMatchFlag_RightSideSloppy = (1<<5), + MD_StringMatchFlag_SlashInsensitive = (1<<6), +}; +enum +{ + MD_NodeMatchFlag_Tags = (1<<16), + MD_NodeMatchFlag_TagArguments = (1<<17), }; -typedef struct MD_UnicodeConsume MD_UnicodeConsume; -struct MD_UnicodeConsume +typedef struct MD_DecodedCodepoint MD_DecodedCodepoint; +struct MD_DecodedCodepoint { MD_u32 codepoint; MD_u32 advance; }; -typedef enum MD_WordStyle +typedef enum MD_IdentifierStyle { - MD_WordStyle_UpperCamelCase, - MD_WordStyle_LowerCamelCase, - MD_WordStyle_UpperCase, - MD_WordStyle_LowerCase, + MD_IdentifierStyle_UpperCamelCase, + MD_IdentifierStyle_LowerCamelCase, + MD_IdentifierStyle_UpperCase, + MD_IdentifierStyle_LowerCase, } -MD_WordStyle; +MD_IdentifierStyle; //~ Node types that are used to build all ASTs. typedef enum MD_NodeKind { - // NOTE(rjf): Must be kept in sync with MD_StringFromNodeKind. + // NOTE(rjf): @maintenance Must be kept in sync with MD_StringFromNodeKind. MD_NodeKind_Nil, + + // NOTE(rjf): Generated by parser MD_NodeKind_File, + MD_NodeKind_ErrorMarker, + + // NOTE(rjf): Parsed from user Metadesk code + MD_NodeKind_Main, + MD_NodeKind_Tag, + + // NOTE(rjf): User-created data structures MD_NodeKind_List, MD_NodeKind_Reference, - // TODO(allen): Proposal names for "Label" - // String, Value, Content, Center, Trunk, Branch, - // Cell, Entity, Node, Code - MD_NodeKind_Label, - MD_NodeKind_Tag, - MD_NodeKind_ErrorMarker, + MD_NodeKind_COUNT, } MD_NodeKind; @@ -310,25 +323,26 @@ typedef MD_u64 MD_NodeFlags; #define MD_NodeFlag_AfterFromBefore(f) ((f) << 1) enum { - // NOTE(rjf): Must be kept in sync with MD_StringListFromNodeFlags. + // NOTE(rjf): @maintenance Must be kept in sync with MD_StringListFromNodeFlags. - // NOTE(rjf): Because of MD_NodeFlag_AfterFromBefore, it is *required* that - // every single pair of "Before*" or "After*" flags be in the correct order - // which is that the Before* flag comes first, and the After* flag comes - // immediately after (After* being the more significant bit). + // NOTE(rjf): @maintenance Because of MD_NodeFlag_AfterFromBefore, it is + // *required* that every single pair of "Before*" or "After*" flags be in + // the correct order which is that the Before* flag comes first, and the + // After* flag comes immediately after (After* being the more significant + // bit). - 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_HasParenLeft = (1<<0), + MD_NodeFlag_HasParenRight = (1<<1), + MD_NodeFlag_HasBracketLeft = (1<<2), + MD_NodeFlag_HasBracketRight = (1<<3), + MD_NodeFlag_HasBraceLeft = (1<<4), + MD_NodeFlag_HasBraceRight = (1<<5), - MD_NodeFlag_BeforeSemicolon = (1<<6), - MD_NodeFlag_AfterSemicolon = (1<<7), + MD_NodeFlag_IsBeforeSemicolon = (1<<6), + MD_NodeFlag_IsAfterSemicolon = (1<<7), - MD_NodeFlag_BeforeComma = (1<<8), - MD_NodeFlag_AfterComma = (1<<9), + MD_NodeFlag_IsBeforeComma = (1<<8), + MD_NodeFlag_IsAfterComma = (1<<9), MD_NodeFlag_StringSingleQuote = (1<<10), MD_NodeFlag_StringDoubleQuote = (1<<11), @@ -358,12 +372,12 @@ struct MD_Node MD_NodeKind kind; MD_NodeFlags flags; MD_String8 string; - MD_String8 whole_string; + MD_String8 raw_string; MD_u64 string_hash; // Comments. - MD_String8 comment_before; - MD_String8 comment_after; + MD_String8 prev_comment; + MD_String8 next_comment; // Source code location information. MD_u64 offset; @@ -419,14 +433,14 @@ struct MD_Map typedef MD_u32 MD_TokenKind; enum { - MD_TokenKind_Identifier = (1<<0), - MD_TokenKind_NumericLiteral = (1<<1), - MD_TokenKind_StringLiteral = (1<<2), - MD_TokenKind_Symbol = (1<<3), - MD_TokenKind_Reserved = (1<<4), - MD_TokenKind_Comment = (1<<5), - MD_TokenKind_Whitespace = (1<<6), - MD_TokenKind_Newline = (1<<7), + MD_TokenKind_Identifier = (1<<0), + MD_TokenKind_NumericLiteral = (1<<1), + MD_TokenKind_StringLiteral = (1<<2), + MD_TokenKind_Symbol = (1<<3), + MD_TokenKind_Reserved = (1<<4), + MD_TokenKind_Comment = (1<<5), + MD_TokenKind_Whitespace = (1<<6), + MD_TokenKind_Newline = (1<<7), MD_TokenKind_BrokenComment = (1<<8), MD_TokenKind_BrokenStringLiteral = (1<<9), MD_TokenKind_BadCharacter = (1<<10), @@ -456,36 +470,39 @@ struct MD_Token MD_TokenKind kind; MD_NodeFlags node_flags; MD_String8 string; - MD_String8 outer_string; + MD_String8 raw_string; }; //~ Parsing State typedef enum MD_MessageKind { + // NOTE(rjf): @maintenance This enum needs to be sorted in order of + // severity. MD_MessageKind_Null, + MD_MessageKind_Note, MD_MessageKind_Warning, MD_MessageKind_Error, MD_MessageKind_CatastrophicError, } MD_MessageKind; -typedef struct MD_Error MD_Error; -struct MD_Error +typedef struct MD_Message MD_Message; +struct MD_Message { - MD_Error *next; + MD_Message *next; MD_Node *node; MD_MessageKind kind; MD_String8 string; }; -typedef struct MD_ErrorList MD_ErrorList; -struct MD_ErrorList +typedef struct MD_MessageList MD_MessageList; +struct MD_MessageList { - MD_MessageKind max_error_kind; + MD_MessageKind max_message_kind; MD_u64 node_count; - MD_Error *first; - MD_Error *last; + MD_Message *first; + MD_Message *last; }; typedef enum MD_ParseSetRule @@ -499,28 +516,28 @@ typedef struct MD_ParseResult MD_ParseResult; struct MD_ParseResult { MD_Node *node; + // TODO(rjf): Remove once we're not using it for ParseTagList MD_Node *last_node; - MD_u64 bytes_parsed; - MD_ErrorList errors; + MD_u64 string_advance; + MD_MessageList errors; }; //~ Command line parsing helper types. -typedef struct MD_CommandLineOption MD_CommandLineOption; -struct MD_CommandLineOption +typedef struct MD_CmdLineOption MD_CmdLineOption; +struct MD_CmdLineOption { - MD_CommandLineOption *next; + MD_CmdLineOption *next; MD_String8 name; MD_String8List values; }; -typedef struct MD_CommandLine MD_CommandLine; -struct MD_CommandLine +typedef struct MD_CmdLine MD_CmdLine; +struct MD_CmdLine { - MD_String8List arguments; MD_String8List inputs; - MD_CommandLineOption *first_option; - MD_CommandLineOption *last_option; + MD_CmdLineOption *first_option; + MD_CmdLineOption *last_option; }; //~ File system access types. @@ -619,10 +636,12 @@ MD_FUNCTION MD_b32 MD_CharIsReservedSymbol(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); +MD_FUNCTION MD_u8 MD_CharToForwardSlash(MD_u8 c); //~ Strings +MD_FUNCTION MD_u64 MD_CalculateCStringLength(char *cstr); + MD_FUNCTION MD_String8 MD_S8(MD_u8 *str, MD_u64 size); #define MD_S8CString(s) MD_S8((MD_u8 *)(s), MD_CalculateCStringLength(s)) @@ -631,8 +650,11 @@ MD_FUNCTION MD_String8 MD_S8(MD_u8 *str, MD_u64 size); #elif MD_LANG_CPP # define MD_S8Lit(s) MD_S8((MD_u8*)(s), sizeof(s) - 1) #endif +#define MD_S8LitComp(s) {(MD_u8 *)(s), sizeof(s)-1} #if MD_LANG_CPP +// TODO(rjf): @allen this is only supported in C++11 I think, we need a check +// for that in the context cracking static inline MD_String8 operator "" _md(const char *s, size_t size) { @@ -641,37 +663,56 @@ operator "" _md(const char *s, size_t size) } #endif -MD_FUNCTION MD_String8 MD_S8Range(MD_u8 *str, MD_u8 *opl); +MD_FUNCTION MD_String8 MD_S8Range(MD_u8 *first, 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_String8 MD_S8Substring(MD_String8 str, MD_u64 min, MD_u64 max); +MD_FUNCTION MD_String8 MD_S8Skip(MD_String8 str, MD_u64 min); +MD_FUNCTION MD_String8 MD_S8Chop(MD_String8 str, MD_u64 nmax); +MD_FUNCTION MD_String8 MD_S8Prefix(MD_String8 str, MD_u64 size); +MD_FUNCTION MD_String8 MD_S8Suffix(MD_String8 str, MD_u64 size); -MD_FUNCTION MD_b32 MD_StringMatch(MD_String8 a, MD_String8 b, MD_MatchFlags flags); -MD_FUNCTION MD_u64 MD_FindSubstring(MD_String8 str, MD_String8 substring, - MD_u64 start_pos, MD_MatchFlags flags); +MD_FUNCTION MD_b32 MD_S8Match(MD_String8 a, MD_String8 b, MD_MatchFlags flags); +MD_FUNCTION MD_u64 MD_S8FindSubstring(MD_String8 str, MD_String8 substring, + MD_u64 start_pos, MD_MatchFlags flags); -MD_FUNCTION MD_String8 MD_ChopExtension(MD_String8 string); -MD_FUNCTION MD_String8 MD_SkipFolder(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_S8Copy(MD_String8 string); +MD_FUNCTION MD_String8 MD_S8FmtV(char *fmt, va_list args); -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_S8Fmt(char *fmt, ...); -MD_FUNCTION MD_String8 MD_PushStringF(char *fmt, ...); +#define MD_S8VArg(s) (int)(s).size, (s).str -#define MD_StringExpand(s) (int)(s).size, (s).str +MD_FUNCTION void MD_S8ListPush(MD_String8List *list, MD_String8 string); +MD_FUNCTION void MD_S8ListConcat(MD_String8List *list, MD_String8List *to_push); +MD_FUNCTION MD_String8List MD_S8Split(MD_String8 string, int split_count, MD_String8 *splits); +MD_FUNCTION MD_String8 MD_S8ListJoin(MD_String8List list, MD_String8 separator); -MD_FUNCTION void MD_PushStringToList(MD_String8List *list, MD_String8 string); -MD_FUNCTION void MD_PushStringListToList(MD_String8List *list, MD_String8List *to_push); -MD_FUNCTION MD_String8List MD_SplitString(MD_String8 string, int split_count, MD_String8 *splits); -MD_FUNCTION MD_String8 MD_JoinStringList(MD_String8List list, MD_String8 separator); -MD_FUNCTION MD_u64 MD_CalculateCStringLength(char *cstr); +MD_FUNCTION MD_String8 MD_S8Stylize(MD_String8 string, MD_IdentifierStyle word_style, MD_String8 separator); -MD_FUNCTION MD_String8 MD_StyledStringFromString(MD_String8 string, MD_WordStyle word_style, MD_String8 separator); +//~ Unicode Conversions + +MD_FUNCTION MD_DecodedCodepoint MD_DecodeCodepointFromUtf8(MD_u8 *str, MD_u64 max); +MD_FUNCTION MD_DecodedCodepoint MD_DecodeCodepointFromUtf16(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); + +//~ File Name Strings + +// This is intended for removing extensions. +MD_FUNCTION MD_String8 MD_PathChopLastPeriod(MD_String8 string); + +// This is intended for removing everything but the filename. +MD_FUNCTION MD_String8 MD_PathSkipLastSlash(MD_String8 string); + +// This is intended for getting an extension from a filename. +MD_FUNCTION MD_String8 MD_PathSkipLastPeriod(MD_String8 string); + +// This is intended for getting the folder string from a full path. +MD_FUNCTION MD_String8 MD_PathChopLastSlash(MD_String8 string); //~ Numeric Strings @@ -684,21 +725,10 @@ MD_FUNCTION MD_f64 MD_F64FromString(MD_String8 string); 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); - //~ Map Table Data Structure -MD_FUNCTION MD_u64 MD_HashString(MD_String8 string); -MD_FUNCTION MD_u64 MD_HashPointer(void *p); +MD_FUNCTION MD_u64 MD_HashStr(MD_String8 string); +MD_FUNCTION MD_u64 MD_HashPtr(void *p); MD_FUNCTION MD_Map MD_MapMakeBucketCount(MD_u64 bucket_count); MD_FUNCTION MD_Map MD_MapMake(void); @@ -711,15 +741,14 @@ MD_FUNCTION MD_MapSlot* MD_MapOverwrite(MD_Map *map, MD_MapKey key, void *val); //~ Parsing +MD_FUNCTION MD_b32 MD_TokenGroupContainsKind(MD_TokenGroups groups, MD_TokenKind kind); MD_FUNCTION MD_Token MD_TokenFromString(MD_String8 string); MD_FUNCTION MD_u64 MD_LexAdvanceFromSkips(MD_String8 string, MD_TokenKind skip_kinds); -MD_FUNCTION MD_Error * MD_MakeNodeError(MD_Node *node, MD_MessageKind kind, MD_String8 str); -MD_FUNCTION MD_Error * MD_MakeTokenError(MD_String8 parse_contents, MD_Token token, MD_MessageKind kind, MD_String8 str); -MD_FUNCTION void MD_PushErrorToList(MD_ErrorList *list, MD_Error *error); -MD_FUNCTION void MD_PushErrorListToList(MD_ErrorList *list, MD_ErrorList *to_push); +MD_FUNCTION MD_Message * MD_MakeNodeError(MD_Node *node, MD_MessageKind kind, MD_String8 str); +MD_FUNCTION MD_Message * MD_MakeTokenError(MD_String8 parse_contents, MD_Token token, MD_MessageKind kind, MD_String8 str); +MD_FUNCTION void MD_MessageListPush(MD_MessageList *list, MD_Message *message); +MD_FUNCTION void MD_MessageListConcat(MD_MessageList *list, MD_MessageList *to_push); MD_FUNCTION MD_ParseResult MD_ParseResultZero(void); -MD_FUNCTION MD_ParseResult MD_ParseNodeSet(MD_String8 string, MD_u64 offset, MD_Node *parent, MD_ParseSetRule rule); -MD_FUNCTION MD_ParseResult MD_ParseTagList(MD_String8 string, MD_u64 offset); MD_FUNCTION MD_ParseResult MD_ParseOneNode(MD_String8 string, MD_u64 offset); MD_FUNCTION MD_ParseResult MD_ParseWholeString(MD_String8 filename, MD_String8 contents); @@ -727,24 +756,28 @@ MD_FUNCTION MD_ParseResult MD_ParseWholeFile(MD_String8 filename); //~ Location Conversion -MD_FUNCTION MD_CodeLoc MD_CodeLocFromFileBaseOffset(MD_String8 filename, MD_u8 *base, MD_u64 offset); +MD_FUNCTION MD_CodeLoc MD_CodeLocFromFileOffset(MD_String8 filename, MD_u8 *base, MD_u64 offset); MD_FUNCTION MD_CodeLoc MD_CodeLocFromNode(MD_Node *node); //~ Tree/List Building MD_FUNCTION MD_b32 MD_NodeIsNil(MD_Node *node); MD_FUNCTION MD_Node *MD_NilNode(void); -MD_FUNCTION MD_Node *MD_MakeNode(MD_NodeKind kind, MD_String8 string, MD_String8 whole_string, MD_u64 offset); +MD_FUNCTION MD_Node *MD_MakeNode(MD_NodeKind kind, MD_String8 string, MD_String8 raw_string, MD_u64 offset); MD_FUNCTION void MD_PushChild(MD_Node *parent, MD_Node *new_child); MD_FUNCTION void MD_PushTag(MD_Node *node, MD_Node *tag); MD_FUNCTION MD_Node *MD_MakeList(void); -MD_FUNCTION MD_Node *MD_PushReference(MD_Node *list, MD_Node *target); +MD_FUNCTION MD_Node *MD_PushNewReference(MD_Node *list, MD_Node *target); //~ Introspection Helpers +// These calls are for getting info from nodes, and introspecting +// on trees that are returned to you by the parser. + MD_FUNCTION MD_Node * MD_NodeFromString(MD_Node *first, MD_Node *one_past_last, MD_String8 string, MD_MatchFlags flags); MD_FUNCTION MD_Node * MD_NodeFromIndex(MD_Node *first, MD_Node *one_past_last, int n); +MD_FUNCTION MD_Node * MD_NodeFromFlags(MD_Node *first, MD_Node *one_past_last, MD_NodeFlags flags); MD_FUNCTION int MD_IndexFromNode(MD_Node *node); MD_FUNCTION MD_Node * MD_RootFromNode(MD_Node *node); MD_FUNCTION MD_Node * MD_ChildFromString(MD_Node *node, MD_String8 child_string, MD_MatchFlags flags); @@ -756,21 +789,20 @@ MD_FUNCTION MD_Node * MD_TagArgFromString(MD_Node *node, MD_String8 tag_string, MD_FUNCTION MD_b32 MD_NodeHasTag(MD_Node *node, MD_String8 tag_string, MD_MatchFlags flags); MD_FUNCTION MD_i64 MD_ChildCountFromNode(MD_Node *node); MD_FUNCTION MD_i64 MD_TagCountFromNode(MD_Node *node); -MD_FUNCTION MD_Node * MD_Deref(MD_Node *node); -MD_FUNCTION MD_Node * MD_SeekNodeWithFlags(MD_Node *start, MD_NodeFlags one_past_last_flags); +MD_FUNCTION MD_Node * MD_NodeFromReference(MD_Node *node); // NOTE(rjf): For-Loop Helpers #define MD_EachNode(it, first) MD_Node *it = (first); !MD_NodeIsNil(it); it = it->next -#define MD_EachNodeRef(it, first) MD_Node *it##_r = (first), *it = MD_Deref(it##_r); \ +#define MD_EachNodeRef(it, first) MD_Node *it##_r = (first), *it = MD_NodeFromReference(it##_r); \ !MD_NodeIsNil(it##_r); \ -it##_r = it##_r->next, it = MD_Deref(it##_r) +it##_r = it##_r->next, it = MD_NodeFromReference(it##_r) //~ Error/Warning Helpers -MD_FUNCTION void MD_Message(FILE *out, MD_CodeLoc loc, MD_MessageKind kind, MD_String8 str); -MD_FUNCTION void MD_MessageF(FILE *out, MD_CodeLoc loc, MD_MessageKind kind, char *fmt, ...); -MD_FUNCTION void MD_NodeMessage(FILE *out, MD_Node *node, MD_MessageKind kind, MD_String8 str); -MD_FUNCTION void MD_NodeMessageF(FILE *out, MD_Node *node, MD_MessageKind kind, char *fmt, ...); +MD_FUNCTION void MD_PrintMessage(FILE *out, MD_CodeLoc loc, MD_MessageKind kind, MD_String8 str); +MD_FUNCTION void MD_PrintMessageFmt(FILE *out, MD_CodeLoc loc, MD_MessageKind kind, char *fmt, ...); +MD_FUNCTION void MD_PrintNodeMessage(FILE *out, MD_Node *node, MD_MessageKind kind, MD_String8 str); +MD_FUNCTION void MD_PrintNodeMessageFmt(FILE *out, MD_Node *node, MD_MessageKind kind, char *fmt, ...); //~ Tree Comparison/Verification @@ -779,15 +811,15 @@ MD_FUNCTION MD_b32 MD_NodeDeepMatch(MD_Node *a, MD_Node *b, MD_MatchFlags flags) //~ Generation -MD_FUNCTION void MD_OutputTree(FILE *file, MD_Node *node, int indent_spaces); +MD_FUNCTION void MD_DebugOutputTree(FILE *file, MD_Node *node, int indent_spaces); //~ Command Line Argument Helper MD_FUNCTION MD_String8List MD_StringListFromArgCV(int argument_count, char **arguments); -MD_FUNCTION MD_CommandLine MD_CommandLineFromOptions(MD_String8List options); -MD_FUNCTION MD_String8List MD_CommandLineOptionValues(MD_CommandLine cmdln, MD_String8 name); -MD_FUNCTION MD_b32 MD_CommandLineOptionPassed(MD_CommandLine cmdln, MD_String8 name); -MD_FUNCTION MD_i64 MD_CommandLineOptionI64(MD_CommandLine cmdln, MD_String8 name); +MD_FUNCTION MD_CmdLine MD_MakeCmdLineFromOptions(MD_String8List options); +MD_FUNCTION MD_String8List MD_CmdLineValuesFromString(MD_CmdLine cmdln, MD_String8 name); +MD_FUNCTION MD_b32 MD_CmdLineB32FromString(MD_CmdLine cmdln, MD_String8 name); +MD_FUNCTION MD_i64 MD_CmdLineI64FromString(MD_CmdLine cmdln, MD_String8 name); //~ File System diff --git a/source/md_c_helpers.c b/source/md_c_helpers.c index 826eec8..d4fede6 100644 --- a/source/md_c_helpers.c +++ b/source/md_c_helpers.c @@ -89,13 +89,13 @@ MD_C_PostUnaryExprKindFromNode(MD_Node *node) MD_C_ExprKind kind = MD_C_ExprKind_Nil; if(!MD_NodeIsNil(node->first_child)) { - if(node->flags & MD_NodeFlag_ParenLeft && - node->flags & MD_NodeFlag_ParenRight) + if(node->flags & MD_NodeFlag_HasParenLeft && + node->flags & MD_NodeFlag_HasParenRight) { kind = MD_C_ExprKind_Call; } - else if(node->flags & MD_NodeFlag_BracketLeft && - node->flags & MD_NodeFlag_BracketRight) + else if(node->flags & MD_NodeFlag_HasBracketLeft && + node->flags & MD_NodeFlag_HasBracketRight) { kind = MD_C_ExprKind_Subscript; } @@ -110,13 +110,13 @@ MD_C_PreUnaryExprKindFromNode(MD_Node *node) // NOTE(rjf): Special-cases for calls/subscripts. if(!MD_NodeIsNil(node->first_child)) { - if(node->flags & MD_NodeFlag_ParenLeft && - node->flags & MD_NodeFlag_ParenRight) + if(node->flags & MD_NodeFlag_HasParenLeft && + node->flags & MD_NodeFlag_HasParenRight) { kind = MD_C_ExprKind_Call; } - else if(node->flags & MD_NodeFlag_BracketLeft && - node->flags & MD_NodeFlag_BracketRight) + else if(node->flags & MD_NodeFlag_HasBracketLeft && + node->flags & MD_NodeFlag_HasBracketRight) { kind = MD_C_ExprKind_Subscript; } @@ -129,7 +129,7 @@ MD_C_PreUnaryExprKindFromNode(MD_Node *node) _MD_C_ExprKindMetadata *metadata = _MD_MetadataFromExprKind(kind_it); if(metadata->group == MD_C_ExprKindGroup_PreUnary) { - if(MD_StringMatch(node->string, MD_S8CString(metadata->pre_symbol), 0)) + if(MD_S8Match(node->string, MD_S8CString(metadata->pre_symbol), 0)) { kind = kind_it; break; @@ -144,7 +144,7 @@ MD_FUNCTION_IMPL MD_C_ExprKind MD_C_BinaryExprKindFromNode(MD_Node *node) { MD_C_ExprKind kind = MD_C_ExprKind_Nil; - if(node->kind == MD_NodeKind_Label && MD_NodeIsNil(node->first_child)) + if(node->kind == MD_NodeKind_Main && MD_NodeIsNil(node->first_child)) { for(MD_C_ExprKind kind_it = (MD_C_ExprKind)0; kind_it < MD_C_ExprKind_MAX; kind_it = (MD_C_ExprKind)((int)kind_it + 1)) @@ -152,7 +152,7 @@ MD_C_BinaryExprKindFromNode(MD_Node *node) _MD_C_ExprKindMetadata *metadata = _MD_MetadataFromExprKind(kind_it); if(metadata->group == MD_C_ExprKindGroup_Binary) { - if(MD_StringMatch(node->string, MD_S8CString(metadata->symbol), 0)) + if(MD_S8Match(node->string, MD_S8CString(metadata->symbol), 0)) { kind = kind_it; break; @@ -195,7 +195,7 @@ 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 && + if(ctx->at->kind == MD_NodeKind_Main && MD_NodeIsNil(ctx->at->first_child)) { result = 1; @@ -213,12 +213,12 @@ _MD_NodeParse_ConsumeSet(_MD_NodeParseCtx *ctx, MD_Node **out) { MD_b32 result = 0; if(!MD_NodeIsNil(ctx->at->first_child) || - ctx->at->flags & MD_NodeFlag_ParenLeft || - ctx->at->flags & MD_NodeFlag_ParenRight || - ctx->at->flags & MD_NodeFlag_BracketLeft || - ctx->at->flags & MD_NodeFlag_BracketRight || - ctx->at->flags & MD_NodeFlag_BraceLeft || - ctx->at->flags & MD_NodeFlag_BraceRight) + ctx->at->flags & MD_NodeFlag_HasParenLeft || + ctx->at->flags & MD_NodeFlag_HasParenRight || + ctx->at->flags & MD_NodeFlag_HasBracketLeft || + ctx->at->flags & MD_NodeFlag_HasBracketRight || + ctx->at->flags & MD_NodeFlag_HasBraceLeft || + ctx->at->flags & MD_NodeFlag_HasBraceRight) { if(out) { @@ -251,7 +251,7 @@ 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)) + if(MD_S8Match(ctx->at->string, string, 0)) { result = 1; if(out) @@ -321,11 +321,11 @@ _MD_ParseUnaryExpr(_MD_NodeParseCtx *ctx) // NOTE(rjf): Post-Unary Sets (calls and subscripts) if(_MD_NodeParse_ConsumeSet(ctx, &set)) { - if(set->flags & MD_NodeFlag_ParenLeft && set->flags & MD_NodeFlag_ParenRight) + if(set->flags & MD_NodeFlag_HasParenLeft && set->flags & MD_NodeFlag_HasParenRight) { result = MD_C_MakeExpr(set, MD_C_ExprKind_Call, result, 0); } - else if(set->flags & MD_NodeFlag_BracketLeft && set->flags & MD_NodeFlag_BracketRight) + else if(set->flags & MD_NodeFlag_HasBracketLeft && set->flags & MD_NodeFlag_HasBracketRight) { result = MD_C_MakeExpr(set, MD_C_ExprKind_Subscript, result, MD_C_ParseAsExpr(set->first_child, set->last_child)); } @@ -497,7 +497,7 @@ MD_C_ExprMatch(MD_C_Expr *a, MD_C_Expr *b, MD_MatchFlags flags) result = 1; if(a->kind == MD_C_ExprKind_Atom) { - result = MD_StringMatch(a->node->string, b->node->string, flags); + result = MD_S8Match(a->node->string, b->node->string, flags); } } return result; @@ -546,9 +546,9 @@ MD_C_Generate_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)); + MD_S8VArg(node->string), + MD_S8VArg(node->string)); + fprintf(file, "struct %.*s\n{\n", MD_S8VArg(node->string)); for(MD_Node *child = node->first_child; !MD_NodeIsNil(child); child = child->next) { MD_C_Generate_Decl(file, child); @@ -568,7 +568,7 @@ MD_C_Generate_Expr(FILE *file, MD_C_Expr *expr) { case MD_C_ExprKindGroup_Atom: { - fprintf(file, "%.*s", MD_StringExpand(expr->node->string)); + fprintf(file, "%.*s", MD_S8VArg(expr->node->string)); }break; case MD_C_ExprKindGroup_Binary: @@ -621,7 +621,7 @@ MD_C_Generate_TypeLHS(FILE *file, MD_C_Expr *type) case MD_C_ExprKind_Atom: { MD_Node *node = type->node; - fprintf(file, "%.*s", MD_StringExpand(node->whole_string)); + fprintf(file, "%.*s", MD_S8VArg(node->raw_string)); }break; case MD_C_ExprKind_Pointer: @@ -650,7 +650,7 @@ MD_C_Generate_TypeLHS(FILE *file, MD_C_Expr *type) { fprintf(file, "{ unexpected MD_C_ExprKind (%i) in type info for node \"%.*s\" }", type->kind, - MD_StringExpand(type->node->whole_string)); + MD_S8VArg(type->node->raw_string)); }break; } } @@ -696,7 +696,7 @@ MD_FUNCTION_IMPL void MD_C_Generate_DeclByNameAndType(FILE *file, MD_String8 name, MD_C_Expr *type) { MD_C_Generate_TypeLHS(file, type); - fprintf(file, " %.*s", MD_StringExpand(name)); + fprintf(file, " %.*s", MD_S8VArg(name)); MD_C_Generate_TypeRHS(file, type); } diff --git a/source/md_impl.c b/source/md_impl.c index 606f3d9..8fcdae0 100644 --- a/source/md_impl.c +++ b/source/md_impl.c @@ -22,10 +22,10 @@ static MD_Node _md_nil_node = MD_NodeKind_Nil, // kind 0, // flags MD_ZERO_STRUCT, // string - MD_ZERO_STRUCT, // whole_string + MD_ZERO_STRUCT, // raw_string 0xdeadffffffffffull, // string_hash - MD_ZERO_STRUCT, // comment_before - MD_ZERO_STRUCT, // comment_after + MD_ZERO_STRUCT, // prev_comment + MD_ZERO_STRUCT, // next_comment 0, // at &_md_nil_node, // ref_target }; @@ -118,13 +118,21 @@ MD_CharToLower(MD_u8 c) } MD_FUNCTION_IMPL MD_u8 -MD_CorrectSlash(MD_u8 c) +MD_CharToForwardSlash(MD_u8 c) { return (c == '\\' ? '/' : c); } //~ Strings +MD_FUNCTION_IMPL MD_u64 +MD_CalculateCStringLength(char *cstr) +{ + MD_u64 i = 0; + for(; cstr[i]; i += 1); + return i; +} + MD_FUNCTION_IMPL MD_String8 MD_S8(MD_u8 *str, MD_u64 size) { @@ -135,16 +143,16 @@ MD_S8(MD_u8 *str, MD_u64 size) } MD_FUNCTION_IMPL MD_String8 -MD_S8Range(MD_u8 *str, MD_u8 *opl) +MD_S8Range(MD_u8 *first, MD_u8 *opl) { MD_String8 string; - string.str = str; - string.size = (MD_u64)(opl - str); + string.str = first; + string.size = (MD_u64)(opl - first); return string; } MD_FUNCTION_IMPL MD_String8 -MD_StringSubstring(MD_String8 str, MD_u64 min, MD_u64 max) +MD_S8Substring(MD_String8 str, MD_u64 min, MD_u64 max) { if(max > str.size) { @@ -166,46 +174,46 @@ MD_StringSubstring(MD_String8 str, MD_u64 min, MD_u64 max) } MD_FUNCTION_IMPL MD_String8 -MD_StringSkip(MD_String8 str, MD_u64 min) +MD_S8Skip(MD_String8 str, MD_u64 min) { - return MD_StringSubstring(str, min, str.size); + return MD_S8Substring(str, min, str.size); } MD_FUNCTION_IMPL MD_String8 -MD_StringChop(MD_String8 str, MD_u64 nmax) +MD_S8Chop(MD_String8 str, MD_u64 nmax) { - return MD_StringSubstring(str, 0, str.size - nmax); + return MD_S8Substring(str, 0, str.size - nmax); } MD_FUNCTION_IMPL MD_String8 -MD_StringPrefix(MD_String8 str, MD_u64 size) +MD_S8Prefix(MD_String8 str, MD_u64 size) { - return MD_StringSubstring(str, 0, size); + return MD_S8Substring(str, 0, size); } MD_FUNCTION_IMPL MD_String8 -MD_StringSuffix(MD_String8 str, MD_u64 size) +MD_S8Suffix(MD_String8 str, MD_u64 size) { - return MD_StringSubstring(str, str.size - size, str.size); + return MD_S8Substring(str, str.size - size, str.size); } MD_FUNCTION_IMPL MD_b32 -MD_StringMatch(MD_String8 a, MD_String8 b, MD_MatchFlags flags) +MD_S8Match(MD_String8 a, MD_String8 b, MD_MatchFlags flags) { int result = 0; - if(a.size == b.size || flags & MD_MatchFlag_RightSideSloppy) + if(a.size == b.size || flags & MD_StringMatchFlag_RightSideSloppy) { result = 1; for(MD_u64 i = 0; i < a.size; i += 1) { MD_b32 match = (a.str[i] == b.str[i]); - if(flags & MD_MatchFlag_CaseInsensitive) + if(flags & MD_StringMatchFlag_CaseInsensitive) { match |= (MD_CharToLower(a.str[i]) == MD_CharToLower(b.str[i])); } - if(flags & MD_MatchFlag_SlashInsensitive) + if(flags & MD_StringMatchFlag_SlashInsensitive) { - match |= (MD_CorrectSlash(a.str[i]) == MD_CorrectSlash(b.str[i])); + match |= (MD_CharToForwardSlash(a.str[i]) == MD_CharToForwardSlash(b.str[i])); } if(match == 0) { @@ -218,7 +226,7 @@ MD_StringMatch(MD_String8 a, MD_String8 b, MD_MatchFlags flags) } MD_FUNCTION_IMPL MD_u64 -MD_FindSubstring(MD_String8 str, MD_String8 substring, MD_u64 start_pos, MD_MatchFlags flags) +MD_S8FindSubstring(MD_String8 str, MD_String8 substring, MD_u64 start_pos, MD_MatchFlags flags) { MD_b32 found = 0; MD_u64 found_idx = str.size; @@ -226,8 +234,8 @@ MD_FindSubstring(MD_String8 str, MD_String8 substring, MD_u64 start_pos, MD_Matc { if(i + substring.size <= str.size) { - MD_String8 substr_from_str = MD_StringSubstring(str, i, i+substring.size); - if(MD_StringMatch(substr_from_str, substring, flags)) + MD_String8 substr_from_str = MD_S8Substring(str, i, i+substring.size); + if(MD_S8Match(substr_from_str, substring, flags)) { found_idx = i; found = 1; @@ -242,57 +250,7 @@ MD_FindSubstring(MD_String8 str, MD_String8 substring, MD_u64 start_pos, MD_Matc } MD_FUNCTION_IMPL MD_String8 -MD_ChopExtension(MD_String8 string) -{ - MD_u64 period_pos = MD_FindSubstring(string, MD_S8Lit("."), 0, MD_MatchFlag_FindLast); - if(period_pos < string.size) - { - string.size = period_pos; - } - return string; -} - -MD_FUNCTION_IMPL MD_String8 -MD_SkipFolder(MD_String8 string) -{ - MD_u64 slash_pos = MD_FindSubstring(string, MD_S8Lit("/"), 0, - MD_MatchFlag_SlashInsensitive| - MD_MatchFlag_FindLast); - if(slash_pos < string.size) - { - string.str += slash_pos+1; - string.size -= slash_pos+1; - } - return string; -} - -MD_FUNCTION_IMPL MD_String8 -MD_ExtensionFromPath(MD_String8 string) -{ - MD_u64 period_pos = MD_FindSubstring(string, MD_S8Lit("."), 0, MD_MatchFlag_FindLast); - if(period_pos < string.size) - { - string.str += period_pos+1; - string.size -= period_pos+1; - } - return string; -} - -MD_FUNCTION_IMPL MD_String8 -MD_FolderFromPath(MD_String8 string) -{ - MD_u64 slash_pos = MD_FindSubstring(string, MD_S8Lit("/"), 0, - MD_MatchFlag_SlashInsensitive| - MD_MatchFlag_FindLast); - if(slash_pos < string.size) - { - string.size = slash_pos; - } - return string; -} - -MD_FUNCTION_IMPL MD_String8 -MD_PushStringCopy(MD_String8 string) +MD_S8Copy(MD_String8 string) { MD_String8 res; res.size = string.size; @@ -302,7 +260,7 @@ MD_PushStringCopy(MD_String8 string) } MD_FUNCTION_IMPL MD_String8 -MD_PushStringFV(char *fmt, va_list args) +MD_S8FmtV(char *fmt, va_list args) { MD_String8 result = MD_ZERO_STRUCT; va_list args2; @@ -315,18 +273,18 @@ MD_PushStringFV(char *fmt, va_list args) } MD_FUNCTION_IMPL MD_String8 -MD_PushStringF(char *fmt, ...) +MD_S8Fmt(char *fmt, ...) { MD_String8 result = MD_ZERO_STRUCT; va_list args; va_start(args, fmt); - result = MD_PushStringFV(fmt, args); + result = MD_S8FmtV(fmt, args); va_end(args); return result; } MD_FUNCTION_IMPL void -MD_PushStringToList(MD_String8List *list, MD_String8 string) +MD_S8ListPush(MD_String8List *list, MD_String8 string) { MD_String8Node *node = MD_PushArray(MD_String8Node, 1); node->string = string; @@ -337,7 +295,7 @@ MD_PushStringToList(MD_String8List *list, MD_String8 string) } MD_FUNCTION_IMPL void -MD_PushStringListToList(MD_String8List *list, MD_String8List *to_push) +MD_S8ListConcat(MD_String8List *list, MD_String8List *to_push) { if(to_push->first) { @@ -358,7 +316,7 @@ MD_PushStringListToList(MD_String8List *list, MD_String8List *to_push) } MD_FUNCTION_IMPL MD_String8List -MD_SplitString(MD_String8 string, int split_count, MD_String8 *splits) +MD_S8Split(MD_String8 string, int split_count, MD_String8 *splits) { MD_String8List list = MD_ZERO_STRUCT; @@ -384,7 +342,7 @@ MD_SplitString(MD_String8 string, int split_count, MD_String8 *splits) if(match) { MD_String8 split_string = MD_S8(string.str + split_start, i - split_start); - MD_PushStringToList(&list, split_string); + MD_S8ListPush(&list, split_string); split_start = i + splits[split_idx].size; i += splits[split_idx].size - 1; was_split = 1; @@ -395,7 +353,7 @@ MD_SplitString(MD_String8 string, int split_count, MD_String8 *splits) if(was_split == 0 && i == string.size - 1) { MD_String8 split_string = MD_S8(string.str + split_start, i+1 - split_start); - MD_PushStringToList(&list, split_string); + MD_S8ListPush(&list, split_string); break; } } @@ -404,7 +362,7 @@ MD_SplitString(MD_String8 string, int split_count, MD_String8 *splits) } MD_FUNCTION_IMPL MD_String8 -MD_JoinStringList(MD_String8List list, MD_String8 separator) +MD_S8ListJoin(MD_String8List list, MD_String8 separator) { if (list.node_count == 0) { @@ -426,96 +384,8 @@ MD_JoinStringList(MD_String8List list, MD_String8 separator) return string; } -MD_FUNCTION_IMPL MD_u64 -MD_CalculateCStringLength(char *cstr) -{ - MD_u64 i = 0; - for(; cstr[i]; i += 1); - return i; -} - -MD_FUNCTION_IMPL MD_u64 -MD_U64FromString(MD_String8 string, MD_u32 radix) -{ - MD_Assert(2 <= radix && radix <= 16); - static MD_u8 char_to_value[] = { - 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, - 0x08,0x09,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - }; - MD_u64 value = 0; - for (MD_u64 i = 0; i < string.size; i += 1){ - value *= radix; - MD_u8 c = string.str[i]; - value += char_to_value[(c - 0x30)&0x1F]; - } - return(value); -} - -MD_FUNCTION_IMPL MD_i64 -MD_CStyleIntFromString(MD_String8 string) -{ - MD_u64 p = 0; - - // consume sign - MD_i64 sign = +1; - if (p < string.size){ - MD_u8 c = string.str[p]; - if (c == '-'){ - sign = -1; - p += 1; - } - else if (c == '+'){ - p += 1; - } - } - - // radix from prefix - MD_u64 radix = 10; - if (p < string.size){ - MD_u8 c0 = string.str[p]; - if (c0 == '0'){ - p += 1; - radix = 8; - if (p < string.size){ - MD_u8 c1 = string.str[p]; - if (c1 == 'x'){ - p += 1; - radix = 16; - } - else if (c1 == 'b'){ - p += 1; - radix = 2; - } - } - } - } - - // consume integer "digits" - MD_String8 digits_substr = MD_StringSkip(string, p); - MD_u64 n = MD_U64FromString(digits_substr, radix); - - // combine result - MD_i64 result = sign*n; - return(result); -} - -MD_FUNCTION_IMPL MD_f64 -MD_F64FromString(MD_String8 string) -{ - char str[64]; - MD_u64 str_size = string.size; - if (str_size > sizeof(str) - 1){ - str_size = sizeof(str) - 1; - } - MD_MemoryCopy(str, string.str, str_size); - str[str_size] = 0; - return(atof(str)); -} - MD_FUNCTION_IMPL MD_String8 -MD_StyledStringFromString(MD_String8 string, MD_WordStyle word_style, MD_String8 separator) +MD_S8Stylize(MD_String8 string, MD_IdentifierStyle word_style, MD_String8 separator) { MD_String8 result = MD_ZERO_STRUCT; @@ -550,7 +420,7 @@ MD_StyledStringFromString(MD_String8 string, MD_WordStyle word_style, MD_String8 word.size += 1; } making_word = 0; - MD_PushStringToList(&words, word); + MD_S8ListPush(&words, word); } else { @@ -589,7 +459,7 @@ MD_StyledStringFromString(MD_String8 string, MD_WordStyle word_style, MD_String8 // NOTE(rjf): Transform string based on word style. switch(word_style) { - case MD_WordStyle_UpperCamelCase: + case MD_IdentifierStyle_UpperCamelCase: { result.str[write_pos] = MD_CharToUpper(result.str[write_pos]); for(MD_u64 i = write_pos+1; i < write_pos + node->string.size; i += 1) @@ -598,7 +468,7 @@ MD_StyledStringFromString(MD_String8 string, MD_WordStyle word_style, MD_String8 } }break; - case MD_WordStyle_LowerCamelCase: + case MD_IdentifierStyle_LowerCamelCase: { result.str[write_pos] = node == words.first ? MD_CharToLower(result.str[write_pos]) : MD_CharToUpper(result.str[write_pos]); for(MD_u64 i = write_pos+1; i < write_pos + node->string.size; i += 1) @@ -607,7 +477,7 @@ MD_StyledStringFromString(MD_String8 string, MD_WordStyle word_style, MD_String8 } }break; - case MD_WordStyle_UpperCase: + case MD_IdentifierStyle_UpperCase: { for(MD_u64 i = write_pos; i < write_pos + node->string.size; i += 1) { @@ -615,7 +485,7 @@ MD_StyledStringFromString(MD_String8 string, MD_WordStyle word_style, MD_String8 } }break; - case MD_WordStyle_LowerCase: + case MD_IdentifierStyle_LowerCase: { for(MD_u64 i = write_pos; i < write_pos + node->string.size; i += 1) { @@ -640,74 +510,14 @@ MD_StyledStringFromString(MD_String8 string, MD_WordStyle word_style, MD_String8 return result; } -//~ Enum/Flag Strings - -MD_FUNCTION_IMPL MD_String8 -MD_StringFromNodeKind(MD_NodeKind kind) -{ - // NOTE(rjf): Must be kept in sync with MD_NodeKind enum. - static char *cstrs[MD_NodeKind_COUNT] = - { - "Nil", - "File", - "List", - "Reference", - "Label", - "Tag", - "ErrorMarker", - }; - return MD_S8CString(cstrs[kind]); -} - -MD_FUNCTION_IMPL MD_String8List -MD_StringListFromNodeFlags(MD_NodeFlags flags) -{ - // NOTE(rjf): Must be kept in sync with MD_NodeFlags enum. - static char *flag_cstrs[] = - { - "ParenLeft", - "ParenRight", - "BracketLeft", - "BracketRight", - "BraceLeft", - "BraceRight", - - "BeforeSemicolon", - "AfterSemicolon", - - "BeforeComma", - "AfterComma", - - "StringSingleQuote", - "StringDoubleQuote", - "StringTick", - "StringTriplet", - - "Numeric", - "Identifier", - "StringLiteral", - }; - - MD_String8List list = MD_ZERO_STRUCT; - MD_u64 bits = sizeof(flags) * 8; - for(MD_u64 i = 0; i < bits && i < MD_ArrayCount(flag_cstrs); i += 1) - { - if(flags & (1ull << i)) - { - MD_PushStringToList(&list, MD_S8CString(flag_cstrs[i])); - } - } - return list; -} - //~ Unicode Conversions MD_GLOBAL MD_u8 md_utf8_class[32] = { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,2,2,2,2,3,3,4,5, }; -MD_FUNCTION_IMPL MD_UnicodeConsume -MD_CodepointFromUtf8(MD_u8 *str, MD_u64 max) +MD_FUNCTION_IMPL MD_DecodedCodepoint +MD_DecodeCodepointFromUtf8(MD_u8 *str, MD_u64 max) { #define MD_bitmask1 0x01 #define MD_bitmask2 0x03 @@ -720,7 +530,7 @@ MD_CodepointFromUtf8(MD_u8 *str, MD_u64 max) #define MD_bitmask9 0x01FF #define MD_bitmask10 0x03FF - MD_UnicodeConsume result = {~((MD_u32)0), 1}; + MD_DecodedCodepoint result = {~((MD_u32)0), 1}; MD_u8 byte = str[0]; MD_u8 byte_class = md_utf8_class[byte >> 3]; switch (byte_class) @@ -782,10 +592,10 @@ MD_CodepointFromUtf8(MD_u8 *str, MD_u64 max) return(result); } -MD_FUNCTION_IMPL MD_UnicodeConsume -MD_CodepointFromUtf16(MD_u16 *out, MD_u64 max) +MD_FUNCTION_IMPL MD_DecodedCodepoint +MD_DecodeCodepointFromUtf16(MD_u16 *out, MD_u64 max) { - MD_UnicodeConsume result = {~((MD_u32)0), 1}; + MD_DecodedCodepoint result = {~((MD_u32)0), 1}; result.codepoint = out[0]; result.advance = 1; if (1 < max && 0xD800 <= out[0] && out[0] < 0xDC00 && 0xDC00 <= out[1] && out[1] < 0xE000) @@ -865,10 +675,10 @@ MD_S8FromS16(MD_String16 in) MD_u16 *ptr = in.str; MD_u16 *opl = ptr + in.size; MD_u64 size = 0; - MD_UnicodeConsume consume; + MD_DecodedCodepoint consume; for (;ptr < opl;) { - consume = MD_CodepointFromUtf16(ptr, opl - ptr); + consume = MD_DecodeCodepointFromUtf16(ptr, opl - ptr); ptr += consume.advance; size += MD_Utf8FromCodepoint(str + size, consume.codepoint); } @@ -884,10 +694,10 @@ MD_S16FromS8(MD_String8 in) MD_u8 *ptr = in.str; MD_u8 *opl = ptr + in.size; MD_u64 size = 0; - MD_UnicodeConsume consume; + MD_DecodedCodepoint consume; for (;ptr < opl;) { - consume = MD_CodepointFromUtf8(ptr, opl - ptr); + consume = MD_DecodeCodepointFromUtf8(ptr, opl - ptr); ptr += consume.advance; size += MD_Utf16FromCodepoint(str + size, consume.codepoint); } @@ -904,7 +714,7 @@ MD_S8FromS32(MD_String32 in) MD_u32 *ptr = in.str; MD_u32 *opl = ptr + in.size; MD_u64 size = 0; - MD_UnicodeConsume consume; + MD_DecodedCodepoint consume; for (;ptr < opl; ptr += 1) { size += MD_Utf8FromCodepoint(str + size, *ptr); @@ -921,10 +731,10 @@ MD_S32FromS8(MD_String8 in) MD_u8 *ptr = in.str; MD_u8 *opl = ptr + in.size; MD_u64 size = 0; - MD_UnicodeConsume consume; + MD_DecodedCodepoint consume; for (;ptr < opl;) { - consume = MD_CodepointFromUtf8(ptr, opl - ptr); + consume = MD_DecodeCodepointFromUtf8(ptr, opl - ptr); ptr += consume.advance; str[size] = consume.codepoint; size += 1; @@ -934,10 +744,207 @@ MD_S32FromS8(MD_String8 in) return(result); } +//~ File Name Strings + +MD_FUNCTION_IMPL MD_String8 +MD_PathChopLastPeriod(MD_String8 string) +{ + MD_u64 period_pos = MD_S8FindSubstring(string, MD_S8Lit("."), 0, MD_MatchFlag_FindLast); + if(period_pos < string.size) + { + string.size = period_pos; + } + return string; +} + +MD_FUNCTION_IMPL MD_String8 +MD_PathSkipLastSlash(MD_String8 string) +{ + MD_u64 slash_pos = MD_S8FindSubstring(string, MD_S8Lit("/"), 0, + MD_StringMatchFlag_SlashInsensitive| + MD_MatchFlag_FindLast); + if(slash_pos < string.size) + { + string.str += slash_pos+1; + string.size -= slash_pos+1; + } + return string; +} + +MD_FUNCTION_IMPL MD_String8 +MD_PathSkipLastPeriod(MD_String8 string) +{ + MD_u64 period_pos = MD_S8FindSubstring(string, MD_S8Lit("."), 0, MD_MatchFlag_FindLast); + if(period_pos < string.size) + { + string.str += period_pos+1; + string.size -= period_pos+1; + } + return string; +} + +MD_FUNCTION_IMPL MD_String8 +MD_PathChopLastSlash(MD_String8 string) +{ + MD_u64 slash_pos = MD_S8FindSubstring(string, MD_S8Lit("/"), 0, + MD_StringMatchFlag_SlashInsensitive| + MD_MatchFlag_FindLast); + if(slash_pos < string.size) + { + string.size = slash_pos; + } + return string; +} + +//~ Numeric Strings + +MD_FUNCTION_IMPL MD_u64 +MD_U64FromString(MD_String8 string, MD_u32 radix) +{ + MD_Assert(2 <= radix && radix <= 16); + static MD_u8 char_to_value[] = { + 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, + 0x08,0x09,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + }; + MD_u64 value = 0; + for (MD_u64 i = 0; i < string.size; i += 1){ + value *= radix; + MD_u8 c = string.str[i]; + value += char_to_value[(c - 0x30)&0x1F]; + } + return(value); +} + +MD_FUNCTION_IMPL MD_i64 +MD_CStyleIntFromString(MD_String8 string) +{ + MD_u64 p = 0; + + // consume sign + MD_i64 sign = +1; + if (p < string.size){ + MD_u8 c = string.str[p]; + if (c == '-'){ + sign = -1; + p += 1; + } + else if (c == '+'){ + p += 1; + } + } + + // radix from prefix + MD_u64 radix = 10; + if (p < string.size){ + MD_u8 c0 = string.str[p]; + if (c0 == '0'){ + p += 1; + radix = 8; + if (p < string.size){ + MD_u8 c1 = string.str[p]; + if (c1 == 'x'){ + p += 1; + radix = 16; + } + else if (c1 == 'b'){ + p += 1; + radix = 2; + } + } + } + } + + // consume integer "digits" + MD_String8 digits_substr = MD_S8Skip(string, p); + MD_u64 n = MD_U64FromString(digits_substr, radix); + + // combine result + MD_i64 result = sign*n; + return(result); +} + +MD_FUNCTION_IMPL MD_f64 +MD_F64FromString(MD_String8 string) +{ + char str[64]; + MD_u64 str_size = string.size; + if (str_size > sizeof(str) - 1){ + str_size = sizeof(str) - 1; + } + MD_MemoryCopy(str, string.str, str_size); + str[str_size] = 0; + return(atof(str)); +} + +//~ Enum/Flag Strings + +MD_FUNCTION_IMPL MD_String8 +MD_StringFromNodeKind(MD_NodeKind kind) +{ + // NOTE(rjf): @maintenance Must be kept in sync with MD_NodeKind enum. + static char *cstrs[MD_NodeKind_COUNT] = + { + "Nil", + + "File", + "ErrorMarker", + + "Main", + "Tag", + + "List", + "Reference", + }; + return MD_S8CString(cstrs[kind]); +} + +MD_FUNCTION_IMPL MD_String8List +MD_StringListFromNodeFlags(MD_NodeFlags flags) +{ + // NOTE(rjf): @maintenance Must be kept in sync with MD_NodeFlags enum. + static char *flag_cstrs[] = + { + "HasParenLeft", + "HasParenRight", + "HasBracketLeft", + "HasBracketRight", + "HasBraceLeft", + "HasBraceRight", + + "IsBeforeSemicolon", + "IsAfterSemicolon", + + "IsBeforeComma", + "IsAfterComma", + + "StringSingleQuote", + "StringDoubleQuote", + "StringTick", + "StringTriplet", + + "Numeric", + "Identifier", + "StringLiteral", + }; + + MD_String8List list = MD_ZERO_STRUCT; + MD_u64 bits = sizeof(flags) * 8; + for(MD_u64 i = 0; i < bits && i < MD_ArrayCount(flag_cstrs); i += 1) + { + if(flags & (1ull << i)) + { + MD_S8ListPush(&list, MD_S8CString(flag_cstrs[i])); + } + } + return list; +} + //~ Map Table Data Structure MD_FUNCTION_IMPL MD_u64 -MD_HashString(MD_String8 string) +MD_HashStr(MD_String8 string) { MD_u64 result = 5381; for(MD_u64 i = 0; i < string.size; i += 1) @@ -950,7 +957,7 @@ MD_HashString(MD_String8 string) // NOTE(mal): Generic 64-bit hash function (https://nullprogram.com/blog/2018/07/31/) // Reversible, so no collisions. Assumes all bits of the pointer matter. MD_FUNCTION_IMPL MD_u64 -MD_HashPointer(void *p) +MD_HashPtr(void *p) { MD_u64 h = (MD_u64)p; // TODO(rjf): Do we want our own equivalent of UINT64_C? @@ -980,7 +987,7 @@ MD_FUNCTION MD_MapKey MD_MapKeyStr(MD_String8 string){ MD_MapKey result = {0}; if (string.size != 0){ - result.hash = MD_HashString(string); + result.hash = MD_HashStr(string); result.size = string.size; if (string.size > 0){ result.ptr = string.str; @@ -993,7 +1000,7 @@ MD_FUNCTION MD_MapKey MD_MapKeyPtr(void *ptr){ MD_MapKey result = {0}; if (ptr != 0){ - result.hash = MD_HashPointer(ptr); + result.hash = MD_HashPtr(ptr); result.size = 0; result.ptr = ptr; } @@ -1028,7 +1035,7 @@ MD_MapScan(MD_MapSlot *first_slot, MD_MapKey key){ } else{ MD_String8 slot_string = MD_S8((MD_u8*)slot->key.ptr, slot->key.size); - if (MD_StringMatch(slot_string, key_string, 0)){ + if (MD_S8Match(slot_string, key_string, 0)){ result = slot; break; } @@ -1070,6 +1077,12 @@ MD_MapOverwrite(MD_Map *map, MD_MapKey key, void *val){ //~ Parsing +MD_FUNCTION MD_b32 +MD_TokenGroupContainsKind(MD_TokenGroups groups, MD_TokenKind kind) +{ + return (groups & kind) != 0; +} + MD_FUNCTION_IMPL MD_Token MD_TokenFromString(MD_String8 string) { @@ -1310,8 +1323,8 @@ MD_TokenFromString(MD_String8 string) }break; } - token.outer_string = MD_S8Range(first, at); - token.string = MD_StringSubstring(token.outer_string, skip_n, token.outer_string.size - chop_n); + token.raw_string = MD_S8Range(first, at); + token.string = MD_S8Substring(token.raw_string, skip_n, token.raw_string.size - chop_n); #undef MD_TokenizerScan @@ -1327,48 +1340,48 @@ MD_LexAdvanceFromSkips(MD_String8 string, MD_TokenKind skip_kinds) MD_u64 p = 0; for (;;) { - MD_Token token = MD_TokenFromString(MD_StringSkip(string, p)); + MD_Token token = MD_TokenFromString(MD_S8Skip(string, p)); if ((skip_kinds & token.kind) == 0) { result = p; break; } - p += token.outer_string.size; + p += token.raw_string.size; } return(result); } -MD_FUNCTION_IMPL MD_Error * +MD_FUNCTION_IMPL MD_Message * MD_MakeNodeError(MD_Node *node, MD_MessageKind kind, MD_String8 str) { - MD_Error *error = MD_PushArrayZero(MD_Error, 1); + MD_Message *error = MD_PushArrayZero(MD_Message, 1); error->node = node; error->kind = kind; error->string = str; return error; } -MD_FUNCTION_IMPL MD_Error * +MD_FUNCTION_IMPL MD_Message * MD_MakeTokenError(MD_String8 parse_contents, MD_Token token, MD_MessageKind kind, MD_String8 str) { MD_Node *err_node = MD_MakeNode(MD_NodeKind_ErrorMarker, MD_S8Lit(""), parse_contents, - token.outer_string.str - parse_contents.str); + token.raw_string.str - parse_contents.str); return MD_MakeNodeError(err_node, kind, str); } MD_FUNCTION_IMPL void -MD_PushErrorToList(MD_ErrorList *list, MD_Error *error) +MD_MessageListPush(MD_MessageList *list, MD_Message *message) { - MD_QueuePush(list->first, list->last, error); - if(error->kind > list->max_error_kind) + MD_QueuePush(list->first, list->last, message); + if(message->kind > list->max_message_kind) { - list->max_error_kind = error->kind; + list->max_message_kind = message->kind; } list->node_count += 1; } MD_FUNCTION_IMPL void -MD_PushErrorListToList(MD_ErrorList *list, MD_ErrorList *to_push) +MD_MessageListConcat(MD_MessageList *list, MD_MessageList *to_push) { if(list->last) { @@ -1377,9 +1390,9 @@ MD_PushErrorListToList(MD_ErrorList *list, MD_ErrorList *to_push) list->last->next = to_push->first; list->last = to_push->last; list->node_count += to_push->node_count; - if(to_push->max_error_kind > list->max_error_kind) + if(to_push->max_message_kind > list->max_message_kind) { - list->max_error_kind = to_push->max_error_kind; + list->max_message_kind = to_push->max_message_kind; } } } @@ -1405,7 +1418,7 @@ MD_ParseNodeSet(MD_String8 string, MD_u64 offset, MD_Node *parent, MD_ParseSetRu MD_u64 off = offset; //- rjf: fill data from set opener - MD_Token initial_token = MD_TokenFromString(MD_StringSkip(string, offset)); + MD_Token initial_token = MD_TokenFromString(MD_S8Skip(string, offset)); MD_u8 set_opener = 0; MD_NodeFlags set_opener_flags = 0; MD_b32 close_with_brace = 0; @@ -1419,32 +1432,32 @@ MD_ParseNodeSet(MD_String8 string, MD_u64 offset, MD_Node *parent, MD_ParseSetRu case MD_ParseSetRule_EndOnDelimiter: { MD_u64 opener_check_off = off; - opener_check_off += MD_LexAdvanceFromSkips(MD_StringSkip(string, opener_check_off), MD_TokenGroup_Irregular); - initial_token = MD_TokenFromString(MD_StringSkip(string, opener_check_off)); + opener_check_off += MD_LexAdvanceFromSkips(MD_S8Skip(string, opener_check_off), MD_TokenGroup_Irregular); + initial_token = MD_TokenFromString(MD_S8Skip(string, opener_check_off)); if(initial_token.kind == MD_TokenKind_Reserved) { - MD_u8 c = initial_token.outer_string.str[0]; + MD_u8 c = initial_token.raw_string.str[0]; if(c == '{') { set_opener = '{'; - set_opener_flags |= MD_NodeFlag_BraceLeft; - opener_check_off += initial_token.outer_string.size; + set_opener_flags |= MD_NodeFlag_HasBraceLeft; + opener_check_off += initial_token.raw_string.size; off = opener_check_off; close_with_brace = 1; } else if(c == '(') { set_opener = '('; - set_opener_flags |= MD_NodeFlag_ParenLeft; - opener_check_off += initial_token.outer_string.size; + set_opener_flags |= MD_NodeFlag_HasParenLeft; + opener_check_off += initial_token.raw_string.size; off = opener_check_off; close_with_paren = 1; } else if(c == '[') { set_opener = '['; - set_opener_flags |= MD_NodeFlag_BracketLeft; - opener_check_off += initial_token.outer_string.size; + set_opener_flags |= MD_NodeFlag_HasBracketLeft; + opener_check_off += initial_token.raw_string.size; off = opener_check_off; close_with_paren = 1; } @@ -1484,10 +1497,10 @@ MD_ParseNodeSet(MD_String8 string, MD_u64 offset, MD_Node *parent, MD_ParseSetRu //- rjf: check newlines { - MD_Token potential_closer = MD_TokenFromString(MD_StringSkip(string, closer_check_off)); + MD_Token potential_closer = MD_TokenFromString(MD_S8Skip(string, closer_check_off)); if(potential_closer.kind == MD_TokenKind_Newline) { - closer_check_off += potential_closer.outer_string.size; + closer_check_off += potential_closer.raw_string.size; off = closer_check_off; // NOTE(rjf): always terminate with a newline if we have >0 children @@ -1499,10 +1512,10 @@ MD_ParseNodeSet(MD_String8 string, MD_u64 offset, MD_Node *parent, MD_ParseSetRu } // NOTE(rjf): terminate after double newline if we have 0 children - MD_Token next_closer = MD_TokenFromString(MD_StringSkip(string, closer_check_off)); + MD_Token next_closer = MD_TokenFromString(MD_S8Skip(string, closer_check_off)); if(next_closer.kind == MD_TokenKind_Newline) { - closer_check_off += next_closer.outer_string.size; + closer_check_off += next_closer.raw_string.size; off = closer_check_off; got_closer = 1; break; @@ -1512,14 +1525,14 @@ MD_ParseNodeSet(MD_String8 string, MD_u64 offset, MD_Node *parent, MD_ParseSetRu //- rjf: check separators and possible braces from higher parents { - closer_check_off += MD_LexAdvanceFromSkips(MD_StringSkip(string, off), MD_TokenGroup_Irregular); - MD_Token potential_closer = MD_TokenFromString(MD_StringSkip(string, closer_check_off)); + closer_check_off += MD_LexAdvanceFromSkips(MD_S8Skip(string, off), MD_TokenGroup_Irregular); + MD_Token potential_closer = MD_TokenFromString(MD_S8Skip(string, closer_check_off)); if(potential_closer.kind == MD_TokenKind_Reserved) { - MD_u8 c = potential_closer.outer_string.str[0]; + MD_u8 c = potential_closer.raw_string.str[0]; if (c == ',' || c == ';') { - closer_check_off += potential_closer.outer_string.size; + closer_check_off += potential_closer.raw_string.size; off = closer_check_off; break; } @@ -1536,32 +1549,32 @@ MD_ParseNodeSet(MD_String8 string, MD_u64 offset, MD_Node *parent, MD_ParseSetRu if(!close_with_separator && !parse_all) { MD_u64 closer_check_off = off; - closer_check_off += MD_LexAdvanceFromSkips(MD_StringSkip(string, off), MD_TokenGroup_Irregular); - MD_Token potential_closer = MD_TokenFromString(MD_StringSkip(string, closer_check_off)); + closer_check_off += MD_LexAdvanceFromSkips(MD_S8Skip(string, off), MD_TokenGroup_Irregular); + MD_Token potential_closer = MD_TokenFromString(MD_S8Skip(string, closer_check_off)); if(potential_closer.kind == MD_TokenKind_Reserved) { - MD_u8 c = potential_closer.outer_string.str[0]; + MD_u8 c = potential_closer.raw_string.str[0]; if(close_with_brace && c == '}') { - closer_check_off += potential_closer.outer_string.size; + closer_check_off += potential_closer.raw_string.size; off = closer_check_off; - parent->flags |= MD_NodeFlag_BraceRight; + parent->flags |= MD_NodeFlag_HasBraceRight; got_closer = 1; break; } else if(close_with_paren && c == ']') { - closer_check_off += potential_closer.outer_string.size; + closer_check_off += potential_closer.raw_string.size; off = closer_check_off; - parent->flags |= MD_NodeFlag_BracketRight; + parent->flags |= MD_NodeFlag_HasBracketRight; got_closer = 1; break; } else if(close_with_paren && c == ')') { - closer_check_off += potential_closer.outer_string.size; + closer_check_off += potential_closer.raw_string.size; off = closer_check_off; - parent->flags |= MD_NodeFlag_ParenRight; + parent->flags |= MD_NodeFlag_HasParenRight; got_closer = 1; break; } @@ -1570,8 +1583,8 @@ MD_ParseNodeSet(MD_String8 string, MD_u64 offset, MD_Node *parent, MD_ParseSetRu //- rjf: parse next child MD_ParseResult child_parse = MD_ParseOneNode(string, off); - MD_PushErrorListToList(&result.errors, &child_parse.errors); - off += child_parse.bytes_parsed; + MD_MessageListConcat(&result.errors, &child_parse.errors); + off += child_parse.string_advance; //- rjf: hook child into parent if(!MD_NodeIsNil(child_parse.node)) @@ -1579,15 +1592,15 @@ MD_ParseNodeSet(MD_String8 string, MD_u64 offset, MD_Node *parent, MD_ParseSetRu // NOTE(rjf): @error No unnamed set children of implicitly-delimited sets if(close_with_separator && child_parse.node->string.size == 0 && - child_parse.node->flags & (MD_NodeFlag_ParenLeft | - MD_NodeFlag_ParenRight | - MD_NodeFlag_BracketLeft | - MD_NodeFlag_BracketRight | - MD_NodeFlag_BraceLeft | - MD_NodeFlag_BraceRight )) + child_parse.node->flags & (MD_NodeFlag_HasParenLeft | + MD_NodeFlag_HasParenRight | + MD_NodeFlag_HasBracketLeft | + MD_NodeFlag_HasBracketRight | + MD_NodeFlag_HasBraceLeft | + MD_NodeFlag_HasBraceRight )) { - MD_Error *error = MD_MakeNodeError(child_parse.node, MD_MessageKind_Warning, MD_S8Lit("Unnamed set children of implicitly-delimited sets are not legal.")); - MD_PushErrorToList(&result.errors, error); + MD_Message *error = MD_MakeNodeError(child_parse.node, MD_MessageKind_Warning, MD_S8Lit("Unnamed set children of implicitly-delimited sets are not legal.")); + MD_MessageListPush(&result.errors, error); } MD_PushChild(parent, child_parse.node); @@ -1598,19 +1611,19 @@ MD_ParseNodeSet(MD_String8 string, MD_u64 offset, MD_Node *parent, MD_ParseSetRu MD_NodeFlags trailing_separator_flags = 0; if(!close_with_separator) { - off += MD_LexAdvanceFromSkips(MD_StringSkip(string, off), MD_TokenGroup_Irregular); - MD_Token trailing_separator = MD_TokenFromString(MD_StringSkip(string, off)); + off += MD_LexAdvanceFromSkips(MD_S8Skip(string, off), MD_TokenGroup_Irregular); + MD_Token trailing_separator = MD_TokenFromString(MD_S8Skip(string, off)); if (trailing_separator.kind == MD_TokenKind_Reserved){ MD_u8 c = trailing_separator.string.str[0]; if(c == ',') { - trailing_separator_flags |= MD_NodeFlag_BeforeComma; - off += trailing_separator.outer_string.size; + trailing_separator_flags |= MD_NodeFlag_IsBeforeComma; + off += trailing_separator.raw_string.size; } else if(c == ';') { - trailing_separator_flags |= MD_NodeFlag_BeforeSemicolon; - off += trailing_separator.outer_string.size; + trailing_separator_flags |= MD_NodeFlag_IsBeforeSemicolon; + off += trailing_separator.raw_string.size; } } } @@ -1628,30 +1641,31 @@ MD_ParseNodeSet(MD_String8 string, MD_u64 offset, MD_Node *parent, MD_ParseSetRu if(set_opener != 0 && got_closer == 0) { // NOTE(rjf): @error We didn't get a closer for the set - MD_Error *error = MD_MakeTokenError(string, initial_token, MD_MessageKind_CatastrophicError, - MD_PushStringF("Unbalanced \"%c\"", set_opener)); - MD_PushErrorToList(&result.errors, error); + MD_Message *error = MD_MakeTokenError(string, initial_token, MD_MessageKind_CatastrophicError, + MD_S8Fmt("Unbalanced \"%c\"", set_opener)); + MD_MessageListPush(&result.errors, error); } //- rjf: push empty implicit set error, if(close_with_separator && parsed_child_count == 0) { // NOTE(rjf): @error No empty implicitly-delimited sets - MD_Error *error = MD_MakeTokenError(string, initial_token, MD_MessageKind_Error, - MD_S8Lit("Empty implicitly-delimited node list")); - MD_PushErrorToList(&result.errors, error); + MD_Message *error = MD_MakeTokenError(string, initial_token, MD_MessageKind_Error, + MD_S8Lit("Empty implicitly-delimited node list")); + MD_MessageListPush(&result.errors, error); } //- rjf: fill result info result.node = parent->first_child; result.last_node = parent->last_child; - result.bytes_parsed = off - offset; + result.string_advance= off - offset; return result; } +// TODO(rjf): Inline this in the only place it is called MD_FUNCTION_IMPL MD_ParseResult -MD_ParseTagList(MD_String8 string, MD_u64 offset) +_MD_ParseTagList(MD_String8 string, MD_u64 offset) { MD_ParseResult result = MD_ParseResultZero(); MD_u64 off = offset; @@ -1659,49 +1673,49 @@ MD_ParseTagList(MD_String8 string, MD_u64 offset) for(;off < string.size;) { //- rjf: parse @ symbol, signifying start of tag - off += MD_LexAdvanceFromSkips(MD_StringSkip(string, off), MD_TokenGroup_Irregular); - MD_Token next_token = MD_TokenFromString(MD_StringSkip(string, off)); + off += MD_LexAdvanceFromSkips(MD_S8Skip(string, off), MD_TokenGroup_Irregular); + MD_Token next_token = MD_TokenFromString(MD_S8Skip(string, off)); if(next_token.kind != MD_TokenKind_Reserved || next_token.string.str[0] != '@') { break; } - off += next_token.outer_string.size; + off += next_token.raw_string.size; //- rjf: parse string of tag node - MD_Token name = MD_TokenFromString(MD_StringSkip(string, off)); + MD_Token name = MD_TokenFromString(MD_S8Skip(string, off)); MD_u64 name_off = off; if((name.kind & MD_TokenGroup_Label) == 0) { // NOTE(rjf): @error Improper token for tag string - MD_Error *error = MD_MakeTokenError(string, name, MD_MessageKind_Error, - MD_PushStringF("\"%.*s\" is not a proper tag label", - MD_StringExpand(name.outer_string))); - MD_PushErrorToList(&result.errors, error); + MD_Message *error = MD_MakeTokenError(string, name, MD_MessageKind_Error, + MD_S8Fmt("\"%.*s\" is not a proper tag label", + MD_S8VArg(name.raw_string))); + MD_MessageListPush(&result.errors, error); break; } - off += name.outer_string.size; + off += name.raw_string.size; //- rjf: build tag - MD_Node *tag = MD_MakeNode(MD_NodeKind_Tag, name.string, name.outer_string, name_off); + MD_Node *tag = MD_MakeNode(MD_NodeKind_Tag, name.string, name.raw_string, name_off); //- rjf: parse tag arguments - MD_Token open_paren = MD_TokenFromString(MD_StringSkip(string, off)); + MD_Token open_paren = MD_TokenFromString(MD_S8Skip(string, off)); MD_ParseResult args_parse = MD_ParseResultZero(); if(open_paren.kind == MD_TokenKind_Reserved && open_paren.string.str[0] == '(') { args_parse = MD_ParseNodeSet(string, off, tag, MD_ParseSetRule_EndOnDelimiter); - MD_PushErrorListToList(&result.errors, &args_parse.errors); + MD_MessageListConcat(&result.errors, &args_parse.errors); } - off += args_parse.bytes_parsed; + off += args_parse.string_advance; //- rjf: push tag to result MD_NodeDblPushBack(result.node, result.last_node, tag); } //- rjf: fill result - result.bytes_parsed = off - offset; + result.string_advance= off - offset; return result; } @@ -1713,21 +1727,21 @@ MD_ParseOneNode(MD_String8 string, MD_u64 offset) MD_u64 off = offset; //- rjf: parse pre-comment - MD_String8 comment_before = MD_ZERO_STRUCT; + MD_String8 prev_comment = MD_ZERO_STRUCT; { MD_Token comment_token = MD_ZERO_STRUCT; for(;off < string.size;) { - MD_Token token = MD_TokenFromString(MD_StringSkip(string, off)); + MD_Token token = MD_TokenFromString(MD_S8Skip(string, off)); if(token.kind == MD_TokenKind_Comment) { - off += token.outer_string.size; + off += token.raw_string.size; comment_token = token; } else if(token.kind == MD_TokenKind_Newline) { - off += token.outer_string.size; - MD_Token next_token = MD_TokenFromString(MD_StringSkip(string, off)); + off += token.raw_string.size; + MD_Token next_token = MD_TokenFromString(MD_S8Skip(string, off)); if(next_token.kind == MD_TokenKind_Comment) { // NOTE(mal): If more than one comment, use the last comment @@ -1740,20 +1754,20 @@ MD_ParseOneNode(MD_String8 string, MD_u64 offset) } else if((token.kind & MD_TokenGroup_Whitespace) != 0) { - off += token.outer_string.size; + off += token.raw_string.size; } else { break; } - comment_before = comment_token.string; + prev_comment = comment_token.string; } } //- rjf: parse tag list - MD_ParseResult tags_parse = MD_ParseTagList(string, off); - off += tags_parse.bytes_parsed; - MD_PushErrorListToList(&result.errors, &tags_parse.errors); + MD_ParseResult tags_parse = _MD_ParseTagList(string, off); + off += tags_parse.string_advance; + MD_MessageListConcat(&result.errors, &tags_parse.errors); //- rjf: parse node MD_Node *parsed_node = MD_NilNode(); @@ -1761,105 +1775,105 @@ MD_ParseOneNode(MD_String8 string, MD_u64 offset) retry:; { //- rjf: try to parse an unnamed set - off += MD_LexAdvanceFromSkips(MD_StringSkip(string, off), MD_TokenGroup_Irregular); - MD_Token unnamed_set_opener = MD_TokenFromString(MD_StringSkip(string, off)); + off += MD_LexAdvanceFromSkips(MD_S8Skip(string, off), MD_TokenGroup_Irregular); + MD_Token unnamed_set_opener = MD_TokenFromString(MD_S8Skip(string, off)); if(unnamed_set_opener.kind == MD_TokenKind_Reserved) { MD_u8 c = unnamed_set_opener.string.str[0]; if (c == '(' || c == '{' || c == '[') { - parsed_node = MD_MakeNode(MD_NodeKind_Label, MD_S8Lit(""), MD_S8Lit(""), - unnamed_set_opener.outer_string.str - string.str); + parsed_node = MD_MakeNode(MD_NodeKind_Main, MD_S8Lit(""), MD_S8Lit(""), + unnamed_set_opener.raw_string.str - string.str); children_parse = MD_ParseNodeSet(string, off, parsed_node, MD_ParseSetRule_EndOnDelimiter); - off += children_parse.bytes_parsed; - MD_PushErrorListToList(&result.errors, &children_parse.errors); + off += children_parse.string_advance; + MD_MessageListConcat(&result.errors, &children_parse.errors); } else if (c == ')' || c == '}' || c == ']') { // NOTE(rjf): @error Unexpected set closing symbol - MD_Error *error = MD_MakeTokenError(string, unnamed_set_opener, - MD_MessageKind_CatastrophicError, - MD_PushStringF("Unbalanced \"%c\"", c)); - MD_PushErrorToList(&result.errors, error); - off += unnamed_set_opener.outer_string.size; + MD_Message *error = MD_MakeTokenError(string, unnamed_set_opener, + MD_MessageKind_CatastrophicError, + MD_S8Fmt("Unbalanced \"%c\"", c)); + MD_MessageListPush(&result.errors, error); + off += unnamed_set_opener.raw_string.size; } else { // NOTE(rjf): @error Unexpected reserved symbol - MD_Error *error = MD_MakeTokenError(string, unnamed_set_opener, - MD_MessageKind_Error, - MD_PushStringF("Unexpected reserved symbol \"%c\"", c)); - MD_PushErrorToList(&result.errors, error); - off += unnamed_set_opener.outer_string.size; + MD_Message *error = MD_MakeTokenError(string, unnamed_set_opener, + MD_MessageKind_Error, + MD_S8Fmt("Unexpected reserved symbol \"%c\"", c)); + MD_MessageListPush(&result.errors, error); + off += unnamed_set_opener.raw_string.size; } goto end_parse; } //- rjf: try to parse regular node, with/without children - off += MD_LexAdvanceFromSkips(MD_StringSkip(string, off), MD_TokenGroup_Irregular); - MD_Token label_name = MD_TokenFromString(MD_StringSkip(string, off)); + off += MD_LexAdvanceFromSkips(MD_S8Skip(string, off), MD_TokenGroup_Irregular); + MD_Token label_name = MD_TokenFromString(MD_S8Skip(string, off)); if((label_name.kind & MD_TokenGroup_Label) != 0) { - off += label_name.outer_string.size; - parsed_node = MD_MakeNode(MD_NodeKind_Label, label_name.string, label_name.outer_string, - label_name.outer_string.str - string.str); + off += label_name.raw_string.size; + parsed_node = MD_MakeNode(MD_NodeKind_Main, label_name.string, label_name.raw_string, + label_name.raw_string.str - string.str); parsed_node->flags |= label_name.node_flags; //- rjf: try to parse children for this node MD_u64 colon_check_off = off; - colon_check_off += MD_LexAdvanceFromSkips(MD_StringSkip(string, colon_check_off), MD_TokenGroup_Irregular); - MD_Token colon = MD_TokenFromString(MD_StringSkip(string, colon_check_off)); + colon_check_off += MD_LexAdvanceFromSkips(MD_S8Skip(string, colon_check_off), MD_TokenGroup_Irregular); + MD_Token colon = MD_TokenFromString(MD_S8Skip(string, colon_check_off)); if(colon.kind == MD_TokenKind_Reserved && colon.string.str[0] == ':') { - colon_check_off += colon.outer_string.size; + colon_check_off += colon.raw_string.size; off = colon_check_off; children_parse = MD_ParseNodeSet(string, off, parsed_node, MD_ParseSetRule_EndOnDelimiter); - off += children_parse.bytes_parsed; - MD_PushErrorListToList(&result.errors, &children_parse.errors); + off += children_parse.string_advance; + MD_MessageListConcat(&result.errors, &children_parse.errors); } goto end_parse; } //- rjf: collect bad token - MD_Token bad_token = MD_TokenFromString(MD_StringSkip(string, off)); + MD_Token bad_token = MD_TokenFromString(MD_S8Skip(string, off)); if(bad_token.kind & MD_TokenGroup_Error) { - off += bad_token.outer_string.size; + off += bad_token.raw_string.size; switch (bad_token.kind){ case MD_TokenKind_BadCharacter: { // TODO(allen): tighten up with good integer <-> string helpers MD_String8List bytes = {0}; - for(int i_byte = 0; i_byte < bad_token.outer_string.size; ++i_byte) + for(int i_byte = 0; i_byte < bad_token.raw_string.size; ++i_byte) { - MD_PushStringToList(&bytes, MD_PushStringF("0x%02X", bad_token.outer_string.str[i_byte])); + MD_S8ListPush(&bytes, MD_S8Fmt("0x%02X", bad_token.raw_string.str[i_byte])); } - MD_String8 byte_string = MD_JoinStringList(bytes, MD_S8Lit(" ")); + MD_String8 byte_string = MD_S8ListJoin(bytes, MD_S8Lit(" ")); // NOTE(rjf): @error Bad character - MD_Error *error = MD_MakeTokenError(string, bad_token, MD_MessageKind_Error, - MD_PushStringF("Non-ASCII character \"%.*s\"", MD_StringExpand(byte_string))); - MD_PushErrorToList(&result.errors, error); + MD_Message *error = MD_MakeTokenError(string, bad_token, MD_MessageKind_Error, + MD_S8Fmt("Non-ASCII character \"%.*s\"", MD_S8VArg(byte_string))); + MD_MessageListPush(&result.errors, error); }break; case MD_TokenKind_BrokenComment: { // NOTE(rjf): @error Broken Comments - MD_Error *error = MD_MakeTokenError(string, bad_token, MD_MessageKind_Error, - MD_S8Lit("Unterminated comment")); - MD_PushErrorToList(&result.errors, error); + MD_Message *error = MD_MakeTokenError(string, bad_token, MD_MessageKind_Error, + MD_S8Lit("Unterminated comment")); + MD_MessageListPush(&result.errors, error); }break; case MD_TokenKind_BrokenStringLiteral: { // NOTE(rjf): @error Broken String Literals - MD_Error *error = MD_MakeTokenError(string, bad_token, MD_MessageKind_Error, - MD_S8Lit("Unterminated string literal")); - MD_PushErrorToList(&result.errors, error); + MD_Message *error = MD_MakeTokenError(string, bad_token, MD_MessageKind_Error, + MD_S8Lit("Unterminated string literal")); + MD_MessageListPush(&result.errors, error); }break; } goto retry; @@ -1869,16 +1883,16 @@ MD_ParseOneNode(MD_String8 string, MD_u64 offset) end_parse:; //- rjf: parse comments after nodes. - MD_String8 comment_after = MD_ZERO_STRUCT; + MD_String8 next_comment = MD_ZERO_STRUCT; { MD_Token comment_token = MD_ZERO_STRUCT; for(;;) { - MD_Token token = MD_TokenFromString(MD_StringSkip(string, off)); + MD_Token token = MD_TokenFromString(MD_S8Skip(string, off)); if(token.kind == MD_TokenKind_Comment) { comment_token = token; - off += token.outer_string.size; + off += token.raw_string.size; break; } @@ -1888,19 +1902,19 @@ MD_ParseOneNode(MD_String8 string, MD_u64 offset) } else if((token.kind & MD_TokenGroup_Whitespace) != 0) { - off += token.outer_string.size; + off += token.raw_string.size; } else { break; } } - comment_after = comment_token.string; + next_comment = comment_token.string; } //- rjf: fill result - parsed_node->comment_before = comment_before; - parsed_node->comment_after = comment_after; + parsed_node->prev_comment = prev_comment; + parsed_node->next_comment = next_comment; result.node = parsed_node; if(!MD_NodeIsNil(result.node)) { @@ -1908,7 +1922,7 @@ MD_ParseOneNode(MD_String8 string, MD_u64 offset) result.node->last_tag = tags_parse.last_node; } result.last_node = parsed_node; - result.bytes_parsed = off - offset; + result.string_advance= off - offset; return result; } @@ -1919,7 +1933,7 @@ MD_ParseWholeString(MD_String8 filename, MD_String8 contents) MD_Node *root = MD_MakeNode(MD_NodeKind_File, filename, contents, 0); MD_ParseResult result = MD_ParseNodeSet(contents, 0, root, MD_ParseSetRule_Global); result.node = result.last_node = root; - for(MD_Error *error = result.errors.first; error != 0; error = error->next) + for(MD_Message *error = result.errors.first; error != 0; error = error->next) { if(MD_NodeIsNil(error->node->parent)) { @@ -1937,9 +1951,9 @@ MD_ParseWholeFile(MD_String8 filename) if(file_contents.str == 0) { // NOTE(rjf): @error File failing to load - MD_Error *error = MD_MakeNodeError(parse.node, MD_MessageKind_CatastrophicError, - MD_PushStringF("Could not read file \"%.*s\"", MD_StringExpand(filename))); - MD_PushErrorToList(&parse.errors, error); + MD_Message *error = MD_MakeNodeError(parse.node, MD_MessageKind_CatastrophicError, + MD_S8Fmt("Could not read file \"%.*s\"", MD_S8VArg(filename))); + MD_MessageListPush(&parse.errors, error); } return parse; } @@ -1947,7 +1961,7 @@ MD_ParseWholeFile(MD_String8 filename) //~ Location Conversions MD_FUNCTION_IMPL MD_CodeLoc -MD_CodeLocFromFileBaseOffset(MD_String8 filename, MD_u8 *base, MD_u64 offset) +MD_CodeLocFromFileOffset(MD_String8 filename, MD_u8 *base, MD_u64 offset) { MD_CodeLoc loc; loc.filename = filename; @@ -1976,7 +1990,7 @@ MD_FUNCTION_IMPL MD_CodeLoc MD_CodeLocFromNode(MD_Node *node) { MD_Node *root = MD_RootFromNode(node); - MD_CodeLoc loc = MD_CodeLocFromFileBaseOffset(root->string, root->whole_string.str, node->offset); + MD_CodeLoc loc = MD_CodeLocFromFileOffset(root->string, root->raw_string.str, node->offset); return loc; } @@ -1992,12 +2006,12 @@ MD_FUNCTION_IMPL MD_Node * MD_NilNode(void) { return &_md_nil_node; } MD_FUNCTION_IMPL MD_Node * -MD_MakeNode(MD_NodeKind kind, MD_String8 string, MD_String8 whole_string, MD_u64 offset) +MD_MakeNode(MD_NodeKind kind, MD_String8 string, MD_String8 raw_string, MD_u64 offset) { MD_Node *node = MD_PushArray(MD_Node, 1); node->kind = kind; node->string = string; - node->whole_string = whole_string; + node->raw_string = raw_string; node->next = node->prev = node->parent = node->first_child = node->last_child = node->first_tag = node->last_tag = node->ref_target = MD_NilNode(); @@ -2034,9 +2048,9 @@ MD_MakeList(void) } MD_FUNCTION_IMPL MD_Node* -MD_PushReference(MD_Node *list, MD_Node *target) +MD_PushNewReference(MD_Node *list, MD_Node *target) { - MD_Node *n = MD_MakeNode(MD_NodeKind_Reference, target->string, target->whole_string, target->offset); + MD_Node *n = MD_MakeNode(MD_NodeKind_Reference, target->string, target->raw_string, target->offset); n->ref_target = target; MD_PushChild(list, n); return(n); @@ -2050,7 +2064,7 @@ MD_NodeFromString(MD_Node *first, MD_Node *one_past_last, MD_String8 string, MD_ MD_Node *result = MD_NilNode(); for(MD_Node *node = first; !MD_NodeIsNil(node) && node != one_past_last; node = node->next) { - if(MD_StringMatch(string, node->string, flags)) + if(MD_S8Match(string, node->string, flags)) { result = node; break; @@ -2078,6 +2092,21 @@ MD_NodeFromIndex(MD_Node *first, MD_Node *one_past_last, int n) return result; } +MD_FUNCTION_IMPL MD_Node * +MD_NodeFromFlags(MD_Node *first, MD_Node *one_past_last, MD_NodeFlags flags) +{ + MD_Node *result = MD_NilNode(); + for(MD_Node *n = first; n != one_past_last && !MD_NodeIsNil(n); n = n->next) + { + if(n->flags & flags) + { + result = n; + break; + } + } + return result; +} + MD_FUNCTION_IMPL int MD_IndexFromNode(MD_Node *node) { @@ -2086,7 +2115,7 @@ MD_IndexFromNode(MD_Node *node) return idx; } -MD_FUNCTION MD_Node * +MD_FUNCTION_IMPL MD_Node * MD_RootFromNode(MD_Node *node) { MD_Node *parent = node; @@ -2165,7 +2194,7 @@ MD_TagCountFromNode(MD_Node *node) } MD_FUNCTION_IMPL MD_Node * -MD_Deref(MD_Node *node) +MD_NodeFromReference(MD_Node *node) { MD_Node *result = node; while(result->kind == MD_NodeKind_Reference) @@ -2175,62 +2204,48 @@ MD_Deref(MD_Node *node) return result; } -MD_FUNCTION MD_Node * -MD_SeekNodeWithFlags(MD_Node *start, MD_NodeFlags one_past_last_flags) -{ - MD_Node *result = MD_NilNode(); - for(MD_EachNode(it, start->next)) - { - if(it->flags & one_past_last_flags) - { - result = it; - break; - } - } - return result; -} - //~ Error/Warning Helpers -MD_FUNCTION void -MD_Message(FILE *out, MD_CodeLoc loc, MD_MessageKind kind, MD_String8 str) +MD_FUNCTION_IMPL void +MD_PrintMessage(FILE *out, MD_CodeLoc loc, MD_MessageKind kind, MD_String8 str) { const char *kind_name = ""; switch (kind){ default: break; + case MD_MessageKind_Note: kind_name = "note: "; break; case MD_MessageKind_Warning: kind_name = "warning: "; break; case MD_MessageKind_Error: kind_name = "error: "; break; case MD_MessageKind_CatastrophicError: kind_name = "fatal error: "; break; } fprintf(out, "%.*s:%i:%i: %s%.*s\n", - MD_StringExpand(loc.filename), loc.line, loc.column, - kind_name, MD_StringExpand(str)); + MD_S8VArg(loc.filename), loc.line, loc.column, + kind_name, MD_S8VArg(str)); } MD_FUNCTION_IMPL void -MD_MessageF(FILE *out, MD_CodeLoc loc, MD_MessageKind kind, char *fmt, ...) +MD_PrintMessageFmt(FILE *out, MD_CodeLoc loc, MD_MessageKind kind, char *fmt, ...) { // TODO(allen): use scratch va_list args; va_start(args, fmt); - MD_Message(out, loc, kind, MD_PushStringFV(fmt, args)); + MD_PrintMessage(out, loc, kind, MD_S8FmtV(fmt, args)); va_end(args); } MD_FUNCTION_IMPL void -MD_NodeMessage(FILE *out, MD_Node *node, MD_MessageKind kind, MD_String8 str) +MD_PrintNodeMessage(FILE *out, MD_Node *node, MD_MessageKind kind, MD_String8 str) { MD_CodeLoc loc = MD_CodeLocFromNode(node); - MD_Message(out, loc, kind, str); + MD_PrintMessage(out, loc, kind, str); } MD_FUNCTION_IMPL void -MD_NodeMessageF(FILE *out, MD_Node *node, MD_MessageKind kind, char *fmt, ...) +MD_PrintNodeMessageFmt(FILE *out, MD_Node *node, MD_MessageKind kind, char *fmt, ...) { // TODO(allen): use scratch va_list args; va_start(args, fmt); - MD_NodeMessage(out, node, kind, MD_PushStringFV(fmt, args)); + MD_PrintNodeMessage(out, node, kind, MD_S8FmtV(fmt, args)); va_end(args); } @@ -2240,10 +2255,10 @@ MD_FUNCTION_IMPL MD_b32 MD_NodeMatch(MD_Node *a, MD_Node *b, MD_MatchFlags flags) { MD_b32 result = 0; - if(a->kind == b->kind && MD_StringMatch(a->string, b->string, flags)) + if(a->kind == b->kind && MD_S8Match(a->string, b->string, flags)) { result = 1; - if(a->kind != MD_NodeKind_Tag && (flags & MD_MatchFlag_Tags)) + if(a->kind != MD_NodeKind_Tag && (flags & MD_NodeMatchFlag_Tags)) { for(MD_Node *a_tag = a->first_tag, *b_tag = b->first_tag; !MD_NodeIsNil(a_tag) || !MD_NodeIsNil(b_tag); @@ -2251,7 +2266,7 @@ MD_NodeMatch(MD_Node *a, MD_Node *b, MD_MatchFlags flags) { if(MD_NodeMatch(a_tag, b_tag, flags)) { - if(flags & MD_MatchFlag_TagArguments) + if(flags & MD_NodeMatchFlag_TagArguments) { for(MD_Node *a_tag_arg = a_tag->first_child, *b_tag_arg = b_tag->first_child; !MD_NodeIsNil(a_tag_arg) || !MD_NodeIsNil(b_tag_arg); @@ -2301,19 +2316,19 @@ MD_NodeDeepMatch(MD_Node *a, MD_Node *b, MD_MatchFlags flags) //~ Generation MD_FUNCTION_IMPL void -MD_OutputTree(FILE *file, MD_Node *node, int indent_spaces) +MD_DebugOutputTree(FILE *file, MD_Node *node, int indent_spaces) { #define MD_PrintIndent() do { for(int i = 0; i < indent_spaces; i += 1) fprintf(file, " "); } while(0) for(MD_Node *tag = node->first_tag; !MD_NodeIsNil(tag); tag = tag->next) { MD_PrintIndent(); - fprintf(file, "@%.*s", MD_StringExpand(tag->string)); + fprintf(file, "@%.*s", MD_S8VArg(tag->string)); if(!MD_NodeIsNil(tag->first_child)) { fprintf(file, "("); for(MD_Node *child = tag->first_child; !MD_NodeIsNil(child); child = child->next) { - MD_OutputTree(file, child, 0); + MD_DebugOutputTree(file, child, 0); fprintf(file, ", "); } fprintf(file, ")\n"); @@ -2328,15 +2343,15 @@ MD_OutputTree(FILE *file, MD_Node *node, int indent_spaces) fprintf(file, "\n"); } - if(node->whole_string.size > 0) + if(node->raw_string.size > 0) { MD_PrintIndent(); - fprintf(file, "%.*s", MD_StringExpand(node->whole_string)); + fprintf(file, "%.*s", MD_S8VArg(node->raw_string)); } if(!MD_NodeIsNil(node->first_child)) { - if(node->whole_string.size > 0) + if(node->raw_string.size > 0) { fprintf(file, ":\n"); } @@ -2344,7 +2359,7 @@ MD_OutputTree(FILE *file, MD_Node *node, int indent_spaces) fprintf(file, "{\n"); for(MD_Node *child = node->first_child; !MD_NodeIsNil(child); child = child->next) { - MD_OutputTree(file, child, indent_spaces+2); + MD_DebugOutputTree(file, child, indent_spaces+2); } MD_PrintIndent(); fprintf(file, "}\n"); @@ -2364,16 +2379,15 @@ MD_StringListFromArgCV(int argument_count, char **arguments) MD_String8List options = MD_ZERO_STRUCT; for(int i = 1; i < argument_count; i += 1) { - MD_PushStringToList(&options, MD_S8CString(arguments[i])); + MD_S8ListPush(&options, MD_S8CString(arguments[i])); } return options; } -MD_FUNCTION MD_CommandLine -MD_CommandLineFromOptions(MD_String8List options) +MD_FUNCTION MD_CmdLine +MD_MakeCmdLineFromOptions(MD_String8List options) { - MD_CommandLine cmdln = MD_ZERO_STRUCT; - cmdln.arguments = options; + MD_CmdLine cmdln = MD_ZERO_STRUCT; for(MD_String8Node *n = options.first, *next = 0; n; n = next) @@ -2383,27 +2397,27 @@ MD_CommandLineFromOptions(MD_String8List options) //- rjf: figure out whether or not this is an option by checking for `-` or `--` // from the beginning of the string MD_String8 option_name = MD_ZERO_STRUCT; - if(MD_StringMatch(MD_StringPrefix(n->string, 2), MD_S8Lit("--"), 0)) + if(MD_S8Match(MD_S8Prefix(n->string, 2), MD_S8Lit("--"), 0)) { - option_name = MD_StringSkip(n->string, 2); + option_name = MD_S8Skip(n->string, 2); } - else if(MD_StringMatch(MD_StringPrefix(n->string, 1), MD_S8Lit("-"), 0)) + else if(MD_S8Match(MD_S8Prefix(n->string, 1), MD_S8Lit("-"), 0)) { - option_name = MD_StringSkip(n->string, 1); + option_name = MD_S8Skip(n->string, 1); } //- rjf: trim off anything after a `:` or `=`, use that as the first value string MD_String8 first_value = MD_ZERO_STRUCT; MD_b32 has_many_values = 0; if(option_name.size != 0) { - MD_u64 colon_signifier_pos = MD_FindSubstring(option_name, MD_S8Lit(":"), 0, 0); - MD_u64 equal_signifier_pos = MD_FindSubstring(option_name, MD_S8Lit("="), 0, 0); + MD_u64 colon_signifier_pos = MD_S8FindSubstring(option_name, MD_S8Lit(":"), 0, 0); + MD_u64 equal_signifier_pos = MD_S8FindSubstring(option_name, MD_S8Lit("="), 0, 0); MD_u64 signifier_pos = colon_signifier_pos > equal_signifier_pos ? equal_signifier_pos : colon_signifier_pos; if(signifier_pos < option_name.size) { - first_value = MD_StringSkip(option_name, signifier_pos+1); - option_name = MD_StringPrefix(option_name, signifier_pos); - if(MD_StringMatch(MD_StringSuffix(first_value, 1), MD_S8Lit(","), 0)) + first_value = MD_S8Skip(option_name, signifier_pos+1); + option_name = MD_S8Prefix(option_name, signifier_pos); + if(MD_S8Match(MD_S8Suffix(first_value, 1), MD_S8Lit(","), 0)) { has_many_values = 1; } @@ -2418,7 +2432,7 @@ MD_CommandLineFromOptions(MD_String8List options) //- rjf: push first value if(first_value.size != 0) { - MD_PushStringToList(&option_values, first_value); + MD_S8ListPush(&option_values, first_value); } //- rjf: scan next string values, add them to option values until we hit a lack @@ -2428,7 +2442,7 @@ MD_CommandLineFromOptions(MD_String8List options) for(MD_String8Node *v = next; v; v = v->next, next = v) { MD_String8 value_str = v->string; - MD_b32 next_has_arguments = MD_StringMatch(MD_StringSuffix(value_str, 1), MD_S8Lit(","), 0); + MD_b32 next_has_arguments = MD_S8Match(MD_S8Suffix(value_str, 1), MD_S8Lit(","), 0); MD_b32 in_quotes = 0; MD_u64 start = 0; for(MD_u64 i = 0; i <= value_str.size; i += 1) @@ -2437,7 +2451,7 @@ MD_CommandLineFromOptions(MD_String8List options) { if(start != i) { - MD_PushStringToList(&option_values, MD_StringSubstring(value_str, start, i)); + MD_S8ListPush(&option_values, MD_S8Substring(value_str, start, i)); } start = i+1; } @@ -2455,7 +2469,7 @@ MD_CommandLineFromOptions(MD_String8List options) //- rjf: insert the fully parsed option { - MD_CommandLineOption *opt = MD_PushArray(MD_CommandLineOption, 1); + MD_CmdLineOption *opt = MD_PushArray(MD_CmdLineOption, 1); MD_MemoryZero(opt, sizeof(*opt)); opt->name = option_name; opt->values = option_values; @@ -2474,7 +2488,7 @@ MD_CommandLineFromOptions(MD_String8List options) //- rjf: this argument is not an option, push it to regular inputs list. else { - MD_PushStringToList(&cmdln.inputs, n->string); + MD_S8ListPush(&cmdln.inputs, n->string); } } @@ -2482,12 +2496,12 @@ MD_CommandLineFromOptions(MD_String8List options) } MD_FUNCTION MD_String8List -MD_CommandLineOptionValues(MD_CommandLine cmdln, MD_String8 name) +MD_CmdLineValuesFromString(MD_CmdLine cmdln, MD_String8 name) { MD_String8List values = MD_ZERO_STRUCT; - for(MD_CommandLineOption *opt = cmdln.first_option; opt; opt = opt->next) + for(MD_CmdLineOption *opt = cmdln.first_option; opt; opt = opt->next) { - if(MD_StringMatch(opt->name, name, 0)) + if(MD_S8Match(opt->name, name, 0)) { values = opt->values; break; @@ -2497,12 +2511,12 @@ MD_CommandLineOptionValues(MD_CommandLine cmdln, MD_String8 name) } MD_FUNCTION MD_b32 -MD_CommandLineOptionPassed(MD_CommandLine cmdln, MD_String8 name) +MD_CmdLineB32FromString(MD_CmdLine cmdln, MD_String8 name) { MD_b32 result = 0; - for(MD_CommandLineOption *opt = cmdln.first_option; opt; opt = opt->next) + for(MD_CmdLineOption *opt = cmdln.first_option; opt; opt = opt->next) { - if(MD_StringMatch(opt->name, name, 0)) + if(MD_S8Match(opt->name, name, 0)) { result = 1; break; @@ -2512,11 +2526,11 @@ MD_CommandLineOptionPassed(MD_CommandLine cmdln, MD_String8 name) } MD_FUNCTION MD_i64 -MD_CommandLineOptionI64(MD_CommandLine cmdln, MD_String8 name) +MD_CmdLineI64FromString(MD_CmdLine cmdln, MD_String8 name) { MD_i64 v = 0; - MD_String8List values = MD_CommandLineOptionValues(cmdln, name); - MD_String8 value_str = MD_JoinStringList(values, MD_S8Lit("")); + MD_String8List values = MD_CmdLineValuesFromString(cmdln, name); + MD_String8 value_str = MD_S8ListJoin(values, MD_S8Lit("")); v = MD_CStyleIntFromString(value_str); return v; } @@ -2527,7 +2541,7 @@ MD_FUNCTION_IMPL MD_String8 MD_LoadEntireFile(MD_String8 filename) { MD_String8 file_contents = MD_ZERO_STRUCT; - FILE *file = fopen((char*)MD_PushStringCopy(filename).str, "rb"); + FILE *file = fopen((char*)MD_S8Copy(filename).str, "rb"); if(file) { fseek(file, 0, SEEK_END); diff --git a/source/md_linux.c b/source/md_linux.c index a90ef90..a0347b4 100644 --- a/source/md_linux.c +++ b/source/md_linux.c @@ -4,7 +4,7 @@ #include #include #include - #include +#include // NOTE(mal): To get these constants I need to #define _GNU_SOURCE, which invites non-POSIX behavior I'd rather avoid #ifndef O_PATH @@ -26,22 +26,22 @@ static MD_b32 MD_LINUX_FileIterIncrement(MD_FileIter *opaque_it, MD_String8 path, MD_FileInfo *out_info) { MD_b32 result = 0; - + MD_LINUX_FileIter *it = (MD_LINUX_FileIter *)opaque_it; if(it->dir == 0) { it->dir = opendir((char*)path.str); it->dir_fd = open((char *)path.str, O_PATH|O_CLOEXEC); } - + if(it->dir != 0 && it->dir_fd != -1) { struct dirent *dir_entry = readdir(it->dir); if(dir_entry) { - out_info->filename = MD_PushStringF("%s", dir_entry->d_name); + out_info->filename = MD_S8Fmt("%s", dir_entry->d_name); out_info->flags = 0; - + struct stat st; if(fstatat(it->dir_fd, dir_entry->d_name, &st, AT_NO_AUTOMOUNT|AT_SYMLINK_NOFOLLOW) == 0) { @@ -54,7 +54,7 @@ MD_LINUX_FileIterIncrement(MD_FileIter *opaque_it, MD_String8 path, MD_FileInfo result = 1; } } - + if(result == 0) { if(it->dir != 0) @@ -68,7 +68,7 @@ MD_LINUX_FileIterIncrement(MD_FileIter *opaque_it, MD_String8 path, MD_FileInfo it->dir_fd = -1; } } - + return result; } diff --git a/source/md_posix.c b/source/md_posix.c index 4fb487e..aeec99e 100644 --- a/source/md_posix.c +++ b/source/md_posix.c @@ -15,7 +15,7 @@ static MD_b32 MD_POSIX_FileIterIncrement(MD_FileIter *opaque_it, MD_String8 path, MD_FileInfo *out_info) { MD_b32 result = 0; - + MD_POSIX_FileIter *it = (MD_POSIX_FileIter *)opaque_it; if(it->dir == 0) { @@ -27,16 +27,16 @@ MD_POSIX_FileIterIncrement(MD_FileIter *opaque_it, MD_String8 path, MD_FileInfo struct dirent *dir_entry = readdir(it->dir); if(dir_entry) { - out_info->filename = MD_PushStringF("%s", dir_entry->d_name); + out_info->filename = MD_S8Fmt("%s", dir_entry->d_name); out_info->flags = 0; - + if(path.size > 1 && path.str[path.size-1] == '/') { path.size -= 1; } - + struct stat st; - MD_String8 cfile_path = MD_PushStringF("%.*s/%s", MD_StringExpand(path), dir_entry->d_name); + MD_String8 cfile_path = MD_S8Fmt("%.*s/%s", MD_S8VArg(path), dir_entry->d_name); if(stat((char *)cfile_path.str, &st) == 0) { if((st.st_mode & S_IFMT) == S_IFDIR) diff --git a/source/md_win32.c b/source/md_win32.c index 8f7e3fe..2bc4f7e 100644 --- a/source/md_win32.c +++ b/source/md_win32.c @@ -71,7 +71,7 @@ MD_WIN32_FileIterIncrement(MD_FileIter *it, MD_String8 path, MD_FileInfo *out_in { need_star = 1; } - MD_String8 cpath = need_star ? MD_PushStringF("%.*s*", MD_StringExpand(path)) : path; + MD_String8 cpath = need_star ? MD_S8Fmt("%.*s*", MD_S8VArg(path)) : path; state = FindFirstFileA((char*)cpath.str, &find_data); result = !!state; } @@ -88,7 +88,7 @@ MD_WIN32_FileIterIncrement(MD_FileIter *it, MD_String8 path, MD_FileInfo *out_in { out_info->flags |= MD_FileFlag_Directory; } - out_info->filename = MD_PushStringF("%s", find_data.cFileName); + out_info->filename = MD_S8Fmt("%s", find_data.cFileName); out_info->file_size = ((((MD_u64)find_data.nFileSizeHigh) << 32) | ((MD_u64)find_data.nFileSizeLow)); } diff --git a/tests/cpp_build_test.cpp b/tests/cpp_build_test.cpp index 1bd12ff..834ae56 100644 --- a/tests/cpp_build_test.cpp +++ b/tests/cpp_build_test.cpp @@ -5,7 +5,7 @@ int main(void) { MD_String8 foo = "foo"_md; MD_String8 bar = "bar"_md; - MD_String8 str = MD_PushStringF("%S%S", foo, bar); - printf("%.*s", MD_StringExpand(str)); + MD_String8 str = MD_S8Fmt("%S%S", foo, bar); + printf("%.*s", MD_S8VArg(str)); return 0; } diff --git a/tests/grammar.c b/tests/grammar.c index f9743f8..4b1f5e7 100644 --- a/tests/grammar.c +++ b/tests/grammar.c @@ -42,8 +42,8 @@ MD_GLOBAL struct static void TagSquareBracketSetsAsOptional(MD_Node *node, MD_Node *optional_tag) { - if(node->kind == MD_NodeKind_Label && - (node->flags & MD_NodeFlag_BracketLeft) && (node->flags & MD_NodeFlag_BracketRight)) + if(node->kind == MD_NodeKind_Main && + (node->flags & MD_NodeFlag_HasBracketLeft) && (node->flags & MD_NodeFlag_HasBracketRight)) { if(node->string.size) // NOTE(mal): Production. Tag belongs to the first child { @@ -66,7 +66,7 @@ static MD_Node * NewChildLabel(MD_Node *parent, MD_String8 label) { MD_Node *result = 0; - result = MD_MakeNode(MD_NodeKind_Label, label, label, 0); + result = MD_MakeNode(MD_NodeKind_Main, label, label, 0); if(parent) { MD_PushChild(parent, result); @@ -97,9 +97,9 @@ static void PrintRule(MD_Map *depth_map, MD_Node *rule) for(MD_EachNode(tag, rule->first_tag)) { - if(!MD_StringMatch(tag->string, MD_S8Lit(OPTIONAL_TAG), 0)) + if(!MD_S8Match(tag->string, MD_S8Lit(OPTIONAL_TAG), 0)) { - printf("@%.*s ", MD_StringExpand(tag->string)); + printf("@%.*s ", MD_S8VArg(tag->string)); } } @@ -127,7 +127,7 @@ static void PrintRule(MD_Map *depth_map, MD_Node *rule) else { MD_Assert(rule->string.size > 0); - printf("%.*s", MD_StringExpand(rule->string)); + printf("%.*s", MD_S8VArg(rule->string)); } if(is_literal_char) @@ -150,7 +150,7 @@ typedef enum OperationFlags static void Extend(MD_String8 *s, char c) { - *s = MD_PushStringF("%.*s%c", MD_StringExpand(*s), c); + *s = MD_S8Fmt("%.*s%c", MD_S8VArg(*s), c); } static void ExpandProduction(MD_Node *production, MD_String8List *out, MD_Node *cur_node, @@ -181,31 +181,31 @@ static void ExpandRule(MD_Node *rule, MD_String8List *out_strings, MD_Node *cur_ MD_Node *node_to_tag = 0; OperationFlags old_op_flags = op_flags; for(MD_EachNode(tag_node, rule_element->first_tag)){ - if(MD_StringMatch(tag_node->string, MD_S8Lit("child"), 0)) + if(MD_S8Match(tag_node->string, MD_S8Lit("child"), 0)) { cur_node = NewChild(cur_node); op_flags &= ~OperationFlag_Tag; // NOTE(mal): Tag parameters are not tags } - else if(MD_StringMatch(tag_node->string, MD_S8Lit("sibling"), 0)) + else if(MD_S8Match(tag_node->string, MD_S8Lit("sibling"), 0)) { cur_node = NewChild(cur_node->parent); } - else if(MD_StringMatch(tag_node->string, MD_S8Lit("fill"), 0)) + else if(MD_S8Match(tag_node->string, MD_S8Lit("fill"), 0)) { op_flags |= OperationFlag_Fill; } - else if(MD_StringMatch(tag_node->string, MD_S8Lit("tag"), 0)) + else if(MD_S8Match(tag_node->string, MD_S8Lit("tag"), 0)) { op_flags |= OperationFlag_Tag; node_to_tag = cur_node; cur_node = NewChild(0); cur_node->kind = MD_NodeKind_Tag; } - else if(MD_StringMatch(tag_node->string, MD_S8Lit("markup"), 0)) + else if(MD_S8Match(tag_node->string, MD_S8Lit("markup"), 0)) { op_flags |= OperationFlag_Markup; } - else if(MD_StringMatch(tag_node->string, MD_S8Lit(OPTIONAL_TAG), 0)) + else if(MD_S8Match(tag_node->string, MD_S8Lit(OPTIONAL_TAG), 0)) { } else @@ -238,12 +238,12 @@ static void ExpandRule(MD_Node *rule, MD_String8List *out_strings, MD_Node *cur_ c = rule_element->string.str[0]; } - MD_String8 character = MD_PushStringF("%c", c); - MD_PushStringToList(out_strings, character); + MD_String8 character = MD_S8Fmt("%c", c); + MD_S8ListPush(out_strings, character); if(op_flags & OperationFlag_Fill) { - Extend(&cur_node->whole_string, c); + Extend(&cur_node->raw_string, c); if(!(op_flags & OperationFlag_Markup)) { Extend(&cur_node->string, c); @@ -360,11 +360,11 @@ static MD_b32 EqualList(MD_Node *a, MD_Node *b) static MD_b32 EqualTrees(MD_Node *a, MD_Node *b) { MD_b32 result = (a->kind == b->kind && - MD_StringMatch(a->string, b->string, 0) && - MD_StringMatch(a->whole_string, b->whole_string, 0)); + MD_S8Match(a->string, b->string, 0) && + MD_S8Match(a->raw_string, b->raw_string, 0)); result &= EqualList(a->first_tag, b->first_tag); result &= EqualList(a->first_child, b->first_child); - result &= MD_StringMatch(a->comment_before, b->comment_before, 0); + result &= MD_S8Match(a->prev_comment, b->prev_comment, 0); return result; } @@ -475,16 +475,16 @@ FirstBadNodeAtPointer(MD_Node *node) { MD_Node *result = 0; MD_Node *root = MD_RootFromNode(node); - MD_u8 *node_at = root->whole_string.str + node->offset; + MD_u8 *node_at = root->raw_string.str + node->offset; switch(node->kind){ case MD_NodeKind_File: { } break; - case MD_NodeKind_Label: + case MD_NodeKind_Main: { - if(node_at != node->whole_string.str) + if(node_at != node->raw_string.str) { - if(node->whole_string.size) + if(node->raw_string.size) { result = node; } @@ -505,7 +505,7 @@ FirstBadNodeAtPointer(MD_Node *node) case MD_NodeKind_List: case MD_NodeKind_Tag: { - if(node_at != node->whole_string.str) + if(node_at != node->raw_string.str) { result = node; goto end; @@ -562,7 +562,7 @@ int main(int argument_count, char **arguments) } else { - if(MD_StringMatch(rule_element->string, MD_S8Lit("|"), 0) && + if(MD_S8Match(rule_element->string, MD_S8Lit("|"), 0) && !(rule_element->flags & MD_NodeFlag_StringLiteral)) { rule = NewChild(production); @@ -607,7 +607,7 @@ int main(int argument_count, char **arguments) MD_Node *non_terminal_production = FindNonTerminalProduction(production, &visited_productions); if(non_terminal_production) { - fprintf(stderr, "Error: Non-terminal production \"%.*s\"\n", MD_StringExpand(non_terminal_production->string)); + fprintf(stderr, "Error: Non-terminal production \"%.*s\"\n", MD_S8VArg(non_terminal_production->string)); goto error; } } @@ -618,7 +618,7 @@ int main(int argument_count, char **arguments) MD_MapSlot *slot = MD_MapLookup(&visited_productions, MD_MapKeyStr(production->string)); if(!slot) { - fprintf(stderr, "Warning: Unreachable production \"%.*s\"\n", MD_StringExpand(production->string)); + fprintf(stderr, "Warning: Unreachable production \"%.*s\"\n", MD_S8VArg(production->string)); } } @@ -702,7 +702,7 @@ int main(int argument_count, char **arguments) #if DEBUG_RULES_AFTER_TRANSFORMATIONS for(MD_EachNode(production, productions->first_child)) { - printf("%.*s (min %lu): \n", MD_StringExpand(production->string), GET_DEPTH(production)); + printf("%.*s (min %lu): \n", MD_S8VArg(production->string), GET_DEPTH(production)); for(MD_EachNode(rule, production->first_child)) { printf(" "); @@ -732,7 +732,7 @@ int main(int argument_count, char **arguments) MD_String8List string_list = {0}; // NOTE(mal): Generate a random MD file ExpandProduction(file_production_node, &string_list, test.expected_output, 0, depth_map, max_production_depth, 0); - test.input = MD_JoinStringList(string_list, MD_S8Lit("")); + test.input = MD_S8ListJoin(string_list, MD_S8Lit("")); Test *prev = 0; for(Test *cur = first_test; cur; cur = cur->next) @@ -766,19 +766,19 @@ int main(int argument_count, char **arguments) for(Test *test = first_test; test; test = test->next) { MD_Node *file_node = MD_ParseWholeString(MD_S8Lit(""), test->input).node; - file_node->string = file_node->whole_string = (MD_String8){0}; + file_node->string = file_node->raw_string = (MD_String8){0}; #if DEBUG_PRINT_GENERATED_TESTS - printf("> %.*s <\n", MD_StringExpand(EscapeNewlines(test->input))); + printf("> %.*s <\n", MD_S8VArg(EscapeNewlines(test->input))); #endif if(!EqualTrees(file_node, test->expected_output)) { printf("\nFailed test %d\n", i_test); - printf("> %.*s <\n", MD_StringExpand(test->input)); + printf("> %.*s <\n", MD_S8VArg(test->input)); printf("MD:\n"); - MD_OutputTree(stdout, file_node, 0); + MD_DebugOutputTree(stdout, file_node, 0); printf("Grammar:\n"); - MD_OutputTree(stdout, test->expected_output, 0); printf("\n"); + MD_DebugOutputTree(stdout, test->expected_output, 0); printf("\n"); return -1; } @@ -786,11 +786,11 @@ int main(int argument_count, char **arguments) if(bad_at_node) { printf("\nBad node->at on test %d\n", i_test); - printf("> %.*s <\n", MD_StringExpand(test->input)); + printf("> %.*s <\n", MD_S8VArg(test->input)); printf("MD:\n"); - MD_OutputTree(stdout, file_node, 0); + MD_DebugOutputTree(stdout, file_node, 0); printf("offending_node"); - MD_OutputTree(stdout, bad_at_node, 0); + MD_DebugOutputTree(stdout, bad_at_node, 0); return -1; } ++i_test; diff --git a/tests/grammar.md b/tests/grammar.md index 1e857ff..2a6c463 100644 --- a/tests/grammar.md +++ b/tests/grammar.md @@ -95,10 +95,10 @@ unscoped_set_tail : {':' @child unscoped_set | ' ' @sibling unscoped_set | ':' /* Comments * Comments around nodes are accessible to the user. Here's how they behave: * - The text inside a comment immediatly following a node is stored as the - * comment_after member of that node. No newlines can happen between a + * next_comment member of that node. No newlines can happen between a * node and its after_comment. * - The text inside a comment preceding a node is stored as the - * comment_before of that node _unless_ it is already the comment_after + * prev_comment of that node _unless_ it is already the next_comment * of another node. One newline between the comment and the node is * obviously necessary in the case of C++-style comments and it's also * allowed for C-style comments. @@ -108,9 +108,9 @@ unscoped_set_tail : {':' @child unscoped_set | ' ' @sibling unscoped_set | ':' * The semantically annotated Backus-Naur form that we're using is not a * good fit to describe the grammar of comments. * To prevent the comment in "a /* comment */ b" from being interpreted as - * a comment_before of "b", instead of what it is (a comment_after of "a"), - * we would have to complicate the grammar by introducing several extra - * productions with this specific purpose in mind. - * The sensitivity of whitespace in the attachment of comments to nodes is - * also cumbersome to express in BNF. - */ +* a prev_comment of "b", instead of what it is (a next_comment of "a"), +* we would have to complicate the grammar by introducing several extra +* productions with this specific purpose in mind. +* The sensitivity of whitespace in the attachment of comments to nodes is +* also cumbersome to express in BNF. +*/ diff --git a/tests/sanity_tests.c b/tests/sanity_tests.c index ab46c19..e8bb050 100644 --- a/tests/sanity_tests.c +++ b/tests/sanity_tests.c @@ -71,7 +71,7 @@ MakeTestNode(MD_NodeKind kind, MD_String8 string) static MD_C_Expr * AtomExpr(char *str) { - return MD_C_MakeExpr(MakeTestNode(MD_NodeKind_Label, MD_S8CString(str)), + return MD_C_MakeExpr(MakeTestNode(MD_NodeKind_Main, MD_S8CString(str)), MD_C_ExprKind_Atom, MD_C_NilExpr(), MD_C_NilExpr()); } @@ -91,7 +91,7 @@ static MD_b32 MatchParsedWithNode(MD_String8 string, MD_Node *tree) { MD_ParseResult parse = MD_ParseOneNode(string, 0); - return MD_NodeDeepMatch(tree, parse.node, MD_MatchFlag_Tags | MD_MatchFlag_TagArguments); + return MD_NodeDeepMatch(tree, parse.node, MD_NodeMatchFlag_Tags | MD_NodeMatchFlag_TagArguments); } static MD_b32 @@ -113,7 +113,7 @@ MatchParsedWithType(MD_String8 string, MD_C_Expr *expr) static MD_b32 TokenMatch(MD_Token token, MD_String8 string, MD_TokenKind kind) { - return MD_StringMatch(string, token.string, 0) && token.kind == kind; + return MD_S8Match(string, token.string, 0) && token.kind == kind; } int main(void) @@ -123,20 +123,20 @@ int main(void) MD_String8 string = MD_S8Lit("abc def 123 456 123_456 abc123 123abc"); MD_Token tokens[] = { - MD_TokenFromString(MD_StringSkip(string, 0)), - MD_TokenFromString(MD_StringSkip(string, 3)), - MD_TokenFromString(MD_StringSkip(string, 4)), - MD_TokenFromString(MD_StringSkip(string, 7)), - MD_TokenFromString(MD_StringSkip(string, 8)), - MD_TokenFromString(MD_StringSkip(string, 11)), - MD_TokenFromString(MD_StringSkip(string, 12)), - MD_TokenFromString(MD_StringSkip(string, 15)), - MD_TokenFromString(MD_StringSkip(string, 16)), - MD_TokenFromString(MD_StringSkip(string, 19)), - MD_TokenFromString(MD_StringSkip(string, 20)), - MD_TokenFromString(MD_StringSkip(string, 23)), - MD_TokenFromString(MD_StringSkip(string, 24)), - MD_TokenFromString(MD_StringSkip(string, 27)), + MD_TokenFromString(MD_S8Skip(string, 0)), + MD_TokenFromString(MD_S8Skip(string, 3)), + MD_TokenFromString(MD_S8Skip(string, 4)), + MD_TokenFromString(MD_S8Skip(string, 7)), + MD_TokenFromString(MD_S8Skip(string, 8)), + MD_TokenFromString(MD_S8Skip(string, 11)), + MD_TokenFromString(MD_S8Skip(string, 12)), + MD_TokenFromString(MD_S8Skip(string, 15)), + MD_TokenFromString(MD_S8Skip(string, 16)), + MD_TokenFromString(MD_S8Skip(string, 19)), + MD_TokenFromString(MD_S8Skip(string, 20)), + MD_TokenFromString(MD_S8Skip(string, 23)), + MD_TokenFromString(MD_S8Skip(string, 24)), + MD_TokenFromString(MD_S8Skip(string, 27)), }; TestResult(TokenMatch(tokens[0], MD_S8Lit("abc"), MD_TokenKind_Identifier)); @@ -153,37 +153,37 @@ int main(void) Test("Empty Sets") { - TestResult(MatchParsedWithNode(MD_S8Lit("{}"), MakeTestNode(MD_NodeKind_Label, MD_S8Lit("")))); - TestResult(MatchParsedWithNode(MD_S8Lit("()"), MakeTestNode(MD_NodeKind_Label, MD_S8Lit("")))); - TestResult(MatchParsedWithNode(MD_S8Lit("[]"), MakeTestNode(MD_NodeKind_Label, MD_S8Lit("")))); - TestResult(MatchParsedWithNode(MD_S8Lit("[)"), MakeTestNode(MD_NodeKind_Label, MD_S8Lit("")))); - TestResult(MatchParsedWithNode(MD_S8Lit("(]"), MakeTestNode(MD_NodeKind_Label, MD_S8Lit("")))); + TestResult(MatchParsedWithNode(MD_S8Lit("{}"), MakeTestNode(MD_NodeKind_Main, MD_S8Lit("")))); + TestResult(MatchParsedWithNode(MD_S8Lit("()"), MakeTestNode(MD_NodeKind_Main, MD_S8Lit("")))); + TestResult(MatchParsedWithNode(MD_S8Lit("[]"), MakeTestNode(MD_NodeKind_Main, MD_S8Lit("")))); + TestResult(MatchParsedWithNode(MD_S8Lit("[)"), MakeTestNode(MD_NodeKind_Main, MD_S8Lit("")))); + TestResult(MatchParsedWithNode(MD_S8Lit("(]"), MakeTestNode(MD_NodeKind_Main, MD_S8Lit("")))); } Test("Simple Unnamed Sets") { { MD_String8 string = MD_S8Lit("{a, b, c}"); - MD_Node *tree = MakeTestNode(MD_NodeKind_Label, MD_S8Lit("")); - MD_PushChild(tree, MakeTestNode(MD_NodeKind_Label, MD_S8Lit("a"))); - MD_PushChild(tree, MakeTestNode(MD_NodeKind_Label, MD_S8Lit("b"))); - MD_PushChild(tree, MakeTestNode(MD_NodeKind_Label, MD_S8Lit("c"))); + MD_Node *tree = MakeTestNode(MD_NodeKind_Main, MD_S8Lit("")); + MD_PushChild(tree, MakeTestNode(MD_NodeKind_Main, MD_S8Lit("a"))); + MD_PushChild(tree, MakeTestNode(MD_NodeKind_Main, MD_S8Lit("b"))); + MD_PushChild(tree, MakeTestNode(MD_NodeKind_Main, MD_S8Lit("c"))); TestResult(MatchParsedWithNode(string, tree)); } { MD_String8 string = MD_S8Lit("(1 2 3 4 5)"); - MD_Node *tree = MakeTestNode(MD_NodeKind_Label, MD_S8Lit("")); - MD_PushChild(tree, MakeTestNode(MD_NodeKind_Label, MD_S8Lit("1"))); - MD_PushChild(tree, MakeTestNode(MD_NodeKind_Label, MD_S8Lit("2"))); - MD_PushChild(tree, MakeTestNode(MD_NodeKind_Label, MD_S8Lit("3"))); - MD_PushChild(tree, MakeTestNode(MD_NodeKind_Label, MD_S8Lit("4"))); - MD_PushChild(tree, MakeTestNode(MD_NodeKind_Label, MD_S8Lit("5"))); + MD_Node *tree = MakeTestNode(MD_NodeKind_Main, MD_S8Lit("")); + MD_PushChild(tree, MakeTestNode(MD_NodeKind_Main, MD_S8Lit("1"))); + MD_PushChild(tree, MakeTestNode(MD_NodeKind_Main, MD_S8Lit("2"))); + MD_PushChild(tree, MakeTestNode(MD_NodeKind_Main, MD_S8Lit("3"))); + MD_PushChild(tree, MakeTestNode(MD_NodeKind_Main, MD_S8Lit("4"))); + MD_PushChild(tree, MakeTestNode(MD_NodeKind_Main, MD_S8Lit("5"))); TestResult(MatchParsedWithNode(string, tree)); } { MD_String8 string = MD_S8Lit("{a}"); - MD_Node *tree = MakeTestNode(MD_NodeKind_Label, MD_S8Lit("")); - MD_PushChild(tree, MakeTestNode(MD_NodeKind_Label, MD_S8Lit("a"))); + MD_Node *tree = MakeTestNode(MD_NodeKind_Main, MD_S8Lit("")); + MD_PushChild(tree, MakeTestNode(MD_NodeKind_Main, MD_S8Lit("a"))); TestResult(MatchParsedWithNode(string, tree)); } } @@ -191,10 +191,10 @@ int main(void) Test("Simple Named Sets") { MD_String8 string = MD_S8Lit("simple_set: {a, b, c}"); - MD_Node *tree = MakeTestNode(MD_NodeKind_Label, MD_S8Lit("simple_set")); - MD_PushChild(tree, MakeTestNode(MD_NodeKind_Label, MD_S8Lit("a"))); - MD_PushChild(tree, MakeTestNode(MD_NodeKind_Label, MD_S8Lit("b"))); - MD_PushChild(tree, MakeTestNode(MD_NodeKind_Label, MD_S8Lit("c"))); + MD_Node *tree = MakeTestNode(MD_NodeKind_Main, MD_S8Lit("simple_set")); + MD_PushChild(tree, MakeTestNode(MD_NodeKind_Main, MD_S8Lit("a"))); + MD_PushChild(tree, MakeTestNode(MD_NodeKind_Main, MD_S8Lit("b"))); + MD_PushChild(tree, MakeTestNode(MD_NodeKind_Main, MD_S8Lit("c"))); TestResult(MatchParsedWithNode(string, tree)); } @@ -202,72 +202,72 @@ int main(void) { { MD_String8 string = MD_S8Lit("{a b:{1 2 3} c}"); - MD_Node *tree = MakeTestNode(MD_NodeKind_Label, MD_S8Lit("")); - MD_PushChild(tree, MakeTestNode(MD_NodeKind_Label, MD_S8Lit("a"))); + MD_Node *tree = MakeTestNode(MD_NodeKind_Main, MD_S8Lit("")); + MD_PushChild(tree, MakeTestNode(MD_NodeKind_Main, MD_S8Lit("a"))); { - MD_Node *sub = MakeTestNode(MD_NodeKind_Label, MD_S8Lit("b")); - MD_PushChild(sub, MakeTestNode(MD_NodeKind_Label, MD_S8Lit("1"))); - MD_PushChild(sub, MakeTestNode(MD_NodeKind_Label, MD_S8Lit("2"))); - MD_PushChild(sub, MakeTestNode(MD_NodeKind_Label, MD_S8Lit("3"))); + MD_Node *sub = MakeTestNode(MD_NodeKind_Main, MD_S8Lit("b")); + MD_PushChild(sub, MakeTestNode(MD_NodeKind_Main, MD_S8Lit("1"))); + MD_PushChild(sub, MakeTestNode(MD_NodeKind_Main, MD_S8Lit("2"))); + MD_PushChild(sub, MakeTestNode(MD_NodeKind_Main, MD_S8Lit("3"))); MD_PushChild(tree, sub); } - MD_PushChild(tree, MakeTestNode(MD_NodeKind_Label, MD_S8Lit("c"))); + MD_PushChild(tree, MakeTestNode(MD_NodeKind_Main, MD_S8Lit("c"))); TestResult(MatchParsedWithNode(string, tree)); } { MD_String8 string = MD_S8Lit("foo: { (size: u64) -> *void }"); - MD_Node *tree = MakeTestNode(MD_NodeKind_Label, MD_S8Lit("foo")); - MD_Node *params = MakeTestNode(MD_NodeKind_Label, MD_S8Lit("")); - MD_Node *size = MakeTestNode(MD_NodeKind_Label, MD_S8Lit("size")); - MD_PushChild(size, MakeTestNode(MD_NodeKind_Label, MD_S8Lit("u64"))); + MD_Node *tree = MakeTestNode(MD_NodeKind_Main, MD_S8Lit("foo")); + MD_Node *params = MakeTestNode(MD_NodeKind_Main, MD_S8Lit("")); + MD_Node *size = MakeTestNode(MD_NodeKind_Main, MD_S8Lit("size")); + MD_PushChild(size, MakeTestNode(MD_NodeKind_Main, MD_S8Lit("u64"))); MD_PushChild(params, size); MD_PushChild(tree, params); - MD_PushChild(tree, MakeTestNode(MD_NodeKind_Label, MD_S8Lit("-"))); - MD_PushChild(tree, MakeTestNode(MD_NodeKind_Label, MD_S8Lit(">"))); - MD_PushChild(tree, MakeTestNode(MD_NodeKind_Label, MD_S8Lit("*"))); - MD_PushChild(tree, MakeTestNode(MD_NodeKind_Label, MD_S8Lit("void"))); + MD_PushChild(tree, MakeTestNode(MD_NodeKind_Main, MD_S8Lit("-"))); + MD_PushChild(tree, MakeTestNode(MD_NodeKind_Main, MD_S8Lit(">"))); + MD_PushChild(tree, MakeTestNode(MD_NodeKind_Main, MD_S8Lit("*"))); + MD_PushChild(tree, MakeTestNode(MD_NodeKind_Main, MD_S8Lit("void"))); TestResult(MatchParsedWithNode(string, tree)); } } Test("Non-Sets") { - TestResult(MatchParsedWithNode(MD_S8Lit("foo"), MakeTestNode(MD_NodeKind_Label, MD_S8Lit("foo")))); - TestResult(MatchParsedWithNode(MD_S8Lit("123"), MakeTestNode(MD_NodeKind_Label, MD_S8Lit("123")))); - TestResult(MatchParsedWithNode(MD_S8Lit("+"), MakeTestNode(MD_NodeKind_Label, MD_S8Lit("+")))); + TestResult(MatchParsedWithNode(MD_S8Lit("foo"), MakeTestNode(MD_NodeKind_Main, MD_S8Lit("foo")))); + TestResult(MatchParsedWithNode(MD_S8Lit("123"), MakeTestNode(MD_NodeKind_Main, MD_S8Lit("123")))); + TestResult(MatchParsedWithNode(MD_S8Lit("+"), MakeTestNode(MD_NodeKind_Main, MD_S8Lit("+")))); } Test("Set Border Flags") { { MD_ParseResult parse = MD_ParseOneNode(MD_S8Lit("(0, 100)"), 0); - TestResult(parse.node->flags & MD_NodeFlag_ParenLeft && - parse.node->flags & MD_NodeFlag_ParenRight); + TestResult(parse.node->flags & MD_NodeFlag_HasParenLeft && + parse.node->flags & MD_NodeFlag_HasParenRight); } { MD_ParseResult parse = MD_ParseOneNode(MD_S8Lit("(0, 100]"), 0); - TestResult(parse.node->flags & MD_NodeFlag_ParenLeft && - parse.node->flags & MD_NodeFlag_BracketRight); + TestResult(parse.node->flags & MD_NodeFlag_HasParenLeft && + parse.node->flags & MD_NodeFlag_HasBracketRight); } { MD_ParseResult parse = MD_ParseOneNode(MD_S8Lit("[0, 100)"), 0); - TestResult(parse.node->flags & MD_NodeFlag_BracketLeft && - parse.node->flags & MD_NodeFlag_ParenRight); + TestResult(parse.node->flags & MD_NodeFlag_HasBracketLeft && + parse.node->flags & MD_NodeFlag_HasParenRight); } { MD_ParseResult parse = MD_ParseOneNode(MD_S8Lit("[0, 100]"), 0); - TestResult(parse.node->flags & MD_NodeFlag_BracketLeft && - parse.node->flags & MD_NodeFlag_BracketRight); + TestResult(parse.node->flags & MD_NodeFlag_HasBracketLeft && + parse.node->flags & MD_NodeFlag_HasBracketRight); } { MD_ParseResult parse = MD_ParseOneNode(MD_S8Lit("{0, 100}"), 0); - TestResult(parse.node->flags & MD_NodeFlag_BraceLeft && - parse.node->flags & MD_NodeFlag_BraceRight); + TestResult(parse.node->flags & MD_NodeFlag_HasBraceLeft && + parse.node->flags & MD_NodeFlag_HasBraceRight); } } @@ -275,13 +275,13 @@ int main(void) { { MD_ParseResult parse = MD_ParseOneNode(MD_S8Lit("(a, b)"), 0); - TestResult(parse.node->first_child->flags & MD_NodeFlag_BeforeComma); - TestResult(parse.node->first_child->next->flags & MD_NodeFlag_AfterComma); + TestResult(parse.node->first_child->flags & MD_NodeFlag_IsBeforeComma); + TestResult(parse.node->first_child->next->flags & MD_NodeFlag_IsAfterComma); } { MD_ParseResult parse = MD_ParseOneNode(MD_S8Lit("(a; b)"), 0); - TestResult(parse.node->first_child->flags & MD_NodeFlag_BeforeSemicolon); - TestResult(parse.node->first_child->next->flags & MD_NodeFlag_AfterSemicolon); + TestResult(parse.node->first_child->flags & MD_NodeFlag_IsBeforeSemicolon); + TestResult(parse.node->first_child->next->flags & MD_NodeFlag_IsAfterSemicolon); } } @@ -391,34 +391,34 @@ int main(void) Test("Style Strings") { { - MD_String8 str = MD_StyledStringFromString(MD_S8Lit("THIS_IS_A_TEST"), MD_WordStyle_UpperCamelCase, MD_S8Lit(" ")); - TestResult(MD_StringMatch(str, MD_S8Lit("This Is A Test"), 0)); + MD_String8 str = MD_S8Stylize(MD_S8Lit("THIS_IS_A_TEST"), MD_IdentifierStyle_UpperCamelCase, MD_S8Lit(" ")); + TestResult(MD_S8Match(str, MD_S8Lit("This Is A Test"), 0)); } { - MD_String8 str = MD_StyledStringFromString(MD_S8Lit("this_is_a_test"), MD_WordStyle_UpperCamelCase, MD_S8Lit(" ")); - TestResult(MD_StringMatch(str, MD_S8Lit("This Is A Test"), 0)); + MD_String8 str = MD_S8Stylize(MD_S8Lit("this_is_a_test"), MD_IdentifierStyle_UpperCamelCase, MD_S8Lit(" ")); + TestResult(MD_S8Match(str, MD_S8Lit("This Is A Test"), 0)); } { - MD_String8 str = MD_StyledStringFromString(MD_S8Lit("ThisIsATest"), MD_WordStyle_UpperCamelCase, MD_S8Lit(" ")); - TestResult(MD_StringMatch(str, MD_S8Lit("This Is A Test"), 0)); + MD_String8 str = MD_S8Stylize(MD_S8Lit("ThisIsATest"), MD_IdentifierStyle_UpperCamelCase, MD_S8Lit(" ")); + TestResult(MD_S8Match(str, MD_S8Lit("This Is A Test"), 0)); } { - MD_String8 str = MD_StyledStringFromString(MD_S8Lit("Here is another test."), MD_WordStyle_UpperCamelCase, MD_S8Lit("")); - TestResult(MD_StringMatch(str, MD_S8Lit("HereIsAnotherTest."), 0)); + MD_String8 str = MD_S8Stylize(MD_S8Lit("Here is another test."), MD_IdentifierStyle_UpperCamelCase, MD_S8Lit("")); + TestResult(MD_S8Match(str, MD_S8Lit("HereIsAnotherTest."), 0)); } } Test("Enum Strings") { - TestResult(MD_StringMatch(MD_StringFromNodeKind(MD_NodeKind_Label), MD_S8Lit("Label"), 0)); - TestResult(MD_StringMatch(MD_StringFromNodeKind(MD_NodeKind_Label), MD_S8Lit("Label"), 0)); - MD_String8List list = MD_StringListFromNodeFlags(MD_NodeFlag_StringLiteral | MD_NodeFlag_ParenLeft | MD_NodeFlag_BeforeSemicolon); + TestResult(MD_S8Match(MD_StringFromNodeKind(MD_NodeKind_Main), MD_S8Lit("Main"), 0)); + TestResult(MD_S8Match(MD_StringFromNodeKind(MD_NodeKind_Main), MD_S8Lit("Main"), 0)); + MD_String8List list = MD_StringListFromNodeFlags(MD_NodeFlag_StringLiteral | MD_NodeFlag_HasParenLeft | MD_NodeFlag_IsBeforeSemicolon); MD_b32 match = 1; for(MD_String8Node *node = list.first; node; node = node->next) { - if(!MD_StringMatch(node->string, MD_S8Lit("StringLiteral"), 0) && - !MD_StringMatch(node->string, MD_S8Lit("ParenLeft"), 0) && - !MD_StringMatch(node->string, MD_S8Lit("BeforeSemicolon"), 0)) + if(!MD_S8Match(node->string, MD_S8Lit("StringLiteral"), 0) && + !MD_S8Match(node->string, MD_S8Lit("HasParenLeft"), 0) && + !MD_S8Match(node->string, MD_S8Lit("IsBeforeSemicolon"), 0)) { match = 0; break; @@ -434,18 +434,18 @@ int main(void) { { MD_ParseResult parse = MD_ParseOneNode(MD_S8Lit("/*foobar*/ (a b c)"), 0); - TestResult(parse.node->kind == MD_NodeKind_Label && - MD_StringMatch(parse.node->comment_before, MD_S8Lit("foobar"), 0)); + TestResult(parse.node->kind == MD_NodeKind_Main && + MD_S8Match(parse.node->prev_comment, MD_S8Lit("foobar"), 0)); } { MD_ParseResult parse = MD_ParseOneNode(MD_S8Lit("// foobar\n(a b c)"), 0); - TestResult(parse.node->kind == MD_NodeKind_Label && - MD_StringMatch(parse.node->comment_before, MD_S8Lit(" foobar"), 0)); + TestResult(parse.node->kind == MD_NodeKind_Main && + MD_S8Match(parse.node->prev_comment, MD_S8Lit(" foobar"), 0)); } { MD_ParseResult parse = MD_ParseOneNode(MD_S8Lit("// foobar\n\n(a b c)"), 0); - TestResult(parse.node->kind == MD_NodeKind_Label && - MD_StringMatch(parse.node->comment_before, MD_S8Lit(""), 0)); + TestResult(parse.node->kind == MD_NodeKind_Main && + MD_S8Match(parse.node->prev_comment, MD_S8Lit(""), 0)); } } @@ -453,23 +453,23 @@ int main(void) { { MD_ParseResult parse = MD_ParseOneNode(MD_S8Lit("(a b c) /*foobar*/"), 0); - TestResult(parse.node->kind == MD_NodeKind_Label && - MD_StringMatch(parse.node->comment_after, MD_S8Lit("foobar"), 0)); + TestResult(parse.node->kind == MD_NodeKind_Main && + MD_S8Match(parse.node->next_comment, MD_S8Lit("foobar"), 0)); } { MD_ParseResult parse = MD_ParseOneNode(MD_S8Lit("(a b c) // foobar"), 0); - TestResult(parse.node->kind == MD_NodeKind_Label && - MD_StringMatch(parse.node->comment_after, MD_S8Lit(" foobar"), 0)); + TestResult(parse.node->kind == MD_NodeKind_Main && + MD_S8Match(parse.node->next_comment, MD_S8Lit(" foobar"), 0)); } { MD_ParseResult parse = MD_ParseOneNode(MD_S8Lit("(a b c)\n// foobar"), 0); - TestResult(parse.node->kind == MD_NodeKind_Label && - MD_StringMatch(parse.node->comment_after, MD_S8Lit(""), 0)); + TestResult(parse.node->kind == MD_NodeKind_Main && + MD_S8Match(parse.node->next_comment, MD_S8Lit(""), 0)); } { MD_ParseResult parse = MD_ParseOneNode(MD_S8Lit("(a b c)\n\n// foobar"), 0); - TestResult(parse.node->kind == MD_NodeKind_Label && - MD_StringMatch(parse.node->comment_after, MD_S8Lit(""), 0)); + TestResult(parse.node->kind == MD_NodeKind_Main && + MD_S8Match(parse.node->next_comment, MD_S8Lit(""), 0)); } } } @@ -495,7 +495,7 @@ int main(void) MD_b32 columns_match = 1; { - MD_Error *e = parse.errors.first; + MD_Message *e = parse.errors.first; for(int i_error = 0; i_error < max_error_count && tests[i_test].columns[i_error]; ++i_error) { if(!e || MD_CodeLocFromNode(e->node).column != tests[i_test].columns[i_error]) @@ -574,60 +574,60 @@ int main(void) nodes[i] = result.node; } - TestResult(MD_StringMatch(nodes[0]->string, MD_S8Lit("foo-bar"), 0)); - TestResult(MD_StringMatch(nodes[1]->string, MD_S8Lit("foo-bar"), 0)); - TestResult(MD_StringMatch(nodes[2]->string, MD_S8Lit("foo-bar"), 0)); - TestResult(MD_StringMatch(nodes[3]->string, MD_S8Lit("foo-bar"), 0)); - TestResult(MD_StringMatch(nodes[4]->string, MD_S8Lit("foo-bar"), 0)); - TestResult(MD_StringMatch(nodes[5]->string, MD_S8Lit("foo-bar"), 0)); + TestResult(MD_S8Match(nodes[0]->string, MD_S8Lit("foo-bar"), 0)); + TestResult(MD_S8Match(nodes[1]->string, MD_S8Lit("foo-bar"), 0)); + TestResult(MD_S8Match(nodes[2]->string, MD_S8Lit("foo-bar"), 0)); + TestResult(MD_S8Match(nodes[3]->string, MD_S8Lit("foo-bar"), 0)); + TestResult(MD_S8Match(nodes[4]->string, MD_S8Lit("foo-bar"), 0)); + TestResult(MD_S8Match(nodes[5]->string, MD_S8Lit("foo-bar"), 0)); - TestResult(MD_StringMatch(nodes[0]->whole_string, samples[0], 0)); - TestResult(MD_StringMatch(nodes[1]->whole_string, samples[1], 0)); - TestResult(MD_StringMatch(nodes[2]->whole_string, samples[2], 0)); - TestResult(MD_StringMatch(nodes[3]->whole_string, samples[3], 0)); - TestResult(MD_StringMatch(nodes[4]->whole_string, samples[4], 0)); - TestResult(MD_StringMatch(nodes[5]->whole_string, samples[5], 0)); + TestResult(MD_S8Match(nodes[0]->raw_string, samples[0], 0)); + TestResult(MD_S8Match(nodes[1]->raw_string, samples[1], 0)); + TestResult(MD_S8Match(nodes[2]->raw_string, samples[2], 0)); + TestResult(MD_S8Match(nodes[3]->raw_string, samples[3], 0)); + TestResult(MD_S8Match(nodes[4]->raw_string, samples[4], 0)); + TestResult(MD_S8Match(nodes[5]->raw_string, samples[5], 0)); } Test("String escaping") { { MD_ParseResult parse = MD_ParseOneNode(MD_S8Lit("`\\``"), 0); - TestResult(MD_StringMatch(parse.node->string, MD_S8Lit("\\`"), 0)); + TestResult(MD_S8Match(parse.node->string, MD_S8Lit("\\`"), 0)); } { MD_ParseResult parse = MD_ParseOneNode(MD_S8Lit("``` \\``` ```"), 0); - TestResult(MD_StringMatch(parse.node->string, MD_S8Lit(" \\``` "), 0)); + TestResult(MD_S8Match(parse.node->string, MD_S8Lit(" \\``` "), 0)); } { MD_ParseResult parse = MD_ParseOneNode(MD_S8Lit("`````\\````"), 0); - TestResult(MD_StringMatch(parse.node->string, MD_S8Lit("``\\`"), 0)); + TestResult(MD_S8Match(parse.node->string, MD_S8Lit("``\\`"), 0)); } { MD_ParseResult parse = MD_ParseOneNode(MD_S8Lit("`\\'`"), 0); - TestResult(MD_StringMatch(parse.node->string, MD_S8Lit("\\'"), 0)); + TestResult(MD_S8Match(parse.node->string, MD_S8Lit("\\'"), 0)); } { MD_ParseResult parse = MD_ParseOneNode(MD_S8Lit("''' \\''' '''"), 0); - TestResult(MD_StringMatch(parse.node->string, MD_S8Lit(" \\''' "), 0)); + TestResult(MD_S8Match(parse.node->string, MD_S8Lit(" \\''' "), 0)); } { MD_ParseResult parse = MD_ParseOneNode(MD_S8Lit("'''''\\''''"), 0); - TestResult(MD_StringMatch(parse.node->string, MD_S8Lit("''\\'"), 0)); + TestResult(MD_S8Match(parse.node->string, MD_S8Lit("''\\'"), 0)); } { MD_ParseResult parse = MD_ParseOneNode(MD_S8Lit("`\\\"`"), 0); - TestResult(MD_StringMatch(parse.node->string, MD_S8Lit("\\\""), 0)); + TestResult(MD_S8Match(parse.node->string, MD_S8Lit("\\\""), 0)); } { MD_ParseResult parse = MD_ParseOneNode(MD_S8Lit("\"\"\" \\\"\"\" \"\"\""), 0); - TestResult(MD_StringMatch(parse.node->string, MD_S8Lit(" \\\"\"\" "), 0)); + TestResult(MD_S8Match(parse.node->string, MD_S8Lit(" \\\"\"\" "), 0)); } { MD_ParseResult parse = MD_ParseOneNode(MD_S8Lit("\"\"\"\"\"\\\"\"\"\""), 0); - TestResult(MD_StringMatch(parse.node->string, MD_S8Lit("\"\"\\\""), 0)); + TestResult(MD_S8Match(parse.node->string, MD_S8Lit("\"\"\\\""), 0)); } } @@ -638,48 +638,48 @@ int main(void) MD_ParseResult parse = MD_ParseOneNode(MD_S8Lit("foo:{x y z; a b c}"), 0); MD_Node *node = parse.node; MD_Node *group_first = node->first_child; - MD_Node *group_last = MD_SeekNodeWithFlags(group_first, MD_NodeFlag_AfterSemicolon); + MD_Node *group_opl = MD_NodeFromFlags(group_first->next, MD_NilNode(), MD_NodeFlag_IsAfterSemicolon); - TestResult(MD_StringMatch(group_first->string, MD_S8Lit("x"), 0)); - TestResult(MD_StringMatch(group_first->next->string, MD_S8Lit("y"), 0)); - TestResult(MD_StringMatch(group_first->next->next->string, MD_S8Lit("z"), 0)); - TestResult(group_last == group_first->next->next->next); + TestResult(MD_S8Match(group_first->string, MD_S8Lit("x"), 0)); + TestResult(MD_S8Match(group_first->next->string, MD_S8Lit("y"), 0)); + TestResult(MD_S8Match(group_first->next->next->string, MD_S8Lit("z"), 0)); + TestResult(group_opl == group_first->next->next->next); - group_first = group_last; - group_last = MD_SeekNodeWithFlags(group_first, MD_NodeFlag_AfterSemicolon); + group_first = group_opl; + group_opl = MD_NodeFromFlags(group_first, MD_NilNode(), MD_NodeFlag_IsAfterSemicolon); - TestResult(MD_StringMatch(group_first->string, MD_S8Lit("a"), 0)); - TestResult(MD_StringMatch(group_first->next->string, MD_S8Lit("b"), 0)); - TestResult(MD_StringMatch(group_first->next->next->string, MD_S8Lit("c"), 0)); - TestResult(group_last == group_first->next->next->next); + TestResult(MD_S8Match(group_first->string, MD_S8Lit("a"), 0)); + TestResult(MD_S8Match(group_first->next->string, MD_S8Lit("b"), 0)); + TestResult(MD_S8Match(group_first->next->next->string, MD_S8Lit("c"), 0)); + TestResult(group_opl == group_first->next->next->next); } { MD_ParseResult parse = MD_ParseOneNode(MD_S8Lit("foo:{a b c , d e f , g h i}"), 0); MD_Node *node = parse.node; MD_Node *group_first = 0; - MD_Node *group_last = 0; + MD_Node *group_opl = 0; group_first = node->first_child; - group_last = MD_SeekNodeWithFlags(group_first, MD_NodeFlag_AfterComma); - TestResult(MD_StringMatch(group_first->string, MD_S8Lit("a"), 0)); - TestResult(MD_StringMatch(group_first->next->string, MD_S8Lit("b"), 0)); - TestResult(MD_StringMatch(group_first->next->next->string, MD_S8Lit("c"), 0)); - TestResult(group_last == group_first->next->next->next); + group_opl = MD_NodeFromFlags(group_first, MD_NilNode(), MD_NodeFlag_IsAfterComma); + TestResult(MD_S8Match(group_first->string, MD_S8Lit("a"), 0)); + TestResult(MD_S8Match(group_first->next->string, MD_S8Lit("b"), 0)); + TestResult(MD_S8Match(group_first->next->next->string, MD_S8Lit("c"), 0)); + TestResult(group_opl == group_first->next->next->next); - group_first = group_last; - group_last = MD_SeekNodeWithFlags(group_first, MD_NodeFlag_AfterComma); - TestResult(MD_StringMatch(group_first->string, MD_S8Lit("d"), 0)); - TestResult(MD_StringMatch(group_first->next->string, MD_S8Lit("e"), 0)); - TestResult(MD_StringMatch(group_first->next->next->string, MD_S8Lit("f"), 0)); - TestResult(group_last == group_first->next->next->next); + group_first = group_opl; + group_opl = MD_NodeFromFlags(group_first, MD_NilNode(), MD_NodeFlag_IsAfterComma); + TestResult(MD_S8Match(group_first->string, MD_S8Lit("d"), 0)); + TestResult(MD_S8Match(group_first->next->string, MD_S8Lit("e"), 0)); + TestResult(MD_S8Match(group_first->next->next->string, MD_S8Lit("f"), 0)); + TestResult(group_opl == group_first->next->next->next); - group_first = group_last; - group_last = MD_SeekNodeWithFlags(group_first, MD_NodeFlag_AfterComma); - TestResult(MD_StringMatch(group_first->string, MD_S8Lit("g"), 0)); - TestResult(MD_StringMatch(group_first->next->string, MD_S8Lit("h"), 0)); - TestResult(MD_StringMatch(group_first->next->next->string, MD_S8Lit("i"), 0)); - TestResult(group_last == group_first->next->next->next); + group_first = group_opl; + group_opl = MD_NodeFromFlags(group_first, MD_NilNode(), MD_NodeFlag_IsAfterComma); + TestResult(MD_S8Match(group_first->string, MD_S8Lit("g"), 0)); + TestResult(MD_S8Match(group_first->next->string, MD_S8Lit("h"), 0)); + TestResult(MD_S8Match(group_first->next->next->string, MD_S8Lit("i"), 0)); + TestResult(group_opl == group_first->next->next->next); } } @@ -867,4 +867,4 @@ int main(void) } return 0; -} \ No newline at end of file +} diff --git a/tests/unicode_test.c b/tests/unicode_test.c index 623df3c..b504737 100644 --- a/tests/unicode_test.c +++ b/tests/unicode_test.c @@ -5,11 +5,11 @@ void run_test_on_string(MD_String8 string) { MD_String16 s16 = MD_S16FromS8(string); MD_String8 s8_ts16 = MD_S8FromS16(s16); - MD_Assert(MD_StringMatch(s8_ts16, string, 0)); + MD_Assert(MD_S8Match(s8_ts16, string, 0)); MD_String32 s32 = MD_S32FromS8(string); MD_String8 s8_ts32 = MD_S8FromS32(s32); - MD_Assert(MD_StringMatch(s8_ts32, string, 0)); + MD_Assert(MD_S8Match(s8_ts32, string, 0)); } int main(void)