Devel-Optic

 view release on metacpan or  search on metacpan

lib/Devel/Optic/Lens/Perlish/Interpreter.pm  view on Meta::CPAN

package Devel::Optic::Lens::Perlish::Interpreter;
$Devel::Optic::Lens::Perlish::Interpreter::VERSION = '0.015';
# ABSTRACT: Basic recursive interpreter for Perlish lens

use strict;
use warnings;

use Exporter qw(import);
our @EXPORT_OK = qw(run);

use Carp qw(croak);
our @CARP_NOT = qw(Devel::Optic::Lens::Perlish Devel::Optic);

use Devel::Optic::Lens::Perlish::Constants qw(:all);

use Scalar::Util qw(looks_like_number);
use Ref::Util qw(is_arrayref is_hashref is_refref is_scalarref is_ref);

sub run {
    my ($scope, $ast) = @_;
    my ($type, $payload) = @$ast;
    if ($type eq OP_ACCESS) {
        return _access($scope, undef, $ast, $payload);
    }

    if ($type eq SYMBOL) {
        return _symbol($scope, $payload);
    }

    croak sprintf("invalid query: %s does not start with access or symbol",
        _ast_to_code($ast),
    );
}

sub _access {
    my ($scope, $parent, $self, $children) = @_;

    my ($left, $right) = @$children;

    my ($l_arg, $r_arg);
    my ($l_type, $l_val) = @$left;
    my ($r_type, $r_val) = @$right;

    if ($l_type eq SYMBOL) {
        $l_arg = _symbol($scope, $l_val);
    }

    if ($l_type eq OP_ACCESS) {
        $l_arg = _access($scope, $self, $left, $l_val);
    }

    if ($r_type eq OP_ACCESS) {
        die "an access can't be followed directly by another access. the parser admitted an invalid program. please report this!";
    }

    if ($r_type eq OP_HASHKEY) {
        return _hashkey($scope, $self, $left, $right, $l_arg, $r_val);
    }

    if ($r_type eq OP_ARRAYINDEX) {
        return _arrayindex($scope, $self, $left, $right, $l_arg, $r_val, $left);
    }
}

sub _arrayindex {
    my ($scope, $access_node, $array_node, $index_node, $arrayref, $child) = @_;
    my ($type, $value) = @$child;

    if (!is_arrayref($arrayref)) {
        croak sprintf("invalid array access: '%s' is %s, not array",
            _ast_to_code($array_node),
            _sample_or_ref($arrayref),
        );
    }

    if ($type eq STRING) {
        croak sprintf("invalid array access: can't index '%s' with string '%s'",



( run in 2.787 seconds using v1.01-cache-2.11-cpan-364913b4093 )