fix msvc
This commit is contained in:
383
vendor/mruby-compiler2/lib/prism/include/prism.h
vendored
Normal file
383
vendor/mruby-compiler2/lib/prism/include/prism.h
vendored
Normal file
@@ -0,0 +1,383 @@
|
||||
/**
|
||||
* @file prism.h
|
||||
*
|
||||
* The main header file for the prism parser.
|
||||
*/
|
||||
#ifndef PRISM_H
|
||||
#define PRISM_H
|
||||
|
||||
#include "prism/defines.h"
|
||||
#include "prism/util/pm_buffer.h"
|
||||
#include "prism/util/pm_char.h"
|
||||
#include "prism/util/pm_integer.h"
|
||||
#include "prism/util/pm_memchr.h"
|
||||
#include "prism/util/pm_strncasecmp.h"
|
||||
#include "prism/util/pm_strpbrk.h"
|
||||
#include "prism/ast.h"
|
||||
#include "prism/diagnostic.h"
|
||||
#include "prism/node.h"
|
||||
#include "prism/options.h"
|
||||
#include "prism/pack.h"
|
||||
#include "prism/parser.h"
|
||||
#include "prism/prettyprint.h"
|
||||
#include "prism/regexp.h"
|
||||
#include "prism/static_literals.h"
|
||||
#include "prism/version.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <locale.h>
|
||||
#include <math.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <strings.h>
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The prism version and the serialization format.
|
||||
*
|
||||
* @returns The prism version as a constant string.
|
||||
*/
|
||||
PRISM_EXPORTED_FUNCTION const char * pm_version(void);
|
||||
|
||||
/**
|
||||
* Initialize a parser with the given start and end pointers.
|
||||
*
|
||||
* @param parser The parser to initialize.
|
||||
* @param source The source to parse.
|
||||
* @param size The size of the source.
|
||||
* @param options The optional options to use when parsing.
|
||||
*/
|
||||
PRISM_EXPORTED_FUNCTION void pm_parser_init(pm_parser_t *parser, const uint8_t *source, size_t size, const pm_options_t *options);
|
||||
|
||||
/**
|
||||
* Register a callback that will be called whenever prism changes the encoding
|
||||
* it is using to parse based on the magic comment.
|
||||
*
|
||||
* @param parser The parser to register the callback with.
|
||||
* @param callback The callback to register.
|
||||
*/
|
||||
PRISM_EXPORTED_FUNCTION void pm_parser_register_encoding_changed_callback(pm_parser_t *parser, pm_encoding_changed_callback_t callback);
|
||||
|
||||
/**
|
||||
* Free any memory associated with the given parser.
|
||||
*
|
||||
* @param parser The parser to free.
|
||||
*/
|
||||
PRISM_EXPORTED_FUNCTION void pm_parser_free(pm_parser_t *parser);
|
||||
|
||||
/**
|
||||
* Initiate the parser with the given parser.
|
||||
*
|
||||
* @param parser The parser to use.
|
||||
* @return The AST representing the source.
|
||||
*/
|
||||
PRISM_EXPORTED_FUNCTION pm_node_t * pm_parse(pm_parser_t *parser);
|
||||
|
||||
/**
|
||||
* This function is used in pm_parse_stream to retrieve a line of input from a
|
||||
* stream. It closely mirrors that of fgets so that fgets can be used as the
|
||||
* default implementation.
|
||||
*/
|
||||
typedef char * (pm_parse_stream_fgets_t)(char *string, int size, void *stream);
|
||||
|
||||
/**
|
||||
* Parse a stream of Ruby source and return the tree.
|
||||
*
|
||||
* @param parser The parser to use.
|
||||
* @param buffer The buffer to use.
|
||||
* @param stream The stream to parse.
|
||||
* @param stream_fgets The function to use to read from the stream.
|
||||
* @param options The optional options to use when parsing.
|
||||
* @return The AST representing the source.
|
||||
*/
|
||||
PRISM_EXPORTED_FUNCTION pm_node_t * pm_parse_stream(pm_parser_t *parser, pm_buffer_t *buffer, void *stream, pm_parse_stream_fgets_t *stream_fgets, const pm_options_t *options);
|
||||
|
||||
// We optionally support serializing to a binary string. For systems that don't
|
||||
// want or need this functionality, it can be turned off with the
|
||||
// PRISM_EXCLUDE_SERIALIZATION define.
|
||||
#ifndef PRISM_EXCLUDE_SERIALIZATION
|
||||
|
||||
/**
|
||||
* Parse and serialize the AST represented by the source that is read out of the
|
||||
* given stream into to the given buffer.
|
||||
*
|
||||
* @param buffer The buffer to serialize to.
|
||||
* @param stream The stream to parse.
|
||||
* @param stream_fgets The function to use to read from the stream.
|
||||
* @param data The optional data to pass to the parser.
|
||||
*/
|
||||
PRISM_EXPORTED_FUNCTION void pm_serialize_parse_stream(pm_buffer_t *buffer, void *stream, pm_parse_stream_fgets_t *stream_fgets, const char *data);
|
||||
|
||||
/**
|
||||
* Serialize the given list of comments to the given buffer.
|
||||
*
|
||||
* @param parser The parser to serialize.
|
||||
* @param list The list of comments to serialize.
|
||||
* @param buffer The buffer to serialize to.
|
||||
*/
|
||||
void pm_serialize_comment_list(pm_parser_t *parser, pm_list_t *list, pm_buffer_t *buffer);
|
||||
|
||||
/**
|
||||
* Serialize the name of the encoding to the buffer.
|
||||
*
|
||||
* @param encoding The encoding to serialize.
|
||||
* @param buffer The buffer to serialize to.
|
||||
*/
|
||||
void pm_serialize_encoding(const pm_encoding_t *encoding, pm_buffer_t *buffer);
|
||||
|
||||
/**
|
||||
* Serialize the encoding, metadata, nodes, and constant pool.
|
||||
*
|
||||
* @param parser The parser to serialize.
|
||||
* @param node The node to serialize.
|
||||
* @param buffer The buffer to serialize to.
|
||||
*/
|
||||
void pm_serialize_content(pm_parser_t *parser, pm_node_t *node, pm_buffer_t *buffer);
|
||||
|
||||
/**
|
||||
* Serialize the AST represented by the given node to the given buffer.
|
||||
*
|
||||
* @param parser The parser to serialize.
|
||||
* @param node The node to serialize.
|
||||
* @param buffer The buffer to serialize to.
|
||||
*/
|
||||
PRISM_EXPORTED_FUNCTION void pm_serialize(pm_parser_t *parser, pm_node_t *node, pm_buffer_t *buffer);
|
||||
|
||||
/**
|
||||
* Parse the given source to the AST and dump the AST to the given buffer.
|
||||
*
|
||||
* @param buffer The buffer to serialize to.
|
||||
* @param source The source to parse.
|
||||
* @param size The size of the source.
|
||||
* @param data The optional data to pass to the parser.
|
||||
*/
|
||||
PRISM_EXPORTED_FUNCTION void pm_serialize_parse(pm_buffer_t *buffer, const uint8_t *source, size_t size, const char *data);
|
||||
|
||||
/**
|
||||
* Parse and serialize the comments in the given source to the given buffer.
|
||||
*
|
||||
* @param buffer The buffer to serialize to.
|
||||
* @param source The source to parse.
|
||||
* @param size The size of the source.
|
||||
* @param data The optional data to pass to the parser.
|
||||
*/
|
||||
PRISM_EXPORTED_FUNCTION void pm_serialize_parse_comments(pm_buffer_t *buffer, const uint8_t *source, size_t size, const char *data);
|
||||
|
||||
/**
|
||||
* Lex the given source and serialize to the given buffer.
|
||||
*
|
||||
* @param source The source to lex.
|
||||
* @param size The size of the source.
|
||||
* @param buffer The buffer to serialize to.
|
||||
* @param data The optional data to pass to the lexer.
|
||||
*/
|
||||
PRISM_EXPORTED_FUNCTION void pm_serialize_lex(pm_buffer_t *buffer, const uint8_t *source, size_t size, const char *data);
|
||||
|
||||
/**
|
||||
* Parse and serialize both the AST and the tokens represented by the given
|
||||
* source to the given buffer.
|
||||
*
|
||||
* @param buffer The buffer to serialize to.
|
||||
* @param source The source to parse.
|
||||
* @param size The size of the source.
|
||||
* @param data The optional data to pass to the parser.
|
||||
*/
|
||||
PRISM_EXPORTED_FUNCTION void pm_serialize_parse_lex(pm_buffer_t *buffer, const uint8_t *source, size_t size, const char *data);
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Parse the source and return true if it parses without errors or warnings.
|
||||
*
|
||||
* @param source The source to parse.
|
||||
* @param size The size of the source.
|
||||
* @param data The optional data to pass to the parser.
|
||||
* @return True if the source parses without errors or warnings.
|
||||
*/
|
||||
PRISM_EXPORTED_FUNCTION bool pm_parse_success_p(const uint8_t *source, size_t size, const char *data);
|
||||
|
||||
/**
|
||||
* Returns a string representation of the given token type.
|
||||
*
|
||||
* @param token_type The token type to convert to a string.
|
||||
* @return A string representation of the given token type.
|
||||
*/
|
||||
PRISM_EXPORTED_FUNCTION const char * pm_token_type_name(pm_token_type_t token_type);
|
||||
|
||||
/**
|
||||
* Returns the human name of the given token type.
|
||||
*
|
||||
* @param token_type The token type to convert to a human name.
|
||||
* @return The human name of the given token type.
|
||||
*/
|
||||
const char * pm_token_type_human(pm_token_type_t token_type);
|
||||
|
||||
// We optionally support dumping to JSON. For systems that don't want or need
|
||||
// this functionality, it can be turned off with the PRISM_EXCLUDE_JSON define.
|
||||
#ifndef PRISM_EXCLUDE_JSON
|
||||
|
||||
/**
|
||||
* Dump JSON to the given buffer.
|
||||
*
|
||||
* @param buffer The buffer to serialize to.
|
||||
* @param parser The parser that parsed the node.
|
||||
* @param node The node to serialize.
|
||||
*/
|
||||
PRISM_EXPORTED_FUNCTION void pm_dump_json(pm_buffer_t *buffer, const pm_parser_t *parser, const pm_node_t *node);
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Represents the results of a slice query.
|
||||
*/
|
||||
typedef enum {
|
||||
/** Returned if the encoding given to a slice query was invalid. */
|
||||
PM_STRING_QUERY_ERROR = -1,
|
||||
|
||||
/** Returned if the result of the slice query is false. */
|
||||
PM_STRING_QUERY_FALSE,
|
||||
|
||||
/** Returned if the result of the slice query is true. */
|
||||
PM_STRING_QUERY_TRUE
|
||||
} pm_string_query_t;
|
||||
|
||||
/**
|
||||
* Check that the slice is a valid local variable name.
|
||||
*
|
||||
* @param source The source to check.
|
||||
* @param length The length of the source.
|
||||
* @param encoding_name The name of the encoding of the source.
|
||||
* @return PM_STRING_QUERY_TRUE if the query is true, PM_STRING_QUERY_FALSE if
|
||||
* the query is false, and PM_STRING_QUERY_ERROR if the encoding was invalid.
|
||||
*/
|
||||
PRISM_EXPORTED_FUNCTION pm_string_query_t pm_string_query_local(const uint8_t *source, size_t length, const char *encoding_name);
|
||||
|
||||
/**
|
||||
* Check that the slice is a valid constant name.
|
||||
*
|
||||
* @param source The source to check.
|
||||
* @param length The length of the source.
|
||||
* @param encoding_name The name of the encoding of the source.
|
||||
* @return PM_STRING_QUERY_TRUE if the query is true, PM_STRING_QUERY_FALSE if
|
||||
* the query is false, and PM_STRING_QUERY_ERROR if the encoding was invalid.
|
||||
*/
|
||||
PRISM_EXPORTED_FUNCTION pm_string_query_t pm_string_query_constant(const uint8_t *source, size_t length, const char *encoding_name);
|
||||
|
||||
/**
|
||||
* Check that the slice is a valid method name.
|
||||
*
|
||||
* @param source The source to check.
|
||||
* @param length The length of the source.
|
||||
* @param encoding_name The name of the encoding of the source.
|
||||
* @return PM_STRING_QUERY_TRUE if the query is true, PM_STRING_QUERY_FALSE if
|
||||
* the query is false, and PM_STRING_QUERY_ERROR if the encoding was invalid.
|
||||
*/
|
||||
PRISM_EXPORTED_FUNCTION pm_string_query_t pm_string_query_method_name(const uint8_t *source, size_t length, const char *encoding_name);
|
||||
|
||||
/**
|
||||
* @mainpage
|
||||
*
|
||||
* Prism is a parser for the Ruby programming language. It is designed to be
|
||||
* portable, error tolerant, and maintainable. It is written in C99 and has no
|
||||
* dependencies. It is currently being integrated into
|
||||
* [CRuby](https://github.com/ruby/ruby),
|
||||
* [JRuby](https://github.com/jruby/jruby),
|
||||
* [TruffleRuby](https://github.com/oracle/truffleruby),
|
||||
* [Sorbet](https://github.com/sorbet/sorbet), and
|
||||
* [Syntax Tree](https://github.com/ruby-syntax-tree/syntax_tree).
|
||||
*
|
||||
* @section getting-started Getting started
|
||||
*
|
||||
* If you're vendoring this project and compiling it statically then as long as
|
||||
* you have a C99 compiler you will be fine. If you're linking against it as
|
||||
* shared library, then you should compile with `-fvisibility=hidden` and
|
||||
* `-DPRISM_EXPORT_SYMBOLS` to tell prism to make only its public interface
|
||||
* visible.
|
||||
*
|
||||
* @section parsing Parsing
|
||||
*
|
||||
* In order to parse Ruby code, the structures and functions that you're going
|
||||
* to want to use and be aware of are:
|
||||
*
|
||||
* * `pm_parser_t` - the main parser structure
|
||||
* * `pm_parser_init` - initialize a parser
|
||||
* * `pm_parse` - parse and return the root node
|
||||
* * `pm_node_destroy` - deallocate the root node returned by `pm_parse`
|
||||
* * `pm_parser_free` - free the internal memory of the parser
|
||||
*
|
||||
* Putting all of this together would look something like:
|
||||
*
|
||||
* ```c
|
||||
* void parse(const uint8_t *source, size_t length) {
|
||||
* pm_parser_t parser;
|
||||
* pm_parser_init(&parser, source, length, NULL);
|
||||
*
|
||||
* pm_node_t *root = pm_parse(&parser);
|
||||
* printf("PARSED!\n");
|
||||
*
|
||||
* pm_node_destroy(&parser, root);
|
||||
* pm_parser_free(&parser);
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* All of the nodes "inherit" from `pm_node_t` by embedding those structures as
|
||||
* their first member. This means you can downcast and upcast any node in the
|
||||
* tree to a `pm_node_t`.
|
||||
*
|
||||
* @section serializing Serializing
|
||||
*
|
||||
* Prism provides the ability to serialize the AST and its related metadata into
|
||||
* a binary format. This format is designed to be portable to different
|
||||
* languages and runtimes so that you only need to make one FFI call in order to
|
||||
* parse Ruby code. The structures and functions that you're going to want to
|
||||
* use and be aware of are:
|
||||
*
|
||||
* * `pm_buffer_t` - a small buffer object that will hold the serialized AST
|
||||
* * `pm_buffer_free` - free the memory associated with the buffer
|
||||
* * `pm_serialize` - serialize the AST into a buffer
|
||||
* * `pm_serialize_parse` - parse and serialize the AST into a buffer
|
||||
*
|
||||
* Putting all of this together would look something like:
|
||||
*
|
||||
* ```c
|
||||
* void serialize(const uint8_t *source, size_t length) {
|
||||
* pm_buffer_t buffer = { 0 };
|
||||
*
|
||||
* pm_serialize_parse(&buffer, source, length, NULL);
|
||||
* printf("SERIALIZED!\n");
|
||||
*
|
||||
* pm_buffer_free(&buffer);
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @section inspecting Inspecting
|
||||
*
|
||||
* Prism provides the ability to inspect the AST by pretty-printing nodes. You
|
||||
* can do this with the `pm_prettyprint` function, which you would use like:
|
||||
*
|
||||
* ```c
|
||||
* void prettyprint(const uint8_t *source, size_t length) {
|
||||
* pm_parser_t parser;
|
||||
* pm_parser_init(&parser, source, length, NULL);
|
||||
*
|
||||
* pm_node_t *root = pm_parse(&parser);
|
||||
* pm_buffer_t buffer = { 0 };
|
||||
*
|
||||
* pm_prettyprint(&buffer, &parser, root);
|
||||
* printf("%*.s\n", (int) buffer.length, buffer.value);
|
||||
*
|
||||
* pm_buffer_free(&buffer);
|
||||
* pm_node_destroy(&parser, root);
|
||||
* pm_parser_free(&parser);
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
|
||||
#endif
|
||||
7964
vendor/mruby-compiler2/lib/prism/include/prism/ast.h
vendored
Normal file
7964
vendor/mruby-compiler2/lib/prism/include/prism/ast.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
260
vendor/mruby-compiler2/lib/prism/include/prism/defines.h
vendored
Normal file
260
vendor/mruby-compiler2/lib/prism/include/prism/defines.h
vendored
Normal file
@@ -0,0 +1,260 @@
|
||||
/**
|
||||
* @file defines.h
|
||||
*
|
||||
* Macro definitions used throughout the prism library.
|
||||
*
|
||||
* This file should be included first by any *.h or *.c in prism for consistency
|
||||
* and to ensure that the macros are defined before they are used.
|
||||
*/
|
||||
#ifndef PRISM_DEFINES_H
|
||||
#define PRISM_DEFINES_H
|
||||
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
/**
|
||||
* We want to be able to use the PRI* macros for printing out integers, but on
|
||||
* some platforms they aren't included unless this is already defined.
|
||||
*/
|
||||
#define __STDC_FORMAT_MACROS
|
||||
// Include sys/types.h before inttypes.h to work around issue with
|
||||
// certain versions of GCC and newlib which causes omission of PRIx64
|
||||
#include <sys/types.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
/**
|
||||
* When we are parsing using recursive descent, we want to protect against
|
||||
* malicious payloads that could attempt to crash our parser. We do this by
|
||||
* specifying a maximum depth to which we are allowed to recurse.
|
||||
*/
|
||||
#ifndef PRISM_DEPTH_MAXIMUM
|
||||
#define PRISM_DEPTH_MAXIMUM 10000
|
||||
#endif
|
||||
|
||||
/**
|
||||
* By default, we compile with -fvisibility=hidden. When this is enabled, we
|
||||
* need to mark certain functions as being publically-visible. This macro does
|
||||
* that in a compiler-agnostic way.
|
||||
*/
|
||||
#ifndef PRISM_EXPORTED_FUNCTION
|
||||
# ifdef PRISM_EXPORT_SYMBOLS
|
||||
# ifdef _WIN32
|
||||
# define PRISM_EXPORTED_FUNCTION __declspec(dllexport) extern
|
||||
# else
|
||||
# define PRISM_EXPORTED_FUNCTION __attribute__((__visibility__("default"))) extern
|
||||
# endif
|
||||
# else
|
||||
# define PRISM_EXPORTED_FUNCTION
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Certain compilers support specifying that a function accepts variadic
|
||||
* parameters that look like printf format strings to provide a better developer
|
||||
* experience when someone is using the function. This macro does that in a
|
||||
* compiler-agnostic way.
|
||||
*/
|
||||
#if defined(__GNUC__)
|
||||
# if defined(__MINGW_PRINTF_FORMAT)
|
||||
# define PRISM_ATTRIBUTE_FORMAT(string_index, argument_index) __attribute__((format(__MINGW_PRINTF_FORMAT, string_index, argument_index)))
|
||||
# else
|
||||
# define PRISM_ATTRIBUTE_FORMAT(string_index, argument_index) __attribute__((format(printf, string_index, argument_index)))
|
||||
# endif
|
||||
#elif defined(__clang__)
|
||||
# define PRISM_ATTRIBUTE_FORMAT(string_index, argument_index) __attribute__((__format__(__printf__, string_index, argument_index)))
|
||||
#else
|
||||
# define PRISM_ATTRIBUTE_FORMAT(string_index, argument_index)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* GCC will warn if you specify a function or parameter that is unused at
|
||||
* runtime. This macro allows you to mark a function or parameter as unused in a
|
||||
* compiler-agnostic way.
|
||||
*/
|
||||
#if defined(__GNUC__)
|
||||
# define PRISM_ATTRIBUTE_UNUSED __attribute__((unused))
|
||||
#else
|
||||
# define PRISM_ATTRIBUTE_UNUSED
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Old Visual Studio versions do not support the inline keyword, so we need to
|
||||
* define it to be __inline.
|
||||
*/
|
||||
#if defined(_MSC_VER) && !defined(inline)
|
||||
# define inline __inline
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Old Visual Studio versions before 2015 do not implement sprintf, but instead
|
||||
* implement _snprintf. We standard that here.
|
||||
*/
|
||||
#if !defined(snprintf) && defined(_MSC_VER) && (_MSC_VER < 1900)
|
||||
# define snprintf _snprintf
|
||||
#endif
|
||||
|
||||
/**
|
||||
* A simple utility macro to concatenate two tokens together, necessary when one
|
||||
* of the tokens is itself a macro.
|
||||
*/
|
||||
#define PM_CONCATENATE(left, right) left ## right
|
||||
|
||||
/**
|
||||
* We want to be able to use static assertions, but they weren't standardized
|
||||
* until C11. As such, we polyfill it here by making a hacky typedef that will
|
||||
* fail to compile due to a negative array size if the condition is false.
|
||||
*/
|
||||
#if defined(_Static_assert)
|
||||
# define PM_STATIC_ASSERT(line, condition, message) _Static_assert(condition, message)
|
||||
#else
|
||||
# define PM_STATIC_ASSERT(line, condition, message) typedef char PM_CONCATENATE(static_assert_, line)[(condition) ? 1 : -1]
|
||||
#endif
|
||||
|
||||
/**
|
||||
* In general, libc for embedded systems does not support memory-mapped files.
|
||||
* If the target platform is POSIX or Windows, we can map a file in memory and
|
||||
* read it in a more efficient manner.
|
||||
*/
|
||||
#ifdef _WIN32
|
||||
# define PRISM_HAS_MMAP
|
||||
#else
|
||||
# include <unistd.h>
|
||||
# ifdef _POSIX_MAPPED_FILES
|
||||
# define PRISM_HAS_MMAP
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* If PRISM_HAS_NO_FILESYSTEM is defined, then we want to exclude all filesystem
|
||||
* related code from the library. All filesystem related code should be guarded
|
||||
* by PRISM_HAS_FILESYSTEM.
|
||||
*/
|
||||
#ifndef PRISM_HAS_NO_FILESYSTEM
|
||||
# define PRISM_HAS_FILESYSTEM
|
||||
#endif
|
||||
|
||||
/**
|
||||
* isinf on POSIX systems it accepts a float, a double, or a long double.
|
||||
* But mingw didn't provide an isinf macro, only an isinf function that only
|
||||
* accepts floats, so we need to use _finite instead.
|
||||
*/
|
||||
#ifdef __MINGW64__
|
||||
#include <float.h>
|
||||
#define PRISM_ISINF(x) (!_finite(x))
|
||||
#else
|
||||
#define PRISM_ISINF(x) isinf(x)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* If you build prism with a custom allocator, configure it with
|
||||
* "-D PRISM_XALLOCATOR" to use your own allocator that defines xmalloc,
|
||||
* xrealloc, xcalloc, and xfree.
|
||||
*
|
||||
* For example, your `prism_xallocator.h` file could look like this:
|
||||
*
|
||||
* ```
|
||||
* #ifndef PRISM_XALLOCATOR_H
|
||||
* #define PRISM_XALLOCATOR_H
|
||||
* #define xmalloc my_malloc
|
||||
* #define xrealloc my_realloc
|
||||
* #define xcalloc my_calloc
|
||||
* #define xfree my_free
|
||||
* #endif
|
||||
* ```
|
||||
*/
|
||||
#ifdef PRISM_XALLOCATOR
|
||||
#include "prism_xallocator.h"
|
||||
#else
|
||||
#ifndef xmalloc
|
||||
/**
|
||||
* The malloc function that should be used. This can be overridden with
|
||||
* the PRISM_XALLOCATOR define.
|
||||
*/
|
||||
#define xmalloc malloc
|
||||
#endif
|
||||
|
||||
#ifndef xrealloc
|
||||
/**
|
||||
* The realloc function that should be used. This can be overridden with
|
||||
* the PRISM_XALLOCATOR define.
|
||||
*/
|
||||
#define xrealloc realloc
|
||||
#endif
|
||||
|
||||
#ifndef xcalloc
|
||||
/**
|
||||
* The calloc function that should be used. This can be overridden with
|
||||
* the PRISM_XALLOCATOR define.
|
||||
*/
|
||||
#define xcalloc calloc
|
||||
#endif
|
||||
|
||||
#ifndef xfree
|
||||
/**
|
||||
* The free function that should be used. This can be overridden with the
|
||||
* PRISM_XALLOCATOR define.
|
||||
*/
|
||||
#define xfree free
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* If PRISM_BUILD_MINIMAL is defined, then we're going to define every possible
|
||||
* switch that will turn off certain features of prism.
|
||||
*/
|
||||
#ifdef PRISM_BUILD_MINIMAL
|
||||
/** Exclude the serialization API. */
|
||||
#define PRISM_EXCLUDE_SERIALIZATION
|
||||
|
||||
/** Exclude the JSON serialization API. */
|
||||
#define PRISM_EXCLUDE_JSON
|
||||
|
||||
/** Exclude the Array#pack parser API. */
|
||||
#define PRISM_EXCLUDE_PACK
|
||||
|
||||
/** Exclude the prettyprint API. */
|
||||
#define PRISM_EXCLUDE_PRETTYPRINT
|
||||
|
||||
/** Exclude the full set of encodings, using the minimal only. */
|
||||
#define PRISM_ENCODING_EXCLUDE_FULL
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Support PRISM_LIKELY and PRISM_UNLIKELY to help the compiler optimize its
|
||||
* branch predication.
|
||||
*/
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
/** The compiler should predicate that this branch will be taken. */
|
||||
#define PRISM_LIKELY(x) __builtin_expect(!!(x), 1)
|
||||
|
||||
/** The compiler should predicate that this branch will not be taken. */
|
||||
#define PRISM_UNLIKELY(x) __builtin_expect(!!(x), 0)
|
||||
#else
|
||||
/** Void because this platform does not support branch prediction hints. */
|
||||
#define PRISM_LIKELY(x) (x)
|
||||
|
||||
/** Void because this platform does not support branch prediction hints. */
|
||||
#define PRISM_UNLIKELY(x) (x)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* We use -Wimplicit-fallthrough to guard potentially unintended fall-through between cases of a switch.
|
||||
* Use PRISM_FALLTHROUGH to explicitly annotate cases where the fallthrough is intentional.
|
||||
*/
|
||||
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L // C23 or later
|
||||
#define PRISM_FALLTHROUGH [[fallthrough]];
|
||||
#elif defined(__GNUC__) || defined(__clang__)
|
||||
#define PRISM_FALLTHROUGH __attribute__((fallthrough));
|
||||
#elif defined(_MSC_VER)
|
||||
#define PRISM_FALLTHROUGH __fallthrough;
|
||||
#else
|
||||
#define PRISM_FALLTHROUGH
|
||||
#endif
|
||||
|
||||
#endif
|
||||
451
vendor/mruby-compiler2/lib/prism/include/prism/diagnostic.h
vendored
Normal file
451
vendor/mruby-compiler2/lib/prism/include/prism/diagnostic.h
vendored
Normal file
@@ -0,0 +1,451 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* This file is generated by the templates/template.rb script and should not */
|
||||
/* be modified manually. See */
|
||||
/* templates/include/prism/diagnostic.h.erb */
|
||||
/* if you are looking to modify the */
|
||||
/* template */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @file diagnostic.h
|
||||
*
|
||||
* A list of diagnostics generated during parsing.
|
||||
*/
|
||||
#ifndef PRISM_DIAGNOSTIC_H
|
||||
#define PRISM_DIAGNOSTIC_H
|
||||
|
||||
#include "prism/ast.h"
|
||||
#include "prism/defines.h"
|
||||
#include "prism/util/pm_list.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
/**
|
||||
* The diagnostic IDs of all of the diagnostics, used to communicate the types
|
||||
* of errors between the parser and the user.
|
||||
*/
|
||||
typedef enum {
|
||||
// These are the error diagnostics.
|
||||
PM_ERR_ALIAS_ARGUMENT,
|
||||
PM_ERR_ALIAS_ARGUMENT_NUMBERED_REFERENCE,
|
||||
PM_ERR_AMPAMPEQ_MULTI_ASSIGN,
|
||||
PM_ERR_ARGUMENT_AFTER_BLOCK,
|
||||
PM_ERR_ARGUMENT_AFTER_FORWARDING_ELLIPSES,
|
||||
PM_ERR_ARGUMENT_BARE_HASH,
|
||||
PM_ERR_ARGUMENT_BLOCK_FORWARDING,
|
||||
PM_ERR_ARGUMENT_BLOCK_MULTI,
|
||||
PM_ERR_ARGUMENT_CONFLICT_AMPERSAND,
|
||||
PM_ERR_ARGUMENT_CONFLICT_STAR,
|
||||
PM_ERR_ARGUMENT_CONFLICT_STAR_STAR,
|
||||
PM_ERR_ARGUMENT_FORMAL_CLASS,
|
||||
PM_ERR_ARGUMENT_FORMAL_CONSTANT,
|
||||
PM_ERR_ARGUMENT_FORMAL_GLOBAL,
|
||||
PM_ERR_ARGUMENT_FORMAL_IVAR,
|
||||
PM_ERR_ARGUMENT_FORWARDING_UNBOUND,
|
||||
PM_ERR_ARGUMENT_NO_FORWARDING_AMPERSAND,
|
||||
PM_ERR_ARGUMENT_NO_FORWARDING_ELLIPSES,
|
||||
PM_ERR_ARGUMENT_NO_FORWARDING_STAR,
|
||||
PM_ERR_ARGUMENT_NO_FORWARDING_STAR_STAR,
|
||||
PM_ERR_ARGUMENT_SPLAT_AFTER_ASSOC_SPLAT,
|
||||
PM_ERR_ARGUMENT_SPLAT_AFTER_SPLAT,
|
||||
PM_ERR_ARGUMENT_TERM_PAREN,
|
||||
PM_ERR_ARGUMENT_UNEXPECTED_BLOCK,
|
||||
PM_ERR_ARRAY_ELEMENT,
|
||||
PM_ERR_ARRAY_EXPRESSION,
|
||||
PM_ERR_ARRAY_EXPRESSION_AFTER_STAR,
|
||||
PM_ERR_ARRAY_SEPARATOR,
|
||||
PM_ERR_ARRAY_TERM,
|
||||
PM_ERR_BEGIN_LONELY_ELSE,
|
||||
PM_ERR_BEGIN_TERM,
|
||||
PM_ERR_BEGIN_UPCASE_BRACE,
|
||||
PM_ERR_BEGIN_UPCASE_TERM,
|
||||
PM_ERR_BEGIN_UPCASE_TOPLEVEL,
|
||||
PM_ERR_BLOCK_PARAM_LOCAL_VARIABLE,
|
||||
PM_ERR_BLOCK_PARAM_PIPE_TERM,
|
||||
PM_ERR_BLOCK_TERM_BRACE,
|
||||
PM_ERR_BLOCK_TERM_END,
|
||||
PM_ERR_CANNOT_PARSE_EXPRESSION,
|
||||
PM_ERR_CANNOT_PARSE_STRING_PART,
|
||||
PM_ERR_CASE_EXPRESSION_AFTER_CASE,
|
||||
PM_ERR_CASE_EXPRESSION_AFTER_WHEN,
|
||||
PM_ERR_CASE_MATCH_MISSING_PREDICATE,
|
||||
PM_ERR_CASE_MISSING_CONDITIONS,
|
||||
PM_ERR_CASE_TERM,
|
||||
PM_ERR_CLASS_IN_METHOD,
|
||||
PM_ERR_CLASS_NAME,
|
||||
PM_ERR_CLASS_SUPERCLASS,
|
||||
PM_ERR_CLASS_TERM,
|
||||
PM_ERR_CLASS_UNEXPECTED_END,
|
||||
PM_ERR_CLASS_VARIABLE_BARE,
|
||||
PM_ERR_CONDITIONAL_ELSIF_PREDICATE,
|
||||
PM_ERR_CONDITIONAL_IF_PREDICATE,
|
||||
PM_ERR_CONDITIONAL_PREDICATE_TERM,
|
||||
PM_ERR_CONDITIONAL_TERM,
|
||||
PM_ERR_CONDITIONAL_TERM_ELSE,
|
||||
PM_ERR_CONDITIONAL_UNLESS_PREDICATE,
|
||||
PM_ERR_CONDITIONAL_UNTIL_PREDICATE,
|
||||
PM_ERR_CONDITIONAL_WHILE_PREDICATE,
|
||||
PM_ERR_CONSTANT_PATH_COLON_COLON_CONSTANT,
|
||||
PM_ERR_DEF_ENDLESS,
|
||||
PM_ERR_DEF_ENDLESS_SETTER,
|
||||
PM_ERR_DEF_NAME,
|
||||
PM_ERR_DEF_PARAMS_TERM,
|
||||
PM_ERR_DEF_PARAMS_TERM_PAREN,
|
||||
PM_ERR_DEF_RECEIVER,
|
||||
PM_ERR_DEF_RECEIVER_TERM,
|
||||
PM_ERR_DEF_TERM,
|
||||
PM_ERR_DEFINED_EXPRESSION,
|
||||
PM_ERR_EMBDOC_TERM,
|
||||
PM_ERR_EMBEXPR_END,
|
||||
PM_ERR_EMBVAR_INVALID,
|
||||
PM_ERR_END_UPCASE_BRACE,
|
||||
PM_ERR_END_UPCASE_TERM,
|
||||
PM_ERR_ESCAPE_INVALID_CONTROL,
|
||||
PM_ERR_ESCAPE_INVALID_CONTROL_REPEAT,
|
||||
PM_ERR_ESCAPE_INVALID_HEXADECIMAL,
|
||||
PM_ERR_ESCAPE_INVALID_META,
|
||||
PM_ERR_ESCAPE_INVALID_META_REPEAT,
|
||||
PM_ERR_ESCAPE_INVALID_UNICODE,
|
||||
PM_ERR_ESCAPE_INVALID_UNICODE_CM_FLAGS,
|
||||
PM_ERR_ESCAPE_INVALID_UNICODE_LIST,
|
||||
PM_ERR_ESCAPE_INVALID_UNICODE_LITERAL,
|
||||
PM_ERR_ESCAPE_INVALID_UNICODE_LONG,
|
||||
PM_ERR_ESCAPE_INVALID_UNICODE_SHORT,
|
||||
PM_ERR_ESCAPE_INVALID_UNICODE_TERM,
|
||||
PM_ERR_EXPECT_ARGUMENT,
|
||||
PM_ERR_EXPECT_EOL_AFTER_STATEMENT,
|
||||
PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ,
|
||||
PM_ERR_EXPECT_EXPRESSION_AFTER_COMMA,
|
||||
PM_ERR_EXPECT_EXPRESSION_AFTER_EQUAL,
|
||||
PM_ERR_EXPECT_EXPRESSION_AFTER_LESS_LESS,
|
||||
PM_ERR_EXPECT_EXPRESSION_AFTER_LPAREN,
|
||||
PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR,
|
||||
PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ,
|
||||
PM_ERR_EXPECT_EXPRESSION_AFTER_QUESTION,
|
||||
PM_ERR_EXPECT_EXPRESSION_AFTER_SPLAT,
|
||||
PM_ERR_EXPECT_EXPRESSION_AFTER_SPLAT_HASH,
|
||||
PM_ERR_EXPECT_EXPRESSION_AFTER_STAR,
|
||||
PM_ERR_EXPECT_FOR_DELIMITER,
|
||||
PM_ERR_EXPECT_IDENT_REQ_PARAMETER,
|
||||
PM_ERR_EXPECT_IN_DELIMITER,
|
||||
PM_ERR_EXPECT_LPAREN_REQ_PARAMETER,
|
||||
PM_ERR_EXPECT_MESSAGE,
|
||||
PM_ERR_EXPECT_RBRACKET,
|
||||
PM_ERR_EXPECT_RPAREN,
|
||||
PM_ERR_EXPECT_RPAREN_AFTER_MULTI,
|
||||
PM_ERR_EXPECT_RPAREN_REQ_PARAMETER,
|
||||
PM_ERR_EXPECT_SINGLETON_CLASS_DELIMITER,
|
||||
PM_ERR_EXPECT_STRING_CONTENT,
|
||||
PM_ERR_EXPECT_WHEN_DELIMITER,
|
||||
PM_ERR_EXPRESSION_BARE_HASH,
|
||||
PM_ERR_EXPRESSION_NOT_WRITABLE,
|
||||
PM_ERR_EXPRESSION_NOT_WRITABLE_ENCODING,
|
||||
PM_ERR_EXPRESSION_NOT_WRITABLE_FALSE,
|
||||
PM_ERR_EXPRESSION_NOT_WRITABLE_FILE,
|
||||
PM_ERR_EXPRESSION_NOT_WRITABLE_LINE,
|
||||
PM_ERR_EXPRESSION_NOT_WRITABLE_NIL,
|
||||
PM_ERR_EXPRESSION_NOT_WRITABLE_NUMBERED,
|
||||
PM_ERR_EXPRESSION_NOT_WRITABLE_SELF,
|
||||
PM_ERR_EXPRESSION_NOT_WRITABLE_TRUE,
|
||||
PM_ERR_FLOAT_PARSE,
|
||||
PM_ERR_FOR_COLLECTION,
|
||||
PM_ERR_FOR_IN,
|
||||
PM_ERR_FOR_INDEX,
|
||||
PM_ERR_FOR_TERM,
|
||||
PM_ERR_GLOBAL_VARIABLE_BARE,
|
||||
PM_ERR_HASH_EXPRESSION_AFTER_LABEL,
|
||||
PM_ERR_HASH_KEY,
|
||||
PM_ERR_HASH_ROCKET,
|
||||
PM_ERR_HASH_TERM,
|
||||
PM_ERR_HASH_VALUE,
|
||||
PM_ERR_HEREDOC_IDENTIFIER,
|
||||
PM_ERR_HEREDOC_TERM,
|
||||
PM_ERR_INCOMPLETE_QUESTION_MARK,
|
||||
PM_ERR_INCOMPLETE_VARIABLE_CLASS,
|
||||
PM_ERR_INCOMPLETE_VARIABLE_CLASS_3_3,
|
||||
PM_ERR_INCOMPLETE_VARIABLE_INSTANCE,
|
||||
PM_ERR_INCOMPLETE_VARIABLE_INSTANCE_3_3,
|
||||
PM_ERR_INSTANCE_VARIABLE_BARE,
|
||||
PM_ERR_INVALID_BLOCK_EXIT,
|
||||
PM_ERR_INVALID_CHARACTER,
|
||||
PM_ERR_INVALID_COMMA,
|
||||
PM_ERR_INVALID_ENCODING_MAGIC_COMMENT,
|
||||
PM_ERR_INVALID_ESCAPE_CHARACTER,
|
||||
PM_ERR_INVALID_FLOAT_EXPONENT,
|
||||
PM_ERR_INVALID_LOCAL_VARIABLE_READ,
|
||||
PM_ERR_INVALID_LOCAL_VARIABLE_WRITE,
|
||||
PM_ERR_INVALID_MULTIBYTE_CHAR,
|
||||
PM_ERR_INVALID_MULTIBYTE_CHARACTER,
|
||||
PM_ERR_INVALID_MULTIBYTE_ESCAPE,
|
||||
PM_ERR_INVALID_NUMBER_BINARY,
|
||||
PM_ERR_INVALID_NUMBER_DECIMAL,
|
||||
PM_ERR_INVALID_NUMBER_FRACTION,
|
||||
PM_ERR_INVALID_NUMBER_HEXADECIMAL,
|
||||
PM_ERR_INVALID_NUMBER_OCTAL,
|
||||
PM_ERR_INVALID_NUMBER_UNDERSCORE_INNER,
|
||||
PM_ERR_INVALID_NUMBER_UNDERSCORE_TRAILING,
|
||||
PM_ERR_INVALID_PERCENT,
|
||||
PM_ERR_INVALID_PERCENT_EOF,
|
||||
PM_ERR_INVALID_PRINTABLE_CHARACTER,
|
||||
PM_ERR_INVALID_RETRY_AFTER_ELSE,
|
||||
PM_ERR_INVALID_RETRY_AFTER_ENSURE,
|
||||
PM_ERR_INVALID_RETRY_WITHOUT_RESCUE,
|
||||
PM_ERR_INVALID_SYMBOL,
|
||||
PM_ERR_INVALID_VARIABLE_GLOBAL,
|
||||
PM_ERR_INVALID_VARIABLE_GLOBAL_3_3,
|
||||
PM_ERR_INVALID_YIELD,
|
||||
PM_ERR_IT_NOT_ALLOWED_NUMBERED,
|
||||
PM_ERR_IT_NOT_ALLOWED_ORDINARY,
|
||||
PM_ERR_LAMBDA_OPEN,
|
||||
PM_ERR_LAMBDA_TERM_BRACE,
|
||||
PM_ERR_LAMBDA_TERM_END,
|
||||
PM_ERR_LIST_I_LOWER_ELEMENT,
|
||||
PM_ERR_LIST_I_LOWER_TERM,
|
||||
PM_ERR_LIST_I_UPPER_ELEMENT,
|
||||
PM_ERR_LIST_I_UPPER_TERM,
|
||||
PM_ERR_LIST_W_LOWER_ELEMENT,
|
||||
PM_ERR_LIST_W_LOWER_TERM,
|
||||
PM_ERR_LIST_W_UPPER_ELEMENT,
|
||||
PM_ERR_LIST_W_UPPER_TERM,
|
||||
PM_ERR_MALLOC_FAILED,
|
||||
PM_ERR_MIXED_ENCODING,
|
||||
PM_ERR_MODULE_IN_METHOD,
|
||||
PM_ERR_MODULE_NAME,
|
||||
PM_ERR_MODULE_TERM,
|
||||
PM_ERR_MULTI_ASSIGN_MULTI_SPLATS,
|
||||
PM_ERR_MULTI_ASSIGN_UNEXPECTED_REST,
|
||||
PM_ERR_NESTING_TOO_DEEP,
|
||||
PM_ERR_NO_LOCAL_VARIABLE,
|
||||
PM_ERR_NON_ASSOCIATIVE_OPERATOR,
|
||||
PM_ERR_NOT_EXPRESSION,
|
||||
PM_ERR_NUMBER_LITERAL_UNDERSCORE,
|
||||
PM_ERR_NUMBERED_PARAMETER_INNER_BLOCK,
|
||||
PM_ERR_NUMBERED_PARAMETER_IT,
|
||||
PM_ERR_NUMBERED_PARAMETER_ORDINARY,
|
||||
PM_ERR_NUMBERED_PARAMETER_OUTER_BLOCK,
|
||||
PM_ERR_OPERATOR_MULTI_ASSIGN,
|
||||
PM_ERR_OPERATOR_WRITE_ARGUMENTS,
|
||||
PM_ERR_OPERATOR_WRITE_BLOCK,
|
||||
PM_ERR_PARAMETER_ASSOC_SPLAT_MULTI,
|
||||
PM_ERR_PARAMETER_BLOCK_MULTI,
|
||||
PM_ERR_PARAMETER_CIRCULAR,
|
||||
PM_ERR_PARAMETER_FORWARDING_AFTER_REST,
|
||||
PM_ERR_PARAMETER_METHOD_NAME,
|
||||
PM_ERR_PARAMETER_NAME_DUPLICATED,
|
||||
PM_ERR_PARAMETER_NO_DEFAULT,
|
||||
PM_ERR_PARAMETER_NO_DEFAULT_KW,
|
||||
PM_ERR_PARAMETER_NUMBERED_RESERVED,
|
||||
PM_ERR_PARAMETER_ORDER,
|
||||
PM_ERR_PARAMETER_SPLAT_MULTI,
|
||||
PM_ERR_PARAMETER_STAR,
|
||||
PM_ERR_PARAMETER_UNEXPECTED_FWD,
|
||||
PM_ERR_PARAMETER_UNEXPECTED_NO_KW,
|
||||
PM_ERR_PARAMETER_WILD_LOOSE_COMMA,
|
||||
PM_ERR_PATTERN_ARRAY_MULTIPLE_RESTS,
|
||||
PM_ERR_PATTERN_CAPTURE_DUPLICATE,
|
||||
PM_ERR_PATTERN_EXPRESSION_AFTER_BRACKET,
|
||||
PM_ERR_PATTERN_EXPRESSION_AFTER_COMMA,
|
||||
PM_ERR_PATTERN_EXPRESSION_AFTER_HROCKET,
|
||||
PM_ERR_PATTERN_EXPRESSION_AFTER_IN,
|
||||
PM_ERR_PATTERN_EXPRESSION_AFTER_KEY,
|
||||
PM_ERR_PATTERN_EXPRESSION_AFTER_PAREN,
|
||||
PM_ERR_PATTERN_EXPRESSION_AFTER_PIN,
|
||||
PM_ERR_PATTERN_EXPRESSION_AFTER_PIPE,
|
||||
PM_ERR_PATTERN_EXPRESSION_AFTER_RANGE,
|
||||
PM_ERR_PATTERN_EXPRESSION_AFTER_REST,
|
||||
PM_ERR_PATTERN_FIND_MISSING_INNER,
|
||||
PM_ERR_PATTERN_HASH_IMPLICIT,
|
||||
PM_ERR_PATTERN_HASH_KEY,
|
||||
PM_ERR_PATTERN_HASH_KEY_DUPLICATE,
|
||||
PM_ERR_PATTERN_HASH_KEY_INTERPOLATED,
|
||||
PM_ERR_PATTERN_HASH_KEY_LABEL,
|
||||
PM_ERR_PATTERN_HASH_KEY_LOCALS,
|
||||
PM_ERR_PATTERN_IDENT_AFTER_HROCKET,
|
||||
PM_ERR_PATTERN_LABEL_AFTER_COMMA,
|
||||
PM_ERR_PATTERN_REST,
|
||||
PM_ERR_PATTERN_TERM_BRACE,
|
||||
PM_ERR_PATTERN_TERM_BRACKET,
|
||||
PM_ERR_PATTERN_TERM_PAREN,
|
||||
PM_ERR_PIPEPIPEEQ_MULTI_ASSIGN,
|
||||
PM_ERR_REGEXP_ENCODING_OPTION_MISMATCH,
|
||||
PM_ERR_REGEXP_INCOMPAT_CHAR_ENCODING,
|
||||
PM_ERR_REGEXP_INVALID_UNICODE_RANGE,
|
||||
PM_ERR_REGEXP_NON_ESCAPED_MBC,
|
||||
PM_ERR_REGEXP_PARSE_ERROR,
|
||||
PM_ERR_REGEXP_TERM,
|
||||
PM_ERR_REGEXP_UNKNOWN_OPTIONS,
|
||||
PM_ERR_REGEXP_UTF8_CHAR_NON_UTF8_REGEXP,
|
||||
PM_ERR_RESCUE_EXPRESSION,
|
||||
PM_ERR_RESCUE_MODIFIER_VALUE,
|
||||
PM_ERR_RESCUE_TERM,
|
||||
PM_ERR_RESCUE_VARIABLE,
|
||||
PM_ERR_RETURN_INVALID,
|
||||
PM_ERR_SCRIPT_NOT_FOUND,
|
||||
PM_ERR_SINGLETON_FOR_LITERALS,
|
||||
PM_ERR_STATEMENT_ALIAS,
|
||||
PM_ERR_STATEMENT_POSTEXE_END,
|
||||
PM_ERR_STATEMENT_PREEXE_BEGIN,
|
||||
PM_ERR_STATEMENT_UNDEF,
|
||||
PM_ERR_STRING_CONCATENATION,
|
||||
PM_ERR_STRING_INTERPOLATED_TERM,
|
||||
PM_ERR_STRING_LITERAL_EOF,
|
||||
PM_ERR_STRING_LITERAL_TERM,
|
||||
PM_ERR_SYMBOL_INVALID,
|
||||
PM_ERR_SYMBOL_TERM_DYNAMIC,
|
||||
PM_ERR_SYMBOL_TERM_INTERPOLATED,
|
||||
PM_ERR_TERNARY_COLON,
|
||||
PM_ERR_TERNARY_EXPRESSION_FALSE,
|
||||
PM_ERR_TERNARY_EXPRESSION_TRUE,
|
||||
PM_ERR_UNARY_DISALLOWED,
|
||||
PM_ERR_UNARY_RECEIVER,
|
||||
PM_ERR_UNDEF_ARGUMENT,
|
||||
PM_ERR_UNEXPECTED_BLOCK_ARGUMENT,
|
||||
PM_ERR_UNEXPECTED_INDEX_BLOCK,
|
||||
PM_ERR_UNEXPECTED_INDEX_KEYWORDS,
|
||||
PM_ERR_UNEXPECTED_LABEL,
|
||||
PM_ERR_UNEXPECTED_MULTI_WRITE,
|
||||
PM_ERR_UNEXPECTED_RANGE_OPERATOR,
|
||||
PM_ERR_UNEXPECTED_SAFE_NAVIGATION,
|
||||
PM_ERR_UNEXPECTED_TOKEN_CLOSE_CONTEXT,
|
||||
PM_ERR_UNEXPECTED_TOKEN_IGNORE,
|
||||
PM_ERR_UNTIL_TERM,
|
||||
PM_ERR_VOID_EXPRESSION,
|
||||
PM_ERR_WHILE_TERM,
|
||||
PM_ERR_WRITE_TARGET_IN_METHOD,
|
||||
PM_ERR_WRITE_TARGET_READONLY,
|
||||
PM_ERR_WRITE_TARGET_UNEXPECTED,
|
||||
PM_ERR_XSTRING_TERM,
|
||||
|
||||
// These are the warning diagnostics.
|
||||
PM_WARN_AMBIGUOUS_BINARY_OPERATOR,
|
||||
PM_WARN_AMBIGUOUS_FIRST_ARGUMENT_MINUS,
|
||||
PM_WARN_AMBIGUOUS_FIRST_ARGUMENT_PLUS,
|
||||
PM_WARN_AMBIGUOUS_PREFIX_AMPERSAND,
|
||||
PM_WARN_AMBIGUOUS_PREFIX_STAR,
|
||||
PM_WARN_AMBIGUOUS_PREFIX_STAR_STAR,
|
||||
PM_WARN_AMBIGUOUS_SLASH,
|
||||
PM_WARN_COMPARISON_AFTER_COMPARISON,
|
||||
PM_WARN_DOT_DOT_DOT_EOL,
|
||||
PM_WARN_EQUAL_IN_CONDITIONAL,
|
||||
PM_WARN_EQUAL_IN_CONDITIONAL_3_3,
|
||||
PM_WARN_END_IN_METHOD,
|
||||
PM_WARN_DUPLICATED_HASH_KEY,
|
||||
PM_WARN_DUPLICATED_WHEN_CLAUSE,
|
||||
PM_WARN_FLOAT_OUT_OF_RANGE,
|
||||
PM_WARN_IGNORED_FROZEN_STRING_LITERAL,
|
||||
PM_WARN_INDENTATION_MISMATCH,
|
||||
PM_WARN_INTEGER_IN_FLIP_FLOP,
|
||||
PM_WARN_INVALID_CHARACTER,
|
||||
PM_WARN_INVALID_MAGIC_COMMENT_VALUE,
|
||||
PM_WARN_INVALID_NUMBERED_REFERENCE,
|
||||
PM_WARN_KEYWORD_EOL,
|
||||
PM_WARN_LITERAL_IN_CONDITION_DEFAULT,
|
||||
PM_WARN_LITERAL_IN_CONDITION_VERBOSE,
|
||||
PM_WARN_SHAREABLE_CONSTANT_VALUE_LINE,
|
||||
PM_WARN_SHEBANG_CARRIAGE_RETURN,
|
||||
PM_WARN_UNEXPECTED_CARRIAGE_RETURN,
|
||||
PM_WARN_UNREACHABLE_STATEMENT,
|
||||
PM_WARN_UNUSED_LOCAL_VARIABLE,
|
||||
PM_WARN_VOID_STATEMENT,
|
||||
} pm_diagnostic_id_t;
|
||||
|
||||
/**
|
||||
* This struct represents a diagnostic generated during parsing.
|
||||
*
|
||||
* @extends pm_list_node_t
|
||||
*/
|
||||
typedef struct {
|
||||
/** The embedded base node. */
|
||||
pm_list_node_t node;
|
||||
|
||||
/** The location of the diagnostic in the source. */
|
||||
pm_location_t location;
|
||||
|
||||
/** The ID of the diagnostic. */
|
||||
pm_diagnostic_id_t diag_id;
|
||||
|
||||
/** The message associated with the diagnostic. */
|
||||
const char *message;
|
||||
|
||||
/**
|
||||
* Whether or not the memory related to the message of this diagnostic is
|
||||
* owned by this diagnostic. If it is, it needs to be freed when the
|
||||
* diagnostic is freed.
|
||||
*/
|
||||
bool owned;
|
||||
|
||||
/**
|
||||
* The level of the diagnostic, see `pm_error_level_t` and
|
||||
* `pm_warning_level_t` for possible values.
|
||||
*/
|
||||
uint8_t level;
|
||||
} pm_diagnostic_t;
|
||||
|
||||
/**
|
||||
* The levels of errors generated during parsing.
|
||||
*/
|
||||
typedef enum {
|
||||
/** For errors that should raise a syntax error. */
|
||||
PM_ERROR_LEVEL_SYNTAX = 0,
|
||||
|
||||
/** For errors that should raise an argument error. */
|
||||
PM_ERROR_LEVEL_ARGUMENT = 1,
|
||||
|
||||
/** For errors that should raise a load error. */
|
||||
PM_ERROR_LEVEL_LOAD = 2
|
||||
} pm_error_level_t;
|
||||
|
||||
/**
|
||||
* The levels of warnings generated during parsing.
|
||||
*/
|
||||
typedef enum {
|
||||
/** For warnings which should be emitted if $VERBOSE != nil. */
|
||||
PM_WARNING_LEVEL_DEFAULT = 0,
|
||||
|
||||
/** For warnings which should be emitted if $VERBOSE == true. */
|
||||
PM_WARNING_LEVEL_VERBOSE = 1
|
||||
} pm_warning_level_t;
|
||||
|
||||
/**
|
||||
* Get the human-readable name of the given diagnostic ID.
|
||||
*
|
||||
* @param diag_id The diagnostic ID.
|
||||
* @return The human-readable name of the diagnostic ID.
|
||||
*/
|
||||
const char * pm_diagnostic_id_human(pm_diagnostic_id_t diag_id);
|
||||
|
||||
/**
|
||||
* Append a diagnostic to the given list of diagnostics that is using shared
|
||||
* memory for its message.
|
||||
*
|
||||
* @param list The list to append to.
|
||||
* @param start The start of the diagnostic.
|
||||
* @param end The end of the diagnostic.
|
||||
* @param diag_id The diagnostic ID.
|
||||
* @return Whether the diagnostic was successfully appended.
|
||||
*/
|
||||
bool pm_diagnostic_list_append(pm_list_t *list, const uint8_t *start, const uint8_t *end, pm_diagnostic_id_t diag_id);
|
||||
|
||||
/**
|
||||
* Append a diagnostic to the given list of diagnostics that is using a format
|
||||
* string for its message.
|
||||
*
|
||||
* @param list The list to append to.
|
||||
* @param start The start of the diagnostic.
|
||||
* @param end The end of the diagnostic.
|
||||
* @param diag_id The diagnostic ID.
|
||||
* @param ... The arguments to the format string for the message.
|
||||
* @return Whether the diagnostic was successfully appended.
|
||||
*/
|
||||
bool pm_diagnostic_list_append_format(pm_list_t *list, const uint8_t *start, const uint8_t *end, pm_diagnostic_id_t diag_id, ...);
|
||||
|
||||
/**
|
||||
* Deallocate the internal state of the given diagnostic list.
|
||||
*
|
||||
* @param list The list to deallocate.
|
||||
*/
|
||||
void pm_diagnostic_list_free(pm_list_t *list);
|
||||
|
||||
#endif
|
||||
283
vendor/mruby-compiler2/lib/prism/include/prism/encoding.h
vendored
Normal file
283
vendor/mruby-compiler2/lib/prism/include/prism/encoding.h
vendored
Normal file
@@ -0,0 +1,283 @@
|
||||
/**
|
||||
* @file encoding.h
|
||||
*
|
||||
* The encoding interface and implementations used by the parser.
|
||||
*/
|
||||
#ifndef PRISM_ENCODING_H
|
||||
#define PRISM_ENCODING_H
|
||||
|
||||
#include "prism/defines.h"
|
||||
#include "prism/util/pm_strncasecmp.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* This struct defines the functions necessary to implement the encoding
|
||||
* interface so we can determine how many bytes the subsequent character takes.
|
||||
* Each callback should return the number of bytes, or 0 if the next bytes are
|
||||
* invalid for the encoding and type.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* Return the number of bytes that the next character takes if it is valid
|
||||
* in the encoding. Does not read more than n bytes. It is assumed that n is
|
||||
* at least 1.
|
||||
*/
|
||||
size_t (*char_width)(const uint8_t *b, ptrdiff_t n);
|
||||
|
||||
/**
|
||||
* Return the number of bytes that the next character takes if it is valid
|
||||
* in the encoding and is alphabetical. Does not read more than n bytes. It
|
||||
* is assumed that n is at least 1.
|
||||
*/
|
||||
size_t (*alpha_char)(const uint8_t *b, ptrdiff_t n);
|
||||
|
||||
/**
|
||||
* Return the number of bytes that the next character takes if it is valid
|
||||
* in the encoding and is alphanumeric. Does not read more than n bytes. It
|
||||
* is assumed that n is at least 1.
|
||||
*/
|
||||
size_t (*alnum_char)(const uint8_t *b, ptrdiff_t n);
|
||||
|
||||
/**
|
||||
* Return true if the next character is valid in the encoding and is an
|
||||
* uppercase character. Does not read more than n bytes. It is assumed that
|
||||
* n is at least 1.
|
||||
*/
|
||||
bool (*isupper_char)(const uint8_t *b, ptrdiff_t n);
|
||||
|
||||
/**
|
||||
* The name of the encoding. This should correspond to a value that can be
|
||||
* passed to Encoding.find in Ruby.
|
||||
*/
|
||||
const char *name;
|
||||
|
||||
/**
|
||||
* Return true if the encoding is a multibyte encoding.
|
||||
*/
|
||||
bool multibyte;
|
||||
} pm_encoding_t;
|
||||
|
||||
/**
|
||||
* All of the lookup tables use the first bit of each embedded byte to indicate
|
||||
* whether the codepoint is alphabetical.
|
||||
*/
|
||||
#define PRISM_ENCODING_ALPHABETIC_BIT 1 << 0
|
||||
|
||||
/**
|
||||
* All of the lookup tables use the second bit of each embedded byte to indicate
|
||||
* whether the codepoint is alphanumeric.
|
||||
*/
|
||||
#define PRISM_ENCODING_ALPHANUMERIC_BIT 1 << 1
|
||||
|
||||
/**
|
||||
* All of the lookup tables use the third bit of each embedded byte to indicate
|
||||
* whether the codepoint is uppercase.
|
||||
*/
|
||||
#define PRISM_ENCODING_UPPERCASE_BIT 1 << 2
|
||||
|
||||
/**
|
||||
* Return the size of the next character in the UTF-8 encoding.
|
||||
*
|
||||
* @param b The bytes to read.
|
||||
* @param n The number of bytes that can be read.
|
||||
* @returns The number of bytes that the next character takes if it is valid in
|
||||
* the encoding, or 0 if it is not.
|
||||
*/
|
||||
size_t pm_encoding_utf_8_char_width(const uint8_t *b, ptrdiff_t n);
|
||||
|
||||
/**
|
||||
* Return the size of the next character in the UTF-8 encoding if it is an
|
||||
* alphabetical character.
|
||||
*
|
||||
* @param b The bytes to read.
|
||||
* @param n The number of bytes that can be read.
|
||||
* @returns The number of bytes that the next character takes if it is valid in
|
||||
* the encoding, or 0 if it is not.
|
||||
*/
|
||||
size_t pm_encoding_utf_8_alpha_char(const uint8_t *b, ptrdiff_t n);
|
||||
|
||||
/**
|
||||
* Return the size of the next character in the UTF-8 encoding if it is an
|
||||
* alphanumeric character.
|
||||
*
|
||||
* @param b The bytes to read.
|
||||
* @param n The number of bytes that can be read.
|
||||
* @returns The number of bytes that the next character takes if it is valid in
|
||||
* the encoding, or 0 if it is not.
|
||||
*/
|
||||
size_t pm_encoding_utf_8_alnum_char(const uint8_t *b, ptrdiff_t n);
|
||||
|
||||
/**
|
||||
* Return true if the next character in the UTF-8 encoding if it is an uppercase
|
||||
* character.
|
||||
*
|
||||
* @param b The bytes to read.
|
||||
* @param n The number of bytes that can be read.
|
||||
* @returns True if the next character is valid in the encoding and is an
|
||||
* uppercase character, or false if it is not.
|
||||
*/
|
||||
bool pm_encoding_utf_8_isupper_char(const uint8_t *b, ptrdiff_t n);
|
||||
|
||||
/**
|
||||
* This lookup table is referenced in both the UTF-8 encoding file and the
|
||||
* parser directly in order to speed up the default encoding processing. It is
|
||||
* used to indicate whether a character is alphabetical, alphanumeric, or
|
||||
* uppercase in unicode mappings.
|
||||
*/
|
||||
extern const uint8_t pm_encoding_unicode_table[256];
|
||||
|
||||
/**
|
||||
* These are all of the encodings that prism supports.
|
||||
*/
|
||||
typedef enum {
|
||||
PM_ENCODING_UTF_8 = 0,
|
||||
PM_ENCODING_US_ASCII,
|
||||
PM_ENCODING_ASCII_8BIT,
|
||||
PM_ENCODING_EUC_JP,
|
||||
PM_ENCODING_WINDOWS_31J,
|
||||
|
||||
// We optionally support excluding the full set of encodings to only support the
|
||||
// minimum necessary to process Ruby code without encoding comments.
|
||||
#ifndef PRISM_ENCODING_EXCLUDE_FULL
|
||||
PM_ENCODING_BIG5,
|
||||
PM_ENCODING_BIG5_HKSCS,
|
||||
PM_ENCODING_BIG5_UAO,
|
||||
PM_ENCODING_CESU_8,
|
||||
PM_ENCODING_CP51932,
|
||||
PM_ENCODING_CP850,
|
||||
PM_ENCODING_CP852,
|
||||
PM_ENCODING_CP855,
|
||||
PM_ENCODING_CP949,
|
||||
PM_ENCODING_CP950,
|
||||
PM_ENCODING_CP951,
|
||||
PM_ENCODING_EMACS_MULE,
|
||||
PM_ENCODING_EUC_JP_MS,
|
||||
PM_ENCODING_EUC_JIS_2004,
|
||||
PM_ENCODING_EUC_KR,
|
||||
PM_ENCODING_EUC_TW,
|
||||
PM_ENCODING_GB12345,
|
||||
PM_ENCODING_GB18030,
|
||||
PM_ENCODING_GB1988,
|
||||
PM_ENCODING_GB2312,
|
||||
PM_ENCODING_GBK,
|
||||
PM_ENCODING_IBM437,
|
||||
PM_ENCODING_IBM720,
|
||||
PM_ENCODING_IBM737,
|
||||
PM_ENCODING_IBM775,
|
||||
PM_ENCODING_IBM852,
|
||||
PM_ENCODING_IBM855,
|
||||
PM_ENCODING_IBM857,
|
||||
PM_ENCODING_IBM860,
|
||||
PM_ENCODING_IBM861,
|
||||
PM_ENCODING_IBM862,
|
||||
PM_ENCODING_IBM863,
|
||||
PM_ENCODING_IBM864,
|
||||
PM_ENCODING_IBM865,
|
||||
PM_ENCODING_IBM866,
|
||||
PM_ENCODING_IBM869,
|
||||
PM_ENCODING_ISO_8859_1,
|
||||
PM_ENCODING_ISO_8859_2,
|
||||
PM_ENCODING_ISO_8859_3,
|
||||
PM_ENCODING_ISO_8859_4,
|
||||
PM_ENCODING_ISO_8859_5,
|
||||
PM_ENCODING_ISO_8859_6,
|
||||
PM_ENCODING_ISO_8859_7,
|
||||
PM_ENCODING_ISO_8859_8,
|
||||
PM_ENCODING_ISO_8859_9,
|
||||
PM_ENCODING_ISO_8859_10,
|
||||
PM_ENCODING_ISO_8859_11,
|
||||
PM_ENCODING_ISO_8859_13,
|
||||
PM_ENCODING_ISO_8859_14,
|
||||
PM_ENCODING_ISO_8859_15,
|
||||
PM_ENCODING_ISO_8859_16,
|
||||
PM_ENCODING_KOI8_R,
|
||||
PM_ENCODING_KOI8_U,
|
||||
PM_ENCODING_MAC_CENT_EURO,
|
||||
PM_ENCODING_MAC_CROATIAN,
|
||||
PM_ENCODING_MAC_CYRILLIC,
|
||||
PM_ENCODING_MAC_GREEK,
|
||||
PM_ENCODING_MAC_ICELAND,
|
||||
PM_ENCODING_MAC_JAPANESE,
|
||||
PM_ENCODING_MAC_ROMAN,
|
||||
PM_ENCODING_MAC_ROMANIA,
|
||||
PM_ENCODING_MAC_THAI,
|
||||
PM_ENCODING_MAC_TURKISH,
|
||||
PM_ENCODING_MAC_UKRAINE,
|
||||
PM_ENCODING_SHIFT_JIS,
|
||||
PM_ENCODING_SJIS_DOCOMO,
|
||||
PM_ENCODING_SJIS_KDDI,
|
||||
PM_ENCODING_SJIS_SOFTBANK,
|
||||
PM_ENCODING_STATELESS_ISO_2022_JP,
|
||||
PM_ENCODING_STATELESS_ISO_2022_JP_KDDI,
|
||||
PM_ENCODING_TIS_620,
|
||||
PM_ENCODING_UTF8_MAC,
|
||||
PM_ENCODING_UTF8_DOCOMO,
|
||||
PM_ENCODING_UTF8_KDDI,
|
||||
PM_ENCODING_UTF8_SOFTBANK,
|
||||
PM_ENCODING_WINDOWS_1250,
|
||||
PM_ENCODING_WINDOWS_1251,
|
||||
PM_ENCODING_WINDOWS_1252,
|
||||
PM_ENCODING_WINDOWS_1253,
|
||||
PM_ENCODING_WINDOWS_1254,
|
||||
PM_ENCODING_WINDOWS_1255,
|
||||
PM_ENCODING_WINDOWS_1256,
|
||||
PM_ENCODING_WINDOWS_1257,
|
||||
PM_ENCODING_WINDOWS_1258,
|
||||
PM_ENCODING_WINDOWS_874,
|
||||
#endif
|
||||
|
||||
PM_ENCODING_MAXIMUM
|
||||
} pm_encoding_type_t;
|
||||
|
||||
/**
|
||||
* This is the table of all of the encodings that prism supports.
|
||||
*/
|
||||
extern const pm_encoding_t pm_encodings[PM_ENCODING_MAXIMUM];
|
||||
|
||||
/**
|
||||
* This is the default UTF-8 encoding. We need a reference to it to quickly
|
||||
* create parsers.
|
||||
*/
|
||||
#define PM_ENCODING_UTF_8_ENTRY (&pm_encodings[PM_ENCODING_UTF_8])
|
||||
|
||||
/**
|
||||
* This is the US-ASCII encoding. We need a reference to it to be able to
|
||||
* compare against it when a string is being created because it could possibly
|
||||
* need to fall back to ASCII-8BIT.
|
||||
*/
|
||||
#define PM_ENCODING_US_ASCII_ENTRY (&pm_encodings[PM_ENCODING_US_ASCII])
|
||||
|
||||
/**
|
||||
* This is the ASCII-8BIT encoding. We need a reference to it so that pm_strpbrk
|
||||
* can compare against it because invalid multibyte characters are not a thing
|
||||
* in this encoding. It is also needed for handling Regexp encoding flags.
|
||||
*/
|
||||
#define PM_ENCODING_ASCII_8BIT_ENTRY (&pm_encodings[PM_ENCODING_ASCII_8BIT])
|
||||
|
||||
/**
|
||||
* This is the EUC-JP encoding. We need a reference to it to quickly process
|
||||
* regular expression modifiers.
|
||||
*/
|
||||
#define PM_ENCODING_EUC_JP_ENTRY (&pm_encodings[PM_ENCODING_EUC_JP])
|
||||
|
||||
/**
|
||||
* This is the Windows-31J encoding. We need a reference to it to quickly
|
||||
* process regular expression modifiers.
|
||||
*/
|
||||
#define PM_ENCODING_WINDOWS_31J_ENTRY (&pm_encodings[PM_ENCODING_WINDOWS_31J])
|
||||
|
||||
/**
|
||||
* Parse the given name of an encoding and return a pointer to the corresponding
|
||||
* encoding struct if one can be found, otherwise return NULL.
|
||||
*
|
||||
* @param start A pointer to the first byte of the name.
|
||||
* @param end A pointer to the last byte of the name.
|
||||
* @returns A pointer to the encoding struct if one is found, otherwise NULL.
|
||||
*/
|
||||
const pm_encoding_t * pm_encoding_find(const uint8_t *start, const uint8_t *end);
|
||||
|
||||
#endif
|
||||
129
vendor/mruby-compiler2/lib/prism/include/prism/node.h
vendored
Normal file
129
vendor/mruby-compiler2/lib/prism/include/prism/node.h
vendored
Normal file
@@ -0,0 +1,129 @@
|
||||
/**
|
||||
* @file node.h
|
||||
*
|
||||
* Functions related to nodes in the AST.
|
||||
*/
|
||||
#ifndef PRISM_NODE_H
|
||||
#define PRISM_NODE_H
|
||||
|
||||
#include "prism/defines.h"
|
||||
#include "prism/parser.h"
|
||||
#include "prism/util/pm_buffer.h"
|
||||
|
||||
/**
|
||||
* Loop through each node in the node list, writing each node to the given
|
||||
* pm_node_t pointer.
|
||||
*/
|
||||
#define PM_NODE_LIST_FOREACH(list, index, node) \
|
||||
for (size_t index = 0; index < (list)->size && ((node) = (list)->nodes[index]); index++)
|
||||
|
||||
/**
|
||||
* Append a new node onto the end of the node list.
|
||||
*
|
||||
* @param list The list to append to.
|
||||
* @param node The node to append.
|
||||
*/
|
||||
void pm_node_list_append(pm_node_list_t *list, pm_node_t *node);
|
||||
|
||||
/**
|
||||
* Prepend a new node onto the beginning of the node list.
|
||||
*
|
||||
* @param list The list to prepend to.
|
||||
* @param node The node to prepend.
|
||||
*/
|
||||
void pm_node_list_prepend(pm_node_list_t *list, pm_node_t *node);
|
||||
|
||||
/**
|
||||
* Concatenate the given node list onto the end of the other node list.
|
||||
*
|
||||
* @param list The list to concatenate onto.
|
||||
* @param other The list to concatenate.
|
||||
*/
|
||||
void pm_node_list_concat(pm_node_list_t *list, pm_node_list_t *other);
|
||||
|
||||
/**
|
||||
* Free the internal memory associated with the given node list.
|
||||
*
|
||||
* @param list The list to free.
|
||||
*/
|
||||
void pm_node_list_free(pm_node_list_t *list);
|
||||
|
||||
/**
|
||||
* Deallocate a node and all of its children.
|
||||
*
|
||||
* @param parser The parser that owns the node.
|
||||
* @param node The node to deallocate.
|
||||
*/
|
||||
PRISM_EXPORTED_FUNCTION void pm_node_destroy(pm_parser_t *parser, struct pm_node *node);
|
||||
|
||||
/**
|
||||
* Returns a string representation of the given node type.
|
||||
*
|
||||
* @param node_type The node type to convert to a string.
|
||||
* @return A string representation of the given node type.
|
||||
*/
|
||||
PRISM_EXPORTED_FUNCTION const char * pm_node_type_to_str(pm_node_type_t node_type);
|
||||
|
||||
/**
|
||||
* Visit each of the nodes in this subtree using the given visitor callback. The
|
||||
* callback function will be called for each node in the subtree. If it returns
|
||||
* false, then that node's children will not be visited. If it returns true,
|
||||
* then the children will be visited. The data parameter is treated as an opaque
|
||||
* pointer and is passed to the visitor callback for consumers to use as they
|
||||
* see fit.
|
||||
*
|
||||
* As an example:
|
||||
*
|
||||
* ```c
|
||||
* #include "prism.h"
|
||||
*
|
||||
* bool visit(const pm_node_t *node, void *data) {
|
||||
* size_t *indent = (size_t *) data;
|
||||
* for (size_t i = 0; i < *indent * 2; i++) putc(' ', stdout);
|
||||
* printf("%s\n", pm_node_type_to_str(node->type));
|
||||
*
|
||||
* size_t next_indent = *indent + 1;
|
||||
* size_t *next_data = &next_indent;
|
||||
* pm_visit_child_nodes(node, visit, next_data);
|
||||
*
|
||||
* return false;
|
||||
* }
|
||||
*
|
||||
* int main(void) {
|
||||
* const char *source = "1 + 2; 3 + 4";
|
||||
* size_t size = strlen(source);
|
||||
*
|
||||
* pm_parser_t parser;
|
||||
* pm_options_t options = { 0 };
|
||||
* pm_parser_init(&parser, (const uint8_t *) source, size, &options);
|
||||
*
|
||||
* size_t indent = 0;
|
||||
* pm_node_t *node = pm_parse(&parser);
|
||||
*
|
||||
* size_t *data = &indent;
|
||||
* pm_visit_node(node, visit, data);
|
||||
*
|
||||
* pm_node_destroy(&parser, node);
|
||||
* pm_parser_free(&parser);
|
||||
* return EXIT_SUCCESS;
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @param node The root node to start visiting from.
|
||||
* @param visitor The callback to call for each node in the subtree.
|
||||
* @param data An opaque pointer that is passed to the visitor callback.
|
||||
*/
|
||||
PRISM_EXPORTED_FUNCTION void pm_visit_node(const pm_node_t *node, bool (*visitor)(const pm_node_t *node, void *data), void *data);
|
||||
|
||||
/**
|
||||
* Visit the children of the given node with the given callback. This is the
|
||||
* default behavior for walking the tree that is called from pm_visit_node if
|
||||
* the callback returns true.
|
||||
*
|
||||
* @param node The node to visit the children of.
|
||||
* @param visitor The callback to call for each child node.
|
||||
* @param data An opaque pointer that is passed to the visitor callback.
|
||||
*/
|
||||
PRISM_EXPORTED_FUNCTION void pm_visit_child_nodes(const pm_node_t *node, bool (*visitor)(const pm_node_t *node, void *data), void *data);
|
||||
|
||||
#endif
|
||||
442
vendor/mruby-compiler2/lib/prism/include/prism/options.h
vendored
Normal file
442
vendor/mruby-compiler2/lib/prism/include/prism/options.h
vendored
Normal file
@@ -0,0 +1,442 @@
|
||||
/**
|
||||
* @file options.h
|
||||
*
|
||||
* The options that can be passed to parsing.
|
||||
*/
|
||||
#ifndef PRISM_OPTIONS_H
|
||||
#define PRISM_OPTIONS_H
|
||||
|
||||
#include "prism/defines.h"
|
||||
#include "prism/util/pm_char.h"
|
||||
#include "prism/util/pm_string.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* String literals should be made frozen.
|
||||
*/
|
||||
#define PM_OPTIONS_FROZEN_STRING_LITERAL_DISABLED ((int8_t) -1)
|
||||
|
||||
/**
|
||||
* String literals may be frozen or mutable depending on the implementation
|
||||
* default.
|
||||
*/
|
||||
#define PM_OPTIONS_FROZEN_STRING_LITERAL_UNSET ((int8_t) 0)
|
||||
|
||||
/**
|
||||
* String literals should be made mutable.
|
||||
*/
|
||||
#define PM_OPTIONS_FROZEN_STRING_LITERAL_ENABLED ((int8_t) 1)
|
||||
|
||||
/**
|
||||
* A scope of locals surrounding the code that is being parsed.
|
||||
*/
|
||||
typedef struct pm_options_scope {
|
||||
/** The number of locals in the scope. */
|
||||
size_t locals_count;
|
||||
|
||||
/** The names of the locals in the scope. */
|
||||
pm_string_t *locals;
|
||||
|
||||
/** Flags for the set of forwarding parameters in this scope. */
|
||||
uint8_t forwarding;
|
||||
} pm_options_scope_t;
|
||||
|
||||
/** The default value for parameters. */
|
||||
static const uint8_t PM_OPTIONS_SCOPE_FORWARDING_NONE = 0x0;
|
||||
|
||||
/** When the scope is fowarding with the * parameter. */
|
||||
static const uint8_t PM_OPTIONS_SCOPE_FORWARDING_POSITIONALS = 0x1;
|
||||
|
||||
/** When the scope is fowarding with the ** parameter. */
|
||||
static const uint8_t PM_OPTIONS_SCOPE_FORWARDING_KEYWORDS = 0x2;
|
||||
|
||||
/** When the scope is fowarding with the & parameter. */
|
||||
static const uint8_t PM_OPTIONS_SCOPE_FORWARDING_BLOCK = 0x4;
|
||||
|
||||
/** When the scope is fowarding with the ... parameter. */
|
||||
static const uint8_t PM_OPTIONS_SCOPE_FORWARDING_ALL = 0x8;
|
||||
|
||||
// Forward declaration needed by the callback typedef.
|
||||
struct pm_options;
|
||||
|
||||
/**
|
||||
* The callback called when additional switches are found in a shebang comment
|
||||
* that need to be processed by the runtime.
|
||||
*
|
||||
* @param options The options struct that may be updated by this callback.
|
||||
* Certain fields will be checked for changes, specifically encoding,
|
||||
* command_line, and frozen_string_literal.
|
||||
* @param source The source of the shebang comment.
|
||||
* @param length The length of the source.
|
||||
* @param shebang_callback_data Any additional data that should be passed along
|
||||
* to the callback.
|
||||
*/
|
||||
typedef void (*pm_options_shebang_callback_t)(struct pm_options *options, const uint8_t *source, size_t length, void *shebang_callback_data);
|
||||
|
||||
/**
|
||||
* The version of Ruby syntax that we should be parsing with. This is used to
|
||||
* allow consumers to specify which behavior they want in case they need to
|
||||
* parse in the same way as a specific version of CRuby would have.
|
||||
*/
|
||||
typedef enum {
|
||||
/** The current version of prism. */
|
||||
PM_OPTIONS_VERSION_LATEST = 0,
|
||||
|
||||
/** The vendored version of prism in CRuby 3.3.x. */
|
||||
PM_OPTIONS_VERSION_CRUBY_3_3 = 1,
|
||||
|
||||
/** The vendored version of prism in CRuby 3.4.x. */
|
||||
PM_OPTIONS_VERSION_CRUBY_3_4 = 2
|
||||
} pm_options_version_t;
|
||||
|
||||
/**
|
||||
* The options that can be passed to the parser.
|
||||
*/
|
||||
typedef struct pm_options {
|
||||
/**
|
||||
* The callback to call when additional switches are found in a shebang
|
||||
* comment.
|
||||
*/
|
||||
pm_options_shebang_callback_t shebang_callback;
|
||||
|
||||
/**
|
||||
* Any additional data that should be passed along to the shebang callback
|
||||
* if one was set.
|
||||
*/
|
||||
void *shebang_callback_data;
|
||||
|
||||
/** The name of the file that is currently being parsed. */
|
||||
pm_string_t filepath;
|
||||
|
||||
/**
|
||||
* The line within the file that the parse starts on. This value is
|
||||
* 1-indexed.
|
||||
*/
|
||||
int32_t line;
|
||||
|
||||
/**
|
||||
* The name of the encoding that the source file is in. Note that this must
|
||||
* correspond to a name that can be found with Encoding.find in Ruby.
|
||||
*/
|
||||
pm_string_t encoding;
|
||||
|
||||
/**
|
||||
* The number of scopes surrounding the code that is being parsed.
|
||||
*/
|
||||
size_t scopes_count;
|
||||
|
||||
/**
|
||||
* The scopes surrounding the code that is being parsed. For most parses
|
||||
* this will be NULL, but for evals it will be the locals that are in scope
|
||||
* surrounding the eval. Scopes are ordered from the outermost scope to the
|
||||
* innermost one.
|
||||
*/
|
||||
pm_options_scope_t *scopes;
|
||||
|
||||
/**
|
||||
* The version of prism that we should be parsing with. This is used to
|
||||
* allow consumers to specify which behavior they want in case they need to
|
||||
* parse exactly as a specific version of CRuby.
|
||||
*/
|
||||
pm_options_version_t version;
|
||||
|
||||
/** A bitset of the various options that were set on the command line. */
|
||||
uint8_t command_line;
|
||||
|
||||
/**
|
||||
* Whether or not the frozen string literal option has been set.
|
||||
* May be:
|
||||
* - PM_OPTIONS_FROZEN_STRING_LITERAL_DISABLED
|
||||
* - PM_OPTIONS_FROZEN_STRING_LITERAL_ENABLED
|
||||
* - PM_OPTIONS_FROZEN_STRING_LITERAL_UNSET
|
||||
*/
|
||||
int8_t frozen_string_literal;
|
||||
|
||||
/**
|
||||
* Whether or not the encoding magic comments should be respected. This is a
|
||||
* niche use-case where you want to parse a file with a specific encoding
|
||||
* but ignore any encoding magic comments at the top of the file.
|
||||
*/
|
||||
bool encoding_locked;
|
||||
|
||||
/**
|
||||
* When the file being parsed is the main script, the shebang will be
|
||||
* considered for command-line flags (or for implicit -x). The caller needs
|
||||
* to pass this information to the parser so that it can behave correctly.
|
||||
*/
|
||||
bool main_script;
|
||||
|
||||
/**
|
||||
* When the file being parsed is considered a "partial" script, jumps will
|
||||
* not be marked as errors if they are not contained within loops/blocks.
|
||||
* This is used in the case that you're parsing a script that you know will
|
||||
* be embedded inside another script later, but you do not have that context
|
||||
* yet. For example, when parsing an ERB template that will be evaluated
|
||||
* inside another script.
|
||||
*/
|
||||
bool partial_script;
|
||||
|
||||
/**
|
||||
* Whether or not the parser should freeze the nodes that it creates. This
|
||||
* makes it possible to have a deeply frozen AST that is safe to share
|
||||
* between concurrency primitives.
|
||||
*/
|
||||
bool freeze;
|
||||
} pm_options_t;
|
||||
|
||||
/**
|
||||
* A bit representing whether or not the command line -a option was set. -a
|
||||
* splits the input line $_ into $F.
|
||||
*/
|
||||
static const uint8_t PM_OPTIONS_COMMAND_LINE_A = 0x1;
|
||||
|
||||
/**
|
||||
* A bit representing whether or not the command line -e option was set. -e
|
||||
* allow the user to specify a script to be executed. This is necessary for
|
||||
* prism to know because certain warnings are not generated when -e is used.
|
||||
*/
|
||||
static const uint8_t PM_OPTIONS_COMMAND_LINE_E = 0x2;
|
||||
|
||||
/**
|
||||
* A bit representing whether or not the command line -l option was set. -l
|
||||
* chomps the input line by default.
|
||||
*/
|
||||
static const uint8_t PM_OPTIONS_COMMAND_LINE_L = 0x4;
|
||||
|
||||
/**
|
||||
* A bit representing whether or not the command line -n option was set. -n
|
||||
* wraps the script in a while gets loop.
|
||||
*/
|
||||
static const uint8_t PM_OPTIONS_COMMAND_LINE_N = 0x8;
|
||||
|
||||
/**
|
||||
* A bit representing whether or not the command line -p option was set. -p
|
||||
* prints the value of $_ at the end of each loop.
|
||||
*/
|
||||
static const uint8_t PM_OPTIONS_COMMAND_LINE_P = 0x10;
|
||||
|
||||
/**
|
||||
* A bit representing whether or not the command line -x option was set. -x
|
||||
* searches the input file for a shebang that matches the current Ruby engine.
|
||||
*/
|
||||
static const uint8_t PM_OPTIONS_COMMAND_LINE_X = 0x20;
|
||||
|
||||
/**
|
||||
* Set the shebang callback option on the given options struct.
|
||||
*
|
||||
* @param options The options struct to set the shebang callback on.
|
||||
* @param shebang_callback The shebang callback to set.
|
||||
* @param shebang_callback_data Any additional data that should be passed along
|
||||
* to the callback.
|
||||
*/
|
||||
PRISM_EXPORTED_FUNCTION void pm_options_shebang_callback_set(pm_options_t *options, pm_options_shebang_callback_t shebang_callback, void *shebang_callback_data);
|
||||
|
||||
/**
|
||||
* Set the filepath option on the given options struct.
|
||||
*
|
||||
* @param options The options struct to set the filepath on.
|
||||
* @param filepath The filepath to set.
|
||||
*/
|
||||
PRISM_EXPORTED_FUNCTION void pm_options_filepath_set(pm_options_t *options, const char *filepath);
|
||||
|
||||
/**
|
||||
* Set the line option on the given options struct.
|
||||
*
|
||||
* @param options The options struct to set the line on.
|
||||
* @param line The line to set.
|
||||
*/
|
||||
PRISM_EXPORTED_FUNCTION void pm_options_line_set(pm_options_t *options, int32_t line);
|
||||
|
||||
/**
|
||||
* Set the encoding option on the given options struct.
|
||||
*
|
||||
* @param options The options struct to set the encoding on.
|
||||
* @param encoding The encoding to set.
|
||||
*/
|
||||
PRISM_EXPORTED_FUNCTION void pm_options_encoding_set(pm_options_t *options, const char *encoding);
|
||||
|
||||
/**
|
||||
* Set the encoding_locked option on the given options struct.
|
||||
*
|
||||
* @param options The options struct to set the encoding_locked value on.
|
||||
* @param encoding_locked The encoding_locked value to set.
|
||||
*/
|
||||
PRISM_EXPORTED_FUNCTION void pm_options_encoding_locked_set(pm_options_t *options, bool encoding_locked);
|
||||
|
||||
/**
|
||||
* Set the frozen string literal option on the given options struct.
|
||||
*
|
||||
* @param options The options struct to set the frozen string literal value on.
|
||||
* @param frozen_string_literal The frozen string literal value to set.
|
||||
*/
|
||||
PRISM_EXPORTED_FUNCTION void pm_options_frozen_string_literal_set(pm_options_t *options, bool frozen_string_literal);
|
||||
|
||||
/**
|
||||
* Sets the command line option on the given options struct.
|
||||
*
|
||||
* @param options The options struct to set the command line option on.
|
||||
* @param command_line The command_line value to set.
|
||||
*/
|
||||
PRISM_EXPORTED_FUNCTION void pm_options_command_line_set(pm_options_t *options, uint8_t command_line);
|
||||
|
||||
/**
|
||||
* Set the version option on the given options struct by parsing the given
|
||||
* string. If the string contains an invalid option, this returns false.
|
||||
* Otherwise, it returns true.
|
||||
*
|
||||
* @param options The options struct to set the version on.
|
||||
* @param version The version to set.
|
||||
* @param length The length of the version string.
|
||||
* @return Whether or not the version was parsed successfully.
|
||||
*/
|
||||
PRISM_EXPORTED_FUNCTION bool pm_options_version_set(pm_options_t *options, const char *version, size_t length);
|
||||
|
||||
/**
|
||||
* Set the main script option on the given options struct.
|
||||
*
|
||||
* @param options The options struct to set the main script value on.
|
||||
* @param main_script The main script value to set.
|
||||
*/
|
||||
PRISM_EXPORTED_FUNCTION void pm_options_main_script_set(pm_options_t *options, bool main_script);
|
||||
|
||||
/**
|
||||
* Set the partial script option on the given options struct.
|
||||
*
|
||||
* @param options The options struct to set the partial script value on.
|
||||
* @param partial_script The partial script value to set.
|
||||
*/
|
||||
PRISM_EXPORTED_FUNCTION void pm_options_partial_script_set(pm_options_t *options, bool partial_script);
|
||||
|
||||
/**
|
||||
* Set the freeze option on the given options struct.
|
||||
*
|
||||
* @param options The options struct to set the freeze value on.
|
||||
* @param freeze The freeze value to set.
|
||||
*/
|
||||
PRISM_EXPORTED_FUNCTION void pm_options_freeze_set(pm_options_t *options, bool freeze);
|
||||
|
||||
/**
|
||||
* Allocate and zero out the scopes array on the given options struct.
|
||||
*
|
||||
* @param options The options struct to initialize the scopes array on.
|
||||
* @param scopes_count The number of scopes to allocate.
|
||||
* @return Whether or not the scopes array was initialized successfully.
|
||||
*/
|
||||
PRISM_EXPORTED_FUNCTION bool pm_options_scopes_init(pm_options_t *options, size_t scopes_count);
|
||||
|
||||
/**
|
||||
* Return a pointer to the scope at the given index within the given options.
|
||||
*
|
||||
* @param options The options struct to get the scope from.
|
||||
* @param index The index of the scope to get.
|
||||
* @return A pointer to the scope at the given index.
|
||||
*/
|
||||
PRISM_EXPORTED_FUNCTION const pm_options_scope_t * pm_options_scope_get(const pm_options_t *options, size_t index);
|
||||
|
||||
/**
|
||||
* Create a new options scope struct. This will hold a set of locals that are in
|
||||
* scope surrounding the code that is being parsed.
|
||||
*
|
||||
* @param scope The scope struct to initialize.
|
||||
* @param locals_count The number of locals to allocate.
|
||||
* @return Whether or not the scope was initialized successfully.
|
||||
*/
|
||||
PRISM_EXPORTED_FUNCTION bool pm_options_scope_init(pm_options_scope_t *scope, size_t locals_count);
|
||||
|
||||
/**
|
||||
* Return a pointer to the local at the given index within the given scope.
|
||||
*
|
||||
* @param scope The scope struct to get the local from.
|
||||
* @param index The index of the local to get.
|
||||
* @return A pointer to the local at the given index.
|
||||
*/
|
||||
PRISM_EXPORTED_FUNCTION const pm_string_t * pm_options_scope_local_get(const pm_options_scope_t *scope, size_t index);
|
||||
|
||||
/**
|
||||
* Set the forwarding option on the given scope struct.
|
||||
*
|
||||
* @param scope The scope struct to set the forwarding on.
|
||||
* @param forwarding The forwarding value to set.
|
||||
*/
|
||||
PRISM_EXPORTED_FUNCTION void pm_options_scope_forwarding_set(pm_options_scope_t *scope, uint8_t forwarding);
|
||||
|
||||
/**
|
||||
* Free the internal memory associated with the options.
|
||||
*
|
||||
* @param options The options struct whose internal memory should be freed.
|
||||
*/
|
||||
PRISM_EXPORTED_FUNCTION void pm_options_free(pm_options_t *options);
|
||||
|
||||
/**
|
||||
* Deserialize an options struct from the given binary string. This is used to
|
||||
* pass options to the parser from an FFI call so that consumers of the library
|
||||
* from an FFI perspective don't have to worry about the structure of our
|
||||
* options structs. Since the source of these calls will be from Ruby
|
||||
* implementation internals we assume it is from a trusted source.
|
||||
*
|
||||
* `data` is assumed to be a valid pointer pointing to well-formed data. The
|
||||
* layout of this data should be the same every time, and is described below:
|
||||
*
|
||||
* | # bytes | field |
|
||||
* | ------- | -------------------------- |
|
||||
* | `4` | the length of the filepath |
|
||||
* | ... | the filepath bytes |
|
||||
* | `4` | the line number |
|
||||
* | `4` | the length the encoding |
|
||||
* | ... | the encoding bytes |
|
||||
* | `1` | frozen string literal |
|
||||
* | `1` | -p command line option |
|
||||
* | `1` | -n command line option |
|
||||
* | `1` | -l command line option |
|
||||
* | `1` | -a command line option |
|
||||
* | `1` | the version |
|
||||
* | `1` | encoding locked |
|
||||
* | `1` | main script |
|
||||
* | `1` | partial script |
|
||||
* | `1` | freeze |
|
||||
* | `4` | the number of scopes |
|
||||
* | ... | the scopes |
|
||||
*
|
||||
* The version field is an enum, so it should be one of the following values:
|
||||
*
|
||||
* | value | version |
|
||||
* | ----- | ------------------------- |
|
||||
* | `0` | use the latest version of prism |
|
||||
* | `1` | use the version of prism that is vendored in CRuby 3.3.0 |
|
||||
*
|
||||
* Each scope is laid out as follows:
|
||||
*
|
||||
* | # bytes | field |
|
||||
* | ------- | -------------------------- |
|
||||
* | `4` | the number of locals |
|
||||
* | `1` | the forwarding flags |
|
||||
* | ... | the locals |
|
||||
*
|
||||
* Each local is laid out as follows:
|
||||
*
|
||||
* | # bytes | field |
|
||||
* | ------- | -------------------------- |
|
||||
* | `4` | the length of the local |
|
||||
* | ... | the local bytes |
|
||||
*
|
||||
* Some additional things to note about this layout:
|
||||
*
|
||||
* * The filepath can have a length of 0, in which case we'll consider it an
|
||||
* empty string.
|
||||
* * The line number should be 0-indexed.
|
||||
* * The encoding can have a length of 0, in which case we'll use the default
|
||||
* encoding (UTF-8). If it's not 0, it should correspond to a name of an
|
||||
* encoding that can be passed to `Encoding.find` in Ruby.
|
||||
* * The frozen string literal, encoding locked, main script, and partial script
|
||||
* fields are booleans, so their values should be either 0 or 1.
|
||||
* * The number of scopes can be 0.
|
||||
*
|
||||
* @param options The options struct to deserialize into.
|
||||
* @param data The binary string to deserialize from.
|
||||
*/
|
||||
void pm_options_read(pm_options_t *options, const char *data);
|
||||
|
||||
#endif
|
||||
163
vendor/mruby-compiler2/lib/prism/include/prism/pack.h
vendored
Normal file
163
vendor/mruby-compiler2/lib/prism/include/prism/pack.h
vendored
Normal file
@@ -0,0 +1,163 @@
|
||||
/**
|
||||
* @file pack.h
|
||||
*
|
||||
* A pack template string parser.
|
||||
*/
|
||||
#ifndef PRISM_PACK_H
|
||||
#define PRISM_PACK_H
|
||||
|
||||
#include "prism/defines.h"
|
||||
|
||||
// We optionally support parsing String#pack templates. For systems that don't
|
||||
// want or need this functionality, it can be turned off with the
|
||||
// PRISM_EXCLUDE_PACK define.
|
||||
#ifdef PRISM_EXCLUDE_PACK
|
||||
|
||||
void pm_pack_parse(void);
|
||||
|
||||
#else
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/** The version of the pack template language that we are parsing. */
|
||||
typedef enum pm_pack_version {
|
||||
PM_PACK_VERSION_3_2_0
|
||||
} pm_pack_version;
|
||||
|
||||
/** The type of pack template we are parsing. */
|
||||
typedef enum pm_pack_variant {
|
||||
PM_PACK_VARIANT_PACK,
|
||||
PM_PACK_VARIANT_UNPACK
|
||||
} pm_pack_variant;
|
||||
|
||||
/** A directive within the pack template. */
|
||||
typedef enum pm_pack_type {
|
||||
PM_PACK_SPACE,
|
||||
PM_PACK_COMMENT,
|
||||
PM_PACK_INTEGER,
|
||||
PM_PACK_UTF8,
|
||||
PM_PACK_BER,
|
||||
PM_PACK_FLOAT,
|
||||
PM_PACK_STRING_SPACE_PADDED,
|
||||
PM_PACK_STRING_NULL_PADDED,
|
||||
PM_PACK_STRING_NULL_TERMINATED,
|
||||
PM_PACK_STRING_MSB,
|
||||
PM_PACK_STRING_LSB,
|
||||
PM_PACK_STRING_HEX_HIGH,
|
||||
PM_PACK_STRING_HEX_LOW,
|
||||
PM_PACK_STRING_UU,
|
||||
PM_PACK_STRING_MIME,
|
||||
PM_PACK_STRING_BASE64,
|
||||
PM_PACK_STRING_FIXED,
|
||||
PM_PACK_STRING_POINTER,
|
||||
PM_PACK_MOVE,
|
||||
PM_PACK_BACK,
|
||||
PM_PACK_NULL,
|
||||
PM_PACK_END
|
||||
} pm_pack_type;
|
||||
|
||||
/** The signness of a pack directive. */
|
||||
typedef enum pm_pack_signed {
|
||||
PM_PACK_UNSIGNED,
|
||||
PM_PACK_SIGNED,
|
||||
PM_PACK_SIGNED_NA
|
||||
} pm_pack_signed;
|
||||
|
||||
/** The endianness of a pack directive. */
|
||||
typedef enum pm_pack_endian {
|
||||
PM_PACK_AGNOSTIC_ENDIAN,
|
||||
PM_PACK_LITTLE_ENDIAN, // aka 'VAX', or 'V'
|
||||
PM_PACK_BIG_ENDIAN, // aka 'network', or 'N'
|
||||
PM_PACK_NATIVE_ENDIAN,
|
||||
PM_PACK_ENDIAN_NA
|
||||
} pm_pack_endian;
|
||||
|
||||
/** The size of an integer pack directive. */
|
||||
typedef enum pm_pack_size {
|
||||
PM_PACK_SIZE_SHORT,
|
||||
PM_PACK_SIZE_INT,
|
||||
PM_PACK_SIZE_LONG,
|
||||
PM_PACK_SIZE_LONG_LONG,
|
||||
PM_PACK_SIZE_8,
|
||||
PM_PACK_SIZE_16,
|
||||
PM_PACK_SIZE_32,
|
||||
PM_PACK_SIZE_64,
|
||||
PM_PACK_SIZE_P,
|
||||
PM_PACK_SIZE_NA
|
||||
} pm_pack_size;
|
||||
|
||||
/** The type of length of a pack directive. */
|
||||
typedef enum pm_pack_length_type {
|
||||
PM_PACK_LENGTH_FIXED,
|
||||
PM_PACK_LENGTH_MAX,
|
||||
PM_PACK_LENGTH_RELATIVE, // special case for unpack @*
|
||||
PM_PACK_LENGTH_NA
|
||||
} pm_pack_length_type;
|
||||
|
||||
/** The type of encoding for a pack template string. */
|
||||
typedef enum pm_pack_encoding {
|
||||
PM_PACK_ENCODING_START,
|
||||
PM_PACK_ENCODING_ASCII_8BIT,
|
||||
PM_PACK_ENCODING_US_ASCII,
|
||||
PM_PACK_ENCODING_UTF_8
|
||||
} pm_pack_encoding;
|
||||
|
||||
/** The result of parsing a pack template. */
|
||||
typedef enum pm_pack_result {
|
||||
PM_PACK_OK,
|
||||
PM_PACK_ERROR_UNSUPPORTED_DIRECTIVE,
|
||||
PM_PACK_ERROR_UNKNOWN_DIRECTIVE,
|
||||
PM_PACK_ERROR_LENGTH_TOO_BIG,
|
||||
PM_PACK_ERROR_BANG_NOT_ALLOWED,
|
||||
PM_PACK_ERROR_DOUBLE_ENDIAN
|
||||
} pm_pack_result;
|
||||
|
||||
/**
|
||||
* Parse a single directive from a pack or unpack format string.
|
||||
*
|
||||
* @param variant (in) pack or unpack
|
||||
* @param format (in, out) the start of the next directive to parse on calling,
|
||||
* and advanced beyond the parsed directive on return, or as much of it as
|
||||
* was consumed until an error was encountered
|
||||
* @param format_end (in) the end of the format string
|
||||
* @param type (out) the type of the directive
|
||||
* @param signed_type (out) whether the value is signed
|
||||
* @param endian (out) the endianness of the value
|
||||
* @param size (out) the size of the value
|
||||
* @param length_type (out) what kind of length is specified
|
||||
* @param length (out) the length of the directive
|
||||
* @param encoding (in, out) takes the current encoding of the string which
|
||||
* would result from parsing the whole format string, and returns a possibly
|
||||
* changed directive - the encoding should be `PM_PACK_ENCODING_START` when
|
||||
* pm_pack_parse is called for the first directive in a format string
|
||||
*
|
||||
* @return `PM_PACK_OK` on success or `PM_PACK_ERROR_*` on error
|
||||
* @note Consult Ruby documentation for the meaning of directives.
|
||||
*/
|
||||
PRISM_EXPORTED_FUNCTION pm_pack_result
|
||||
pm_pack_parse(
|
||||
pm_pack_variant variant,
|
||||
const char **format,
|
||||
const char *format_end,
|
||||
pm_pack_type *type,
|
||||
pm_pack_signed *signed_type,
|
||||
pm_pack_endian *endian,
|
||||
pm_pack_size *size,
|
||||
pm_pack_length_type *length_type,
|
||||
uint64_t *length,
|
||||
pm_pack_encoding *encoding
|
||||
);
|
||||
|
||||
/**
|
||||
* Prism abstracts sizes away from the native system - this converts an abstract
|
||||
* size to a native size.
|
||||
*
|
||||
* @param size The abstract size to convert.
|
||||
* @return The native size.
|
||||
*/
|
||||
PRISM_EXPORTED_FUNCTION size_t pm_size_to_native(pm_pack_size size);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
933
vendor/mruby-compiler2/lib/prism/include/prism/parser.h
vendored
Normal file
933
vendor/mruby-compiler2/lib/prism/include/prism/parser.h
vendored
Normal file
@@ -0,0 +1,933 @@
|
||||
/**
|
||||
* @file parser.h
|
||||
*
|
||||
* The parser used to parse Ruby source.
|
||||
*/
|
||||
#ifndef PRISM_PARSER_H
|
||||
#define PRISM_PARSER_H
|
||||
|
||||
#include "prism/defines.h"
|
||||
#include "prism/ast.h"
|
||||
#include "prism/encoding.h"
|
||||
#include "prism/options.h"
|
||||
#include "prism/static_literals.h"
|
||||
#include "prism/util/pm_constant_pool.h"
|
||||
#include "prism/util/pm_list.h"
|
||||
#include "prism/util/pm_newline_list.h"
|
||||
#include "prism/util/pm_string.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
/**
|
||||
* This enum provides various bits that represent different kinds of states that
|
||||
* the lexer can track. This is used to determine which kind of token to return
|
||||
* based on the context of the parser.
|
||||
*/
|
||||
typedef enum {
|
||||
PM_LEX_STATE_BIT_BEG,
|
||||
PM_LEX_STATE_BIT_END,
|
||||
PM_LEX_STATE_BIT_ENDARG,
|
||||
PM_LEX_STATE_BIT_ENDFN,
|
||||
PM_LEX_STATE_BIT_ARG,
|
||||
PM_LEX_STATE_BIT_CMDARG,
|
||||
PM_LEX_STATE_BIT_MID,
|
||||
PM_LEX_STATE_BIT_FNAME,
|
||||
PM_LEX_STATE_BIT_DOT,
|
||||
PM_LEX_STATE_BIT_CLASS,
|
||||
PM_LEX_STATE_BIT_LABEL,
|
||||
PM_LEX_STATE_BIT_LABELED,
|
||||
PM_LEX_STATE_BIT_FITEM
|
||||
} pm_lex_state_bit_t;
|
||||
|
||||
/**
|
||||
* This enum combines the various bits from the above enum into individual
|
||||
* values that represent the various states of the lexer.
|
||||
*/
|
||||
typedef enum {
|
||||
PM_LEX_STATE_NONE = 0,
|
||||
PM_LEX_STATE_BEG = (1 << PM_LEX_STATE_BIT_BEG),
|
||||
PM_LEX_STATE_END = (1 << PM_LEX_STATE_BIT_END),
|
||||
PM_LEX_STATE_ENDARG = (1 << PM_LEX_STATE_BIT_ENDARG),
|
||||
PM_LEX_STATE_ENDFN = (1 << PM_LEX_STATE_BIT_ENDFN),
|
||||
PM_LEX_STATE_ARG = (1 << PM_LEX_STATE_BIT_ARG),
|
||||
PM_LEX_STATE_CMDARG = (1 << PM_LEX_STATE_BIT_CMDARG),
|
||||
PM_LEX_STATE_MID = (1 << PM_LEX_STATE_BIT_MID),
|
||||
PM_LEX_STATE_FNAME = (1 << PM_LEX_STATE_BIT_FNAME),
|
||||
PM_LEX_STATE_DOT = (1 << PM_LEX_STATE_BIT_DOT),
|
||||
PM_LEX_STATE_CLASS = (1 << PM_LEX_STATE_BIT_CLASS),
|
||||
PM_LEX_STATE_LABEL = (1 << PM_LEX_STATE_BIT_LABEL),
|
||||
PM_LEX_STATE_LABELED = (1 << PM_LEX_STATE_BIT_LABELED),
|
||||
PM_LEX_STATE_FITEM = (1 << PM_LEX_STATE_BIT_FITEM),
|
||||
PM_LEX_STATE_BEG_ANY = PM_LEX_STATE_BEG | PM_LEX_STATE_MID | PM_LEX_STATE_CLASS,
|
||||
PM_LEX_STATE_ARG_ANY = PM_LEX_STATE_ARG | PM_LEX_STATE_CMDARG,
|
||||
PM_LEX_STATE_END_ANY = PM_LEX_STATE_END | PM_LEX_STATE_ENDARG | PM_LEX_STATE_ENDFN
|
||||
} pm_lex_state_t;
|
||||
|
||||
/**
|
||||
* The type of quote that a heredoc uses.
|
||||
*/
|
||||
typedef enum {
|
||||
PM_HEREDOC_QUOTE_NONE,
|
||||
PM_HEREDOC_QUOTE_SINGLE = '\'',
|
||||
PM_HEREDOC_QUOTE_DOUBLE = '"',
|
||||
PM_HEREDOC_QUOTE_BACKTICK = '`',
|
||||
} pm_heredoc_quote_t;
|
||||
|
||||
/**
|
||||
* The type of indentation that a heredoc uses.
|
||||
*/
|
||||
typedef enum {
|
||||
PM_HEREDOC_INDENT_NONE,
|
||||
PM_HEREDOC_INDENT_DASH,
|
||||
PM_HEREDOC_INDENT_TILDE,
|
||||
} pm_heredoc_indent_t;
|
||||
|
||||
/**
|
||||
* All of the information necessary to store to lexing a heredoc.
|
||||
*/
|
||||
typedef struct {
|
||||
/** A pointer to the start of the heredoc identifier. */
|
||||
const uint8_t *ident_start;
|
||||
|
||||
/** The length of the heredoc identifier. */
|
||||
size_t ident_length;
|
||||
|
||||
/** The type of quote that the heredoc uses. */
|
||||
pm_heredoc_quote_t quote;
|
||||
|
||||
/** The type of indentation that the heredoc uses. */
|
||||
pm_heredoc_indent_t indent;
|
||||
} pm_heredoc_lex_mode_t;
|
||||
|
||||
/**
|
||||
* When lexing Ruby source, the lexer has a small amount of state to tell which
|
||||
* kind of token it is currently lexing. For example, when we find the start of
|
||||
* a string, the first token that we return is a TOKEN_STRING_BEGIN token. After
|
||||
* that the lexer is now in the PM_LEX_STRING mode, and will return tokens that
|
||||
* are found as part of a string.
|
||||
*/
|
||||
typedef struct pm_lex_mode {
|
||||
/** The type of this lex mode. */
|
||||
enum {
|
||||
/** This state is used when any given token is being lexed. */
|
||||
PM_LEX_DEFAULT,
|
||||
|
||||
/**
|
||||
* This state is used when we're lexing as normal but inside an embedded
|
||||
* expression of a string.
|
||||
*/
|
||||
PM_LEX_EMBEXPR,
|
||||
|
||||
/**
|
||||
* This state is used when we're lexing a variable that is embedded
|
||||
* directly inside of a string with the # shorthand.
|
||||
*/
|
||||
PM_LEX_EMBVAR,
|
||||
|
||||
/** This state is used when you are inside the content of a heredoc. */
|
||||
PM_LEX_HEREDOC,
|
||||
|
||||
/**
|
||||
* This state is used when we are lexing a list of tokens, as in a %w
|
||||
* word list literal or a %i symbol list literal.
|
||||
*/
|
||||
PM_LEX_LIST,
|
||||
|
||||
/**
|
||||
* This state is used when a regular expression has been begun and we
|
||||
* are looking for the terminator.
|
||||
*/
|
||||
PM_LEX_REGEXP,
|
||||
|
||||
/**
|
||||
* This state is used when we are lexing a string or a string-like
|
||||
* token, as in string content with either quote or an xstring.
|
||||
*/
|
||||
PM_LEX_STRING
|
||||
} mode;
|
||||
|
||||
/** The data associated with this type of lex mode. */
|
||||
union {
|
||||
struct {
|
||||
/** This keeps track of the nesting level of the list. */
|
||||
size_t nesting;
|
||||
|
||||
/** Whether or not interpolation is allowed in this list. */
|
||||
bool interpolation;
|
||||
|
||||
/**
|
||||
* When lexing a list, it takes into account balancing the
|
||||
* terminator if the terminator is one of (), [], {}, or <>.
|
||||
*/
|
||||
uint8_t incrementor;
|
||||
|
||||
/** This is the terminator of the list literal. */
|
||||
uint8_t terminator;
|
||||
|
||||
/**
|
||||
* This is the character set that should be used to delimit the
|
||||
* tokens within the list.
|
||||
*/
|
||||
uint8_t breakpoints[11];
|
||||
} list;
|
||||
|
||||
struct {
|
||||
/**
|
||||
* This keeps track of the nesting level of the regular expression.
|
||||
*/
|
||||
size_t nesting;
|
||||
|
||||
/**
|
||||
* When lexing a regular expression, it takes into account balancing
|
||||
* the terminator if the terminator is one of (), [], {}, or <>.
|
||||
*/
|
||||
uint8_t incrementor;
|
||||
|
||||
/** This is the terminator of the regular expression. */
|
||||
uint8_t terminator;
|
||||
|
||||
/**
|
||||
* This is the character set that should be used to delimit the
|
||||
* tokens within the regular expression.
|
||||
*/
|
||||
uint8_t breakpoints[7];
|
||||
} regexp;
|
||||
|
||||
struct {
|
||||
/** This keeps track of the nesting level of the string. */
|
||||
size_t nesting;
|
||||
|
||||
/** Whether or not interpolation is allowed in this string. */
|
||||
bool interpolation;
|
||||
|
||||
/**
|
||||
* Whether or not at the end of the string we should allow a :,
|
||||
* which would indicate this was a dynamic symbol instead of a
|
||||
* string.
|
||||
*/
|
||||
bool label_allowed;
|
||||
|
||||
/**
|
||||
* When lexing a string, it takes into account balancing the
|
||||
* terminator if the terminator is one of (), [], {}, or <>.
|
||||
*/
|
||||
uint8_t incrementor;
|
||||
|
||||
/**
|
||||
* This is the terminator of the string. It is typically either a
|
||||
* single or double quote.
|
||||
*/
|
||||
uint8_t terminator;
|
||||
|
||||
/**
|
||||
* This is the character set that should be used to delimit the
|
||||
* tokens within the string.
|
||||
*/
|
||||
uint8_t breakpoints[7];
|
||||
} string;
|
||||
|
||||
struct {
|
||||
/**
|
||||
* All of the data necessary to lex a heredoc.
|
||||
*/
|
||||
pm_heredoc_lex_mode_t base;
|
||||
|
||||
/**
|
||||
* This is the pointer to the character where lexing should resume
|
||||
* once the heredoc has been completely processed.
|
||||
*/
|
||||
const uint8_t *next_start;
|
||||
|
||||
/**
|
||||
* This is used to track the amount of common whitespace on each
|
||||
* line so that we know how much to dedent each line in the case of
|
||||
* a tilde heredoc.
|
||||
*/
|
||||
size_t *common_whitespace;
|
||||
|
||||
/** True if the previous token ended with a line continuation. */
|
||||
bool line_continuation;
|
||||
} heredoc;
|
||||
} as;
|
||||
|
||||
/** The previous lex state so that it knows how to pop. */
|
||||
struct pm_lex_mode *prev;
|
||||
} pm_lex_mode_t;
|
||||
|
||||
/**
|
||||
* We pre-allocate a certain number of lex states in order to avoid having to
|
||||
* call malloc too many times while parsing. You really shouldn't need more than
|
||||
* this because you only really nest deeply when doing string interpolation.
|
||||
*/
|
||||
#define PM_LEX_STACK_SIZE 4
|
||||
|
||||
/**
|
||||
* The parser used to parse Ruby source.
|
||||
*/
|
||||
typedef struct pm_parser pm_parser_t;
|
||||
|
||||
/**
|
||||
* While parsing, we keep track of a stack of contexts. This is helpful for
|
||||
* error recovery so that we can pop back to a previous context when we hit a
|
||||
* token that is understood by a parent context but not by the current context.
|
||||
*/
|
||||
typedef enum {
|
||||
/** a null context, used for returning a value from a function */
|
||||
PM_CONTEXT_NONE = 0,
|
||||
|
||||
/** a begin statement */
|
||||
PM_CONTEXT_BEGIN,
|
||||
|
||||
/** an ensure statement with an explicit begin */
|
||||
PM_CONTEXT_BEGIN_ENSURE,
|
||||
|
||||
/** a rescue else statement with an explicit begin */
|
||||
PM_CONTEXT_BEGIN_ELSE,
|
||||
|
||||
/** a rescue statement with an explicit begin */
|
||||
PM_CONTEXT_BEGIN_RESCUE,
|
||||
|
||||
/** expressions in block arguments using braces */
|
||||
PM_CONTEXT_BLOCK_BRACES,
|
||||
|
||||
/** expressions in block arguments using do..end */
|
||||
PM_CONTEXT_BLOCK_KEYWORDS,
|
||||
|
||||
/** an ensure statement within a do..end block */
|
||||
PM_CONTEXT_BLOCK_ENSURE,
|
||||
|
||||
/** a rescue else statement within a do..end block */
|
||||
PM_CONTEXT_BLOCK_ELSE,
|
||||
|
||||
/** a rescue statement within a do..end block */
|
||||
PM_CONTEXT_BLOCK_RESCUE,
|
||||
|
||||
/** a case when statements */
|
||||
PM_CONTEXT_CASE_WHEN,
|
||||
|
||||
/** a case in statements */
|
||||
PM_CONTEXT_CASE_IN,
|
||||
|
||||
/** a class declaration */
|
||||
PM_CONTEXT_CLASS,
|
||||
|
||||
/** an ensure statement within a class statement */
|
||||
PM_CONTEXT_CLASS_ENSURE,
|
||||
|
||||
/** a rescue else statement within a class statement */
|
||||
PM_CONTEXT_CLASS_ELSE,
|
||||
|
||||
/** a rescue statement within a class statement */
|
||||
PM_CONTEXT_CLASS_RESCUE,
|
||||
|
||||
/** a method definition */
|
||||
PM_CONTEXT_DEF,
|
||||
|
||||
/** an ensure statement within a method definition */
|
||||
PM_CONTEXT_DEF_ENSURE,
|
||||
|
||||
/** a rescue else statement within a method definition */
|
||||
PM_CONTEXT_DEF_ELSE,
|
||||
|
||||
/** a rescue statement within a method definition */
|
||||
PM_CONTEXT_DEF_RESCUE,
|
||||
|
||||
/** a method definition's parameters */
|
||||
PM_CONTEXT_DEF_PARAMS,
|
||||
|
||||
/** a defined? expression */
|
||||
PM_CONTEXT_DEFINED,
|
||||
|
||||
/** a method definition's default parameter */
|
||||
PM_CONTEXT_DEFAULT_PARAMS,
|
||||
|
||||
/** an else clause */
|
||||
PM_CONTEXT_ELSE,
|
||||
|
||||
/** an elsif clause */
|
||||
PM_CONTEXT_ELSIF,
|
||||
|
||||
/** an interpolated expression */
|
||||
PM_CONTEXT_EMBEXPR,
|
||||
|
||||
/** a for loop */
|
||||
PM_CONTEXT_FOR,
|
||||
|
||||
/** a for loop's index */
|
||||
PM_CONTEXT_FOR_INDEX,
|
||||
|
||||
/** an if statement */
|
||||
PM_CONTEXT_IF,
|
||||
|
||||
/** a lambda expression with braces */
|
||||
PM_CONTEXT_LAMBDA_BRACES,
|
||||
|
||||
/** a lambda expression with do..end */
|
||||
PM_CONTEXT_LAMBDA_DO_END,
|
||||
|
||||
/** an ensure statement within a lambda expression */
|
||||
PM_CONTEXT_LAMBDA_ENSURE,
|
||||
|
||||
/** a rescue else statement within a lambda expression */
|
||||
PM_CONTEXT_LAMBDA_ELSE,
|
||||
|
||||
/** a rescue statement within a lambda expression */
|
||||
PM_CONTEXT_LAMBDA_RESCUE,
|
||||
|
||||
/** the predicate clause of a loop statement */
|
||||
PM_CONTEXT_LOOP_PREDICATE,
|
||||
|
||||
/** the top level context */
|
||||
PM_CONTEXT_MAIN,
|
||||
|
||||
/** a module declaration */
|
||||
PM_CONTEXT_MODULE,
|
||||
|
||||
/** an ensure statement within a module statement */
|
||||
PM_CONTEXT_MODULE_ENSURE,
|
||||
|
||||
/** a rescue else statement within a module statement */
|
||||
PM_CONTEXT_MODULE_ELSE,
|
||||
|
||||
/** a rescue statement within a module statement */
|
||||
PM_CONTEXT_MODULE_RESCUE,
|
||||
|
||||
/** a multiple target expression */
|
||||
PM_CONTEXT_MULTI_TARGET,
|
||||
|
||||
/** a parenthesized expression */
|
||||
PM_CONTEXT_PARENS,
|
||||
|
||||
/** an END block */
|
||||
PM_CONTEXT_POSTEXE,
|
||||
|
||||
/** a predicate inside an if/elsif/unless statement */
|
||||
PM_CONTEXT_PREDICATE,
|
||||
|
||||
/** a BEGIN block */
|
||||
PM_CONTEXT_PREEXE,
|
||||
|
||||
/** a modifier rescue clause */
|
||||
PM_CONTEXT_RESCUE_MODIFIER,
|
||||
|
||||
/** a singleton class definition */
|
||||
PM_CONTEXT_SCLASS,
|
||||
|
||||
/** an ensure statement with a singleton class */
|
||||
PM_CONTEXT_SCLASS_ENSURE,
|
||||
|
||||
/** a rescue else statement with a singleton class */
|
||||
PM_CONTEXT_SCLASS_ELSE,
|
||||
|
||||
/** a rescue statement with a singleton class */
|
||||
PM_CONTEXT_SCLASS_RESCUE,
|
||||
|
||||
/** a ternary expression */
|
||||
PM_CONTEXT_TERNARY,
|
||||
|
||||
/** an unless statement */
|
||||
PM_CONTEXT_UNLESS,
|
||||
|
||||
/** an until statement */
|
||||
PM_CONTEXT_UNTIL,
|
||||
|
||||
/** a while statement */
|
||||
PM_CONTEXT_WHILE,
|
||||
} pm_context_t;
|
||||
|
||||
/** This is a node in a linked list of contexts. */
|
||||
typedef struct pm_context_node {
|
||||
/** The context that this node represents. */
|
||||
pm_context_t context;
|
||||
|
||||
/** A pointer to the previous context in the linked list. */
|
||||
struct pm_context_node *prev;
|
||||
} pm_context_node_t;
|
||||
|
||||
/** This is the type of a comment that we've found while parsing. */
|
||||
typedef enum {
|
||||
PM_COMMENT_INLINE,
|
||||
PM_COMMENT_EMBDOC
|
||||
} pm_comment_type_t;
|
||||
|
||||
/**
|
||||
* This is a node in the linked list of comments that we've found while parsing.
|
||||
*
|
||||
* @extends pm_list_node_t
|
||||
*/
|
||||
typedef struct pm_comment {
|
||||
/** The embedded base node. */
|
||||
pm_list_node_t node;
|
||||
|
||||
/** The location of the comment in the source. */
|
||||
pm_location_t location;
|
||||
|
||||
/** The type of comment that we've found. */
|
||||
pm_comment_type_t type;
|
||||
} pm_comment_t;
|
||||
|
||||
/**
|
||||
* This is a node in the linked list of magic comments that we've found while
|
||||
* parsing.
|
||||
*
|
||||
* @extends pm_list_node_t
|
||||
*/
|
||||
typedef struct {
|
||||
/** The embedded base node. */
|
||||
pm_list_node_t node;
|
||||
|
||||
/** A pointer to the start of the key in the source. */
|
||||
const uint8_t *key_start;
|
||||
|
||||
/** A pointer to the start of the value in the source. */
|
||||
const uint8_t *value_start;
|
||||
|
||||
/** The length of the key in the source. */
|
||||
uint32_t key_length;
|
||||
|
||||
/** The length of the value in the source. */
|
||||
uint32_t value_length;
|
||||
} pm_magic_comment_t;
|
||||
|
||||
/**
|
||||
* When the encoding that is being used to parse the source is changed by prism,
|
||||
* we provide the ability here to call out to a user-defined function.
|
||||
*/
|
||||
typedef void (*pm_encoding_changed_callback_t)(pm_parser_t *parser);
|
||||
|
||||
/**
|
||||
* When you are lexing through a file, the lexer needs all of the information
|
||||
* that the parser additionally provides (for example, the local table). So if
|
||||
* you want to properly lex Ruby, you need to actually lex it in the context of
|
||||
* the parser. In order to provide this functionality, we optionally allow a
|
||||
* struct to be attached to the parser that calls back out to a user-provided
|
||||
* callback when each token is lexed.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* This opaque pointer is used to provide whatever information the user
|
||||
* deemed necessary to the callback. In our case we use it to pass the array
|
||||
* that the tokens get appended into.
|
||||
*/
|
||||
void *data;
|
||||
|
||||
/**
|
||||
* This is the callback that is called when a token is lexed. It is passed
|
||||
* the opaque data pointer, the parser, and the token that was lexed.
|
||||
*/
|
||||
void (*callback)(void *data, pm_parser_t *parser, pm_token_t *token);
|
||||
} pm_lex_callback_t;
|
||||
|
||||
/** The type of shareable constant value that can be set. */
|
||||
typedef uint8_t pm_shareable_constant_value_t;
|
||||
static const pm_shareable_constant_value_t PM_SCOPE_SHAREABLE_CONSTANT_NONE = 0x0;
|
||||
static const pm_shareable_constant_value_t PM_SCOPE_SHAREABLE_CONSTANT_LITERAL = PM_SHAREABLE_CONSTANT_NODE_FLAGS_LITERAL;
|
||||
static const pm_shareable_constant_value_t PM_SCOPE_SHAREABLE_CONSTANT_EXPERIMENTAL_EVERYTHING = PM_SHAREABLE_CONSTANT_NODE_FLAGS_EXPERIMENTAL_EVERYTHING;
|
||||
static const pm_shareable_constant_value_t PM_SCOPE_SHAREABLE_CONSTANT_EXPERIMENTAL_COPY = PM_SHAREABLE_CONSTANT_NODE_FLAGS_EXPERIMENTAL_COPY;
|
||||
|
||||
/**
|
||||
* This tracks an individual local variable in a certain lexical context, as
|
||||
* well as the number of times is it read.
|
||||
*/
|
||||
typedef struct {
|
||||
/** The name of the local variable. */
|
||||
pm_constant_id_t name;
|
||||
|
||||
/** The location of the local variable in the source. */
|
||||
pm_location_t location;
|
||||
|
||||
/** The index of the local variable in the local table. */
|
||||
uint32_t index;
|
||||
|
||||
/** The number of times the local variable is read. */
|
||||
uint32_t reads;
|
||||
|
||||
/** The hash of the local variable. */
|
||||
uint32_t hash;
|
||||
} pm_local_t;
|
||||
|
||||
/**
|
||||
* This is a set of local variables in a certain lexical context (method, class,
|
||||
* module, etc.). We need to track how many times these variables are read in
|
||||
* order to warn if they only get written.
|
||||
*/
|
||||
typedef struct pm_locals {
|
||||
/** The number of local variables in the set. */
|
||||
uint32_t size;
|
||||
|
||||
/** The capacity of the local variables set. */
|
||||
uint32_t capacity;
|
||||
|
||||
/** The nullable allocated memory for the local variables in the set. */
|
||||
pm_local_t *locals;
|
||||
} pm_locals_t;
|
||||
|
||||
/** The flags about scope parameters that can be set. */
|
||||
typedef uint8_t pm_scope_parameters_t;
|
||||
static const pm_scope_parameters_t PM_SCOPE_PARAMETERS_NONE = 0x0;
|
||||
static const pm_scope_parameters_t PM_SCOPE_PARAMETERS_FORWARDING_POSITIONALS = 0x1;
|
||||
static const pm_scope_parameters_t PM_SCOPE_PARAMETERS_FORWARDING_KEYWORDS = 0x2;
|
||||
static const pm_scope_parameters_t PM_SCOPE_PARAMETERS_FORWARDING_BLOCK = 0x4;
|
||||
static const pm_scope_parameters_t PM_SCOPE_PARAMETERS_FORWARDING_ALL = 0x8;
|
||||
static const pm_scope_parameters_t PM_SCOPE_PARAMETERS_IMPLICIT_DISALLOWED = 0x10;
|
||||
static const pm_scope_parameters_t PM_SCOPE_PARAMETERS_NUMBERED_INNER = 0x20;
|
||||
static const pm_scope_parameters_t PM_SCOPE_PARAMETERS_NUMBERED_FOUND = 0x40;
|
||||
|
||||
/**
|
||||
* This struct represents a node in a linked list of scopes. Some scopes can see
|
||||
* into their parent scopes, while others cannot.
|
||||
*/
|
||||
typedef struct pm_scope {
|
||||
/** A pointer to the previous scope in the linked list. */
|
||||
struct pm_scope *previous;
|
||||
|
||||
/** The IDs of the locals in the given scope. */
|
||||
pm_locals_t locals;
|
||||
|
||||
/**
|
||||
* This is a list of the implicit parameters contained within the block.
|
||||
* These will be processed after the block is parsed to determine the kind
|
||||
* of parameters node that should be used and to check if any errors need to
|
||||
* be added.
|
||||
*/
|
||||
pm_node_list_t implicit_parameters;
|
||||
|
||||
/**
|
||||
* This is a bitfield that indicates the parameters that are being used in
|
||||
* this scope. It is a combination of the PM_SCOPE_PARAMETERS_* constants.
|
||||
* There are three different kinds of parameters that can be used in a
|
||||
* scope:
|
||||
*
|
||||
* - Ordinary parameters (e.g., def foo(bar); end)
|
||||
* - Numbered parameters (e.g., def foo; _1; end)
|
||||
* - The it parameter (e.g., def foo; it; end)
|
||||
*
|
||||
* If ordinary parameters are being used, then certain parameters can be
|
||||
* forwarded to another method/structure. Those are indicated by four
|
||||
* additional bits in the params field. For example, some combinations of:
|
||||
*
|
||||
* - def foo(*); end
|
||||
* - def foo(**); end
|
||||
* - def foo(&); end
|
||||
* - def foo(...); end
|
||||
*/
|
||||
pm_scope_parameters_t parameters;
|
||||
|
||||
/**
|
||||
* The current state of constant shareability for this scope. This is
|
||||
* changed by magic shareable_constant_value comments.
|
||||
*/
|
||||
pm_shareable_constant_value_t shareable_constant;
|
||||
|
||||
/**
|
||||
* A boolean indicating whether or not this scope can see into its parent.
|
||||
* If closed is true, then the scope cannot see into its parent.
|
||||
*/
|
||||
bool closed;
|
||||
} pm_scope_t;
|
||||
|
||||
/**
|
||||
* A struct that represents a stack of boolean values.
|
||||
*/
|
||||
typedef uint32_t pm_state_stack_t;
|
||||
|
||||
/**
|
||||
* This struct represents the overall parser. It contains a reference to the
|
||||
* source file, as well as pointers that indicate where in the source it's
|
||||
* currently parsing. It also contains the most recent and current token that
|
||||
* it's considering.
|
||||
*/
|
||||
struct pm_parser {
|
||||
/**
|
||||
* The next node identifier that will be assigned. This is a unique
|
||||
* identifier used to track nodes such that the syntax tree can be dropped
|
||||
* but the node can be found through another parse.
|
||||
*/
|
||||
uint32_t node_id;
|
||||
|
||||
/** The current state of the lexer. */
|
||||
pm_lex_state_t lex_state;
|
||||
|
||||
/** Tracks the current nesting of (), [], and {}. */
|
||||
int enclosure_nesting;
|
||||
|
||||
/**
|
||||
* Used to temporarily track the nesting of enclosures to determine if a {
|
||||
* is the beginning of a lambda following the parameters of a lambda.
|
||||
*/
|
||||
int lambda_enclosure_nesting;
|
||||
|
||||
/**
|
||||
* Used to track the nesting of braces to ensure we get the correct value
|
||||
* when we are interpolating blocks with braces.
|
||||
*/
|
||||
int brace_nesting;
|
||||
|
||||
/**
|
||||
* The stack used to determine if a do keyword belongs to the predicate of a
|
||||
* while, until, or for loop.
|
||||
*/
|
||||
pm_state_stack_t do_loop_stack;
|
||||
|
||||
/**
|
||||
* The stack used to determine if a do keyword belongs to the beginning of a
|
||||
* block.
|
||||
*/
|
||||
pm_state_stack_t accepts_block_stack;
|
||||
|
||||
/** A stack of lex modes. */
|
||||
struct {
|
||||
/** The current mode of the lexer. */
|
||||
pm_lex_mode_t *current;
|
||||
|
||||
/** The stack of lexer modes. */
|
||||
pm_lex_mode_t stack[PM_LEX_STACK_SIZE];
|
||||
|
||||
/** The current index into the lexer mode stack. */
|
||||
size_t index;
|
||||
} lex_modes;
|
||||
|
||||
/** The pointer to the start of the source. */
|
||||
const uint8_t *start;
|
||||
|
||||
/** The pointer to the end of the source. */
|
||||
const uint8_t *end;
|
||||
|
||||
/** The previous token we were considering. */
|
||||
pm_token_t previous;
|
||||
|
||||
/** The current token we're considering. */
|
||||
pm_token_t current;
|
||||
|
||||
/**
|
||||
* This is a special field set on the parser when we need the parser to jump
|
||||
* to a specific location when lexing the next token, as opposed to just
|
||||
* using the end of the previous token. Normally this is NULL.
|
||||
*/
|
||||
const uint8_t *next_start;
|
||||
|
||||
/**
|
||||
* This field indicates the end of a heredoc whose identifier was found on
|
||||
* the current line. If another heredoc is found on the same line, then this
|
||||
* will be moved forward to the end of that heredoc. If no heredocs are
|
||||
* found on a line then this is NULL.
|
||||
*/
|
||||
const uint8_t *heredoc_end;
|
||||
|
||||
/** The list of comments that have been found while parsing. */
|
||||
pm_list_t comment_list;
|
||||
|
||||
/** The list of magic comments that have been found while parsing. */
|
||||
pm_list_t magic_comment_list;
|
||||
|
||||
/**
|
||||
* An optional location that represents the location of the __END__ marker
|
||||
* and the rest of the content of the file. This content is loaded into the
|
||||
* DATA constant when the file being parsed is the main file being executed.
|
||||
*/
|
||||
pm_location_t data_loc;
|
||||
|
||||
/** The list of warnings that have been found while parsing. */
|
||||
pm_list_t warning_list;
|
||||
|
||||
/** The list of errors that have been found while parsing. */
|
||||
pm_list_t error_list;
|
||||
|
||||
/** The current local scope. */
|
||||
pm_scope_t *current_scope;
|
||||
|
||||
/** The current parsing context. */
|
||||
pm_context_node_t *current_context;
|
||||
|
||||
/**
|
||||
* The hash keys for the hash that is currently being parsed. This is not
|
||||
* usually necessary because it can pass it down the various call chains,
|
||||
* but in the event that you're parsing a hash that is being directly
|
||||
* pushed into another hash with **, we need to share the hash keys so that
|
||||
* we can warn for the nested hash as well.
|
||||
*/
|
||||
pm_static_literals_t *current_hash_keys;
|
||||
|
||||
/**
|
||||
* The encoding functions for the current file is attached to the parser as
|
||||
* it's parsing so that it can change with a magic comment.
|
||||
*/
|
||||
const pm_encoding_t *encoding;
|
||||
|
||||
/**
|
||||
* When the encoding that is being used to parse the source is changed by
|
||||
* prism, we provide the ability here to call out to a user-defined
|
||||
* function.
|
||||
*/
|
||||
pm_encoding_changed_callback_t encoding_changed_callback;
|
||||
|
||||
/**
|
||||
* This pointer indicates where a comment must start if it is to be
|
||||
* considered an encoding comment.
|
||||
*/
|
||||
const uint8_t *encoding_comment_start;
|
||||
|
||||
/**
|
||||
* This is an optional callback that can be attached to the parser that will
|
||||
* be called whenever a new token is lexed by the parser.
|
||||
*/
|
||||
pm_lex_callback_t *lex_callback;
|
||||
|
||||
/**
|
||||
* This is the path of the file being parsed. We use the filepath when
|
||||
* constructing SourceFileNodes.
|
||||
*/
|
||||
pm_string_t filepath;
|
||||
|
||||
/**
|
||||
* This constant pool keeps all of the constants defined throughout the file
|
||||
* so that we can reference them later.
|
||||
*/
|
||||
pm_constant_pool_t constant_pool;
|
||||
|
||||
/** This is the list of newline offsets in the source file. */
|
||||
pm_newline_list_t newline_list;
|
||||
|
||||
/**
|
||||
* We want to add a flag to integer nodes that indicates their base. We only
|
||||
* want to parse these once, but we don't have space on the token itself to
|
||||
* communicate this information. So we store it here and pass it through
|
||||
* when we find tokens that we need it for.
|
||||
*/
|
||||
pm_node_flags_t integer_base;
|
||||
|
||||
/**
|
||||
* This string is used to pass information from the lexer to the parser. It
|
||||
* is particularly necessary because of escape sequences.
|
||||
*/
|
||||
pm_string_t current_string;
|
||||
|
||||
/**
|
||||
* The line number at the start of the parse. This will be used to offset
|
||||
* the line numbers of all of the locations.
|
||||
*/
|
||||
int32_t start_line;
|
||||
|
||||
/**
|
||||
* When a string-like expression is being lexed, any byte or escape sequence
|
||||
* that resolves to a value whose top bit is set (i.e., >= 0x80) will
|
||||
* explicitly set the encoding to the same encoding as the source.
|
||||
* Alternatively, if a unicode escape sequence is used (e.g., \\u{80}) that
|
||||
* resolves to a value whose top bit is set, then the encoding will be
|
||||
* explicitly set to UTF-8.
|
||||
*
|
||||
* The _next_ time this happens, if the encoding that is about to become the
|
||||
* explicitly set encoding does not match the previously set explicit
|
||||
* encoding, a mixed encoding error will be emitted.
|
||||
*
|
||||
* When the expression is finished being lexed, the explicit encoding
|
||||
* controls the encoding of the expression. For the most part this means
|
||||
* that the expression will either be encoded in the source encoding or
|
||||
* UTF-8. This holds for all encodings except US-ASCII. If the source is
|
||||
* US-ASCII and an explicit encoding was set that was _not_ UTF-8, then the
|
||||
* expression will be encoded as ASCII-8BIT.
|
||||
*
|
||||
* Note that if the expression is a list, different elements within the same
|
||||
* list can have different encodings, so this will get reset between each
|
||||
* element. Furthermore all of this only applies to lists that support
|
||||
* interpolation, because otherwise escapes that could change the encoding
|
||||
* are ignored.
|
||||
*
|
||||
* At first glance, it may make more sense for this to live on the lexer
|
||||
* mode, but we need it here to communicate back to the parser for character
|
||||
* literals that do not push a new lexer mode.
|
||||
*/
|
||||
const pm_encoding_t *explicit_encoding;
|
||||
|
||||
/**
|
||||
* When parsing block exits (e.g., break, next, redo), we need to validate
|
||||
* that they are in correct contexts. For the most part we can do this by
|
||||
* looking at our parent contexts. However, modifier while and until
|
||||
* expressions can change that context to make block exits valid. In these
|
||||
* cases, we need to keep track of the block exits and then validate them
|
||||
* after the expression has been parsed.
|
||||
*
|
||||
* We use a pointer here because we don't want to keep a whole list attached
|
||||
* since this will only be used in the context of begin/end expressions.
|
||||
*/
|
||||
pm_node_list_t *current_block_exits;
|
||||
|
||||
/** The version of prism that we should use to parse. */
|
||||
pm_options_version_t version;
|
||||
|
||||
/** The command line flags given from the options. */
|
||||
uint8_t command_line;
|
||||
|
||||
/**
|
||||
* Whether or not we have found a frozen_string_literal magic comment with
|
||||
* a true or false value.
|
||||
* May be:
|
||||
* - PM_OPTIONS_FROZEN_STRING_LITERAL_DISABLED
|
||||
* - PM_OPTIONS_FROZEN_STRING_LITERAL_ENABLED
|
||||
* - PM_OPTIONS_FROZEN_STRING_LITERAL_UNSET
|
||||
*/
|
||||
int8_t frozen_string_literal;
|
||||
|
||||
/**
|
||||
* Whether or not we are parsing an eval string. This impacts whether or not
|
||||
* we should evaluate if block exits/yields are valid.
|
||||
*/
|
||||
bool parsing_eval;
|
||||
|
||||
/**
|
||||
* Whether or not we are parsing a "partial" script, which is a script that
|
||||
* will be evaluated in the context of another script, so we should not
|
||||
* check jumps (next/break/etc.) for validity.
|
||||
*/
|
||||
bool partial_script;
|
||||
|
||||
/** Whether or not we're at the beginning of a command. */
|
||||
bool command_start;
|
||||
|
||||
/** Whether or not we're currently recovering from a syntax error. */
|
||||
bool recovering;
|
||||
|
||||
/**
|
||||
* This is very specialized behavior for when you want to parse in a context
|
||||
* that does not respect encoding comments. Its main use case is translating
|
||||
* into the whitequark/parser AST which re-encodes source files in UTF-8
|
||||
* before they are parsed and ignores encoding comments.
|
||||
*/
|
||||
bool encoding_locked;
|
||||
|
||||
/**
|
||||
* Whether or not the encoding has been changed by a magic comment. We use
|
||||
* this to provide a fast path for the lexer instead of going through the
|
||||
* function pointer.
|
||||
*/
|
||||
bool encoding_changed;
|
||||
|
||||
/**
|
||||
* This flag indicates that we are currently parsing a pattern matching
|
||||
* expression and impacts that calculation of newlines.
|
||||
*/
|
||||
bool pattern_matching_newlines;
|
||||
|
||||
/** This flag indicates that we are currently parsing a keyword argument. */
|
||||
bool in_keyword_arg;
|
||||
|
||||
/**
|
||||
* Whether or not the parser has seen a token that has semantic meaning
|
||||
* (i.e., a token that is not a comment or whitespace).
|
||||
*/
|
||||
bool semantic_token_seen;
|
||||
|
||||
/**
|
||||
* True if the current regular expression being lexed contains only ASCII
|
||||
* characters.
|
||||
*/
|
||||
bool current_regular_expression_ascii_only;
|
||||
|
||||
/**
|
||||
* By default, Ruby always warns about mismatched indentation. This can be
|
||||
* toggled with a magic comment.
|
||||
*/
|
||||
bool warn_mismatched_indentation;
|
||||
};
|
||||
|
||||
#endif
|
||||
34
vendor/mruby-compiler2/lib/prism/include/prism/prettyprint.h
vendored
Normal file
34
vendor/mruby-compiler2/lib/prism/include/prism/prettyprint.h
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
* @file prettyprint.h
|
||||
*
|
||||
* An AST node pretty-printer.
|
||||
*/
|
||||
#ifndef PRISM_PRETTYPRINT_H
|
||||
#define PRISM_PRETTYPRINT_H
|
||||
|
||||
#include "prism/defines.h"
|
||||
|
||||
#ifdef PRISM_EXCLUDE_PRETTYPRINT
|
||||
|
||||
void pm_prettyprint(void);
|
||||
|
||||
#else
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "prism/ast.h"
|
||||
#include "prism/parser.h"
|
||||
#include "prism/util/pm_buffer.h"
|
||||
|
||||
/**
|
||||
* Pretty-prints the AST represented by the given node to the given buffer.
|
||||
*
|
||||
* @param output_buffer The buffer to write the pretty-printed AST to.
|
||||
* @param parser The parser that parsed the AST.
|
||||
* @param node The root node of the AST to pretty-print.
|
||||
*/
|
||||
PRISM_EXPORTED_FUNCTION void pm_prettyprint(pm_buffer_t *output_buffer, const pm_parser_t *parser, const pm_node_t *node);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
43
vendor/mruby-compiler2/lib/prism/include/prism/regexp.h
vendored
Normal file
43
vendor/mruby-compiler2/lib/prism/include/prism/regexp.h
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* @file regexp.h
|
||||
*
|
||||
* A regular expression parser.
|
||||
*/
|
||||
#ifndef PRISM_REGEXP_H
|
||||
#define PRISM_REGEXP_H
|
||||
|
||||
#include "prism/defines.h"
|
||||
#include "prism/parser.h"
|
||||
#include "prism/encoding.h"
|
||||
#include "prism/util/pm_memchr.h"
|
||||
#include "prism/util/pm_string.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
/**
|
||||
* This callback is called when a named capture group is found.
|
||||
*/
|
||||
typedef void (*pm_regexp_name_callback_t)(const pm_string_t *name, void *data);
|
||||
|
||||
/**
|
||||
* This callback is called when a parse error is found.
|
||||
*/
|
||||
typedef void (*pm_regexp_error_callback_t)(const uint8_t *start, const uint8_t *end, const char *message, void *data);
|
||||
|
||||
/**
|
||||
* Parse a regular expression.
|
||||
*
|
||||
* @param parser The parser that is currently being used.
|
||||
* @param source The source code to parse.
|
||||
* @param size The size of the source code.
|
||||
* @param extended_mode Whether to parse the regular expression in extended mode.
|
||||
* @param name_callback The optional callback to call when a named capture group is found.
|
||||
* @param name_data The optional data to pass to the name callback.
|
||||
* @param error_callback The callback to call when a parse error is found.
|
||||
* @param error_data The data to pass to the error callback.
|
||||
*/
|
||||
PRISM_EXPORTED_FUNCTION void pm_regexp_parse(pm_parser_t *parser, const uint8_t *source, size_t size, bool extended_mode, pm_regexp_name_callback_t name_callback, void *name_data, pm_regexp_error_callback_t error_callback, void *error_data);
|
||||
|
||||
#endif
|
||||
121
vendor/mruby-compiler2/lib/prism/include/prism/static_literals.h
vendored
Normal file
121
vendor/mruby-compiler2/lib/prism/include/prism/static_literals.h
vendored
Normal file
@@ -0,0 +1,121 @@
|
||||
/**
|
||||
* @file static_literals.h
|
||||
*
|
||||
* A set of static literal nodes that can be checked for duplicates.
|
||||
*/
|
||||
#ifndef PRISM_STATIC_LITERALS_H
|
||||
#define PRISM_STATIC_LITERALS_H
|
||||
|
||||
#include "prism/defines.h"
|
||||
#include "prism/ast.h"
|
||||
#include "prism/util/pm_newline_list.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/**
|
||||
* An internal hash table for a set of nodes.
|
||||
*/
|
||||
typedef struct {
|
||||
/** The array of nodes in the hash table. */
|
||||
pm_node_t **nodes;
|
||||
|
||||
/** The size of the hash table. */
|
||||
uint32_t size;
|
||||
|
||||
/** The space that has been allocated in the hash table. */
|
||||
uint32_t capacity;
|
||||
} pm_node_hash_t;
|
||||
|
||||
/**
|
||||
* Certain sets of nodes (hash keys and when clauses) check for duplicate nodes
|
||||
* to alert the user of potential issues. To do this, we keep a set of the nodes
|
||||
* that have been seen so far, and compare whenever we find a new node.
|
||||
*
|
||||
* We bucket the nodes based on their type to minimize the number of comparisons
|
||||
* that need to be performed.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* This is the set of IntegerNode and SourceLineNode instances.
|
||||
*/
|
||||
pm_node_hash_t integer_nodes;
|
||||
|
||||
/**
|
||||
* This is the set of FloatNode instances.
|
||||
*/
|
||||
pm_node_hash_t float_nodes;
|
||||
|
||||
/**
|
||||
* This is the set of RationalNode and ImaginaryNode instances.
|
||||
*/
|
||||
pm_node_hash_t number_nodes;
|
||||
|
||||
/**
|
||||
* This is the set of StringNode and SourceFileNode instances.
|
||||
*/
|
||||
pm_node_hash_t string_nodes;
|
||||
|
||||
/**
|
||||
* This is the set of RegularExpressionNode instances.
|
||||
*/
|
||||
pm_node_hash_t regexp_nodes;
|
||||
|
||||
/**
|
||||
* This is the set of SymbolNode instances.
|
||||
*/
|
||||
pm_node_hash_t symbol_nodes;
|
||||
|
||||
/**
|
||||
* A pointer to the last TrueNode instance that was inserted, or NULL.
|
||||
*/
|
||||
pm_node_t *true_node;
|
||||
|
||||
/**
|
||||
* A pointer to the last FalseNode instance that was inserted, or NULL.
|
||||
*/
|
||||
pm_node_t *false_node;
|
||||
|
||||
/**
|
||||
* A pointer to the last NilNode instance that was inserted, or NULL.
|
||||
*/
|
||||
pm_node_t *nil_node;
|
||||
|
||||
/**
|
||||
* A pointer to the last SourceEncodingNode instance that was inserted, or
|
||||
* NULL.
|
||||
*/
|
||||
pm_node_t *source_encoding_node;
|
||||
} pm_static_literals_t;
|
||||
|
||||
/**
|
||||
* Add a node to the set of static literals.
|
||||
*
|
||||
* @param newline_list The list of newline offsets to use to calculate lines.
|
||||
* @param start_line The line number that the parser starts on.
|
||||
* @param literals The set of static literals to add the node to.
|
||||
* @param node The node to add to the set.
|
||||
* @param replace Whether to replace the previous node if one already exists.
|
||||
* @return A pointer to the node that is being overwritten, if there is one.
|
||||
*/
|
||||
pm_node_t * pm_static_literals_add(const pm_newline_list_t *newline_list, int32_t start_line, pm_static_literals_t *literals, pm_node_t *node, bool replace);
|
||||
|
||||
/**
|
||||
* Free the internal memory associated with the given static literals set.
|
||||
*
|
||||
* @param literals The set of static literals to free.
|
||||
*/
|
||||
void pm_static_literals_free(pm_static_literals_t *literals);
|
||||
|
||||
/**
|
||||
* Create a string-based representation of the given static literal.
|
||||
*
|
||||
* @param buffer The buffer to write the string to.
|
||||
* @param newline_list The list of newline offsets to use to calculate lines.
|
||||
* @param start_line The line number that the parser starts on.
|
||||
* @param encoding_name The name of the encoding of the source being parsed.
|
||||
* @param node The node to create a string representation of.
|
||||
*/
|
||||
void pm_static_literal_inspect(pm_buffer_t *buffer, const pm_newline_list_t *newline_list, int32_t start_line, const char *encoding_name, const pm_node_t *node);
|
||||
|
||||
#endif
|
||||
228
vendor/mruby-compiler2/lib/prism/include/prism/util/pm_buffer.h
vendored
Normal file
228
vendor/mruby-compiler2/lib/prism/include/prism/util/pm_buffer.h
vendored
Normal file
@@ -0,0 +1,228 @@
|
||||
/**
|
||||
* @file pm_buffer.h
|
||||
*
|
||||
* A wrapper around a contiguous block of allocated memory.
|
||||
*/
|
||||
#ifndef PRISM_BUFFER_H
|
||||
#define PRISM_BUFFER_H
|
||||
|
||||
#include "prism/defines.h"
|
||||
#include "prism/util/pm_char.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/**
|
||||
* A pm_buffer_t is a simple memory buffer that stores data in a contiguous
|
||||
* block of memory.
|
||||
*/
|
||||
typedef struct {
|
||||
/** The length of the buffer in bytes. */
|
||||
size_t length;
|
||||
|
||||
/** The capacity of the buffer in bytes that has been allocated. */
|
||||
size_t capacity;
|
||||
|
||||
/** A pointer to the start of the buffer. */
|
||||
char *value;
|
||||
} pm_buffer_t;
|
||||
|
||||
/**
|
||||
* Return the size of the pm_buffer_t struct.
|
||||
*
|
||||
* @returns The size of the pm_buffer_t struct.
|
||||
*/
|
||||
PRISM_EXPORTED_FUNCTION size_t pm_buffer_sizeof(void);
|
||||
|
||||
/**
|
||||
* Initialize a pm_buffer_t with the given capacity.
|
||||
*
|
||||
* @param buffer The buffer to initialize.
|
||||
* @param capacity The capacity of the buffer.
|
||||
* @returns True if the buffer was initialized successfully, false otherwise.
|
||||
*/
|
||||
bool pm_buffer_init_capacity(pm_buffer_t *buffer, size_t capacity);
|
||||
|
||||
/**
|
||||
* Initialize a pm_buffer_t with its default values.
|
||||
*
|
||||
* @param buffer The buffer to initialize.
|
||||
* @returns True if the buffer was initialized successfully, false otherwise.
|
||||
*/
|
||||
PRISM_EXPORTED_FUNCTION bool pm_buffer_init(pm_buffer_t *buffer);
|
||||
|
||||
/**
|
||||
* Return the value of the buffer.
|
||||
*
|
||||
* @param buffer The buffer to get the value of.
|
||||
* @returns The value of the buffer.
|
||||
*/
|
||||
PRISM_EXPORTED_FUNCTION char * pm_buffer_value(const pm_buffer_t *buffer);
|
||||
|
||||
/**
|
||||
* Return the length of the buffer.
|
||||
*
|
||||
* @param buffer The buffer to get the length of.
|
||||
* @returns The length of the buffer.
|
||||
*/
|
||||
PRISM_EXPORTED_FUNCTION size_t pm_buffer_length(const pm_buffer_t *buffer);
|
||||
|
||||
/**
|
||||
* Append the given amount of space as zeroes to the buffer.
|
||||
*
|
||||
* @param buffer The buffer to append to.
|
||||
* @param length The amount of space to append and zero.
|
||||
*/
|
||||
void pm_buffer_append_zeroes(pm_buffer_t *buffer, size_t length);
|
||||
|
||||
/**
|
||||
* Append a formatted string to the buffer.
|
||||
*
|
||||
* @param buffer The buffer to append to.
|
||||
* @param format The format string to append.
|
||||
* @param ... The arguments to the format string.
|
||||
*/
|
||||
void pm_buffer_append_format(pm_buffer_t *buffer, const char *format, ...) PRISM_ATTRIBUTE_FORMAT(2, 3);
|
||||
|
||||
/**
|
||||
* Append a string to the buffer.
|
||||
*
|
||||
* @param buffer The buffer to append to.
|
||||
* @param value The string to append.
|
||||
* @param length The length of the string to append.
|
||||
*/
|
||||
void pm_buffer_append_string(pm_buffer_t *buffer, const char *value, size_t length);
|
||||
|
||||
/**
|
||||
* Append a list of bytes to the buffer.
|
||||
*
|
||||
* @param buffer The buffer to append to.
|
||||
* @param value The bytes to append.
|
||||
* @param length The length of the bytes to append.
|
||||
*/
|
||||
void pm_buffer_append_bytes(pm_buffer_t *buffer, const uint8_t *value, size_t length);
|
||||
|
||||
/**
|
||||
* Append a single byte to the buffer.
|
||||
*
|
||||
* @param buffer The buffer to append to.
|
||||
* @param value The byte to append.
|
||||
*/
|
||||
void pm_buffer_append_byte(pm_buffer_t *buffer, uint8_t value);
|
||||
|
||||
/**
|
||||
* Append a 32-bit unsigned integer to the buffer as a variable-length integer.
|
||||
*
|
||||
* @param buffer The buffer to append to.
|
||||
* @param value The integer to append.
|
||||
*/
|
||||
void pm_buffer_append_varuint(pm_buffer_t *buffer, uint32_t value);
|
||||
|
||||
/**
|
||||
* Append a 32-bit signed integer to the buffer as a variable-length integer.
|
||||
*
|
||||
* @param buffer The buffer to append to.
|
||||
* @param value The integer to append.
|
||||
*/
|
||||
void pm_buffer_append_varsint(pm_buffer_t *buffer, int32_t value);
|
||||
|
||||
/**
|
||||
* Append a double to the buffer.
|
||||
*
|
||||
* @param buffer The buffer to append to.
|
||||
* @param value The double to append.
|
||||
*/
|
||||
void pm_buffer_append_double(pm_buffer_t *buffer, double value);
|
||||
|
||||
/**
|
||||
* Append a unicode codepoint to the buffer.
|
||||
*
|
||||
* @param buffer The buffer to append to.
|
||||
* @param value The character to append.
|
||||
* @returns True if the codepoint was valid and appended successfully, false
|
||||
* otherwise.
|
||||
*/
|
||||
bool pm_buffer_append_unicode_codepoint(pm_buffer_t *buffer, uint32_t value);
|
||||
|
||||
/**
|
||||
* The different types of escaping that can be performed by the buffer when
|
||||
* appending a slice of Ruby source code.
|
||||
*/
|
||||
typedef enum {
|
||||
PM_BUFFER_ESCAPING_RUBY,
|
||||
PM_BUFFER_ESCAPING_JSON
|
||||
} pm_buffer_escaping_t;
|
||||
|
||||
/**
|
||||
* Append a slice of source code to the buffer.
|
||||
*
|
||||
* @param buffer The buffer to append to.
|
||||
* @param source The source code to append.
|
||||
* @param length The length of the source code to append.
|
||||
* @param escaping The type of escaping to perform.
|
||||
*/
|
||||
void pm_buffer_append_source(pm_buffer_t *buffer, const uint8_t *source, size_t length, pm_buffer_escaping_t escaping);
|
||||
|
||||
/**
|
||||
* Prepend the given string to the buffer.
|
||||
*
|
||||
* @param buffer The buffer to prepend to.
|
||||
* @param value The string to prepend.
|
||||
* @param length The length of the string to prepend.
|
||||
*/
|
||||
void pm_buffer_prepend_string(pm_buffer_t *buffer, const char *value, size_t length);
|
||||
|
||||
/**
|
||||
* Concatenate one buffer onto another.
|
||||
*
|
||||
* @param destination The buffer to concatenate onto.
|
||||
* @param source The buffer to concatenate.
|
||||
*/
|
||||
void pm_buffer_concat(pm_buffer_t *destination, const pm_buffer_t *source);
|
||||
|
||||
/**
|
||||
* Clear the buffer by reducing its size to 0. This does not free the allocated
|
||||
* memory, but it does allow the buffer to be reused.
|
||||
*
|
||||
* @param buffer The buffer to clear.
|
||||
*/
|
||||
void pm_buffer_clear(pm_buffer_t *buffer);
|
||||
|
||||
/**
|
||||
* Strip the whitespace from the end of the buffer.
|
||||
*
|
||||
* @param buffer The buffer to strip.
|
||||
*/
|
||||
void pm_buffer_rstrip(pm_buffer_t *buffer);
|
||||
|
||||
/**
|
||||
* Checks if the buffer includes the given value.
|
||||
*
|
||||
* @param buffer The buffer to check.
|
||||
* @param value The value to check for.
|
||||
* @returns The index of the first occurrence of the value in the buffer, or
|
||||
* SIZE_MAX if the value is not found.
|
||||
*/
|
||||
size_t pm_buffer_index(const pm_buffer_t *buffer, char value);
|
||||
|
||||
/**
|
||||
* Insert the given string into the buffer at the given index.
|
||||
*
|
||||
* @param buffer The buffer to insert into.
|
||||
* @param index The index to insert at.
|
||||
* @param value The string to insert.
|
||||
* @param length The length of the string to insert.
|
||||
*/
|
||||
void pm_buffer_insert(pm_buffer_t *buffer, size_t index, const char *value, size_t length);
|
||||
|
||||
/**
|
||||
* Free the memory associated with the buffer.
|
||||
*
|
||||
* @param buffer The buffer to free.
|
||||
*/
|
||||
PRISM_EXPORTED_FUNCTION void pm_buffer_free(pm_buffer_t *buffer);
|
||||
|
||||
#endif
|
||||
204
vendor/mruby-compiler2/lib/prism/include/prism/util/pm_char.h
vendored
Normal file
204
vendor/mruby-compiler2/lib/prism/include/prism/util/pm_char.h
vendored
Normal file
@@ -0,0 +1,204 @@
|
||||
/**
|
||||
* @file pm_char.h
|
||||
*
|
||||
* Functions for working with characters and strings.
|
||||
*/
|
||||
#ifndef PRISM_CHAR_H
|
||||
#define PRISM_CHAR_H
|
||||
|
||||
#include "prism/defines.h"
|
||||
#include "prism/util/pm_newline_list.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
/**
|
||||
* Returns the number of characters at the start of the string that are
|
||||
* whitespace. Disallows searching past the given maximum number of characters.
|
||||
*
|
||||
* @param string The string to search.
|
||||
* @param length The maximum number of characters to search.
|
||||
* @return The number of characters at the start of the string that are
|
||||
* whitespace.
|
||||
*/
|
||||
size_t pm_strspn_whitespace(const uint8_t *string, ptrdiff_t length);
|
||||
|
||||
/**
|
||||
* Returns the number of characters at the start of the string that are
|
||||
* whitespace while also tracking the location of each newline. Disallows
|
||||
* searching past the given maximum number of characters.
|
||||
*
|
||||
* @param string The string to search.
|
||||
* @param length The maximum number of characters to search.
|
||||
* @param newline_list The list of newlines to populate.
|
||||
* @return The number of characters at the start of the string that are
|
||||
* whitespace.
|
||||
*/
|
||||
size_t pm_strspn_whitespace_newlines(const uint8_t *string, ptrdiff_t length, pm_newline_list_t *newline_list);
|
||||
|
||||
/**
|
||||
* Returns the number of characters at the start of the string that are inline
|
||||
* whitespace. Disallows searching past the given maximum number of characters.
|
||||
*
|
||||
* @param string The string to search.
|
||||
* @param length The maximum number of characters to search.
|
||||
* @return The number of characters at the start of the string that are inline
|
||||
* whitespace.
|
||||
*/
|
||||
size_t pm_strspn_inline_whitespace(const uint8_t *string, ptrdiff_t length);
|
||||
|
||||
/**
|
||||
* Returns the number of characters at the start of the string that are decimal
|
||||
* digits. Disallows searching past the given maximum number of characters.
|
||||
*
|
||||
* @param string The string to search.
|
||||
* @param length The maximum number of characters to search.
|
||||
* @return The number of characters at the start of the string that are decimal
|
||||
* digits.
|
||||
*/
|
||||
size_t pm_strspn_decimal_digit(const uint8_t *string, ptrdiff_t length);
|
||||
|
||||
/**
|
||||
* Returns the number of characters at the start of the string that are
|
||||
* hexadecimal digits. Disallows searching past the given maximum number of
|
||||
* characters.
|
||||
*
|
||||
* @param string The string to search.
|
||||
* @param length The maximum number of characters to search.
|
||||
* @return The number of characters at the start of the string that are
|
||||
* hexadecimal digits.
|
||||
*/
|
||||
size_t pm_strspn_hexadecimal_digit(const uint8_t *string, ptrdiff_t length);
|
||||
|
||||
/**
|
||||
* Returns the number of characters at the start of the string that are octal
|
||||
* digits or underscores. Disallows searching past the given maximum number of
|
||||
* characters.
|
||||
*
|
||||
* If multiple underscores are found in a row or if an underscore is
|
||||
* found at the end of the number, then the invalid pointer is set to the index
|
||||
* of the first invalid underscore.
|
||||
*
|
||||
* @param string The string to search.
|
||||
* @param length The maximum number of characters to search.
|
||||
* @param invalid The pointer to set to the index of the first invalid
|
||||
* underscore.
|
||||
* @return The number of characters at the start of the string that are octal
|
||||
* digits or underscores.
|
||||
*/
|
||||
size_t pm_strspn_octal_number(const uint8_t *string, ptrdiff_t length, const uint8_t **invalid);
|
||||
|
||||
/**
|
||||
* Returns the number of characters at the start of the string that are decimal
|
||||
* digits or underscores. Disallows searching past the given maximum number of
|
||||
* characters.
|
||||
*
|
||||
* If multiple underscores are found in a row or if an underscore is
|
||||
* found at the end of the number, then the invalid pointer is set to the index
|
||||
* of the first invalid underscore.
|
||||
*
|
||||
* @param string The string to search.
|
||||
* @param length The maximum number of characters to search.
|
||||
* @param invalid The pointer to set to the index of the first invalid
|
||||
* underscore.
|
||||
* @return The number of characters at the start of the string that are decimal
|
||||
* digits or underscores.
|
||||
*/
|
||||
size_t pm_strspn_decimal_number(const uint8_t *string, ptrdiff_t length, const uint8_t **invalid);
|
||||
|
||||
/**
|
||||
* Returns the number of characters at the start of the string that are
|
||||
* hexadecimal digits or underscores. Disallows searching past the given maximum
|
||||
* number of characters.
|
||||
*
|
||||
* If multiple underscores are found in a row or if an underscore is
|
||||
* found at the end of the number, then the invalid pointer is set to the index
|
||||
* of the first invalid underscore.
|
||||
*
|
||||
* @param string The string to search.
|
||||
* @param length The maximum number of characters to search.
|
||||
* @param invalid The pointer to set to the index of the first invalid
|
||||
* underscore.
|
||||
* @return The number of characters at the start of the string that are
|
||||
* hexadecimal digits or underscores.
|
||||
*/
|
||||
size_t pm_strspn_hexadecimal_number(const uint8_t *string, ptrdiff_t length, const uint8_t **invalid);
|
||||
|
||||
/**
|
||||
* Returns the number of characters at the start of the string that are regexp
|
||||
* options. Disallows searching past the given maximum number of characters.
|
||||
*
|
||||
* @param string The string to search.
|
||||
* @param length The maximum number of characters to search.
|
||||
* @return The number of characters at the start of the string that are regexp
|
||||
* options.
|
||||
*/
|
||||
size_t pm_strspn_regexp_option(const uint8_t *string, ptrdiff_t length);
|
||||
|
||||
/**
|
||||
* Returns the number of characters at the start of the string that are binary
|
||||
* digits or underscores. Disallows searching past the given maximum number of
|
||||
* characters.
|
||||
*
|
||||
* If multiple underscores are found in a row or if an underscore is
|
||||
* found at the end of the number, then the invalid pointer is set to the index
|
||||
* of the first invalid underscore.
|
||||
*
|
||||
* @param string The string to search.
|
||||
* @param length The maximum number of characters to search.
|
||||
* @param invalid The pointer to set to the index of the first invalid
|
||||
* underscore.
|
||||
* @return The number of characters at the start of the string that are binary
|
||||
* digits or underscores.
|
||||
*/
|
||||
size_t pm_strspn_binary_number(const uint8_t *string, ptrdiff_t length, const uint8_t **invalid);
|
||||
|
||||
/**
|
||||
* Returns true if the given character is a whitespace character.
|
||||
*
|
||||
* @param b The character to check.
|
||||
* @return True if the given character is a whitespace character.
|
||||
*/
|
||||
bool pm_char_is_whitespace(const uint8_t b);
|
||||
|
||||
/**
|
||||
* Returns true if the given character is an inline whitespace character.
|
||||
*
|
||||
* @param b The character to check.
|
||||
* @return True if the given character is an inline whitespace character.
|
||||
*/
|
||||
bool pm_char_is_inline_whitespace(const uint8_t b);
|
||||
|
||||
/**
|
||||
* Returns true if the given character is a binary digit.
|
||||
*
|
||||
* @param b The character to check.
|
||||
* @return True if the given character is a binary digit.
|
||||
*/
|
||||
bool pm_char_is_binary_digit(const uint8_t b);
|
||||
|
||||
/**
|
||||
* Returns true if the given character is an octal digit.
|
||||
*
|
||||
* @param b The character to check.
|
||||
* @return True if the given character is an octal digit.
|
||||
*/
|
||||
bool pm_char_is_octal_digit(const uint8_t b);
|
||||
|
||||
/**
|
||||
* Returns true if the given character is a decimal digit.
|
||||
*
|
||||
* @param b The character to check.
|
||||
* @return True if the given character is a decimal digit.
|
||||
*/
|
||||
bool pm_char_is_decimal_digit(const uint8_t b);
|
||||
|
||||
/**
|
||||
* Returns true if the given character is a hexadecimal digit.
|
||||
*
|
||||
* @param b The character to check.
|
||||
* @return True if the given character is a hexadecimal digit.
|
||||
*/
|
||||
bool pm_char_is_hexadecimal_digit(const uint8_t b);
|
||||
|
||||
#endif
|
||||
218
vendor/mruby-compiler2/lib/prism/include/prism/util/pm_constant_pool.h
vendored
Normal file
218
vendor/mruby-compiler2/lib/prism/include/prism/util/pm_constant_pool.h
vendored
Normal file
@@ -0,0 +1,218 @@
|
||||
/**
|
||||
* @file pm_constant_pool.h
|
||||
*
|
||||
* A data structure that stores a set of strings.
|
||||
*
|
||||
* Each string is assigned a unique id, which can be used to compare strings for
|
||||
* equality. This comparison ends up being much faster than strcmp, since it
|
||||
* only requires a single integer comparison.
|
||||
*/
|
||||
#ifndef PRISM_CONSTANT_POOL_H
|
||||
#define PRISM_CONSTANT_POOL_H
|
||||
|
||||
#include "prism/defines.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/**
|
||||
* When we allocate constants into the pool, we reserve 0 to mean that the slot
|
||||
* is not yet filled. This constant is reused in other places to indicate the
|
||||
* lack of a constant id.
|
||||
*/
|
||||
#define PM_CONSTANT_ID_UNSET 0
|
||||
|
||||
/**
|
||||
* A constant id is a unique identifier for a constant in the constant pool.
|
||||
*/
|
||||
typedef uint32_t pm_constant_id_t;
|
||||
|
||||
/**
|
||||
* A list of constant IDs. Usually used to represent a set of locals.
|
||||
*/
|
||||
typedef struct {
|
||||
/** The number of constant ids in the list. */
|
||||
size_t size;
|
||||
|
||||
/** The number of constant ids that have been allocated in the list. */
|
||||
size_t capacity;
|
||||
|
||||
/** The constant ids in the list. */
|
||||
pm_constant_id_t *ids;
|
||||
} pm_constant_id_list_t;
|
||||
|
||||
/**
|
||||
* Initialize a list of constant ids.
|
||||
*
|
||||
* @param list The list to initialize.
|
||||
*/
|
||||
void pm_constant_id_list_init(pm_constant_id_list_t *list);
|
||||
|
||||
/**
|
||||
* Initialize a list of constant ids with a given capacity.
|
||||
*
|
||||
* @param list The list to initialize.
|
||||
* @param capacity The initial capacity of the list.
|
||||
*/
|
||||
void pm_constant_id_list_init_capacity(pm_constant_id_list_t *list, size_t capacity);
|
||||
|
||||
/**
|
||||
* Append a constant id to a list of constant ids. Returns false if any
|
||||
* potential reallocations fail.
|
||||
*
|
||||
* @param list The list to append to.
|
||||
* @param id The id to append.
|
||||
* @return Whether the append succeeded.
|
||||
*/
|
||||
bool pm_constant_id_list_append(pm_constant_id_list_t *list, pm_constant_id_t id);
|
||||
|
||||
/**
|
||||
* Insert a constant id into a list of constant ids at the specified index.
|
||||
*
|
||||
* @param list The list to insert into.
|
||||
* @param index The index at which to insert.
|
||||
* @param id The id to insert.
|
||||
*/
|
||||
void pm_constant_id_list_insert(pm_constant_id_list_t *list, size_t index, pm_constant_id_t id);
|
||||
|
||||
/**
|
||||
* Checks if the current constant id list includes the given constant id.
|
||||
*
|
||||
* @param list The list to check.
|
||||
* @param id The id to check for.
|
||||
* @return Whether the list includes the given id.
|
||||
*/
|
||||
bool pm_constant_id_list_includes(pm_constant_id_list_t *list, pm_constant_id_t id);
|
||||
|
||||
/**
|
||||
* Free the memory associated with a list of constant ids.
|
||||
*
|
||||
* @param list The list to free.
|
||||
*/
|
||||
void pm_constant_id_list_free(pm_constant_id_list_t *list);
|
||||
|
||||
/**
|
||||
* The type of bucket in the constant pool hash map. This determines how the
|
||||
* bucket should be freed.
|
||||
*/
|
||||
typedef unsigned int pm_constant_pool_bucket_type_t;
|
||||
|
||||
/** By default, each constant is a slice of the source. */
|
||||
static const pm_constant_pool_bucket_type_t PM_CONSTANT_POOL_BUCKET_DEFAULT = 0;
|
||||
|
||||
/** An owned constant is one for which memory has been allocated. */
|
||||
static const pm_constant_pool_bucket_type_t PM_CONSTANT_POOL_BUCKET_OWNED = 1;
|
||||
|
||||
/** A constant constant is known at compile time. */
|
||||
static const pm_constant_pool_bucket_type_t PM_CONSTANT_POOL_BUCKET_CONSTANT = 2;
|
||||
|
||||
/** A bucket in the hash map. */
|
||||
typedef struct {
|
||||
/** The incremental ID used for indexing back into the pool. */
|
||||
unsigned int id: 30;
|
||||
|
||||
/** The type of the bucket, which determines how to free it. */
|
||||
pm_constant_pool_bucket_type_t type: 2;
|
||||
|
||||
/** The hash of the bucket. */
|
||||
uint32_t hash;
|
||||
} pm_constant_pool_bucket_t;
|
||||
|
||||
/** A constant in the pool which effectively stores a string. */
|
||||
typedef struct {
|
||||
/** A pointer to the start of the string. */
|
||||
const uint8_t *start;
|
||||
|
||||
/** The length of the string. */
|
||||
size_t length;
|
||||
} pm_constant_t;
|
||||
|
||||
/** The overall constant pool, which stores constants found while parsing. */
|
||||
typedef struct {
|
||||
/** The buckets in the hash map. */
|
||||
pm_constant_pool_bucket_t *buckets;
|
||||
|
||||
/** The constants that are stored in the buckets. */
|
||||
pm_constant_t *constants;
|
||||
|
||||
/** The number of buckets in the hash map. */
|
||||
uint32_t size;
|
||||
|
||||
/** The number of buckets that have been allocated in the hash map. */
|
||||
uint32_t capacity;
|
||||
} pm_constant_pool_t;
|
||||
|
||||
/**
|
||||
* Initialize a new constant pool with a given capacity.
|
||||
*
|
||||
* @param pool The pool to initialize.
|
||||
* @param capacity The initial capacity of the pool.
|
||||
* @return Whether the initialization succeeded.
|
||||
*/
|
||||
bool pm_constant_pool_init(pm_constant_pool_t *pool, uint32_t capacity);
|
||||
|
||||
/**
|
||||
* Return a pointer to the constant indicated by the given constant id.
|
||||
*
|
||||
* @param pool The pool to get the constant from.
|
||||
* @param constant_id The id of the constant to get.
|
||||
* @return A pointer to the constant.
|
||||
*/
|
||||
pm_constant_t * pm_constant_pool_id_to_constant(const pm_constant_pool_t *pool, pm_constant_id_t constant_id);
|
||||
|
||||
/**
|
||||
* Find a constant in a constant pool. Returns the id of the constant, or 0 if
|
||||
* the constant is not found.
|
||||
*
|
||||
* @param pool The pool to find the constant in.
|
||||
* @param start A pointer to the start of the constant.
|
||||
* @param length The length of the constant.
|
||||
* @return The id of the constant.
|
||||
*/
|
||||
pm_constant_id_t pm_constant_pool_find(const pm_constant_pool_t *pool, const uint8_t *start, size_t length);
|
||||
|
||||
/**
|
||||
* Insert a constant into a constant pool that is a slice of a source string.
|
||||
* Returns the id of the constant, or 0 if any potential calls to resize fail.
|
||||
*
|
||||
* @param pool The pool to insert the constant into.
|
||||
* @param start A pointer to the start of the constant.
|
||||
* @param length The length of the constant.
|
||||
* @return The id of the constant.
|
||||
*/
|
||||
pm_constant_id_t pm_constant_pool_insert_shared(pm_constant_pool_t *pool, const uint8_t *start, size_t length);
|
||||
|
||||
/**
|
||||
* Insert a constant into a constant pool from memory that is now owned by the
|
||||
* constant pool. Returns the id of the constant, or 0 if any potential calls to
|
||||
* resize fail.
|
||||
*
|
||||
* @param pool The pool to insert the constant into.
|
||||
* @param start A pointer to the start of the constant.
|
||||
* @param length The length of the constant.
|
||||
* @return The id of the constant.
|
||||
*/
|
||||
pm_constant_id_t pm_constant_pool_insert_owned(pm_constant_pool_t *pool, uint8_t *start, size_t length);
|
||||
|
||||
/**
|
||||
* Insert a constant into a constant pool from memory that is constant. Returns
|
||||
* the id of the constant, or 0 if any potential calls to resize fail.
|
||||
*
|
||||
* @param pool The pool to insert the constant into.
|
||||
* @param start A pointer to the start of the constant.
|
||||
* @param length The length of the constant.
|
||||
* @return The id of the constant.
|
||||
*/
|
||||
pm_constant_id_t pm_constant_pool_insert_constant(pm_constant_pool_t *pool, const uint8_t *start, size_t length);
|
||||
|
||||
/**
|
||||
* Free the memory associated with a constant pool.
|
||||
*
|
||||
* @param pool The pool to free.
|
||||
*/
|
||||
void pm_constant_pool_free(pm_constant_pool_t *pool);
|
||||
|
||||
#endif
|
||||
126
vendor/mruby-compiler2/lib/prism/include/prism/util/pm_integer.h
vendored
Normal file
126
vendor/mruby-compiler2/lib/prism/include/prism/util/pm_integer.h
vendored
Normal file
@@ -0,0 +1,126 @@
|
||||
/**
|
||||
* @file pm_integer.h
|
||||
*
|
||||
* This module provides functions for working with arbitrary-sized integers.
|
||||
*/
|
||||
#ifndef PRISM_NUMBER_H
|
||||
#define PRISM_NUMBER_H
|
||||
|
||||
#include "prism/defines.h"
|
||||
#include "prism/util/pm_buffer.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/**
|
||||
* A structure represents an arbitrary-sized integer.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* The number of allocated values. length is set to 0 if the integer fits
|
||||
* into uint32_t.
|
||||
*/
|
||||
size_t length;
|
||||
|
||||
/**
|
||||
* List of 32-bit integers. Set to NULL if the integer fits into uint32_t.
|
||||
*/
|
||||
uint32_t *values;
|
||||
|
||||
/**
|
||||
* Embedded value for small integer. This value is set to 0 if the value
|
||||
* does not fit into uint32_t.
|
||||
*/
|
||||
uint32_t value;
|
||||
|
||||
/**
|
||||
* Whether or not the integer is negative. It is stored this way so that a
|
||||
* zeroed pm_integer_t is always positive zero.
|
||||
*/
|
||||
bool negative;
|
||||
} pm_integer_t;
|
||||
|
||||
/**
|
||||
* An enum controlling the base of an integer. It is expected that the base is
|
||||
* already known before parsing the integer, even though it could be derived
|
||||
* from the string itself.
|
||||
*/
|
||||
typedef enum {
|
||||
/** The default decimal base, with no prefix. Leading 0s will be ignored. */
|
||||
PM_INTEGER_BASE_DEFAULT,
|
||||
|
||||
/** The binary base, indicated by a 0b or 0B prefix. */
|
||||
PM_INTEGER_BASE_BINARY,
|
||||
|
||||
/** The octal base, indicated by a 0, 0o, or 0O prefix. */
|
||||
PM_INTEGER_BASE_OCTAL,
|
||||
|
||||
/** The decimal base, indicated by a 0d, 0D, or empty prefix. */
|
||||
PM_INTEGER_BASE_DECIMAL,
|
||||
|
||||
/** The hexadecimal base, indicated by a 0x or 0X prefix. */
|
||||
PM_INTEGER_BASE_HEXADECIMAL,
|
||||
|
||||
/**
|
||||
* An unknown base, in which case pm_integer_parse will derive it based on
|
||||
* the content of the string. This is less efficient and does more
|
||||
* comparisons, so if callers know the base ahead of time, they should use
|
||||
* that instead.
|
||||
*/
|
||||
PM_INTEGER_BASE_UNKNOWN
|
||||
} pm_integer_base_t;
|
||||
|
||||
/**
|
||||
* Parse an integer from a string. This assumes that the format of the integer
|
||||
* has already been validated, as internal validation checks are not performed
|
||||
* here.
|
||||
*
|
||||
* @param integer The integer to parse into.
|
||||
* @param base The base of the integer.
|
||||
* @param start The start of the string.
|
||||
* @param end The end of the string.
|
||||
*/
|
||||
void pm_integer_parse(pm_integer_t *integer, pm_integer_base_t base, const uint8_t *start, const uint8_t *end);
|
||||
|
||||
/**
|
||||
* Compare two integers. This function returns -1 if the left integer is less
|
||||
* than the right integer, 0 if they are equal, and 1 if the left integer is
|
||||
* greater than the right integer.
|
||||
*
|
||||
* @param left The left integer to compare.
|
||||
* @param right The right integer to compare.
|
||||
* @return The result of the comparison.
|
||||
*/
|
||||
int pm_integer_compare(const pm_integer_t *left, const pm_integer_t *right);
|
||||
|
||||
/**
|
||||
* Reduce a ratio of integers to its simplest form.
|
||||
*
|
||||
* If either the numerator or denominator do not fit into a 32-bit integer, then
|
||||
* this function is a no-op. In the future, we may consider reducing even the
|
||||
* larger numbers, but for now we're going to keep it simple.
|
||||
*
|
||||
* @param numerator The numerator of the ratio.
|
||||
* @param denominator The denominator of the ratio.
|
||||
*/
|
||||
void pm_integers_reduce(pm_integer_t *numerator, pm_integer_t *denominator);
|
||||
|
||||
/**
|
||||
* Convert an integer to a decimal string.
|
||||
*
|
||||
* @param buffer The buffer to append the string to.
|
||||
* @param integer The integer to convert to a string.
|
||||
*/
|
||||
PRISM_EXPORTED_FUNCTION void pm_integer_string(pm_buffer_t *buffer, const pm_integer_t *integer);
|
||||
|
||||
/**
|
||||
* Free the internal memory of an integer. This memory will only be allocated if
|
||||
* the integer exceeds the size of a single node in the linked list.
|
||||
*
|
||||
* @param integer The integer to free.
|
||||
*/
|
||||
PRISM_EXPORTED_FUNCTION void pm_integer_free(pm_integer_t *integer);
|
||||
|
||||
#endif
|
||||
97
vendor/mruby-compiler2/lib/prism/include/prism/util/pm_list.h
vendored
Normal file
97
vendor/mruby-compiler2/lib/prism/include/prism/util/pm_list.h
vendored
Normal file
@@ -0,0 +1,97 @@
|
||||
/**
|
||||
* @file pm_list.h
|
||||
*
|
||||
* An abstract linked list.
|
||||
*/
|
||||
#ifndef PRISM_LIST_H
|
||||
#define PRISM_LIST_H
|
||||
|
||||
#include "prism/defines.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/**
|
||||
* This struct represents an abstract linked list that provides common
|
||||
* functionality. It is meant to be used any time a linked list is necessary to
|
||||
* store data.
|
||||
*
|
||||
* The linked list itself operates off a set of pointers. Because the pointers
|
||||
* are not necessarily sequential, they can be of any size. We use this fact to
|
||||
* allow the consumer of this linked list to extend the node struct to include
|
||||
* any data they want. This is done by using the pm_list_node_t as the first
|
||||
* member of the struct.
|
||||
*
|
||||
* For example, if we want to store a list of integers, we can do the following:
|
||||
*
|
||||
* ```c
|
||||
* typedef struct {
|
||||
* pm_list_node_t node;
|
||||
* int value;
|
||||
* } pm_int_node_t;
|
||||
*
|
||||
* pm_list_t list = { 0 };
|
||||
* pm_int_node_t *node = xmalloc(sizeof(pm_int_node_t));
|
||||
* node->value = 5;
|
||||
*
|
||||
* pm_list_append(&list, &node->node);
|
||||
* ```
|
||||
*
|
||||
* The pm_list_t struct is used to represent the overall linked list. It
|
||||
* contains a pointer to the head and tail of the list. This allows for easy
|
||||
* iteration and appending of new nodes.
|
||||
*/
|
||||
typedef struct pm_list_node {
|
||||
/** A pointer to the next node in the list. */
|
||||
struct pm_list_node *next;
|
||||
} pm_list_node_t;
|
||||
|
||||
/**
|
||||
* This represents the overall linked list. It keeps a pointer to the head and
|
||||
* tail so that iteration is easy and pushing new nodes is easy.
|
||||
*/
|
||||
typedef struct {
|
||||
/** The size of the list. */
|
||||
size_t size;
|
||||
|
||||
/** A pointer to the head of the list. */
|
||||
pm_list_node_t *head;
|
||||
|
||||
/** A pointer to the tail of the list. */
|
||||
pm_list_node_t *tail;
|
||||
} pm_list_t;
|
||||
|
||||
/**
|
||||
* Returns true if the given list is empty.
|
||||
*
|
||||
* @param list The list to check.
|
||||
* @return True if the given list is empty, otherwise false.
|
||||
*/
|
||||
PRISM_EXPORTED_FUNCTION bool pm_list_empty_p(pm_list_t *list);
|
||||
|
||||
/**
|
||||
* Returns the size of the list.
|
||||
*
|
||||
* @param list The list to check.
|
||||
* @return The size of the list.
|
||||
*/
|
||||
PRISM_EXPORTED_FUNCTION size_t pm_list_size(pm_list_t *list);
|
||||
|
||||
/**
|
||||
* Append a node to the given list.
|
||||
*
|
||||
* @param list The list to append to.
|
||||
* @param node The node to append.
|
||||
*/
|
||||
void pm_list_append(pm_list_t *list, pm_list_node_t *node);
|
||||
|
||||
/**
|
||||
* Deallocate the internal state of the given list.
|
||||
*
|
||||
* @param list The list to free.
|
||||
*/
|
||||
PRISM_EXPORTED_FUNCTION void pm_list_free(pm_list_t *list);
|
||||
|
||||
#endif
|
||||
29
vendor/mruby-compiler2/lib/prism/include/prism/util/pm_memchr.h
vendored
Normal file
29
vendor/mruby-compiler2/lib/prism/include/prism/util/pm_memchr.h
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* @file pm_memchr.h
|
||||
*
|
||||
* A custom memchr implementation.
|
||||
*/
|
||||
#ifndef PRISM_MEMCHR_H
|
||||
#define PRISM_MEMCHR_H
|
||||
|
||||
#include "prism/defines.h"
|
||||
#include "prism/encoding.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/**
|
||||
* We need to roll our own memchr to handle cases where the encoding changes and
|
||||
* we need to search for a character in a buffer that could be the trailing byte
|
||||
* of a multibyte character.
|
||||
*
|
||||
* @param source The source string.
|
||||
* @param character The character to search for.
|
||||
* @param number The maximum number of bytes to search.
|
||||
* @param encoding_changed Whether the encoding changed.
|
||||
* @param encoding A pointer to the encoding.
|
||||
* @return A pointer to the first occurrence of the character in the source
|
||||
* string, or NULL if no such character exists.
|
||||
*/
|
||||
void * pm_memchr(const void *source, int character, size_t number, bool encoding_changed, const pm_encoding_t *encoding);
|
||||
|
||||
#endif
|
||||
113
vendor/mruby-compiler2/lib/prism/include/prism/util/pm_newline_list.h
vendored
Normal file
113
vendor/mruby-compiler2/lib/prism/include/prism/util/pm_newline_list.h
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
/**
|
||||
* @file pm_newline_list.h
|
||||
*
|
||||
* A list of byte offsets of newlines in a string.
|
||||
*
|
||||
* When compiling the syntax tree, it's necessary to know the line and column
|
||||
* of many nodes. This is necessary to support things like error messages,
|
||||
* tracepoints, etc.
|
||||
*
|
||||
* It's possible that we could store the start line, start column, end line, and
|
||||
* end column on every node in addition to the offsets that we already store,
|
||||
* but that would be quite a lot of memory overhead.
|
||||
*/
|
||||
#ifndef PRISM_NEWLINE_LIST_H
|
||||
#define PRISM_NEWLINE_LIST_H
|
||||
|
||||
#include "prism/defines.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/**
|
||||
* A list of offsets of newlines in a string. The offsets are assumed to be
|
||||
* sorted/inserted in ascending order.
|
||||
*/
|
||||
typedef struct {
|
||||
/** A pointer to the start of the source string. */
|
||||
const uint8_t *start;
|
||||
|
||||
/** The number of offsets in the list. */
|
||||
size_t size;
|
||||
|
||||
/** The capacity of the list that has been allocated. */
|
||||
size_t capacity;
|
||||
|
||||
/** The list of offsets. */
|
||||
size_t *offsets;
|
||||
} pm_newline_list_t;
|
||||
|
||||
/**
|
||||
* A line and column in a string.
|
||||
*/
|
||||
typedef struct {
|
||||
/** The line number. */
|
||||
int32_t line;
|
||||
|
||||
/** The column number. */
|
||||
uint32_t column;
|
||||
} pm_line_column_t;
|
||||
|
||||
/**
|
||||
* Initialize a new newline list with the given capacity. Returns true if the
|
||||
* allocation of the offsets succeeds, otherwise returns false.
|
||||
*
|
||||
* @param list The list to initialize.
|
||||
* @param start A pointer to the start of the source string.
|
||||
* @param capacity The initial capacity of the list.
|
||||
* @return True if the allocation of the offsets succeeds, otherwise false.
|
||||
*/
|
||||
bool pm_newline_list_init(pm_newline_list_t *list, const uint8_t *start, size_t capacity);
|
||||
|
||||
/**
|
||||
* Clear out the newlines that have been appended to the list.
|
||||
*
|
||||
* @param list The list to clear.
|
||||
*/
|
||||
void
|
||||
pm_newline_list_clear(pm_newline_list_t *list);
|
||||
|
||||
/**
|
||||
* Append a new offset to the newline list. Returns true if the reallocation of
|
||||
* the offsets succeeds (if one was necessary), otherwise returns false.
|
||||
*
|
||||
* @param list The list to append to.
|
||||
* @param cursor A pointer to the offset to append.
|
||||
* @return True if the reallocation of the offsets succeeds (if one was
|
||||
* necessary), otherwise false.
|
||||
*/
|
||||
bool pm_newline_list_append(pm_newline_list_t *list, const uint8_t *cursor);
|
||||
|
||||
/**
|
||||
* Returns the line of the given offset. If the offset is not in the list, the
|
||||
* line of the closest offset less than the given offset is returned.
|
||||
*
|
||||
* @param list The list to search.
|
||||
* @param cursor A pointer to the offset to search for.
|
||||
* @param start_line The line to start counting from.
|
||||
* @return The line of the given offset.
|
||||
*/
|
||||
int32_t pm_newline_list_line(const pm_newline_list_t *list, const uint8_t *cursor, int32_t start_line);
|
||||
|
||||
/**
|
||||
* Returns the line and column of the given offset. If the offset is not in the
|
||||
* list, the line and column of the closest offset less than the given offset
|
||||
* are returned.
|
||||
*
|
||||
* @param list The list to search.
|
||||
* @param cursor A pointer to the offset to search for.
|
||||
* @param start_line The line to start counting from.
|
||||
* @return The line and column of the given offset.
|
||||
*/
|
||||
pm_line_column_t pm_newline_list_line_column(const pm_newline_list_t *list, const uint8_t *cursor, int32_t start_line);
|
||||
|
||||
/**
|
||||
* Free the internal memory allocated for the newline list.
|
||||
*
|
||||
* @param list The list to free.
|
||||
*/
|
||||
void pm_newline_list_free(pm_newline_list_t *list);
|
||||
|
||||
#endif
|
||||
190
vendor/mruby-compiler2/lib/prism/include/prism/util/pm_string.h
vendored
Normal file
190
vendor/mruby-compiler2/lib/prism/include/prism/util/pm_string.h
vendored
Normal file
@@ -0,0 +1,190 @@
|
||||
/**
|
||||
* @file pm_string.h
|
||||
*
|
||||
* A generic string type that can have various ownership semantics.
|
||||
*/
|
||||
#ifndef PRISM_STRING_H
|
||||
#define PRISM_STRING_H
|
||||
|
||||
#include "prism/defines.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
// The following headers are necessary to read files using demand paging.
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#elif defined(_POSIX_MAPPED_FILES)
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#elif defined(PRISM_HAS_FILESYSTEM)
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
|
||||
/**
|
||||
* A generic string type that can have various ownership semantics.
|
||||
*/
|
||||
typedef struct {
|
||||
/** A pointer to the start of the string. */
|
||||
const uint8_t *source;
|
||||
|
||||
/** The length of the string in bytes of memory. */
|
||||
size_t length;
|
||||
|
||||
/** The type of the string. This field determines how the string should be freed. */
|
||||
enum {
|
||||
/** This string is a constant string, and should not be freed. */
|
||||
PM_STRING_CONSTANT,
|
||||
|
||||
/** This is a slice of another string, and should not be freed. */
|
||||
PM_STRING_SHARED,
|
||||
|
||||
/** This string owns its memory, and should be freed using `pm_string_free`. */
|
||||
PM_STRING_OWNED,
|
||||
|
||||
#ifdef PRISM_HAS_MMAP
|
||||
/** This string is a memory-mapped file, and should be freed using `pm_string_free`. */
|
||||
PM_STRING_MAPPED
|
||||
#endif
|
||||
} type;
|
||||
} pm_string_t;
|
||||
|
||||
/**
|
||||
* Returns the size of the pm_string_t struct. This is necessary to allocate the
|
||||
* correct amount of memory in the FFI backend.
|
||||
*
|
||||
* @return The size of the pm_string_t struct.
|
||||
*/
|
||||
PRISM_EXPORTED_FUNCTION size_t pm_string_sizeof(void);
|
||||
|
||||
/**
|
||||
* Defines an empty string. This is useful for initializing a string that will
|
||||
* be filled in later.
|
||||
*/
|
||||
#define PM_STRING_EMPTY ((pm_string_t) { .type = PM_STRING_CONSTANT, .source = NULL, .length = 0 })
|
||||
|
||||
/**
|
||||
* Initialize a shared string that is based on initial input.
|
||||
*
|
||||
* @param string The string to initialize.
|
||||
* @param start The start of the string.
|
||||
* @param end The end of the string.
|
||||
*/
|
||||
void pm_string_shared_init(pm_string_t *string, const uint8_t *start, const uint8_t *end);
|
||||
|
||||
/**
|
||||
* Initialize an owned string that is responsible for freeing allocated memory.
|
||||
*
|
||||
* @param string The string to initialize.
|
||||
* @param source The source of the string.
|
||||
* @param length The length of the string.
|
||||
*/
|
||||
void pm_string_owned_init(pm_string_t *string, uint8_t *source, size_t length);
|
||||
|
||||
/**
|
||||
* Initialize a constant string that doesn't own its memory source.
|
||||
*
|
||||
* @param string The string to initialize.
|
||||
* @param source The source of the string.
|
||||
* @param length The length of the string.
|
||||
*/
|
||||
void pm_string_constant_init(pm_string_t *string, const char *source, size_t length);
|
||||
|
||||
/**
|
||||
* Represents the result of calling pm_string_mapped_init or
|
||||
* pm_string_file_init. We need this additional information because there is
|
||||
* not a platform-agnostic way to indicate that the file that was attempted to
|
||||
* be opened was a directory.
|
||||
*/
|
||||
typedef enum {
|
||||
/** Indicates that the string was successfully initialized. */
|
||||
PM_STRING_INIT_SUCCESS = 0,
|
||||
/**
|
||||
* Indicates a generic error from a string_*_init function, where the type
|
||||
* of error should be read from `errno` or `GetLastError()`.
|
||||
*/
|
||||
PM_STRING_INIT_ERROR_GENERIC = 1,
|
||||
/**
|
||||
* Indicates that the file that was attempted to be opened was a directory.
|
||||
*/
|
||||
PM_STRING_INIT_ERROR_DIRECTORY = 2
|
||||
} pm_string_init_result_t;
|
||||
|
||||
/**
|
||||
* Read the file indicated by the filepath parameter into source and load its
|
||||
* contents and size into the given `pm_string_t`. The given `pm_string_t`
|
||||
* should be freed using `pm_string_free` when it is no longer used.
|
||||
*
|
||||
* We want to use demand paging as much as possible in order to avoid having to
|
||||
* read the entire file into memory (which could be detrimental to performance
|
||||
* for large files). This means that if we're on windows we'll use
|
||||
* `MapViewOfFile`, on POSIX systems that have access to `mmap` we'll use
|
||||
* `mmap`, and on other POSIX systems we'll use `read`.
|
||||
*
|
||||
* @param string The string to initialize.
|
||||
* @param filepath The filepath to read.
|
||||
* @return The success of the read, indicated by the value of the enum.
|
||||
*/
|
||||
PRISM_EXPORTED_FUNCTION pm_string_init_result_t pm_string_mapped_init(pm_string_t *string, const char *filepath);
|
||||
|
||||
/**
|
||||
* Read the file indicated by the filepath parameter into source and load its
|
||||
* contents and size into the given `pm_string_t`. The given `pm_string_t`
|
||||
* should be freed using `pm_string_free` when it is no longer used.
|
||||
*
|
||||
* @param string The string to initialize.
|
||||
* @param filepath The filepath to read.
|
||||
* @return The success of the read, indicated by the value of the enum.
|
||||
*/
|
||||
PRISM_EXPORTED_FUNCTION pm_string_init_result_t pm_string_file_init(pm_string_t *string, const char *filepath);
|
||||
|
||||
/**
|
||||
* Ensure the string is owned. If it is not, then reinitialize it as owned and
|
||||
* copy over the previous source.
|
||||
*
|
||||
* @param string The string to ensure is owned.
|
||||
*/
|
||||
void pm_string_ensure_owned(pm_string_t *string);
|
||||
|
||||
/**
|
||||
* Compare the underlying lengths and bytes of two strings. Returns 0 if the
|
||||
* strings are equal, a negative number if the left string is less than the
|
||||
* right string, and a positive number if the left string is greater than the
|
||||
* right string.
|
||||
*
|
||||
* @param left The left string to compare.
|
||||
* @param right The right string to compare.
|
||||
* @return The comparison result.
|
||||
*/
|
||||
int pm_string_compare(const pm_string_t *left, const pm_string_t *right);
|
||||
|
||||
/**
|
||||
* Returns the length associated with the string.
|
||||
*
|
||||
* @param string The string to get the length of.
|
||||
* @return The length of the string.
|
||||
*/
|
||||
PRISM_EXPORTED_FUNCTION size_t pm_string_length(const pm_string_t *string);
|
||||
|
||||
/**
|
||||
* Returns the start pointer associated with the string.
|
||||
*
|
||||
* @param string The string to get the start pointer of.
|
||||
* @return The start pointer of the string.
|
||||
*/
|
||||
PRISM_EXPORTED_FUNCTION const uint8_t * pm_string_source(const pm_string_t *string);
|
||||
|
||||
/**
|
||||
* Free the associated memory of the given string.
|
||||
*
|
||||
* @param string The string to free.
|
||||
*/
|
||||
PRISM_EXPORTED_FUNCTION void pm_string_free(pm_string_t *string);
|
||||
|
||||
#endif
|
||||
32
vendor/mruby-compiler2/lib/prism/include/prism/util/pm_strncasecmp.h
vendored
Normal file
32
vendor/mruby-compiler2/lib/prism/include/prism/util/pm_strncasecmp.h
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
/**
|
||||
* @file pm_strncasecmp.h
|
||||
*
|
||||
* A custom strncasecmp implementation.
|
||||
*/
|
||||
#ifndef PRISM_STRNCASECMP_H
|
||||
#define PRISM_STRNCASECMP_H
|
||||
|
||||
#include "prism/defines.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* Compare two strings, ignoring case, up to the given length. Returns 0 if the
|
||||
* strings are equal, a negative number if string1 is less than string2, or a
|
||||
* positive number if string1 is greater than string2.
|
||||
*
|
||||
* Note that this is effectively our own implementation of strncasecmp, but it's
|
||||
* not available on all of the platforms we want to support so we're rolling it
|
||||
* here.
|
||||
*
|
||||
* @param string1 The first string to compare.
|
||||
* @param string2 The second string to compare
|
||||
* @param length The maximum number of characters to compare.
|
||||
* @return 0 if the strings are equal, a negative number if string1 is less than
|
||||
* string2, or a positive number if string1 is greater than string2.
|
||||
*/
|
||||
int pm_strncasecmp(const uint8_t *string1, const uint8_t *string2, size_t length);
|
||||
|
||||
#endif
|
||||
46
vendor/mruby-compiler2/lib/prism/include/prism/util/pm_strpbrk.h
vendored
Normal file
46
vendor/mruby-compiler2/lib/prism/include/prism/util/pm_strpbrk.h
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* @file pm_strpbrk.h
|
||||
*
|
||||
* A custom strpbrk implementation.
|
||||
*/
|
||||
#ifndef PRISM_STRPBRK_H
|
||||
#define PRISM_STRPBRK_H
|
||||
|
||||
#include "prism/defines.h"
|
||||
#include "prism/diagnostic.h"
|
||||
#include "prism/parser.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
/**
|
||||
* Here we have rolled our own version of strpbrk. The standard library strpbrk
|
||||
* has undefined behavior when the source string is not null-terminated. We want
|
||||
* to support strings that are not null-terminated because pm_parse does not
|
||||
* have the contract that the string is null-terminated. (This is desirable
|
||||
* because it means the extension can call pm_parse with the result of a call to
|
||||
* mmap).
|
||||
*
|
||||
* The standard library strpbrk also does not support passing a maximum length
|
||||
* to search. We want to support this for the reason mentioned above, but we
|
||||
* also don't want it to stop on null bytes. Ruby actually allows null bytes
|
||||
* within strings, comments, regular expressions, etc. So we need to be able to
|
||||
* skip past them.
|
||||
*
|
||||
* Finally, we want to support encodings wherein the charset could contain
|
||||
* characters that are trailing bytes of multi-byte characters. For example, in
|
||||
* Shift-JIS, the backslash character can be a trailing byte. In that case we
|
||||
* need to take a slower path and iterate one multi-byte character at a time.
|
||||
*
|
||||
* @param parser The parser.
|
||||
* @param source The source to search.
|
||||
* @param charset The charset to search for.
|
||||
* @param length The maximum number of bytes to search.
|
||||
* @param validate Whether to validate that the source string is valid in the
|
||||
* current encoding of the parser.
|
||||
* @return A pointer to the first character in the source string that is in the
|
||||
* charset, or NULL if no such character exists.
|
||||
*/
|
||||
const uint8_t * pm_strpbrk(pm_parser_t *parser, const uint8_t *source, const uint8_t *charset, ptrdiff_t length, bool validate);
|
||||
|
||||
#endif
|
||||
29
vendor/mruby-compiler2/lib/prism/include/prism/version.h
vendored
Normal file
29
vendor/mruby-compiler2/lib/prism/include/prism/version.h
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* @file version.h
|
||||
*
|
||||
* The version of the Prism library.
|
||||
*/
|
||||
#ifndef PRISM_VERSION_H
|
||||
#define PRISM_VERSION_H
|
||||
|
||||
/**
|
||||
* The major version of the Prism library as an int.
|
||||
*/
|
||||
#define PRISM_VERSION_MAJOR 1
|
||||
|
||||
/**
|
||||
* The minor version of the Prism library as an int.
|
||||
*/
|
||||
#define PRISM_VERSION_MINOR 4
|
||||
|
||||
/**
|
||||
* The patch version of the Prism library as an int.
|
||||
*/
|
||||
#define PRISM_VERSION_PATCH 0
|
||||
|
||||
/**
|
||||
* The version of the Prism library as a constant string.
|
||||
*/
|
||||
#define PRISM_VERSION "1.4.0"
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user