goodheart 0.4.9 → 0.4.10
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/.github/workflows/rspec.yml +17 -0
- data/.github/workflows/rubocop.yml +18 -0
- data/.gitignore +2 -0
- data/.rubocop.yml +63 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +43 -16
- data/README.md +1 -1
- data/Rakefile +3 -1
- data/bin/console +1 -0
- data/goodheart.gemspec +18 -11
- data/lib/clojure/alias.rb +2 -0
- data/lib/clojure/core.rb +34 -32
- data/lib/clojure/lib.rb +4 -3
- data/lib/clojure/namespace.rb +12 -7
- data/lib/clojure/reader.rb +36 -30
- data/lib/clojure/runtime.rb +3 -10
- data/lib/clojure.rb +2 -0
- data/lib/goodheart/version.rb +3 -1
- data/lib/goodheart.rb +2 -0
- metadata +59 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cf1d4debf40e50022b21900caa26cc8bd78bc4f5f39c1284fe3ecaca0f044ae1
|
4
|
+
data.tar.gz: 582394b87648c170dc3432b8bb195473fbd187b6ca3ce030c007e3689ad769e2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f124c78b08c57b3c0cb5ae22906ff022688d74b32b8c8ad23848cc747aea0ac117d1d91834a96c0d2ecc17380c5a2950124ac75abee9cad7286edaf03d64739c
|
7
|
+
data.tar.gz: 8e7eef6b865b1811ab12eab50a48a469c3b84be702cc72e2bf68c0b8f1ec185e696a3f6df5569b54c30091b4a0bc58ee71033412685227600c4a3f09d7ad506c
|
@@ -0,0 +1,17 @@
|
|
1
|
+
name: RSpec
|
2
|
+
|
3
|
+
on:
|
4
|
+
- pull_request
|
5
|
+
|
6
|
+
jobs:
|
7
|
+
test:
|
8
|
+
runs-on: ubuntu-latest
|
9
|
+
steps:
|
10
|
+
- uses: actions/checkout@v2
|
11
|
+
- uses: ruby/setup-ruby@v1
|
12
|
+
with:
|
13
|
+
ruby-version: 2.6
|
14
|
+
bundler-cache: true
|
15
|
+
|
16
|
+
- name: Run test
|
17
|
+
run: bundle exec rspec
|
@@ -0,0 +1,18 @@
|
|
1
|
+
name: Rubocop
|
2
|
+
|
3
|
+
on:
|
4
|
+
- pull_request
|
5
|
+
|
6
|
+
jobs:
|
7
|
+
test:
|
8
|
+
runs-on: ubuntu-latest
|
9
|
+
|
10
|
+
steps:
|
11
|
+
- uses: actions/checkout@v2
|
12
|
+
- uses: ruby/setup-ruby@v1
|
13
|
+
with:
|
14
|
+
ruby-version: 2.6
|
15
|
+
bundler-cache: true
|
16
|
+
|
17
|
+
- name: Run linter
|
18
|
+
run: bundle exec rubocop
|
data/.gitignore
CHANGED
data/.rubocop.yml
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
require:
|
2
|
+
- rubocop-rake
|
3
|
+
- rubocop-rspec
|
4
|
+
|
5
|
+
AllCops:
|
6
|
+
NewCops: enable
|
7
|
+
|
8
|
+
Layout/LineLength:
|
9
|
+
Max: 120
|
10
|
+
|
11
|
+
Metrics/MethodLength:
|
12
|
+
Max: 24
|
13
|
+
|
14
|
+
Metrics/ClassLength:
|
15
|
+
Max: 512
|
16
|
+
|
17
|
+
Metrics/BlockLength:
|
18
|
+
Max: 256
|
19
|
+
|
20
|
+
Layout/SpaceAroundEqualsInParameterDefault:
|
21
|
+
EnforcedStyle: no_space
|
22
|
+
|
23
|
+
Style/StringLiterals:
|
24
|
+
EnforcedStyle: double_quotes
|
25
|
+
|
26
|
+
Style/HashSyntax:
|
27
|
+
EnforcedStyle: ruby19_no_mixed_keys
|
28
|
+
|
29
|
+
Style/CollectionMethods:
|
30
|
+
Enabled: true
|
31
|
+
PreferredMethods:
|
32
|
+
reduce: "inject"
|
33
|
+
|
34
|
+
Style/ParenthesesAroundCondition:
|
35
|
+
AllowSafeAssignment: false
|
36
|
+
Lint/AssignmentInCondition:
|
37
|
+
AllowSafeAssignment: false
|
38
|
+
|
39
|
+
Style/RaiseArgs:
|
40
|
+
Enabled: false
|
41
|
+
|
42
|
+
Style/SignalException:
|
43
|
+
EnforcedStyle: only_raise
|
44
|
+
|
45
|
+
Layout/SpaceInsideBlockBraces:
|
46
|
+
SpaceBeforeBlockParameters: false
|
47
|
+
|
48
|
+
# Check with yard instead.
|
49
|
+
Style/Documentation:
|
50
|
+
Enabled: false
|
51
|
+
|
52
|
+
Naming/BinaryOperatorParameterName:
|
53
|
+
Enabled: false
|
54
|
+
|
55
|
+
# Style preference
|
56
|
+
Style/MethodDefParentheses:
|
57
|
+
Enabled: false
|
58
|
+
|
59
|
+
RSpec/MultipleExpectations:
|
60
|
+
Max: 4
|
61
|
+
|
62
|
+
RSpec/ExampleLength:
|
63
|
+
Max: 16
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,27 +1,51 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
goodheart (0.
|
4
|
+
goodheart (0.4.9)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: https://rubygems.org/
|
8
8
|
specs:
|
9
|
+
ast (2.4.2)
|
9
10
|
byebug (10.0.2)
|
10
|
-
diff-lcs (1.
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
rspec
|
11
|
+
diff-lcs (1.5.0)
|
12
|
+
parallel (1.22.1)
|
13
|
+
parser (3.1.2.0)
|
14
|
+
ast (~> 2.4.1)
|
15
|
+
rainbow (3.1.1)
|
16
|
+
rake (13.0.6)
|
17
|
+
regexp_parser (2.3.0)
|
18
|
+
rexml (3.2.5)
|
19
|
+
rspec (3.11.0)
|
20
|
+
rspec-core (~> 3.11.0)
|
21
|
+
rspec-expectations (~> 3.11.0)
|
22
|
+
rspec-mocks (~> 3.11.0)
|
23
|
+
rspec-core (3.11.0)
|
24
|
+
rspec-support (~> 3.11.0)
|
25
|
+
rspec-expectations (3.11.0)
|
19
26
|
diff-lcs (>= 1.2.0, < 2.0)
|
20
|
-
rspec-support (~> 3.
|
21
|
-
rspec-mocks (3.
|
27
|
+
rspec-support (~> 3.11.0)
|
28
|
+
rspec-mocks (3.11.1)
|
22
29
|
diff-lcs (>= 1.2.0, < 2.0)
|
23
|
-
rspec-support (~> 3.
|
24
|
-
rspec-support (3.
|
30
|
+
rspec-support (~> 3.11.0)
|
31
|
+
rspec-support (3.11.0)
|
32
|
+
rubocop (1.28.1)
|
33
|
+
parallel (~> 1.10)
|
34
|
+
parser (>= 3.1.0.0)
|
35
|
+
rainbow (>= 2.2.2, < 4.0)
|
36
|
+
regexp_parser (>= 1.8, < 3.0)
|
37
|
+
rexml
|
38
|
+
rubocop-ast (>= 1.17.0, < 2.0)
|
39
|
+
ruby-progressbar (~> 1.7)
|
40
|
+
unicode-display_width (>= 1.4.0, < 3.0)
|
41
|
+
rubocop-ast (1.17.0)
|
42
|
+
parser (>= 3.1.1.0)
|
43
|
+
rubocop-rake (0.6.0)
|
44
|
+
rubocop (~> 1.0)
|
45
|
+
rubocop-rspec (2.10.0)
|
46
|
+
rubocop (~> 1.19)
|
47
|
+
ruby-progressbar (1.11.0)
|
48
|
+
unicode-display_width (2.1.0)
|
25
49
|
|
26
50
|
PLATFORMS
|
27
51
|
x86_64-linux
|
@@ -30,8 +54,11 @@ DEPENDENCIES
|
|
30
54
|
bundler (~> 2.2.29)
|
31
55
|
byebug (~> 10.0)
|
32
56
|
goodheart!
|
33
|
-
rake (~>
|
57
|
+
rake (~> 13.0)
|
34
58
|
rspec (~> 3.0)
|
59
|
+
rubocop (~> 1.28)
|
60
|
+
rubocop-rake (~> 0.6)
|
61
|
+
rubocop-rspec (~> 2.10)
|
35
62
|
|
36
63
|
BUNDLED WITH
|
37
|
-
2.2.
|
64
|
+
2.2.30
|
data/README.md
CHANGED
@@ -46,7 +46,7 @@ Or install it yourself as:
|
|
46
46
|
require "goodheart"
|
47
47
|
|
48
48
|
runtime = Clojure::Runtime.new
|
49
|
-
runtime.
|
49
|
+
runtime.read("validation", open("shared_validation.clj").read)
|
50
50
|
runtime.namespace("validation").evaluate(["validate", data])
|
51
51
|
```
|
52
52
|
|
data/Rakefile
CHANGED
data/bin/console
CHANGED
data/goodheart.gemspec
CHANGED
@@ -1,17 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
|
2
|
-
lib = File.expand_path("
|
3
|
+
lib = File.expand_path("lib", __dir__)
|
3
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
5
|
require "goodheart/version"
|
5
6
|
|
6
7
|
Gem::Specification.new do |spec|
|
7
8
|
spec.name = "goodheart"
|
8
9
|
spec.version = Goodheart::VERSION
|
9
|
-
spec.authors = ["
|
10
|
-
spec.email = ["
|
10
|
+
spec.authors = ["dimafedotov"]
|
11
|
+
spec.email = ["fedotov2d@gmail.com"]
|
11
12
|
|
12
|
-
spec.summary =
|
13
|
-
spec.description =
|
14
|
-
spec.homepage = "https://github.com/
|
13
|
+
spec.summary = "Clojure interpreter and runtime."
|
14
|
+
spec.description = "Good Heart allows you to put some Clojure right inside you Ruby application."
|
15
|
+
spec.homepage = "https://github.com/dimafedotov/goodheart"
|
15
16
|
spec.license = "MIT"
|
16
17
|
|
17
18
|
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
@@ -23,17 +24,23 @@ Gem::Specification.new do |spec|
|
|
23
24
|
# "public gem pushes."
|
24
25
|
# end
|
25
26
|
|
27
|
+
spec.required_ruby_version = "~> 2.6.6"
|
28
|
+
|
26
29
|
# Specify which files should be added to the gem when it is released.
|
27
30
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
28
|
-
spec.files
|
29
|
-
`git ls-files -z`.split("\x0").reject {
|
31
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
32
|
+
`git ls-files -z`.split("\x0").reject {|f| f.match(%r{^(spec)/}) }
|
30
33
|
end
|
31
34
|
spec.bindir = "exe"
|
32
|
-
spec.executables = spec.files.grep(%r{^exe/}) {
|
35
|
+
spec.executables = spec.files.grep(%r{^exe/}) {|f| File.basename(f) }
|
33
36
|
spec.require_paths = ["lib"]
|
34
37
|
|
35
38
|
spec.add_development_dependency "bundler", "~> 2.2.29"
|
36
|
-
spec.add_development_dependency "rake", "~> 10.0"
|
37
|
-
spec.add_development_dependency "rspec", "~> 3.0"
|
38
39
|
spec.add_development_dependency "byebug", "~> 10.0"
|
40
|
+
spec.add_development_dependency "rake", "~> 13.0"
|
41
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
42
|
+
spec.add_development_dependency "rubocop", "~> 1.28"
|
43
|
+
spec.add_development_dependency "rubocop-rake", "~> 0.6"
|
44
|
+
spec.add_development_dependency "rubocop-rspec", "~> 2.10"
|
45
|
+
spec.metadata["rubygems_mfa_required"] = "true"
|
39
46
|
end
|
data/lib/clojure/alias.rb
CHANGED
data/lib/clojure/core.rb
CHANGED
@@ -1,15 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Clojure
|
2
4
|
class Core
|
3
5
|
extend Library
|
4
6
|
|
5
|
-
define "+", ->(_ctx, args) { args.
|
6
|
-
define "-", ->(_ctx, args) { args.
|
7
|
-
define "*", ->(_ctx, args) { args.
|
8
|
-
define "/", ->(_ctx, args) { args.
|
7
|
+
define "+", ->(_ctx, args) { args.inject(:+) }
|
8
|
+
define "-", ->(_ctx, args) { args.inject(:-) }
|
9
|
+
define "*", ->(_ctx, args) { args.inject(:*) }
|
10
|
+
define "/", ->(_ctx, args) { args.inject(:/) }
|
9
11
|
|
10
|
-
define "=", ->(_ctx, args) {
|
11
|
-
define ">", ->(_ctx, args) {
|
12
|
-
define "<", ->(_ctx, args) {
|
12
|
+
define "=", ->(_ctx, args) { !args.inject {|x, y| x == y ? x : break }.nil? }
|
13
|
+
define ">", ->(_ctx, args) { !args.inject {|x, y| x > y ? x : break }.nil? }
|
14
|
+
define "<", ->(_ctx, args) { !args.inject {|x, y| x < y ? x : break }.nil? }
|
13
15
|
|
14
16
|
define "vector", ->(_ctx, args) { Array[*args] }
|
15
17
|
define "hash-map", ->(_ctx, args) { Hash[*args] }
|
@@ -17,28 +19,29 @@ module Clojure
|
|
17
19
|
define "str", ->(_ctx, args) { args.map(&:to_s).join }
|
18
20
|
define "quote", ->(_ctx, args) { args.first }
|
19
21
|
|
20
|
-
define "not", ->(_ctx, args) {
|
22
|
+
define "not", ->(_ctx, args) { !args }
|
21
23
|
define "nil?", ->(_ctx, args) { args.first.nil? }
|
22
24
|
|
23
|
-
define "do", ->(_ctx, args) { args.map {
|
25
|
+
define "do", ->(_ctx, args) { args.map {|f| ctx.evaluate f } }
|
24
26
|
|
25
27
|
define "subs", ->(ctx, args) { (ctx.evaluate(args[0]))[ctx.evaluate(args[1])..(ctx.evaluate(args[2]) || -1)] }
|
26
28
|
|
27
29
|
define "let", (lambda do |ctx, forms|
|
28
30
|
# skip "vector" from params
|
29
|
-
bindings = forms[0][1
|
31
|
+
bindings = forms[0][1..]
|
30
32
|
lctx = ctx.dup
|
31
33
|
bindings.each_slice(2) do |k, v|
|
32
34
|
lctx[k] = lctx.evaluate(v)
|
33
35
|
end
|
34
|
-
forms[1
|
36
|
+
forms[1..].map do |f|
|
35
37
|
lctx.evaluate(f)
|
36
38
|
end.last
|
37
39
|
end)
|
38
40
|
|
39
41
|
define "for", (lambda do |ctx, forms|
|
40
42
|
head, expr, extra = *forms
|
41
|
-
raise
|
43
|
+
raise StandardError, "Wrong number of args passed to: core/for" if extra
|
44
|
+
|
42
45
|
key = head[1]
|
43
46
|
col = ctx.evaluate head[2]
|
44
47
|
col.map do |i|
|
@@ -47,9 +50,9 @@ module Clojure
|
|
47
50
|
end
|
48
51
|
end)
|
49
52
|
|
50
|
-
define "and", ->(ctx, args) { args.map {
|
53
|
+
define "and", ->(ctx, args) { args.map {|form| ctx.evaluate form }.all? }
|
51
54
|
define "or", (lambda do |ctx, args|
|
52
|
-
args.find {
|
55
|
+
args.find {|form| !ctx.evaluate(form).nil? }
|
53
56
|
end)
|
54
57
|
|
55
58
|
define "if", (lambda do |ctx, args|
|
@@ -64,12 +67,12 @@ module Clojure
|
|
64
67
|
|
65
68
|
define "map", (lambda do |ctx, args|
|
66
69
|
fn, coll = args
|
67
|
-
coll.map {
|
70
|
+
coll.map {|i| fn[ctx, [i]] }
|
68
71
|
end)
|
69
72
|
|
70
73
|
define "filter", (lambda do |ctx, args|
|
71
74
|
fn, coll = args
|
72
|
-
coll.select {
|
75
|
+
coll.select {|i| fn[ctx, [i]] }
|
73
76
|
end)
|
74
77
|
|
75
78
|
define "distinct", ->(_ctx, args) { (args[0] || []).uniq }
|
@@ -77,19 +80,17 @@ module Clojure
|
|
77
80
|
define "remove", (lambda do |ctx, args|
|
78
81
|
fn, coll = args
|
79
82
|
new_coll = coll.dup
|
80
|
-
new_coll.delete_if {
|
83
|
+
new_coll.delete_if {|i| fn[ctx, [i]] }
|
81
84
|
end)
|
82
85
|
|
83
86
|
define "def", (lambda do |ctx, args|
|
84
87
|
ctx[args[0]] = ctx.evaluate args[1]
|
85
|
-
"#{ctx[
|
88
|
+
"#{ctx['*ns*']}/#{args[0]}"
|
86
89
|
end)
|
87
90
|
|
88
|
-
define "byebug", ->(ctx, args) { byebug }
|
89
|
-
|
90
91
|
define "merge", (lambda do |ctx, args|
|
91
92
|
coll = ctx.evaluate args[0]
|
92
|
-
args[1
|
93
|
+
args[1..].each do |arg|
|
93
94
|
coll.merge! ctx.evaluate(arg)
|
94
95
|
end
|
95
96
|
coll
|
@@ -97,28 +98,28 @@ module Clojure
|
|
97
98
|
|
98
99
|
define "assoc", (lambda do |ctx, args|
|
99
100
|
coll = ctx.evaluate args[0]
|
100
|
-
pairs = args[1
|
101
|
+
pairs = args[1..].map {|x| ctx.evaluate x }
|
101
102
|
coll.merge(Hash[*pairs])
|
102
103
|
end)
|
103
104
|
|
104
|
-
define "first", (lambda do |
|
105
|
+
define "first", (lambda do |_ctx, args|
|
105
106
|
args.first.first
|
106
107
|
end)
|
107
108
|
|
108
|
-
define "rest", (lambda do |
|
109
|
-
args.first[1
|
109
|
+
define "rest", (lambda do |_ctx, args|
|
110
|
+
args.first[1..]
|
110
111
|
end)
|
111
112
|
|
112
113
|
define "ns", (lambda do |ctx, args|
|
113
114
|
self["def"][ctx, ["*ns*", ["quote", args[0]]]]
|
114
115
|
if args[1] && args[1][0] == :require
|
115
|
-
args[1][1
|
116
|
+
args[1][1..].each do |refer|
|
116
117
|
ns = refer[1].to_sym
|
117
|
-
binds = Hash[*refer[2
|
118
|
+
binds = Hash[*refer[2..]]
|
118
119
|
bindings = {}
|
119
120
|
bindings[binds[:as]] = [ns] if binds[:as]
|
120
121
|
if binds[:refer]
|
121
|
-
binds[:refer][1
|
122
|
+
binds[:refer][1..].each do |ref|
|
122
123
|
bindings[ref] = [ns, ref]
|
123
124
|
end
|
124
125
|
end
|
@@ -129,20 +130,21 @@ module Clojure
|
|
129
130
|
end
|
130
131
|
end
|
131
132
|
end
|
133
|
+
|
132
134
|
nil
|
133
135
|
end)
|
134
136
|
|
135
137
|
define "fn", (lambda do |ctx, args|
|
136
138
|
# TODO: poor implementation
|
137
139
|
lambda do |_ctx, fn_args|
|
138
|
-
params = args[0][1
|
139
|
-
fn_ctx = ctx.merge(
|
140
|
-
args[1
|
140
|
+
params = args[0][1..].zip(fn_args)
|
141
|
+
fn_ctx = ctx.merge(params.to_h)
|
142
|
+
args[1..].map do |form|
|
141
143
|
fn_ctx.evaluate form
|
142
144
|
end.last
|
143
145
|
end
|
144
146
|
end)
|
145
147
|
|
146
|
-
define "defn", ->(ctx, args) { self[
|
148
|
+
define "defn", ->(ctx, args) { self["def"].call(ctx, [args[0], self["fn"].call(ctx, args[1..])]) }
|
147
149
|
end
|
148
150
|
end
|
data/lib/clojure/lib.rb
CHANGED
data/lib/clojure/namespace.rb
CHANGED
@@ -1,14 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Clojure
|
2
4
|
class Namespace < Hash
|
3
5
|
# Clojure's ns | evaluation context | class
|
4
6
|
|
7
|
+
# rubocop:disable Lint/MissingSuper
|
5
8
|
def initialize(runtime)
|
6
9
|
@runtime = runtime
|
7
10
|
end
|
11
|
+
# rubocop:enable Lint/MissingSuper
|
8
12
|
|
9
13
|
attr_reader :runtime
|
10
14
|
|
11
|
-
# calls
|
15
|
+
# calls with postponed evaluation of expression
|
12
16
|
SPECIAL = %w[ns fn defn def quote let for].freeze
|
13
17
|
|
14
18
|
def evaluate(form)
|
@@ -25,14 +29,14 @@ module Clojure
|
|
25
29
|
private
|
26
30
|
|
27
31
|
def resolve(symbol)
|
28
|
-
n, ns = symbol.split(
|
32
|
+
n, ns = symbol.split("/").reverse
|
29
33
|
i = self[ns] || self[n] || Clojure::Core[symbol] || raise("Can't resolve #{symbol}.")
|
30
34
|
case i
|
31
35
|
when Clojure::Alias
|
32
36
|
if ns
|
33
|
-
i.lookup
|
37
|
+
i.lookup[n]
|
34
38
|
else
|
35
|
-
i.lookup
|
39
|
+
i.lookup
|
36
40
|
end
|
37
41
|
else
|
38
42
|
i
|
@@ -46,15 +50,16 @@ module Clojure
|
|
46
50
|
form_eval head
|
47
51
|
when Symbol
|
48
52
|
# dirty keyword IFn
|
49
|
-
->
|
53
|
+
->(_ctx, args) { args[0][head] }
|
50
54
|
else
|
51
55
|
resolve head
|
52
56
|
end
|
53
|
-
raise
|
57
|
+
raise StandardError, "Function #{head} not defined" unless fn
|
58
|
+
|
54
59
|
args = if head.is_a?(String) && SPECIAL.include?(head)
|
55
60
|
expressions
|
56
61
|
else
|
57
|
-
expressions.map {
|
62
|
+
expressions.map {|f| evaluate f }
|
58
63
|
end
|
59
64
|
fn.call self, args
|
60
65
|
end
|
data/lib/clojure/reader.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Clojure
|
2
4
|
# read Clojure as Ruby's data-structures
|
3
5
|
class Reader
|
@@ -7,10 +9,10 @@ module Clojure
|
|
7
9
|
@ast = []
|
8
10
|
loop do
|
9
11
|
break if eof?
|
12
|
+
|
10
13
|
r = read_next
|
11
14
|
@ast << r if r
|
12
15
|
end
|
13
|
-
true
|
14
16
|
end
|
15
17
|
|
16
18
|
def inspect
|
@@ -31,30 +33,34 @@ module Clojure
|
|
31
33
|
@cursor = @io.getc || :eof
|
32
34
|
end
|
33
35
|
|
36
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
37
|
+
# rubocop:disable Metrics/AbcSize
|
34
38
|
def read_next
|
35
39
|
# puts "reading next"
|
36
40
|
# puts "-> #{cursor}"
|
37
41
|
case cursor
|
38
|
-
when :eof then
|
39
|
-
when /\s
|
40
|
-
when
|
41
|
-
when /\;/ then skip_comment
|
42
|
+
when :eof then nil
|
43
|
+
when /\s|,/ then skip_char
|
44
|
+
when /;/ then skip_comment
|
42
45
|
when /\d/ then read_number
|
43
46
|
when /\(/ then read_form
|
44
47
|
when /\[/ then read_form till: "]", into: ["vector"]
|
45
48
|
when /\{/ then read_form till: "}", into: ["hash-map"]
|
46
|
-
when
|
47
|
-
when
|
48
|
-
when
|
49
|
+
when /:/ then read_keyword
|
50
|
+
when /"/ then read_string
|
51
|
+
when /'/ then read_quote
|
49
52
|
when /\#/ then read_special
|
50
53
|
when /\S/ then read_symbol
|
54
|
+
else raise StandardError, "Unexpected symbol: #{cursor}"
|
51
55
|
end
|
52
56
|
end
|
57
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
58
|
+
# rubocop:enable Metrics/AbcSize
|
53
59
|
|
54
60
|
def read_special
|
55
61
|
case next_char
|
56
|
-
when
|
57
|
-
else raise
|
62
|
+
when /_/ then read_sexp_comment
|
63
|
+
else raise StandardError, "Unknown token: ##{cursor}"
|
58
64
|
end
|
59
65
|
end
|
60
66
|
|
@@ -79,7 +85,8 @@ module Clojure
|
|
79
85
|
skip_char # opening parenthesis
|
80
86
|
ast = into
|
81
87
|
until cursor == till
|
82
|
-
raise
|
88
|
+
raise StandardError, "Unbalanced #{opening}#{till}" if eof?
|
89
|
+
|
83
90
|
r = read_next
|
84
91
|
ast << r if r
|
85
92
|
end
|
@@ -89,18 +96,18 @@ module Clojure
|
|
89
96
|
|
90
97
|
def read_number
|
91
98
|
n = cursor
|
92
|
-
while next_char.match
|
93
|
-
|
99
|
+
n << cursor while next_char.match(/[\d|.]/)
|
100
|
+
begin
|
101
|
+
Integer(n)
|
102
|
+
rescue StandardError
|
103
|
+
Float(n)
|
94
104
|
end
|
95
|
-
Integer(n) rescue Float(n)
|
96
105
|
end
|
97
106
|
|
98
107
|
def read_keyword
|
99
108
|
next_char
|
100
109
|
k = cursor
|
101
|
-
while next_char.match
|
102
|
-
k << cursor
|
103
|
-
end
|
110
|
+
k << cursor while next_char.match(/\w|\.|#|-|_/)
|
104
111
|
k.to_sym
|
105
112
|
end
|
106
113
|
|
@@ -109,34 +116,33 @@ module Clojure
|
|
109
116
|
["quote", read_next]
|
110
117
|
end
|
111
118
|
|
119
|
+
# rubocop:disable Metrics/AbcSize
|
112
120
|
def read_string
|
113
121
|
next_char
|
114
122
|
if cursor == '"'
|
115
123
|
next_char
|
116
|
-
return [
|
124
|
+
return ["str", ["quote", ""]]
|
117
125
|
end
|
118
126
|
s = cursor.dup
|
119
127
|
prev = cursor
|
120
|
-
until
|
121
|
-
if cursor
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
s << cursor
|
128
|
+
until next_char == '"' && prev != "\\"
|
129
|
+
if cursor != "\\"
|
130
|
+
s << if prev == "\\" && cursor != '"'
|
131
|
+
"\\#{cursor}"
|
132
|
+
else
|
133
|
+
cursor
|
134
|
+
end
|
128
135
|
end
|
129
136
|
prev = cursor
|
130
137
|
end
|
131
138
|
next_char
|
132
|
-
[
|
139
|
+
["str", ["quote", s]]
|
133
140
|
end
|
141
|
+
# rubocop:enable Metrics/AbcSize
|
134
142
|
|
135
143
|
def read_symbol
|
136
144
|
symbol = cursor
|
137
|
-
while next_char.match(
|
138
|
-
symbol << cursor
|
139
|
-
end
|
145
|
+
symbol << cursor while next_char.match(%r{\w|-|\.|\?|\+|/})
|
140
146
|
symbol
|
141
147
|
end
|
142
148
|
end
|
data/lib/clojure/runtime.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Clojure
|
2
4
|
class Runtime
|
3
5
|
def initialize
|
@@ -14,19 +16,10 @@ module Clojure
|
|
14
16
|
@namespaces[lib.name.downcase.gsub("::", ".").to_sym] = lib
|
15
17
|
end
|
16
18
|
|
17
|
-
def load(filename)
|
18
|
-
ns = Clojure::Namespace.new(self)
|
19
|
-
source = open(filename).read
|
20
|
-
ast = Clojure::Reader.new(source).ast
|
21
|
-
ast.each { |form| ns.evaluate form }
|
22
|
-
ns_name = ns["*ns*"]
|
23
|
-
@namespaces[ns_name.to_sym] = namespace(ns_name).merge(ns)
|
24
|
-
end
|
25
|
-
|
26
19
|
def read(ns_name, source)
|
27
20
|
ast = Clojure::Reader.new(source).ast
|
28
21
|
ns = namespace ns_name.to_sym
|
29
|
-
ast.map {
|
22
|
+
ast.map {|form| ns.evaluate form }.last
|
30
23
|
end
|
31
24
|
end
|
32
25
|
end
|
data/lib/clojure.rb
CHANGED
data/lib/goodheart/version.rb
CHANGED
data/lib/goodheart.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: goodheart
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
-
|
7
|
+
- dimafedotov
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-04-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -25,7 +25,7 @@ dependencies:
|
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 2.2.29
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: byebug
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '13.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '13.0'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: rspec
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -53,28 +67,59 @@ dependencies:
|
|
53
67
|
- !ruby/object:Gem::Version
|
54
68
|
version: '3.0'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
70
|
+
name: rubocop
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
58
72
|
requirements:
|
59
73
|
- - "~>"
|
60
74
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
75
|
+
version: '1.28'
|
62
76
|
type: :development
|
63
77
|
prerelease: false
|
64
78
|
version_requirements: !ruby/object:Gem::Requirement
|
65
79
|
requirements:
|
66
80
|
- - "~>"
|
67
81
|
- !ruby/object:Gem::Version
|
68
|
-
version: '
|
82
|
+
version: '1.28'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rubocop-rake
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0.6'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0.6'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rubocop-rspec
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '2.10'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '2.10'
|
69
111
|
description: Good Heart allows you to put some Clojure right inside you Ruby application.
|
70
112
|
email:
|
71
|
-
-
|
113
|
+
- fedotov2d@gmail.com
|
72
114
|
executables: []
|
73
115
|
extensions: []
|
74
116
|
extra_rdoc_files: []
|
75
117
|
files:
|
118
|
+
- ".github/workflows/rspec.yml"
|
119
|
+
- ".github/workflows/rubocop.yml"
|
76
120
|
- ".gitignore"
|
77
121
|
- ".rspec"
|
122
|
+
- ".rubocop.yml"
|
78
123
|
- ".travis.yml"
|
79
124
|
- CODE_OF_CONDUCT.md
|
80
125
|
- Gemfile
|
@@ -94,19 +139,20 @@ files:
|
|
94
139
|
- lib/clojure/runtime.rb
|
95
140
|
- lib/goodheart.rb
|
96
141
|
- lib/goodheart/version.rb
|
97
|
-
homepage: https://github.com/
|
142
|
+
homepage: https://github.com/dimafedotov/goodheart
|
98
143
|
licenses:
|
99
144
|
- MIT
|
100
|
-
metadata:
|
145
|
+
metadata:
|
146
|
+
rubygems_mfa_required: 'true'
|
101
147
|
post_install_message:
|
102
148
|
rdoc_options: []
|
103
149
|
require_paths:
|
104
150
|
- lib
|
105
151
|
required_ruby_version: !ruby/object:Gem::Requirement
|
106
152
|
requirements:
|
107
|
-
- - "
|
153
|
+
- - "~>"
|
108
154
|
- !ruby/object:Gem::Version
|
109
|
-
version:
|
155
|
+
version: 2.6.6
|
110
156
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
111
157
|
requirements:
|
112
158
|
- - ">="
|
@@ -116,5 +162,5 @@ requirements: []
|
|
116
162
|
rubygems_version: 3.0.3
|
117
163
|
signing_key:
|
118
164
|
specification_version: 4
|
119
|
-
summary: Clojure
|
165
|
+
summary: Clojure interpreter and runtime.
|
120
166
|
test_files: []
|