Class: C64Asm::Macro

Inherits:
Object
  • Object
show all
Defined in:
lib/c64asm/asm.rb

Overview

Macro is the top-level building block

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(vars = {}, &blk) ⇒ Macro

Create new macro You can supply a hash of default variables that will be available within the block.



633
634
635
636
637
638
# File 'lib/c64asm/asm.rb', line 633

def initialize(vars = {}, &blk)
  @variables = vars
  @procs = []

  @procs.push(blk) if blk
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args, &blk) ⇒ Object (private)

The DSL happens here



713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
# File 'lib/c64asm/asm.rb', line 713

def method_missing(name, *args, &blk)
  name = :and if name == :ane
  if OP_CODES.has_key? name
    begin
      if args.length == 0
        op = Operand.new(name)
      else
        arg = args.first
        mod = args[1] or false
        op = Operand.new(name, arg, mod)
      end
    rescue OperandError => e
      parse_error "Operand error: #{e.to_s}"
    end
    @code.push(op)
    op
  elsif @vars.has_key? name
    @vars[name]
  else
    parse_error "Method :#{name} not found"
  end
end

Instance Attribute Details

#variablesObject (readonly)

Returns the value of attribute variables.



629
630
631
# File 'lib/c64asm/asm.rb', line 629

def variables
  @variables
end

Instance Method Details

#add_code(&blk) ⇒ Object

Add more code to a block



641
# File 'lib/c64asm/asm.rb', line 641

def add_code(&blk); @procs.push(blk); end

#align(addr) ⇒ Object (private)

Add alignment nop



666
667
668
669
670
671
672
673
# File 'lib/c64asm/asm.rb', line 666

def align(addr)
  begin
    @code.push(Align.new(addr))
  rescue AlignError => e
    parse_error "Align instruction error: #{e.to_s}"
  end
  addr
end

#block(stuff) ⇒ Object (private)

Add block nop



699
700
701
702
703
# File 'lib/c64asm/asm.rb', line 699

def block(stuff)
  parse_error 'Block not an instance of Block' unless stuff.instance_of? Block
  @code.push(stuff)
  stuff.length
end

#call(vars = {}) ⇒ Object

Return a block from the macro given variables

Raises:



647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
# File 'lib/c64asm/asm.rb', line 647

def call(vars = {})
  return Block.new if @procs.empty?

  @code = Block.new
  @labels = []

  # check for extraneous variables
  extra = vars.keys - @variables.keys
  raise MacroError, "Extraneous variables #{extra.join(', ')}" unless extra.empty?

  # merge variable hash
  @vars = @variables.merge(vars)

  @procs.each{|b| instance_eval(&b)}
  @code
end

#data(arg, mode = :default) ⇒ Object (private)

Add data nop



688
689
690
691
692
693
694
695
696
# File 'lib/c64asm/asm.rb', line 688

def data(arg, mode = :default)
  begin
    data = Data.new(arg, mode)
    @code.push(data)
  rescue DataError => e
    parse_error "Data instruction error: #{e.to_s}"
  end
  data.length
end

#insert(stuff) ⇒ Object (private)

Add more code



706
707
708
709
710
# File 'lib/c64asm/asm.rb', line 706

def insert(stuff)
  parse_error 'Block not an instance of Block' unless stuff.instance_of? Block
  @code += stuff
  stuff.length
end

#label(name) ⇒ Object (private)

Add label nop



676
677
678
679
680
681
682
683
684
685
# File 'lib/c64asm/asm.rb', line 676

def label(name)
  parse_warn "Redefinition of label #{name}" if @labels.member? name
  begin
    @code.push(Label.new(name))
  rescue LabelError => e
    parse_error "Label instruction error: #{e.to_s}"
  end
  @labels.push(name)
  name
end

#parse_error(msg) ⇒ Object (private)

Parse error logging helper

Raises:



743
744
745
746
# File 'lib/c64asm/asm.rb', line 743

def parse_error(msg)
  say :error, msg
  raise MacroError
end

#parse_warn(msg) ⇒ Object (private)

Parse error logging helper



749
# File 'lib/c64asm/asm.rb', line 749

def parse_warn(msg); say :warn, msg; end

#say(level, msg) ⇒ Object (private)

General logging helper



737
738
739
740
# File 'lib/c64asm/asm.rb', line 737

def say(level, msg)
  from = caller[2].match(/.*?\:\d+/)[0]
  C64Asm.log level, "(#{from}) #{msg}"
end

#to_sObject

Return pretty string representation



644
# File 'lib/c64asm/asm.rb', line 644

def to_s; "<Macro #{@procs.length} #{@variables.to_s}>"; end