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