rip-lang 1.0.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.
Files changed (80) hide show
  1. package/.cursor/rules/rip-agent-onboarding.md +681 -0
  2. package/.github/ISSUE_TEMPLATE/bug_report.yml +98 -0
  3. package/.github/ISSUE_TEMPLATE/coffeescript_compatibility.yml +86 -0
  4. package/.github/ISSUE_TEMPLATE/config.yml +9 -0
  5. package/.github/ISSUE_TEMPLATE/feature_request.yml +82 -0
  6. package/.github/ISSUE_TEMPLATE/question.yml +55 -0
  7. package/.github/pull_request_template.md +84 -0
  8. package/AGENT.md +623 -0
  9. package/CONTRIBUTING.md +331 -0
  10. package/LICENSE +21 -0
  11. package/README.md +1245 -0
  12. package/SETUP.md +144 -0
  13. package/bar.coffee +394 -0
  14. package/bin/rip +162 -0
  15. package/bunfig.toml +11 -0
  16. package/docs/BROWSER.md +983 -0
  17. package/docs/CODEGEN.md +1023 -0
  18. package/docs/COFFEESCRIPT-COMPARISON.md +740 -0
  19. package/docs/COMPREHENSIONS.md +572 -0
  20. package/docs/REGEX-PLUS.md +441 -0
  21. package/docs/SOLAR.md +846 -0
  22. package/docs/SPECIAL-OPERATORS.md +769 -0
  23. package/docs/STRING.md +363 -0
  24. package/docs/WHY-NOT-COFFEESCRIPT.md +184 -0
  25. package/docs/WHY-YES-RIP.md +690 -0
  26. package/docs/WORKFLOW.md +306 -0
  27. package/docs/dist/rip.browser.js +6798 -0
  28. package/docs/dist/rip.browser.min.js +242 -0
  29. package/docs/dist/rip.browser.min.js.br +0 -0
  30. package/docs/example.html +177 -0
  31. package/docs/examples/README.md +154 -0
  32. package/docs/examples/arrows.rip +84 -0
  33. package/docs/examples/async-await.rip +59 -0
  34. package/docs/examples/existential.rip +86 -0
  35. package/docs/examples/fibonacci.rip +12 -0
  36. package/docs/examples/module.rip +38 -0
  37. package/docs/examples/object-syntax.rip +74 -0
  38. package/docs/examples/prototype.rip +30 -0
  39. package/docs/examples/ranges.rip +45 -0
  40. package/docs/examples/switch.rip +50 -0
  41. package/docs/examples/ternary.rip +36 -0
  42. package/docs/examples/use-loader.js +9 -0
  43. package/docs/examples/utils.rip +20 -0
  44. package/docs/index.html +65 -0
  45. package/docs/repl.html +914 -0
  46. package/docs/rip-1280w.png +0 -0
  47. package/docs/rip.svg +4 -0
  48. package/package.json +52 -0
  49. package/rip-loader.ts +27 -0
  50. package/scripts/build-browser.js +76 -0
  51. package/scripts/serve.js +71 -0
  52. package/src/browser.js +97 -0
  53. package/src/codegen.js +4808 -0
  54. package/src/compiler.js +270 -0
  55. package/src/grammar/grammar.rip +801 -0
  56. package/src/grammar/solar.rip +1056 -0
  57. package/src/lexer.js +3145 -0
  58. package/src/parser.js +352 -0
  59. package/src/repl.js +423 -0
  60. package/test/rip/assignment.rip +115 -0
  61. package/test/rip/async.rip +361 -0
  62. package/test/rip/basic.rip +171 -0
  63. package/test/rip/classes.rip +167 -0
  64. package/test/rip/compatibility.rip +338 -0
  65. package/test/rip/comprehensions.rip +104 -0
  66. package/test/rip/control.rip +177 -0
  67. package/test/rip/data.rip +215 -0
  68. package/test/rip/errors.rip +129 -0
  69. package/test/rip/functions.rip +443 -0
  70. package/test/rip/guards.rip +247 -0
  71. package/test/rip/literals.rip +131 -0
  72. package/test/rip/loops.rip +117 -0
  73. package/test/rip/modules.rip +87 -0
  74. package/test/rip/operators.rip +158 -0
  75. package/test/rip/optional.rip +184 -0
  76. package/test/rip/properties.rip +94 -0
  77. package/test/rip/regex.rip +301 -0
  78. package/test/rip/stabilization.rip +825 -0
  79. package/test/rip/strings.rip +483 -0
  80. package/test/runner.js +329 -0
@@ -0,0 +1,94 @@
1
+ # Test: Property Access (6 node types)
2
+ # Tests ".", "?.", "::", "?::", "[]", "?[]" node types
3
+
4
+ # ============================================================================
5
+ # Property Access: "."
6
+ # ============================================================================
7
+
8
+ # Basic property access
9
+ test "property access", "obj = {x: 42}; obj.x", 42
10
+ test "nested property", "obj = {a: {b: 10}}; obj.a.b", 10
11
+ test "property chain", "obj = {a: {b: {c: 5}}}; obj.a.b.c", 5
12
+
13
+ # Code generation
14
+ code "property access", "obj.prop", "obj.prop"
15
+ code "chained property", "obj.a.b", "obj.a.b"
16
+
17
+ # Method access
18
+ test "method access", "obj = {fn: -> 42}; obj.fn()", 42
19
+
20
+ # ============================================================================
21
+ # Optional Chaining: "?."
22
+ # ============================================================================
23
+
24
+ # Optional property access
25
+ test "optional chain exists", "obj = {x: 42}; obj?.x", 42
26
+ test "optional chain null", "obj = null; obj?.x", undefined
27
+ test "optional chain undefined", "obj = undefined; obj?.x", undefined
28
+
29
+ # Code generation
30
+ code "optional chain", "obj?.prop", "obj?.prop"
31
+
32
+ # Chained optional access
33
+ test "chained optional", "obj = {a: {b: 10}}; obj?.a?.b", 10
34
+ test "chained optional null", "obj = {a: null}; obj?.a?.b", undefined
35
+
36
+ # ============================================================================
37
+ # Prototype Access: "::"
38
+ # ============================================================================
39
+
40
+ # Direct prototype access
41
+ test "prototype access", "Array::push", Array.prototype.push
42
+ test "prototype method", "Boolean::toString", Boolean.prototype.toString
43
+
44
+ # Code generation
45
+ code "prototype access", "obj::method", "obj.prototype.method"
46
+
47
+ # Shorthand prototype
48
+ test "shorthand prototype", "Array::", Array.prototype
49
+
50
+ # ============================================================================
51
+ # Optional Prototype: "?::"
52
+ # ============================================================================
53
+
54
+ # Optional prototype access
55
+ test "optional prototype exists", "Array?::push", Array.prototype.push
56
+ test "optional prototype null", "obj = null; obj?::method", undefined
57
+
58
+ # Code generation
59
+ code "optional prototype", "obj?::method", "(obj != null ? obj.prototype.method : undefined)"
60
+
61
+ # ============================================================================
62
+ # Array Indexing: "[]"
63
+ # ============================================================================
64
+
65
+ # Basic indexing
66
+ test "array index", "arr = [10, 20, 30]; arr[1]", 20
67
+ test "negative index", "arr = [1, 2, 3]; arr[arr.length - 1]", 3
68
+ test "index expression", "arr = [10, 20]; i = 1; arr[i]", 20
69
+
70
+ # Code generation
71
+ code "array index", "arr[0]", "arr[0]"
72
+ code "index expression", "arr[i + 1]", "arr[(i + 1)]"
73
+
74
+ # Object bracket notation
75
+ test "object bracket", 'obj = {name: "test"}; obj["name"]', "test"
76
+ test "dynamic property", 'obj = {x: 42}; key = "x"; obj[key]', 42
77
+
78
+ # ============================================================================
79
+ # Optional Indexing: "?[]"
80
+ # ============================================================================
81
+
82
+ # Optional array indexing (ES6)
83
+ test "optional index exists", "arr = [1, 2, 3]\narr?.[1]", 2
84
+ test "optional index null", "arr = null\narr?.[0]", undefined
85
+
86
+ # Code generation
87
+ code "optional index", "arr?.[i]", "arr?.[i]"
88
+
89
+ # ============================================================================
90
+ # Stats for CODEGEN.md
91
+ # ============================================================================
92
+ # Node types: ., [], ::, ?., ?.[, ?::
93
+ # Tests: 29 total (29 passing, 0 failing)
94
+ # Coverage: Property access, array indexing, prototype access, optional chaining, dynamic properties, nested access
@@ -0,0 +1,301 @@
1
+ # Test: Regular Expressions (1 node type)
2
+ # Tests "regex" node type
3
+
4
+ # ============================================================================
5
+ # Regular Expression Literals: "regex"
6
+ # ============================================================================
7
+
8
+ # Basic regex
9
+ test "regex literal test", '/hello/.test("hello world")', true
10
+ test "regex literal no match", '/goodbye/.test("hello world")', false
11
+
12
+ # Regex with flags
13
+ test "regex with i flag", '/HELLO/i.test("hello")', true
14
+ test "regex with g flag", '"aaa".match(/a/g).length', 3
15
+
16
+ # Code generation
17
+ code "regex literal", "/test/", "/test/"
18
+ code "regex with flags", "/test/gi", "/test/gi"
19
+
20
+ # Regex methods
21
+ test "regex exec", '/world/.exec("hello world")[0]', "world"
22
+ test "string match", '"test123".match(/\\d+/)[0]', "123"
23
+
24
+ # ============================================================================
25
+ # Stats for CODEGEN.md
26
+ # ============================================================================
27
+ # Regex implemented: 0/1 (0%)
28
+ # Tests passing: 0/8 (0%)
29
+
30
+ # Test: Regex Features (=~ and regex indexing)
31
+ # Tests Ruby-style regex matching with automatic _ variable capture
32
+
33
+ # ============================================================================
34
+ # =~ Operator (Regex Match with _ capture)
35
+ # ============================================================================
36
+
37
+ # Basic regex match
38
+ test '=~ basic match', '''
39
+ text = 'hello world'
40
+ result = text =~ /world/
41
+ result[0]
42
+ ''', 'world'
43
+
44
+ # Capture groups with _
45
+ test '=~ capture groups', '''
46
+ text = 'hello world'
47
+ text =~ /(\\w+) (\\w+)/
48
+ _[1]
49
+ ''', 'hello'
50
+
51
+ # Multiple captures
52
+ test '=~ multiple captures', '''
53
+ text = 'hello world'
54
+ text =~ /(\\w+) (\\w+)/
55
+ _[2]
56
+ ''', 'world'
57
+
58
+ # No match returns null
59
+ test '=~ no match', '''
60
+ text = 'hello'
61
+ result = text =~ /xyz/
62
+ result
63
+ ''', null
64
+
65
+ # Match at start
66
+ test '=~ match at start', '''
67
+ text = 'hello world'
68
+ text =~ /^(\\w+)/
69
+ _[1]
70
+ ''', 'hello'
71
+
72
+ # Match at end
73
+ test '=~ match at end', '''
74
+ text = 'hello world'
75
+ text =~ /(\\w+)$/
76
+ _[1]
77
+ ''', 'world'
78
+
79
+ # With flags
80
+ test '=~ case insensitive', '''
81
+ text = 'HELLO'
82
+ text =~ /hello/i
83
+ _[0]
84
+ ''', 'HELLO'
85
+
86
+ # Global flag (returns first match, sets _)
87
+ test '=~ global flag', '''
88
+ text = 'foo bar foo'
89
+ text =~ /foo/g
90
+ _[0]
91
+ ''', 'foo'
92
+
93
+ # Works with numbers (via toSearchable)
94
+ test '=~ with number', '''
95
+ num = 12345
96
+ num =~ /(\\d{3})/
97
+ _[1]
98
+ ''', '123'
99
+
100
+ # Works with null (converts to empty string)
101
+ test '=~ with null', '''
102
+ x = null
103
+ result = x =~ /test/
104
+ result
105
+ ''', null
106
+
107
+ # Email parsing example
108
+ test '=~ email parsing', '''
109
+ email = 'user@example.com'
110
+ email =~ /(.+)@(.+)/
111
+ _[2]
112
+ ''', 'example.com'
113
+
114
+ # ============================================================================
115
+ # Regex Indexing (value[/pattern/] and value[/pattern/, n])
116
+ # ============================================================================
117
+
118
+ # Simple regex indexing (returns full match)
119
+ test 'regex index simple', '"steve"[/eve/]', 'eve'
120
+
121
+ # Regex indexing with capture group
122
+ test 'regex index capture', '"steve"[/e(v)e/, 1]', 'v'
123
+
124
+ # Multiple capture groups
125
+ test 'regex index multiple captures', '''
126
+ text = 'hello world'
127
+ text[/(\\w+) (\\w+)/, 2]
128
+ ''', 'world'
129
+
130
+ # No match returns null
131
+ test 'regex index no match', '"hello"[/xyz/]', null
132
+
133
+ # Works with numbers
134
+ test 'regex index number', '''
135
+ num = 12345
136
+ num[/\\d{3}/]
137
+ ''', '123'
138
+
139
+ # Email domain extraction
140
+ test 'regex index email domain', '''
141
+ email = 'user@example.com'
142
+ email[/@(.+)$/, 1]
143
+ ''', 'example.com'
144
+
145
+ # Phone parsing
146
+ test 'regex index phone', '''
147
+ phone = '(555) 123-4567'
148
+ phone[/\\((\\d{3})\\) (\\d{3})-(\\d{4})/, 2]
149
+ ''', '123'
150
+
151
+ # URL parsing
152
+ test 'regex index url', '''
153
+ url = 'https://example.com/path'
154
+ url[/:\\/\\/(\\w+\\.\\w+)/, 1]
155
+ ''', 'example.com'
156
+
157
+ # Case insensitive
158
+ test 'regex index case insensitive', '"HELLO"[/hello/i]', 'HELLO'
159
+
160
+ # With anchors (full match required, can't extract partial)
161
+ test 'regex index anchored', '"test123"[/^(test)(\\d+)$/, 1]', 'test'
162
+
163
+ # Nested groups
164
+ test 'regex index nested groups', '''
165
+ text = 'abc123xyz'
166
+ text[/([a-z]+)(\\d+)/, 2]
167
+ ''', '123'
168
+
169
+ # ============================================================================
170
+ # Combined Usage (=~ then _ access)
171
+ # ============================================================================
172
+
173
+ # Use =~ then access _ directly
174
+ test 'combined =~ and _', '''
175
+ text = 'hello world'
176
+ if text =~ /(\\w+) (\\w+)/
177
+ _[1] + '-' + _[2]
178
+ else
179
+ 'no match'
180
+ ''', 'hello-world'
181
+
182
+ # Chain multiple regex operations
183
+ test 'chained regex ops', '''
184
+ email = 'admin@company.com'
185
+ if email =~ /(.+)@(.+)/
186
+ domain = _[2]
187
+ domain[/(\\w+)\\./, 1]
188
+ else
189
+ null
190
+ ''', 'company'
191
+
192
+ # Regex in conditionals
193
+ test 'regex in conditional', '''
194
+ text = 'user@example.com'
195
+ result = if text =~ /@/
196
+ 'has @'
197
+ else
198
+ 'no @'
199
+ result
200
+ ''', 'has @'
201
+
202
+ # ============================================================================
203
+ # Validator Pattern Examples (from your code)
204
+ # ============================================================================
205
+
206
+ # ID validator pattern
207
+ test 'validator id pattern', '''
208
+ validate = (v) -> v[/^([1-9]\\d{0,19})$/] and parseInt(_[1])
209
+ validate('12345')
210
+ ''', 12345
211
+
212
+ # Email validator pattern
213
+ test 'validator email pattern', '''
214
+ validate = (v) -> v[/^([a-zA-Z0-9._%+-]+)@([a-zA-Z0-9.-]+\\.[a-zA-Z]{2,})$/] and _[0]
215
+ validate('test@example.com')
216
+ ''', 'test@example.com'
217
+
218
+ # Zip code extractor
219
+ test 'validator zip pattern', '''
220
+ validate = (v) -> v[/^(\\d{5})/] and _[1]
221
+ validate('12345-6789')
222
+ ''', '12345'
223
+
224
+ # Boolean validator with =~
225
+ test 'validator truthy pattern', '''
226
+ validate = (v) -> (v =~ /^(true|t|1|yes|y|on)$/i) and true
227
+ validate('YES')
228
+ ''', true
229
+
230
+ # Phone formatter pattern
231
+ test 'validator phone pattern', '''
232
+ num = '2125551234'
233
+ if num =~ /^([2-9][0-8][0-9])([2-9]\\d\\d)(\\d{4})$/
234
+ "(#{_[1]}) #{_[2]}-#{_[3]}"
235
+ else
236
+ null
237
+ ''', '(212) 555-1234'
238
+
239
+ # ============================================================================
240
+ # Edge Cases
241
+ # ============================================================================
242
+
243
+ # Empty string
244
+ test 'regex index empty string', '""[/test/]', null
245
+
246
+ # Null value (converts to empty string)
247
+ test 'regex match null', '''
248
+ x = null
249
+ x =~ /test/
250
+ ''', null
251
+
252
+ # Array (joins with comma)
253
+ test 'regex match array', '''
254
+ arr = ['hello', 'world']
255
+ arr =~ /hello/
256
+ _[0]
257
+ ''', 'hello'
258
+
259
+ # Boolean (converts to string)
260
+ test 'regex match boolean', '''
261
+ x = true
262
+ x =~ /true/
263
+ _[0]
264
+ ''', 'true'
265
+
266
+ # Out of range capture index returns undefined
267
+ test 'regex index out of range', '''
268
+ x = "test"[/test/, 5]
269
+ x
270
+ ''', undefined
271
+
272
+ # ============================================================================
273
+ # Heregex Interpolation Behavior
274
+ # ============================================================================
275
+
276
+ # IMPORTANT DISTINCTION:
277
+ # - Strings: Both #{...} and ${...} interpolate
278
+ # - Heregex: Only #{...} interpolates, ${...} stays literal (for regex patterns)
279
+
280
+ # #{...} interpolation works in heregex (CoffeeScript style)
281
+ test "heregex #{} interpolation", '''
282
+ name = "world"
283
+ pattern = ///hello#{name}///
284
+ pattern.test("helloworld")
285
+ ''', true
286
+
287
+ # ${...} does NOT interpolate in heregex - stays as literal regex pattern (no escape needed!)
288
+ code "heregex ${} no interpolation", '///test${var}end///', '/test${var}end/'
289
+
290
+ # $ anchor works correctly in heregex
291
+ test "heregex $ anchor", '''
292
+ pattern = ///^test$///
293
+ pattern.test("test") and not pattern.test("testing")
294
+ ''', true
295
+
296
+ # ============================================================================
297
+ # Stats for CODEGEN.md
298
+ # ============================================================================
299
+ # Node types: regex (literals, heregex)
300
+ # Tests: 46 total (46 passing, 0 failing)
301
+ # Coverage: Regex literals, flags, heregex (extended), =~ operator, regex indexing, validators, edge cases, interpolation behavior