prism 1.9.0 → 2.0.0.rc2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +88 -0
- data/CODE_OF_CONDUCT.md +1 -1
- data/LICENSE.md +1 -1
- data/Makefile +41 -12
- data/README.md +35 -97
- data/config.yml +174 -161
- data/docs/build_system.md +2 -2
- data/docs/configuration.md +5 -4
- data/docs/encoding.md +2 -2
- data/docs/fuzzing.md +4 -11
- data/docs/javascript.md +19 -4
- data/docs/mapping.md +1 -1
- data/docs/releasing.md +77 -5
- data/docs/relocation.md +2 -4
- data/docs/serialization.md +22 -24
- data/docs/testing.md +46 -29
- data/ext/prism/api_node.c +1461 -1401
- data/ext/prism/extconf.rb +3 -4
- data/ext/prism/extension.c +796 -422
- data/ext/prism/extension.h +3 -3
- data/include/prism/arena.h +37 -0
- data/include/prism/ast.h +2727 -610
- data/include/prism/buffer.h +52 -0
- data/include/prism/comments.h +55 -0
- data/include/prism/compiler/accel.h +26 -0
- data/include/prism/compiler/align.h +36 -0
- data/include/prism/compiler/assume.h +25 -0
- data/include/prism/compiler/bswap.h +46 -0
- data/include/prism/compiler/endianness.h +34 -0
- data/include/prism/compiler/exported.h +24 -0
- data/include/prism/compiler/fallthrough.h +22 -0
- data/include/prism/compiler/filesystem.h +32 -0
- data/include/prism/compiler/flex_array.h +19 -0
- data/include/prism/compiler/force_inline.h +21 -0
- data/include/prism/compiler/format.h +25 -0
- data/include/prism/compiler/inline.h +17 -0
- data/include/prism/compiler/nodiscard.h +22 -0
- data/include/prism/compiler/nonnull.h +18 -0
- data/include/prism/compiler/unused.h +18 -0
- data/include/prism/constant_pool.h +81 -0
- data/include/prism/diagnostic.h +38 -403
- data/include/prism/errors_format.h +53 -0
- data/include/prism/excludes.h +29 -0
- data/include/prism/integer.h +41 -0
- data/include/prism/internal/allocator.h +68 -0
- data/include/prism/internal/allocator_debug.h +88 -0
- data/include/prism/internal/arena.h +108 -0
- data/include/prism/internal/bit.h +42 -0
- data/include/prism/internal/buffer.h +94 -0
- data/include/prism/internal/char.h +145 -0
- data/include/prism/internal/comments.h +53 -0
- data/include/prism/internal/constant_pool.h +152 -0
- data/include/prism/internal/diagnostic.h +389 -0
- data/include/prism/{encoding.h → internal/encoding.h} +27 -68
- data/include/prism/internal/integer.h +68 -0
- data/include/prism/internal/isinf.h +16 -0
- data/include/prism/internal/line_offset_list.h +34 -0
- data/include/prism/{util/pm_list.h → internal/list.h} +11 -52
- data/include/prism/internal/magic_comments.h +23 -0
- data/include/prism/internal/memchr.h +15 -0
- data/include/prism/internal/node.h +38 -0
- data/include/prism/internal/options.h +232 -0
- data/include/prism/internal/parser.h +1004 -0
- data/include/prism/internal/regexp.h +26 -0
- data/include/prism/internal/serialize.h +39 -0
- data/include/prism/internal/source.h +72 -0
- data/include/prism/{static_literals.h → internal/static_literals.h} +26 -47
- data/include/prism/internal/stringy.h +35 -0
- data/include/prism/{util/pm_strncasecmp.h → internal/strncasecmp.h} +3 -17
- data/include/prism/{util/pm_strpbrk.h → internal/strpbrk.h} +7 -20
- data/include/prism/internal/tokens.h +11 -0
- data/include/prism/internal/xxh3.h +16 -0
- data/include/prism/json.h +32 -0
- data/include/prism/line_offset_list.h +61 -0
- data/include/prism/magic_comments.h +35 -0
- data/include/prism/node.h +18 -53
- data/include/prism/options.h +146 -280
- data/include/prism/parser.h +356 -867
- data/include/prism/prettyprint.h +6 -9
- data/include/prism/serialize.h +115 -0
- data/include/prism/source.h +155 -0
- data/include/prism/stream.h +28 -0
- data/include/prism/string_query.h +74 -0
- data/include/prism/stringy.h +72 -0
- data/include/prism/version.h +12 -3
- data/include/prism.h +43 -320
- data/lib/prism/compiler.rb +319 -305
- data/lib/prism/desugar_compiler.rb +105 -34
- data/lib/prism/dispatcher.rb +646 -473
- data/lib/prism/dot_visitor.rb +592 -511
- data/lib/prism/dsl.rb +391 -25
- data/lib/prism/ffi.rb +258 -90
- data/lib/prism/inspect_visitor.rb +357 -325
- data/lib/prism/lex_compat.rb +254 -212
- data/lib/prism/mutation_compiler.rb +313 -305
- data/lib/prism/node.rb +20966 -6992
- data/lib/prism/node_ext.rb +180 -187
- data/lib/prism/node_find.rb +215 -0
- data/lib/prism/parse_result/errors.rb +7 -1
- data/lib/prism/parse_result/newlines.rb +276 -8
- data/lib/prism/parse_result.rb +468 -139
- data/lib/prism/pattern.rb +65 -20
- data/lib/prism/reflection.rb +23 -12
- data/lib/prism/relocation.rb +149 -87
- data/lib/prism/serialize.rb +3460 -539
- data/lib/prism/string_query.rb +24 -1
- data/lib/prism/translation/parser/builder.rb +10 -2
- data/lib/prism/translation/parser/compiler.rb +44 -52
- data/lib/prism/translation/parser/lexer.rb +41 -92
- data/lib/prism/translation/parser.rb +1 -1
- data/lib/prism/translation/parser_current.rb +1 -1
- data/lib/prism/translation/ripper/lexer.rb +8 -10
- data/lib/prism/translation/ripper/sexp.rb +2 -10
- data/lib/prism/translation/ripper/shim.rb +2 -0
- data/lib/prism/translation/ripper.rb +967 -209
- data/lib/prism/translation/ruby_parser.rb +73 -316
- data/lib/prism/translation.rb +2 -0
- data/lib/prism/visitor.rb +632 -5
- data/lib/prism.rb +79 -9
- data/prism.gemspec +128 -62
- data/rbi/generated/prism/compiler.rbi +489 -0
- data/rbi/generated/prism/desugar_compiler.rbi +306 -0
- data/rbi/generated/prism/dispatcher.rbi +1138 -0
- data/rbi/generated/prism/dot_visitor.rbi +618 -0
- data/rbi/generated/prism/dsl.rbi +751 -0
- data/rbi/generated/prism/inspect_visitor.rbi +503 -0
- data/rbi/generated/prism/lex_compat.rbi +162 -0
- data/rbi/generated/prism/mutation_compiler.rbi +464 -0
- data/rbi/generated/prism/node.rbi +14407 -0
- data/rbi/generated/prism/node_ext.rbi +259 -0
- data/rbi/generated/prism/node_find.rbi +79 -0
- data/rbi/generated/prism/parse_result/errors.rbi +21 -0
- data/rbi/generated/prism/parse_result/newlines.rbi +208 -0
- data/rbi/generated/prism/parse_result.rbi +776 -0
- data/rbi/generated/prism/pattern.rbi +134 -0
- data/rbi/generated/prism/reflection.rbi +89 -0
- data/rbi/generated/prism/relocation.rbi +329 -0
- data/rbi/generated/prism/serialize.rbi +184 -0
- data/rbi/generated/prism/string_query.rbi +43 -0
- data/rbi/generated/prism/translation.rbi +7 -0
- data/rbi/generated/prism/visitor.rbi +650 -0
- data/rbi/generated/prism.rbi +86 -0
- data/rbi/prism/translation/parser_versions.rbi +5 -0
- data/rbi/rubyvm/node_find.rbi +14 -0
- data/sig/generated/prism/compiler.rbs +492 -0
- data/sig/generated/prism/desugar_compiler.rbs +305 -0
- data/sig/generated/prism/dispatcher.rbs +1292 -0
- data/sig/generated/prism/dot_visitor.rbs +635 -0
- data/sig/generated/prism/dsl.rbs +928 -0
- data/sig/generated/prism/inspect_visitor.rbs +509 -0
- data/sig/generated/prism/lex_compat.rbs +166 -0
- data/sig/{prism → generated/prism}/mutation_compiler.rbs +309 -4
- data/sig/generated/prism/node.rbs +20896 -0
- data/sig/generated/prism/node_ext.rbs +290 -0
- data/sig/generated/prism/node_find.rbs +90 -0
- data/sig/generated/prism/parse_result/errors.rbs +22 -0
- data/sig/generated/prism/parse_result/newlines.rbs +223 -0
- data/sig/generated/prism/parse_result.rbs +871 -0
- data/sig/generated/prism/pattern.rbs +156 -0
- data/sig/generated/prism/reflection.rbs +101 -0
- data/sig/generated/prism/relocation.rbs +428 -0
- data/sig/generated/prism/serialize.rbs +198 -0
- data/sig/generated/prism/string_query.rbs +43 -0
- data/sig/generated/prism/translation.rbs +8 -0
- data/sig/generated/prism/visitor.rbs +1111 -0
- data/sig/generated/prism.rbs +84 -0
- data/sig/manifest.yaml +2 -0
- data/src/arena.c +117 -0
- data/src/{util/pm_buffer.c → buffer.c} +53 -21
- data/src/{util/pm_char.c → char.c} +28 -57
- data/src/comments.c +454 -0
- data/src/constant_pool.c +406 -0
- data/src/diagnostic.c +97 -65
- data/src/encoding.c +8 -3
- data/src/errors_format.c +519 -0
- data/src/{util/pm_integer.c → integer.c} +33 -22
- data/src/json.c +5733 -0
- data/src/line_offset_list.c +100 -0
- data/src/list.c +24 -0
- data/src/{util/pm_memchr.c → memchr.c} +8 -6
- data/src/node.c +3504 -7674
- data/src/options.c +162 -49
- data/src/parser.c +367 -0
- data/src/prettyprint.c +421 -354
- data/src/prism.c +8402 -7161
- data/src/regexp.c +961 -45
- data/src/serialize.c +460 -424
- data/src/source.c +518 -0
- data/src/static_literals.c +111 -43
- data/src/string_query.c +180 -0
- data/src/stringy.c +91 -0
- data/src/{util/pm_strncasecmp.c → strncasecmp.c} +5 -4
- data/src/strpbrk.c +447 -0
- data/src/{token_type.c → tokens.c} +39 -18
- data/src/xxh3.c +292 -0
- metadata +128 -63
- data/ext/prism/api_pack.c +0 -276
- data/include/prism/defines.h +0 -260
- data/include/prism/pack.h +0 -163
- data/include/prism/regexp.h +0 -43
- data/include/prism/util/pm_buffer.h +0 -236
- data/include/prism/util/pm_char.h +0 -204
- data/include/prism/util/pm_constant_pool.h +0 -218
- data/include/prism/util/pm_integer.h +0 -130
- data/include/prism/util/pm_memchr.h +0 -29
- data/include/prism/util/pm_newline_list.h +0 -113
- data/include/prism/util/pm_string.h +0 -200
- data/lib/prism/pack.rb +0 -230
- data/lib/prism/parse_result/comments.rb +0 -188
- data/rbi/prism/compiler.rbi +0 -12
- data/rbi/prism/dsl.rbi +0 -524
- data/rbi/prism/inspect_visitor.rbi +0 -12
- data/rbi/prism/node.rbi +0 -8750
- data/rbi/prism/node_ext.rbi +0 -107
- data/rbi/prism/parse_result.rbi +0 -404
- data/rbi/prism/reflection.rbi +0 -58
- data/rbi/prism/string_query.rbi +0 -12
- data/rbi/prism/visitor.rbi +0 -473
- data/rbi/prism.rbi +0 -63
- data/sig/prism/compiler.rbs +0 -9
- data/sig/prism/dispatcher.rbs +0 -19
- data/sig/prism/dot_visitor.rbs +0 -6
- data/sig/prism/dsl.rbs +0 -351
- data/sig/prism/inspect_visitor.rbs +0 -22
- data/sig/prism/lex_compat.rbs +0 -10
- data/sig/prism/node.rbs +0 -4042
- data/sig/prism/node_ext.rbs +0 -149
- data/sig/prism/pack.rbs +0 -43
- data/sig/prism/parse_result/comments.rbs +0 -38
- data/sig/prism/parse_result.rbs +0 -197
- data/sig/prism/pattern.rbs +0 -13
- data/sig/prism/reflection.rbs +0 -50
- data/sig/prism/relocation.rbs +0 -185
- data/sig/prism/serialize.rbs +0 -8
- data/sig/prism/string_query.rbs +0 -11
- data/sig/prism/visitor.rbs +0 -169
- data/sig/prism.rbs +0 -272
- data/src/pack.c +0 -509
- data/src/util/pm_constant_pool.c +0 -342
- data/src/util/pm_list.c +0 -49
- data/src/util/pm_newline_list.c +0 -125
- data/src/util/pm_string.c +0 -381
- data/src/util/pm_strpbrk.c +0 -206
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# Generated from lib/prism.rb with RBS::Inline
|
|
2
|
+
|
|
3
|
+
# The Prism Ruby parser.
|
|
4
|
+
#
|
|
5
|
+
# "Parsing Ruby is suddenly manageable!"
|
|
6
|
+
# - You, hopefully
|
|
7
|
+
module Prism
|
|
8
|
+
# Raised when requested to parse as the currently running Ruby version but Prism has no support for it.
|
|
9
|
+
class CurrentVersionError < ArgumentError
|
|
10
|
+
# Initialize a new exception for the given ruby version string.
|
|
11
|
+
#
|
|
12
|
+
# : (String version) -> void
|
|
13
|
+
def initialize: (String version) -> void
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# :call-seq:
|
|
17
|
+
# lex_compat(source, **options) -> LexCompat::Result
|
|
18
|
+
#
|
|
19
|
+
# Returns a parse result whose value is an array of tokens that closely
|
|
20
|
+
# resembles the return value of Ripper.lex.
|
|
21
|
+
#
|
|
22
|
+
# For supported options, see Prism.parse.
|
|
23
|
+
#
|
|
24
|
+
# : (String source, **untyped options) -> LexCompat::Result
|
|
25
|
+
def self.lex_compat: (String source, **untyped options) -> LexCompat::Result
|
|
26
|
+
|
|
27
|
+
# :call-seq:
|
|
28
|
+
# load(source, serialized, freeze) -> ParseResult
|
|
29
|
+
#
|
|
30
|
+
# Load the serialized AST using the source as a reference into a tree.
|
|
31
|
+
#
|
|
32
|
+
# : (String source, String serialized, ?bool freeze) -> ParseResult
|
|
33
|
+
def self.load: (String source, String serialized, ?bool freeze) -> ParseResult
|
|
34
|
+
|
|
35
|
+
# Given a Method, UnboundMethod, Proc, or Thread::Backtrace::Location,
|
|
36
|
+
# returns the Prism node representing it. On CRuby, this uses node_id for
|
|
37
|
+
# an exact match. On other implementations, it falls back to best-effort
|
|
38
|
+
# matching by source location line number.
|
|
39
|
+
#
|
|
40
|
+
# : (Method | UnboundMethod | Proc | Thread::Backtrace::Location callable) -> Node?
|
|
41
|
+
def self.find: (Method | UnboundMethod | Proc | Thread::Backtrace::Location callable) -> Node?
|
|
42
|
+
|
|
43
|
+
VERSION: String
|
|
44
|
+
|
|
45
|
+
BACKEND: :CEXT | :FFI
|
|
46
|
+
|
|
47
|
+
interface _Stream
|
|
48
|
+
def gets: (?Integer integer) -> (String | nil)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def self.parse: (String source, ?filepath: String, ?attach_comments: bool, ?command_line: String, ?encoding: Encoding | false, ?freeze: bool, ?frozen_string_literal: bool, ?line: Integer, ?main_script: bool, ?partial_script: bool, ?raise_error: Symbol | true, ?scopes: Array[Array[Symbol]], ?version: String) -> ParseResult
|
|
52
|
+
|
|
53
|
+
def self.profile: (String source, ?filepath: String, ?attach_comments: bool, ?command_line: String, ?encoding: Encoding | false, ?freeze: bool, ?frozen_string_literal: bool, ?line: Integer, ?main_script: bool, ?partial_script: bool, ?raise_error: Symbol | true, ?scopes: Array[Array[Symbol]], ?version: String) -> void
|
|
54
|
+
|
|
55
|
+
def self.lex: (String source, ?filepath: String, ?attach_comments: bool, ?command_line: String, ?encoding: Encoding | false, ?freeze: bool, ?frozen_string_literal: bool, ?line: Integer, ?main_script: bool, ?partial_script: bool, ?raise_error: Symbol | true, ?scopes: Array[Array[Symbol]], ?version: String) -> LexResult
|
|
56
|
+
|
|
57
|
+
def self.parse_lex: (String source, ?filepath: String, ?attach_comments: bool, ?command_line: String, ?encoding: Encoding | false, ?freeze: bool, ?frozen_string_literal: bool, ?line: Integer, ?main_script: bool, ?partial_script: bool, ?raise_error: Symbol | true, ?scopes: Array[Array[Symbol]], ?version: String) -> ParseLexResult
|
|
58
|
+
|
|
59
|
+
def self.dump: (String source, ?filepath: String, ?attach_comments: bool, ?command_line: String, ?encoding: Encoding | false, ?freeze: bool, ?frozen_string_literal: bool, ?line: Integer, ?main_script: bool, ?partial_script: bool, ?raise_error: Symbol | true, ?scopes: Array[Array[Symbol]], ?version: String) -> String
|
|
60
|
+
|
|
61
|
+
def self.parse_comments: (String source, ?filepath: String, ?attach_comments: bool, ?command_line: String, ?encoding: Encoding | false, ?freeze: bool, ?frozen_string_literal: bool, ?line: Integer, ?main_script: bool, ?partial_script: bool, ?raise_error: Symbol | true, ?scopes: Array[Array[Symbol]], ?version: String) -> Array[Comment]
|
|
62
|
+
|
|
63
|
+
def self.parse_success?: (String source, ?filepath: String, ?attach_comments: bool, ?command_line: String, ?encoding: Encoding | false, ?freeze: bool, ?frozen_string_literal: bool, ?line: Integer, ?main_script: bool, ?partial_script: bool, ?raise_error: Symbol | true, ?scopes: Array[Array[Symbol]], ?version: String) -> bool
|
|
64
|
+
|
|
65
|
+
def self.parse_failure?: (String source, ?filepath: String, ?attach_comments: bool, ?command_line: String, ?encoding: Encoding | false, ?freeze: bool, ?frozen_string_literal: bool, ?line: Integer, ?main_script: bool, ?partial_script: bool, ?raise_error: Symbol | true, ?scopes: Array[Array[Symbol]], ?version: String) -> bool
|
|
66
|
+
|
|
67
|
+
def self.parse_stream: (_Stream stream, ?filepath: String, ?attach_comments: bool, ?command_line: String, ?encoding: Encoding | false, ?freeze: bool, ?frozen_string_literal: bool, ?line: Integer, ?main_script: bool, ?partial_script: bool, ?raise_error: Symbol | true, ?scopes: Array[Array[Symbol]], ?version: String) -> ParseResult
|
|
68
|
+
|
|
69
|
+
def self.parse_file: (path filepath, ?attach_comments: bool, ?command_line: String, ?encoding: Encoding | false, ?freeze: bool, ?frozen_string_literal: bool, ?line: Integer, ?main_script: bool, ?partial_script: bool, ?raise_error: Symbol | true, ?scopes: Array[Array[Symbol]], ?version: String) -> ParseResult
|
|
70
|
+
|
|
71
|
+
def self.profile_file: (path filepath, ?attach_comments: bool, ?command_line: String, ?encoding: Encoding | false, ?freeze: bool, ?frozen_string_literal: bool, ?line: Integer, ?main_script: bool, ?partial_script: bool, ?raise_error: Symbol | true, ?scopes: Array[Array[Symbol]], ?version: String) -> void
|
|
72
|
+
|
|
73
|
+
def self.lex_file: (path filepath, ?attach_comments: bool, ?command_line: String, ?encoding: Encoding | false, ?freeze: bool, ?frozen_string_literal: bool, ?line: Integer, ?main_script: bool, ?partial_script: bool, ?raise_error: Symbol | true, ?scopes: Array[Array[Symbol]], ?version: String) -> LexResult
|
|
74
|
+
|
|
75
|
+
def self.parse_lex_file: (path filepath, ?attach_comments: bool, ?command_line: String, ?encoding: Encoding | false, ?freeze: bool, ?frozen_string_literal: bool, ?line: Integer, ?main_script: bool, ?partial_script: bool, ?raise_error: Symbol | true, ?scopes: Array[Array[Symbol]], ?version: String) -> ParseLexResult
|
|
76
|
+
|
|
77
|
+
def self.dump_file: (path filepath, ?attach_comments: bool, ?command_line: String, ?encoding: Encoding | false, ?freeze: bool, ?frozen_string_literal: bool, ?line: Integer, ?main_script: bool, ?partial_script: bool, ?raise_error: Symbol | true, ?scopes: Array[Array[Symbol]], ?version: String) -> String
|
|
78
|
+
|
|
79
|
+
def self.parse_file_comments: (path filepath, ?attach_comments: bool, ?command_line: String, ?encoding: Encoding | false, ?freeze: bool, ?frozen_string_literal: bool, ?line: Integer, ?main_script: bool, ?partial_script: bool, ?raise_error: Symbol | true, ?scopes: Array[Array[Symbol]], ?version: String) -> Array[Comment]
|
|
80
|
+
|
|
81
|
+
def self.parse_file_success?: (path filepath, ?attach_comments: bool, ?command_line: String, ?encoding: Encoding | false, ?freeze: bool, ?frozen_string_literal: bool, ?line: Integer, ?main_script: bool, ?partial_script: bool, ?raise_error: Symbol | true, ?scopes: Array[Array[Symbol]], ?version: String) -> bool
|
|
82
|
+
|
|
83
|
+
def self.parse_file_failure?: (path filepath, ?attach_comments: bool, ?command_line: String, ?encoding: Encoding | false, ?freeze: bool, ?frozen_string_literal: bool, ?line: Integer, ?main_script: bool, ?partial_script: bool, ?raise_error: Symbol | true, ?scopes: Array[Array[Symbol]], ?version: String) -> bool
|
|
84
|
+
end
|
data/sig/manifest.yaml
ADDED
data/src/arena.c
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
#include "prism/internal/arena.h"
|
|
2
|
+
|
|
3
|
+
#include "prism/internal/allocator.h"
|
|
4
|
+
|
|
5
|
+
#include <assert.h>
|
|
6
|
+
#include <stdio.h>
|
|
7
|
+
#include <stdlib.h>
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Compute the block allocation size using offsetof so it is correct regardless
|
|
11
|
+
* of PM_FLEX_ARRAY_LENGTH.
|
|
12
|
+
*/
|
|
13
|
+
#define PM_ARENA_BLOCK_SIZE(data_size) (offsetof(pm_arena_block_t, data) + (data_size))
|
|
14
|
+
|
|
15
|
+
/** Initial block data size: 8 KB. */
|
|
16
|
+
#define PM_ARENA_INITIAL_SIZE 8192
|
|
17
|
+
|
|
18
|
+
/** Double the block size every this many blocks. */
|
|
19
|
+
#define PM_ARENA_GROWTH_INTERVAL 8
|
|
20
|
+
|
|
21
|
+
/** Maximum block data size: 1 MB. */
|
|
22
|
+
#define PM_ARENA_MAX_SIZE (1024 * 1024)
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Compute the data size for the next block.
|
|
26
|
+
*/
|
|
27
|
+
static size_t
|
|
28
|
+
pm_arena_next_block_size(const pm_arena_t *arena, size_t min_size) {
|
|
29
|
+
size_t size = PM_ARENA_INITIAL_SIZE;
|
|
30
|
+
|
|
31
|
+
for (size_t exp = PM_ARENA_GROWTH_INTERVAL; exp <= arena->block_count; exp += PM_ARENA_GROWTH_INTERVAL) {
|
|
32
|
+
if (size < PM_ARENA_MAX_SIZE) size *= 2;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return size > min_size ? size : min_size;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Allocate a new block with the given data capacity and initial usage, link it
|
|
40
|
+
* into the arena, and return it. Aborts on allocation failure.
|
|
41
|
+
*/
|
|
42
|
+
static pm_arena_block_t *
|
|
43
|
+
pm_arena_block_new(pm_arena_t *arena, size_t data_size, size_t initial_used) {
|
|
44
|
+
assert(initial_used <= data_size);
|
|
45
|
+
pm_arena_block_t *block = (pm_arena_block_t *) xmalloc(PM_ARENA_BLOCK_SIZE(data_size));
|
|
46
|
+
|
|
47
|
+
if (block == NULL) {
|
|
48
|
+
fprintf(stderr, "prism: out of memory; aborting\n");
|
|
49
|
+
abort();
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
block->capacity = data_size;
|
|
53
|
+
block->used = initial_used;
|
|
54
|
+
block->prev = arena->current;
|
|
55
|
+
arena->current = block;
|
|
56
|
+
arena->block_count++;
|
|
57
|
+
|
|
58
|
+
return block;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Ensure the arena has at least `capacity` bytes available in its current
|
|
63
|
+
* block, allocating a new block if necessary. This allows callers to
|
|
64
|
+
* pre-size the arena to avoid repeated small block allocations.
|
|
65
|
+
*/
|
|
66
|
+
void
|
|
67
|
+
pm_arena_reserve(pm_arena_t *arena, size_t capacity) {
|
|
68
|
+
if (capacity <= PM_ARENA_INITIAL_SIZE) return;
|
|
69
|
+
if (arena->current != NULL && (arena->current->capacity - arena->current->used) >= capacity) return;
|
|
70
|
+
pm_arena_block_new(arena, capacity, 0);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Slow path for pm_arena_alloc: allocate a new block and return a pointer to
|
|
75
|
+
* the first `size` bytes. Called when the current block has insufficient space.
|
|
76
|
+
*/
|
|
77
|
+
void *
|
|
78
|
+
pm_arena_alloc_slow(pm_arena_t *arena, size_t size) {
|
|
79
|
+
size_t block_data_size = pm_arena_next_block_size(arena, size);
|
|
80
|
+
pm_arena_block_t *block = pm_arena_block_new(arena, block_data_size, size);
|
|
81
|
+
return block->data;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Returns a newly allocated and initialized arena.
|
|
86
|
+
*/
|
|
87
|
+
pm_arena_t *
|
|
88
|
+
pm_arena_new(void) {
|
|
89
|
+
pm_arena_t *arena = (pm_arena_t *) xcalloc(1, sizeof(pm_arena_t));
|
|
90
|
+
if (arena == NULL) abort();
|
|
91
|
+
return arena;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Free all blocks in the arena.
|
|
96
|
+
*/
|
|
97
|
+
void
|
|
98
|
+
pm_arena_cleanup(pm_arena_t *arena) {
|
|
99
|
+
pm_arena_block_t *block = arena->current;
|
|
100
|
+
|
|
101
|
+
while (block != NULL) {
|
|
102
|
+
pm_arena_block_t *prev = block->prev;
|
|
103
|
+
xfree_sized(block, PM_ARENA_BLOCK_SIZE(block->capacity));
|
|
104
|
+
block = prev;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
*arena = (pm_arena_t) { 0 };
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Frees both the held memory and the arena itself.
|
|
112
|
+
*/
|
|
113
|
+
void
|
|
114
|
+
pm_arena_free(pm_arena_t *arena) {
|
|
115
|
+
pm_arena_cleanup(arena);
|
|
116
|
+
xfree_sized(arena, sizeof(pm_arena_t));
|
|
117
|
+
}
|
|
@@ -1,31 +1,38 @@
|
|
|
1
|
-
#include "prism/
|
|
1
|
+
#include "prism/internal/buffer.h"
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
3
|
+
#include "prism/compiler/inline.h"
|
|
4
|
+
|
|
5
|
+
#include "prism/internal/char.h"
|
|
6
|
+
#include "prism/internal/allocator.h"
|
|
7
|
+
|
|
8
|
+
#include <assert.h>
|
|
9
|
+
#include <stdarg.h>
|
|
10
|
+
#include <stdio.h>
|
|
11
|
+
#include <stdlib.h>
|
|
12
|
+
#include <string.h>
|
|
10
13
|
|
|
11
14
|
/**
|
|
12
15
|
* Initialize a pm_buffer_t with the given capacity.
|
|
13
16
|
*/
|
|
14
|
-
|
|
15
|
-
|
|
17
|
+
void
|
|
18
|
+
pm_buffer_init(pm_buffer_t *buffer, size_t capacity) {
|
|
16
19
|
buffer->length = 0;
|
|
17
20
|
buffer->capacity = capacity;
|
|
18
21
|
|
|
19
22
|
buffer->value = (char *) xmalloc(capacity);
|
|
20
|
-
|
|
23
|
+
if (buffer->value == NULL) abort();
|
|
21
24
|
}
|
|
22
25
|
|
|
23
26
|
/**
|
|
24
|
-
*
|
|
27
|
+
* Allocate and initialize a new buffer.
|
|
25
28
|
*/
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
+
pm_buffer_t *
|
|
30
|
+
pm_buffer_new(void) {
|
|
31
|
+
pm_buffer_t *buffer = (pm_buffer_t *) xmalloc(sizeof(pm_buffer_t));
|
|
32
|
+
if (buffer == NULL) abort();
|
|
33
|
+
|
|
34
|
+
pm_buffer_init(buffer, 1024);
|
|
35
|
+
return buffer;
|
|
29
36
|
}
|
|
30
37
|
|
|
31
38
|
/**
|
|
@@ -45,11 +52,18 @@ pm_buffer_length(const pm_buffer_t *buffer) {
|
|
|
45
52
|
}
|
|
46
53
|
|
|
47
54
|
/**
|
|
48
|
-
* Append the given amount of space to the buffer.
|
|
55
|
+
* Append the given amount of space to the buffer. Returns false when there is
|
|
56
|
+
* nothing to write: either the allocation failed or the length is zero. A
|
|
57
|
+
* zero-initialized buffer has a NULL value until its first allocation, and
|
|
58
|
+
* passing NULL to memcpy/memset/memmove is undefined behavior even for zero
|
|
59
|
+
* bytes, so callers must not write in the zero case.
|
|
49
60
|
*/
|
|
50
|
-
static
|
|
61
|
+
static PRISM_INLINE bool
|
|
51
62
|
pm_buffer_append_length(pm_buffer_t *buffer, size_t length) {
|
|
63
|
+
if (length == 0) return false;
|
|
64
|
+
|
|
52
65
|
size_t next_length = buffer->length + length;
|
|
66
|
+
const size_t original_capacity = buffer->capacity;
|
|
53
67
|
|
|
54
68
|
if (next_length > buffer->capacity) {
|
|
55
69
|
if (buffer->capacity == 0) {
|
|
@@ -60,7 +74,7 @@ pm_buffer_append_length(pm_buffer_t *buffer, size_t length) {
|
|
|
60
74
|
buffer->capacity *= 2;
|
|
61
75
|
}
|
|
62
76
|
|
|
63
|
-
buffer->value =
|
|
77
|
+
buffer->value = xrealloc_sized(buffer->value, buffer->capacity, original_capacity);
|
|
64
78
|
if (buffer->value == NULL) return false;
|
|
65
79
|
}
|
|
66
80
|
|
|
@@ -71,7 +85,7 @@ pm_buffer_append_length(pm_buffer_t *buffer, size_t length) {
|
|
|
71
85
|
/**
|
|
72
86
|
* Append a generic pointer to memory to the buffer.
|
|
73
87
|
*/
|
|
74
|
-
static
|
|
88
|
+
static PRISM_INLINE void
|
|
75
89
|
pm_buffer_append(pm_buffer_t *buffer, const void *source, size_t length) {
|
|
76
90
|
size_t cursor = buffer->length;
|
|
77
91
|
if (pm_buffer_append_length(buffer, length)) {
|
|
@@ -172,6 +186,15 @@ pm_buffer_append_double(pm_buffer_t *buffer, double value) {
|
|
|
172
186
|
pm_buffer_append(buffer, source, sizeof(double));
|
|
173
187
|
}
|
|
174
188
|
|
|
189
|
+
/**
|
|
190
|
+
* Append a 64-bit unsigned integer to the buffer in native endian order.
|
|
191
|
+
*/
|
|
192
|
+
void
|
|
193
|
+
pm_buffer_append_uint64(pm_buffer_t *buffer, uint64_t value) {
|
|
194
|
+
const void *source = &value;
|
|
195
|
+
pm_buffer_append(buffer, source, sizeof(uint64_t));
|
|
196
|
+
}
|
|
197
|
+
|
|
175
198
|
/**
|
|
176
199
|
* Append a unicode codepoint to the buffer.
|
|
177
200
|
*/
|
|
@@ -349,9 +372,18 @@ pm_buffer_insert(pm_buffer_t *buffer, size_t index, const char *value, size_t le
|
|
|
349
372
|
}
|
|
350
373
|
|
|
351
374
|
/**
|
|
352
|
-
* Free the memory
|
|
375
|
+
* Free the memory held by the buffer.
|
|
376
|
+
*/
|
|
377
|
+
void
|
|
378
|
+
pm_buffer_cleanup(pm_buffer_t *buffer) {
|
|
379
|
+
xfree_sized(buffer->value, buffer->capacity);
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
/**
|
|
383
|
+
* Free both the memory held by the buffer and the buffer itself.
|
|
353
384
|
*/
|
|
354
385
|
void
|
|
355
386
|
pm_buffer_free(pm_buffer_t *buffer) {
|
|
356
|
-
|
|
387
|
+
pm_buffer_cleanup(buffer);
|
|
388
|
+
xfree_sized(buffer, sizeof(pm_buffer_t));
|
|
357
389
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
#include "prism/
|
|
1
|
+
#include "prism/internal/char.h"
|
|
2
|
+
|
|
3
|
+
#include "prism/compiler/inline.h"
|
|
4
|
+
#include "prism/internal/line_offset_list.h"
|
|
2
5
|
|
|
3
|
-
#define PRISM_CHAR_BIT_WHITESPACE (1 << 0)
|
|
4
|
-
#define PRISM_CHAR_BIT_INLINE_WHITESPACE (1 << 1)
|
|
5
6
|
#define PRISM_CHAR_BIT_REGEXP_OPTION (1 << 2)
|
|
6
7
|
|
|
7
8
|
#define PRISM_NUMBER_BIT_BINARY_DIGIT (1 << 0)
|
|
@@ -13,7 +14,7 @@
|
|
|
13
14
|
#define PRISM_NUMBER_BIT_HEXADECIMAL_DIGIT (1 << 6)
|
|
14
15
|
#define PRISM_NUMBER_BIT_HEXADECIMAL_NUMBER (1 << 7)
|
|
15
16
|
|
|
16
|
-
|
|
17
|
+
const uint8_t pm_byte_table[256] = {
|
|
17
18
|
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
|
|
18
19
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 3, 3, 3, 0, 0, // 0x
|
|
19
20
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
|
|
@@ -57,7 +58,7 @@ static const uint8_t pm_number_table[256] = {
|
|
|
57
58
|
* Returns the number of characters at the start of the string that match the
|
|
58
59
|
* given kind. Disallows searching past the given maximum number of characters.
|
|
59
60
|
*/
|
|
60
|
-
static
|
|
61
|
+
static PRISM_INLINE size_t
|
|
61
62
|
pm_strspn_char_kind(const uint8_t *string, ptrdiff_t length, uint8_t kind) {
|
|
62
63
|
if (length <= 0) return 0;
|
|
63
64
|
|
|
@@ -77,21 +78,36 @@ pm_strspn_whitespace(const uint8_t *string, ptrdiff_t length) {
|
|
|
77
78
|
return pm_strspn_char_kind(string, length, PRISM_CHAR_BIT_WHITESPACE);
|
|
78
79
|
}
|
|
79
80
|
|
|
81
|
+
/**
|
|
82
|
+
* Returns the number of characters at the end of the string that are
|
|
83
|
+
* whitespace. Disallows searching past the given maximum number of characters.
|
|
84
|
+
*/
|
|
85
|
+
size_t
|
|
86
|
+
pm_strrspn_whitespace(const uint8_t *string, ptrdiff_t length) {
|
|
87
|
+
if (length <= 0) return 0;
|
|
88
|
+
|
|
89
|
+
size_t size = 0;
|
|
90
|
+
size_t maximum = (size_t) length;
|
|
91
|
+
|
|
92
|
+
while (size < maximum && (pm_byte_table[string[maximum - size - 1]] & PRISM_CHAR_BIT_WHITESPACE)) size++;
|
|
93
|
+
return size;
|
|
94
|
+
}
|
|
95
|
+
|
|
80
96
|
/**
|
|
81
97
|
* Returns the number of characters at the start of the string that are
|
|
82
98
|
* whitespace while also tracking the location of each newline. Disallows
|
|
83
99
|
* searching past the given maximum number of characters.
|
|
84
100
|
*/
|
|
85
101
|
size_t
|
|
86
|
-
pm_strspn_whitespace_newlines(const uint8_t *string, ptrdiff_t length,
|
|
102
|
+
pm_strspn_whitespace_newlines(const uint8_t *string, ptrdiff_t length, pm_arena_t *arena, pm_line_offset_list_t *line_offsets, uint32_t start_offset) {
|
|
87
103
|
if (length <= 0) return 0;
|
|
88
104
|
|
|
89
|
-
|
|
90
|
-
|
|
105
|
+
uint32_t size = 0;
|
|
106
|
+
uint32_t maximum = (uint32_t) length;
|
|
91
107
|
|
|
92
108
|
while (size < maximum && (pm_byte_table[string[size]] & PRISM_CHAR_BIT_WHITESPACE)) {
|
|
93
109
|
if (string[size] == '\n') {
|
|
94
|
-
|
|
110
|
+
pm_line_offset_list_append(arena, line_offsets, start_offset + size + 1);
|
|
95
111
|
}
|
|
96
112
|
|
|
97
113
|
size++;
|
|
@@ -100,15 +116,6 @@ pm_strspn_whitespace_newlines(const uint8_t *string, ptrdiff_t length, pm_newlin
|
|
|
100
116
|
return size;
|
|
101
117
|
}
|
|
102
118
|
|
|
103
|
-
/**
|
|
104
|
-
* Returns the number of characters at the start of the string that are inline
|
|
105
|
-
* whitespace. Disallows searching past the given maximum number of characters.
|
|
106
|
-
*/
|
|
107
|
-
size_t
|
|
108
|
-
pm_strspn_inline_whitespace(const uint8_t *string, ptrdiff_t length) {
|
|
109
|
-
return pm_strspn_char_kind(string, length, PRISM_CHAR_BIT_INLINE_WHITESPACE);
|
|
110
|
-
}
|
|
111
|
-
|
|
112
119
|
/**
|
|
113
120
|
* Returns the number of characters at the start of the string that are regexp
|
|
114
121
|
* options. Disallows searching past the given maximum number of characters.
|
|
@@ -118,36 +125,13 @@ pm_strspn_regexp_option(const uint8_t *string, ptrdiff_t length) {
|
|
|
118
125
|
return pm_strspn_char_kind(string, length, PRISM_CHAR_BIT_REGEXP_OPTION);
|
|
119
126
|
}
|
|
120
127
|
|
|
121
|
-
/**
|
|
122
|
-
* Returns true if the given character matches the given kind.
|
|
123
|
-
*/
|
|
124
|
-
static inline bool
|
|
125
|
-
pm_char_is_char_kind(const uint8_t b, uint8_t kind) {
|
|
126
|
-
return (pm_byte_table[b] & kind) != 0;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
/**
|
|
130
|
-
* Returns true if the given character is a whitespace character.
|
|
131
|
-
*/
|
|
132
|
-
bool
|
|
133
|
-
pm_char_is_whitespace(const uint8_t b) {
|
|
134
|
-
return pm_char_is_char_kind(b, PRISM_CHAR_BIT_WHITESPACE);
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
/**
|
|
138
|
-
* Returns true if the given character is an inline whitespace character.
|
|
139
|
-
*/
|
|
140
|
-
bool
|
|
141
|
-
pm_char_is_inline_whitespace(const uint8_t b) {
|
|
142
|
-
return pm_char_is_char_kind(b, PRISM_CHAR_BIT_INLINE_WHITESPACE);
|
|
143
|
-
}
|
|
144
128
|
|
|
145
129
|
/**
|
|
146
130
|
* Scan through the string and return the number of characters at the start of
|
|
147
131
|
* the string that match the given kind. Disallows searching past the given
|
|
148
132
|
* maximum number of characters.
|
|
149
133
|
*/
|
|
150
|
-
static
|
|
134
|
+
static PRISM_INLINE size_t
|
|
151
135
|
pm_strspn_number_kind(const uint8_t *string, ptrdiff_t length, uint8_t kind) {
|
|
152
136
|
if (length <= 0) return 0;
|
|
153
137
|
|
|
@@ -166,7 +150,7 @@ pm_strspn_number_kind(const uint8_t *string, ptrdiff_t length, uint8_t kind) {
|
|
|
166
150
|
* Additionally, report the location of the last invalid underscore character
|
|
167
151
|
* found in the string through the out invalid parameter.
|
|
168
152
|
*/
|
|
169
|
-
static
|
|
153
|
+
static PRISM_INLINE size_t
|
|
170
154
|
pm_strspn_number_kind_underscores(const uint8_t *string, ptrdiff_t length, const uint8_t **invalid, uint8_t kind) {
|
|
171
155
|
if (length <= 0) return 0;
|
|
172
156
|
|
|
@@ -267,7 +251,7 @@ pm_strspn_hexadecimal_number(const uint8_t *string, ptrdiff_t length, const uint
|
|
|
267
251
|
/**
|
|
268
252
|
* Returns true if the given character matches the given kind.
|
|
269
253
|
*/
|
|
270
|
-
static
|
|
254
|
+
static PRISM_INLINE bool
|
|
271
255
|
pm_char_is_number_kind(const uint8_t b, uint8_t kind) {
|
|
272
256
|
return (pm_number_table[b] & kind) != 0;
|
|
273
257
|
}
|
|
@@ -303,16 +287,3 @@ bool
|
|
|
303
287
|
pm_char_is_hexadecimal_digit(const uint8_t b) {
|
|
304
288
|
return pm_char_is_number_kind(b, PRISM_NUMBER_BIT_HEXADECIMAL_DIGIT);
|
|
305
289
|
}
|
|
306
|
-
|
|
307
|
-
#undef PRISM_CHAR_BIT_WHITESPACE
|
|
308
|
-
#undef PRISM_CHAR_BIT_INLINE_WHITESPACE
|
|
309
|
-
#undef PRISM_CHAR_BIT_REGEXP_OPTION
|
|
310
|
-
|
|
311
|
-
#undef PRISM_NUMBER_BIT_BINARY_DIGIT
|
|
312
|
-
#undef PRISM_NUMBER_BIT_BINARY_NUMBER
|
|
313
|
-
#undef PRISM_NUMBER_BIT_OCTAL_DIGIT
|
|
314
|
-
#undef PRISM_NUMBER_BIT_OCTAL_NUMBER
|
|
315
|
-
#undef PRISM_NUMBER_BIT_DECIMAL_DIGIT
|
|
316
|
-
#undef PRISM_NUMBER_BIT_DECIMAL_NUMBER
|
|
317
|
-
#undef PRISM_NUMBER_BIT_HEXADECIMAL_NUMBER
|
|
318
|
-
#undef PRISM_NUMBER_BIT_HEXADECIMAL_DIGIT
|