calc_jgomez40 0.0.2 → 0.0.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 861e6c75b217b55d0b8c1d8528ecabd7c68bca79
4
- data.tar.gz: d92252649fd2e65b0a698a4269791bfd8e37addd
3
+ metadata.gz: e5dfe1f154a350d932fe0b2f82cf4d67de86e2df
4
+ data.tar.gz: abe76b073ad521d809c82b39a6a8226e9d907837
5
5
  SHA512:
6
- metadata.gz: 7ed00eb029dd271709cb343e095f162df3ccf29e24a8e87b18a3455ab9d14db82c2a9e86eba9ba853a2858a7e1342fc5d989869866bc1e34edb96240637a1557
7
- data.tar.gz: eecce5d8f90a5382003c233d8e27f2fcf7fd9c698b41d104280816becfcb94a9a0e684bfb8a64c28485b73c57addb3bd7851f6993881d78ef153b55dd46e0d8b
6
+ metadata.gz: 263b0cc058f0893b2a166a656a3b5181ff44266736c03bf245493a713847d5d0586b92bbb5b7a6262e230cf46cfbd7cf26e0dcbee76480580b160028de8c5679
7
+ data.tar.gz: a1f6d8c5c05f1d076096e6af97128fb14ebb95f73a60a365ffad1efbeedb169931a7bef9ed762e515c341680e2b571462fb725ef0a3746ffa5f2e02d91b2bf66
data/bin/calc CHANGED
@@ -4,19 +4,63 @@ require 'rubygems'
4
4
  require 'calculator'
5
5
  require 'calcex'
6
6
 
7
- $stdout.print "> "
8
- $stdout.flush
7
+ $calc = Calculator.new()
9
8
 
10
- text = gets
9
+ def interactiveCalc
10
+ $stdout.print "> "
11
+ $stdout.flush
12
+ text = gets
13
+ makeCalc(text)
14
+ interactiveCalc()
15
+ end
11
16
 
12
- $calc = Calculator.new()
17
+ def makeCalc(text)
18
+ $stdout.puts "=> " + $calc.eval(text).to_s + $calc.printVar()
19
+ end
20
+
21
+ def setEnvVars
22
+ ENV.each do |key, value|
23
+ if key.start_with?("CALCVAR") == true then
24
+ var = key.slice(7, key.size)
25
+ text = var + "=" + value + "\n"
26
+ $calc.eval(text)
27
+ end
28
+ end
29
+ $calc.changeSetEnvVars(false)
30
+ end
31
+
32
+ def processArgs
33
+ args = ARGF.argv
34
+ i = 0
35
+ while i < args.size-1 do
36
+ optionArg = args[i]
37
+ if optionArg == "-e" then
38
+ $calc.envConf()
39
+ setEnvVars()
40
+ elsif (optionArg == "-v") then
41
+ text = args[i+1] + "\n"
42
+ $calc.eval(text)
43
+ i += 1
44
+ else
45
+ lines = ARGF.readlines
46
+ lines.each do |line| makeCalc(line) end
47
+ end
48
+ i += 1
49
+ end
50
+ end
51
+
52
+ def main
53
+ setEnvVars()
54
+ processArgs()
55
+ interactiveCalc()
56
+ end
13
57
 
14
58
  begin
15
- puts "= " + $calc.eval(text).to_s
59
+ main()
16
60
  rescue ParseError
17
- puts "Parse Error"
61
+ puts "* Parse Error"
18
62
  rescue UnrecognizedTokenException
19
- puts "UnrecognizedTokenException"
63
+ puts "* UnrecognizedTokenException"
20
64
  rescue
21
- puts "Unkown exception"
65
+ puts "* Unkown exception"
22
66
  end
data/lib/ast.rb CHANGED
@@ -8,10 +8,10 @@ class BinaryNode
8
8
  @right = right
9
9
  end
10
10
  end
11
-
11
+
12
12
  class UnaryNode
13
13
  attr_reader :subTree
14
-
14
+
15
15
  def initialize(subTree)
16
16
  @subTree = subTree
17
17
  end
@@ -21,9 +21,9 @@ class AddNode < BinaryNode
21
21
  def initialize(left, right)
22
22
  super(left,right)
23
23
  end
24
-
25
- def evaluate
26
- @left.evaluate + @right.evaluate
24
+
25
+ def evaluate
26
+ return @left.evaluate() + @right.evaluate()
27
27
  end
28
28
  end
29
29
 
@@ -31,54 +31,119 @@ class SubNode < BinaryNode
31
31
  def initialize(left, right)
32
32
  super(left,right)
33
33
  end
34
-
35
- def evaluate
36
- return @left.evaluate - @right.evaluate
34
+
35
+ def evaluate
36
+ return @left.evaluate() - @right.evaluate()
37
37
  end
38
38
  end
39
+
39
40
  class TimesNode < BinaryNode
40
41
  def initialize(left, right)
41
- super(left,right)
42
+ super(left, right)
42
43
  end
43
44
 
44
45
  def evaluate
45
- @left.evaluate * @right.evaluate
46
+ left.evaluate * right.evaluate
46
47
  end
47
48
  end
48
49
 
49
50
  class DivideNode < BinaryNode
50
51
  def initialize(left, right)
51
- super(left,right)
52
+ super(left, right)
53
+ end
54
+
55
+ def evaluate
56
+ left.evaluate / right.evaluate
57
+ end
58
+ end
59
+
60
+ class ModNode < BinaryNode
61
+ def initialize(left, right)
62
+ super(left, right)
52
63
  end
53
64
 
54
65
  def evaluate
55
- @left.evaluate / @right.evaluate
66
+ left.evaluate % right.evaluate
56
67
  end
57
68
  end
58
69
 
59
70
  class StoreNode < UnaryNode
60
- def initialize(subTree)
61
- super(subTree)
71
+ def initialize(sub)
72
+ super(sub)
62
73
  end
63
74
 
64
75
  def evaluate
65
- $calc.memory = subTree.evaluate
76
+ $calc.memory = subTree.evaluate
66
77
  end
67
78
  end
68
79
 
69
80
  class RecallNode
70
81
  def evaluate
71
- $calc.memory
72
- end
82
+ $calc.memory
83
+ end
73
84
  end
74
85
 
75
-
76
- class NumNode
86
+ class NumNode
77
87
  def initialize(num)
78
88
  @num = num
79
89
  end
80
-
90
+
91
+ def evaluate
92
+ return @num
93
+ end
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
+ return val
138
+ end
139
+ end
140
+
141
+ class GetNode
142
+ def initialize(key)
143
+ @key = key
144
+ end
145
+
81
146
  def evaluate
82
- @num
147
+ return $calc.get(@key)
83
148
  end
84
149
  end
data/lib/calcex.rb CHANGED
@@ -1,3 +1,2 @@
1
-
2
1
  class ParseError < Exception; end
3
2
  class UnrecognizedTokenException < Exception; end
data/lib/calculator.rb CHANGED
@@ -3,14 +3,67 @@ require 'ast'
3
3
 
4
4
  class Calculator
5
5
  attr_accessor :memory
6
-
6
+
7
7
  def initialize()
8
8
  @memory = 0
9
+ @useEnvVars = false
10
+ @setEnvVars = false
11
+ @createVar = false
12
+ @lastCreateKey = ''
13
+ @varsEnv = Hash.new()
14
+ @vars = Hash.new()
9
15
  end
10
-
16
+
11
17
  def eval(expr)
12
18
  parser = Parser.new(StringIO.new(expr))
13
19
  ast = parser.parse()
14
20
  return ast.evaluate()
15
21
  end
22
+
23
+ def set(key, value)
24
+ if @setEnvVars == true then
25
+ @varsEnv.store(key, value)
26
+ else
27
+ @vars.store(key, value)
28
+ end
29
+ @createVar = true;
30
+ @lastCreateKey = key
31
+ end
32
+ def isEnvVar(key)
33
+ if @varsEnv.has_key?(key) == true then
34
+ return true
35
+ else
36
+ return false
37
+ end
38
+ end
39
+ def get(keyToGet)
40
+ if @useEnvVars == true && isEnvVar(key) == true then
41
+ @varsEnv.each {|key, val|
42
+ if keyToGet == key then
43
+ return val
44
+ end }
45
+ else
46
+ @vars.each {|key, val|
47
+ if keyToGet == key then
48
+ return val
49
+ end }
50
+ end
51
+ return 0
52
+ end
53
+ def envConf
54
+ @useEnvVars = true
55
+ end
56
+
57
+ def changeSetEnvVars(bool)
58
+ @setEnvVars = bool
59
+ end
60
+
61
+ def printVar
62
+ result = ''
63
+ if @createVar == true then
64
+ result = " [ #{@lastCreateKey} <- #{get(@lastCreateKey)} ]"
65
+ @createVar = false
66
+ end
67
+ return result
68
+ end
16
69
  end
data/lib/parser.rb CHANGED
@@ -7,124 +7,144 @@ class Parser
7
7
  def initialize(istream)
8
8
  @scan = Scanner.new(istream)
9
9
  end
10
-
11
- def parse()
12
- return Prog()
10
+
11
+ def parse
12
+ Prog()
13
13
  end
14
14
 
15
15
  private
16
- def Prog()
16
+ def Prog
17
17
  result = Expr()
18
- t = @scan.getToken()
19
-
18
+ t = @scan.getToken
20
19
  if t.type != :eof then
21
20
  print "Expected EOF. Found ", t.type, ".\n"
22
21
  raise ParseError.new
23
22
  end
24
23
 
25
- return result
24
+ result
26
25
  end
27
26
 
28
- def Expr()
27
+ def Expr
29
28
  RestExpr(Term())
30
29
  end
31
-
30
+
32
31
  def RestExpr(e)
33
- t = @scan.getToken()
32
+ t = @scan.getToken
34
33
 
35
34
  if t.type == :add then
36
- return RestExpr(AddNode.new(e,Term()))
35
+ return RestExpr(AddNode.new(e,Term()))
37
36
  end
38
37
 
39
38
  if t.type == :sub then
40
39
  return RestExpr(SubNode.new(e,Term()))
41
40
  end
42
-
43
- @scan.putBackToken()
41
+
42
+ @scan.putBackToken
44
43
 
45
44
  e
46
45
  end
47
46
 
48
- def Term()
49
- # Write your Term() code here. This code is just temporary
50
- # so you can try the calculator out before finishing it.
51
-
52
- # t = @scan.getToken()
53
-
54
- #if t.type == :number then
55
- # val = t.lex.to_i
56
- #return NumNode.new(val)
57
- #end
58
-
59
- # puts "Term not implemented\n"
60
-
61
- # raise ParseError.new
47
+ def Term
62
48
  RestTerm(Storable())
63
49
  end
64
-
50
+
65
51
  def RestTerm(e)
66
52
  t = @scan.getToken
67
- if t.type == :times
68
- return RestTerm(TimesNode.new(e,Storable()))
53
+
54
+ if t.type == :times then
55
+ return RestTerm(TimesNode.new(e,Storable()))
69
56
  end
70
57
 
71
- if t.type == :divide
72
- return RestTerm(DivideNode.new(e,Storable()))
73
-
58
+ if t.type == :divide then
59
+ return RestTerm(DivideNode.new(e,Storable()))
74
60
  end
75
-
61
+
62
+ if t.type == :mod then
63
+ return RestTerm(ModNode.new(e,Storable()))
64
+ end
65
+
76
66
  @scan.putBackToken
77
-
67
+
78
68
  e
79
69
  end
80
-
81
-
82
- def Storable()
83
- result = Factor()
84
70
 
71
+ def Storable
72
+ MemOperation(Factor())
73
+ end
74
+
75
+ def MemOperation(e)
85
76
  t = @scan.getToken
86
77
 
87
- if t.type == :keyword then
88
- if t.lex == "S" then
89
- return StoreNode(result)
78
+ if t.type == :keyword
79
+ if t.lex == "S"
80
+ return StoreNode.new(e)
90
81
  end
91
- puts "Expected s found: ",t.lex
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}"
92
+ print " at line #{t.line} col: #{t.col}"
92
93
  raise ParseError.new
93
94
  end
94
95
 
95
96
  @scan.putBackToken
96
- result
97
-
97
+
98
+ e
98
99
  end
99
-
100
- def Factor()
100
+
101
+ def Factor
101
102
  t = @scan.getToken
102
103
 
103
- if t.type == :number then
104
+ if t.type == :number
104
105
  return NumNode.new(t.lex.to_i)
105
106
  end
106
107
 
107
- if t.type == :keyword then
108
- if t.lex == "R" then
108
+ if t.type == :keyword
109
+ if t.lex == 'R'
109
110
  return RecallNode.new
110
111
  end
111
- puts "Factor not implemented" + t.lex
112
- raise ParserError.new
112
+
113
+ if t.lex == 'C'
114
+ return ClearNode.new
115
+ end
116
+ puts "We found an error on Factor::keyword"
117
+ raise ParseError.new
113
118
  end
114
- if t.type == :lparen then
115
- result = Expr()
116
-
119
+
120
+ if t.type == :lparen
121
+ result = Expr()
117
122
  t = @scan.getToken
118
- if t == :rparen then
119
- return result
123
+ if t.type == :rparen
124
+ return result
120
125
  end
121
-
122
- puts "Expected ) no found: " + t.lex.to_i
123
- raise ParserError.new
124
-
126
+ puts "We found an error on Factor::rparen"
127
+ print " at line #{t.line} col: #{t.col}"
128
+ raise ParseError.new
125
129
  end
126
- puts "Expected number, R ( found:" + t.type.to_s
127
- raise ParserError.new
128
130
 
129
- end
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)
149
+ end
130
150
  end
data/lib/scanner.rb CHANGED
@@ -4,33 +4,33 @@ 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","C","M"])
8
8
  @lineCount = 1
9
9
  @colCount = -1
10
10
  @needToken = true
11
11
  @lastToken = nil
12
12
  end
13
-
14
- def putBackToken
13
+
14
+ def putBackToken()
15
15
  @needToken = false
16
16
  end
17
17
 
18
- def getToken
19
- unless @needToken
18
+ def getToken()
19
+ if !@needToken
20
20
  @needToken = true
21
21
  return @lastToken
22
22
  end
23
-
23
+
24
24
  state = 0
25
25
  foundOne = false
26
26
  c = @istream.getc()
27
-
27
+
28
28
  if @istream.eof() then
29
29
  @lastToken = Token.new(:eof,@lineCount,@colCount)
30
30
  return @lastToken
31
31
  end
32
-
33
- until foundOne
32
+
33
+ while !foundOne
34
34
  @colCount = @colCount + 1
35
35
  case state
36
36
  when 0
@@ -45,7 +45,9 @@ 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 == ?\n then
48
+ elsif c == ?% then state = 9
49
+ elsif c == ?= then state = 10
50
+ elsif c == ?\n then
49
51
  @colCount = -1
50
52
  @lineCount = @lineCount+1
51
53
  elsif isWhiteSpace(c) then state = state #ignore whitespace
@@ -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
@@ -99,8 +107,8 @@ class Scanner
99
107
  end
100
108
 
101
109
  end
102
-
103
- @istream.ungetc(c)
110
+
111
+ @istream.ungetc(c)
104
112
  @colCount = @colCount - 1
105
113
  if type == :number or type == :identifier or type == :keyword then
106
114
  t = LexicalToken.new(type,lex,line,column)
@@ -109,18 +117,18 @@ class Scanner
109
117
  end
110
118
 
111
119
  @lastToken = t
112
- return t
120
+ return t
113
121
  end
114
122
 
115
123
  private
116
- def isLetter(c)
124
+ def isLetter(c)
117
125
  return ((?a <= c and c <= ?z) or (?A <= c and c <= ?Z))
118
126
  end
119
-
127
+
120
128
  def isDigit(c)
121
129
  return (?0 <= c and c <= ?9)
122
130
  end
123
-
131
+
124
132
  def isWhiteSpace(c)
125
133
  return (c == ?\ or c == ?\n or c == ?\t)
126
134
  end
data/lib/token.rb CHANGED
File without changes
metadata CHANGED
@@ -1,17 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: calc_jgomez40
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
- - Kent D. Lee - Juan Francisco Cardona Mc - Juan Sebastian Gomez
7
+ - Kent D. Lee - Juan Francisco Cardona Mc
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-11-11 00:00:00.000000000 Z
11
+ date: 2015-11-12 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: An calculator implementation on ruby
14
- email: fcardona@eafit.edu.co
14
+ email: jgomez40@eafit.edu.co
15
15
  executables:
16
16
  - calc
17
17
  extensions: []
@@ -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.7
47
+ rubygems_version: 2.4.5.1
48
48
  signing_key:
49
49
  specification_version: 4
50
50
  summary: Another calculator in ruby