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.
- package/.cursor/rules/rip-agent-onboarding.md +681 -0
- package/.github/ISSUE_TEMPLATE/bug_report.yml +98 -0
- package/.github/ISSUE_TEMPLATE/coffeescript_compatibility.yml +86 -0
- package/.github/ISSUE_TEMPLATE/config.yml +9 -0
- package/.github/ISSUE_TEMPLATE/feature_request.yml +82 -0
- package/.github/ISSUE_TEMPLATE/question.yml +55 -0
- package/.github/pull_request_template.md +84 -0
- package/AGENT.md +623 -0
- package/CONTRIBUTING.md +331 -0
- package/LICENSE +21 -0
- package/README.md +1245 -0
- package/SETUP.md +144 -0
- package/bar.coffee +394 -0
- package/bin/rip +162 -0
- package/bunfig.toml +11 -0
- package/docs/BROWSER.md +983 -0
- package/docs/CODEGEN.md +1023 -0
- package/docs/COFFEESCRIPT-COMPARISON.md +740 -0
- package/docs/COMPREHENSIONS.md +572 -0
- package/docs/REGEX-PLUS.md +441 -0
- package/docs/SOLAR.md +846 -0
- package/docs/SPECIAL-OPERATORS.md +769 -0
- package/docs/STRING.md +363 -0
- package/docs/WHY-NOT-COFFEESCRIPT.md +184 -0
- package/docs/WHY-YES-RIP.md +690 -0
- package/docs/WORKFLOW.md +306 -0
- package/docs/dist/rip.browser.js +6798 -0
- package/docs/dist/rip.browser.min.js +242 -0
- package/docs/dist/rip.browser.min.js.br +0 -0
- package/docs/example.html +177 -0
- package/docs/examples/README.md +154 -0
- package/docs/examples/arrows.rip +84 -0
- package/docs/examples/async-await.rip +59 -0
- package/docs/examples/existential.rip +86 -0
- package/docs/examples/fibonacci.rip +12 -0
- package/docs/examples/module.rip +38 -0
- package/docs/examples/object-syntax.rip +74 -0
- package/docs/examples/prototype.rip +30 -0
- package/docs/examples/ranges.rip +45 -0
- package/docs/examples/switch.rip +50 -0
- package/docs/examples/ternary.rip +36 -0
- package/docs/examples/use-loader.js +9 -0
- package/docs/examples/utils.rip +20 -0
- package/docs/index.html +65 -0
- package/docs/repl.html +914 -0
- package/docs/rip-1280w.png +0 -0
- package/docs/rip.svg +4 -0
- package/package.json +52 -0
- package/rip-loader.ts +27 -0
- package/scripts/build-browser.js +76 -0
- package/scripts/serve.js +71 -0
- package/src/browser.js +97 -0
- package/src/codegen.js +4808 -0
- package/src/compiler.js +270 -0
- package/src/grammar/grammar.rip +801 -0
- package/src/grammar/solar.rip +1056 -0
- package/src/lexer.js +3145 -0
- package/src/parser.js +352 -0
- package/src/repl.js +423 -0
- package/test/rip/assignment.rip +115 -0
- package/test/rip/async.rip +361 -0
- package/test/rip/basic.rip +171 -0
- package/test/rip/classes.rip +167 -0
- package/test/rip/compatibility.rip +338 -0
- package/test/rip/comprehensions.rip +104 -0
- package/test/rip/control.rip +177 -0
- package/test/rip/data.rip +215 -0
- package/test/rip/errors.rip +129 -0
- package/test/rip/functions.rip +443 -0
- package/test/rip/guards.rip +247 -0
- package/test/rip/literals.rip +131 -0
- package/test/rip/loops.rip +117 -0
- package/test/rip/modules.rip +87 -0
- package/test/rip/operators.rip +158 -0
- package/test/rip/optional.rip +184 -0
- package/test/rip/properties.rip +94 -0
- package/test/rip/regex.rip +301 -0
- package/test/rip/stabilization.rip +825 -0
- package/test/rip/strings.rip +483 -0
- package/test/runner.js +329 -0
package/SETUP.md
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# Rip Global Setup Guide
|
|
2
|
+
|
|
3
|
+
Quick guide to set up Rip so `.rip` files work anywhere with Bun.
|
|
4
|
+
|
|
5
|
+
## One-Time Setup (5 minutes)
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# 1. Clone Rip
|
|
9
|
+
git clone https://github.com/yourusername/rip.git
|
|
10
|
+
cd rip
|
|
11
|
+
|
|
12
|
+
# 2. Link globally
|
|
13
|
+
bun link
|
|
14
|
+
|
|
15
|
+
# 3. Configure Bun to auto-load Rip
|
|
16
|
+
echo 'preload = ["rip-lang/loader"]' >> ~/.bunfig.toml
|
|
17
|
+
|
|
18
|
+
# 4. Verify
|
|
19
|
+
bun pm ls --global | grep rip-lang
|
|
20
|
+
cat ~/.bunfig.toml
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Test It Works
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
# Go anywhere
|
|
27
|
+
cd ~
|
|
28
|
+
|
|
29
|
+
# Create a test file
|
|
30
|
+
cat > hello.rip << 'EOF'
|
|
31
|
+
def greet(name)
|
|
32
|
+
"Hello, ${name}!"
|
|
33
|
+
|
|
34
|
+
console.log greet("World")
|
|
35
|
+
EOF
|
|
36
|
+
|
|
37
|
+
# Run it
|
|
38
|
+
bun hello.rip
|
|
39
|
+
# → Hello, World!
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## How It Works
|
|
43
|
+
|
|
44
|
+
1. **`bun link`** - Makes the `rip-lang` package available globally
|
|
45
|
+
2. **`~/.bunfig.toml`** - Tells Bun to preload the Rip loader for all projects
|
|
46
|
+
3. **Automatic compilation** - When you run `bun script.rip`, the loader compiles it on-the-fly
|
|
47
|
+
|
|
48
|
+
## Using in Projects
|
|
49
|
+
|
|
50
|
+
### Import .rip modules
|
|
51
|
+
|
|
52
|
+
```rip
|
|
53
|
+
# utils.rip
|
|
54
|
+
export def add(a, b)
|
|
55
|
+
a + b
|
|
56
|
+
|
|
57
|
+
export multiply = (a, b) => a * b
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
```rip
|
|
61
|
+
# main.rip
|
|
62
|
+
import { add, multiply } from "./utils.rip"
|
|
63
|
+
|
|
64
|
+
console.log add(5, 3) # 8
|
|
65
|
+
console.log multiply(4, 7) # 28
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
bun main.rip # Works!
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Per-project override
|
|
73
|
+
|
|
74
|
+
If you want project-specific configuration:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
# In your project directory
|
|
78
|
+
echo 'preload = ["rip-lang/loader"]' > bunfig.toml
|
|
79
|
+
|
|
80
|
+
# Now this project uses Rip
|
|
81
|
+
bun your-script.rip
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Uninstalling
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
# Remove global link
|
|
88
|
+
bun unlink rip-lang
|
|
89
|
+
|
|
90
|
+
# Remove from global config
|
|
91
|
+
sed -i.bak '/rip-lang/d' ~/.bunfig.toml
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Troubleshooting
|
|
95
|
+
|
|
96
|
+
### "Cannot find package rip-lang"
|
|
97
|
+
|
|
98
|
+
The package isn't linked. Run:
|
|
99
|
+
```bash
|
|
100
|
+
cd /path/to/rip-lang
|
|
101
|
+
bun link
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Imports not working
|
|
105
|
+
|
|
106
|
+
Make sure you include the `.rip` extension:
|
|
107
|
+
```rip
|
|
108
|
+
import { fn } from "./utils.rip" # ✅ Good
|
|
109
|
+
import { fn } from "./utils" # ❌ Bad
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Changes not reflecting
|
|
113
|
+
|
|
114
|
+
Bun might be caching. Try:
|
|
115
|
+
```bash
|
|
116
|
+
bun --bun script.rip # Bypass cache
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## What Gets Installed
|
|
120
|
+
|
|
121
|
+
**Global:**
|
|
122
|
+
- Link to `rip-lang` package (via `bun link`)
|
|
123
|
+
- One line in `~/.bunfig.toml`
|
|
124
|
+
|
|
125
|
+
**Nothing else!** Rip has zero dependencies.
|
|
126
|
+
|
|
127
|
+
## Future: NPM Package
|
|
128
|
+
|
|
129
|
+
Once Rip is published to npm:
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
# Install globally
|
|
133
|
+
bun add -g rip-lang
|
|
134
|
+
|
|
135
|
+
# Or per-project
|
|
136
|
+
bun add -d rip-lang
|
|
137
|
+
|
|
138
|
+
# Same config
|
|
139
|
+
echo 'preload = ["rip-lang/loader"]' > bunfig.toml
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
**Questions?** See [README.md](README.md) for complete documentation.
|
package/bar.coffee
ADDED
|
@@ -0,0 +1,394 @@
|
|
|
1
|
+
#!/usr/bin/env coffee
|
|
2
|
+
|
|
3
|
+
# =============================================================================
|
|
4
|
+
# bar.coffee: HL7-like message payload processing library
|
|
5
|
+
#
|
|
6
|
+
# Author: Steve Shreeve <steve.shreeve@ariselab.com>
|
|
7
|
+
# Legal: Copyright (C) 2017, Arise Lab. All rights reserved.
|
|
8
|
+
# =============================================================================
|
|
9
|
+
|
|
10
|
+
PDF417 = require './pdf-417'
|
|
11
|
+
|
|
12
|
+
type = (obj) -> if obj? then (obj.constructor?.name or Object::toString.call(obj)[8...-1]).toLowerCase() else String(obj)
|
|
13
|
+
|
|
14
|
+
get = (str, one, two) ->
|
|
15
|
+
len = if +one > 0 then +one else if +two > 0 then +two else 0
|
|
16
|
+
alt = if two >= '' then two else ''
|
|
17
|
+
if str then (if len and str.length > len then str[0...len] else str) else alt
|
|
18
|
+
|
|
19
|
+
time = (len=14) ->
|
|
20
|
+
str = new Date().toISOString()
|
|
21
|
+
str = [str[0..3], str[5..6], str[8..9], str[11..12], str[14..15], str[17..18]].join('')
|
|
22
|
+
str[0...len]
|
|
23
|
+
|
|
24
|
+
class Bar
|
|
25
|
+
constructor: (obj...) ->
|
|
26
|
+
obj = obj[0] if obj.length < 2
|
|
27
|
+
who = type(obj)
|
|
28
|
+
|
|
29
|
+
# delimiters
|
|
30
|
+
[@fld, @rep, @com, @str] = "|~^".split('')
|
|
31
|
+
|
|
32
|
+
# initialize (newer spec)
|
|
33
|
+
# @str = """
|
|
34
|
+
# H||||^^||
|
|
35
|
+
# P|||||||||^^|||||||||||^^|||||||||^^|||||||^|||||||||^|||||||||^^^^^^^^^^^^^^|^^^^^^^|||||||||||||||||^^|^^|^^|^^||||^||||||^^|^^^^|||^||||
|
|
36
|
+
# C|||||||||||||||||||^||||||||
|
|
37
|
+
# A|||||||||||||||||||||^^|^|^||||||^^|^^^^^|||^^^||
|
|
38
|
+
# M||||||
|
|
39
|
+
# T|||||||||||||||||||||||||||||||||||||||||
|
|
40
|
+
# S|^^^^^^|
|
|
41
|
+
# G||^|||
|
|
42
|
+
# D|||
|
|
43
|
+
# L||
|
|
44
|
+
# E||
|
|
45
|
+
# """
|
|
46
|
+
|
|
47
|
+
# initialize (older spec for Edifecs)
|
|
48
|
+
@str = """
|
|
49
|
+
H||||^^||
|
|
50
|
+
P|||||||||^^|||||||||||^^|||||||||^^|||||||^|||||||||^|||||||||^^^^^^^^^^^^^^|^^^^^^^|||||||||||||||||^^|^^|^^|^^||||^||||||^^|^^^^|||^||
|
|
51
|
+
C|||||||||||||||||||^||||||||
|
|
52
|
+
A|||||||||||||||||||||^^|^|^||||||^^|^^^^^|||
|
|
53
|
+
M||||||
|
|
54
|
+
T|||||||||||||||||||||||||||||||||||||||||
|
|
55
|
+
S|^^^^^^|
|
|
56
|
+
D|||
|
|
57
|
+
L||
|
|
58
|
+
E||
|
|
59
|
+
"""
|
|
60
|
+
@ary = @to_a(@str)
|
|
61
|
+
|
|
62
|
+
# load message
|
|
63
|
+
if obj then switch who
|
|
64
|
+
when 'string' then @set(obj)
|
|
65
|
+
when 'array' then @data(obj)
|
|
66
|
+
when 'object' then @data(obj)
|
|
67
|
+
else throw "unable to create Bar objects from #{who} objects"
|
|
68
|
+
|
|
69
|
+
to_a: (str) -> @ary = str.trim().split(/[\r\n]+/).map((str) => str.trim().split(@fld)) # force parse
|
|
70
|
+
to_s: (eol) -> @str = @ary.map((row) => row.join(@fld)).join(eol or "\r") # force build
|
|
71
|
+
scan: (rgx, str = @str or @to_s()) ->
|
|
72
|
+
ary = []
|
|
73
|
+
str.replace rgx, (use, arg..., idx, all) ->
|
|
74
|
+
len = arg.length
|
|
75
|
+
ary.push(if len > 1 then arg else if len is 1 then arg[0] else use)
|
|
76
|
+
use
|
|
77
|
+
ary
|
|
78
|
+
make: (seg) -> [seg.toUpperCase(), '']
|
|
79
|
+
|
|
80
|
+
# ┌──────────────┬─────┬────┬─────┬─────┬─────┬───────────────────┬───┐
|
|
81
|
+
# │ seg.fld(rep) │ rgx │rep │ get │ set │ ary │ notes │ # │
|
|
82
|
+
# ╞══════════════╪═════╪════╪═════╪═════╪═════╪═══════════════════╪═══╡
|
|
83
|
+
# │ seg.fld-5 │ und │ 1 │ beg │ end │ │ beg/end or append │ 1 │
|
|
84
|
+
# │ seg.fld(0)-5 │ '0' │ 0 │ beg │ pre │ │ pre fld or append │ 5 │
|
|
85
|
+
# │ seg.fld(+)-5 │ '+' │ + │ end │ aft │ │ always append │ 4 │
|
|
86
|
+
# ├──────────────┼─────┼────┼─────┼─────┼─────┼───────────────────┼───┤
|
|
87
|
+
# │ seg.fld(2)-5 │ '2' │ 2 │ idx │ idx │ yes │ idx or append │ 3 │
|
|
88
|
+
# │ seg.fld()-5 │ '' │-1 │ end │ end │ yes │ last or append │ 2 │
|
|
89
|
+
# ├──────────────┼─────┼────┼─────┼─────┼─────┼───────────────────┼───┤
|
|
90
|
+
# │ seg.fld(?)-5 │ '?' │ ? │ ask │ all │ yes │ set all │ 6 │
|
|
91
|
+
# └──────────────┴─────┴────┴─────┴─────┴─────┴───────────────────┴───┘
|
|
92
|
+
|
|
93
|
+
data: (pos, val) ->
|
|
94
|
+
# console.log ["data:", arguments.length, Array.apply(null, arguments)]
|
|
95
|
+
switch cnt = arguments.length
|
|
96
|
+
when 0 then return @str or @to_s()
|
|
97
|
+
when 1 then switch type(obj = pos)
|
|
98
|
+
when 'array' then @data(obj[i], obj[i+1]) for i in [0...obj.length] by 2; return @
|
|
99
|
+
when 'object' then @data(key, val) for key, val of obj ; return @
|
|
100
|
+
when 'string' then return @set(obj) if /\s/.test(obj)
|
|
101
|
+
when 2 then if val in [undefined, null, false] then return @
|
|
102
|
+
else
|
|
103
|
+
obj = Array.apply(null, arguments)
|
|
104
|
+
len = obj.length
|
|
105
|
+
@data(obj[i], obj[i+1]) for i in [0...(len - 1)] by 2
|
|
106
|
+
return if len % 2 then @data(obj[len - 1]) else @
|
|
107
|
+
|
|
108
|
+
rgx = ///^ # String 'H.1(2)-3'
|
|
109
|
+
([HPCAMBKITSGDLE]) # 1: seg 'H'
|
|
110
|
+
[-.]?([1-9]\d*)? # 2: fld '1'
|
|
111
|
+
(?:\(([?+]|\d*)\))? # 3: rep '2'
|
|
112
|
+
[-.]?([1-9]\d*)? # 4: com '3'
|
|
113
|
+
(?:\[(\d+)\])? # 5: chr (set character position when "Y")
|
|
114
|
+
(?:\=(.+))? # 6: hcv (set hard coded value when "Y")
|
|
115
|
+
$///i.exec(pos) or throw "invalid access: #{pos}"
|
|
116
|
+
|
|
117
|
+
seg = rgx[1]
|
|
118
|
+
fld = +rgx[2] if rgx[2]?
|
|
119
|
+
rep = rgx[3]; rep and '+?'.includes(rep) or rep = +rep or if rep>='' then rep.length - 1 else if cnt is 1 then null else -1
|
|
120
|
+
com = +rgx[4] if rgx[4]?
|
|
121
|
+
chr = +rgx[5] if rgx[5]?
|
|
122
|
+
hcv = rgx[6]
|
|
123
|
+
|
|
124
|
+
if cnt is 1 # get
|
|
125
|
+
regx = new RegExp("^#{seg}.*", "igm")
|
|
126
|
+
|
|
127
|
+
return '' unless out = @scan(regx)[0 ] # get first one
|
|
128
|
+
return '' unless out = out.split(@fld)[fld ] if fld
|
|
129
|
+
return '' if -1< out = out.split(@rep).length if rep is '?'
|
|
130
|
+
return '' unless out = out.split(@rep)[rep - 1] if rep or (com and (rep or= 1))
|
|
131
|
+
return '' unless out = out.split(@com)[com - 1] if com
|
|
132
|
+
out
|
|
133
|
+
|
|
134
|
+
else # set
|
|
135
|
+
# console.log ["data:", arguments.length, Array.apply(null, arguments)]
|
|
136
|
+
|
|
137
|
+
@str = null # invalidate @str on set
|
|
138
|
+
regx = new RegExp("^#{seg}", "i")
|
|
139
|
+
|
|
140
|
+
# adjust arrays
|
|
141
|
+
unless ~(idx = @ary.findIndex (row) -> regx.test row[0])
|
|
142
|
+
idx = @ary.push(@make seg) - 1 # append
|
|
143
|
+
row = @ary[idx]
|
|
144
|
+
|
|
145
|
+
# adjust value (we could do custom transforms here)
|
|
146
|
+
val = if val? then "#{val}" else ""
|
|
147
|
+
yep = val.toUpperCase() is "Y" if hcv or chr
|
|
148
|
+
val = hcv if hcv and yep
|
|
149
|
+
|
|
150
|
+
unless fld? # set whole segment
|
|
151
|
+
row[1..] = val.split(@fld)
|
|
152
|
+
else # set field
|
|
153
|
+
|
|
154
|
+
# allow values to span multiple fields
|
|
155
|
+
[val, etc...] = val.split(@fld)
|
|
156
|
+
|
|
157
|
+
unless (had = row[fld] or "") # no prior value
|
|
158
|
+
had += @rep for [1...rep] by 1 if rep and rep > 1
|
|
159
|
+
had += @com for [1...com] by 1 if com and com > 1
|
|
160
|
+
val = 1 if val is ':rep' # auto-count
|
|
161
|
+
val = @chr_set(chr, yep) if chr
|
|
162
|
+
val = had + val
|
|
163
|
+
else # existing value
|
|
164
|
+
|
|
165
|
+
# repeat logic: fld(rep) is analogous to seg(num)
|
|
166
|
+
our = had.split(@rep)
|
|
167
|
+
len = our.length
|
|
168
|
+
if rep in [1,0,'+']
|
|
169
|
+
if rep >= 0 and len > (idx = 0)
|
|
170
|
+
rep or our.unshift('') # pre fld
|
|
171
|
+
else idx = our.push('') - 1 # append
|
|
172
|
+
else # idx, last, '?'
|
|
173
|
+
if +rep # idx, last
|
|
174
|
+
rep += (len or 1) + 1 if rep < 0 # last
|
|
175
|
+
our.push('') for [len...rep] by 1 if rep > len # grow
|
|
176
|
+
idx = rep - 1
|
|
177
|
+
if rep>=0 or rep is '+'
|
|
178
|
+
val = our.length if val is ':rep' # auto-count
|
|
179
|
+
else throw "setting by '?' is not yet implemented"
|
|
180
|
+
|
|
181
|
+
# assemble value
|
|
182
|
+
unless com
|
|
183
|
+
val = @chr_set(chr, yep, our[idx]) if chr
|
|
184
|
+
our[idx] = val
|
|
185
|
+
else
|
|
186
|
+
one = our[idx].split(@com)
|
|
187
|
+
val = @chr_set(chr, yep, our[com - 1]) if chr
|
|
188
|
+
one[com - 1] = val
|
|
189
|
+
our[idx] = one.join(@com)
|
|
190
|
+
val = our.join(@rep)
|
|
191
|
+
|
|
192
|
+
# set field value(s)
|
|
193
|
+
row.push('') for [row.length...fld] if fld > row.length
|
|
194
|
+
row[fld..(fld+etc.length)] = [val, etc...]
|
|
195
|
+
|
|
196
|
+
@ # return self
|
|
197
|
+
|
|
198
|
+
chr_set: (chr, yep, val) ->
|
|
199
|
+
ary = (val or '').split ''
|
|
200
|
+
ary[chr - 1] = if yep then 'Y' else ' '
|
|
201
|
+
val = (now or ' ' for now in ary).join('').replace(/\s+$/, '')
|
|
202
|
+
|
|
203
|
+
set: (str) ->
|
|
204
|
+
|
|
205
|
+
# handy regexes
|
|
206
|
+
enc = [ /^\s*[A-Z]\|/im , /^\s*([^#][^\r\n]*)/gm ]
|
|
207
|
+
tpl = [ /^\s*[A-Z][-.]\d+/im, /^\s*([^\s#]+)\s+([^\r\n]*)/igm ]
|
|
208
|
+
|
|
209
|
+
switch
|
|
210
|
+
when enc[0].test str # encoded string
|
|
211
|
+
for row in @scan enc[1], str
|
|
212
|
+
[seg, col...] = row.split(@fld)
|
|
213
|
+
for fld, nfld in col
|
|
214
|
+
for rep, nrep in fld.split(@rep)
|
|
215
|
+
all = rep.split(@com)
|
|
216
|
+
mas = all.length > 1
|
|
217
|
+
for com, ncom in all when com # skip falsy values
|
|
218
|
+
tag = "#{seg.toLowerCase()}.#{nfld + 1}"
|
|
219
|
+
tag += "(#{nrep + 1})" if nrep > 0
|
|
220
|
+
tag += "-#{ncom + 1}" if mas
|
|
221
|
+
# p [tag, com]
|
|
222
|
+
@data(tag, com)
|
|
223
|
+
when tpl[0].test str # templated string
|
|
224
|
+
@data(pair...) for pair in @scan tpl[1], str when pair[1] # skip falsy values
|
|
225
|
+
else throw "unable to import invalid string"
|
|
226
|
+
|
|
227
|
+
@ # return self
|
|
228
|
+
|
|
229
|
+
to_png: ->
|
|
230
|
+
png = new PDF417( @inspect()).to_png()
|
|
231
|
+
png.exp = new PDF417(@exp.inspect()).to_png() if @exp
|
|
232
|
+
png.over = true if @over
|
|
233
|
+
png
|
|
234
|
+
|
|
235
|
+
to_svg: -> new PDF417(@inspect()).to_svg()
|
|
236
|
+
|
|
237
|
+
inspect: -> @to_s().toUpperCase()
|
|
238
|
+
|
|
239
|
+
show: ->
|
|
240
|
+
pad = (new Array(9+1)).join ' '
|
|
241
|
+
rgx = RegExp "[^#{@com}]"
|
|
242
|
+
for [seg, row...] in @ary
|
|
243
|
+
for fld, i in row when fld > '' and rgx.test fld
|
|
244
|
+
all = fld.split @rep
|
|
245
|
+
for rep, j in all
|
|
246
|
+
tag = "#{seg.toLowerCase()}.#{i+1}"
|
|
247
|
+
tag += "(#{j+1})" if all.length > 1
|
|
248
|
+
console.log "#{tag}#{pad[tag.length..-1]}#{rep}"
|
|
249
|
+
|
|
250
|
+
# ==[ Helpers ]==
|
|
251
|
+
|
|
252
|
+
name: (person) -> [
|
|
253
|
+
person.last_name
|
|
254
|
+
person.first_name
|
|
255
|
+
person.middle_name or ''
|
|
256
|
+
].join('^')
|
|
257
|
+
|
|
258
|
+
address: (address) -> [
|
|
259
|
+
get(address.street, 30)
|
|
260
|
+
get(address.city, 25) # sometimes only 15?
|
|
261
|
+
get(address.state)
|
|
262
|
+
get(address.zip).replace('-', '')
|
|
263
|
+
].join('|')
|
|
264
|
+
|
|
265
|
+
module.exports = Bar
|
|
266
|
+
|
|
267
|
+
# ==[ Command line invocation ]==
|
|
268
|
+
|
|
269
|
+
if !module.parent
|
|
270
|
+
fs = require 'fs'
|
|
271
|
+
|
|
272
|
+
list = process.argv.slice 2
|
|
273
|
+
|
|
274
|
+
for file in list
|
|
275
|
+
console.log "\n==[ #{file} ]==\n"
|
|
276
|
+
try
|
|
277
|
+
bar = new Bar fs.readFileSync(file).toString()
|
|
278
|
+
bar.show()
|
|
279
|
+
catch
|
|
280
|
+
console.log "Invalid\n"
|
|
281
|
+
|
|
282
|
+
###
|
|
283
|
+
|
|
284
|
+
# ==[ Testing ]==
|
|
285
|
+
|
|
286
|
+
p = -> console.log arg for arg in arguments
|
|
287
|
+
exit = require('process').exit
|
|
288
|
+
|
|
289
|
+
PDF417 = require './pdf-417'
|
|
290
|
+
|
|
291
|
+
do ->
|
|
292
|
+
# x = ". Operators with higher precedence are evaluated first.\n\nA common example:\n\n3 + 4 * 5 // returns 23\nThe multiplication operator (\"*\") has higher precedence than the addition operator (\"+\") and thus will be evaluated first.\n\nAssociativity\nAssociativity determines the order in which operators of the same precedence are processed. For example, consider an expression:\n\na OP b OP c\nLeft-associativity (left-to-right) means that it is processed as (a OP b) OP c, while right-associativity (right-to-left) means it is interpreted as a OP (b OP c). Assignment operators are right-associative, so you can write:\n\na = b = 5;\nwith the expected result that a and b get the value 5. This is because the assignment operator returns the value that it assigned. First, b is set to 5. Then the a is also set to 5, the return value of b = 5, aka right operand of the assignment."
|
|
293
|
+
# y = new PDF417(x).generate()
|
|
294
|
+
|
|
295
|
+
x = ". Operator"
|
|
296
|
+
y = new PDF417(x)
|
|
297
|
+
z = await y.to_png()
|
|
298
|
+
p z.toString()
|
|
299
|
+
|
|
300
|
+
p new Bar """
|
|
301
|
+
H|XHR1.0|#{time(8)}|E
|
|
302
|
+
P|XYZ999||||||123456|999888777|TEST^SON^|19850615|M|||||||03||TEST^DAD^||123 Main|Anytown|CA|93456||3||DOCTOR^BOB^|||334455||||^|||||||||^|||||||N||^^^^^^^^^^^^^^|^^^^^^^||||||||||||||||1407891260|||||
|
|
303
|
+
C||||||||||||||||N|#{time(8)}||^|||LCM|QA09|N|0847||
|
|
304
|
+
T|500918||||||||||||||||||||||||||||||||||||||||
|
|
305
|
+
S|500918^A^TNG^ANT^^^This is the tongue.~500918^B^TNGBS^^^^This is the base of the tongue.~500918^C^TNGBR^^^^This is the border of the tongue.~500918^D^TNGS^D^^^This is the surface of the tongue.|
|
|
306
|
+
D|F16.183^I63.10^S33.131D||
|
|
307
|
+
L|680|
|
|
308
|
+
E|0|
|
|
309
|
+
"""
|
|
310
|
+
|
|
311
|
+
# p new Bar """
|
|
312
|
+
# h.1 XHR1.0
|
|
313
|
+
# h.2 #{time(8)}
|
|
314
|
+
# h.3 E
|
|
315
|
+
# p.1 XYZ999
|
|
316
|
+
# p.7 123456
|
|
317
|
+
# p.8 999888777
|
|
318
|
+
# p.9-1 TEST
|
|
319
|
+
# p.9-2 SON
|
|
320
|
+
# p.10 19850615
|
|
321
|
+
# p.11 M
|
|
322
|
+
# p.18 03
|
|
323
|
+
# p.20-1 TEST
|
|
324
|
+
# p.20-2 DAD
|
|
325
|
+
# p.22 123 Main
|
|
326
|
+
# p.23 Anytown
|
|
327
|
+
# p.24 CA
|
|
328
|
+
# p.25 93456
|
|
329
|
+
# p.27 3
|
|
330
|
+
# p.29-1 DOCTOR
|
|
331
|
+
# p.29-2 BOB
|
|
332
|
+
# p.32 334455
|
|
333
|
+
# p.52 N
|
|
334
|
+
# p.71 1407891260
|
|
335
|
+
# c.16 N
|
|
336
|
+
# c.17 #{time(8)}
|
|
337
|
+
# c.22 LCM
|
|
338
|
+
# c.23 QA09
|
|
339
|
+
# c.24 N
|
|
340
|
+
# c.25 0847
|
|
341
|
+
# t.1 500918
|
|
342
|
+
# s.1-1 500918
|
|
343
|
+
# s.1-2 A
|
|
344
|
+
# s.1-3 TNG
|
|
345
|
+
# s.1-4 ANT
|
|
346
|
+
# s.1-7 This is the tongue.
|
|
347
|
+
# s.1(2)-1 500918
|
|
348
|
+
# s.1(2)-2 B
|
|
349
|
+
# s.1(2)-3 TNGBS
|
|
350
|
+
# s.1(2)-7 This is the base of the tongue.
|
|
351
|
+
# s.1(3)-1 500918
|
|
352
|
+
# s.1(3)-2 C
|
|
353
|
+
# s.1(3)-3 TNGBR
|
|
354
|
+
# s.1(3)-7 This is the border of the tongue.
|
|
355
|
+
# s.1(4)-1 500918
|
|
356
|
+
# s.1(4)-2 D
|
|
357
|
+
# s.1(4)-3 TNGS
|
|
358
|
+
# s.1(4)-4 D
|
|
359
|
+
# s.1(4)-7 This is the surface of the tongue.
|
|
360
|
+
# d.1-1 F16.183
|
|
361
|
+
# d.1-2 I63.10
|
|
362
|
+
# d.1-3 S33.131D
|
|
363
|
+
# l.1 680
|
|
364
|
+
# e.1 0
|
|
365
|
+
# """
|
|
366
|
+
|
|
367
|
+
# PDF417.to_png("real.png", x.to_s("\r"))
|
|
368
|
+
|
|
369
|
+
# return png image
|
|
370
|
+
to_png(bar)
|
|
371
|
+
|
|
372
|
+
# "H|LCM04.06.10|20130628||^^|PA|\r"
|
|
373
|
+
# "P||1033|Y|N|||05330010|200975012250|TESTY^TESTER^|19800101|M|123456789|100 FAST LANE|Huntsville|AL|35806|2567211139|XI||TESTY^TESTER^|123456789|100 FAST LANE|Huntsville|AL|35806||1||PETERSON^ALAN^|1234567890||B47114||CIGNH||^||||ABCD1231234|||AARPA||^||||123456789|||N||^^^^^^^^^^^^^^|^^^^^^^|2567211139||||||||||*||190||67|1477555225|^^|^^|^^|^^|||C|17930500030^2013|1||Y||N|\r"
|
|
374
|
+
# "C||||||||||||||||N|20130628|500|^|||LCM|HVQ5|N|1252||"
|
|
375
|
+
# "A|||190|1|C|N||||X|X||20121111||||X||||22.2^20121111^22.2|22.2^22.2|Y^3|N||N|Y|N|Y^^|^^^^^|||"
|
|
376
|
+
# "T|X02123|010801|276024|998085|||||||||||||||||||||||||||||||||||||"
|
|
377
|
+
# "M||||||"
|
|
378
|
+
# "B|||||||||||||||||||||"
|
|
379
|
+
# "K|^|||||||||||||||^^^^||||||"
|
|
380
|
+
# "I|1^1^005|2^1^001|^^|^^|^^|^^|^^|^^|"
|
|
381
|
+
# "L|752|"
|
|
382
|
+
# "E|6|"
|
|
383
|
+
|
|
384
|
+
# "Quest: ||||||^GEBERT-PARIKH^CHRIS^^^^^^UPIN~1366608093^GEBERT-PARIKH^CHRIS^^^^^^NPI|||||||||||^^^^^^|"
|
|
385
|
+
# "OBR|3|0023686||^^^1759^CBC (H/H, RBC, INDICES, WBC, PLT)^MET|||20170320153400|||||||||^GEBERT-PARIKH^CHRIS^^^^^^UPIN~1366608093^GEBERT-PARIKH^CHRIS^^^^^^NPI|||||||||||^^^^^^|"
|
|
386
|
+
# "OBR|4|0023686||^^^10231^COMPREHENSIVE METABOLIC PANEL^MET|||20170320153400|||||||||^GEBERT-PARIKH^CHRIS^^^^^^UPIN~1366608093^GEBERT-PARIKH^CHRIS^^^^^^NPI|||||||||||^^^^^^|"
|
|
387
|
+
# "928289728728728272"
|
|
388
|
+
# "OBR|5|0023686||^^^17306^VITAMIN D, 25-HYDROXY, TOTAL, IMMUNOASSAY^MET|||20170320153400|||||||||^GEBERT-PARIKH^CHRIS^^^^^^UPIN~1366608093^GEBERT-PARIKH^CHRIS^^^^^^NPI|||||||||||^^^^^^|"
|
|
389
|
+
# "DG1|1|ICD|Z0000||"
|
|
390
|
+
# "DG1|2|ICD|Z8679||"
|
|
391
|
+
# "DG1|3|ICD|Z862||"
|
|
392
|
+
# "FTS|1041667412||
|
|
393
|
+
|
|
394
|
+
###
|
package/bin/rip
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
|
|
3
|
+
import { readFileSync, writeFileSync, existsSync } from 'fs';
|
|
4
|
+
import { execSync } from 'child_process';
|
|
5
|
+
import { fileURLToPath } from 'url';
|
|
6
|
+
import { dirname, join } from 'path';
|
|
7
|
+
import { Compiler } from '../src/compiler.js';
|
|
8
|
+
import { startREPL } from '../src/repl.js';
|
|
9
|
+
import packageJson from '../package.json' with { type: 'json' };
|
|
10
|
+
|
|
11
|
+
// Get the directory where this script lives
|
|
12
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
13
|
+
const __dirname = dirname(__filename);
|
|
14
|
+
|
|
15
|
+
const VERSION = packageJson.version;
|
|
16
|
+
const SUMMARY = packageJson.description;
|
|
17
|
+
|
|
18
|
+
function printHelp() {
|
|
19
|
+
console.log(`
|
|
20
|
+
Rip ${VERSION} - ${SUMMARY}
|
|
21
|
+
|
|
22
|
+
Usage:
|
|
23
|
+
rip [options] [file]
|
|
24
|
+
rip # Start interactive REPL (no arguments)
|
|
25
|
+
|
|
26
|
+
Options:
|
|
27
|
+
-c, --compile Show compiled JavaScript (compile mode)
|
|
28
|
+
-h, --help Show this help message
|
|
29
|
+
-o, --output <file> Write JavaScript to file
|
|
30
|
+
-q, --quiet Suppress headers (with -c)
|
|
31
|
+
-r, --repl Start interactive REPL
|
|
32
|
+
-s, --sexpr Show s-expressions
|
|
33
|
+
-t, --tokens Show token stream
|
|
34
|
+
-v, --version Show version number
|
|
35
|
+
|
|
36
|
+
Examples:
|
|
37
|
+
rip # Interactive REPL
|
|
38
|
+
rip script.rip # Execute script (auto-detects .rip)
|
|
39
|
+
rip script.rip arg1 arg2 # Execute with arguments
|
|
40
|
+
rip -c example.rip # Compile to stdout
|
|
41
|
+
rip -q example.rip # Just the JS (for piping)
|
|
42
|
+
rip -o output.js example.rip # Save to file
|
|
43
|
+
rip -s -t example.rip # Show everything (debug mode)
|
|
44
|
+
echo 'x = 1 + 2' | rip # Read from stdin
|
|
45
|
+
|
|
46
|
+
Shebang support:
|
|
47
|
+
#!/usr/bin/env rip # Execute with rip
|
|
48
|
+
#!/usr/bin/env bun # Execute with bun (also works)
|
|
49
|
+
`);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
async function main() {
|
|
53
|
+
const args = process.argv.slice(2);
|
|
54
|
+
|
|
55
|
+
if (args.includes('-h') || args.includes('--help')) {
|
|
56
|
+
printHelp();
|
|
57
|
+
process.exit(0);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (args.includes('-v') || args.includes('--version')) {
|
|
61
|
+
console.log(`Rip ${VERSION} - ${SUMMARY}`);
|
|
62
|
+
process.exit(0);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Check if REPL should be started
|
|
66
|
+
// Launch REPL if: no args AND stdin is a TTY (not piped), OR explicit -r flag
|
|
67
|
+
const isTTY = process.stdin.isTTY;
|
|
68
|
+
if ((args.length === 0 && isTTY) || args.includes('-r') || args.includes('--repl')) {
|
|
69
|
+
startREPL();
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const options = {
|
|
74
|
+
compile: args.includes('-c') || args.includes('--compile'),
|
|
75
|
+
showTokens: args.includes('-t') || args.includes('--tokens'),
|
|
76
|
+
showSExpr: args.includes('-s') || args.includes('--sexpr'),
|
|
77
|
+
quiet: args.includes('-q') || args.includes('--quiet')
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
// Find input file (last non-option argument)
|
|
81
|
+
let inputFile = null;
|
|
82
|
+
let outputFile = null;
|
|
83
|
+
|
|
84
|
+
for (let i = 0; i < args.length; i++) {
|
|
85
|
+
if (args[i] === '-o' || args[i] === '--output') {
|
|
86
|
+
outputFile = args[i + 1];
|
|
87
|
+
i++;
|
|
88
|
+
} else if (!args[i].startsWith('-') && !inputFile) {
|
|
89
|
+
inputFile = args[i]; // Only take first non-option as input file
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// If .rip file without compile flags → execute instead of compile
|
|
94
|
+
const hasCompileFlag = options.compile || options.showTokens || options.showSExpr || outputFile;
|
|
95
|
+
if (inputFile && inputFile.endsWith('.rip') && !hasCompileFlag) {
|
|
96
|
+
// Check if file exists
|
|
97
|
+
if (!existsSync(inputFile)) {
|
|
98
|
+
console.error(`Error: File not found: ${inputFile}`);
|
|
99
|
+
process.exit(1);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Execute the script with Bun using our loader
|
|
103
|
+
const loaderPath = join(__dirname, '../rip-loader.ts');
|
|
104
|
+
|
|
105
|
+
// Get script arguments (everything after the input file)
|
|
106
|
+
const inputFileIndex = args.indexOf(inputFile);
|
|
107
|
+
const scriptArgs = args.slice(inputFileIndex + 1);
|
|
108
|
+
|
|
109
|
+
try {
|
|
110
|
+
execSync(`bun --preload ${loaderPath} ${inputFile} ${scriptArgs.join(' ')}`, {
|
|
111
|
+
stdio: 'inherit'
|
|
112
|
+
});
|
|
113
|
+
process.exit(0);
|
|
114
|
+
} catch (error) {
|
|
115
|
+
process.exit(error.status || 1);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
let source;
|
|
120
|
+
|
|
121
|
+
try {
|
|
122
|
+
if (!inputFile) {
|
|
123
|
+
// Read from stdin if no file specified (file descriptor 0)
|
|
124
|
+
source = readFileSync(0, 'utf-8');
|
|
125
|
+
} else {
|
|
126
|
+
// Check if file exists first
|
|
127
|
+
if (!existsSync(inputFile)) {
|
|
128
|
+
console.error(`Error: File not found: ${inputFile}`);
|
|
129
|
+
process.exit(1);
|
|
130
|
+
}
|
|
131
|
+
// Read source file
|
|
132
|
+
source = readFileSync(inputFile, 'utf-8');
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Compile
|
|
136
|
+
const compiler = new Compiler(options);
|
|
137
|
+
const result = compiler.compile(source);
|
|
138
|
+
|
|
139
|
+
// Output
|
|
140
|
+
if (outputFile) {
|
|
141
|
+
// Save to file
|
|
142
|
+
writeFileSync(outputFile, result.code, 'utf-8');
|
|
143
|
+
if (!options.quiet) {
|
|
144
|
+
console.log(`Compiled to ${outputFile}`);
|
|
145
|
+
}
|
|
146
|
+
} else {
|
|
147
|
+
// Default mode - compile and output to stdout
|
|
148
|
+
if (!options.quiet) {
|
|
149
|
+
console.log(`// == JavaScript output by Rip ${VERSION} == //\n`);
|
|
150
|
+
}
|
|
151
|
+
console.log(result.code);
|
|
152
|
+
}
|
|
153
|
+
} catch (error) {
|
|
154
|
+
console.error('Compilation Error:', error.message);
|
|
155
|
+
if (error.stack) {
|
|
156
|
+
console.error(error.stack);
|
|
157
|
+
}
|
|
158
|
+
process.exit(1);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
main();
|