-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathtuple.cpp
More file actions
117 lines (108 loc) · 3.16 KB
/
Copy pathtuple.cpp
File metadata and controls
117 lines (108 loc) · 3.16 KB
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
117
#include "tuple.h"
#include "../utils.h"
#include "class.h"
#include "errors.h"
#include "file.h"
#include "string.h"
#include "tuple_iterator.h"
Tuple *Tuple::create(int size) {
Tuple *t = Gc::allocTuple2(size);
t->size = size;
Utils::fillNil(t->values(), size);
return t;
}
Value next_tuple_construct_1(const Value *args, int numargs) {
(void)numargs;
EXPECT(tuple, "new(_)", 1, Integer);
int64_t num = args[1].toInteger();
if(num < 1) {
return RuntimeError::sete("Tuple size must be > 0!");
}
Tuple *t = Tuple::create(num);
return t;
}
Value next_tuple_copy(const Value *args, int numargs) {
(void)numargs;
Tuple *t = args[0].toTuple();
// we avoid Tuple::create here, because
// that's going to call fillNil. The slots
// are going to be written over anyway.
Tuple *nt = Gc::allocTuple2(t->size);
nt->size = t->size;
memcpy(nt->values(), t->values(), sizeof(Value) * t->size);
return Value(nt);
}
Value next_tuple_size(const Value *args, int numargs) {
(void)numargs;
return Value(args[0].toTuple()->size);
}
Value next_tuple_iterate(const Value *args, int numargs) {
(void)numargs;
return Value(TupleIterator::from(args[0].toTuple()));
}
Value next_tuple_get(const Value *args, int numargs) {
(void)numargs;
EXPECT(tuple, "[](_)", 1, Integer);
int64_t idx = args[1].toInteger();
int64_t effective_idx = idx;
Tuple * t = args[0].toTuple();
if(idx < 0) {
effective_idx += t->size;
}
if(effective_idx < t->size) {
return t->values()[effective_idx];
}
if(t->size == 0) {
IDXERR("Tuple is empty!", 0, 0, idx);
}
IDXERR("Invalid tuple index!", -t->size, t->size - 1, idx);
return ValueNil;
}
Value next_tuple_set(const Value *args, int numargs) {
(void)numargs;
EXPECT(tuple, "[](_,_)", 1, Integer);
int64_t idx = args[1].toInteger();
int64_t effective_idx = idx;
Tuple * t = args[0].toTuple();
if(idx < 0) {
effective_idx += t->size;
}
if(effective_idx < t->size) {
return t->values()[effective_idx] = args[2];
}
if(t->size == 0) {
IDXERR("Tuple is empty!", 0, 0, idx);
}
IDXERR("Invalid tuple index!", -t->size, t->size - 1, idx);
return ValueNil;
}
Value next_tuple_str(const Value *args, int numargs) {
(void)numargs;
EXPECT(tuple, "str(_)", 1, File);
File *f = args[1].toFile();
if(!f->stream->isWritable()) {
return FileError::sete("File is not writable!");
}
f->writableStream()->write("(");
Tuple *a = args[0].toTuple();
if(a->size > 0) {
if(String::toStringValue(a->values()[0], f) == ValueNil)
return ValueNil;
for(int i = 1; i < a->size; i++) {
f->writableStream()->write(", ");
if(String::toStringValue(a->values()[i], f) == ValueNil)
return ValueNil;
}
}
f->writableStream()->write(")");
return ValueTrue;
}
void Tuple::init(Class *TupleClass) {
TupleClass->add_builtin_fn("(_)", 1, next_tuple_construct_1);
TupleClass->add_builtin_fn("copy()", 0, next_tuple_copy);
TupleClass->add_builtin_fn("iterate()", 0, next_tuple_iterate);
TupleClass->add_builtin_fn("size()", 0, next_tuple_size);
TupleClass->add_builtin_fn_nest("str(_)", 1, next_tuple_str);
TupleClass->add_builtin_fn("[](_)", 1, next_tuple_get);
TupleClass->add_builtin_fn("[](_,_)", 2, next_tuple_set);
}