Skip to content

Instantly share code, notes, and snippets.

@lizmat
Created February 12, 2023 14:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lizmat/ec4dc6ebda05c6f5075508ca2ad2383b to your computer and use it in GitHub Desktop.
Save lizmat/ec4dc6ebda05c6f5075508ca2ad2383b to your computer and use it in GitHub Desktop.
diff --git a/src/Raku/Actions.nqp b/src/Raku/Actions.nqp
index dce1474c4..b351c48ae 100644
--- a/src/Raku/Actions.nqp
+++ b/src/Raku/Actions.nqp
@@ -1681,7 +1681,7 @@ class Raku::Actions is HLL::Actions does Raku::CommonActions {
$name := ~$<variable>;
}
- my $decl := self.r('VarDeclaration', 'Implicit', 'Constant').new(
+ my $decl := self.r('VarDeclaration', 'Constant').new(
:$name,
:value(self.r('BeginTime').IMPL-BEGIN-TIME-EVALUATE($value, $*R, $*CU.context)),
:scope($*SCOPE));
diff --git a/src/Raku/ast/variable-declaration.rakumod b/src/Raku/ast/variable-declaration.rakumod
index 0e811d405..c1d70df09 100644
--- a/src/Raku/ast/variable-declaration.rakumod
+++ b/src/Raku/ast/variable-declaration.rakumod
@@ -194,7 +194,115 @@ class RakuAST::TraitTarget::Variable
}
}
-# A basic variable declaration of the form `my SomeType $foo = 42` or `has Foo $x .= new`.
+# A basic constant declaration of the form `my Type constant $foo = 42`
+class RakuAST::VarDeclaration::Constant
+ is RakuAST::Declaration
+ is RakuAST::TraitTarget
+ is RakuAST::BeginTime
+ is RakuAST::CheckTime
+ is RakuAST::CompileTimeValue
+ is RakuAST::ImplicitLookups
+{
+ has str $.name;
+ has Mu $.value;
+ has RakuAST::Type $.type;
+ has Mu $!package;
+
+ method new(str :$name!, str :$scope!, Mu :$value!, RakuAST::Type :$type) {
+ my $obj := nqp::create(self);
+ nqp::bindattr_s($obj, RakuAST::VarDeclaration::Constant,'$!name',$name);
+ nqp::bindattr_s($obj, RakuAST::Declaration, '$!scope', $scope);
+ nqp::bindattr($obj,RakuAST::VarDeclaration::Constant,'$!value',$value);
+ nqp::bindattr($obj, RakuAST::VarDeclaration::Constant, '$!type',
+ $type // RakuAST::Type);
+ $obj
+ }
+
+ method lexical-name() { $!name }
+ method default-scope() { 'my' }
+ method allowed-scopes() { self.IMPL-WRAP-LIST(['my', 'our']) }
+
+ method PRODUCE-IMPLICIT-LOOKUPS() {
+ self.IMPL-WRAP-LIST($!type ?? [$!type] !! [])
+ }
+
+ method attach(RakuAST::Resolver $resolver) {
+ if self.scope eq 'our' {
+ # There is always a package, even if it's just GLOBALish
+ nqp::bindattr(self, RakuAST::VarDeclaration::Constant, '$!package',
+ $resolver.current-package);
+ }
+ }
+
+ method visit-children(Code $visitor) {
+ my $type := $!type;
+ $visitor($type) if nqp::isconcrete($type);
+ self.visit-traits($visitor);
+ }
+
+ method PERFORM-BEGIN(
+ RakuAST::Resolver $resolver,
+ RakuAST::IMPL::QASTContext $context
+ ) {
+ self.apply-traits(
+ $resolver, $context, self, :SYMBOL(RakuAST::StrLiteral.new($!name))
+ );
+ }
+
+ method PERFORM-CHECK(
+ RakuAST::Resolver $resolver,
+ RakuAST::IMPL::QASTContext $context
+ ) {
+ if $!type {
+ my $type := self.IMPL-UNWRAP-LIST(
+ self.get-implicit-lookups
+ )[0].resolution.compile-time-value;
+
+ unless nqp::istype(nqp::what($!value), $type) {
+ self.add-sorry($resolver.build-exception('X::Comp::TypeCheck',
+ operation => 'constant declaration',
+ expected => $type,
+ got => nqp::what($!value)
+ ));
+ return False;
+ }
+ }
+ True
+ }
+
+ method IMPL-QAST-DECL(RakuAST::IMPL::QASTContext $context) {
+ my $value := $!value;
+ $context.ensure-sc($value);
+ my $constant := QAST::Var.new(
+ :decl('static'), :scope('lexical'), :name($!name), :value($!value)
+ );
+ self.scope eq 'our'
+ ?? QAST::Op.new(
+ :op('bind'),
+ $constant,
+ QAST::Op.new(
+ :op('callmethod'), :name('VIVIFY-KEY'),
+ QAST::Op.new(:op('who'), QAST::WVal.new(:value($!package))),
+ QAST::SVal.new(:value($!name))
+ )
+ )
+ !! $constant
+ }
+
+ method IMPL-LOOKUP-QAST(RakuAST::IMPL::QASTContext $context) {
+ QAST::Var.new(:name($!name), :scope<lexical>)
+ }
+
+ method IMPL-TO-QAST(RakuAST::IMPL::QASTContext $context) {
+ QAST::Var.new(:name($!name), :scope<lexical>)
+ }
+}
+
+# A basic variable declaration of the form `my SomeType $foo = 42` or
+# `has Foo $x .= new`.
class RakuAST::VarDeclaration::Simple
is RakuAST::Declaration
is RakuAST::ImplicitLookups
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment