prism 1.4.0 → 1.6.0
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 +51 -1
- data/Makefile +4 -2
- data/README.md +2 -0
- data/config.yml +266 -38
- data/docs/design.md +2 -2
- data/docs/parser_translation.md +8 -23
- data/docs/releasing.md +5 -24
- data/docs/ripper_translation.md +1 -1
- data/ext/prism/api_node.c +2 -0
- data/ext/prism/extension.c +25 -3
- data/ext/prism/extension.h +1 -1
- data/include/prism/ast.h +306 -50
- data/include/prism/diagnostic.h +5 -0
- data/include/prism/options.h +43 -3
- data/include/prism/regexp.h +2 -2
- data/include/prism/util/pm_buffer.h +8 -0
- data/include/prism/util/pm_integer.h +4 -0
- data/include/prism/util/pm_list.h +6 -0
- data/include/prism/util/pm_string.h +12 -2
- data/include/prism/version.h +2 -2
- data/include/prism.h +39 -14
- data/lib/prism/compiler.rb +456 -151
- data/lib/prism/desugar_compiler.rb +1 -0
- data/lib/prism/dispatcher.rb +16 -0
- data/lib/prism/dot_visitor.rb +5 -1
- data/lib/prism/dsl.rb +3 -0
- data/lib/prism/ffi.rb +25 -9
- data/lib/prism/inspect_visitor.rb +3 -0
- data/lib/prism/lex_compat.rb +1 -0
- data/lib/prism/mutation_compiler.rb +3 -0
- data/lib/prism/node.rb +507 -336
- data/lib/prism/node_ext.rb +4 -1
- data/lib/prism/pack.rb +2 -0
- data/lib/prism/parse_result/comments.rb +1 -0
- data/lib/prism/parse_result/errors.rb +1 -0
- data/lib/prism/parse_result/newlines.rb +1 -0
- data/lib/prism/parse_result.rb +1 -0
- data/lib/prism/pattern.rb +1 -0
- data/lib/prism/polyfill/scan_byte.rb +14 -0
- data/lib/prism/polyfill/warn.rb +36 -0
- data/lib/prism/reflection.rb +3 -0
- data/lib/prism/relocation.rb +1 -0
- data/lib/prism/serialize.rb +25 -19
- data/lib/prism/string_query.rb +1 -0
- data/lib/prism/translation/parser/builder.rb +1 -0
- data/lib/prism/translation/parser/compiler.rb +47 -25
- data/lib/prism/translation/parser/lexer.rb +29 -21
- data/lib/prism/translation/parser.rb +21 -2
- data/lib/prism/translation/parser33.rb +1 -0
- data/lib/prism/translation/parser34.rb +1 -0
- data/lib/prism/translation/parser35.rb +1 -0
- data/lib/prism/translation/parser_current.rb +24 -0
- data/lib/prism/translation/ripper/sexp.rb +1 -0
- data/lib/prism/translation/ripper.rb +17 -1
- data/lib/prism/translation/ruby_parser.rb +287 -4
- data/lib/prism/translation.rb +2 -0
- data/lib/prism/visitor.rb +457 -152
- data/lib/prism.rb +23 -0
- data/prism.gemspec +5 -1
- data/rbi/prism/dsl.rbi +3 -3
- data/rbi/prism/node.rbi +21 -9
- data/sig/prism/dispatcher.rbs +3 -0
- data/sig/prism/dsl.rbs +3 -3
- data/sig/prism/node.rbs +444 -30
- data/sig/prism/node_ext.rbs +84 -17
- data/sig/prism/parse_result/comments.rbs +38 -0
- data/sig/prism/parse_result.rbs +4 -0
- data/sig/prism/reflection.rbs +1 -1
- data/sig/prism.rbs +4 -0
- data/src/diagnostic.c +9 -1
- data/src/node.c +2 -0
- data/src/options.c +2 -2
- data/src/prettyprint.c +2 -0
- data/src/prism.c +324 -147
- data/src/serialize.c +2 -0
- data/src/token_type.c +36 -34
- data/src/util/pm_string.c +6 -8
- metadata +7 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2ef507799374ba0281ff3d8ab78fc29f673b3fc213f695ae68c65cf0d38b4bcc
|
|
4
|
+
data.tar.gz: 7610a756cffd1aeb517f135446ae25360568cc00e6d78e748470469bd345463c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 539d064482f82c7fd85c7e8269b1c400fd576b20effbcb857636667ce8818367eea35446bc7ee2decf3cdde7171883e8aeaa154c2bf1b8d7f3c7fa5c12203f08
|
|
7
|
+
data.tar.gz: 59181adcac710bf7697b1dec0556eb306f9cf79d2b7492e0392d9698401dd3abb5a1406fc5d66d1c4d0acbd85d9ebf8e674683e9ec585d765216953f80a75297
|
data/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,52 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [1.6.0] - 2025-10-16
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- Add support for passing `"current"` as the version option to `Prism.*` APIs.
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
- Remove a compiler warning for a missing unsigned cast for a shift value.
|
|
18
|
+
|
|
19
|
+
## [1.5.2] - 2025-10-09
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
|
|
23
|
+
- Fix character literal forced encoding when a unicode escape sequence is used.
|
|
24
|
+
- Reject `1 if foo = bar baz`.
|
|
25
|
+
- Clear static literal flag on interpolated strings.
|
|
26
|
+
- Reject optional argument/endless method definition ambiguity.
|
|
27
|
+
|
|
28
|
+
## [1.5.1] - 2025-09-13
|
|
29
|
+
|
|
30
|
+
### Changed
|
|
31
|
+
|
|
32
|
+
- Revert of a bug introduced with static literal flags on interpolated strings.
|
|
33
|
+
|
|
34
|
+
## [1.5.0] - 2025-09-12
|
|
35
|
+
|
|
36
|
+
### Added
|
|
37
|
+
|
|
38
|
+
- Add `Prism::Translation::ParserCurrent`.
|
|
39
|
+
- Add `Integer::to_u32_digits` for the Rust API.
|
|
40
|
+
- Add `pm_comment_type_t` field for the Rust API.
|
|
41
|
+
- Support leading logical operators for CRuby 3.5+.
|
|
42
|
+
|
|
43
|
+
### Changed
|
|
44
|
+
|
|
45
|
+
- Mark Prism as ractor-safe.
|
|
46
|
+
- Enforce a minimum version for the parser translation layer.
|
|
47
|
+
- Many fixes to the parser translation layer.
|
|
48
|
+
- Accept a newline after the `defined?` keyword.
|
|
49
|
+
- Reject `true && not true`.
|
|
50
|
+
- Make `it = it` assign nil to match parse.y behavior [Bug #21139].
|
|
51
|
+
- Some fixes to the ruby parser translation layer.
|
|
52
|
+
- Ensure call nodes have the correct ending location.
|
|
53
|
+
- Reject `foo && return bar`.
|
|
54
|
+
|
|
9
55
|
## [1.4.0] - 2025-03-18
|
|
10
56
|
|
|
11
57
|
### Added
|
|
@@ -649,7 +695,11 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a
|
|
|
649
695
|
|
|
650
696
|
- 🎉 Initial release! 🎉
|
|
651
697
|
|
|
652
|
-
[unreleased]: https://github.com/ruby/prism/compare/v1.
|
|
698
|
+
[unreleased]: https://github.com/ruby/prism/compare/v1.6.0...HEAD
|
|
699
|
+
[1.6.0]: https://github.com/ruby/prism/compare/v1.5.2...v1.6.0
|
|
700
|
+
[1.5.2]: https://github.com/ruby/prism/compare/v1.5.1...v1.5.2
|
|
701
|
+
[1.5.1]: https://github.com/ruby/prism/compare/v1.5.0...v1.5.1
|
|
702
|
+
[1.5.0]: https://github.com/ruby/prism/compare/v1.4.0...v1.5.0
|
|
653
703
|
[1.4.0]: https://github.com/ruby/prism/compare/v1.3.0...v1.4.0
|
|
654
704
|
[1.3.0]: https://github.com/ruby/prism/compare/v1.2.0...v1.3.0
|
|
655
705
|
[1.2.0]: https://github.com/ruby/prism/compare/v1.1.0...v1.2.0
|
data/Makefile
CHANGED
|
@@ -12,8 +12,10 @@ SOEXT ?= $(shell ruby -e 'puts RbConfig::CONFIG["SOEXT"]')
|
|
|
12
12
|
|
|
13
13
|
CPPFLAGS := -Iinclude $(CPPFLAGS)
|
|
14
14
|
CFLAGS := -g -O2 -std=c99 -Wall -Werror -Wextra -Wpedantic -Wundef -Wconversion -Wno-missing-braces -fPIC -fvisibility=hidden -Wimplicit-fallthrough $(CFLAGS)
|
|
15
|
+
JAVA_WASM_CFLAGS := -g -Oz -std=c99 -Wall -Werror -Wextra -Wpedantic -Wundef -Wconversion -Wno-missing-braces -fPIC -fvisibility=hidden -Wimplicit-fallthrough $(JAVA_WASM_CFLAGS)
|
|
15
16
|
CC ?= cc
|
|
16
17
|
AR ?= ar
|
|
18
|
+
ARFLAGS ?= -r$(V0:1=v)
|
|
17
19
|
WASI_SDK_PATH := /opt/wasi-sdk
|
|
18
20
|
|
|
19
21
|
MAKEDIRS ?= mkdir -p
|
|
@@ -37,7 +39,7 @@ build/libprism.$(SOEXT): $(SHARED_OBJECTS)
|
|
|
37
39
|
|
|
38
40
|
build/libprism.a: $(STATIC_OBJECTS)
|
|
39
41
|
$(ECHO) "building $@ with $(AR)"
|
|
40
|
-
$(Q) $(AR) $(ARFLAGS) $@ $(STATIC_OBJECTS)
|
|
42
|
+
$(Q) $(AR) $(ARFLAGS) $@ $(STATIC_OBJECTS)
|
|
41
43
|
|
|
42
44
|
javascript/src/prism.wasm: Makefile $(SOURCES) $(HEADERS)
|
|
43
45
|
$(ECHO) "building $@"
|
|
@@ -45,7 +47,7 @@ javascript/src/prism.wasm: Makefile $(SOURCES) $(HEADERS)
|
|
|
45
47
|
|
|
46
48
|
java-wasm/src/test/resources/prism.wasm: Makefile $(SOURCES) $(HEADERS)
|
|
47
49
|
$(ECHO) "building $@"
|
|
48
|
-
$(Q) $(WASI_SDK_PATH)/bin/clang $(DEBUG_FLAGS) -DPRISM_EXPORT_SYMBOLS -D_WASI_EMULATED_MMAN -lwasi-emulated-mman $(CPPFLAGS) $(
|
|
50
|
+
$(Q) $(WASI_SDK_PATH)/bin/clang $(DEBUG_FLAGS) -DPRISM_EXCLUDE_PRETTYPRINT -DPRISM_EXPORT_SYMBOLS -D_WASI_EMULATED_MMAN -lwasi-emulated-mman $(CPPFLAGS) $(JAVA_WASM_CFLAGS) -Wl,--export-all -Wl,--no-entry -mexec-model=reactor -lc++ -lc++abi -o $@ $(SOURCES)
|
|
49
51
|
|
|
50
52
|
build/shared/%.o: src/%.c Makefile $(HEADERS)
|
|
51
53
|
$(ECHO) "compiling $@"
|
data/README.md
CHANGED
|
@@ -135,7 +135,9 @@ Prism has been integrated into the majority of Ruby runtimes, many libraries, an
|
|
|
135
135
|
* [sorbet-eraser](https://github.com/kddnewton/sorbet-eraser/pull/25)
|
|
136
136
|
* [synvert](https://github.com/xinminlabs/synvert-core-ruby)
|
|
137
137
|
* [typeprof](https://github.com/ruby/typeprof)
|
|
138
|
+
* [unparser](https://github.com/mbj/unparser) (via parser translator)
|
|
138
139
|
|
|
139
140
|
### Applications
|
|
140
141
|
|
|
141
142
|
* [gem.sh](https://github.com/marcoroth/gem.sh/pull/96)
|
|
143
|
+
* [Sorbet](https://github.com/sorbet/sorbet)
|
data/config.yml
CHANGED
|
@@ -60,6 +60,7 @@ errors:
|
|
|
60
60
|
- CONDITIONAL_WHILE_PREDICATE
|
|
61
61
|
- CONSTANT_PATH_COLON_COLON_CONSTANT
|
|
62
62
|
- DEF_ENDLESS
|
|
63
|
+
- DEF_ENDLESS_PARAMETERS
|
|
63
64
|
- DEF_ENDLESS_SETTER
|
|
64
65
|
- DEF_NAME
|
|
65
66
|
- DEF_PARAMS_TERM
|
|
@@ -101,6 +102,8 @@ errors:
|
|
|
101
102
|
- EXPECT_FOR_DELIMITER
|
|
102
103
|
- EXPECT_IDENT_REQ_PARAMETER
|
|
103
104
|
- EXPECT_IN_DELIMITER
|
|
105
|
+
- EXPECT_LPAREN_AFTER_NOT_LPAREN
|
|
106
|
+
- EXPECT_LPAREN_AFTER_NOT_OTHER
|
|
104
107
|
- EXPECT_LPAREN_REQ_PARAMETER
|
|
105
108
|
- EXPECT_MESSAGE
|
|
106
109
|
- EXPECT_RBRACKET
|
|
@@ -320,13 +323,42 @@ warnings:
|
|
|
320
323
|
- UNUSED_LOCAL_VARIABLE
|
|
321
324
|
- VOID_STATEMENT
|
|
322
325
|
tokens:
|
|
326
|
+
# The order of the tokens at the beginning is important, because we use them
|
|
327
|
+
# for a lookup table.
|
|
323
328
|
- name: EOF
|
|
324
329
|
value: 1
|
|
325
330
|
comment: final token in the file
|
|
326
|
-
- name:
|
|
327
|
-
comment: "
|
|
328
|
-
- name:
|
|
329
|
-
comment: "
|
|
331
|
+
- name: BRACE_RIGHT
|
|
332
|
+
comment: "}"
|
|
333
|
+
- name: COMMA
|
|
334
|
+
comment: ","
|
|
335
|
+
- name: EMBEXPR_END
|
|
336
|
+
comment: "}"
|
|
337
|
+
- name: KEYWORD_DO
|
|
338
|
+
comment: "do"
|
|
339
|
+
- name: KEYWORD_ELSE
|
|
340
|
+
comment: "else"
|
|
341
|
+
- name: KEYWORD_ELSIF
|
|
342
|
+
comment: "elsif"
|
|
343
|
+
- name: KEYWORD_END
|
|
344
|
+
comment: "end"
|
|
345
|
+
- name: KEYWORD_ENSURE
|
|
346
|
+
comment: "ensure"
|
|
347
|
+
- name: KEYWORD_IN
|
|
348
|
+
comment: "in"
|
|
349
|
+
- name: KEYWORD_RESCUE
|
|
350
|
+
comment: "rescue"
|
|
351
|
+
- name: KEYWORD_THEN
|
|
352
|
+
comment: "then"
|
|
353
|
+
- name: KEYWORD_WHEN
|
|
354
|
+
comment: "when"
|
|
355
|
+
- name: NEWLINE
|
|
356
|
+
comment: "a newline character outside of other tokens"
|
|
357
|
+
- name: PARENTHESIS_RIGHT
|
|
358
|
+
comment: ")"
|
|
359
|
+
- name: SEMICOLON
|
|
360
|
+
comment: ";"
|
|
361
|
+
# Tokens from here on are not used for lookup, and can be in any order.
|
|
330
362
|
- name: AMPERSAND
|
|
331
363
|
comment: "&"
|
|
332
364
|
- name: AMPERSAND_AMPERSAND
|
|
@@ -349,8 +381,6 @@ tokens:
|
|
|
349
381
|
comment: "!~"
|
|
350
382
|
- name: BRACE_LEFT
|
|
351
383
|
comment: "{"
|
|
352
|
-
- name: BRACE_RIGHT
|
|
353
|
-
comment: "}"
|
|
354
384
|
- name: BRACKET_LEFT
|
|
355
385
|
comment: "["
|
|
356
386
|
- name: BRACKET_LEFT_ARRAY
|
|
@@ -373,8 +403,6 @@ tokens:
|
|
|
373
403
|
comment: ":"
|
|
374
404
|
- name: COLON_COLON
|
|
375
405
|
comment: "::"
|
|
376
|
-
- name: COMMA
|
|
377
|
-
comment: ","
|
|
378
406
|
- name: COMMENT
|
|
379
407
|
comment: "a comment"
|
|
380
408
|
- name: CONSTANT
|
|
@@ -393,8 +421,6 @@ tokens:
|
|
|
393
421
|
comment: "a line inside of embedded documentation"
|
|
394
422
|
- name: EMBEXPR_BEGIN
|
|
395
423
|
comment: "#{"
|
|
396
|
-
- name: EMBEXPR_END
|
|
397
|
-
comment: "}"
|
|
398
424
|
- name: EMBVAR
|
|
399
425
|
comment: "#"
|
|
400
426
|
- name: EQUAL
|
|
@@ -461,20 +487,10 @@ tokens:
|
|
|
461
487
|
comment: "def"
|
|
462
488
|
- name: KEYWORD_DEFINED
|
|
463
489
|
comment: "defined?"
|
|
464
|
-
- name: KEYWORD_DO
|
|
465
|
-
comment: "do"
|
|
466
490
|
- name: KEYWORD_DO_LOOP
|
|
467
491
|
comment: "do keyword for a predicate in a while, until, or for loop"
|
|
468
|
-
- name: KEYWORD_ELSE
|
|
469
|
-
comment: "else"
|
|
470
|
-
- name: KEYWORD_ELSIF
|
|
471
|
-
comment: "elsif"
|
|
472
|
-
- name: KEYWORD_END
|
|
473
|
-
comment: "end"
|
|
474
492
|
- name: KEYWORD_END_UPCASE
|
|
475
493
|
comment: "END"
|
|
476
|
-
- name: KEYWORD_ENSURE
|
|
477
|
-
comment: "ensure"
|
|
478
494
|
- name: KEYWORD_FALSE
|
|
479
495
|
comment: "false"
|
|
480
496
|
- name: KEYWORD_FOR
|
|
@@ -483,8 +499,6 @@ tokens:
|
|
|
483
499
|
comment: "if"
|
|
484
500
|
- name: KEYWORD_IF_MODIFIER
|
|
485
501
|
comment: "if in the modifier form"
|
|
486
|
-
- name: KEYWORD_IN
|
|
487
|
-
comment: "in"
|
|
488
502
|
- name: KEYWORD_MODULE
|
|
489
503
|
comment: "module"
|
|
490
504
|
- name: KEYWORD_NEXT
|
|
@@ -497,8 +511,6 @@ tokens:
|
|
|
497
511
|
comment: "or"
|
|
498
512
|
- name: KEYWORD_REDO
|
|
499
513
|
comment: "redo"
|
|
500
|
-
- name: KEYWORD_RESCUE
|
|
501
|
-
comment: "rescue"
|
|
502
514
|
- name: KEYWORD_RESCUE_MODIFIER
|
|
503
515
|
comment: "rescue in the modifier form"
|
|
504
516
|
- name: KEYWORD_RETRY
|
|
@@ -509,8 +521,6 @@ tokens:
|
|
|
509
521
|
comment: "self"
|
|
510
522
|
- name: KEYWORD_SUPER
|
|
511
523
|
comment: "super"
|
|
512
|
-
- name: KEYWORD_THEN
|
|
513
|
-
comment: "then"
|
|
514
524
|
- name: KEYWORD_TRUE
|
|
515
525
|
comment: "true"
|
|
516
526
|
- name: KEYWORD_UNDEF
|
|
@@ -523,8 +533,6 @@ tokens:
|
|
|
523
533
|
comment: "until"
|
|
524
534
|
- name: KEYWORD_UNTIL_MODIFIER
|
|
525
535
|
comment: "until in the modifier form"
|
|
526
|
-
- name: KEYWORD_WHEN
|
|
527
|
-
comment: "when"
|
|
528
536
|
- name: KEYWORD_WHILE
|
|
529
537
|
comment: "while"
|
|
530
538
|
- name: KEYWORD_WHILE_MODIFIER
|
|
@@ -561,16 +569,12 @@ tokens:
|
|
|
561
569
|
comment: "-="
|
|
562
570
|
- name: MINUS_GREATER
|
|
563
571
|
comment: "->"
|
|
564
|
-
- name: NEWLINE
|
|
565
|
-
comment: "a newline character outside of other tokens"
|
|
566
572
|
- name: NUMBERED_REFERENCE
|
|
567
573
|
comment: "a numbered reference to a capture group in the previous regular expression match"
|
|
568
574
|
- name: PARENTHESIS_LEFT
|
|
569
575
|
comment: "("
|
|
570
576
|
- name: PARENTHESIS_LEFT_PARENTHESES
|
|
571
577
|
comment: "( for a parentheses node"
|
|
572
|
-
- name: PARENTHESIS_RIGHT
|
|
573
|
-
comment: ")"
|
|
574
578
|
- name: PERCENT
|
|
575
579
|
comment: "%"
|
|
576
580
|
- name: PERCENT_EQUAL
|
|
@@ -603,8 +607,6 @@ tokens:
|
|
|
603
607
|
comment: "the beginning of a regular expression"
|
|
604
608
|
- name: REGEXP_END
|
|
605
609
|
comment: "the end of a regular expression"
|
|
606
|
-
- name: SEMICOLON
|
|
607
|
-
comment: ";"
|
|
608
610
|
- name: SLASH
|
|
609
611
|
comment: "/"
|
|
610
612
|
- name: SLASH_EQUAL
|
|
@@ -649,6 +651,10 @@ tokens:
|
|
|
649
651
|
comment: "a separator between words in a list"
|
|
650
652
|
- name: __END__
|
|
651
653
|
comment: "marker for the point in the file at which the parser should stop"
|
|
654
|
+
- name: MISSING
|
|
655
|
+
comment: "a token that was expected but not found"
|
|
656
|
+
- name: NOT_PROVIDED
|
|
657
|
+
comment: "a token that was not present but it is okay"
|
|
652
658
|
flags:
|
|
653
659
|
- name: ArgumentsNodeFlags
|
|
654
660
|
values:
|
|
@@ -987,8 +993,19 @@ nodes:
|
|
|
987
993
|
- name: constant
|
|
988
994
|
type: node?
|
|
989
995
|
kind:
|
|
990
|
-
- ConstantReadNode
|
|
991
996
|
- ConstantPathNode
|
|
997
|
+
- ConstantReadNode
|
|
998
|
+
comment: |
|
|
999
|
+
Represents the optional constant preceding the Array
|
|
1000
|
+
|
|
1001
|
+
foo in Bar[]
|
|
1002
|
+
^^^
|
|
1003
|
+
|
|
1004
|
+
foo in Bar[1, 2, 3]
|
|
1005
|
+
^^^
|
|
1006
|
+
|
|
1007
|
+
foo in Bar::Baz[1, 2, 3]
|
|
1008
|
+
^^^^^^^^
|
|
992
1009
|
- name: requireds
|
|
993
1010
|
type: node[]
|
|
994
1011
|
kind: pattern expression
|
|
@@ -1784,7 +1801,7 @@ nodes:
|
|
|
1784
1801
|
Represents the predicate of the case statement. This can be either `nil` or any [non-void expressions](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression).
|
|
1785
1802
|
|
|
1786
1803
|
case true; when false; end
|
|
1787
|
-
|
|
1804
|
+
^^^^
|
|
1788
1805
|
- name: conditions
|
|
1789
1806
|
type: node[]
|
|
1790
1807
|
kind: WhenNode
|
|
@@ -1828,6 +1845,11 @@ nodes:
|
|
|
1828
1845
|
type: constant[]
|
|
1829
1846
|
- name: class_keyword_loc
|
|
1830
1847
|
type: location
|
|
1848
|
+
comment: |
|
|
1849
|
+
Represents the location of the `class` keyword.
|
|
1850
|
+
|
|
1851
|
+
class Foo end
|
|
1852
|
+
^^^^^
|
|
1831
1853
|
- name: constant_path
|
|
1832
1854
|
type: node
|
|
1833
1855
|
kind:
|
|
@@ -1836,18 +1858,43 @@ nodes:
|
|
|
1836
1858
|
- on error: CallNode # class 0.X end
|
|
1837
1859
|
- name: inheritance_operator_loc
|
|
1838
1860
|
type: location?
|
|
1861
|
+
comment: |
|
|
1862
|
+
Represents the location of the `<` operator.
|
|
1863
|
+
|
|
1864
|
+
class Foo < Bar
|
|
1865
|
+
^
|
|
1839
1866
|
- name: superclass
|
|
1840
1867
|
type: node?
|
|
1841
1868
|
kind: non-void expression
|
|
1869
|
+
comment: |
|
|
1870
|
+
Represents the superclass of the class.
|
|
1871
|
+
|
|
1872
|
+
class Foo < Bar
|
|
1873
|
+
^^^
|
|
1842
1874
|
- name: body
|
|
1843
1875
|
type: node?
|
|
1844
1876
|
kind:
|
|
1845
1877
|
- StatementsNode
|
|
1846
1878
|
- BeginNode
|
|
1879
|
+
comment: |
|
|
1880
|
+
Represents the body of the class.
|
|
1881
|
+
|
|
1882
|
+
class Foo
|
|
1883
|
+
foo
|
|
1884
|
+
^^^
|
|
1847
1885
|
- name: end_keyword_loc
|
|
1848
1886
|
type: location
|
|
1887
|
+
comment: |
|
|
1888
|
+
Represents the location of the `end` keyword.
|
|
1889
|
+
|
|
1890
|
+
class Foo end
|
|
1891
|
+
^^^
|
|
1849
1892
|
- name: name
|
|
1850
1893
|
type: constant
|
|
1894
|
+
comment: |
|
|
1895
|
+
The name of the class.
|
|
1896
|
+
|
|
1897
|
+
class Foo end # name `:Foo`
|
|
1851
1898
|
comment: |
|
|
1852
1899
|
Represents a class declaration involving the `class` keyword.
|
|
1853
1900
|
|
|
@@ -2374,23 +2421,68 @@ nodes:
|
|
|
2374
2421
|
- name: constant
|
|
2375
2422
|
type: node?
|
|
2376
2423
|
kind:
|
|
2377
|
-
- ConstantReadNode
|
|
2378
2424
|
- ConstantPathNode
|
|
2425
|
+
- ConstantReadNode
|
|
2426
|
+
comment: |
|
|
2427
|
+
Represents the optional constant preceding the pattern
|
|
2428
|
+
|
|
2429
|
+
foo in Foo(*bar, baz, *qux)
|
|
2430
|
+
^^^
|
|
2379
2431
|
- name: left
|
|
2380
2432
|
type: node
|
|
2381
2433
|
kind: SplatNode
|
|
2434
|
+
comment: |
|
|
2435
|
+
Represents the first wildcard node in the pattern.
|
|
2436
|
+
|
|
2437
|
+
foo in *bar, baz, *qux
|
|
2438
|
+
^^^^
|
|
2439
|
+
|
|
2440
|
+
foo in Foo(*bar, baz, *qux)
|
|
2441
|
+
^^^^
|
|
2382
2442
|
- name: requireds
|
|
2383
2443
|
type: node[]
|
|
2384
2444
|
kind: pattern expression
|
|
2445
|
+
comment: |
|
|
2446
|
+
Represents the nodes in between the wildcards.
|
|
2447
|
+
|
|
2448
|
+
foo in *bar, baz, *qux
|
|
2449
|
+
^^^
|
|
2450
|
+
|
|
2451
|
+
foo in Foo(*bar, baz, 1, *qux)
|
|
2452
|
+
^^^^^^
|
|
2385
2453
|
- name: right
|
|
2386
2454
|
type: node
|
|
2387
2455
|
kind:
|
|
2388
2456
|
- SplatNode
|
|
2389
2457
|
- on error: MissingNode
|
|
2458
|
+
comment: |
|
|
2459
|
+
Represents the second wildcard node in the pattern.
|
|
2460
|
+
|
|
2461
|
+
foo in *bar, baz, *qux
|
|
2462
|
+
^^^^
|
|
2463
|
+
|
|
2464
|
+
foo in Foo(*bar, baz, *qux)
|
|
2465
|
+
^^^^
|
|
2390
2466
|
- name: opening_loc
|
|
2391
2467
|
type: location?
|
|
2468
|
+
comment: |
|
|
2469
|
+
The location of the opening brace.
|
|
2470
|
+
|
|
2471
|
+
foo in [*bar, baz, *qux]
|
|
2472
|
+
^
|
|
2473
|
+
|
|
2474
|
+
foo in Foo(*bar, baz, *qux)
|
|
2475
|
+
^
|
|
2392
2476
|
- name: closing_loc
|
|
2393
2477
|
type: location?
|
|
2478
|
+
comment: |
|
|
2479
|
+
The location of the closing brace.
|
|
2480
|
+
|
|
2481
|
+
foo in [*bar, baz, *qux]
|
|
2482
|
+
^
|
|
2483
|
+
|
|
2484
|
+
foo in Foo(*bar, baz, *qux)
|
|
2485
|
+
^
|
|
2394
2486
|
comment: |
|
|
2395
2487
|
Represents a find pattern in pattern matching.
|
|
2396
2488
|
|
|
@@ -2402,6 +2494,9 @@ nodes:
|
|
|
2402
2494
|
|
|
2403
2495
|
foo in Foo(*bar, baz, *qux)
|
|
2404
2496
|
^^^^^^^^^^^^^^^^^^^^
|
|
2497
|
+
|
|
2498
|
+
foo => *bar, baz, *qux
|
|
2499
|
+
^^^^^^^^^^^^^^^
|
|
2405
2500
|
- name: FlipFlopNode
|
|
2406
2501
|
flags: RangeFlags
|
|
2407
2502
|
fields:
|
|
@@ -2679,20 +2774,60 @@ nodes:
|
|
|
2679
2774
|
- name: constant
|
|
2680
2775
|
type: node?
|
|
2681
2776
|
kind:
|
|
2682
|
-
- ConstantReadNode
|
|
2683
2777
|
- ConstantPathNode
|
|
2778
|
+
- ConstantReadNode
|
|
2779
|
+
comment: |
|
|
2780
|
+
Represents the optional constant preceding the Hash.
|
|
2781
|
+
|
|
2782
|
+
foo => Bar[a: 1, b: 2]
|
|
2783
|
+
^^^
|
|
2784
|
+
|
|
2785
|
+
foo => Bar::Baz[a: 1, b: 2]
|
|
2786
|
+
^^^^^^^^
|
|
2684
2787
|
- name: elements
|
|
2685
2788
|
type: node[]
|
|
2686
2789
|
kind: AssocNode
|
|
2790
|
+
comment: |
|
|
2791
|
+
Represents the explicit named hash keys and values.
|
|
2792
|
+
|
|
2793
|
+
foo => { a: 1, b:, ** }
|
|
2794
|
+
^^^^^^^^
|
|
2687
2795
|
- name: rest
|
|
2688
2796
|
type: node?
|
|
2689
2797
|
kind:
|
|
2690
2798
|
- AssocSplatNode
|
|
2691
2799
|
- NoKeywordsParameterNode
|
|
2800
|
+
comment: |
|
|
2801
|
+
Represents the rest of the Hash keys and values. This can be named, unnamed, or explicitly forbidden via `**nil`, this last one results in a `NoKeywordsParameterNode`.
|
|
2802
|
+
|
|
2803
|
+
foo => { a: 1, b:, **c }
|
|
2804
|
+
^^^
|
|
2805
|
+
|
|
2806
|
+
foo => { a: 1, b:, ** }
|
|
2807
|
+
^^
|
|
2808
|
+
|
|
2809
|
+
foo => { a: 1, b:, **nil }
|
|
2810
|
+
^^^^^
|
|
2692
2811
|
- name: opening_loc
|
|
2693
2812
|
type: location?
|
|
2813
|
+
comment: |
|
|
2814
|
+
The location of the opening brace.
|
|
2815
|
+
|
|
2816
|
+
foo => { a: 1 }
|
|
2817
|
+
^
|
|
2818
|
+
|
|
2819
|
+
foo => Bar[a: 1]
|
|
2820
|
+
^
|
|
2694
2821
|
- name: closing_loc
|
|
2695
2822
|
type: location?
|
|
2823
|
+
comment: |
|
|
2824
|
+
The location of the closing brace.
|
|
2825
|
+
|
|
2826
|
+
foo => { a: 1 }
|
|
2827
|
+
^
|
|
2828
|
+
|
|
2829
|
+
foo => Bar[a: 1]
|
|
2830
|
+
^
|
|
2696
2831
|
comment: |
|
|
2697
2832
|
Represents a hash pattern in pattern matching.
|
|
2698
2833
|
|
|
@@ -2701,6 +2836,12 @@ nodes:
|
|
|
2701
2836
|
|
|
2702
2837
|
foo => { a: 1, b: 2, **c }
|
|
2703
2838
|
^^^^^^^^^^^^^^^^^^^
|
|
2839
|
+
|
|
2840
|
+
foo => Bar[a: 1, b: 2]
|
|
2841
|
+
^^^^^^^^^^^^^^^
|
|
2842
|
+
|
|
2843
|
+
foo in { a: 1, b: 2 }
|
|
2844
|
+
^^^^^^^^^^^^^^
|
|
2704
2845
|
- name: IfNode
|
|
2705
2846
|
fields:
|
|
2706
2847
|
- name: if_keyword_loc
|
|
@@ -3353,6 +3494,9 @@ nodes:
|
|
|
3353
3494
|
|
|
3354
3495
|
foo, bar = baz
|
|
3355
3496
|
^^^ ^^^
|
|
3497
|
+
|
|
3498
|
+
foo => baz
|
|
3499
|
+
^^^
|
|
3356
3500
|
- name: LocalVariableWriteNode
|
|
3357
3501
|
fields:
|
|
3358
3502
|
- name: name
|
|
@@ -3443,11 +3587,65 @@ nodes:
|
|
|
3443
3587
|
- name: value
|
|
3444
3588
|
type: node
|
|
3445
3589
|
kind: non-void expression
|
|
3590
|
+
comment: |
|
|
3591
|
+
Represents the left-hand side of the operator.
|
|
3592
|
+
|
|
3593
|
+
foo => bar
|
|
3594
|
+
^^^
|
|
3446
3595
|
- name: pattern
|
|
3447
3596
|
type: node
|
|
3448
3597
|
kind: pattern expression
|
|
3598
|
+
comment: |
|
|
3599
|
+
Represents the right-hand side of the operator. The type of the node depends on the expression.
|
|
3600
|
+
|
|
3601
|
+
Anything that looks like a local variable name (including `_`) will result in a `LocalVariableTargetNode`.
|
|
3602
|
+
|
|
3603
|
+
foo => a # This is equivalent to writing `a = foo`
|
|
3604
|
+
^
|
|
3605
|
+
|
|
3606
|
+
Using an explicit `Array` or combining expressions with `,` will result in a `ArrayPatternNode`. This can be preceded by a constant.
|
|
3607
|
+
|
|
3608
|
+
foo => [a]
|
|
3609
|
+
^^^
|
|
3610
|
+
|
|
3611
|
+
foo => a, b
|
|
3612
|
+
^^^^
|
|
3613
|
+
|
|
3614
|
+
foo => Bar[a, b]
|
|
3615
|
+
^^^^^^^^^
|
|
3616
|
+
|
|
3617
|
+
If the array pattern contains at least two wildcard matches, a `FindPatternNode` is created instead.
|
|
3618
|
+
|
|
3619
|
+
foo => *, 1, *a
|
|
3620
|
+
^^^^^
|
|
3621
|
+
|
|
3622
|
+
Using an explicit `Hash` or a constant with square brackets and hash keys in the square brackets will result in a `HashPatternNode`.
|
|
3623
|
+
|
|
3624
|
+
foo => { a: 1, b: }
|
|
3625
|
+
|
|
3626
|
+
foo => Bar[a: 1, b:]
|
|
3627
|
+
|
|
3628
|
+
foo => Bar[**]
|
|
3629
|
+
|
|
3630
|
+
To use any variable that needs run time evaluation, pinning is required. This results in a `PinnedVariableNode`
|
|
3631
|
+
|
|
3632
|
+
foo => ^a
|
|
3633
|
+
^^
|
|
3634
|
+
|
|
3635
|
+
Similar, any expression can be used with pinning. This results in a `PinnedExpressionNode`.
|
|
3636
|
+
|
|
3637
|
+
foo => ^(a + 1)
|
|
3638
|
+
|
|
3639
|
+
Anything else will result in the regular node for that expression, for example a `ConstantReadNode`.
|
|
3640
|
+
|
|
3641
|
+
foo => CONST
|
|
3449
3642
|
- name: operator_loc
|
|
3450
3643
|
type: location
|
|
3644
|
+
comment: |
|
|
3645
|
+
The location of the operator.
|
|
3646
|
+
|
|
3647
|
+
foo => bar
|
|
3648
|
+
^^
|
|
3451
3649
|
comment: |
|
|
3452
3650
|
Represents the use of the `=>` operator.
|
|
3453
3651
|
|
|
@@ -3877,12 +4075,32 @@ nodes:
|
|
|
3877
4075
|
- name: expression
|
|
3878
4076
|
type: node
|
|
3879
4077
|
kind: non-void expression
|
|
4078
|
+
comment: |
|
|
4079
|
+
The expression used in the pinned expression
|
|
4080
|
+
|
|
4081
|
+
foo in ^(bar)
|
|
4082
|
+
^^^
|
|
3880
4083
|
- name: operator_loc
|
|
3881
4084
|
type: location
|
|
4085
|
+
comment: |
|
|
4086
|
+
The location of the `^` operator
|
|
4087
|
+
|
|
4088
|
+
foo in ^(bar)
|
|
4089
|
+
^
|
|
3882
4090
|
- name: lparen_loc
|
|
3883
4091
|
type: location
|
|
4092
|
+
comment: |
|
|
4093
|
+
The location of the opening parenthesis.
|
|
4094
|
+
|
|
4095
|
+
foo in ^(bar)
|
|
4096
|
+
^
|
|
3884
4097
|
- name: rparen_loc
|
|
3885
4098
|
type: location
|
|
4099
|
+
comment: |
|
|
4100
|
+
The location of the closing parenthesis.
|
|
4101
|
+
|
|
4102
|
+
foo in ^(bar)
|
|
4103
|
+
^
|
|
3886
4104
|
comment: |
|
|
3887
4105
|
Represents the use of the `^` operator for pinning an expression in a pattern matching expression.
|
|
3888
4106
|
|
|
@@ -3901,8 +4119,18 @@ nodes:
|
|
|
3901
4119
|
- NumberedReferenceReadNode # foo in ^$1
|
|
3902
4120
|
- ItLocalVariableReadNode # proc { 1 in ^it }
|
|
3903
4121
|
- on error: MissingNode # foo in ^Bar
|
|
4122
|
+
comment: |
|
|
4123
|
+
The variable used in the pinned expression
|
|
4124
|
+
|
|
4125
|
+
foo in ^bar
|
|
4126
|
+
^^^
|
|
3904
4127
|
- name: operator_loc
|
|
3905
4128
|
type: location
|
|
4129
|
+
comment: |
|
|
4130
|
+
The location of the `^` operator
|
|
4131
|
+
|
|
4132
|
+
foo in ^bar
|
|
4133
|
+
^
|
|
3906
4134
|
comment: |
|
|
3907
4135
|
Represents the use of the `^` operator for pinning a variable in a pattern matching expression.
|
|
3908
4136
|
|
data/docs/design.md
CHANGED
|
@@ -18,11 +18,11 @@ The templated files contain all of the code required to allocate and initialize
|
|
|
18
18
|
|
|
19
19
|
In order to provide the best possible error tolerance, the parser is hand-written. It is structured using Pratt parsing, a technique developed by Vaughan Pratt back in the 1970s. Below are a bunch of links to articles and papers that explain Pratt parsing in more detail.
|
|
20
20
|
|
|
21
|
-
* https://
|
|
21
|
+
* https://github.com/tdop/tdop.github.io/raw/master/original.pdf
|
|
22
22
|
* https://tdop.github.io/
|
|
23
23
|
* https://journal.stuffwithstuff.com/2011/03/19/pratt-parsers-expression-parsing-made-easy/
|
|
24
24
|
* https://matklad.github.io/2020/04/13/simple-but-powerful-pratt-parsing.html
|
|
25
|
-
* https://chidiwilliams.com/
|
|
25
|
+
* https://chidiwilliams.com/posts/on-recursive-descent-and-pratt-parsing
|
|
26
26
|
|
|
27
27
|
You can find most of the functions that correspond to constructs in the Pratt parsing algorithm in `prism.c`. As a couple of examples:
|
|
28
28
|
|