3
3
# in QAST::Compiler. Since the mapping is pretty close, the nodes themselves
4
4
# know how to become PIR.
5
5
6
+ class PIRT::CallResult {
7
+ has str $ ! result ;
8
+
9
+ method new (: $ result ! ) {
10
+ my $ obj := nqp ::create(self );
11
+ nqp ::bindattr_s($ obj , PIRT::CallResult, ' $!result' ,
12
+ $ result ~~ PIRT::Node ?? $ result . result !! $ result );
13
+ $ obj
14
+ }
15
+
16
+ method result () {
17
+ $ ! result
18
+ }
19
+ }
20
+
6
21
class PIRT::Node {
7
22
my % op_compilers := nqp ::hash(
8
23
' call' , sub (@ args ) {
9
- nqp ::die(" NYI" );
24
+ " " ~
25
+ ($ * HAS_RESULT ?? @ args . shift () ~ " = " !! ' ' ) ~
26
+ @ args . shift () ~ " (" ~ nqp :: join (" , " , @ args ) ~ " )"
10
27
},
11
28
' callmethod' , sub (@ args ) {
12
29
nqp ::die(" NYI" );
@@ -33,16 +50,25 @@ class PIRT::Node {
33
50
my $ i := 1 ;
34
51
my $ c := nqp :: elems ($ _ );
35
52
my $ arg ;
53
+ my $ * HAS_RESULT := 0 ;
54
+ my $ result ;
36
55
while $ i < $ c {
37
56
$ arg := $ _ [$ i ];
38
57
if $ arg ~~ PIRT::Node {
39
58
nqp :: push (@ op_args , $ arg . result);
40
59
}
60
+ elsif $ arg ~~ PIRT::CallResult {
61
+ $ result := $ arg . result;
62
+ $ * HAS_RESULT := 1 ;
63
+ }
41
64
else {
42
65
nqp :: push (@ op_args , $ arg );
43
66
}
44
67
$ i := $ i + 1 ;
45
68
}
69
+ if $ * HAS_RESULT {
70
+ nqp :: unshift (@ op_args , $ result );
71
+ }
46
72
if nqp ::existskey(% op_compilers , $ op_name ) {
47
73
nqp :: push (@ parts , % op_compilers {$ op_name }(@ op_args ));
48
74
}
@@ -67,9 +93,23 @@ class PIRT::Node {
67
93
68
94
class PIRT::Sub is PIRT::Node {
69
95
has @ ! children ;
96
+ has str $ ! subid ;
97
+ has str $ ! pirflags ;
98
+ has str $ ! name ;
99
+ has @ ! loadlibs ;
100
+
70
101
has @ ! nested_blocks ;
71
102
has str $ ! cached_pir ;
72
103
104
+ method escape ($ str ) {
105
+ my $ esc := pir::escape__Ss($ str );
106
+ nqp :: index ($ esc , ' \x' , 0 ) >= 0 ??
107
+ ' utf8:"' ~ $ esc ~ ' "' !!
108
+ (nqp :: index ($ esc , ' \u' , 0 ) >= 0 ??
109
+ ' unicode:"' ~ $ esc ~ ' "' !!
110
+ ' "' ~ $ esc ~ ' "' )
111
+ }
112
+
73
113
method new () {
74
114
my $ obj := nqp ::create(self );
75
115
nqp ::bindattr($ obj , PIRT::Sub, ' @!children' , nqp ::list());
@@ -80,10 +120,29 @@ class PIRT::Sub is PIRT::Node {
80
120
nqp :: push (@ ! children , $ node );
81
121
}
82
122
83
- method push_pirop (* @ opbits ) {
123
+ method push_pirop (* @ opbits , : $ result ) {
124
+ if $ result {
125
+ nqp :: push (@ opbits , PIRT::CallResult. new ($ result ));
126
+ }
84
127
nqp :: push (@ ! children , @ opbits )
85
128
}
86
129
130
+ method subid (* @ value ) {
131
+ @ value ?? ($ ! subid := @ value [0 ]) !! $ ! subid
132
+ }
133
+
134
+ method pirflags (* @ value ) {
135
+ @ value ?? ($ ! pirflags := @ value [0 ]) !! $ ! pirflags
136
+ }
137
+
138
+ method name (* @ value ) {
139
+ @ value ?? ($ ! name := @ value [0 ]) !! $ ! name
140
+ }
141
+
142
+ method loadlibs (@ libs ? ) {
143
+ @ libs ?? (@ ! loadlibs := @ libs ) !! @ ! loadlibs
144
+ }
145
+
87
146
method result () {
88
147
nqp ::die(" Cannot use a PIRT::Sub in a context expecting a result" );
89
148
}
@@ -92,7 +151,17 @@ class PIRT::Sub is PIRT::Node {
92
151
my @ parts ;
93
152
94
153
# Sub prelude.
95
- nqp :: push (@ parts , " .sub ''" );
154
+ for @ ! loadlibs {
155
+ nqp :: push (@ parts , " .loadlib " ~ self . escape($ _ ));
156
+ }
157
+ my $ sub_decl := " .sub " ~ self . escape($ ! name || ' ' );
158
+ if $ ! subid {
159
+ $ sub_decl := $ sub_decl ~ " :subid(" ~ self . escape($ ! subid ) ~ " )" ;
160
+ }
161
+ if $ ! pirflags {
162
+ $ sub_decl := $ sub_decl ~ ' ' ~ $ ! pirflags
163
+ }
164
+ nqp :: push (@ parts , $ sub_decl );
96
165
97
166
# Compile sub contents, collecting any nested blocks.
98
167
my @ * PIRT_BLOCKS ;
@@ -138,7 +207,10 @@ class PIRT::Ops is PIRT::Node {
138
207
nqp :: push (@ ! children , $ node )
139
208
}
140
209
141
- method push_pirop (* @ opbits ) {
210
+ method push_pirop (* @ opbits , : $ result ) {
211
+ if $ result {
212
+ nqp :: push (@ opbits , PIRT::CallResult. new ($ result ));
213
+ }
142
214
nqp :: push (@ ! children , @ opbits )
143
215
}
144
216
0 commit comments