calc_jgomez88 0.0.2

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 61a2b5a27d01d7760aedb6ed9a2715c2dda44b8c
4
+ data.tar.gz: 844adc3e28d0d7e5e88d7dc32686127bb6133aa6
5
+ SHA512:
6
+ metadata.gz: 8a8d4dd2b9d7cd230d39111c4f9626645dab902c6dcfc9740a9aafa5fd22dcadf78bcc03f313ffed0faefb50ed9abe781925535e2c12eb8b3e0e7a2319c47328
7
+ data.tar.gz: ff5f8da5c84f4f1d62fc44435944d42edacb81fa3ce755c045f75e2e95416f81c569641c1c183fc21fbf2fc4c687b5f36eed26bf47f7f646179b25577d0635c1
data/bin/calc ADDED
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env ruby
2
+ # env busca donde esta instalado ruby
3
+ # cuerpo principal de toda la calculadora
4
+ require 'rubygems'
5
+ require 'calculator'
6
+ require 'calcex'
7
+
8
+ $stdout.print "> "
9
+ $stdout.flush
10
+
11
+ text = gets
12
+
13
+ $calc = Calculator.new()
14
+
15
+ begin
16
+ puts "= " + $calc.eval(text).to_s
17
+ rescue ParseError
18
+ puts "Parse Error"
19
+ rescue UnrecognizedTokenException
20
+ puts "UnrecognizedTokenException"
21
+ rescue
22
+ puts "Unkown exception"
23
+ end
data/lib/ast.rb ADDED
@@ -0,0 +1,89 @@
1
+ require 'set'
2
+
3
+
4
+ class BinaryNode
5
+ attr_reader :left, :right
6
+
7
+ def initialize(left,right) #inicializacion
8
+ @left = left
9
+ @right = right
10
+ end
11
+ end
12
+
13
+ class UnaryNode
14
+ attr_reader :subTree
15
+
16
+ def initialize(subTree)
17
+ @subTree = subTree
18
+ end
19
+ end
20
+
21
+ class AddNode < BinaryNode #hereda de binaryNode
22
+ def initialize(left, right)
23
+ super(left,right)
24
+ end
25
+
26
+ def evaluate()
27
+ @left.evaluate() + @right.evaluate()
28
+ #los obtiene y los evalua
29
+ end
30
+ end
31
+
32
+ class SubNode < BinaryNode
33
+ def initialize(left, right)
34
+ super(left,right)
35
+ end
36
+
37
+ def evaluate()
38
+ return @left.evaluate() - @right.evaluate()
39
+ end
40
+ end
41
+
42
+ class TimesNode < BinaryNode
43
+ def initialize(left, right)
44
+ super(left,right)
45
+ end
46
+
47
+ def evaluate()
48
+ return @left.evaluate() * @right.evaluate()
49
+ end
50
+ end
51
+
52
+ class DivideNode < BinaryNode
53
+ def initialize(left, right)
54
+ super(left,right)
55
+ end
56
+
57
+ def evaluate()
58
+ return @left.evaluate() / @right.evaluate()
59
+ end
60
+ end
61
+
62
+
63
+ class StoreNode < UnaryNode
64
+ #
65
+ def initialize(subTree)
66
+ super(subTree)
67
+ end
68
+
69
+ def evaluate
70
+ $calc.memory = subTree.evaluate()
71
+ end
72
+ end
73
+
74
+ class RecallNode
75
+ #
76
+ def evaluate
77
+ $calc.memory
78
+ end
79
+ end
80
+
81
+ class NumNode
82
+ def initialize(num) #
83
+ @num = num
84
+ end
85
+
86
+ def evaluate()
87
+ return @num
88
+ end
89
+ end
data/lib/calcex.rb ADDED
@@ -0,0 +1,4 @@
1
+
2
+ class ParseError < Exception; end
3
+ class UnrecognizedTokenException < Exception; end
4
+ #para generar una expecion ; para poder separar el fin de la clase
data/lib/calculator.rb ADDED
@@ -0,0 +1,17 @@
1
+ require 'parser'
2
+ require 'ast'
3
+
4
+ class Calculator
5
+ attr_accessor :memory #lo cambiamos por accessor atttr_reader : memory
6
+
7
+
8
+ def initialize()
9
+ @memory = 0
10
+ end
11
+
12
+ def eval(expr)
13
+ parser = Parser.new(StringIO.new(expr))
14
+ ast = parser.parse()
15
+ return ast.evaluate()
16
+ end
17
+ end
data/lib/parser.rb ADDED
@@ -0,0 +1,138 @@
1
+ require 'ast'
2
+ require 'scanner'
3
+ require 'token'
4
+ require 'calcex'
5
+
6
+ class Parser
7
+ def initialize(istream)
8
+ @scan = Scanner.new(istream)
9
+ #recibe un flujo de datos
10
+ end
11
+
12
+ def parse()
13
+ return Prog()
14
+ end
15
+
16
+ private
17
+ def Prog()
18
+ result = Expr()
19
+ t = @scan.getToken()
20
+ #produce el sigiente token
21
+
22
+ if t.type != :eof then
23
+ print "Expected EOF. Found ", t.type, ".\n"
24
+ raise ParseError.new
25
+
26
+ end
27
+
28
+ return result
29
+ #el resultado es unaarbol abstracto sintatico
30
+ end
31
+
32
+ def Expr()
33
+ return RestExpr(Term())
34
+ end
35
+
36
+ def RestExpr(e)
37
+ t = @scan.getToken()
38
+ #leo el token
39
+
40
+ if t.type == :add then
41
+ return RestExpr(AddNode.new(e,Term()))
42
+ end
43
+
44
+ if t.type == :sub then
45
+ return RestExpr(SubNode.new(e,Term()))
46
+ end
47
+
48
+ @scan.putBackToken()
49
+
50
+
51
+ return e
52
+ end
53
+
54
+ def Term()
55
+ # Write your Term() code here. This code is just temporary
56
+ # so you can try the calculator out before finishing it.
57
+
58
+ # t = @scan.getToken()
59
+
60
+ # if t.type == :number then
61
+ # val = t.lex.to_i
62
+ # return NumNode.new(val)
63
+ # end
64
+
65
+ # puts "Term not implemented\n"
66
+
67
+ # raise ParseError.new
68
+ RestTerm(Storable())
69
+ end
70
+
71
+ def RestTerm(e)
72
+
73
+ # puts "RestTerm not implemented"
74
+ # raise ParseError.new # "Parse Error"
75
+ #lo borramos
76
+ t = @scan.getToken
77
+ if t.type == :times
78
+ return RestTerm (TimesNode.new(e, Storable()))
79
+ end
80
+ if t.type == :divide
81
+ #mira el tipo de token
82
+ return RestTerm(DivideNode.new(e, Storable()))
83
+ end
84
+ @scan.putBackToken
85
+
86
+ return e
87
+ end
88
+
89
+ def Storable()
90
+
91
+ # puts "Storable not implemented"
92
+ # raise ParseError.new # "Parse Error"
93
+ #lo borramos
94
+ result=Factor()
95
+ t = @scan.getToken
96
+ if t.type== :keyword then
97
+ if t.lex == "S" then
98
+ return StoreNode.new(result)
99
+ end
100
+ puts "Expected S found: ",t.lex
101
+ raise ParseError.new
102
+ end
103
+ @scan.putBackToken
104
+ return result
105
+ end
106
+
107
+ def Factor()
108
+
109
+ # puts "Factor not implemented"
110
+ # raise ParserError.new # "Parse Error"
111
+ #lo borramos
112
+ t = @scan.getToken
113
+ if t.type == :number then
114
+ return NumNode.new(t.lex.to_i)
115
+ #se convierte a integers
116
+ end
117
+ if t.type == :keyword then
118
+ if t.lex == "R" then
119
+ return RecallNode.new
120
+ end
121
+ puts "Expected R found: " + t.lex
122
+ raise ParseError.new
123
+ end
124
+ if t.type == :lparen then
125
+ result = Expr()
126
+ t=@scan.getToken
127
+
128
+ if t.type == :rparen then
129
+ return result
130
+ end
131
+
132
+ puts "Expected ) found: " + t.type.to_s
133
+ raise ParseError.new
134
+ end
135
+ puts "Expected number,R ( found: " + t.type.to_s
136
+ raise ParseError
137
+ end
138
+ end
data/lib/scanner.rb ADDED
@@ -0,0 +1,136 @@
1
+ require 'stringio'
2
+ #incluye los modulos(flujo de entrada de un string)
3
+ require 'calcex'
4
+ #modulo de las exepciones de ruby
5
+
6
+ class Scanner
7
+ def initialize(inStream)
8
+ @istream = inStream
9
+ #flujo de entrada
10
+ @keywords = Set.new(["S","R"])
11
+ @lineCount = 1
12
+ @colCount = -1
13
+ @needToken = true
14
+ @lastToken = nil
15
+ end
16
+
17
+ def putBackToken
18
+ #pone el valor
19
+ @needToken = false
20
+ end
21
+
22
+ def getToken
23
+ unless @needToken
24
+ @needToken = true
25
+ return @lastToken
26
+ end
27
+
28
+ state = 0
29
+ foundOne = false
30
+ c = @istream.getc()
31
+ #QUE TIPO DE CARACTER HAY
32
+
33
+ if @istream.eof() then
34
+ @lastToken = Token.new(:eof,@lineCount,@colCount)
35
+ return @lastToken
36
+ end
37
+
38
+ until foundOne
39
+ @colCount = @colCount + 1
40
+ case state
41
+ #COMIENZA CON el caracter 0
42
+ when 0
43
+ lex = ""
44
+ column = @colCount
45
+ line = @lineCount
46
+ if isLetter(c) then state=1
47
+ #pregunta de que tipo de caracter
48
+ elsif isDigit(c) then state=2
49
+ elsif c == ?+ then state = 3
50
+ elsif c == ?- then state = 4
51
+ elsif c == ?* then state = 5
52
+ elsif c == ?/ then state = 6
53
+ elsif c == ?( then state = 7
54
+ elsif c == ?) then state = 8
55
+ elsif c == ?\n then
56
+ @colCount = -1
57
+ @lineCount = @lineCount+1
58
+ elsif isWhiteSpace(c) then state = state #ignore whitespace
59
+ elsif @istream.eof() then
60
+ @foundOne = true
61
+ type = :eof
62
+ else
63
+ #lanza la exeception
64
+ puts "Unrecognized Token found at line ",line," and column ",column,"\n"
65
+ raise UnrecognizedTokenException # "Unrecognized Token"
66
+ end
67
+ when 1
68
+ if isLetter(c) or isDigit(c) then state = 1
69
+ else
70
+ if @keywords.include?(lex) then
71
+ #mira si esta inncluido el lexema
72
+ foundOne = true
73
+ type = :keyword
74
+ else
75
+ foundOne = true
76
+ type = :identifier
77
+ end
78
+ end
79
+ when 2
80
+ if isDigit(c) then state = 2
81
+ else
82
+ type = :number
83
+ foundOne = true
84
+ end
85
+ when 3
86
+ type = :add
87
+ foundOne = true
88
+ when 4
89
+ type = :sub
90
+ foundOne = true
91
+ when 5
92
+ type = :times
93
+ foundOne = true
94
+ when 6
95
+ type = :divide
96
+ foundOne = true
97
+ when 7
98
+ type = :lparen
99
+ foundOne = true
100
+ when 8
101
+ type = :rparen
102
+ foundOne = true
103
+ end
104
+
105
+ if !foundOne then
106
+ lex.concat(c)
107
+ c = @istream.getc()
108
+ end
109
+
110
+ end
111
+
112
+ @istream.ungetc(c)
113
+ @colCount = @colCount - 1
114
+ if type == :number or type == :identifier or type == :keyword then
115
+ t = LexicalToken.new(type,lex,line,column)
116
+ else
117
+ t = Token.new(type,line,column)
118
+ end
119
+
120
+ @lastToken = t
121
+ return t
122
+ end
123
+ #todoso los tributos son protegidos y los metodos pueden ser protegido o privado
124
+ private
125
+ def isLetter(c)
126
+ return ((?a <= c and c <= ?z) or (?A <= c and c <= ?Z))
127
+ end
128
+
129
+ def isDigit(c)
130
+ return (?0 <= c and c <= ?9)
131
+ end
132
+
133
+ def isWhiteSpace(c)
134
+ return (c == ?\ or c == ?\n or c == ?\t)
135
+ end
136
+ end
data/lib/token.rb ADDED
@@ -0,0 +1,19 @@
1
+ class Token
2
+ attr_reader :type, :line, :col
3
+
4
+ def initialize(type,lineNum,colNum)
5
+ @type = type
6
+ @line = lineNum
7
+ @col = colNum
8
+ end
9
+ end
10
+
11
+ class LexicalToken < Token #herencia simple token
12
+ attr_reader :lex
13
+
14
+ def initialize(type,lex,lineNum,colNum) #lexema que va a leer polimorfismo
15
+ super(type,lineNum,colNum) #clase padre token
16
+
17
+ @lex = lex #instancias de lexical token podran tener @lex
18
+ end
19
+ end
metadata ADDED
@@ -0,0 +1,51 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: calc_jgomez88
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Kent D. Lee - Juan Francisco Cardona Mc-juan camilo gomez
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-11-12 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: An calculator implementation on ruby
14
+ email: fcardona@eafit.edu.co-jgomez88@eafit.edu.co
15
+ executables:
16
+ - calc
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - bin/calc
21
+ - lib/ast.rb
22
+ - lib/calcex.rb
23
+ - lib/calculator.rb
24
+ - lib/parser.rb
25
+ - lib/scanner.rb
26
+ - lib/token.rb
27
+ homepage: http://www1.eafit.edu.co/fcardona/cursos/st0244/rubycal
28
+ licenses:
29
+ - ARTISTIC
30
+ metadata: {}
31
+ post_install_message:
32
+ rdoc_options: []
33
+ require_paths:
34
+ - lib
35
+ required_ruby_version: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ required_rubygems_version: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ requirements: []
46
+ rubyforge_project:
47
+ rubygems_version: 2.4.7
48
+ signing_key:
49
+ specification_version: 4
50
+ summary: Another calculator in ruby
51
+ test_files: []