kalc 0.6.0 → 0.7.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.
- data/Gemfile.lock +9 -9
- data/README.md +112 -0
- data/kalc.gemspec +1 -1
- data/lib/kalc/grammar.rb +4 -0
- data/lib/kalc/interpreter.rb +23 -1
- data/lib/kalc/version.rb +1 -1
- data/spec/interpreter_spec.rb +5 -0
- metadata +5 -5
- data/README.textile +0 -118
data/Gemfile.lock
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
kalc (0.
|
5
|
-
parslet (~> 1.
|
4
|
+
kalc (0.7.0)
|
5
|
+
parslet (~> 1.4)
|
6
6
|
|
7
7
|
GEM
|
8
8
|
remote: http://rubygems.org/
|
@@ -12,14 +12,14 @@ GEM
|
|
12
12
|
parslet (1.4.0)
|
13
13
|
blankslate (~> 2.0)
|
14
14
|
rake (0.9.2.2)
|
15
|
-
rspec (2.
|
16
|
-
rspec-core (~> 2.
|
17
|
-
rspec-expectations (~> 2.
|
18
|
-
rspec-mocks (~> 2.
|
19
|
-
rspec-core (2.
|
20
|
-
rspec-expectations (2.
|
15
|
+
rspec (2.11.0)
|
16
|
+
rspec-core (~> 2.11.0)
|
17
|
+
rspec-expectations (~> 2.11.0)
|
18
|
+
rspec-mocks (~> 2.11.0)
|
19
|
+
rspec-core (2.11.1)
|
20
|
+
rspec-expectations (2.11.2)
|
21
21
|
diff-lcs (~> 1.1.3)
|
22
|
-
rspec-mocks (2.
|
22
|
+
rspec-mocks (2.11.2)
|
23
23
|
|
24
24
|
PLATFORMS
|
25
25
|
ruby
|
data/README.md
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
kalc
|
2
|
+
====
|
3
|
+
|
4
|
+
kalc is a small functional programming language that (gasp) borrows a lot of its
|
5
|
+
syntax from the Excel formula language.
|
6
|
+
|
7
|
+
ikalc
|
8
|
+
-----
|
9
|
+
|
10
|
+
kalc comes with its own repl, known as `ikalc`. Start it up in your console by
|
11
|
+
typing in `ikalc`
|
12
|
+
|
13
|
+
Syntax
|
14
|
+
------
|
15
|
+
|
16
|
+
kalc is a tiny language, and it has very little syntax. It does support
|
17
|
+
functions, variable assignment, and arithmetic.
|
18
|
+
|
19
|
+
Numbers
|
20
|
+
-------
|
21
|
+
|
22
|
+
All numbers are floating point.
|
23
|
+
|
24
|
+
1 =\> 1.0 2.020 =\> 2.02 1.23E =\> 12300000000.0
|
25
|
+
|
26
|
+
Arithmetic
|
27
|
+
----------
|
28
|
+
|
29
|
+
1 + 1 / (10 \* 100) - 3 + 3 - (3 - 2) 1 \> 1 SUM(1, 2, 3, 4, 5)
|
30
|
+
|
31
|
+
Arithmetic is standard infix with nesting via parenthesis.
|
32
|
+
|
33
|
+
Logical operations
|
34
|
+
------------------
|
35
|
+
|
36
|
+
1 \> 2 ? 1 : 3 # Ternary (1 || 2) \> 3 1 \> 2 or 3 <2 # false OR(1 > 2, 3 \<
|
37
|
+
2, 8 == 8) # true
|
38
|
+
|
39
|
+
Variable assignment
|
40
|
+
-------------------
|
41
|
+
|
42
|
+
a := 1 b := 2 d := a + b
|
43
|
+
|
44
|
+
Functions
|
45
|
+
---------
|
46
|
+
|
47
|
+
You can create functions in kalc:
|
48
|
+
|
49
|
+
DEFINE FOO(a, b) { a + b }
|
50
|
+
|
51
|
+
You can also call functions in kalc:
|
52
|
+
|
53
|
+
\> a = FOO(2, 3) \> a 5
|
54
|
+
|
55
|
+
There are a few examples of functions in `lib/stdlib.kalc`
|
56
|
+
|
57
|
+
Built-in functions
|
58
|
+
------------------
|
59
|
+
|
60
|
+
There are some built-in functions (in `lib/kalc/interpreter.rb`). They are based
|
61
|
+
on the Excel formula functions, so you should see some overlap.
|
62
|
+
|
63
|
+
Some of them are:
|
64
|
+
|
65
|
+
IF, OR, NOT, AND, RAND, SYSTEM, ISLOGICAL, ISNONTEXT, ISNUMBER, ISTEXT, ABS,
|
66
|
+
DEGREES, PRODUCT, RADIANS, ROUND, SUM, TRUNC, LN, ACOS, ACOSH, ASIN, ASINH,
|
67
|
+
ATAN, ATANH, CBRT, COS, COSH, ERF, ERFC, EXP, GAMMA, LGAMMA, LOG, LOG2,
|
68
|
+
LOG10, SIN, SINH, SQRT, TAN, TANH, UPPER, LOWER, CHOMP, CHOP, CHR, CLEAR,
|
69
|
+
COUNT, DOWNCASE, HEX, INSPECT, INTERN, TO_SYM, LENGTH, SIZE, LSTRIP, SUCC,
|
70
|
+
NEXT, OCT, ORD, REVERSE, RSTRIP, STRIP, SWAPCASE, TO_C, TO_F, TO_I, TO_R,
|
71
|
+
UPCASE, P, PP, PUTS, PLUS_ONE, MINUS_ONE, SQUARE, CUBE, FIB, FACTORIAL,
|
72
|
+
TOWERS_OF_HANOI
|
73
|
+
|
74
|
+
Loops
|
75
|
+
-----
|
76
|
+
|
77
|
+
There are no looping mechanisms to speak of, but recursion works (pretty) well.
|
78
|
+
**Note:** *go too deep and you might blow the stack!*
|
79
|
+
|
80
|
+
DEFINE SAMPLE_LOOP(a) { PUTS(a) IF(a == 1, 1, SAMPLE_LOOP(a - 1)) }
|
81
|
+
|
82
|
+
There are a few examples of loops via recursion in `lib/stdlib.kalc`
|
83
|
+
|
84
|
+
Weirdness
|
85
|
+
---------
|
86
|
+
|
87
|
+
And here is where it gets a bit weird. It has to look a bit like Excel, so you
|
88
|
+
can expect things to look odd in places.
|
89
|
+
|
90
|
+
For example, here is how you compare 2 variables:
|
91
|
+
|
92
|
+
# Assign '1' to 'a' and '2' to 'b' a := 1 b := 2
|
93
|
+
|
94
|
+
# Does 'a' equal 'b'? a = b \> false
|
95
|
+
|
96
|
+
# Also, you can do this: a == b \> false
|
97
|
+
|
98
|
+
(a == a) && (b = b) \> true
|
99
|
+
|
100
|
+
'=' and '==' are both equality operators. Use ':=' for assignment.
|
101
|
+
|
102
|
+
More inside
|
103
|
+
-----------
|
104
|
+
|
105
|
+
Not everything is documented yet. As you can see, it is a mix of a lot of
|
106
|
+
different ideas. The goal is to have an excel-like language that is somewhat
|
107
|
+
functional.
|
108
|
+
|
109
|
+
Contributing
|
110
|
+
------------
|
111
|
+
|
112
|
+
Fork on GitHub and after you've committed tested patches, send a pull request.
|
data/kalc.gemspec
CHANGED
data/lib/kalc/grammar.rb
CHANGED
@@ -113,7 +113,11 @@ class Kalc::Grammar < Parslet::Parser
|
|
113
113
|
match('[eE]') >> match('[-+]').maybe >> digits
|
114
114
|
}
|
115
115
|
|
116
|
+
# We are using a really broad definition of what a number is.
|
117
|
+
# Numbers can be 1, 1.0, 0.1, 1.0e4, +1.0E10, etc
|
116
118
|
rule(:number) {
|
119
|
+
(match('[+-]').maybe >>
|
120
|
+
(str('.') >> digits >> exponent.maybe).as(:number) >> spaces?) |
|
117
121
|
(match('[+-]').maybe >>
|
118
122
|
digits >> (str('.') >> digits).maybe >> exponent.maybe).as(:number) >> spaces?
|
119
123
|
}
|
data/lib/kalc/interpreter.rb
CHANGED
@@ -103,7 +103,8 @@ module Kalc
|
|
103
103
|
[ 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atanh',
|
104
104
|
'cbrt', 'cos', 'cosh',
|
105
105
|
'erf', 'erfc', 'exp',
|
106
|
-
'
|
106
|
+
'gamma',
|
107
|
+
'lgamma', 'log', 'log2', 'log10',
|
107
108
|
'sin', 'sinh', 'sqrt',
|
108
109
|
'tan', 'tanh',
|
109
110
|
]
|
@@ -123,6 +124,27 @@ module Kalc
|
|
123
124
|
val.eval(cxt).downcase
|
124
125
|
})
|
125
126
|
|
127
|
+
# Strings
|
128
|
+
string_funs =
|
129
|
+
[
|
130
|
+
'chomp', 'chop', 'chr', 'clear', 'count',
|
131
|
+
'downcase',
|
132
|
+
'hex',
|
133
|
+
'inspect', 'intern', 'to_sym',
|
134
|
+
'length', 'size', 'lstrip',
|
135
|
+
'succ', 'next',
|
136
|
+
'oct', 'ord',
|
137
|
+
'reverse', 'rstrip',
|
138
|
+
'strip', 'swapcase', 'to_c', 'to_f', 'to_i', 'to_r',
|
139
|
+
'upcase'
|
140
|
+
]
|
141
|
+
|
142
|
+
string_funs.each do |str_fun|
|
143
|
+
env.add_function(str_fun.upcase.to_sym, lambda { |cxt, val|
|
144
|
+
String.new(val.eval(cxt)).send(str_fun.to_sym)
|
145
|
+
})
|
146
|
+
end
|
147
|
+
|
126
148
|
# Debug
|
127
149
|
env.add_function(:P, lambda { |cxt, *output|
|
128
150
|
p output
|
data/lib/kalc/version.rb
CHANGED
data/spec/interpreter_spec.rb
CHANGED
@@ -78,6 +78,11 @@ describe Kalc::Interpreter do
|
|
78
78
|
it { evaluate("1.23e-10").should == 1.23e-10 }
|
79
79
|
end
|
80
80
|
|
81
|
+
context "Numbers starting with a decimal point" do
|
82
|
+
it { evaluate("0.4").should == 0.4 }
|
83
|
+
it { evaluate(".4").should == 0.4 }
|
84
|
+
end
|
85
|
+
|
81
86
|
private
|
82
87
|
def evaluate(expression)
|
83
88
|
g = @grammar.parse(expression)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kalc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-08-27 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -50,7 +50,7 @@ dependencies:
|
|
50
50
|
requirements:
|
51
51
|
- - ~>
|
52
52
|
- !ruby/object:Gem::Version
|
53
|
-
version: '1.
|
53
|
+
version: '1.4'
|
54
54
|
type: :runtime
|
55
55
|
prerelease: false
|
56
56
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -58,7 +58,7 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - ~>
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '1.
|
61
|
+
version: '1.4'
|
62
62
|
description: Calculation language slightly based on Excel's formula language.
|
63
63
|
email:
|
64
64
|
- mrcsparker@gmail.com
|
@@ -71,7 +71,7 @@ files:
|
|
71
71
|
- Gemfile
|
72
72
|
- Gemfile.lock
|
73
73
|
- LICENSE
|
74
|
-
- README.
|
74
|
+
- README.md
|
75
75
|
- bin/ikalc
|
76
76
|
- bin/kalc
|
77
77
|
- examples/add.kalc
|
data/README.textile
DELETED
@@ -1,118 +0,0 @@
|
|
1
|
-
h1. kalc
|
2
|
-
|
3
|
-
h2. Introduction
|
4
|
-
|
5
|
-
kalc is a small functional programming language that (gasp) borrows a lot of
|
6
|
-
its syntax from the Excel formula language.
|
7
|
-
|
8
|
-
h2. ikalc
|
9
|
-
|
10
|
-
kalc comes with its own repl, known as ikalc. It evaluates when you press return.
|
11
|
-
|
12
|
-
h2. Syntax
|
13
|
-
|
14
|
-
kalc is a tiny language, and it has very little syntax. It does support
|
15
|
-
functions, variable assignment, and arithmetic.
|
16
|
-
|
17
|
-
h3. Numbers
|
18
|
-
|
19
|
-
All numbers are floating point.
|
20
|
-
|
21
|
-
<pre>
|
22
|
-
1 => 1.0
|
23
|
-
2.020 => 2.02
|
24
|
-
1.23E => 12300000000.0
|
25
|
-
</pre>
|
26
|
-
|
27
|
-
h3. Arithmetic
|
28
|
-
|
29
|
-
<pre>
|
30
|
-
1 + 1 / (10 * 100) - 3 + 3 - (3 - 2)
|
31
|
-
1 > 1
|
32
|
-
SUM(1, 2, 3, 4, 5)
|
33
|
-
</pre>
|
34
|
-
|
35
|
-
Arithmetic is standard infix with nesting via parenthesis.
|
36
|
-
|
37
|
-
h3. Logical operations
|
38
|
-
|
39
|
-
<pre>
|
40
|
-
1 > 2 ? 1 : 3 # Ternary
|
41
|
-
(1 || 2) > 3
|
42
|
-
1 > 2 or 3 < 2 # false
|
43
|
-
OR(1 > 2, 3 < 2, 8 == 8) # true
|
44
|
-
</pre>
|
45
|
-
|
46
|
-
h3. Variable assignment
|
47
|
-
|
48
|
-
<pre>
|
49
|
-
a := 1
|
50
|
-
b := 2
|
51
|
-
d := a + b
|
52
|
-
</pre>
|
53
|
-
|
54
|
-
h3. Creating functions
|
55
|
-
|
56
|
-
<pre>
|
57
|
-
DEFINE FOO(a, b) {
|
58
|
-
a + b
|
59
|
-
}
|
60
|
-
</pre>
|
61
|
-
|
62
|
-
There are a few examples of functions in lib/stdlib.kalc
|
63
|
-
|
64
|
-
h3. Loops
|
65
|
-
|
66
|
-
There are no looping mechanisms to speak of, but recursion works well.
|
67
|
-
|
68
|
-
<pre>
|
69
|
-
DEFINE SAMPLE_LOOP(a) {
|
70
|
-
PUTS(a)
|
71
|
-
IF(a == 1, 1, SAMPLE_LOOP(a - 1))
|
72
|
-
}
|
73
|
-
</pre>
|
74
|
-
|
75
|
-
h3. Weirdness
|
76
|
-
|
77
|
-
And here is where it gets a bit weird. It has to look a bit like
|
78
|
-
Excel, so you can expect things to look odd in places.
|
79
|
-
|
80
|
-
For example, here is how you compare 2 variables:
|
81
|
-
|
82
|
-
<pre>
|
83
|
-
# Assign '1' to 'a' and '2' to 'b'
|
84
|
-
|
85
|
-
a := 1
|
86
|
-
b := 2
|
87
|
-
|
88
|
-
# Does 'a' equal 'b'?
|
89
|
-
|
90
|
-
a = b
|
91
|
-
|
92
|
-
> false
|
93
|
-
|
94
|
-
# Also, you can do this:
|
95
|
-
|
96
|
-
a == b
|
97
|
-
|
98
|
-
> false
|
99
|
-
|
100
|
-
(a == a) && (b = b)
|
101
|
-
|
102
|
-
> true
|
103
|
-
|
104
|
-
</pre>
|
105
|
-
|
106
|
-
'=' and '==' are both equality operators. Use
|
107
|
-
':=' for assignment.
|
108
|
-
|
109
|
-
h4. More inside
|
110
|
-
|
111
|
-
Not everything is documented yet. As you can see, it is a mix of
|
112
|
-
a lot of different ideas. The goal is to have an excel-like language
|
113
|
-
that is somewhat functional.
|
114
|
-
|
115
|
-
h2. Contributing
|
116
|
-
|
117
|
-
Fork on GitHub and after you've committed tested patches, send a pull request.
|
118
|
-
|