CPU-Z80-Assembler

 view release on metacpan or  search on metacpan

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

#------------------------------------------------------------------------------
# $Id$
# Parser 'CPU::Z80::Assembler::Parser' generated by ParserGenerator.pm

package CPU::Z80::Assembler::Parser;

use strict;
use warnings;

use Data::Dump 'dump';
use Iterator::Simple::Lookahead;
use Asm::Preproc::Token;
use Carp;

use constant {
	ARGS => 0, PROG => 1, INPUT => 2,		# to decode args in parser functions
};


our $VERSION = '2.25';

use CPU::Z80::Assembler;
use CPU::Z80::Assembler::Expr;
use CPU::Z80::Assembler::Macro;
use CPU::Z80::Assembler::Opcode;
use CPU::Z80::Assembler::JumpOpcode;
use Asm::Preproc::Token;

use base "Exporter";
our @EXPORT = qw( z80parser );

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

=head1 NAME

CPU::Z80::Assembler::Parser - Parser for the Z80 assembler

=head1 SYNOPSIS

  use CPU::Z80::Assembler::Parser;
  z80parser($input, $program);

=head1 DESCRIPTION

This module converts an input stream of tokens returned by the
L<CPU::Z80::Assembler|CPU::Z80::Assembler> C<z80lexer> to a binary object code
that is returned in the
passed L<CPU::Z80::Assembler::Program|CPU::Z80::Assembler::Program> object.

=head1 EXPORTS

By default the z80parser subroutines is exported.

=head1 FUNCTIONS

=head2 z80parser

This function is just a wrapper around the parse function.
It takes as parameter a stream of assembly tokens as returned by the 
lexer and a L<CPU::Z80::Assembler::Program|CPU::Z80::Assembler::Program> object to collect the 
object code.

The assembly program is parsed and loaded into L<CPU::Z80::Assembler::Program|CPU::Z80::Assembler::Program>.

=cut

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



#------------------------------------------------------------------------------
# Parsing state machine
# Each state hash has:
# 	terminal => (state ID), for a shift
# 	terminal => [ (subrule ID), (next state ID) ], for a sub-rule followed by a shift
# 	terminal => [ (subrule ID), sub{} ], for a sub-rule followed by an accept
# 	terminal => sub{}, for an accept
# Each sub{} is called with $sub->($args, $user); 
# $args is [] of all parsed elements
# $user is the user pointer passed to parse()
our $start_state = 3903;
our @state_table = (
	# [0] 
	{ binop => 1, cont_expr_N => 2, def_label => 4, end => 9, expr => 10, expr2 => 12, expr_DIS => 14, expr_N => 15, expr_NDIS => 16, expr_NN => 17, expr_const => 18, expr_list => 19, expr_list_N => 21, expr_list_NN => 22, expr_list_text => 23, expr_lis...

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

		return \@bytes;
	}
}
# expr_text_number : NUMBER
sub _action_expr_text_number_16 {
	my @bytes;
	my $value = eval($_[ARGS][0]->value); $@ and die $@; # ASSERT
	while ($value) {
		unshift(@bytes, $value & 0xFF);
		$value >>= 8;
	}
	return \@bytes;
}
# expr_text_string : STRING
sub _action_expr_text_string_15 {
	my @bytes = map {ord($_)} split(//, $_[ARGS][0]->value);
	return \@bytes;
}
# expr_textz : "[expr_text]"
sub _action_expr_textz_18 {
	my @bytes = ( @{ $_[ARGS][0] }, 0 );
	return \@bytes;
}
# inline_const : "[expr]"
sub _action_inline_const_14 {
	my $expr = CPU::Z80::Assembler::Expr->new(
				child 	=> $_[ARGS][0],
				line	=> $_[ARGS][0][0]->line);
	my $value = $expr->evaluate();
	$_[INPUT]->unget(Asm::Preproc::Token->new($value,
											  $value,
											  $expr->line));
	return 0;	# return dummy value to keep index into values correct
}
# macro : macro NAME "[macro_args_optional]" "[macro_body]"
sub _action_macro_28 {
	my $name = $_[ARGS][1]->value;
	exists $_[PROG]->macros->{$name}
		and $_[ARGS][1]->error("macro $name redefined");

	my $macro = $_[ARGS][3];
	$macro->name(   $name );
	$macro->params( $_[ARGS][2] );
	$_[PROG]->macros->{$name} = $macro;
}
# macro_arg2 : "," NAME
sub _action_macro_arg2_25 {
	$_[ARGS][1]->value
}
# macro_arg : NAME
sub _action_macro_arg_24 {
	$_[ARGS][0]->value
}
# macro_args_optional : "[macro_args]?"
sub _action_macro_args_optional_26 {
	defined($_[ARGS][0]) ? $_[ARGS][0] : []
}
# macro_body : "{"
sub _action_macro_body_27 {
	$_[INPUT]->unget($_[ARGS][0]);		# push back starting token
	my $macro = CPU::Z80::Assembler::Macro->new();
	$macro->parse_body($_[INPUT]);
	return $macro;
}
# opcode : bit "[inline_const]" 0 "," "(" iy "+" "[expr_DIS]" ")" "[end]"
sub _action_opcode_100 {
	_add_opcode(@_, 0xFD, 0xCB, $_[ARGS][7], 0x46);
}
# opcode : res "[inline_const]" 4 "," "(" iy ")" "," h "[end]"
sub _action_opcode_1000 {
	_add_opcode(@_, 0xFD, 0xCB, 0x00, 0xA4);
}
# opcode : res "[inline_const]" 4 "," "(" iy ")" "," l "[end]"
sub _action_opcode_1001 {
	_add_opcode(@_, 0xFD, 0xCB, 0x00, 0xA5);
}
# opcode : res "[inline_const]" 4 "," "(" iy "+" "[expr_DIS]" ")" "[end]"
sub _action_opcode_1002 {
	_add_opcode(@_, 0xFD, 0xCB, $_[ARGS][7], 0xA6);
}
# opcode : res "[inline_const]" 4 "," "(" iy "+" "[expr_DIS]" ")" "," a "[end]"
sub _action_opcode_1003 {
	_add_opcode(@_, 0xFD, 0xCB, $_[ARGS][7], 0xA7);
}
# opcode : res "[inline_const]" 4 "," "(" iy "+" "[expr_DIS]" ")" "," b "[end]"
sub _action_opcode_1004 {
	_add_opcode(@_, 0xFD, 0xCB, $_[ARGS][7], 0xA0);
}
# opcode : res "[inline_const]" 4 "," "(" iy "+" "[expr_DIS]" ")" "," c "[end]"
sub _action_opcode_1005 {
	_add_opcode(@_, 0xFD, 0xCB, $_[ARGS][7], 0xA1);
}
# opcode : res "[inline_const]" 4 "," "(" iy "+" "[expr_DIS]" ")" "," d "[end]"
sub _action_opcode_1006 {
	_add_opcode(@_, 0xFD, 0xCB, $_[ARGS][7], 0xA2);
}
# opcode : res "[inline_const]" 4 "," "(" iy "+" "[expr_DIS]" ")" "," e "[end]"
sub _action_opcode_1007 {
	_add_opcode(@_, 0xFD, 0xCB, $_[ARGS][7], 0xA3);
}
# opcode : res "[inline_const]" 4 "," "(" iy "+" "[expr_DIS]" ")" "," h "[end]"
sub _action_opcode_1008 {
	_add_opcode(@_, 0xFD, 0xCB, $_[ARGS][7], 0xA4);
}
# opcode : res "[inline_const]" 4 "," "(" iy "+" "[expr_DIS]" ")" "," l "[end]"
sub _action_opcode_1009 {
	_add_opcode(@_, 0xFD, 0xCB, $_[ARGS][7], 0xA5);
}
# opcode : bit "[inline_const]" 0 "," a "[end]"
sub _action_opcode_101 {
	_add_opcode(@_, 0xCB, 0x47);
}
# opcode : res "[inline_const]" 4 "," a "[end]"
sub _action_opcode_1010 {
	_add_opcode(@_, 0xCB, 0xA7);
}
# opcode : res "[inline_const]" 4 "," b "[end]"
sub _action_opcode_1011 {
	_add_opcode(@_, 0xCB, 0xA0);
}
# opcode : res "[inline_const]" 4 "," c "[end]"



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