package Camila::caller;

use Camila::grammar;
use Data::Dumper;

require 5.6.0;
use strict;
use warnings;
use Carp;

require Exporter;
require DynaLoader;
use AutoLoader;

our @ISA = qw(Exporter DynaLoader);

# Items to export into callers namespace by default. Note: do not export
# names by default without a very good reason. Use EXPORT_OK instead.
# Do not simply export all your public functions/methods/constants.

# This allows declaration	use Camila::caller ':all';
# If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
# will save memory.
our %EXPORT_TAGS = ( 'all' => [ qw() ] );
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
our @EXPORT = qw();
our $VERSION = 0.01;

sub AUTOLOAD {
    my $constname;
    our $AUTOLOAD;
    ($constname = $AUTOLOAD) =~ s/.*:://;
    croak "& not defined" if $constname eq 'constant';
    my $val = constant($constname, @_ ? $_[0] : 0);
    if ($! != 0) {
	if ($! =~ /Invalid/ || $!{EINVAL}) {
	    $AutoLoader::AUTOLOAD = $AUTOLOAD;
	    goto &AutoLoader::AUTOLOAD;
	}
	else {
	    croak "Your vendor has not defined Camila::caller macro $constname";
	}
    }
    {
	no strict 'refs';
	# Fixed between 5.005_53 and 5.005_61
	if ($] >= 5.00561) {
	    *$AUTOLOAD = sub () { $val };
	}
	else {
	    *$AUTOLOAD = sub { $val };
	}
    }
    goto &$AUTOLOAD;
}

bootstrap Camila::caller $VERSION;

sub parse_string {
  my $string = shift;
  my $parser = new Camila::grammar;
  p_scan_string($string);
  $parser->YYParse(yylex   => \&Camila::caller::yylex,
		   yyerror => \&Camila::caller::yyerror);
  return $parser;
}
sub parse {
  my $parser = new Camila::grammar;
  $parser->YYParse(yylex   => \&Camila::caller::yylex,
		   yyerror => \&Camila::caller::yyerror);
  return $parser;
}

sub yylex {
    my ($a,$b) = (plex(),plextext());
    return ($a,$b) if $a;
    return ('',$b);
}

sub yyerror {
  my $msg = shift;
  # print STDERR Dumper($msg);
  my $lineno = plexlineno();
  my $text = plextext();

  my $found = $msg->YYCurtok;
  my @expect = $msg->YYExpect();
  my $expect = join(" or ",map {"'$_'"} @expect);
  warn "Found '$found' and expecting $expect at line $lineno\n"; # near '$text'.\n";
}


1;
__END__

