|  line  | 
 stmt  | 
 bran  | 
 cond  | 
 sub  | 
 pod  | 
 time  | 
 code  | 
| 
1
 | 
  
 
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 package Statistics::R::IO::QapEncoding;  | 
| 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # ABSTRACT: Functions for parsing Rserve packets  | 
| 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 $Statistics::R::IO::QapEncoding::VERSION = '1.0002';  | 
| 
4
 | 
10
 | 
 
 | 
 
 | 
  
10
  
 | 
 
 | 
520
 | 
 use 5.010;  | 
| 
 
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
34
 | 
    | 
| 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
6
 | 
10
 | 
 
 | 
 
 | 
  
10
  
 | 
 
 | 
47
 | 
 use strict;  | 
| 
 
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
20
 | 
    | 
| 
 
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
244
 | 
    | 
| 
7
 | 
10
 | 
 
 | 
 
 | 
  
10
  
 | 
 
 | 
50
 | 
 use warnings FATAL => 'all';  | 
| 
 
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
20
 | 
    | 
| 
 
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
419
 | 
    | 
| 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
9
 | 
10
 | 
 
 | 
 
 | 
  
10
  
 | 
 
 | 
48
 | 
 use Exporter 'import';  | 
| 
 
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
36
 | 
    | 
| 
 
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
757
 | 
    | 
| 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 our @EXPORT = qw( );  | 
| 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 our @EXPORT_OK = qw( decode );  | 
| 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 our %EXPORT_TAGS = ( all => [ @EXPORT_OK ], );  | 
| 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
16
 | 
10
 | 
 
 | 
 
 | 
  
10
  
 | 
 
 | 
62
 | 
 use Statistics::R::IO::Parser qw( :all );  | 
| 
 
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
33
 | 
    | 
| 
 
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2540
 | 
    | 
| 
17
 | 
10
 | 
 
 | 
 
 | 
  
10
  
 | 
 
 | 
73
 | 
 use Statistics::R::IO::ParserState;  | 
| 
 
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
31
 | 
    | 
| 
 
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
224
 | 
    | 
| 
18
 | 
10
 | 
 
 | 
 
 | 
  
10
  
 | 
 
 | 
294
 | 
 use Statistics::R::REXP::Character;  | 
| 
 
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
23
 | 
    | 
| 
 
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
199
 | 
    | 
| 
19
 | 
10
 | 
 
 | 
 
 | 
  
10
  
 | 
 
 | 
2688
 | 
 use Statistics::R::REXP::Complex;  | 
| 
 
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
33
 | 
    | 
| 
 
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
294
 | 
    | 
| 
20
 | 
10
 | 
 
 | 
 
 | 
  
10
  
 | 
 
 | 
406
 | 
 use Statistics::R::REXP::Double;  | 
| 
 
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
20
 | 
    | 
| 
 
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
205
 | 
    | 
| 
21
 | 
10
 | 
 
 | 
 
 | 
  
10
  
 | 
 
 | 
302
 | 
 use Statistics::R::REXP::Integer;  | 
| 
 
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
21
 | 
    | 
| 
 
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
185
 | 
    | 
| 
22
 | 
10
 | 
 
 | 
 
 | 
  
10
  
 | 
 
 | 
290
 | 
 use Statistics::R::REXP::List;  | 
| 
 
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
17
 | 
    | 
| 
 
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
191
 | 
    | 
| 
23
 | 
10
 | 
 
 | 
 
 | 
  
10
  
 | 
 
 | 
280
 | 
 use Statistics::R::REXP::Logical;  | 
| 
 
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
105
 | 
    | 
| 
 
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
378
 | 
    | 
| 
24
 | 
10
 | 
 
 | 
 
 | 
  
10
  
 | 
 
 | 
397
 | 
 use Statistics::R::REXP::Raw;  | 
| 
 
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
30
 | 
    | 
| 
 
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
212
 | 
    | 
| 
25
 | 
10
 | 
 
 | 
 
 | 
  
10
  
 | 
 
 | 
292
 | 
 use Statistics::R::REXP::Language;  | 
| 
 
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
20
 | 
    | 
| 
 
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
211
 | 
    | 
| 
26
 | 
10
 | 
 
 | 
 
 | 
  
10
  
 | 
 
 | 
300
 | 
 use Statistics::R::REXP::Symbol;  | 
| 
 
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
18
 | 
    | 
| 
 
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
276
 | 
    | 
| 
27
 | 
10
 | 
 
 | 
 
 | 
  
10
  
 | 
 
 | 
325
 | 
 use Statistics::R::REXP::Null;  | 
| 
 
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
17
 | 
    | 
| 
 
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
236
 | 
    | 
| 
28
 | 
10
 | 
 
 | 
 
 | 
  
10
  
 | 
 
 | 
285
 | 
 use Statistics::R::REXP::GlobalEnvironment;  | 
| 
 
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
18
 | 
    | 
| 
 
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
231
 | 
    | 
| 
29
 | 
10
 | 
 
 | 
 
 | 
  
10
  
 | 
 
 | 
3192
 | 
 use Statistics::R::REXP::Unknown;  | 
| 
 
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
25
 | 
    | 
| 
 
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
239
 | 
    | 
| 
30
 | 
10
 | 
 
 | 
 
 | 
  
10
  
 | 
 
 | 
3092
 | 
 use Statistics::R::REXP::S4;  | 
| 
 
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
28
 | 
    | 
| 
 
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
265
 | 
    | 
| 
31
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
32
 | 
10
 | 
 
 | 
 
 | 
  
10
  
 | 
 
 | 
58
 | 
 use Carp;  | 
| 
 
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
18
 | 
    | 
| 
 
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
696
 | 
    | 
| 
33
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 use constant {  | 
| 
35
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1419
 | 
     DT_INT => 1, # int  | 
| 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     DT_CHAR => 2, # char  | 
| 
37
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     DT_DOUBLE => 3, # double  | 
| 
38
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     DT_STRING => 4, # zero- terminated string  | 
| 
39
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     DT_BYTESTREAM => 5, # stream of bytes (unlike DT_STRING may  | 
| 
40
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                         # contain 0)  | 
| 
41
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     DT_SEXP => 10, # encoded SEXP  | 
| 
42
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     DT_ARRAY => 11, # array of objects (i.e. first 4 bytes specify how  | 
| 
43
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     # many subsequent objects are part of the array; 0  | 
| 
44
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     # is legitimate)  | 
| 
45
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     DT_CUSTOM => 32, # custom types not defined in the protocol but  | 
| 
46
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                      # used by applications  | 
| 
47
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     DT_LARGE => 64, # new in 0102: if this flag is set then the length  | 
| 
48
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     # of the object is coded as 56-bit integer  | 
| 
49
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     # enlarging the header by 4 bytes  | 
| 
50
 | 
10
 | 
 
 | 
 
 | 
  
10
  
 | 
 
 | 
59
 | 
 };  | 
| 
 
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
24
 | 
    | 
| 
51
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
52
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # eXpression Types:  transport format of the encoded SEXPs:  | 
| 
53
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # [0] int type/len (1 byte type, 3 bytes len - same as SET_PAR)  | 
| 
54
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # [4] REXP attr (if bit 8 in type is set)  | 
| 
55
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # [4/8] data .. */  | 
| 
56
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # Expression type classification:  | 
| 
57
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #    P = primary type  | 
| 
58
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #    s = secondary type - its decoding is identical to  | 
| 
59
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #        a primary type and thus the client doesn't need to  | 
| 
60
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #        decode it separately.  | 
| 
61
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #    - = deprecated/removed. if a client doesn't need to  | 
| 
62
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #        support old Rserve versions, those can be safely skipped.  | 
| 
63
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # XT_* types:  | 
| 
64
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 use constant {  | 
| 
65
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
28940
 | 
     XT_NULL => 0,   # P data: [0]  | 
| 
66
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     XT_INT => 1,    # - data: [4]int  | 
| 
67
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     XT_DOUBLE => 2, # - data: [8]double  | 
| 
68
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     XT_STR => 3,    # P data: [n]char null-term. strg.  | 
| 
69
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     XT_LANG => 4,   # - data: same as XT_LIST  | 
| 
70
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     XT_SYM => 5,    # - data: [n]char symbol name  | 
| 
71
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     XT_BOOL => 6,   # - data: [1]byte boolean (1=TRUE, 0=FALSE, 2=NA)  | 
| 
72
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     XT_S4 => 7,     # P data: [0]  | 
| 
73
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     XT_VECTOR => 16,     # P data: [?]REXP,REXP,...  | 
| 
74
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     XT_LIST => 17,       # - X head, X vals, X tag (since 0.1-5)  | 
| 
75
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     XT_CLOS => 18,       # P X formals, X body (closure; since 0.1-5)  | 
| 
76
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     XT_SYMNAME => 19,    # s same as XT_STR (since 0.5)  | 
| 
77
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     XT_LIST_NOTAG => 20, # s same as XT_VECTOR (since 0.5)  | 
| 
78
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     XT_LIST_TAG => 21, # P X tag, X val, Y tag, Y val, ... (since 0.5)  | 
| 
79
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     XT_LANG_NOTAG => 22,        # s same as XT_LIST_NOTAG (since 0.5)  | 
| 
80
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     XT_LANG_TAG => 23,          # s same as XT_LIST_TAG (since 0.5)  | 
| 
81
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     XT_VECTOR_EXP => 26,        # s same as XT_VECTOR (since 0.5)  | 
| 
82
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     XT_VECTOR_STR => 27, # - same as XT_VECTOR (since 0.5 but unused, use XT_ARRAY_STR instead)  | 
| 
83
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     XT_ARRAY_INT => 32,  # P data: [n*4]int,int,...  | 
| 
84
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     XT_ARRAY_DOUBLE => 33,      # P data: [n*8]double,double,...  | 
| 
85
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     XT_ARRAY_STR => 34, # P data: string,string,...  | 
| 
86
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                         # (string=byte,byte,...,0) padded with '\01'  | 
| 
87
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     XT_ARRAY_BOOL_UA => 35, # - data: [n]byte,byte,... (unaligned! NOT supported anymore)  | 
| 
88
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     XT_ARRAY_BOOL => 36,    # P data: int(n),byte,byte,...  | 
| 
89
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     XT_RAW => 37,           # P data: int(n),byte,byte,...  | 
| 
90
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     XT_ARRAY_CPLX => 38, # P data: [n*16]double,double,... (Re,Im,Re,Im,...)  | 
| 
91
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     XT_UNKNOWN => 48, # P data: [4]int - SEXP type (as from TYPEOF(x))  | 
| 
92
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
93
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     XT_LARGE => 64, # new in 0102: if this flag is set then the length  | 
| 
94
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     # of the object is coded as 56-bit integer  | 
| 
95
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     # enlarging the header by 4 bytes  | 
| 
96
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     XT_HAS_ATTR => 128,      # flag; if set, the following REXP is the  | 
| 
97
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                              # attribute  | 
| 
98
 | 
10
 | 
 
 | 
 
 | 
  
10
  
 | 
 
 | 
54
 | 
 };  | 
| 
 
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
18
 | 
    | 
| 
99
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
100
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub unpack_sexp_info {  | 
| 
101
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     bind(\&any_uint32,  | 
| 
102
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
          sub {  | 
| 
103
 | 
1098
 | 
 
 | 
  
 50
  
 | 
  
1098
  
 | 
 
 | 
2873
 | 
              my $object_info = shift // return;  | 
| 
104
 | 
1098
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2281
 | 
              my $is_long = $object_info & XT_LARGE;  | 
| 
105
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
106
 | 
1098
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
2383
 | 
              if ($is_long) {  | 
| 
107
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                  ## TODO: if `is_long`, then the next 4 bytes contain  | 
| 
108
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                  ## the upper half of the length  | 
| 
109
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                  error "Sorry, long packets aren't supported yet"   | 
| 
110
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
              } else {  | 
| 
111
 | 
1098
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5681
 | 
                  mreturn { has_attributes => $object_info & XT_HAS_ATTR,  | 
| 
112
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                            is_long => $is_long,  | 
| 
113
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                            object_type => $object_info & 0x3F,  | 
| 
114
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                            length => $object_info >> 8,  | 
| 
115
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                  }  | 
| 
116
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
              }  | 
| 
117
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
          })  | 
| 
118
 | 
1098
 | 
 
 | 
 
 | 
  
1098
  
 | 
  
1
  
 | 
5782
 | 
 }  | 
| 
119
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
120
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
121
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub sexp_data {  | 
| 
122
 | 
1098
 | 
 
 | 
 
 | 
  
1098
  
 | 
  
1
  
 | 
1649
 | 
     my $object_info = shift;  | 
| 
123
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
124
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     bind(maybe_attributes($object_info),  | 
| 
125
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
          sub {  | 
| 
126
 | 
1098
 | 
 
 | 
 
 | 
  
1098
  
 | 
 
 | 
1560
 | 
              my ($object_info, $attributes) = @{shift()};  | 
| 
 
 | 
1098
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1990
 | 
    | 
| 
127
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                | 
| 
128
 | 
1098
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
7650
 | 
     if ($object_info->{object_type} == XT_NULL) {  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
129
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # encoded Nil  | 
| 
130
 | 
17
 | 
 
 | 
 
 | 
 
 | 
 
 | 
134
 | 
         mreturn(Statistics::R::REXP::Null->new)  | 
| 
131
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } elsif ($object_info->{object_type} == XT_ARRAY_INT) {  | 
| 
132
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # integer vector  | 
| 
133
 | 
120
 | 
 
 | 
 
 | 
 
 | 
 
 | 
349
 | 
         intsxp($object_info, $attributes)  | 
| 
134
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } elsif ($object_info->{object_type} == XT_ARRAY_BOOL) {  | 
| 
135
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # logical vector  | 
| 
136
 | 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
49
 | 
         lglsxp($object_info, $attributes)  | 
| 
137
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } elsif ($object_info->{object_type} == XT_ARRAY_DOUBLE) {  | 
| 
138
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # numeric vector  | 
| 
139
 | 
123
 | 
 
 | 
 
 | 
 
 | 
 
 | 
387
 | 
         dblsxp($object_info, $attributes)  | 
| 
140
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } elsif ($object_info->{object_type} == XT_ARRAY_CPLX) {  | 
| 
141
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # complex vector  | 
| 
142
 | 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
77
 | 
         cplxsxp($object_info, $attributes)  | 
| 
143
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } elsif ($object_info->{object_type} == XT_ARRAY_STR) {  | 
| 
144
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # character vector  | 
| 
145
 | 
194
 | 
 
 | 
 
 | 
 
 | 
 
 | 
622
 | 
         strsxp($object_info, $attributes)  | 
| 
146
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } elsif ($object_info->{object_type} == XT_RAW) {  | 
| 
147
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # raw vector  | 
| 
148
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
32
 | 
         rawsxp($object_info)  | 
| 
149
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } elsif ($object_info->{object_type} == XT_VECTOR) {  | 
| 
150
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # list (generic vector)  | 
| 
151
 | 
69
 | 
 
 | 
 
 | 
 
 | 
 
 | 
246
 | 
         vecsxp($object_info, $attributes)  | 
| 
152
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } elsif ($object_info->{object_type} == XT_VECTOR_EXP) {  | 
| 
153
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # expression vector  | 
| 
154
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
50
 | 
         expsxp($object_info, $attributes)  | 
| 
155
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } elsif ($object_info->{object_type} == XT_LIST_NOTAG) {  | 
| 
156
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # pairlist with no tags  | 
| 
157
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $object_info->{has_tags} = 0;  | 
| 
158
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         listsxp($object_info)  | 
| 
159
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } elsif ($object_info->{object_type} == XT_LIST_TAG) {  | 
| 
160
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # pairlist with tags  | 
| 
161
 | 
100
 | 
 
 | 
 
 | 
 
 | 
 
 | 
228
 | 
         $object_info->{has_tags} = 1;  | 
| 
162
 | 
100
 | 
 
 | 
 
 | 
 
 | 
 
 | 
310
 | 
         listsxp($object_info)  | 
| 
163
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } elsif ($object_info->{object_type} == XT_LANG_NOTAG) {  | 
| 
164
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # language without tags  | 
| 
165
 | 
37
 | 
 
 | 
 
 | 
 
 | 
 
 | 
77
 | 
         $object_info->{has_tags} = 0;  | 
| 
166
 | 
37
 | 
 
 | 
 
 | 
 
 | 
 
 | 
112
 | 
         langsxp($object_info, $attributes)  | 
| 
167
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } elsif ($object_info->{object_type} == XT_LANG_TAG) {  | 
| 
168
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # language with tags  | 
| 
169
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12
 | 
         $object_info->{has_tags} = 1;  | 
| 
170
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
19
 | 
         langsxp($object_info, $attributes)  | 
| 
171
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } elsif ($object_info->{object_type} == XT_SYMNAME) {  | 
| 
172
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # symbol  | 
| 
173
 | 
350
 | 
 
 | 
 
 | 
 
 | 
 
 | 
915
 | 
         symsxp($object_info)  | 
| 
174
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } elsif ($object_info->{object_type} == XT_CLOS) {  | 
| 
175
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # closure  | 
| 
176
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         closxp($object_info, $attributes)  | 
| 
177
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } elsif ($object_info->{object_type} == XT_UNKNOWN) {  | 
| 
178
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # unknown  | 
| 
179
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
61
 | 
         nosxp($object_info, $attributes)  | 
| 
180
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } elsif ($object_info->{object_type} == XT_S4) {  | 
| 
181
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # unknown  | 
| 
182
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
20
 | 
         s4sxp($object_info, $attributes)  | 
| 
183
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } else {  | 
| 
184
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         error "unimplemented XT_TYPE: " . $object_info->{object_type}  | 
| 
185
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     }  | 
| 
186
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
          })  | 
| 
187
 | 
1098
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2172
 | 
 }  | 
| 
188
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
189
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
190
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub maybe_attributes {  | 
| 
191
 | 
1098
 | 
 
 | 
 
 | 
  
1098
  
 | 
  
1
  
 | 
1685
 | 
     my $object_info = shift;  | 
| 
192
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
193
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     sub {  | 
| 
194
 | 
1098
 | 
  
 50
  
 | 
 
 | 
  
1098
  
 | 
 
 | 
2295
 | 
         my $state = shift or return;  | 
| 
195
 | 
1098
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1473
 | 
         my $attributes;  | 
| 
196
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
197
 | 
1098
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
2627
 | 
         if ($object_info->{has_attributes}) {  | 
| 
198
 | 
100
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2080
 | 
             my $attributes_start = $state->position;  | 
| 
199
 | 
100
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
701
 | 
             my $result = dt_sexp_data()->($state) or return;  | 
| 
200
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
201
 | 
100
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5670
 | 
             $attributes = { tagged_pairlist_to_attribute_hash(shift @$result) };  | 
| 
202
 | 
100
 | 
 
 | 
 
 | 
 
 | 
 
 | 
307
 | 
             $state = shift @$result;  | 
| 
203
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
204
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             ## adjust SEXP length for that already consumed by attributes  | 
| 
205
 | 
100
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3473
 | 
             $object_info->{length} -= $state->position - $attributes_start;  | 
| 
206
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
207
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
           | 
| 
208
 | 
1098
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3675
 | 
         [ [$object_info, $attributes], $state]  | 
| 
209
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
210
 | 
1098
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6045
 | 
 }  | 
| 
211
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
212
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
213
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub tagged_pairlist_to_rexp_hash {  | 
| 
214
 | 
100
 | 
  
 50
  
 | 
 
 | 
  
100
  
 | 
  
1
  
 | 
370
 | 
     my $list = shift or return;  | 
| 
215
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
216
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     croak "Tagged element has an attribute?!"  | 
| 
217
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         if exists $list->{attributes} &&  | 
| 
218
 | 
100
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
425
 | 
         grep {$_ ne 'names'} keys %{$list->{attributes}};  | 
| 
 
 | 
100
 | 
 
 | 
 
 | 
 
 | 
 
 | 
438
 | 
    | 
| 
 
 | 
100
 | 
 
 | 
 
 | 
 
 | 
 
 | 
338
 | 
    | 
| 
219
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
220
 | 
100
 | 
 
 | 
 
 | 
 
 | 
 
 | 
208
 | 
     my @elements = @{$list->elements};  | 
| 
 
 | 
100
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1742
 | 
    | 
| 
221
 | 
100
 | 
 
 | 
 
 | 
 
 | 
 
 | 
614
 | 
     my @names = @{$list->attributes->{names}->elements};  | 
| 
 
 | 
100
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1509
 | 
    | 
| 
222
 | 
100
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
2126
 | 
     die 'length of tags does not match the elements' unless  | 
| 
223
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         scalar(@elements) == scalar(@names);  | 
| 
224
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
225
 | 
100
 | 
 
 | 
 
 | 
 
 | 
 
 | 
191
 | 
     my %rexps;  | 
| 
226
 | 
100
 | 
 
 | 
 
 | 
 
 | 
 
 | 
333
 | 
     while (my $name = shift(@names)) {  | 
| 
227
 | 
235
 | 
 
 | 
 
 | 
 
 | 
 
 | 
338
 | 
         my $value = shift(@elements);  | 
| 
228
 | 
235
 | 
 
 | 
 
 | 
 
 | 
 
 | 
754
 | 
         $rexps{$name} = $value;  | 
| 
229
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
230
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     %rexps  | 
| 
231
 | 
100
 | 
 
 | 
 
 | 
 
 | 
 
 | 
454
 | 
 }  | 
| 
232
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
233
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
234
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub tagged_pairlist_to_attribute_hash {  | 
| 
235
 | 
100
 | 
 
 | 
 
 | 
  
100
  
 | 
  
1
  
 | 
302
 | 
     my %rexp_hash = tagged_pairlist_to_rexp_hash @_;  | 
| 
236
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
237
 | 
100
 | 
 
 | 
 
 | 
 
 | 
 
 | 
240
 | 
     my $row_names = $rexp_hash{'row.names'};  | 
| 
238
 | 
100
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
309
 | 
     if ($row_names && $row_names->type eq 'integer' &&  | 
| 
 
 | 
 
 | 
 
 | 
  
 66
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
239
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         ! defined $row_names->elements->[0]) {  | 
| 
240
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         ## compact encoding when rownames are integers 1..n: the  | 
| 
241
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         ## length n is in the second element, but can be negative to  | 
| 
242
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         ## denote "automatic" rownames  | 
| 
243
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
550
 | 
         my $n = abs($row_names->elements->[1]);  | 
| 
244
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
139
 | 
         $rexp_hash{'row.names'} = Statistics::R::REXP::Integer->new([1..$n]);  | 
| 
245
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
246
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
247
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     %rexp_hash  | 
| 
248
 | 
100
 | 
 
 | 
 
 | 
 
 | 
 
 | 
431
 | 
 }  | 
| 
249
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
250
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
251
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub s4sxp {  | 
| 
252
 | 
6
 | 
 
 | 
 
 | 
  
6
  
 | 
  
1
  
 | 
29
 | 
     my ($object_info, $attributes) = (shift, shift);  | 
| 
253
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
103
 | 
     my $class = $attributes->{class}->elements;  | 
| 
254
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     croak "S4 'class' must be a single-element array" unless  | 
| 
255
 | 
6
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
48
 | 
         ref($class) eq 'ARRAY' && scalar(@{$class}) == 1;  | 
| 
 
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
28
 | 
    | 
| 
256
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
93
 | 
     my $package = $attributes->{class}->attributes->{package}->elements;  | 
| 
257
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     croak "S4 'package' must be a single-element array" unless  | 
| 
258
 | 
6
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
126
 | 
         ref($package) eq 'ARRAY' && scalar(@{$package}) == 1;  | 
| 
 
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
24
 | 
    | 
| 
259
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
260
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # the remaining attributes should be object's slots  | 
| 
261
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
21
 | 
     delete $attributes->{class};  | 
| 
262
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
97
 | 
     my $slots = $attributes;  | 
| 
263
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
264
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
67
 | 
     mreturn(Statistics::R::REXP::S4->new(class => $class->[0],  | 
| 
265
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                                          package => $package->[0],  | 
| 
266
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                                          slots => $slots))  | 
| 
267
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
268
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
269
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub symsxp {  | 
| 
270
 | 
350
 | 
 
 | 
 
 | 
  
350
  
 | 
  
1
  
 | 
551
 | 
     my $object_info = shift;  | 
| 
271
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
272
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     bind(count($object_info->{length}, \&any_char),  | 
| 
273
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
          sub {  | 
| 
274
 | 
350
 | 
  
 50
  
 | 
 
 | 
  
350
  
 | 
 
 | 
573
 | 
              my @chars = @{shift or return};  | 
| 
 
 | 
350
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1624
 | 
    | 
| 
275
 | 
350
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
3560
 | 
              pop @chars while @chars && !ord($chars[-1]);  | 
| 
276
 | 
350
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2312
 | 
              mreturn(Statistics::R::REXP::Symbol->new(join('', @chars)))  | 
| 
277
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
          })  | 
| 
278
 | 
350
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1029
 | 
 }  | 
| 
279
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
280
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
281
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub nosxp {  | 
| 
282
 | 
18
 | 
 
 | 
 
 | 
  
18
  
 | 
  
1
  
 | 
53
 | 
     my ($object_info, $attributes) = (shift, shift);  | 
| 
283
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
284
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     bind(\&any_uint32,  | 
| 
285
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
          sub {  | 
| 
286
 | 
18
 | 
  
 50
  
 | 
 
 | 
  
18
  
 | 
 
 | 
89
 | 
              my $sexp_id = shift or return;  | 
| 
287
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
288
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
67
 | 
              my %args = (sexptype => $sexp_id);  | 
| 
289
 | 
18
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
57
 | 
              if ($attributes) {  | 
| 
290
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
                  $args{attributes} = $attributes  | 
| 
291
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
              }  | 
| 
292
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                | 
| 
293
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
158
 | 
              mreturn(Statistics::R::REXP::Unknown->new(%args))  | 
| 
294
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
          })  | 
| 
295
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
99
 | 
 }  | 
| 
296
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
297
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
298
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub intsxp {  | 
| 
299
 | 
120
 | 
 
 | 
 
 | 
  
120
  
 | 
  
1
  
 | 
279
 | 
     my ($object_info, $attributes) = (shift, shift);  | 
| 
300
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
301
 | 
120
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
386
 | 
     if ($object_info->{length} % 4 == 0) {  | 
| 
302
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         bind(count($object_info->{length}/4,  | 
| 
303
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                    any_int32_na),  | 
| 
304
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
              sub {  | 
| 
305
 | 
120
 | 
  
 50
  
 | 
 
 | 
  
120
  
 | 
 
 | 
254
 | 
                  my @ints = @{shift or return};  | 
| 
 
 | 
120
 | 
 
 | 
 
 | 
 
 | 
 
 | 
466
 | 
    | 
| 
306
 | 
120
 | 
 
 | 
 
 | 
 
 | 
 
 | 
457
 | 
                  my %args = (elements => [@ints]);  | 
| 
307
 | 
120
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
304
 | 
                  if ($attributes) {  | 
| 
308
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
53
 | 
                      $args{attributes} = $attributes  | 
| 
309
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                  }  | 
| 
310
 | 
120
 | 
 
 | 
 
 | 
 
 | 
 
 | 
868
 | 
                  mreturn(Statistics::R::REXP::Integer->new(%args));  | 
| 
311
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
              })  | 
| 
312
 | 
120
 | 
 
 | 
 
 | 
 
 | 
 
 | 
538
 | 
     } else {  | 
| 
313
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         error "TODO: intsxp length doesn't align by 4: " .  | 
| 
314
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             $object_info->{length}  | 
| 
315
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     }  | 
| 
316
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
317
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
318
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
319
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub dblsxp {  | 
| 
320
 | 
123
 | 
 
 | 
 
 | 
  
123
  
 | 
  
1
  
 | 
317
 | 
     my ($object_info, $attributes) = (shift, shift);  | 
| 
321
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
322
 | 
123
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
433
 | 
     if ($object_info->{length} % 8 == 0) {  | 
| 
323
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         bind(count($object_info->{length}/8,  | 
| 
324
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                    any_real64_na),  | 
| 
325
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
              sub {  | 
| 
326
 | 
123
 | 
  
 50
  
 | 
 
 | 
  
123
  
 | 
 
 | 
280
 | 
                  my @dbls = @{shift or return};  | 
| 
 
 | 
123
 | 
 
 | 
 
 | 
 
 | 
 
 | 
523
 | 
    | 
| 
327
 | 
123
 | 
 
 | 
 
 | 
 
 | 
 
 | 
507
 | 
                  my %args = (elements => [@dbls]);  | 
| 
328
 | 
123
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
341
 | 
                  if ($attributes) {  | 
| 
329
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
54
 | 
                      $args{attributes} = $attributes  | 
| 
330
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                  }  | 
| 
331
 | 
123
 | 
 
 | 
 
 | 
 
 | 
 
 | 
893
 | 
                  mreturn(Statistics::R::REXP::Double->new(%args));  | 
| 
332
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
              })  | 
| 
333
 | 
123
 | 
 
 | 
 
 | 
 
 | 
 
 | 
581
 | 
     } else {  | 
| 
334
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         error "TODO: dblsxp length doesn't align by 8: " .  | 
| 
335
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             $object_info->{length}  | 
| 
336
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     }  | 
| 
337
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
338
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
339
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
340
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub cplxsxp {  | 
| 
341
 | 
21
 | 
 
 | 
 
 | 
  
21
  
 | 
  
1
  
 | 
58
 | 
     my ($object_info, $attributes) = (shift, shift);  | 
| 
342
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
343
 | 
21
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
80
 | 
     if ($object_info->{length} % 16 == 0) {  | 
| 
344
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         bind(count($object_info->{length}/8,  | 
| 
345
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                    any_real64_na),  | 
| 
346
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
              sub {  | 
| 
347
 | 
21
 | 
  
 50
  
 | 
 
 | 
  
21
  
 | 
 
 | 
40
 | 
                  my @dbls = @{shift or return};  | 
| 
 
 | 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
93
 | 
    | 
| 
348
 | 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
46
 | 
                  my @cplx;  | 
| 
349
 | 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
97
 | 
                  while (my ($re, $im) = splice(@dbls, 0, 2)) {  | 
| 
350
 | 
33
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
990
 | 
                      if (defined($re) && defined($im)) {  | 
| 
351
 | 
30
 | 
 
 | 
 
 | 
 
 | 
 
 | 
137
 | 
                          push(@cplx, Math::Complex::cplx($re, $im))  | 
| 
352
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                      }  | 
| 
353
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                      else {  | 
| 
354
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13
 | 
                          push(@cplx, undef)  | 
| 
355
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                      }  | 
| 
356
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                  }  | 
| 
357
 | 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1424
 | 
                  my %args = (elements => [@cplx]);  | 
| 
358
 | 
21
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
64
 | 
                  if ($attributes) {  | 
| 
359
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
                      $args{attributes} = $attributes  | 
| 
360
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                  }  | 
| 
361
 | 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
211
 | 
                  mreturn(Statistics::R::REXP::Complex->new(%args));  | 
| 
362
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
              })  | 
| 
363
 | 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
112
 | 
     } else {  | 
| 
364
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         error "TODO: cplxsxp length doesn't align by 16: " .  | 
| 
365
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             $object_info->{length}  | 
| 
366
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     }  | 
| 
367
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
368
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
369
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
370
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub lglsxp {  | 
| 
371
 | 
14
 | 
 
 | 
 
 | 
  
14
  
 | 
  
1
  
 | 
35
 | 
     my ($object_info, $attributes) = (shift, shift);  | 
| 
372
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
373
 | 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
36
 | 
     my $dt_length = $object_info->{length},;  | 
| 
374
 | 
14
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
42
 | 
     if ($dt_length) {  | 
| 
375
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         bind(\&any_uint32,  | 
| 
376
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
              sub {  | 
| 
377
 | 
14
 | 
 
 | 
  
 50
  
 | 
  
14
  
 | 
 
 | 
51
 | 
                  my $true_length = shift // return;  | 
| 
378
 | 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
45
 | 
                  my $padding_length = $dt_length - $true_length - 4;  | 
| 
379
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
380
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                  bind(seq(count($true_length,  | 
| 
381
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                                 \&any_uint8),  | 
| 
382
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                           count($padding_length,  | 
| 
383
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                                 \&any_uint8)),  | 
| 
384
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                       sub {  | 
| 
385
 | 
14
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
26
 | 
                           my ($elements, $padding) = @{shift or return};  | 
| 
 
 | 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
46
 | 
    | 
| 
386
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                           my %args = (elements => [  | 
| 
387
 | 
14
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
50
 | 
                                           map { $_ == 2 ? undef : $_ } @{$elements}  | 
| 
 
 | 
31
 | 
 
 | 
 
 | 
 
 | 
 
 | 
97
 | 
    | 
| 
 
 | 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
36
 | 
    | 
| 
388
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                                       ]);  | 
| 
389
 | 
14
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
45
 | 
                           if ($attributes) {  | 
| 
390
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
                               $args{attributes} = $attributes  | 
| 
391
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                           }  | 
| 
392
 | 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
133
 | 
                           mreturn(Statistics::R::REXP::Logical->new(%args));  | 
| 
393
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                       })  | 
| 
394
 | 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
55
 | 
              })  | 
| 
395
 | 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
87
 | 
     } else {  | 
| 
396
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         mreturn(Statistics::R::REXP::Logical->new);  | 
| 
397
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
398
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
399
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
400
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
401
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub rawsxp {  | 
| 
402
 | 
9
 | 
 
 | 
 
 | 
  
9
  
 | 
  
1
  
 | 
16
 | 
     my $object_info = shift;  | 
| 
403
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
404
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
21
 | 
     my $dt_length = $object_info->{length},;  | 
| 
405
 | 
9
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
28
 | 
     if ($dt_length) {  | 
| 
406
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         bind(\&any_uint32,  | 
| 
407
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
              sub {  | 
| 
408
 | 
9
 | 
 
 | 
  
 50
  
 | 
  
9
  
 | 
 
 | 
64
 | 
                  my $true_length = shift // return;  | 
| 
409
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
27
 | 
                  my $padding_length = $dt_length - $true_length - 4;  | 
| 
410
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
411
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                  bind(seq(count($true_length,  | 
| 
412
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                                 \&any_uint8),  | 
| 
413
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                           count($padding_length,  | 
| 
414
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                                \&any_uint8)),  | 
| 
415
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                       sub {  | 
| 
416
 | 
9
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
17
 | 
                           my ($elements, $padding) = @{shift or return};  | 
| 
 
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
31
 | 
    | 
| 
417
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
52
 | 
                           mreturn(Statistics::R::REXP::Raw->new($elements));  | 
| 
418
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                       })  | 
| 
419
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
34
 | 
              })  | 
| 
420
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
48
 | 
     } else {  | 
| 
421
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         mreturn(Statistics::R::REXP::Raw->new);  | 
| 
422
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
423
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
424
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
425
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
426
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub strsxp {  | 
| 
427
 | 
194
 | 
 
 | 
 
 | 
  
194
  
 | 
  
1
  
 | 
445
 | 
     my ($object_info, $attributes) = (shift, shift);  | 
| 
428
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
429
 | 
194
 | 
 
 | 
 
 | 
 
 | 
 
 | 
417
 | 
     my $length = $object_info->{length};  | 
| 
430
 | 
194
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
478
 | 
     if ($length) {  | 
| 
431
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         sub {  | 
| 
432
 | 
188
 | 
 
 | 
 
 | 
  
188
  
 | 
 
 | 
353
 | 
             my $state = shift;  | 
| 
433
 | 
188
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3640
 | 
             my $end_at = $state->position + $length;  | 
| 
434
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
435
 | 
188
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1244
 | 
             my @elements;       # elements of the vector  | 
| 
436
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             my @characters;     # characters in the current element  | 
| 
437
 | 
188
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2892
 | 
             while ($state->position < $end_at) {  | 
| 
438
 | 
3284
 | 
 
 | 
 
 | 
 
 | 
 
 | 
114028
 | 
                 my $ch = $state->at;  | 
| 
439
 | 
3284
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
72037
 | 
                 if (ord($ch)) {  | 
| 
440
 | 
2802
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5568
 | 
                     push @characters, $ch;  | 
| 
441
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 } else {  | 
| 
442
 | 
482
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1508
 | 
                     my $element = join('', @characters);  | 
| 
443
 | 
482
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
1101
 | 
                     if ($element eq "\xFF") {  | 
| 
444
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                         ## NaStringRepresentation  | 
| 
445
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
                         push @elements, undef;  | 
| 
446
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     } else {  | 
| 
447
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                         ## unescape real \xFF characters  | 
| 
448
 | 
479
 | 
 
 | 
 
 | 
 
 | 
 
 | 
911
 | 
                         $element =~ s/\xFF\xFF/\xFF/g;  | 
| 
449
 | 
479
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1008
 | 
                         push @elements, $element;  | 
| 
450
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     }  | 
| 
451
 | 
482
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1098
 | 
                     @characters = ();  | 
| 
452
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 }  | 
| 
453
 | 
3284
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6983
 | 
                 $state = $state->next;  | 
| 
454
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
455
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
               | 
| 
456
 | 
188
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7365
 | 
             my %args = (elements => [@elements]);  | 
| 
457
 | 
188
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
522
 | 
             if ($attributes) {  | 
| 
458
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
34
 | 
                 $args{attributes} = $attributes  | 
| 
459
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
460
 | 
188
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1102
 | 
             [ Statistics::R::REXP::Character->new(%args), $state ];  | 
| 
461
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
462
 | 
188
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1325
 | 
     } else {  | 
| 
463
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
41
 | 
         mreturn(Statistics::R::REXP::Character->new);  | 
| 
464
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
465
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
466
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
467
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
468
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub vecsxp {  | 
| 
469
 | 
84
 | 
 
 | 
 
 | 
  
84
  
 | 
  
1
  
 | 
213
 | 
     my ($object_info, $attributes) = (shift, shift);  | 
| 
470
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
471
 | 
84
 | 
 
 | 
 
 | 
 
 | 
 
 | 
212
 | 
     my $length = $object_info->{length};  | 
| 
472
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     sub {  | 
| 
473
 | 
84
 | 
 
 | 
 
 | 
  
84
  
 | 
 
 | 
178
 | 
         my $state = shift;  | 
| 
474
 | 
84
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1551
 | 
         my $end_at = $state->position + $length;  | 
| 
475
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
           | 
| 
476
 | 
84
 | 
 
 | 
 
 | 
 
 | 
 
 | 
546
 | 
         my @elements;  | 
| 
477
 | 
84
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1253
 | 
         while ($state->position < $end_at) {  | 
| 
478
 | 
231
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
4249
 | 
             my $result = dt_sexp_data()->($state) or return;  | 
| 
479
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
               | 
| 
480
 | 
231
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7219
 | 
             push @elements, shift @$result;  | 
| 
481
 | 
231
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2022
 | 
             $state = shift @$result;  | 
| 
482
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
483
 | 
84
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2226
 | 
         my %args = (elements => [@elements]);  | 
| 
484
 | 
84
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
322
 | 
         if ($attributes) {  | 
| 
485
 | 
30
 | 
 
 | 
 
 | 
 
 | 
 
 | 
83
 | 
             $args{attributes} = $attributes  | 
| 
486
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
487
 | 
84
 | 
 
 | 
 
 | 
 
 | 
 
 | 
496
 | 
         [ Statistics::R::REXP::List->new(%args), $state ];  | 
| 
488
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
489
 | 
84
 | 
 
 | 
 
 | 
 
 | 
 
 | 
516
 | 
 }  | 
| 
490
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
491
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
492
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub expsxp {  | 
| 
493
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     bind(vecsxp(@_), sub {  | 
| 
494
 | 
15
 | 
 
 | 
 
 | 
  
15
  
 | 
 
 | 
31
 | 
         my $list = shift;  | 
| 
495
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
279
 | 
         my %args = (elements => $list->elements);  | 
| 
496
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
296
 | 
         my $attributes = $list->attributes;  | 
| 
497
 | 
15
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
77
 | 
         if ($attributes) {  | 
| 
498
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             $args{attributes} = $attributes  | 
| 
499
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
500
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
127
 | 
         mreturn(Statistics::R::REXP::Expression->new(%args))  | 
| 
501
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     })  | 
| 
502
 | 
15
 | 
 
 | 
 
 | 
  
15
  
 | 
  
1
  
 | 
88
 | 
 }  | 
| 
503
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
504
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
505
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub tagged_pairlist {  | 
| 
506
 | 
142
 | 
 
 | 
 
 | 
  
142
  
 | 
  
1
  
 | 
274
 | 
     my $object_info = shift;  | 
| 
507
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
508
 | 
142
 | 
 
 | 
 
 | 
 
 | 
 
 | 
328
 | 
     my $length = $object_info->{length};  | 
| 
509
 | 
142
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
327
 | 
     if ($length) {  | 
| 
510
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         sub {  | 
| 
511
 | 
142
 | 
 
 | 
 
 | 
  
142
  
 | 
 
 | 
257
 | 
             my $state = shift;  | 
| 
512
 | 
142
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2857
 | 
             my $end_at = $state->position + $length;  | 
| 
513
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
               | 
| 
514
 | 
142
 | 
 
 | 
 
 | 
 
 | 
 
 | 
906
 | 
             my @elements;  | 
| 
515
 | 
142
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2129
 | 
             while ($state->position < $end_at) {  | 
| 
516
 | 
356
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
2477
 | 
                 my $result = dt_sexp_data()->($state) or return;  | 
| 
517
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                   | 
| 
518
 | 
356
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10436
 | 
                 my $value = shift @$result;  | 
| 
519
 | 
356
 | 
 
 | 
 
 | 
 
 | 
 
 | 
844
 | 
                 $state = shift @$result;  | 
| 
520
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
521
 | 
356
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2588
 | 
                 my $element = { value => $value };  | 
| 
522
 | 
356
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
1060
 | 
                 if ($object_info->{has_tags}) {  | 
| 
523
 | 
250
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
731
 | 
                     $result = dt_sexp_data()->($state) or return;  | 
| 
524
 | 
250
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4314
 | 
                     my $tag = shift @$result;  | 
| 
525
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
526
 | 
250
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
985
 | 
                     $element->{tag} = $tag unless $tag->is_null;  | 
| 
527
 | 
250
 | 
 
 | 
 
 | 
 
 | 
 
 | 
657
 | 
                     $state = shift @$result;  | 
| 
528
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 }  | 
| 
529
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                   | 
| 
530
 | 
356
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8932
 | 
                 push @elements, $element;  | 
| 
531
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
532
 | 
142
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1225
 | 
             [ [ @elements ], $state ];  | 
| 
533
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
534
 | 
142
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1173
 | 
     } else {  | 
| 
535
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         mreturn []  | 
| 
536
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
537
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
538
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
539
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
540
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ## At the REXP level, pairlists are treated the same as generic  | 
| 
541
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ## vectors, i.e., as instances of type List. Tags, if present, become  | 
| 
542
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ## the name attribute.  | 
| 
543
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub listsxp {  | 
| 
544
 | 
100
 | 
 
 | 
 
 | 
  
100
  
 | 
  
1
  
 | 
210
 | 
     my $object_info = shift;  | 
| 
545
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ## The `tagged_pairlist` returns an array of cons cells, and we  | 
| 
546
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ## must separate the tags from the elements before invoking the  | 
| 
547
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ## List constructor, with the tags becoming the names attribute  | 
| 
548
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     bind(tagged_pairlist($object_info),  | 
| 
549
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
          sub {  | 
| 
550
 | 
100
 | 
  
 50
  
 | 
 
 | 
  
100
  
 | 
 
 | 
297
 | 
              my $list = shift or return;  | 
| 
551
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
552
 | 
100
 | 
 
 | 
 
 | 
 
 | 
 
 | 
209
 | 
              my @elements;  | 
| 
553
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
              my @names;  | 
| 
554
 | 
100
 | 
 
 | 
 
 | 
 
 | 
 
 | 
269
 | 
              foreach my $element (@$list) {  | 
| 
555
 | 
235
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1516
 | 
                  my $tag = $element->{tag};  | 
| 
556
 | 
235
 | 
 
 | 
 
 | 
 
 | 
 
 | 
351
 | 
                  my $value = $element->{value};  | 
| 
557
 | 
235
 | 
 
 | 
 
 | 
 
 | 
 
 | 
405
 | 
                  push @elements, $value;  | 
| 
558
 | 
235
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
746
 | 
                  push @names, $tag ? $tag->name : '';  | 
| 
559
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
              }  | 
| 
560
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
561
 | 
100
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1200
 | 
              my %args = (elements => [ @elements ]);  | 
| 
562
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
              ## if no element is tagged, then don't construct the  | 
| 
563
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
              ## 'names' attribute  | 
| 
564
 | 
100
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
230
 | 
              if (grep {exists $_->{tag}} @$list) {  | 
| 
 
 | 
235
 | 
 
 | 
 
 | 
 
 | 
 
 | 
563
 | 
    | 
| 
565
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                  $args{attributes} =  {  | 
| 
566
 | 
100
 | 
 
 | 
 
 | 
 
 | 
 
 | 
429
 | 
                      names => Statistics::R::REXP::Character->new([ @names ])  | 
| 
567
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                  };  | 
| 
568
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
              }  | 
| 
569
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
570
 | 
100
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1179
 | 
              mreturn(Statistics::R::REXP::List->new(%args))  | 
| 
571
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
          })  | 
| 
572
 | 
100
 | 
 
 | 
 
 | 
 
 | 
 
 | 
370
 | 
 }  | 
| 
573
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
574
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
575
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ## Language expressions are pairlists, but with a certain structure:  | 
| 
576
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ## - the first element is the reference (name or another language  | 
| 
577
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ##   expression) to the function call  | 
| 
578
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ## - the rest of the list are the arguments of the call, with optional  | 
| 
579
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ##   tags to name them  | 
| 
580
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub langsxp {  | 
| 
581
 | 
42
 | 
 
 | 
 
 | 
  
42
  
 | 
  
1
  
 | 
103
 | 
     my ($object_info, $attributes) = (shift, shift);  | 
| 
582
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ## After the pairlist has been parsed by `tagged_pairlist`, we  | 
| 
583
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ## separate the tags from the elements before invoking the Language  | 
| 
584
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ## constructor, with the tags becoming the names attribute  | 
| 
585
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     bind(tagged_pairlist($object_info),  | 
| 
586
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
          sub {  | 
| 
587
 | 
42
 | 
  
 50
  
 | 
 
 | 
  
42
  
 | 
 
 | 
138
 | 
              my $list = shift or return;  | 
| 
588
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
589
 | 
42
 | 
 
 | 
 
 | 
 
 | 
 
 | 
90
 | 
              my @elements;  | 
| 
590
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
              my @names;  | 
| 
591
 | 
42
 | 
 
 | 
 
 | 
 
 | 
 
 | 
108
 | 
              foreach my $element (@$list) {  | 
| 
592
 | 
121
 | 
 
 | 
 
 | 
 
 | 
 
 | 
232
 | 
                  my $tag = $element->{tag};  | 
| 
593
 | 
121
 | 
 
 | 
 
 | 
 
 | 
 
 | 
173
 | 
                  my $value = $element->{value};  | 
| 
594
 | 
121
 | 
 
 | 
 
 | 
 
 | 
 
 | 
190
 | 
                  push @elements, $value;  | 
| 
595
 | 
121
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
300
 | 
                  push @names, $tag ? $tag->name : '';  | 
| 
596
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
              }  | 
| 
597
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
598
 | 
42
 | 
 
 | 
 
 | 
 
 | 
 
 | 
198
 | 
              my %args = (elements => [ @elements ]);  | 
| 
599
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
              ## if no element is tagged, then don't construct the  | 
| 
600
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
              ## 'names' attribute  | 
| 
601
 | 
42
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
91
 | 
              if (grep {exists $_->{tag}} @$list) {  | 
| 
 
 | 
121
 | 
 
 | 
 
 | 
 
 | 
 
 | 
306
 | 
    | 
| 
602
 | 
5
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
33
 | 
                  $attributes //=  {}; # initialize the hash  | 
| 
603
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
39
 | 
                  $attributes->{names} = Statistics::R::REXP::Character->new([ @names ]);  | 
| 
604
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
              }  | 
| 
605
 | 
42
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
152
 | 
              $args{attributes} = $attributes if $attributes;  | 
| 
606
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
607
 | 
42
 | 
 
 | 
 
 | 
 
 | 
 
 | 
245
 | 
              mreturn(Statistics::R::REXP::Language->new(%args))  | 
| 
608
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
          })  | 
| 
609
 | 
42
 | 
 
 | 
 
 | 
 
 | 
 
 | 
127
 | 
 }  | 
| 
610
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
611
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
612
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub closxp {  | 
| 
613
 | 
  
0
  
 | 
 
 | 
 
 | 
  
0
  
 | 
  
1
  
 | 
0
 | 
     my ($object_info, $attributes) = (shift, shift);  | 
| 
614
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
615
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $length = $object_info->{length};  | 
| 
616
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     bind(count(2, dt_sexp_data()),  | 
| 
617
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
          sub {  | 
| 
618
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
  
0
  
 | 
 
 | 
0
 | 
              my ($args, $body) = @{(shift or return)};  | 
| 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
619
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
              my (@arg_names, @arg_values);  | 
| 
620
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
              if (ref $args eq ref []) {  | 
| 
621
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                  foreach my $arg (@{$args}) {  | 
| 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
622
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                      push @arg_names, $arg->{tag}->name;  | 
| 
623
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                      if (Statistics::R::REXP::Symbol->new('') eq $arg->{value}) {  | 
| 
624
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                          push @arg_values, undef  | 
| 
625
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                      }  | 
| 
626
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                      else {  | 
| 
627
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                          push @arg_values, $arg->{value}  | 
| 
628
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                      }  | 
| 
629
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                  }  | 
| 
630
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
              }  | 
| 
631
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                | 
| 
632
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
              my %args = (body => $body,  | 
| 
633
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                          args => [@arg_names],  | 
| 
634
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                          defaults => [@arg_values]);  | 
| 
635
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                | 
| 
636
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
              $args{attributes} = $attributes if $attributes;  | 
| 
637
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                | 
| 
638
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
              mreturn(Statistics::R::REXP::Closure->new(%args))  | 
| 
639
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
          })  | 
| 
640
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 }  | 
| 
641
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
642
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub dt_sexp_data {  | 
| 
643
 | 
1098
 | 
 
 | 
 
 | 
  
1098
  
 | 
  
1
  
 | 
2392
 | 
     bind(unpack_sexp_info,  | 
| 
644
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
          \&sexp_data)  | 
| 
645
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
646
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
647
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
648
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub decode_sexp {  | 
| 
649
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     bind(seq(uint8(DT_SEXP), \&any_uint24,  | 
| 
650
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
              dt_sexp_data),  | 
| 
651
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
          sub {  | 
| 
652
 | 
161
 | 
 
 | 
 
 | 
  
161
  
 | 
 
 | 
519
 | 
              mreturn shift->[2]  | 
| 
653
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
          })  | 
| 
654
 | 
161
 | 
 
 | 
 
 | 
  
161
  
 | 
  
1
  
 | 
2270
 | 
 }  | 
| 
655
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
656
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
657
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub decode_int {  | 
| 
658
 | 
  
0
  
 | 
 
 | 
 
 | 
  
0
  
 | 
  
1
  
 | 
0
 | 
     die 'TODO: implement'  | 
| 
659
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
660
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
661
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
662
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub decode {  | 
| 
663
 | 
161
 | 
 
 | 
 
 | 
  
161
  
 | 
  
1
  
 | 
139697
 | 
     my $data = shift;  | 
| 
664
 | 
161
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
577
 | 
     return error "Decode requires a scalar data or array reference" if ref $data && ref $data ne ref [];  | 
| 
665
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
666
 | 
161
 | 
 
 | 
 
 | 
 
 | 
 
 | 
620
 | 
     endianness('<');  | 
| 
667
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
668
 | 
161
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1089
 | 
     my $result =  | 
| 
669
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         decode_sexp->(Statistics::R::IO::ParserState->new(data => $data));  | 
| 
670
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
671
 | 
161
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
2114
 | 
     if ($result) {  | 
| 
672
 | 
161
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1798
 | 
         my $state = $result->[1];  | 
| 
673
 | 
161
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
472
 | 
         carp("remaining data: " . (scalar(@{$state->data}) - $state->position))  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
674
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             unless $state->eof;  | 
| 
675
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
676
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
677
 | 
161
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1548
 | 
     $result;  | 
| 
678
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
679
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
680
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
681
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 1;  | 
| 
682
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
683
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 __END__  |