#!/usr/bin/env perl use strict; use warnings; use lib 'lib'; use Sexp::Tiny::Grammar (); use Data::Dump qw(dd); use Scalar::Util qw(blessed); my $src = q{(acme (pi "3.14")(nose "cuke"))}; dd $src; my $r = Sexp::Tiny::Grammar::build_reader(); dd ref($r); $r->read( \$src ); my $ast_ref = $r->value; dd $ast_ref; sub is_qstr { my ($v) = @_; return blessed($v) && $v->isa('Sexp::Tiny::String'); } sub unwrap_qstr { my ( $v, $path ) = @_; if ( is_qstr($v) ) { warn "[unwrap] $path: ", ref($v), qq{ -> plain perl string "}, $v->value, qq{"\n}; return $v->value; } return $v; } sub maybe_number { my ( $v, $path ) = @_; return $v if ref $v; if ( defined($v) && $v =~ /\A[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?\z/ ) { warn "[numify] $path: \"$v\" -> ", 0 + $v, "\n"; return 0 + $v; } return $v; } sub normalize { my ( $node, $path ) = @_; $node = unwrap_qstr( $node, $path ); if ( ref($node) eq 'ARRAY' ) { my @out; for my $i ( 0 .. $#$node ) { push @out, normalize( $node->[$i], "$path\[$i\]" ); } return \@out; } return maybe_number( $node, $path ); } my $norm = normalize( $$ast_ref, '$ast' ); dd $norm;