parsecs 0.2.14
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 +7 -0
- data/ext/libnativemath/extconf.rb +61 -0
- data/lib/parsec.rb +41 -0
- data/lib/string_to_boolean_refinements.rb +10 -0
- data/test/test_parsec.rb +86 -0
- metadata +85 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 61b24503f941948f023ee022527c79b418cfe3186dcd769d2a38ab0df630ff37
|
4
|
+
data.tar.gz: 2d7ad237ace66c7b8322b4c39c1e122a073a6a27f04ee55e7a0ccf02da62eef5
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 574e305a618c0507f41c44fb79981bb16842e46ddedbaa053119c7fcadd45555c8f157008324a451e3d66a69ce8e09a8b40efa3783b808266f7b116b2323b037
|
7
|
+
data.tar.gz: 9ba3a929a6bfbd8e62434f08226df0eee34c36b1f2386f5f44f4b33f5e25333d689f3b7f43eb1e839a5a2f6060844b158befbcc56faa0f1dae9eb6ccde05ab71
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# ext/extconf.rb
|
2
|
+
require 'mkmf'
|
3
|
+
|
4
|
+
# During gem install step, the path is different
|
5
|
+
BASEDIR = if File.exist?('parsec.gemspec')
|
6
|
+
'.'
|
7
|
+
else
|
8
|
+
'../..'
|
9
|
+
end
|
10
|
+
|
11
|
+
LIBDIR = RbConfig::CONFIG['libdir']
|
12
|
+
INCLUDEDIR = RbConfig::CONFIG['includedir']
|
13
|
+
MUPARSER_HEADERS = "#{BASEDIR}/ext/equations-parser/parser".freeze
|
14
|
+
MUPARSER_LIB = "#{BASEDIR}/ext/equations-parser".freeze
|
15
|
+
|
16
|
+
HEADER_DIRS = [INCLUDEDIR, MUPARSER_HEADERS].freeze
|
17
|
+
|
18
|
+
puts HEADER_DIRS
|
19
|
+
puts LIBDIR
|
20
|
+
|
21
|
+
# setup constant that is equal to that of the file path that holds
|
22
|
+
# that static libraries that will need to be compiled against
|
23
|
+
LIB_DIRS = [LIBDIR, MUPARSER_LIB].freeze
|
24
|
+
|
25
|
+
# array of all libraries that the C extension should be compiled against
|
26
|
+
libs = ['-lmuparserx']
|
27
|
+
|
28
|
+
dir_config('libnativemath', HEADER_DIRS, LIB_DIRS)
|
29
|
+
|
30
|
+
abort 'swig is missing. Please install it.' unless find_executable('cmake')
|
31
|
+
|
32
|
+
abort 'swig is missing. Please install it.' unless find_executable('swig')
|
33
|
+
|
34
|
+
# iterate though the libs array, and append them
|
35
|
+
# to the $LOCAL_LIBS array used for the makefile creation
|
36
|
+
libs.each do |lib|
|
37
|
+
$LOCAL_LIBS << "#{lib} "
|
38
|
+
end
|
39
|
+
|
40
|
+
Dir.chdir(BASEDIR) do
|
41
|
+
system('git submodule update --init --recursive')
|
42
|
+
|
43
|
+
Dir.chdir('ext/equations-parser/') do
|
44
|
+
system('cmake CMakeLists.txt -DCMAKE_BUILD_TYPE=Release')
|
45
|
+
system('make')
|
46
|
+
end
|
47
|
+
|
48
|
+
Dir.chdir('ext/libnativemath/') do
|
49
|
+
system('swig -c++ -ruby libnativemath.i')
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
unless File.exist?("#{MUPARSER_HEADERS}/mpParser.h")
|
54
|
+
abort 'mpParser.h header is missing.'
|
55
|
+
end
|
56
|
+
|
57
|
+
unless File.exist?("#{MUPARSER_LIB}/libmuparserx.a")
|
58
|
+
abort 'libmuparserx.a is missing.'
|
59
|
+
end
|
60
|
+
|
61
|
+
create_makefile('ext/libnativemath/libnativemath')
|
data/lib/parsec.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'string_to_boolean_refinements'
|
2
|
+
require 'libnativemath'
|
3
|
+
|
4
|
+
module Parsec
|
5
|
+
# This is the main class responsible to evaluate the equations
|
6
|
+
class Parsec
|
7
|
+
using StringToBooleanRefinements
|
8
|
+
|
9
|
+
VERSION = '0.2.14'.freeze
|
10
|
+
|
11
|
+
def self.eval_equation(equation)
|
12
|
+
# This line removes all spaces that are not between quotation marks
|
13
|
+
# https://stackoverflow.com/questions/205521/using-regex-to-replace-all-spaces-not-in-quotes-in-ruby?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa
|
14
|
+
equation.gsub!(/( |(".*?"))/, '\\2')
|
15
|
+
|
16
|
+
convert(Libnativemath.native_eval(equation))
|
17
|
+
end
|
18
|
+
|
19
|
+
private_class_method
|
20
|
+
|
21
|
+
def self.convert(ans)
|
22
|
+
case ans['value']
|
23
|
+
when 'inf' then return 'Infinity'
|
24
|
+
when 'nan' then return ans['value']
|
25
|
+
end
|
26
|
+
|
27
|
+
case ans['type']
|
28
|
+
when 'int' then return ans['value'].to_i
|
29
|
+
when 'float' then return ans['value'].to_f
|
30
|
+
when 'boolean' then return ans['value'].to_bool
|
31
|
+
when 'string' then return verify_string(ans['value'])
|
32
|
+
when 'c' then return 'complex number'
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.verify_string(output)
|
37
|
+
raise ArgumentError, output.sub('Error: ', '') if output.include?('Error')
|
38
|
+
output.delete('\"')
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# This module add refinements to cast string to boolean
|
2
|
+
module StringToBooleanRefinements
|
3
|
+
refine String do
|
4
|
+
def to_bool
|
5
|
+
return true if self == true || self =~ /(true|t|yes|y|1|on)$/i
|
6
|
+
return false if self == false || nil? || strip.empty? || self =~ /(false|f|no|n|0|off)$/i
|
7
|
+
raise ArgumentError, "invalid value for Boolean: \"#{self}\""
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
data/test/test_parsec.rb
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'parsec'
|
3
|
+
|
4
|
+
# This class test all possible equations for this gem
|
5
|
+
class TestParsec < Minitest::Test
|
6
|
+
def test_defined
|
7
|
+
assert defined?(Parsec::Parsec)
|
8
|
+
assert defined?(Parsec::Parsec::VERSION)
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_simple_math_equations
|
12
|
+
parser = Parsec::Parsec
|
13
|
+
assert_equal(10, parser.eval_equation('(5 + 1) + (6 - 2)'))
|
14
|
+
assert_equal(16, parser.eval_equation('4 + 4 * 3'))
|
15
|
+
assert_equal(2, parser.eval_equation('10.5 / 5.25'))
|
16
|
+
assert_equal(5, parser.eval_equation('abs(-5)'))
|
17
|
+
assert_equal(1, parser.eval_equation('log10(10)'))
|
18
|
+
assert_equal(4, parser.eval_equation('round(4.4)'))
|
19
|
+
assert_equal(729, parser.eval_equation('(3^3)^2'))
|
20
|
+
assert_equal(196_83, parser.eval_equation('3^(3^(2))'))
|
21
|
+
assert_equal(362_880_0, parser.eval_equation('10!'))
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_complex_math_equations
|
25
|
+
parser = Parsec::Parsec
|
26
|
+
assert_equal(6, parser.eval_equation('sqrt(16) + cbrt(8)'))
|
27
|
+
assert_equal(4.30259, parser.eval_equation('log10(10) + ln(e) + log(10)'))
|
28
|
+
assert_equal(2.0, parser.eval_equation('sin(1) + cos(0) + tan(0.15722)'))
|
29
|
+
assert_equal(16, parser.eval_equation('max(1, 2) + min(3, 4) + sum(5, 6)'))
|
30
|
+
assert_equal(9.6, parser.eval_equation('avg(9, 9.8, 10)'))
|
31
|
+
assert_equal(8, parser.eval_equation('pow(2, 3)'))
|
32
|
+
assert_equal(4.56, parser.eval_equation('round_decimal(4.559, 2)'))
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_if_then_else_equations
|
36
|
+
parser = Parsec::Parsec
|
37
|
+
assert_equal('bigger', parser.eval_equation('4 > 2 ? "bigger" : "smaller"'))
|
38
|
+
assert_equal(true, parser.eval_equation('2 == 2 ? true : false'))
|
39
|
+
assert_equal(false, parser.eval_equation('2 != 2 ? true : false'))
|
40
|
+
assert_equal('yes', parser.eval_equation('"this" == "this" ? "yes" : "no"'))
|
41
|
+
assert_equal('yes', parser.eval_equation('"this" != "that" ? "yes" : "no"'))
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_logic_manipulation
|
45
|
+
parser = Parsec::Parsec
|
46
|
+
assert_equal(false, parser.eval_equation('true and false'))
|
47
|
+
assert_equal(true, parser.eval_equation('true or false'))
|
48
|
+
assert_equal(false, parser.eval_equation('(3==3) and (3!=3)'))
|
49
|
+
assert_equal(true, parser.eval_equation('exp(1) == e'))
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_simple_string_manipulation
|
53
|
+
parser = Parsec::Parsec
|
54
|
+
assert_equal(11, parser.eval_equation('length("test string")'))
|
55
|
+
assert_equal('TEST STRING', parser.eval_equation('toupper("test string")'))
|
56
|
+
assert_equal('test string', parser.eval_equation('tolower("TEST STRING")'))
|
57
|
+
assert_equal('Hello World', parser.eval_equation('concat("Hello ", "World")'))
|
58
|
+
assert_equal(5, parser.eval_equation('str2number("5")'))
|
59
|
+
assert_equal('Hello', parser.eval_equation('left("Hello World", 5)'))
|
60
|
+
assert_equal('World', parser.eval_equation('right("Hello World", 5)'))
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_complex_string_manipulation
|
64
|
+
parser = Parsec::Parsec
|
65
|
+
assert_equal('HELLO WORLD', parser.eval_equation('toupper(concat("hello ", "world"))'))
|
66
|
+
assert_equal('test lowercase', parser.eval_equation('tolower("TEST LOWERCASE")'))
|
67
|
+
assert_equal('Hello', parser.eval_equation('left("Hello World", 5)'))
|
68
|
+
assert_equal('World', parser.eval_equation('right("Hello World", 5)'))
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_general_equations
|
72
|
+
parsec = Parsec::Parsec
|
73
|
+
assert_equal(1, parsec.eval_equation('((0.09/1.0)+2.58)-1.67'))
|
74
|
+
assert_equal(40.6853, parsec.eval_equation('10^log(3+2)'))
|
75
|
+
assert_equal(1, parsec.eval_equation('log(e)'))
|
76
|
+
assert_equal(2, parsec.eval_equation('2^5^0'))
|
77
|
+
assert_equal('yes', parsec.eval_equation('5 > 3 ? "yes" : "no"'))
|
78
|
+
assert_equal(1, parsec.eval_equation('"this" == "this" ? 1 : 0'))
|
79
|
+
assert_equal(9.9812, parsec.eval_equation('sqrt(9)+cbrt(8)+abs(-4.9812)'))
|
80
|
+
assert_equal(3_628_680, parsec.send(:eval_equation, '10! - 5! * -(-1)'))
|
81
|
+
assert_equal(true, parsec.eval_equation('sum(1,2,3,4,5) == max(14.99, 15)'))
|
82
|
+
assert_equal(0.55, parsec.eval_equation('avg(1,2,3,4,5,6,7,8,9,10) / 10'))
|
83
|
+
assert_equal(5, parsec.eval_equation('round(4.62)'))
|
84
|
+
assert_equal(4.63, parsec.eval_equation('round_decimal(4.625, 2)'))
|
85
|
+
end
|
86
|
+
end
|
metadata
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: parsecs
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.14
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Nilton Vasques
|
8
|
+
- Victor Cordeiro
|
9
|
+
- Beatriz Fagundes
|
10
|
+
autorequire:
|
11
|
+
bindir: bin
|
12
|
+
cert_chain: []
|
13
|
+
date: 2018-05-23 00:00:00.000000000 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: minitest
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
18
|
+
requirements:
|
19
|
+
- - "~>"
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '5.10'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
requirements:
|
26
|
+
- - "~>"
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
version: '5.10'
|
29
|
+
- !ruby/object:Gem::Dependency
|
30
|
+
name: rake
|
31
|
+
requirement: !ruby/object:Gem::Requirement
|
32
|
+
requirements:
|
33
|
+
- - "~>"
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: '12.1'
|
36
|
+
type: :development
|
37
|
+
prerelease: false
|
38
|
+
version_requirements: !ruby/object:Gem::Requirement
|
39
|
+
requirements:
|
40
|
+
- - "~>"
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: '12.1'
|
43
|
+
description: Parsecs
|
44
|
+
email:
|
45
|
+
- nilton.vasques@gmail.com
|
46
|
+
- victorcorcos@gmail.com
|
47
|
+
- beatrizsfslima@gmail.com
|
48
|
+
executables: []
|
49
|
+
extensions:
|
50
|
+
- ext/libnativemath/extconf.rb
|
51
|
+
extra_rdoc_files: []
|
52
|
+
files:
|
53
|
+
- ext/libnativemath/extconf.rb
|
54
|
+
- lib/parsec.rb
|
55
|
+
- lib/string_to_boolean_refinements.rb
|
56
|
+
- test/test_parsec.rb
|
57
|
+
homepage: https://github.com/niltonvasques/parsec
|
58
|
+
licenses:
|
59
|
+
- mit
|
60
|
+
metadata: {}
|
61
|
+
post_install_message:
|
62
|
+
rdoc_options: []
|
63
|
+
require_paths:
|
64
|
+
- lib
|
65
|
+
- ext/libnativemath
|
66
|
+
- "."
|
67
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
68
|
+
requirements:
|
69
|
+
- - ">="
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: '0'
|
72
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
requirements: []
|
78
|
+
rubyforge_project:
|
79
|
+
rubygems_version: 2.7.6
|
80
|
+
signing_key:
|
81
|
+
specification_version: 4
|
82
|
+
summary: A gem to evaluate math equations using a lighter and faster version of the
|
83
|
+
muparserx C++ library
|
84
|
+
test_files:
|
85
|
+
- test/test_parsec.rb
|