rips 0.0.8 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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
  - - ">="