mirror of
https://github.com/safiire/n65.git
synced 2025-01-05 16:31:31 +00:00
Linting is somewhat better in n64.rb now
This commit is contained in:
parent
fdc3317c12
commit
520a5198af
120
.rubocop.yml
120
.rubocop.yml
@ -1,6 +1,122 @@
|
|||||||
|
|
||||||
Layout/LineLength:
|
Layout/LineLength:
|
||||||
Max: 120
|
Max: 120
|
||||||
|
|
||||||
Naming/MethodParameterName:
|
Naming/MethodParameterName:
|
||||||
MinArgNameLength: 1
|
MinNameLength: 1
|
||||||
|
|
||||||
|
Style/FormatStringToken:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Style/Documentation:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Layout/EmptyLinesAroundAttributeAccessor:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Layout/SpaceAroundMethodCallOperator:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Lint/BinaryOperatorWithIdenticalOperands:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Lint/DeprecatedOpenSSLConstant:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Lint/DuplicateElsifCondition:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Lint/DuplicateRescueException:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Lint/EmptyConditionalBody:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Lint/FloatComparison:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Lint/MissingSuper:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Lint/MixedRegexpCaptureTypes:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Lint/OutOfRangeRegexpRef:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Lint/RaiseException:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Lint/SelfAssignment:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Lint/StructNewOverride:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Lint/TopLevelReturnWithArgument:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Lint/UnreachableLoop:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Style/AccessorGrouping:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Style/ArrayCoercion:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Style/BisectedAttrAccessor:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Style/CaseLikeIf:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Style/ExplicitBlockArgument:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Style/ExponentialNotation:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Style/GlobalStdStream:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Style/HashAsLastArrayItem:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Style/HashEachMethods:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Style/HashLikeCase:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Style/HashTransformKeys:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Style/HashTransformValues:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Style/OptionalBooleanParameter:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Style/RedundantAssignment:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Style/RedundantFetchBlock:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Style/RedundantFileExtensionInRequire:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Style/RedundantRegexpCharacterClass:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Style/RedundantRegexpEscape:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Style/SingleArgumentDig:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Style/SlicingWithRange:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Style/StringConcatenation:
|
||||||
|
Enabled: true
|
||||||
|
68
lib/n65.rb
68
lib/n65.rb
@ -1,10 +1,11 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require_relative 'n65/version'
|
require_relative 'n65/version'
|
||||||
require_relative 'n65/symbol_table'
|
require_relative 'n65/symbol_table'
|
||||||
require_relative 'n65/memory_space'
|
require_relative 'n65/memory_space'
|
||||||
require_relative 'n65/parser'
|
require_relative 'n65/parser'
|
||||||
|
|
||||||
module N65
|
module N65
|
||||||
|
|
||||||
class Assembler
|
class Assembler
|
||||||
attr_reader :program_counter, :current_segment, :current_bank, :symbol_table, :virtual_memory, :promises
|
attr_reader :program_counter, :current_segment, :current_bank, :symbol_table, :virtual_memory, :promises
|
||||||
|
|
||||||
@ -15,10 +16,11 @@ module N65
|
|||||||
class FileNotFound < StandardError; end
|
class FileNotFound < StandardError; end
|
||||||
|
|
||||||
# Assemble from an asm file to a nes ROM
|
# Assemble from an asm file to a nes ROM
|
||||||
|
# TODO: This reall needs a logger instead of all these unless quiet conditions
|
||||||
def self.from_file(infile, options)
|
def self.from_file(infile, options)
|
||||||
raise(FileNotFound, infile) unless File.exists?(infile)
|
raise(FileNotFound, infile) unless File.exist?(infile)
|
||||||
|
|
||||||
assembler = self.new
|
assembler = new
|
||||||
program = File.read(infile)
|
program = File.read(infile)
|
||||||
output_file = options[:output_file]
|
output_file = options[:output_file]
|
||||||
|
|
||||||
@ -28,7 +30,7 @@ module N65
|
|||||||
begin
|
begin
|
||||||
assembler.assemble_one_line(line)
|
assembler.assemble_one_line(line)
|
||||||
rescue StandardError => e
|
rescue StandardError => e
|
||||||
STDERR.puts("\n\n#{e.class}\n#{line}\n#{e}\nOn line #{line_number}")
|
warn("\n\n#{e.class}\n#{line}\n#{e}\nOn line #{line_number}")
|
||||||
exit(1)
|
exit(1)
|
||||||
end
|
end
|
||||||
print '.' unless options[:quiet]
|
print '.' unless options[:quiet]
|
||||||
@ -36,9 +38,9 @@ module N65
|
|||||||
puts unless options[:quiet]
|
puts unless options[:quiet]
|
||||||
|
|
||||||
# Second pass to resolve any missing symbols.
|
# Second pass to resolve any missing symbols.
|
||||||
print "Second pass, resolving symbols..." unless options[:quiet]
|
print 'Second pass, resolving symbols...' unless options[:quiet]
|
||||||
assembler.fulfill_promises
|
assembler.fulfill_promises
|
||||||
puts " Done." unless options[:quiet]
|
puts ' Done.' unless options[:quiet]
|
||||||
|
|
||||||
# Optionally write out a symbol map
|
# Optionally write out a symbol map
|
||||||
if options[:write_symbol_table]
|
if options[:write_symbol_table]
|
||||||
@ -46,7 +48,7 @@ module N65
|
|||||||
File.open("#{output_file}.yaml", 'w') do |fp|
|
File.open("#{output_file}.yaml", 'w') do |fp|
|
||||||
fp.write(assembler.symbol_table.export_to_yaml)
|
fp.write(assembler.symbol_table.export_to_yaml)
|
||||||
end
|
end
|
||||||
puts "Done." unless options[:quiet]
|
puts 'Done.' unless options[:quiet]
|
||||||
end
|
end
|
||||||
|
|
||||||
# Optionally write out cycle count for subroutines
|
# Optionally write out cycle count for subroutines
|
||||||
@ -55,7 +57,7 @@ module N65
|
|||||||
File.open("#{output_file}.cycles.yaml", 'w') do |fp|
|
File.open("#{output_file}.cycles.yaml", 'w') do |fp|
|
||||||
fp.write(assembler.symbol_table.export_cycle_count_yaml)
|
fp.write(assembler.symbol_table.export_cycle_count_yaml)
|
||||||
end
|
end
|
||||||
puts "Done." unless options[:quiet]
|
puts 'Done.' unless options[:quiet]
|
||||||
end
|
end
|
||||||
|
|
||||||
# Emit the complete binary ROM
|
# Emit the complete binary ROM
|
||||||
@ -64,12 +66,12 @@ module N65
|
|||||||
fp.write(rom)
|
fp.write(rom)
|
||||||
end
|
end
|
||||||
|
|
||||||
unless options[:quiet]
|
return if options[:quiet]
|
||||||
rom_size = rom.size
|
|
||||||
rom_size_hex = "%x" % rom_size
|
rom_size = rom.size
|
||||||
assembler.print_bank_usage
|
rom_size_hex = format('%x', rom_size)
|
||||||
puts "Total size: $#{rom_size_hex}, #{rom_size} bytes"
|
assembler.print_bank_usage
|
||||||
end
|
puts "Total size: $#{rom_size_hex}, #{rom_size} bytes"
|
||||||
end
|
end
|
||||||
|
|
||||||
# Initialize with a bank 1 of prog space for starters
|
# Initialize with a bank 1 of prog space for starters
|
||||||
@ -81,8 +83,8 @@ module N65
|
|||||||
@symbol_table = SymbolTable.new
|
@symbol_table = SymbolTable.new
|
||||||
@promises = []
|
@promises = []
|
||||||
@virtual_memory = {
|
@virtual_memory = {
|
||||||
:prog => [MemorySpace.create_prog_rom],
|
prog: [MemorySpace.create_prog_rom],
|
||||||
:char => []
|
char: []
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -90,7 +92,12 @@ module N65
|
|||||||
def get_current_state
|
def get_current_state
|
||||||
saved_program_counter, saved_segment, saved_bank = @program_counter, @current_segment, @current_bank
|
saved_program_counter, saved_segment, saved_bank = @program_counter, @current_segment, @current_bank
|
||||||
saved_scope = symbol_table.scope_stack.dup
|
saved_scope = symbol_table.scope_stack.dup
|
||||||
OpenStruct.new(program_counter: saved_program_counter, segment: saved_segment, bank: saved_bank, scope: saved_scope)
|
OpenStruct.new(
|
||||||
|
program_counter: saved_program_counter,
|
||||||
|
segment: saved_segment,
|
||||||
|
bank: saved_bank,
|
||||||
|
scope: saved_scope
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Set the current state from an OpenStruct
|
# Set the current state from an OpenStruct
|
||||||
@ -106,21 +113,20 @@ module N65
|
|||||||
# with only comments parse to nil, and we just ignore them.
|
# with only comments parse to nil, and we just ignore them.
|
||||||
def assemble_one_line(line)
|
def assemble_one_line(line)
|
||||||
parsed_object = Parser.parse(line)
|
parsed_object = Parser.parse(line)
|
||||||
|
return if parsed_object.nil?
|
||||||
|
|
||||||
unless parsed_object.nil?
|
exec_result = parsed_object.exec(self)
|
||||||
exec_result = parsed_object.exec(self)
|
|
||||||
|
|
||||||
# TODO: I could perhaps keep a tally of cycles used per top level scope here
|
# TODO: I could perhaps keep a tally of cycles used per top level scope here
|
||||||
if parsed_object.respond_to?(:cycles)
|
if parsed_object.respond_to?(:cycles)
|
||||||
# puts "Line: #{line}"
|
# puts "Line: #{line}"
|
||||||
# puts "Cycles #{parsed_object.cycles}"
|
# puts "Cycles #{parsed_object.cycles}"
|
||||||
# puts "Sym: #{@symbol_table.scope_stack}"
|
# puts "Sym: #{@symbol_table.scope_stack}"
|
||||||
@symbol_table.add_cycles(parsed_object.cycles)
|
@symbol_table.add_cycles(parsed_object.cycles)
|
||||||
end
|
|
||||||
|
|
||||||
# If we have returned a promise save it for the second pass
|
|
||||||
@promises << exec_result if exec_result.is_a?(Proc)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# If we have returned a promise save it for the second pass
|
||||||
|
@promises << exec_result if exec_result.is_a?(Proc)
|
||||||
end
|
end
|
||||||
|
|
||||||
# This will empty out our promise queue and try to fullfil operations
|
# This will empty out our promise queue and try to fullfil operations
|
||||||
@ -179,9 +185,7 @@ module N65
|
|||||||
# Set the current bank, create it if it does not exist
|
# Set the current bank, create it if it does not exist
|
||||||
def current_bank=(bank_number)
|
def current_bank=(bank_number)
|
||||||
memory_space = get_virtual_memory_space(@current_segment, bank_number)
|
memory_space = get_virtual_memory_space(@current_segment, bank_number)
|
||||||
if memory_space.nil?
|
@virtual_memory[@current_segment][bank_number] = MemorySpace.create_bank(@current_segment) if memory_space.nil?
|
||||||
@virtual_memory[@current_segment][bank_number] = MemorySpace.create_bank(@current_segment)
|
|
||||||
end
|
|
||||||
@current_bank = bank_number
|
@current_bank = bank_number
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user