Skip to content

Commit

Permalink
Translate cheating use into NQP and split out need and import. Stubs …
Browse files Browse the repository at this point in the history
…for various things we'll need (tags, lexical import).
  • Loading branch information
jnthn committed Mar 10, 2010
1 parent 5b81dfe commit a705b41
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 48 deletions.
6 changes: 5 additions & 1 deletion build/Makefile.in
Expand Up @@ -71,6 +71,7 @@ SOURCES = \
src/gen/role_pm.pir \
src/gen/locator_pm.pir \
src/gen/versiondetectionactions_pm.pir \
src/gen/loader_pm.pir \
$(PERL6_G) \
$(PERL6_A) \
$(DYNEXT_TARGET)
Expand Down Expand Up @@ -147,7 +148,6 @@ CHEATS_PIR = \
src/cheats/relops.pir \
src/cheats/mapiterator.pir \
src/cheats/gatheriterator.pir \
src/cheats/use.pir \
src/cheats/only_infix_redispatcher.pir \
src/cheats/import.pir \
src/cheats/want-caller-side-callsig.pir \
Expand Down Expand Up @@ -361,6 +361,10 @@ src/gen/versiondetectionactions_pm.pir: $(PARROT) $(NQP_PBC) src/Perl6/Module/Ve
$(NQP_EXE) --output=src/gen/versiondetectionactions_pm.pir --encoding=utf8 \
--target=pir src/Perl6/Module/VersionDetectionActions.pm

src/gen/loader_pm.pir: $(PARROT) $(NQP_PBC) src/Perl6/Module/Loader.pm
$(NQP_EXE) --output=src/gen/loader_pm.pir --encoding=utf8 \
--target=pir src/Perl6/Module/Loader.pm

src/gen/builtins.pir: build/gen_builtins_pir.pl $(BUILTINS_PIR)
$(PERL) build/gen_builtins_pir.pl $(BUILTINS_PIR) > src/gen/builtins.pir

Expand Down
33 changes: 31 additions & 2 deletions src/Perl6/Actions.pm
Expand Up @@ -336,9 +336,38 @@ method statement_control:sym<use>($/) {
);
}
else {
@BLOCK[0].loadinit.unshift(
PAST::Op.new( :name('!use'), ~$<module_name>, :node($/) )
# Build up adverbs hash if we have them. Note that we need a hash
# for now (the compile time call) and an AST that builds said hash
# for the runtime call once we've compiled the module.
my $name := $<module_name><longname><name>.Str;
my %adverbs;
my $adverbs_ast := PAST::Op.new(
:name('&circumfix:<{ }>'), PAST::Op.new( :name('&infix:<,>') )
);
if $<module_name><longname><colonpair> {
for $<module_name><longname><colonpair> {
my $ast := $_.ast;
$adverbs_ast[0].push($ast);
%adverbs{$ast[1].value()} := $ast[2].value();
}
}

# Need to immediately load module and get lexicals stubbed in.
# XXX TODO

# Also need code to do the actual loading and import at runtime.
my @ns := pir::split__PSS('::', 'Perl6::Module');
@BLOCK[0].loadinit.push(
PAST::Op.new( :pasttype('callmethod'), :name('need'),
PAST::Var.new( :name('Loader'), :namespace(@ns), :scope('package') ),
$name,
PAST::Op.new( :pirop('getattribute PPS'), $adverbs_ast, '$!storage' )
));
@BLOCK[0].loadinit.push(
PAST::Op.new( :pasttype('callmethod'), :name('import'),
PAST::Var.new( :name('Loader'), :namespace(@ns), :scope('package') ),
$name
));
}
}
make $past;
Expand Down
1 change: 1 addition & 0 deletions src/Perl6/Compiler.pir
Expand Up @@ -99,6 +99,7 @@ Perl6::Compiler - Perl6 compiler
.include 'src/gen/role_pm.pir'
.include 'src/gen/locator_pm.pir'
.include 'src/gen/versiondetectionactions_pm.pir'
.include 'src/gen/loader_pm.pir'
.include 'src/gen/perl6-grammar.pir'
.include 'src/gen/perl6-actions.pir'

Expand Down
53 changes: 53 additions & 0 deletions src/Perl6/Module/Loader.pm
@@ -0,0 +1,53 @@
# This class contains various bits of logic for implemneting need
# and import.
class Perl6::Module::Loader;

method need($name, %name_adverbs) {
# Use locator to find the module.
my @inc := pir::get_hll_global__PS('@INC');
my $pm_file := %name_adverbs<ver> || %name_adverbs<auth> ??
Perl6::Module::Locator.find_module($name, @inc, %name_adverbs<ver>, %name_adverbs<auth>) !!
Perl6::Module::Locator.find_module_no_conditions($name, @inc);
if $pm_file eq '' {
# XXX Awesomeize - include version and auth if specified.
pir::die("Unable to find module '$name'.");
}

# XXX For now, we just use the pre-compiled PIR file. (Yes, epic hack.)
my $pir_file := pir::substr__SSII($pm_file, 0, pir::length__IS($pm_file) - 2) ~ 'pir';
unless pir::stat__ISI($pir_file, 0) {
pir::die("Sorry, for now you must manually compile .pm modules to .pir (missing for $name).");
}
pir::load_bytecode__vS($pir_file);
1;
}

method get_imports($name) {
# Look up default export namespace.
# XXX Here is where we need to support custom tags.
my @nsparts := pir::split__PSS('::', $name);
@nsparts.push('EXPORT');
@nsparts.push('DEFAULT');
return pir::get_hll_namespace__PP(@nsparts);
}

method stub_lexical_imports($name, $block_ast) {
}

method import($name) {
# XXX For now, target is always namespace of the caller. In the
# future we need to be much more smart and handle lexical imports.
my $targetns := Q:PIR {
%r = getinterp
%r = %r['namespace';1]
};
# Get imports.
my %imports := self.get_imports($name);
unless pir::isnull__IP(%imports) {
for %imports {
$targetns{$_.key} := $_.value;
}
}
1;
}
3 changes: 3 additions & 0 deletions src/Perl6/Module/Locator.pm
@@ -1,3 +1,6 @@
# This class handles the mapping of a module name to a file on disk.
# For now it does it purely by looking through all of the candidates;
# in the future, it should be updated to do caching.
class Perl6::Module::Locator;

method find_candidates($lookfor, @inc) {
Expand Down
45 changes: 0 additions & 45 deletions src/cheats/use.pir

This file was deleted.

0 comments on commit a705b41

Please sign in to comment.