preval 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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