preval 0.1.0 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6b1ef70f4fe7a2d5280f11a2466a8543d95fd55a82a7c148b3e9eee720b3ec03
4
- data.tar.gz: 8756a3c7ed21d3b9765925f3888b72349bb215a60230c249e86c87fe3efdeae1
3
+ metadata.gz: 8e6a0c329c5ed18bfae8f21d08c13d96a2abb5c258d4233795c75c1e40019c3a
4
+ data.tar.gz: ea764b40b8983db9e8398a86df971c03d47be73bf3c31ec043293e3f8323cf93
5
5
  SHA512:
6
- metadata.gz: 7c60862886c355c7aa6412947e0d0fc7530fe74d8e506ffcbdd9d62a50e80b6a48d586dd777968adaeeadba49fc6ab01cb4cccbc358aa0530d56e51fb2bb68b0
7
- data.tar.gz: 41bc24f5cf74cf2f06704cf2519ab46753c54a63be181190dca2eaafa33d425caa0b6ed8709ba39ed8b26723aadeb366c69b6896c06e51d3c190c01970c20df2
6
+ metadata.gz: 14f7fd99735026b877061a53db6c13b795e4ea0a98e9ae3f0bfbd52ccabec28e712027323074c1b564f0c561c1f2af726e550e5415ad9014bfb5e9c42f63deb9
7
+ data.tar.gz: 1551ab23dfb06db810a3522727db2ae1915084f00c560072fafbb8033d921a113c78d51edaead97ad19eff82320ee883b81d43b0d870a5e4305949c269402050
@@ -0,0 +1,19 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
6
+
7
+ ## [Unreleased]
8
+
9
+ ## [0.2.0] - 2019-04-18
10
+ ### Added
11
+ - Hook into the `bootsnap` gem if it's loaded.
12
+
13
+ ## [0.1.0] - 2019-03-08
14
+ ### Added
15
+ - Initial release. 🎉
16
+
17
+ [Unreleased]: https://github.com/kddeisz/preval/compare/v0.2.0...HEAD
18
+ [0.2.0]: https://github.com/kddeisz/preval/compare/v0.1.0...v0.2.0
19
+ [0.1.0]: https://github.com/kddeisz/preval/compare/49c899...v0.1.0
data/Gemfile CHANGED
@@ -2,4 +2,5 @@ source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
4
 
5
+ gem 'bootsnap'
5
6
  gem 'sinatra'
@@ -1,12 +1,15 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- preval (0.1.0)
4
+ preval (0.2.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
+ bootsnap (1.4.3)
10
+ msgpack (~> 1.0)
9
11
  minitest (5.11.3)
12
+ msgpack (1.2.10)
10
13
  mustermann (1.0.3)
11
14
  rack (2.0.6)
12
15
  rack-protection (2.0.5)
@@ -23,6 +26,7 @@ PLATFORMS
23
26
  ruby
24
27
 
25
28
  DEPENDENCIES
29
+ bootsnap
26
30
  bundler (~> 2.0)
27
31
  minitest (~> 5.11)
28
32
  preval!
data/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  Certain optimizations that are common in compilers are not immediately possible with Ruby on account of Ruby's flexibility. For example, most compilers will run through a process called [constant folding](https://en.wikipedia.org/wiki/Constant_folding) to eliminate the need to perform extraneous operations at runtime (e.g., `5 + 2` in the source can be replaced with `7`). However, because Ruby allows you to override the `Integer#+` method, it's possible that `5 + 2` would not evaluate to `7`. `preval` assumes that most developers will not override the `Integer#+` method, and performs optimizations under that assumption.
6
6
 
7
- Users must opt in to each of `preval`'s optimizations, as there's no real way of telling whether or not it is 100% safe for any codebase. The more optimizations are allowed to run, the most time and memory savings later. Users can also define their own optimizations by subclassing the `Preval::Visitor` class and using the existing `Preval::Node` APIs to replace and update the Ruby AST as necessary.
7
+ Users must opt in to each of `preval`'s optimizations, as there's no real way of telling whether or not it is 100% safe for any codebase. The more optimizations are allowed to run, the more time and memory savings later. Users can also define their own optimizations by subclassing the `Preval::Visitor` class and using the existing `Preval::Node` APIs to replace and update the Ruby AST as necessary.
8
8
 
9
9
  ## Installation
10
10
 
@@ -24,9 +24,9 @@ Or install it yourself as:
24
24
 
25
25
  ## Usage
26
26
 
27
- At the moment, this gem is a POC and should not be used in production. If you want to experiment with it, you can use the `bootsnap` gem to hook into the compilation process and run `Preval.process` over the source as it comes through. This will eventually be automated.
27
+ If you're using the `bootsnap` gem, `preval` will automatically hook into its compilation step. Otherwise, you'll need to manually call `Preval.process(source)` with your own iseq loader (you can check out [yomikomu](https://github.com/ko1/yomikomu) for an example).
28
28
 
29
- Each optimization is generally named for the function it performs, and can be enabled through the `enable!` method on the visitor class.
29
+ Each optimization is generally named for the function it performs, and can be enabled through the `enable!` method on the visitor class. If you do not explicitly call `enable!` on any optimizations, nothing will change with your source.
30
30
 
31
31
  * `Preval::Visitors::Arithmetic`
32
32
  * replaces constant expressions with their evaluation (e.g., `5 + 2` becomes `7`)
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'preval'
5
+
6
+ Preval::Visitors::Arithmetic.enable!
7
+ Preval::Visitors::Loops.enable!
8
+
9
+ source = ARGV.first
10
+ puts Preval.process(File.exist?(source) ? File.read(source) : source)
@@ -23,3 +23,20 @@ require 'preval/version'
23
23
  require 'preval/visitor'
24
24
  require 'preval/visitors/arithmetic'
25
25
  require 'preval/visitors/loops'
26
+
27
+ if defined?(Bootsnap)
28
+ load_iseq = RubyVM::InstructionSequence.method(:load_iseq)
29
+
30
+ if load_iseq.source_location[0].include?('/bootsnap/')
31
+ Bootsnap::CompileCache::ISeq.singleton_class.prepend(
32
+ Module.new do
33
+ def input_to_storage(source, path)
34
+ source = Preval.process(source)
35
+ RubyVM::InstructionSequence.compile(source, path, path).to_binary
36
+ rescue SyntaxError
37
+ raise Bootsnap::CompileCache::Uncompilable, 'syntax error'
38
+ end
39
+ end
40
+ )
41
+ end
42
+ end
@@ -60,7 +60,7 @@ module Preval
60
60
  to(:do_block) { " do#{body[0] ? " #{source(0)}" : ''}\n#{source(1)}\nend" }
61
61
  to(:dot2) { join('..') }
62
62
  to(:dot3) { join('...') }
63
- to(:dyna_symbol) { ":\"#{source(0)}\"" }
63
+ to(:dyna_symbol) { starts_with?(:xstring_add) ? ":\"#{source(0)}\"" : ":\"#{source(0).join}\"" }
64
64
  to(:END) { "END {\n#{source(0)}\n}"}
65
65
  to(:else) { "else\n#{source(0)}" }
66
66
  to(:elsif) { "elsif #{source(0)}\n#{source(1)}#{body[2] ? "\n#{source(2)}" : ''}" }
@@ -1,3 +1,3 @@
1
1
  module Preval
2
- VERSION = '0.1.0'
2
+ VERSION = '0.2.0'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: preval
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kevin Deisz
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-03-08 00:00:00.000000000 Z
11
+ date: 2019-04-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -61,12 +61,14 @@ extra_rdoc_files: []
61
61
  files:
62
62
  - ".gitignore"
63
63
  - ".travis.yml"
64
+ - CHANGELOG.md
64
65
  - Gemfile
65
66
  - Gemfile.lock
66
67
  - LICENSE
67
68
  - README.md
68
69
  - Rakefile
69
70
  - bin/console
71
+ - bin/print
70
72
  - bin/setup
71
73
  - docs/index.html
72
74
  - docs/server.rb
@@ -98,7 +100,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
98
100
  - !ruby/object:Gem::Version
99
101
  version: '0'
100
102
  requirements: []
101
- rubygems_version: 3.0.2
103
+ rubygems_version: 3.0.3
102
104
  signing_key:
103
105
  specification_version: 4
104
106
  summary: Automatically optimizes your Ruby code