/
Unit.pm
91 lines (83 loc) · 2.69 KB
/
Unit.pm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
use strict;
use warnings;
use 5.010;
# A Unit generates a CLR class with a BOOT member
# All used Units except for the setting go into Niecza.Kernel.Units
# The main program generates a main class, which sets up Units and runs the
# setting
# BOOT subs take one argument, the outer protopad
{
package Unit;
use Moose;
has mainline => (isa => 'Body', is => 'ro', required => 1);
has mainboot => (isa => 'CgOp', is => 'rw');
has name => (isa => 'Str', is => 'ro', required => 1);
has setting => (is => 'ro');
has is_setting => (isa => 'Bool', is => 'ro');
has setting_name => (isa => 'Str', is => 'ro');
sub lift_decls {
$_[0]->mainline->lift_decls;
}
sub to_cgop {
$_[0]->mainboot($_[0]->mainline->to_cgop);
}
sub gen_code {
my ($self) = @_;
$self->mainline->setting($self->setting) if $self->setting;
CodeGen->know_module($self->csname($self->setting_name));
CodeGen->know_module($self->csname);
CodeGen->new(csname => 'BOOT',
ops => CgOp::letn('pkg', CgOp::rawsget('Kernel.Global'),
CgOp::rawscall($self->csname($self->setting_name) . '.Initialize'),
CgOp::letn('protopad',
CgOp::cast('Frame', CgOp::rawsget($self->csname($self->setting_name) .
'.Environment')),
($self->is_setting ?
CgOp::rawsset($self->csname . '.Installer',
CgOp::protosub($self->mainline)) :
CgOp::subcall(CgOp::rawsget($self->csname($self->setting_name) . '.Installer'),
CgOp::newscalar(CgOp::protosub($self->mainline)))),
CgOp::return())));
}
sub csname {
my $x = $_[1] // $_[0]->name;
$x =~ s/::/./g;
$x ||= 'MAIN';
$x;
}
sub write {
my ($self) = @_;
#say STDERR (YAML::XS::Dump($self));
print ::NIECZA_OUT <<EOH;
public class @{[ $self->csname ]} {
EOH
$self->gen_code->write;
$self->mainline->write;
if ($self->is_setting) {
print ::NIECZA_OUT <<EOSB ;
public static IP6 Installer;
EOSB
}
if (!$self->name) { # || has_MAIN
print ::NIECZA_OUT <<EOMAIN ;
public static void Main() {
Initialize();
}
EOMAIN
}
print ::NIECZA_OUT <<EOGB ;
private static bool Initialized;
public static Frame Environment;
public static void Initialize() {
if (!Initialized) {
Initialized = true;
Kernel.RunLoop(new DynBlockDelegate(BOOT));
}
}
}
EOGB
}
__PACKAGE__->meta->make_immutable;
no Moose;
}
1;