From e835ea6fe9223f73c290876944a714c5084d6512 Mon Sep 17 00:00:00 2001 From: Stefan O'Rear Date: Mon, 7 Mar 2011 17:03:00 -0800 Subject: [PATCH] Parse types on declarators --- src/niecza | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/src/niecza b/src/niecza index a45d7c21..af298a9d 100644 --- a/src/niecza +++ b/src/niecza @@ -167,6 +167,69 @@ method package_def ($/) { stub => True); } } + +method multi_declarator:null ($/) { make $.ast } + +method variable_declarator($/) { + if $*MULTINESS { + $/.CURSOR.sorry("Multi variables NYI"); + } + if $ || $ || $ || $ { + $/.CURSOR.sorry("Traits, postconstraints, and shapes on variable declarators NYI"); + } + + my $scope = $*SCOPE // 'my'; + + if $scope eq 'augment' || $scope eq 'supersede' { + $/.CURSOR.sorry("Illogical scope $scope for simple variable"); + } + + my $typeconstraint; + if $*OFTYPE { + my ($name,$rest) = self.mangle_longname($*OFTYPE); + $typeconstraint = defined($rest) ?? [ @$rest,$name ] !! [ 'MY', $name ]; + $/.CURSOR.sorry("Common variables are not unique definitions and may not have types") if $scope eq 'our'; + } + + my $v = $.ast; + my $t = $v; + if ($t && defined "?=~^:".index($t)) { + $/.CURSOR.sorry("Variables with the $t twigil cannot be declared " ~ + "using $scope; they are created " ~ + ($t eq '?' ?? "using 'constant'." !! + $t eq '=' ?? "by parsing POD blocks." !! + $t eq '~' ?? "by 'slang' definitions." !! + "automatically as parameters to the current block.")); + } + + if $scope ne 'has' && ($t eq '.' || $t eq '!') { + $/.CURSOR.sorry("Twigil $t is only valid on attribute definitions ('has')."); + } + + if defined $v { + $/.CURSOR.sorry(":: syntax is only valid when referencing variables, not when defining them."); + } + + my $name = $v ~ $v ~ $v; + # otherwise identical to my + my $slot = ($scope eq 'anon') ?? self.gensym !! $name; + + if $scope eq 'has' { + make ::Op::Attribute.new(|node($/), name => $v, + accessor => $t eq '.', :$typeconstraint); + } elsif $scope eq 'state' { + make ::Op::Lexical.new(|node($/), name => $slot, state_decl => True, + state_backing => self.gensym, declaring => True, :$typeconstraint, + list => $v eq '@', hash => $v eq '%'); + } elsif $scope eq 'our' { + make ::Op::PackageVar.new(|node($/), name => $slot, slot => $slot, + path => [ 'OUR' ]); + } else { + make ::Op::Lexical.new(|node($/), name => $slot, declaring => True, + list => $v eq '@', hash => $v eq '%', :$typeconstraint); + } +} + } my $usage = q:to/EOM/;