rips 0.0.8 → 0.1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: da602175a9a4fad4303735f4839de634fdd6c69f
4
- data.tar.gz: ddec7e453dc99ce5ad427b8a8ba1d727ad3c7858
3
+ metadata.gz: 3fff3963bd941c448681cc84b7866aef618c72d9
4
+ data.tar.gz: 1f77e7972c43bcc523a10f749b4cfc7c3bc04d67
5
5
  SHA512:
6
- metadata.gz: 2e133f6438d2a32d2cc03cc93e72a3ac2ab6f83cbb358146e21d7007334f900bc5df54a9636e499850fba1284fc4ac4c550294c3288b124610605e7e1e0f3169
7
- data.tar.gz: ea199e86cc2cf07d5fde0eb4bcc5a585ed311ac21354c1be517896be45a9e4112d09219c1e4e346c07253638d0e4f10a197b14076fbcf65320100b9ef6489d49
6
+ metadata.gz: d0bb9c555874d3bdfac873b7cec8add0b1f05007684f5406158420cb76e2ca84352b3d2f2c258faadfc466b62a09d18c31173b65c75a9970fe427b182b1040b2
7
+ data.tar.gz: febd89dee2a4629452838ade172abde29357d6c1f14bad915cdcc9dcaccd15ea92452ff617f3c2d11ffef5ab8aaf37a655454ea21b77a5063310bab2183f525e
data/README.md CHANGED
@@ -1,14 +1,63 @@
1
1
  # Rips
2
+ [![Gem Version](https://badge.fury.io/rb/rips.svg)](http://badge.fury.io/rb/rips)
3
+ [![Dependency Status](https://gemnasium.com/Madh93/rips.svg)](https://gemnasium.com/Madh93/rips)
2
4
 
3
- Simple assembler written in Ruby for a simple 16-bit CPU written in Verilog.
5
+ Simple assembler written in Ruby for a simple 16-bit CPU written in Verilog. Based in MIPS syntax with next features:
6
+
7
+ - 18 basic instructions
8
+ - 16 registers ($0-$15)
9
+ - 4 I/O ports (@0-@3)
10
+ - Support labels
11
+ - Support comments
12
+
13
+ ## Requirements
14
+
15
+ Ruby >=1.9.3
4
16
 
5
17
  ## Installation
6
18
 
7
19
  $ gem install rips
20
+
21
+ or download from [RubyGems](https://rubygems.org/gems/rips).
22
+
23
+ **Optional:** [Rips syntax highlightning package for sublime text 2/3](https://github.com/Madh93/rips-syntax/)
8
24
 
9
25
  ## Usage
10
26
 
11
- $ rips instructions.rips
27
+ $ rips [OPTIONS] instructions.rips
28
+
29
+ Examples:
30
+
31
+ $ rips --debug instructions.rips
32
+ $ rips -d instructions.rips -o instructions
33
+
34
+ ## Options
35
+
36
+ -d, --debug Show trace in console
37
+ -o FILE Output file with binary instructions (by default: progfile.dat)
38
+
39
+ ## Instruction Set
40
+
41
+ | Name | MNENOMIC | FORMAT | OPERATION | OPCODE |
42
+ |--------------------|----------|--------|----------------|--------|
43
+ | Move | move | C | move $1, $0 | 0000 |
44
+ | Not | not | C | not $1, $0 | 0001 |
45
+ | Add | add | D | add $2, $0, $1 | 0010 |
46
+ | Subtract | sub | D | sub $2, $0, $1 | 0011 |
47
+ | And | and | D | and $2, $0, $1 | 0100 |
48
+ | Or | or | D | or $2, $0, $1 | 0101 |
49
+ | Sign negation | neg | C | neg $1, $0 | 0110 |
50
+ | Jump | j | B | j label | 1001 |
51
+ | Load Inmediate | li | C | li $0, 10 | 1010 |
52
+ | Load from I/O | lesr | C | lesr $0, @0 | 1011 |
53
+ | Store I/O from Reg | sesr | C | sesr @0, $0 | 1101 |
54
+ | Store I/O from Mem | sesm | C | sesm @0, 10 | 1110 |
55
+ | Relative Jump | ji | B | ji 10 | 011000 |
56
+ | Jump and Link | jal | B | jal label | 101000 |
57
+ | Jump Register | jr | A | jr | 111000 |
58
+ | Branch z!=0 | bnez | B | bnez label | 001111 |
59
+ | Branch z==0 | beqz | B | beqz label | 011111 |
60
+ | No Operation | nop | A | nop | 111111 |
12
61
 
13
62
  ## Contributing
14
63
 
@@ -16,4 +65,4 @@ Simple assembler written in Ruby for a simple 16-bit CPU written in Verilog.
16
65
  2. Create your feature branch (`git checkout -b my-new-feature`)
17
66
  3. Commit your changes (`git commit -am 'Add some feature'`)
18
67
  4. Push to the branch (`git push origin my-new-feature`)
19
- 5. Create a new Pull Request
68
+ 5. Create a new Pull Request
data/bin/rips CHANGED
@@ -1,3 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require 'rips'
3
+ require 'rips'
4
+
5
+ Rips::RipsLauncher.new
@@ -0,0 +1,55 @@
1
+ #### Simple calculator ###
2
+
3
+ # Assign opcodes to add, sub and mul
4
+ define:
5
+ li $5, 8 # add (1000)
6
+ li $6, 4 # sub (0100)
7
+ li $7, 2 # mul(0010)
8
+
9
+ main:
10
+
11
+ # Load from I/O to registers
12
+ lesr $1, @0
13
+ lesr $2, @1
14
+ lesr $3, @2
15
+
16
+ # Check input is add, sub or mul
17
+ sub $4, $3, $5
18
+ beqz op_add
19
+
20
+ sub $4, $3, $6
21
+ beqz op_sub
22
+
23
+ sub $4, $3, $7
24
+ beqz op_mul
25
+
26
+ j main # Infinite loop
27
+
28
+ op_add:
29
+
30
+ add $4, $1, $2
31
+ j store
32
+
33
+ op_sub:
34
+
35
+ sub $4, $1, $2
36
+ j store
37
+
38
+ op_mul:
39
+
40
+ li $8, 1 # Count
41
+ move $4, $0
42
+ add $1, $1, $0 # IF $1==0 -> finish loop
43
+ beqz store
44
+
45
+ loop:
46
+
47
+ add $4, $4, $2 # Repeat $1 times
48
+ sub $1, $1, $8
49
+ bnez loop
50
+
51
+ store:
52
+
53
+ # Store in I/O from register
54
+ sesr @0, $4
55
+ j main
File without changes
@@ -3,34 +3,63 @@ require "rips/assembler"
3
3
  require "rips/error"
4
4
 
5
5
  module Rips
6
+ class RipsLauncher
6
7
 
7
- debug=false
8
+ # @argv: input's arguments
9
+ # @debug: switch to show trace in console
10
+ # @source: source file with Rips instructions
11
+ # @output: output file with binary instructions
12
+ def initialize
13
+ @argv = ARGV
14
+ @debug = debug_mode?
15
+ @source = source_file
16
+ @output = output_file
8
17
 
9
- # Check arguments
10
- if ARGV.include?("-d")
11
- debug = true
12
- ARGV.delete("-d")
13
- elsif ARGV.include?("--debug")
14
- debug = true
15
- ARGV.delete("--debug")
16
- end
17
-
18
- Error::message(1) if ARGV.empty?
19
-
20
- # Check for a valid file
21
- if !File.exist? ARGV[0]
22
- Error::message(2)
23
- elsif !File.readable? ARGV[0]
24
- Error::message(3)
25
- end
18
+ run
19
+ end
26
20
 
27
- rips = Assembler.new(debug)
21
+ private
28
22
 
29
- File.open(ARGV[0], "r") do |f|
30
- f.each_line do |line|
31
- rips << line
23
+ # Check debug mode
24
+ def debug_mode?
25
+ @argv.include?("-d") || @argv.include?("--debug")
32
26
  end
33
- end
34
27
 
35
- rips.run
36
- end
28
+ # Check if it's a valid input file
29
+ def source_file
30
+ source = @argv.find{|x| /\.rips$/ =~ x }
31
+ Error::message(1) if source.nil?
32
+ Error::message(2) if !File.exist?(source)
33
+ Error::message(3) if !File.readable?(source)
34
+ return source
35
+ end
36
+
37
+ # Check cmdline options (now only output)
38
+ def output_file
39
+ if @argv.include?("-o")
40
+ out = @argv[(@argv.index("-o"))+1]
41
+ Error::message(9) if out.nil? || out == @source || out == "-d" || out == "--debug"
42
+ return out
43
+ else
44
+ return "progfile.dat"
45
+ end
46
+ end
47
+
48
+ # Read input file
49
+ def read
50
+ File.open(@source, "r") do |f|
51
+ f.each_line do |line|
52
+ @rips << line
53
+ end
54
+ end
55
+ end
56
+
57
+ # Launch Rips assembler
58
+ def run
59
+ @rips = Assembler.new(@debug)
60
+ read
61
+ @rips.run(@output)
62
+ end
63
+
64
+ end
65
+ end
@@ -1,5 +1,13 @@
1
1
  require "rips/instructions"
2
2
 
3
+ class String
4
+ include Rips::Utils::StringAssemblerExtension
5
+ end
6
+
7
+ class Array
8
+ include Rips::Utils::ArrayExtension
9
+ end
10
+
3
11
  module Rips
4
12
  class Assembler
5
13
 
@@ -22,120 +30,62 @@ module Rips
22
30
  @line = 1
23
31
  end
24
32
 
25
- # Store labels and number line
26
- def find_labels
27
-
28
- @input.each_with_index do |line, i|
29
- if !line.empty?
30
- label = line.scan(/\w+:/)
31
- if (label.size == 1)
32
-
33
- if !@labels.include?(label[0].to_s.split(":").first)
34
- @labels[label[0].to_s.split(":").first] = [*@instructions.each_with_index].bsearch{|x, _| x >= i}.last
35
- else
36
- Error::message(7, i+1, label[0].to_s.split(":").first)
37
- end
38
- end
39
- end
40
- end
41
- end
33
+ private
42
34
 
43
35
  # Store number line for each instruction
44
36
  def find_instructions
45
-
46
37
  @input.each_with_index do |line,i|
47
- if (!line.empty?) && (line.scan(/\w+:/).empty?) && (line[0] != "#")
38
+ if line.instruction?
48
39
  @instructions << i+1
49
40
  end
50
41
  end
51
42
  end
52
43
 
53
- # Stores each new line of file
54
- def << (value)
55
- @input << value.strip
56
- end
57
-
58
- # Analyze and translate each instruction
59
- def run
60
-
61
- find_instructions
62
- find_labels
63
-
64
- @input.each do |line|
65
-
66
- # If line is empty -> next line
67
- # Or if not is a label
68
- if (!line.empty?) && (line.scan(/\w+:/).empty?)
69
-
70
- parse_input(line)
71
- @instruction = nil
72
-
73
- # If it's a comment -> show but not work with it
74
- if line[0] != "#"
75
-
76
- exists_instruction
77
- @instruction = get_instruction
78
-
79
- parse_label
80
-
81
- argument_size
82
- argument_syntax
83
-
84
- @instruction.set_arguments(@cmd[:arguments])
85
- @output << @instruction.code
44
+ # Store labels and number line
45
+ def find_labels
46
+ @input.each_with_index do |line, i|
47
+ if line.label?(i)
48
+ label = line.split(":")[0]
49
+ if !@labels.include?(label)
50
+ @labels[label] = [*@instructions.each_with_index].search{|x, _| x >= i}.last
51
+ else
52
+ Error::message(7, i+1, line)
86
53
  end
87
- show if @debug
88
- end
89
- @line += 1
90
- end
91
-
92
- generate
93
- end
94
-
95
- # Codification log of instruction
96
- def show
97
-
98
- # If line was a comment -> @instruction should be nil
99
- if @instruction.nil?
100
- codification = ""
101
- else
102
- codification = @instruction.code.scan(/.{4}|.+/).join("_")
54
+ end
103
55
  end
104
-
105
- puts "@#{@line}:" \
106
- "\t#{codification}" \
107
- "\t#{@cmd[:comments]}"
108
56
  end
109
57
 
110
- # Generate output in "progfile.dat"
111
- def generate
112
- File.open("progfile.dat", "w") do |f|
113
- @output.each do |line|
114
- f.puts line
115
- end
116
- end
117
- end
118
-
119
58
  # Split on tokens
120
59
  def parse_input (line)
121
60
 
122
- if line[0] == "#"
61
+ if line.comment?
123
62
  @cmd[:comments] = line
124
63
  else
125
- @cmd[:name] = line.split("#").first.split(" ").first.downcase
126
- @cmd[:arguments] = line.split("#").first.split("#{@cmd[:name]} ")
127
- if !@cmd[:arguments].empty?
128
- @cmd[:arguments] = @cmd[:arguments].pop.split("#").first.del(/\s+|\t+/).split(",")
129
- end
130
- if @cmd[:arguments].first == "jr" ||
131
- @cmd[:arguments].first == "nop"
132
- @cmd[:arguments] = []
64
+ @cmd[:name] = line.instruction_name
65
+ if (@cmd[:name] == "jr ") || (@cmd[:name] == "nop ")
66
+ @cmd[:arguments] = []
67
+ else
68
+ @cmd[:arguments] = line.instruction_arguments(@cmd[:name])
133
69
  end
134
- @cmd[:comments] = line.split("#").slice(1..-1).join
70
+ @cmd[:comments] = line.instruction_comments
135
71
  @cmd[:comments].insert(0,"#") if !@cmd[:comments].empty?
136
72
  end
137
73
  end
138
74
 
75
+ # Obtain instruction's instance object
76
+ def get_instruction
77
+ Rips::Instructions.const_get("#{@cmd[:name].capitalize}").new
78
+ end
79
+
80
+ # Exists instruction in Instruction Set?
81
+ def exists_instruction?
82
+ if Instructions::SET.include? (@cmd[:name])
83
+ @instruction = get_instruction
84
+ else
85
+ Error::message(4, @line, @cmd[:name] )
86
+ end
87
+ end
88
+
139
89
  # Translate label's name to instruction's number
140
90
  def parse_label
141
91
  if (@instruction.is_a? Rips::Instructions::Beqz) ||
@@ -146,23 +96,9 @@ module Rips
146
96
  @cmd[:arguments] = [@labels[@cmd[:arguments].first].to_s]
147
97
  end
148
98
  end
149
-
150
- # Obtain instruction's instance object
151
- def get_instruction
152
- Object.const_get("Rips::Instructions::#{@cmd[:name].capitalize}").new
153
- end
154
-
155
- # Exists instruction in Instruction Set?
156
- def exists_instruction
157
- if !Instructions::SET.include? (@cmd[:name])
158
- Error::message( 4,
159
- @line,
160
- @cmd[:name] )
161
- end
162
- end
163
-
99
+
164
100
  # Check number of arguments given with expected by instruction
165
- def argument_size
101
+ def argument_size?
166
102
  if @cmd[:arguments].size != @instruction.args_number
167
103
  Error::message( 5,
168
104
  @line,
@@ -173,16 +109,65 @@ module Rips
173
109
  end
174
110
 
175
111
  # Check if arguments are the same variable type of instruction
176
- def argument_syntax
112
+ def argument_syntax?
177
113
  @instruction.variables.each_with_index do |var,i|
178
- if var.syntax? @cmd[:arguments][i]
179
- @cmd[:arguments][i] = var.to_i(@cmd[:arguments][i])
114
+ if var.valid_syntax? @cmd[:arguments][i]
115
+ @cmd[:arguments][i] = @cmd[:arguments][i].arg_to_i
180
116
  else
181
- Error::message( 6,
182
- @line,
183
- var.error(@cmd[:arguments][i]) )
117
+ Error::message(6, @line, var.error(@cmd[:arguments][i]) )
184
118
  end
185
119
  end
186
120
  end
121
+
122
+ # Codification log of instruction
123
+ def show (i)
124
+ puts "@#{@line}:" \
125
+ "\t#{@output[i].scan(/.{4}|.+/).join("_") unless @instruction.nil?}" \
126
+ "\t#{@cmd[:comments]}"
127
+ end
128
+
129
+ # Generate output in "progfile.dat"
130
+ def generate (path)
131
+ File.open(path, "w") do |f|
132
+ @output.each do |line|
133
+ f.puts line
134
+ end
135
+ end
136
+ end
137
+
138
+ public
139
+
140
+ # Stores each new line of file
141
+ def << (value)
142
+ @input << value.strip
143
+ end
144
+
145
+ # Analyze and translate each instruction
146
+ def run (path = "progfile.dat")
147
+ find_instructions
148
+ find_labels
149
+
150
+ @input.each do |line|
151
+ if (line.instruction?) || (line.comment?)
152
+ parse_input(line)
153
+ @instruction = nil
154
+ # If it's a comment -> show but not work with it
155
+ if line.instruction?
156
+
157
+ exists_instruction?
158
+ parse_label
159
+ argument_size?
160
+ argument_syntax?
161
+
162
+ @instruction.set_arguments(@cmd[:arguments])
163
+ @output << @instruction.code
164
+ end
165
+ show(@output.size-1) if @debug
166
+ end
167
+ @line += 1
168
+ end
169
+ generate(path)
170
+ end
171
+
187
172
  end
188
173
  end
@@ -3,14 +3,15 @@ module Rips
3
3
 
4
4
  MESSAGES =
5
5
  [ "RIPS ERROR (0). Unknown problem.",
6
- "RIPS ERROR (1). No input file (try `rips file.rips`).",
6
+ "RIPS ERROR (1). Invalid input file (try `rips file.rips`).",
7
7
  "RIPS ERROR (2). Doesn't exist file or directory.",
8
8
  "RIPS ERROR (3). Permission denied to read file.",
9
9
  "RIPS ERROR (4). In line %d: doesn't exist `%s` instruction in Instruction Set.",
10
10
  "RIPS ERROR (5). In line %d: for `%s` instruction wrong number of arguments (%d for %d).",
11
11
  "RIPS ERROR (6). In line %d: syntax error, %s.",
12
12
  "RIPS ERROR (7). In line %d: There is already a label called `%s`.",
13
- "RIPS ERROR (8). In line %d: Unknown syntax for label `%s` (try `labelname:`)." ]
13
+ "RIPS ERROR (8). In line %d: Unknown syntax for label `%s` (try `labelname:`).",
14
+ "RIPS ERROR (9). Invalid output file." ]
14
15
 
15
16
  def self.message (num, *args)
16
17
  puts MESSAGES[num] % args
@@ -12,10 +12,6 @@ module Rips
12
12
  def initialize (opcode, args_number)
13
13
  @opcode, @args_number = opcode, args_number
14
14
  end
15
-
16
- # Pass all arguments at once
17
- def set_arguments (args)
18
- end
19
15
 
20
16
  end
21
17
  end
@@ -1,6 +1,11 @@
1
1
  require "rips/instructions/set"
2
2
  require "rips/formats"
3
3
  require "rips/variables"
4
+ require "rips/utils"
5
+
6
+ class Integer
7
+ include Rips::Utils::IntegerExtension
8
+ end
4
9
 
5
10
  module Rips
6
11
  module Instructions
@@ -16,15 +21,7 @@ module Rips
16
21
  @output = []
17
22
  end
18
23
 
19
- # Return number of arguments
20
- def args_number
21
- @format.args_number
22
- end
23
-
24
- # Pass all arguments at once
25
- def set_arguments (args)
26
- @format.set_arguments(args)
27
- end
24
+ private
28
25
 
29
26
  # Add blanks (0 values) for instructions with free space
30
27
  def add_blank
@@ -37,6 +34,18 @@ module Rips
37
34
  end
38
35
  end
39
36
 
37
+ public
38
+
39
+ # Return number of arguments
40
+ def args_number
41
+ @format.args_number
42
+ end
43
+
44
+ # Pass all arguments at once
45
+ def set_arguments (args)
46
+ @format.set_arguments(args)
47
+ end
48
+
40
49
  # Coding to Machine Code
41
50
  def code
42
51
 
@@ -1,18 +1,4 @@
1
- class Integer
2
- def to_bin(width)
3
- if self < 0
4
- '%0*b' % [width, (2**width-1) - ~self]
5
- else
6
- '%0*b' % [width, self]
7
- end
8
- end
9
- end
10
-
11
- class String
12
- def del(regexp)
13
- gsub(regexp,'')
14
- end
15
- def del!(regexp)
16
- gsub!(regexp,'')
17
- end
18
- end
1
+ require "rips/utils/array"
2
+ require "rips/utils/integer"
3
+ require "rips/utils/string_variable"
4
+ require "rips/utils/string_assembler"
@@ -0,0 +1,12 @@
1
+ module Rips
2
+ module Utils
3
+ module ArrayExtension
4
+
5
+ # Binary search or standard search depends version
6
+ def search(&block)
7
+ RUBY_VERSION >= "2" ? self.bsearch(&block) : self.find(&block)
8
+ end
9
+
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,15 @@
1
+ module Rips
2
+ module Utils
3
+ module IntegerExtension
4
+
5
+ def to_bin(width)
6
+ if self < 0
7
+ '%0*b' % [width, (2**width-1) - ~self]
8
+ else
9
+ '%0*b' % [width, self]
10
+ end
11
+ end
12
+
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,62 @@
1
+ require "rips/error"
2
+
3
+ module Rips
4
+ module Utils
5
+ module StringAssemblerExtension
6
+
7
+ # Delete spaces and tabs
8
+ def del(regexp)
9
+ gsub(regexp,'')
10
+ end
11
+
12
+ # Delete spaces and tabs
13
+ def del!(regexp)
14
+ gsub!(regexp,'')
15
+ end
16
+
17
+ # Return integer part of arguments of an instruction
18
+ def arg_to_i
19
+ (/\A[-]?\d+\z/ === self) ? self.to_i : self.slice(1..-1).to_i
20
+ end
21
+
22
+ # Check if string is a comment
23
+ def comment?
24
+ self[0] == "#"
25
+ end
26
+
27
+ # Check if string is a label
28
+ def label?(line)
29
+ if (!self.empty?) && (self[0] != "#") && (self[-1] == ":")
30
+ label = self.scan(/\w+:/)
31
+ if (label.size == 1)
32
+ return true
33
+ elsif (label.size > 1)
34
+ Error::message(8, line+1, self)
35
+ end
36
+ end
37
+ end
38
+
39
+ # Check if string is a instruction
40
+ def instruction?
41
+ (!self.empty?) && (self[0] != "#") && (self.scan(/\w+:/).empty?)
42
+ end
43
+
44
+ # Get intruction's name of string
45
+ def instruction_name
46
+ self.split("#").first.split(" ").first.downcase
47
+ end
48
+
49
+ # Get intruction's arguments of string
50
+ def instruction_arguments(instruction)
51
+ args = self.split("#").first.split("#{instruction} ")
52
+ args.pop.split("#").first.del(/\s+|\t+/).split(",") unless args.empty?
53
+ end
54
+
55
+ # Get intruction's comments of string
56
+ def instruction_comments
57
+ self.split("#").slice(1..-1).join
58
+ end
59
+
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,41 @@
1
+ module Rips
2
+ module Utils
3
+ module StringVariableExtension
4
+
5
+ # Check if value is a valid number (...,-1,0,1...)
6
+ def number? (value)
7
+ /\A[-]?\d+\z/ === value
8
+ end
9
+
10
+ # Check if value is between in permitted range
11
+ def valid_range? (range)
12
+ if number?(self.slice(1..-1))
13
+ self.to_i.between?(range[0], range[1])
14
+ else
15
+ self.slice(1..-1).to_i.between?(range[0], range[1])
16
+ end
17
+ end
18
+
19
+ # Check if value is a valid inmediate (...,-1,0,1...)
20
+ def inmediate?
21
+ number?(self)
22
+ end
23
+
24
+ # Check if value is a register ($0..15)
25
+ def register?
26
+ (self[0] == "$") && number?(self.slice(1..-1))
27
+ end
28
+
29
+ # Check if value is a port (@0..3)
30
+ def port?
31
+ (self[0] == "@") && number?(self.slice(1..-1))
32
+ end
33
+
34
+ # Check if value is an address (0..127 | label)
35
+ def address? (range)
36
+ (self.is_a?(String)) || (number?(self.slice(1..-1)) && valid_range?(range))
37
+ end
38
+
39
+ end
40
+ end
41
+ end
@@ -16,16 +16,11 @@ module Rips
16
16
  end
17
17
 
18
18
  # Check input variable syntax
19
- def syntax? (value)
20
-
21
- if (number?(value)) && (between?(value, @range))
22
- true
23
- elsif value.is_a?(String)
24
- true
25
- else
26
- false
27
- end
19
+ def valid_syntax? (value)
20
+ value.extend(Rips::Utils::StringVariableExtension)
21
+ value.address?(@range)
28
22
  end
23
+
29
24
  end
30
25
  end
31
26
  end
@@ -16,14 +16,9 @@ module Rips
16
16
  end
17
17
 
18
18
  # Check input variable syntax
19
- def syntax? (value)
20
-
21
- # It should be between syntax range
22
- if number?(value) && between?(value, @range)
23
- true
24
- else
25
- false
26
- end
19
+ def valid_syntax? (value)
20
+ value.extend(Rips::Utils::StringVariableExtension)
21
+ value.inmediate? && value.valid_range?(@range)
27
22
  end
28
23
 
29
24
  end
@@ -11,20 +11,14 @@ module Rips
11
11
  # @range: bit's range for variable
12
12
  def initialize(size = 2)
13
13
  super(size)
14
- @syntax = "@0-3"
15
14
  @range = [0, 2**@length-1]
16
15
  @syntax = "@#{@range[0]}-#{@range[1]}"
17
16
  end
18
17
 
19
18
  # Check input variable syntax
20
- def syntax? (value)
21
-
22
- # It should be between syntax range
23
- if port?(value) && between?(value, @range)
24
- true
25
- else
26
- false
27
- end
19
+ def valid_syntax? (value)
20
+ value.extend(Rips::Utils::StringVariableExtension)
21
+ value.port? && value.valid_range?(@range)
28
22
  end
29
23
 
30
24
  end
@@ -16,14 +16,9 @@ module Rips
16
16
  end
17
17
 
18
18
  # Check input variable syntax
19
- def syntax? (value)
20
-
21
- # It should be between syntax range
22
- if register?(value) && between?(value, @range)
23
- true
24
- else
25
- false
26
- end
19
+ def valid_syntax? (value)
20
+ value.extend(Rips::Utils::StringVariableExtension)
21
+ value.register? && value.valid_range?(@range)
27
22
  end
28
23
 
29
24
  end
@@ -1,3 +1,5 @@
1
+ require "rips/utils"
2
+
1
3
  module Rips
2
4
  module Variables
3
5
 
@@ -10,35 +12,11 @@ module Rips
10
12
  @length = length
11
13
  end
12
14
 
13
- # Check if value is a register ($0..15)
14
- def register? (value)
15
- (value[0] == "$") && number?(value.slice(1..-1))
16
- end
17
-
18
- # Check if value is a port (@0..3)
19
- def port? (value)
20
- (value[0] == "@") && number?(value.slice(1..-1))
21
- end
22
-
23
- # Check if value is a valid number (...,-1,0,1...)
24
- def number? (value)
25
- /\A[-]?\d+\z/ === value
26
- end
27
-
28
- # Check if value is between in permitted range
29
- def between? (value, range)
30
- to_i(value).between?(range[0], range[1])
31
- end
32
-
33
- # Return integer part of value
34
- def to_i (value)
35
- number?(value) ? value.to_i : value.slice(1..-1).to_i
36
- end
37
-
38
15
  # Return error message about incorrent syntax
39
16
  def error (value)
40
17
  "unexpected `#{value}` (expected a `#{self.class.to_s.split(':').last}` argument like `#{@syntax}`)"
41
- end
18
+ end
19
+
42
20
  end
43
21
  end
44
22
  end
@@ -1,3 +1,3 @@
1
1
  module Rips
2
- VERSION = "0.0.8"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -22,5 +22,5 @@ Gem::Specification.new do |spec|
22
22
  spec.add_development_dependency "rake", "~> 10.0"
23
23
  spec.add_development_dependency 'rspec'
24
24
 
25
- spec.required_ruby_version = '>= 2.0'
25
+ spec.required_ruby_version = '>= 1.9.3'
26
26
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rips
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.8
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Madh93
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-04-14 00:00:00.000000000 Z
11
+ date: 2015-05-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -67,7 +67,8 @@ files:
67
67
  - README.md
68
68
  - Rakefile
69
69
  - bin/rips
70
- - example.rips
70
+ - examples/calc.rips
71
+ - examples/example.rips
71
72
  - lib/rips.rb
72
73
  - lib/rips/assembler.rb
73
74
  - lib/rips/error.rb
@@ -99,6 +100,10 @@ files:
99
100
  - lib/rips/instructions/set.rb
100
101
  - lib/rips/instructions/sub.rb
101
102
  - lib/rips/utils.rb
103
+ - lib/rips/utils/array.rb
104
+ - lib/rips/utils/integer.rb
105
+ - lib/rips/utils/string_assembler.rb
106
+ - lib/rips/utils/string_variable.rb
102
107
  - lib/rips/variables.rb
103
108
  - lib/rips/variables/address.rb
104
109
  - lib/rips/variables/inmediate.rb
@@ -121,7 +126,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
121
126
  requirements:
122
127
  - - ">="
123
128
  - !ruby/object:Gem::Version
124
- version: '2.0'
129
+ version: 1.9.3
125
130
  required_rubygems_version: !ruby/object:Gem::Requirement
126
131
  requirements:
127
132
  - - ">="