/
Chunk.nqp
116 lines (98 loc) · 3.47 KB
/
Chunk.nqp
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# The different types of js things a Chunk expr can be
my $T_OBJ := 0;
my $T_INT := 1; # We use a javascript number but always treat it as a 32bit integer
my $T_NUM := 2; # We use a javascript number for that
my $T_STR := 3; # We use a javascript str for that
my $T_BOOL := 4; # Something that can be used in boolean context in javascript. To the user it should be presented as a 0 or 1
my $T_CALL_ARG := 5; # Something that will be passed to a sub/method call
my $T_INT16 := 6; # We use a javascript number but always treat it as a 16bit integer
my $T_INT8 := 7; # We use a javascript number but always treat it as a 8bit integer
my $T_RETVAL := 8; # Something that will be returned from a sub/method call
my $T_UINT16 := 9; # We use a javascript number but always treat it as a 16bit integer
my $T_UINT8 := 10; # We use a javascript number but always treat it as a 8bit integer
my $T_VOID := -1; # Value of this type shouldn't exist, we use a "" as the expr
my $T_NONVAL := -2; # something that is not a nqp value
my $T_ARGS := -3; # comma separated arguments to a js call
my $T_ARGS_ARRAY := -4; # an array of arguments to a js call
class Chunk {
has int $!type; # the js type of $!expr
has str $!expr; # a javascript expression without side effects
has $!node; # a QAST::Node that contains info for source maps
has $!setup; # stuff that needs to be executed before the value of $!expr can be used, this contains strings and Chunks.
method new($type, $expr, $setup = nqp::null(), :$node) {
my $obj := nqp::create(self);
$obj.BUILD($type, $expr, $setup, :$node);
$obj
}
method void(*@setup, :$node) {
self.new($T_VOID, "", @setup, :$node);
}
method BUILD($type, $expr, @setup, :$node) {
$!type := $type;
$!expr := $expr;
$!setup := @setup;
$!node := $node if nqp::defined($node);
}
method collect(@strs) {
if nqp::isnull($!setup) {
}
elsif nqp::istype($!setup, Chunk) {
$!setup.collect(@strs);
}
else {
for $!setup -> $part {
if nqp::isstr($part) {
nqp::push_s(@strs, $part);
}
else {
$part.collect(@strs);
}
}
}
}
method join() {
my @strs := nqp::list_s();
self.collect(@strs);
nqp::join('', @strs);
}
method collect_with_source_map_info($offset, @strs, @mapping) {
if nqp::defined($!node) && $!node.node {
nqp::push_i(@mapping, $!node.node.from());
nqp::push_i(@mapping, $offset);
}
if nqp::isnull($!setup) {
0;
}
elsif nqp::istype($!setup, Chunk) {
$!setup.collect_with_source_map_info($offset, @strs, @mapping);
}
else {
my int $count := 0;
for $!setup -> $part {
if nqp::isstr($part) {
$count := $count + nqp::chars($part);
nqp::push_s(@strs, $part);
}
else {
$count := $count + $part.collect_with_source_map_info($offset + $count, @strs, @mapping);
}
}
$count;
}
}
method type() {
$!type;
}
method expr() {
$!expr;
}
method setup() {
$!setup;
}
method node() {
$!node;
}
method is_args_array() {
$!type == $T_ARGS_ARRAY;
}
}