Skip to content

Commit d32e538

Browse files
committed
V 0.0.12 open-source release
0 parents  commit d32e538

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+12573
-0
lines changed

base64/base64.v

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// Copyright (c) 2019 Alexander Medvednikov. All rights reserved.
2+
// Use of this source code is governed by an MIT license
3+
// that can be found in the LICENSE file.
4+
5+
module base64
6+
7+
const (
8+
Index = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
9+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
10+
62, 63, 62, 62, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, 0,
11+
0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
12+
17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 63, 0, 26, 27, 28, 29,
13+
30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46,
14+
47, 48, 49, 50, 51]
15+
)
16+
17+
fn decode(data string) string {
18+
p := data.cstr()
19+
len := data.len
20+
mut pad := 0
21+
if len > 0 && (len % 4 != 0 || p[len - 1] == `=`) {
22+
pad = 1
23+
}
24+
L := ((len + 3) / 4 - pad) * 4
25+
str_len := L / 4 * 3 + pad
26+
mut str := malloc(str_len + 2)
27+
mut j := 0
28+
for i := 0; i < L; i += 4 {
29+
n := (Index[p[i]] << 18) | (Index[p[i + 1]] << 12) |
30+
(Index[p[i + 2]] << 6) | (Index[p[i + 3]])
31+
str[j] = n >> 16
32+
j++
33+
str[j] = n >> 8 & 0xff
34+
j++
35+
str[j] = n & 0xff
36+
j++
37+
}
38+
if pad > 0 {
39+
mut nn := (Index[p[L]] << 18) | (Index[p[L + 1]] << 12)
40+
str[str_len - 1] = nn >> 16
41+
if len > L + 2 && p[L + 2] != `=` {
42+
nn = nn | (Index[p[L + 2]] << 6)
43+
str[str_len] = nn >> 8 & 0xff
44+
}
45+
}
46+
str[str_len + 1] = `\0`
47+
return string(str)
48+
}
49+

builtin/array.v

Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
1+
module builtin
2+
3+
struct array {
4+
// Using a void pointer allows to implement arrays without generics and without generating
5+
// extra code for every type.
6+
data voidptr
7+
pub:
8+
len int
9+
cap int
10+
element_size int
11+
}
12+
13+
// Private function, used by V (`nums := []int`)
14+
fn new_array(mylen int, cap, elm_size int) array {
15+
arr := array {
16+
len: mylen
17+
cap: cap
18+
element_size: elm_size
19+
data: malloc(cap * elm_size)
20+
}
21+
return arr
22+
}
23+
24+
// Private function, used by V (`nums := [1, 2, 3]`)
25+
fn new_array_from_c_array(len, cap, elm_size int, c_array voidptr) array {
26+
arr := array {
27+
len: len
28+
cap: cap
29+
element_size: elm_size
30+
data: malloc(cap * elm_size)
31+
}
32+
// TODO Write all memory functions (like memcpy) in V
33+
C.memcpy(arr.data, c_array, len * elm_size)
34+
return arr
35+
}
36+
37+
// Private function, used by V (`nums := [1, 2, 3] !`)
38+
fn new_array_from_c_array_no_alloc(len, cap, elm_size int, c_array voidptr) array {
39+
arr := array {
40+
len: len
41+
cap: cap
42+
element_size: elm_size
43+
data: c_array
44+
}
45+
return arr
46+
}
47+
48+
// Private function, used by V (`[0; 100]`)
49+
fn array_repeat(val voidptr, nr_repeats int, elm_size int) array {
50+
arr := array {
51+
len: nr_repeats
52+
cap: nr_repeats
53+
element_size: elm_size
54+
data: malloc(nr_repeats * elm_size)
55+
}
56+
for i := 0; i < nr_repeats; i++ {
57+
C.memcpy(arr.data + i * elm_size, val, elm_size)
58+
}
59+
return arr
60+
}
61+
62+
fn (a mut array) append_array(b array) {
63+
for i := 0; i < b.len; i++ {
64+
val := b[i]
65+
a._push(val)
66+
}
67+
}
68+
69+
fn (a mut array) sort_with_compare(compare voidptr) {
70+
C.qsort(a.data, a.len, a.element_size, compare)
71+
}
72+
73+
fn (a mut array) insert(i int, val voidptr) {
74+
if i >= a.len {
75+
panic('array.insert: index larger than length')
76+
return
77+
}
78+
a._push(val)
79+
size := a.element_size
80+
C.memmove(a.data + (i + 1) * size, a.data + i * size, (a.len - i) * size)
81+
a.set(i, val)
82+
}
83+
84+
fn (a mut array) prepend(val voidptr) {
85+
a.insert(0, val)
86+
}
87+
88+
fn (a mut array) delete(idx int) {
89+
size := a.element_size
90+
C.memmove(a.data + idx * size, a.data + (idx + 1) * size, (a.len - idx) * size)
91+
a.len--
92+
a.cap--
93+
}
94+
95+
fn (a array) _get(i int) voidptr {
96+
if i < 0 || i >= a.len {
97+
panic('array index out of range: $i/$a.len')
98+
}
99+
return a.data + i * a.element_size
100+
}
101+
102+
fn (a array) first() voidptr {
103+
if a.len == 0 {
104+
panic('array.first: empty array')
105+
}
106+
return a.data + 0
107+
}
108+
109+
fn (a array) last() voidptr {
110+
if a.len == 0 {
111+
panic('array.last: empty array')
112+
}
113+
return a.data + (a.len - 1) * a.element_size
114+
}
115+
116+
fn (s array) left(n int) array {
117+
if n >= s.len {
118+
return s
119+
}
120+
return s.slice(0, n)
121+
}
122+
123+
fn (s array) right(n int) array {
124+
if n >= s.len {
125+
return s
126+
}
127+
return s.slice(n, s.len)
128+
}
129+
130+
pub fn (s array) slice(start, _end int) array {
131+
mut end := _end
132+
if start > end {
133+
panic('invalid slice index: $start > $end')
134+
}
135+
if end >= s.len {
136+
end = s.len
137+
}
138+
l := end - start
139+
res := array {
140+
element_size: s.element_size
141+
data: s.data + start * s.element_size
142+
len: l
143+
cap: l
144+
}
145+
return res
146+
}
147+
148+
fn (a mut array) set(idx int, val voidptr) {
149+
if idx < 0 || idx >= a.len {
150+
panic('array index out of range: $idx / $a.len')
151+
}
152+
C.memcpy(a.data + a.element_size * idx, val, a.element_size)
153+
}
154+
155+
fn (arr mut array) _push(val voidptr) {
156+
if arr.len >= arr.cap - 1 {
157+
cap := (arr.len + 1) * 2
158+
// println('_push: realloc, new cap=$cap')
159+
if arr.cap == 0 {
160+
arr.data = malloc(cap * arr.element_size)
161+
}
162+
else {
163+
arr.data = C.realloc(arr.data, cap * arr.element_size)
164+
}
165+
arr.cap = cap
166+
}
167+
C.memcpy(arr.data + arr.element_size * arr.len, val, arr.element_size)
168+
arr.len++
169+
}
170+
171+
fn (arr mut array) _push_many(val voidptr, size int) {
172+
if arr.len >= arr.cap - size {
173+
cap := (arr.len + size) * 2
174+
// println('_push: realloc, new cap=$cap')
175+
if arr.cap == 0 {
176+
arr.data = malloc(cap * arr.element_size)
177+
}
178+
else {
179+
arr.data = C.realloc(arr.data, cap * arr.element_size)
180+
}
181+
arr.cap = cap
182+
}
183+
C.memcpy(arr.data + arr.element_size * arr.len, val, arr.element_size * size)
184+
arr.len += size
185+
}
186+
187+
fn (a[]int) str() string {
188+
mut res := '['
189+
for i := 0; i < a.len; i++ {
190+
val := a[i]
191+
res += '$val'
192+
if i < a.len - 1 {
193+
res += ', '
194+
}
195+
}
196+
res += ']'
197+
return res
198+
}
199+
200+
fn (a[]int) free() {
201+
// println('array free')
202+
C.free(a.data)
203+
}
204+
205+
// TODO generic
206+
// "[ 'a', 'b', 'c' ]"
207+
fn (a[]string) str() string {
208+
mut res := '['
209+
for i := 0; i < a.len; i++ {
210+
val := a[i]
211+
res += '"$val"'
212+
if i < a.len - 1 {
213+
res += ', '
214+
}
215+
}
216+
res += ']'
217+
return res
218+
}
219+
220+
fn free(a voidptr) {
221+
C.free(a)
222+
}
223+

0 commit comments

Comments
 (0)