CPU-Z80-Assembler

 view release on metacpan or  search on metacpan

lib/CPU/Z80/Assembler/Program.pm  view on Meta::CPAN

		$args{_segment_id},				# index of the current segment
		$args{_segment_map}	|| {}, 		# map segment name => index in child
		$args{child} 		|| [], 		# list of segments
		$args{symbols}		|| {},		# map name => Node with evaluate() method
		$args{macros}		|| {},		# list of defined macros
	], $class;
}
sub _segment_id		{ defined($_[1]) ? $_[0][0] = $_[1] : $_[0][0] }
sub _segment_map	{ defined($_[1]) ? $_[0][1] = $_[1] : $_[0][1] }
sub child 			{ defined($_[1]) ? $_[0][2] = $_[1] : $_[0][2] }
sub symbols 		{ defined($_[1]) ? $_[0][3] = $_[1] : $_[0][3] }
sub macros 			{ defined($_[1]) ? $_[0][4] = $_[1] : $_[0][4] }

#------------------------------------------------------------------------------

=head1 SYNOPSIS

  use CPU::Z80::Assembler::Program;
  my $program = CPU::Z80::Assembler::Program->new(
                    symbols => {},
                    macros  => {});
  $program->parse($input);
  $segment = $program->segment;
  $segment = $program->segment("CODE");
  $segment = $program->split_segment;
  $program->add_opcodes(@opcodes);
  $program->add_label($name, $line);
  $program->org($address);
  $bytes = $program->bytes;
  $list_output = CPU::Z80::Assembler::List->new(input => \@input, output => \*STDOUT);
  $bytes = $program->bytes($list_output);

=head1 DESCRIPTION

This module defines the class that represents one assembly program composed of
L<CPU::Z80::Assembler::Segment|CPU::Z80::Assembler::Segment>.

=head1 EXPORTS

Nothing.

=head1 FUNCTIONS

=head2 new

Creates a new object, see L<Class::Struct|Class::Struct>.

=head2 child

Each child is one L<CPU::Z80::Assembler::Segment|CPU::Z80::Assembler::Segment> object, in the order found in the
program.

=head2 symbols

Hash of all symbols defined in the program. The key is the symbol name, and 
the value is either a scalar for a constant, a L<CPU::Z80::Assembler::Expr|CPU::Z80::Assembler::Expr> for 
an expression, or a L<CPU::Z80::Assembler::Opcode|CPU::Z80::Assembler::Opcode> for a label.

=head2 macros

Hash of macro names to L<CPU::Z80::Assembler::Macro|CPU::Z80::Assembler::Macro> objects for all defined macros.

=cut

#------------------------------------------------------------------------------

=head2 parse

  $program->parse($input);

Parse the assembly program and collect the opcodes into the object. $input is
a stream of tokens as retrieved by L<CPU::Z80::Assembler|CPU::Z80::Assembler>
C<z80lexer>.

=cut

#------------------------------------------------------------------------------

sub parse { my($self, $input) = @_;
	z80parser($input, $self);
}

#------------------------------------------------------------------------------

=head2 segment

Get/Set the current segment. The current segment is the one where new opcodes 
are added.

When called without arguments returns a L<CPU::Z80::Assembler::Segment|CPU::Z80::Assembler::Segment> object
of the current segment.

When called with a $name, it sets the segment with the given name as current.
If no such segment exists, a new segment with that name is appended to the list
and set current.

=cut

#------------------------------------------------------------------------------

sub segment { 
	my($self, $name) = @_;
	
	if (defined($name) || @{$self->child} == 0) {
		# set or get but still no segments -> create
		$name = "_" unless defined($name);
		
		my $id = $self->_segment_map->{$name};

		if (! defined $id) {
			# new segment
			$id = @{$self->child}; 				# index of new segment
			my $segment = CPU::Z80::Assembler::Segment->new(name => $name);
			push(@{$self->child}, $segment);
			
			$self->_segment_map->{$name} = $id;
		}
		# segment exists
		$self->_segment_id( $id );
		return $self->child->[$id];
	}



( run in 0.419 second using v1.01-cache-2.11-cpan-ceb78f64989 )