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 )