calc_jbusta16 0.2.0 → 0.2.5
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 +4 -4
- data/bin/calcex +64 -0
- data/lib/ast.rb +72 -8
- data/lib/calculator.rb +50 -0
- data/lib/parser.rb +46 -12
- data/lib/scanner.rb +9 -1
- metadata +5 -5
- data/bin/calc +0 -22
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2183149fb606227443cab2502cbb9d415b8add50
|
4
|
+
data.tar.gz: 2ba14b5a251ce3fcf377276374a24f6f817bada1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 090a08af6f50a975ee18b24d1a72194c603fae2b7b2da512f46e4b5993660297879e0c507c18d638c4a0a61744d3f8b4f50473dc6b749a910e54e288edbd33d4
|
7
|
+
data.tar.gz: 103f94ba16eaa4391c75b94c7d9bc92bf577142bf682b79de9849a05d637e9d02f252b48cc15324a0ec5606df1f2bafabb8d4ad92b017fe8f6a29e31af5befec
|
data/bin/calcex
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'calculator'
|
5
|
+
require 'calcex'
|
6
|
+
|
7
|
+
$calc = Calculator.new()
|
8
|
+
|
9
|
+
def makeInteractiveCalc
|
10
|
+
$stdout.print "> "
|
11
|
+
$stdout.flush
|
12
|
+
text = gets
|
13
|
+
makeCalc(text)
|
14
|
+
makeInteractiveCalc()
|
15
|
+
end
|
16
|
+
|
17
|
+
def makeCalc(text)
|
18
|
+
puts "=> " + $calc.eval(text).to_s + $calc.printVar()
|
19
|
+
end
|
20
|
+
|
21
|
+
def setEnvVars
|
22
|
+
$calc.changeSetEnvVars()
|
23
|
+
ENV.each do |key, value|
|
24
|
+
if key.start_with?("CALCVAR") == true then
|
25
|
+
var = key.slice(7, key.size)
|
26
|
+
text = var + "=" + value + "\n"
|
27
|
+
puts text
|
28
|
+
makeCalc(text)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
$calc.changeSetEnvVars()
|
32
|
+
end
|
33
|
+
|
34
|
+
def main
|
35
|
+
args = ARGF.argv
|
36
|
+
setEnvVars()
|
37
|
+
i = 0
|
38
|
+
while i < args.size do
|
39
|
+
optionArg = args[i]
|
40
|
+
puts "args[#{i}]: #{args[i]}"
|
41
|
+
if optionArg == "-e" then
|
42
|
+
$calc.envConf()
|
43
|
+
elsif (optionArg == "-v") then
|
44
|
+
text = args[i+1] + "\n"
|
45
|
+
$calc.eval(text)
|
46
|
+
i += 1
|
47
|
+
else
|
48
|
+
lines = ARGF.readlines
|
49
|
+
lines.each do |line| makeCalc(line) end
|
50
|
+
end
|
51
|
+
i += 1
|
52
|
+
end
|
53
|
+
makeInteractiveCalc()
|
54
|
+
end
|
55
|
+
|
56
|
+
begin
|
57
|
+
main()
|
58
|
+
rescue ParseError
|
59
|
+
puts "* Parse Error"
|
60
|
+
rescue UnrecognizedTokenException
|
61
|
+
puts "* UnrecognizedTokenException"
|
62
|
+
rescue
|
63
|
+
puts "* Unkown exception"
|
64
|
+
end
|
data/lib/ast.rb
CHANGED
@@ -22,7 +22,7 @@ class AddNode < BinaryNode
|
|
22
22
|
super(left,right)
|
23
23
|
end
|
24
24
|
|
25
|
-
def evaluate
|
25
|
+
def evaluate
|
26
26
|
return @left.evaluate() + @right.evaluate()
|
27
27
|
end
|
28
28
|
end
|
@@ -32,7 +32,7 @@ class SubNode < BinaryNode
|
|
32
32
|
super(left,right)
|
33
33
|
end
|
34
34
|
|
35
|
-
def evaluate
|
35
|
+
def evaluate
|
36
36
|
return @left.evaluate() - @right.evaluate()
|
37
37
|
end
|
38
38
|
end
|
@@ -42,7 +42,7 @@ class TimesNode < BinaryNode
|
|
42
42
|
super(left, right)
|
43
43
|
end
|
44
44
|
|
45
|
-
def evaluate
|
45
|
+
def evaluate
|
46
46
|
left.evaluate * right.evaluate
|
47
47
|
end
|
48
48
|
end
|
@@ -52,33 +52,97 @@ class DivideNode < BinaryNode
|
|
52
52
|
super(left, right)
|
53
53
|
end
|
54
54
|
|
55
|
-
def evaluate
|
55
|
+
def evaluate
|
56
56
|
left.evaluate / right.evaluate
|
57
57
|
end
|
58
58
|
end
|
59
59
|
|
60
|
+
class ModNode < BinaryNode
|
61
|
+
def initialize(left, right)
|
62
|
+
super(left, right)
|
63
|
+
end
|
64
|
+
|
65
|
+
def evaluate
|
66
|
+
left.evaluate % right.evaluate
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
60
70
|
class StoreNode < UnaryNode
|
61
71
|
def initialize(sub)
|
62
72
|
super(sub)
|
63
73
|
end
|
64
74
|
|
65
|
-
def evaluate
|
75
|
+
def evaluate
|
66
76
|
$calc.memory = subTree.evaluate
|
67
77
|
end
|
68
78
|
end
|
69
79
|
|
70
80
|
class RecallNode
|
71
|
-
def evaluate
|
81
|
+
def evaluate
|
72
82
|
$calc.memory
|
73
83
|
end
|
74
84
|
end
|
75
85
|
|
76
|
-
class NumNode
|
86
|
+
class NumNode
|
77
87
|
def initialize(num)
|
78
88
|
@num = num
|
79
89
|
end
|
80
90
|
|
81
|
-
def evaluate
|
91
|
+
def evaluate
|
82
92
|
return @num
|
83
93
|
end
|
84
94
|
end
|
95
|
+
|
96
|
+
class PlusNode < UnaryNode
|
97
|
+
def initialize(sub)
|
98
|
+
super(sub)
|
99
|
+
end
|
100
|
+
|
101
|
+
def evaluate
|
102
|
+
valc = $calc.memory + subTree.evaluate
|
103
|
+
$calc.memory = valc
|
104
|
+
return valc
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
class MinusNode < UnaryNode
|
109
|
+
def initialize(sub)
|
110
|
+
super(sub)
|
111
|
+
end
|
112
|
+
|
113
|
+
def evaluate
|
114
|
+
valc = $calc.memory - subTree.evaluate
|
115
|
+
$calc.memory = valc
|
116
|
+
return valc
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
class ClearNode
|
121
|
+
def evaluate
|
122
|
+
valc = 0
|
123
|
+
$calc.memory = valc
|
124
|
+
return valc
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
class SetNode < UnaryNode
|
129
|
+
def initialize(sub, key)
|
130
|
+
super(sub)
|
131
|
+
@key = key
|
132
|
+
end
|
133
|
+
|
134
|
+
def evaluate
|
135
|
+
val = subTree.evaluate
|
136
|
+
$calc.set(@key, val)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
class GetNode
|
141
|
+
def initialize(key)
|
142
|
+
@key = key
|
143
|
+
end
|
144
|
+
|
145
|
+
def evaluate
|
146
|
+
return $calc.get(@key)
|
147
|
+
end
|
148
|
+
end
|
data/lib/calculator.rb
CHANGED
@@ -7,6 +7,12 @@ class Calculator
|
|
7
7
|
|
8
8
|
def initialize()
|
9
9
|
@memory = 0
|
10
|
+
@useEnvVars = false
|
11
|
+
@setEnvVars = false
|
12
|
+
@createVar = false
|
13
|
+
@lastCreateKey = ''
|
14
|
+
@varsEnv = Hash.new()
|
15
|
+
@vars = Hash.new()
|
10
16
|
end
|
11
17
|
|
12
18
|
def eval(expr)
|
@@ -14,4 +20,48 @@ class Calculator
|
|
14
20
|
ast = parser.parse()
|
15
21
|
return ast.evaluate()
|
16
22
|
end
|
23
|
+
|
24
|
+
def set(key, value)
|
25
|
+
if @setEnvVars == true then
|
26
|
+
@varsEnv.store(key, value)
|
27
|
+
else
|
28
|
+
@vars.store(key, value)
|
29
|
+
end
|
30
|
+
@createVar = true;
|
31
|
+
@lastCreateKey = key
|
32
|
+
end
|
33
|
+
|
34
|
+
def get(keyToGet)
|
35
|
+
if @useEnvVars == true && isEnvVar(key) == true then
|
36
|
+
@varsEnv.each {|key, val| if keyToGet == key then return val end }
|
37
|
+
else
|
38
|
+
@vars.each {|key, val| if keyToGet == key then return val end }
|
39
|
+
end
|
40
|
+
return 0
|
41
|
+
end
|
42
|
+
|
43
|
+
def isEnvVar(key)
|
44
|
+
if @varsEnv.has_key?(key) == true then
|
45
|
+
return true
|
46
|
+
else
|
47
|
+
return false
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def envConf
|
52
|
+
@useEnvVars = true
|
53
|
+
end
|
54
|
+
|
55
|
+
def changeSetEnvVars
|
56
|
+
if @setEnvVars == true then @setEnvVars = false else @setEnvVars = true end
|
57
|
+
end
|
58
|
+
|
59
|
+
def printVar
|
60
|
+
result = ''
|
61
|
+
if @createVar == true then
|
62
|
+
result = " [ #{@lastCreateKey} <- #{get(@lastCreateKey)} ]"
|
63
|
+
@createVar = false
|
64
|
+
end
|
65
|
+
return result
|
66
|
+
end
|
17
67
|
end
|
data/lib/parser.rb
CHANGED
@@ -16,7 +16,6 @@ class Parser
|
|
16
16
|
def Prog
|
17
17
|
result = Expr()
|
18
18
|
t = @scan.getToken
|
19
|
-
|
20
19
|
if t.type != :eof then
|
21
20
|
print "Expected EOF. Found ", t.type, ".\n"
|
22
21
|
raise ParseError.new
|
@@ -60,28 +59,43 @@ class Parser
|
|
60
59
|
return RestTerm(DivideNode.new(e,Storable()))
|
61
60
|
end
|
62
61
|
|
62
|
+
if t.type == :mod then
|
63
|
+
return RestTerm(ModNode.new(e,Storable()))
|
64
|
+
end
|
65
|
+
|
63
66
|
@scan.putBackToken
|
64
67
|
|
65
68
|
e
|
66
69
|
end
|
67
|
-
|
70
|
+
|
68
71
|
def Storable
|
69
|
-
|
70
|
-
|
72
|
+
MemOperation(Factor())
|
73
|
+
end
|
74
|
+
|
75
|
+
def MemOperation(e)
|
71
76
|
t = @scan.getToken
|
72
77
|
|
73
78
|
if t.type == :keyword
|
74
79
|
if t.lex == "S"
|
75
|
-
return StoreNode.new(
|
80
|
+
return StoreNode.new(e)
|
76
81
|
end
|
77
|
-
|
82
|
+
|
83
|
+
if t.lex == 'P'
|
84
|
+
return PlusNode.new(e)
|
85
|
+
end
|
86
|
+
|
87
|
+
if t.lex == 'M'
|
88
|
+
return MinusNode.new(e)
|
89
|
+
end
|
90
|
+
|
91
|
+
puts "We found an error on MemOperation #{t.lex}"
|
78
92
|
print " at line #{t.line} col: #{t.col}"
|
79
93
|
raise ParseError.new
|
80
94
|
end
|
81
95
|
|
82
96
|
@scan.putBackToken
|
83
97
|
|
84
|
-
|
98
|
+
e
|
85
99
|
end
|
86
100
|
|
87
101
|
def Factor
|
@@ -92,13 +106,17 @@ class Parser
|
|
92
106
|
end
|
93
107
|
|
94
108
|
if t.type == :keyword
|
95
|
-
if t.lex ==
|
109
|
+
if t.lex == 'R'
|
96
110
|
return RecallNode.new
|
97
111
|
end
|
112
|
+
|
113
|
+
if t.lex == 'C'
|
114
|
+
return ClearNode.new
|
115
|
+
end
|
98
116
|
puts "We found an error on Factor::keyword"
|
99
117
|
raise ParseError.new
|
100
118
|
end
|
101
|
-
|
119
|
+
|
102
120
|
if t.type == :lparen
|
103
121
|
result = Expr()
|
104
122
|
t = @scan.getToken
|
@@ -109,8 +127,24 @@ class Parser
|
|
109
127
|
print " at line #{t.line} col: #{t.col}"
|
110
128
|
raise ParseError.new
|
111
129
|
end
|
112
|
-
|
113
|
-
|
114
|
-
|
130
|
+
|
131
|
+
if t.type == :identifier
|
132
|
+
Assignable(t.lex)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def Assignable(key)
|
137
|
+
t = @scan.getToken
|
138
|
+
if t.type == :assign
|
139
|
+
return Assign(key)
|
140
|
+
end
|
141
|
+
|
142
|
+
@scan.putBackToken
|
143
|
+
|
144
|
+
return GetNode.new(key)
|
145
|
+
end
|
146
|
+
|
147
|
+
def Assign(key)
|
148
|
+
return SetNode.new(Expr(), key)
|
115
149
|
end
|
116
150
|
end
|
data/lib/scanner.rb
CHANGED
@@ -4,7 +4,7 @@ require 'calcex'
|
|
4
4
|
class Scanner
|
5
5
|
def initialize(inStream)
|
6
6
|
@istream = inStream
|
7
|
-
@keywords = Set.new(["S","R"])
|
7
|
+
@keywords = Set.new(["S","R","P","M","C"])
|
8
8
|
@lineCount = 1
|
9
9
|
@colCount = -1
|
10
10
|
@needToken = true
|
@@ -45,6 +45,8 @@ class Scanner
|
|
45
45
|
elsif c == ?/ then state = 6
|
46
46
|
elsif c == ?( then state = 7
|
47
47
|
elsif c == ?) then state = 8
|
48
|
+
elsif c == ?% then state = 9
|
49
|
+
elsif c == ?= then state = 10
|
48
50
|
elsif c == ?\n then
|
49
51
|
@colCount = -1
|
50
52
|
@lineCount = @lineCount+1
|
@@ -91,6 +93,12 @@ class Scanner
|
|
91
93
|
when 8
|
92
94
|
type = :rparen
|
93
95
|
foundOne = true
|
96
|
+
when 9
|
97
|
+
type = :mod
|
98
|
+
foundOne = true
|
99
|
+
when 10
|
100
|
+
type = :assign
|
101
|
+
foundOne = true
|
94
102
|
end
|
95
103
|
|
96
104
|
if !foundOne then
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: calc_jbusta16
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kent D. Lee - Juan Francisco Cardona Mc - Josue Daniel Bustamante
|
@@ -13,18 +13,18 @@ dependencies: []
|
|
13
13
|
description: An calculator implementation on ruby
|
14
14
|
email: j@coderise.org
|
15
15
|
executables:
|
16
|
-
-
|
16
|
+
- calcex
|
17
17
|
extensions: []
|
18
18
|
extra_rdoc_files: []
|
19
19
|
files:
|
20
|
-
- bin/
|
20
|
+
- bin/calcex
|
21
21
|
- lib/ast.rb
|
22
22
|
- lib/calcex.rb
|
23
23
|
- lib/calculator.rb
|
24
24
|
- lib/parser.rb
|
25
25
|
- lib/scanner.rb
|
26
26
|
- lib/token.rb
|
27
|
-
homepage: http://github.com/JosueDanielBust/
|
27
|
+
homepage: http://github.com/JosueDanielBust/rubycalc
|
28
28
|
licenses:
|
29
29
|
- ARTISTIC
|
30
30
|
metadata: {}
|
@@ -44,7 +44,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
44
44
|
version: '0'
|
45
45
|
requirements: []
|
46
46
|
rubyforge_project:
|
47
|
-
rubygems_version: 2.4.
|
47
|
+
rubygems_version: 2.4.8
|
48
48
|
signing_key:
|
49
49
|
specification_version: 4
|
50
50
|
summary: Another calculator in ruby
|
data/bin/calc
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require 'rubygems'
|
4
|
-
require 'calculator'
|
5
|
-
require 'calcex'
|
6
|
-
|
7
|
-
$stdout.print "> "
|
8
|
-
$stdout.flush
|
9
|
-
|
10
|
-
text = gets
|
11
|
-
|
12
|
-
$calc = Calculator.new()
|
13
|
-
|
14
|
-
begin
|
15
|
-
puts "= " + $calc.eval(text).to_s
|
16
|
-
rescue ParseError
|
17
|
-
puts "Parse Error"
|
18
|
-
rescue UnrecognizedTokenException
|
19
|
-
puts "UnrecognizedTokenException"
|
20
|
-
rescue
|
21
|
-
puts "Unkown exception"
|
22
|
-
end
|