builtin: public/private functions, remove lots of duplicate functionality

(string.eq, compare_strings, etc)
pull/701/head
Alexander Medvednikov 2019-06-27 13:14:59 +02:00
parent b846d02cb2
commit 76bf732e63
15 changed files with 109 additions and 120 deletions

View File

@ -63,18 +63,18 @@ fn array_repeat(val voidptr, nr_repeats, elm_size int) array {
return arr return arr
} }
fn (a mut array) append_array(b array) { pub fn (a mut array) append_array(b array) {
for i := 0; i < b.len; i++ { for i := 0; i < b.len; i++ {
val := b[i] val := b[i]
a._push(val) a._push(val)
} }
} }
fn (a mut array) sort_with_compare(compare voidptr) { pub fn (a mut array) sort_with_compare(compare voidptr) {
C.qsort(a.data, a.len, a.element_size, compare) C.qsort(a.data, a.len, a.element_size, compare)
} }
fn (a mut array) insert(i int, val voidptr) { pub fn (a mut array) insert(i int, val voidptr) {
if i >= a.len { if i >= a.len {
panic('array.insert: index larger than length') panic('array.insert: index larger than length')
return return
@ -85,11 +85,11 @@ fn (a mut array) insert(i int, val voidptr) {
a.set(i, val) a.set(i, val)
} }
fn (a mut array) prepend(val voidptr) { pub fn (a mut array) prepend(val voidptr) {
a.insert(0, val) a.insert(0, val)
} }
fn (a mut array) delete(idx int) { pub fn (a mut array) delete(idx int) {
size := a.element_size size := a.element_size
C.memmove(a.data + idx * size, a.data + (idx + 1) * size, (a.len - idx) * size) C.memmove(a.data + idx * size, a.data + (idx + 1) * size, (a.len - idx) * size)
a.len-- a.len--
@ -103,28 +103,28 @@ fn (a array) _get(i int) voidptr {
return a.data + i * a.element_size return a.data + i * a.element_size
} }
fn (a array) first() voidptr { pub fn (a array) first() voidptr {
if a.len == 0 { if a.len == 0 {
panic('array.first: empty array') panic('array.first: empty array')
} }
return a.data + 0 return a.data + 0
} }
fn (a array) last() voidptr { pub fn (a array) last() voidptr {
if a.len == 0 { if a.len == 0 {
panic('array.last: empty array') panic('array.last: empty array')
} }
return a.data + (a.len - 1) * a.element_size return a.data + (a.len - 1) * a.element_size
} }
fn (s array) left(n int) array { pub fn (s array) left(n int) array {
if n >= s.len { if n >= s.len {
return s return s
} }
return s.slice(0, n) return s.slice(0, n)
} }
fn (s array) right(n int) array { pub fn (s array) right(n int) array {
if n >= s.len { if n >= s.len {
return s return s
} }
@ -149,14 +149,14 @@ pub fn (s array) slice(start, _end int) array {
return res return res
} }
fn (a mut array) set(idx int, val voidptr) { pub fn (a mut array) set(idx int, val voidptr) {
if idx < 0 || idx >= a.len { if idx < 0 || idx >= a.len {
panic('array index out of range: $idx / $a.len') panic('array index out of range: $idx / $a.len')
} }
C.memcpy(a.data + a.element_size * idx, val, a.element_size) C.memcpy(a.data + a.element_size * idx, val, a.element_size)
} }
fn (arr mut array) _push(val voidptr) { pub fn (arr mut array) _push(val voidptr) {
if arr.len >= arr.cap - 1 { if arr.len >= arr.cap - 1 {
cap := (arr.len + 1) * 2 cap := (arr.len + 1) * 2
// println('_push: realloc, new cap=$cap') // println('_push: realloc, new cap=$cap')
@ -172,7 +172,7 @@ fn (arr mut array) _push(val voidptr) {
arr.len++ arr.len++
} }
fn (arr mut array) _push_many(val voidptr, size int) { pub fn (arr mut array) _push_many(val voidptr, size int) {
if arr.len >= arr.cap - size { if arr.len >= arr.cap - size {
cap := (arr.len + size) * 2 cap := (arr.len + size) * 2
// println('_push: realloc, new cap=$cap') // println('_push: realloc, new cap=$cap')
@ -188,7 +188,7 @@ fn (arr mut array) _push_many(val voidptr, size int) {
arr.len += size arr.len += size
} }
fn (a[]int) str() string { pub fn (a[]int) str() string {
mut res := '[' mut res := '['
for i := 0; i < a.len; i++ { for i := 0; i < a.len; i++ {
val := a[i] val := a[i]
@ -201,14 +201,14 @@ fn (a[]int) str() string {
return res return res
} }
fn (a[]int) free() { pub fn (a[]int) free() {
// println('array free') // println('array free')
C.free(a.data) C.free(a.data)
} }
// TODO generic // TODO generic
// "[ 'a', 'b', 'c' ]" // "[ 'a', 'b', 'c' ]"
fn (a[]string) str() string { pub fn (a[]string) str() string {
mut res := '[' mut res := '['
for i := 0; i < a.len; i++ { for i := 0; i < a.len; i++ {
val := a[i] val := a[i]

View File

@ -111,13 +111,4 @@ pub fn error(s string) Option {
} }
} }
// TODO this is not used anymore
fn range_int(start, end int) []int {
len := end - start
mut res := [0; len]
for i := 0; i < len; i++ {
res[i] = start + i
}
return res
}

View File

@ -4,31 +4,25 @@
module builtin module builtin
fn (d double) str() string { pub fn (d double) str() string {
buf := malloc(sizeof(double) * 5 + 1)// TODO buf := malloc(sizeof(double) * 5 + 1)// TODO
C.sprintf(buf, '%f', d) C.sprintf(buf, '%f', d)
return tos(buf, _strlen(buf)) return tos(buf, _strlen(buf))
} }
fn (d float) str() string { pub fn (d f64) str() string {
buf := malloc(sizeof(double) * 5 + 1)// TODO buf := malloc(sizeof(double) * 5 + 1)// TODO
C.sprintf(buf, '%f', d) C.sprintf(buf, '%f', d)
return tos(buf, _strlen(buf)) return tos(buf, _strlen(buf))
} }
fn (d f64) str() string { pub fn (d f32) str() string {
buf := malloc(sizeof(double) * 5 + 1)// TODO buf := malloc(sizeof(double) * 5 + 1)// TODO
C.sprintf(buf, '%f', d) C.sprintf(buf, '%f', d)
return tos(buf, _strlen(buf)) return tos(buf, _strlen(buf))
} }
fn (d f32) str() string { pub fn ptr_str(ptr voidptr) string {
buf := malloc(sizeof(double) * 5 + 1)// TODO
C.sprintf(buf, '%f', d)
return tos(buf, _strlen(buf))
}
fn ptr_str(ptr voidptr) string {
buf := malloc(sizeof(double) * 5 + 1)// TODO buf := malloc(sizeof(double) * 5 + 1)// TODO
C.sprintf(buf, '%p', ptr) C.sprintf(buf, '%p', ptr)
return tos(buf, _strlen(buf)) return tos(buf, _strlen(buf))
@ -37,7 +31,7 @@ fn ptr_str(ptr voidptr) string {
// fn (nn i32) str() string { // fn (nn i32) str() string {
// return i // return i
// } // }
fn (nn int) str() string { pub fn (nn int) str() string {
mut n = nn mut n = nn
if n == 0 { if n == 0 {
return '0' return '0'
@ -65,8 +59,8 @@ fn (nn int) str() string {
return tos(buf + max - len, len) return tos(buf + max - len, len)
} }
fn (nn u8) str() string { pub fn (nn u8) str() string {
mut n = nn mut n = nn
if n == u8(0) { if n == u8(0) {
return '0' return '0'
} }
@ -93,7 +87,7 @@ fn (nn u8) str() string {
return tos(buf + max - len, len) return tos(buf + max - len, len)
} }
fn (nn i64) str() string { pub fn (nn i64) str() string {
mut n = nn mut n = nn
if n == i64(0) { if n == i64(0) {
return '0' return '0'
@ -121,28 +115,28 @@ fn (nn i64) str() string {
return tos(buf + max - len, len) return tos(buf + max - len, len)
} }
fn (b bool) str() string { pub fn (b bool) str() string {
if b { if b {
return 'true' return 'true'
} }
return 'false' return 'false'
} }
fn (n int) hex() string { pub fn (n int) hex() string {
s := n.str() s := n.str()
hex := malloc(s.len + 2) hex := malloc(s.len + 2)
C.sprintf(hex, '0x%x', n) C.sprintf(hex, '0x%x', n)
return tos(hex, s.len + 2) return tos(hex, s.len + 2)
} }
fn (n i64) hex() string { pub fn (n i64) hex() string {
s := n.str() s := n.str()
hex := malloc(s.len + 2) hex := malloc(s.len + 2)
C.sprintf(hex, '0x%x', n) C.sprintf(hex, '0x%x', n)
return tos(hex, s.len + 2) return tos(hex, s.len + 2)
} }
fn (a[]byte) contains(val byte) bool { pub fn (a[]byte) contains(val byte) bool {
for aa in a { for aa in a {
if aa == val { if aa == val {
return true return true
@ -155,7 +149,7 @@ fn (a[]byte) contains(val byte) bool {
fn (c rune) str() string { fn (c rune) str() string {
} }
*/ */
fn (c byte) str() string { pub fn (c byte) str() string {
mut str := string { mut str := string {
len: 1 len: 1
str: malloc(2) str: malloc(2)

View File

@ -25,7 +25,7 @@ pub:
// next *Entry // next *Entry
} }
fn new_map(cap, elm_size int) map { pub fn new_map(cap, elm_size int) map {
res := map { res := map {
// len: len, // len: len,
element_size: elm_size element_size: elm_size
@ -108,7 +108,7 @@ pub fn (m mut map) sort() {
m.is_sorted = true m.is_sorted = true
} }
fn (m map) keys() []string { pub fn (m map) keys() []string {
mut keys := []string{} mut keys := []string{}
for i := 0; i < m.entries.len; i++ { for i := 0; i < m.entries.len; i++ {
entry := m.entries[i] entry := m.entries[i]
@ -133,7 +133,7 @@ fn (m map) get(key string, out voidptr) bool {
return false return false
} }
fn (m map) exists(key string) bool { pub fn (m map) exists(key string) bool {
for i := 0; i < m.entries.len; i++ { for i := 0; i < m.entries.len; i++ {
entry := m.entries[i] entry := m.entries[i]
if entry.key == key { if entry.key == key {
@ -143,7 +143,7 @@ fn (m map) exists(key string) bool {
return false return false
} }
fn (m map) print() { pub fn (m map) print() {
println('<<<<<<<<') println('<<<<<<<<')
for i := 0; i < m.entries.len; i++ { for i := 0; i < m.entries.len; i++ {
// entry := m.entries[i] // entry := m.entries[i]
@ -160,12 +160,12 @@ fn (m map) print() {
println('>>>>>>>>>>') println('>>>>>>>>>>')
} }
fn (m map) free() { pub fn (m map) free() {
// C.free(m.table) // C.free(m.table)
// C.free(m.keys_table) // C.free(m.keys_table)
} }
fn (m map_string) str() string { pub fn (m map_string) str() string {
// return 'not impl' // return 'not impl'
if m.entries.len == 0 { if m.entries.len == 0 {
return '{}' return '{}'

View File

@ -21,8 +21,10 @@ pub:
// For C strings only // For C strings only
fn C.strlen(s byteptr) int fn C.strlen(s byteptr) int
fn todo() { }
// Converts a C string to a V string // Converts a C string to a V string
fn tos(s byteptr, len int) string { pub fn tos(s byteptr, len int) string {
// This should never happen. // This should never happen.
if isnil(s) { if isnil(s) {
panic('tos(): nil string') panic('tos(): nil string')
@ -33,7 +35,7 @@ fn tos(s byteptr, len int) string {
} }
} }
fn tos_clone(s byteptr) string { pub fn tos_clone(s byteptr) string {
if isnil(s) { if isnil(s) {
panic('tos: nil string') panic('tos: nil string')
return string{} return string{}
@ -43,7 +45,7 @@ fn tos_clone(s byteptr) string {
return res.clone() return res.clone()
} }
// Same as `tos`, but calculates the length itself. TODO bad name. // Same as `tos`, but calculates the length. Called by `string(bytes)` casts.
fn tos2(s byteptr) string { fn tos2(s byteptr) string {
if isnil(s) { if isnil(s) {
panic('tos2: nil string') panic('tos2: nil string')
@ -54,7 +56,7 @@ fn tos2(s byteptr) string {
return res return res
} }
fn (a string) clone() string { pub fn (a string) clone() string {
mut b := string { mut b := string {
len: a.len len: a.len
str: malloc(a.len + 1) str: malloc(a.len + 1)
@ -66,7 +68,7 @@ fn (a string) clone() string {
return b return b
} }
fn (s string) cstr() byteptr { pub fn (s string) cstr() byteptr {
clone := s.clone() clone := s.clone()
return clone.str return clone.str
} }
@ -134,11 +136,11 @@ pub fn (s string) replace(rep, with string) string {
return tos(b, new_len) return tos(b, new_len)
} }
fn (s string) int() int { pub fn (s string) int() int {
return C.atoi(s.str) return C.atoi(s.str)
} }
fn (s string) f32() f32 { pub fn (s string) f32() f32 {
return C.atof(s.str) return C.atof(s.str)
} }
@ -195,7 +197,7 @@ fn (s string) ge(a string) bool {
} }
// TODO `fn (s string) + (a string)` ? To be consistent with operator overloading syntax. // TODO `fn (s string) + (a string)` ? To be consistent with operator overloading syntax.
fn (s string) add(a string) string { pub fn (s string) add(a string) string {
new_len := a.len + s.len new_len := a.len + s.len
mut res := string { mut res := string {
len: new_len len: new_len
@ -256,7 +258,7 @@ pub fn (s string) split(delim string) []string {
return res return res
} }
fn (s string) split_single(delim byte) []string { pub fn (s string) split_single(delim byte) []string {
mut res := []string mut res := []string
if int(delim) == 0 { if int(delim) == 0 {
res << s res << s
@ -460,7 +462,7 @@ pub fn (s string) to_upper() string {
// 'hey [man] how you doin' // 'hey [man] how you doin'
// find_between('[', ']') == 'man' // find_between('[', ']') == 'man'
fn (s string) find_between(start, end string) string { pub fn (s string) find_between(start, end string) string {
start_pos := s.index(start) start_pos := s.index(start)
if start_pos == -1 { if start_pos == -1 {
return '' return ''
@ -475,7 +477,7 @@ fn (s string) find_between(start, end string) string {
} }
// TODO generic // TODO generic
fn (ar[]string) contains(val string) bool { pub fn (ar[]string) contains(val string) bool {
for s in ar { for s in ar {
if s == val { if s == val {
return true return true
@ -485,7 +487,7 @@ fn (ar[]string) contains(val string) bool {
} }
// TODO generic // TODO generic
fn (ar[]int) contains(val int) bool { pub fn (ar[]int) contains(val int) bool {
for i, s in ar { for i, s in ar {
if s == val { if s == val {
return true return true
@ -494,7 +496,7 @@ fn (ar[]int) contains(val int) bool {
return false return false
} }
fn (a[]string) to_c() voidptr { pub fn (a[]string) to_c() voidptr {
# char ** res = malloc(sizeof(char*) * a.len); # char ** res = malloc(sizeof(char*) * a.len);
for i := 0; i < a.len; i++ { for i := 0; i < a.len; i++ {
val := a[i] val := a[i]
@ -508,7 +510,7 @@ fn is_space(c byte) bool {
return C.isspace(c) return C.isspace(c)
} }
fn (c byte) is_space() bool { pub fn (c byte) is_space() bool {
return is_space(c) return is_space(c)
} }
@ -549,7 +551,7 @@ pub fn (s string) trim(c byte) string {
return res return res
} }
fn (s string) trim_left(cutset string) string { pub fn (s string) trim_left(cutset string) string {
mut start := s.index(cutset) mut start := s.index(cutset)
if start != 0 { if start != 0 {
return s return s
@ -560,7 +562,7 @@ fn (s string) trim_left(cutset string) string {
return s.right(start) return s.right(start)
} }
fn (s string) trim_right(cutset string) string { pub fn (s string) trim_right(cutset string) string {
pos := s.last_index(cutset) pos := s.last_index(cutset)
if pos == -1 { if pos == -1 {
return s return s
@ -601,15 +603,15 @@ pub fn (s mut []string) sort() {
s.sort_with_compare(compare_strings) s.sort_with_compare(compare_strings)
} }
fn (s mut []string) sort_ignore_case() { pub fn (s mut []string) sort_ignore_case() {
s.sort_with_compare(compare_lower_strings) s.sort_with_compare(compare_lower_strings)
} }
fn (s mut []string) sort_by_len() { pub fn (s mut []string) sort_by_len() {
s.sort_with_compare(compare_strings_by_len) s.sort_with_compare(compare_strings_by_len)
} }
fn (s string) ustring() ustring { pub fn (s string) ustring() ustring {
mut res := ustring { mut res := ustring {
s: s s: s
// runes will have at least s.len elements, save reallocations // runes will have at least s.len elements, save reallocations
@ -631,7 +633,7 @@ fn (s string) ustring() ustring {
// It's called from functions like draw_text() where we know that the string is going to be freed // It's called from functions like draw_text() where we know that the string is going to be freed
// right away. Uses global buffer for storing runes []int array. // right away. Uses global buffer for storing runes []int array.
# array_int g_ustring_runes; # array_int g_ustring_runes;
fn (s string) ustring_tmp() ustring { pub fn (s string) ustring_tmp() ustring {
mut res := ustring { mut res := ustring {
s: s s: s
runes: 0 runes: 0
@ -681,7 +683,7 @@ fn (s string) at(idx int) byte {
return s.str[idx] return s.str[idx]
} }
fn (u ustring) at(idx int) string { pub fn (u ustring) at(idx int) string {
return u.substr(idx, idx + 1) return u.substr(idx, idx + 1)
} }
@ -696,11 +698,11 @@ fn abs(a int) int {
return -a return -a
} }
fn (c byte) is_digit() bool { pub fn (c byte) is_digit() bool {
return c >= `0` && c <= `9` return c >= `0` && c <= `9`
} }
fn (c byte) is_letter() bool { pub fn (c byte) is_letter() bool {
return (c >= `a` && c <= `z`) || (c >= `A` && c <= `Z`) return (c >= `a` && c <= `z`) || (c >= `A` && c <= `Z`)
} }
@ -716,7 +718,7 @@ fn (arr[]string) free() {
} }
// all_before('23:34:45.234', '.') == '23:34:45' // all_before('23:34:45.234', '.') == '23:34:45'
fn (s string) all_before(dot string) string { pub fn (s string) all_before(dot string) string {
pos := s.index(dot) pos := s.index(dot)
if pos == -1 { if pos == -1 {
return s return s
@ -724,7 +726,7 @@ fn (s string) all_before(dot string) string {
return s.left(pos) return s.left(pos)
} }
fn (s string) all_before_last(dot string) string { pub fn (s string) all_before_last(dot string) string {
pos := s.last_index(dot) pos := s.last_index(dot)
if pos == -1 { if pos == -1 {
return s return s
@ -732,7 +734,7 @@ fn (s string) all_before_last(dot string) string {
return s.left(pos) return s.left(pos)
} }
fn (s string) all_after(dot string) string { pub fn (s string) all_after(dot string) string {
pos := s.last_index(dot) pos := s.last_index(dot)
if pos == -1 { if pos == -1 {
return s return s
@ -776,11 +778,11 @@ pub fn (a[]string) join(del string) string {
return res return res
} }
fn (s[]string) join_lines() string { pub fn (s[]string) join_lines() string {
return s.join('\n') return s.join('\n')
} }
fn (s string) reverse() string { pub fn (s string) reverse() string {
mut res := string { mut res := string {
len: s.len len: s.len
str: malloc(s.len + 1) str: malloc(s.len + 1)
@ -795,7 +797,7 @@ fn (s string) reverse() string {
// 'hello'.limit(2) => 'he' // 'hello'.limit(2) => 'he'
// 'hi'.limit(10) => 'hi' // 'hi'.limit(10) => 'hi'
fn (s string) limit(max int) string { pub fn (s string) limit(max int) string {
u := s.ustring() u := s.ustring()
if u.len <= max { if u.len <= max {
return s return s
@ -804,13 +806,13 @@ fn (s string) limit(max int) string {
} }
// TODO is_white_space() // TODO is_white_space()
fn (c byte) is_white() bool { pub fn (c byte) is_white() bool {
i := int(c) i := int(c)
return i == 10 || i == 32 || i == 9 || i == 13 || c == `\r` return i == 10 || i == 32 || i == 9 || i == 13 || c == `\r`
} }
// TODO move this to strings.repeat() // TODO move this to strings.repeat()
fn repeat_char(c byte, n int) string { pub fn repeat_char(c byte, n int) string {
if n <= 0 { if n <= 0 {
return '' return ''
} }

View File

@ -9,31 +9,31 @@ struct StringBuilder {
len int len int
} }
fn new_string_builder(initial_size int) StringBuilder { pub fn new_string_builder(initial_size int) StringBuilder {
return StringBuilder { return StringBuilder {
buf: new_array(0, initial_size, sizeof(byte)) buf: new_array(0, initial_size, sizeof(byte))
} }
} }
fn (b mut StringBuilder) write(s string) { pub fn (b mut StringBuilder) write(s string) {
b.buf._push_many(s.str, s.len) b.buf._push_many(s.str, s.len)
b.len += s.len b.len += s.len
} }
fn (b mut StringBuilder) writeln(s string) { pub fn (b mut StringBuilder) writeln(s string) {
b.buf._push_many(s.str, s.len) b.buf._push_many(s.str, s.len)
b.buf << `\n` b.buf << `\n`
b.len += s.len + 1 b.len += s.len + 1
} }
fn (b StringBuilder) str() string { pub fn (b StringBuilder) str() string {
return tos(b.buf.data, b.len) return tos(b.buf.data, b.len)
} }
fn (b StringBuilder) cut(n int) { pub fn (b StringBuilder) cut(n int) {
b.len -= n b.len -= n
} }
fn (b mut StringBuilder) free() { pub fn (b mut StringBuilder) free() {
C.free(b.buf.data) C.free(b.buf.data)
} }

View File

@ -5,7 +5,7 @@
fn test_add() { fn test_add() {
mut a := 'a' mut a := 'a'
a += 'b' a += 'b'
assert a.eq('ab') assert a==('ab')
a = 'a' a = 'a'
for i := 1; i < 1000; i++ { for i := 1; i < 1000; i++ {
a += 'b' a += 'b'
@ -29,7 +29,7 @@ fn test_between() {
fn test_compare() { fn test_compare() {
a := 'Music' a := 'Music'
b := 'src' b := 'src'
assert b.ge(a) assert b>=(a)
} }
fn test_lt() { fn test_lt() {
@ -39,12 +39,12 @@ fn test_lt() {
d := 'b' d := 'b'
e := 'aa' e := 'aa'
f := 'ab' f := 'ab'
assert a.lt(b) assert a<(b)
assert b.lt(c) == false assert !(b<c)
assert c.lt(d) assert c<(d)
assert d.lt(e) == false assert !(d<e)
assert c.lt(e) assert c<(e)
assert e.lt(f) assert e<(f)
} }
fn test_ge() { fn test_ge() {
@ -53,11 +53,11 @@ fn test_ge() {
c := 'ab' c := 'ab'
d := 'abc' d := 'abc'
e := 'aaa' e := 'aaa'
assert b.ge(a) assert b>=(a)
assert c.ge(b) assert c>=(b)
assert d.ge(c) assert d>=(c)
assert c.ge(d) == false assert !(c>=d)
assert e.ge(a) assert e>=(a)
} }
fn test_compare_strings() { fn test_compare_strings() {
@ -150,13 +150,13 @@ fn test_clone() {
fn test_replace() { fn test_replace() {
a := 'hello man!' a := 'hello man!'
mut b := a.replace('man', 'world') mut b := a.replace('man', 'world')
assert b.eq('hello world!') assert b==('hello world!')
b = b.replace('!', '') b = b.replace('!', '')
assert b.eq('hello world') assert b==('hello world')
b = b.replace('h', 'H') b = b.replace('h', 'H')
assert b.eq('Hello world') assert b==('Hello world')
b = b.replace('kek', 'lul') b = b.replace('kek', 'lul')
assert b.eq('Hello world') assert b==('Hello world')
s := 'hey man how are you' s := 'hey man how are you'
assert s.replace('man ', '') == 'hey how are you' assert s.replace('man ', '') == 'hey how are you'
lol := 'lol lol lol' lol := 'lol lol lol'

View File

@ -4,7 +4,7 @@
module builtin module builtin
fn (s string) is_utf8() int { pub fn (s string) is_utf8() int {
faulty_bytes := 0 faulty_bytes := 0
len := s.len len := s.len
i := 0 i := 0
@ -250,7 +250,7 @@ fn (s string) runes() []string {
*/ */
// Convert utf32 to utf8 // Convert utf32 to utf8
// utf32 == Codepoint // utf32 == Codepoint
fn utf32_to_str(code u32) string { pub fn utf32_to_str(code u32) string {
// println('code = $code') // println('code = $code')
buffer := malloc(5) buffer := malloc(5)
# if (code <= 0x7F) { # if (code <= 0x7F) {
@ -282,7 +282,7 @@ fn utf32_to_str(code u32) string {
} }
// TODO copypasta // TODO copypasta
fn utf32_to_str_no_malloc(code u32, buf voidptr) string { pub fn utf32_to_str_no_malloc(code u32, buf voidptr) string {
// println('code = $code') // println('code = $code')
# char* buffer = buf; # char* buffer = buf;
# if (code <= 0x7F) { # if (code <= 0x7F) {
@ -314,7 +314,7 @@ fn utf32_to_str_no_malloc(code u32, buf voidptr) string {
} }
// Convert utf8 to utf32 // Convert utf8 to utf32
fn (_rune string) utf32_code() int { pub fn (_rune string) utf32_code() int {
// println('utf 32 of $rune len=$rune.len') // println('utf 32 of $rune len=$rune.len')
if _rune.len == 0 { if _rune.len == 0 {
return 0 return 0

View File

@ -9,6 +9,7 @@ v.c:
test: v test: v
find .. -name '*_test.v' -print0 | xargs -0 -n1 ./v find .. -name '*_test.v' -print0 | xargs -0 -n1 ./v
echo "Building V examples..."
find ../examples -name '*.v' -print0 | xargs -0 -n1 ./v find ../examples -name '*.v' -print0 | xargs -0 -n1 ./v
clean: clean:

View File

@ -493,7 +493,8 @@ fn (p mut Parser) async_fn_call(f Fn, method_ph int, receiver_var, receiver_type
} }
fn (p mut Parser) fn_call(f Fn, method_ph int, receiver_var, receiver_type string) { fn (p mut Parser) fn_call(f Fn, method_ph int, receiver_var, receiver_type string) {
if !f.is_public && !f.is_c && f.pkg != p.pkg && f.pkg != 'builtin' { //if !f.is_public && !f.is_c && f.pkg != p.pkg && f.pkg != 'builtin' {
if !f.is_public && !f.is_c && !p.is_test && f.pkg != p.pkg {
p.error('function `$f.name` is private') p.error('function `$f.name` is private')
} }
p.calling_c = f.is_c p.calling_c = f.is_c

View File

@ -1163,7 +1163,7 @@ fn (p mut Parser) bool_expression() string {
fn (p mut Parser) bterm() string { fn (p mut Parser) bterm() string {
ph := p.cgen.add_placeholder() ph := p.cgen.add_placeholder()
mut typ = p.expression() mut typ = p.expression()
is_str := typ.eq('string') is_str := typ=='string'
tok := p.tok tok := p.tok
// if tok in [ EQ, GT, LT, LE, GE, NE] { // if tok in [ EQ, GT, LT, LE, GE, NE] {
if tok == EQ || tok == GT || tok == LT || tok == LE || tok == GE || tok == NE { if tok == EQ || tok == GT || tok == LT || tok == LE || tok == GE || tok == NE {
@ -1762,7 +1762,7 @@ fn (p mut Parser) expression() string {
p.cgen('/* expr start*/') p.cgen('/* expr start*/')
ph := p.cgen.add_placeholder() ph := p.cgen.add_placeholder()
mut typ := p.term() mut typ := p.term()
is_str := typ.eq('string') is_str := typ=='string'
// a << b ==> array2_push(&a, b) // a << b ==> array2_push(&a, b)
if p.tok == LEFT_SHIFT { if p.tok == LEFT_SHIFT {
if typ.contains('array_') { if typ.contains('array_') {

View File

@ -442,7 +442,7 @@ fn (p mut Parser) _check_types(got, expected string, throw bool) bool {
return true return true
} }
// Todo void* allows everything right now // Todo void* allows everything right now
if got.eq('void*') || expected.eq('void*') { if got=='void*' || expected=='void*' {
// if !p.builtin_pkg { // if !p.builtin_pkg {
if p.is_play { if p.is_play {
return false return false
@ -451,17 +451,17 @@ fn (p mut Parser) _check_types(got, expected string, throw bool) bool {
} }
// TODO only allow numeric consts to be assigned to bytes, and // TODO only allow numeric consts to be assigned to bytes, and
// throw an error if they are bigger than 255 // throw an error if they are bigger than 255
if got.eq('int') && expected.eq('byte') { if got=='int' && expected=='byte' {
return true return true
} }
if got.eq('byteptr') && expected.eq('byte*') { if got=='byteptr' && expected=='byte*' {
return true return true
} }
if got.eq('int') && expected.eq('byte*') { if got=='int' && expected=='byte*' {
return true return true
} }
// byteptr += int // byteptr += int
if got.eq('int') && expected.eq('byteptr') { if got=='int' && expected=='byteptr' {
return true return true
} }
if got == 'Option' && expected.starts_with('Option_') { if got == 'Option' && expected.starts_with('Option_') {
@ -487,7 +487,7 @@ fn (p mut Parser) _check_types(got, expected string, throw bool) bool {
// return true // return true
// } // }
// Allow pointer arithmetic // Allow pointer arithmetic
if expected.eq('void*') && got.eq('int') { if expected=='void*' && got=='int' {
return true return true
} }
} }

View File

@ -21,7 +21,7 @@ fn display_help() {
fn option_parser() bool { fn option_parser() bool {
help := options{'--help', '-h'} help := options{'--help', '-h'}
for i := 0; i < os.args.len; i++ { for i := 0; i < os.args.len; i++ {
if compare_strings(os.args[i], help.long_opt) == 0 || compare_strings(os.args[i], help.short_opt) == 0 { if os.args[i]== help.long_opt || os.args[i]== help.short_opt {
display_help() display_help()
return true return true
} }
@ -116,7 +116,7 @@ fn is_broke(money int) bool {
quit := options{'yes', 'y'} quit := options{'yes', 'y'}
println('You\'ve $money V. Do you want to quit the casino with your winnings? (y/n)') println('You\'ve $money V. Do you want to quit the casino with your winnings? (y/n)')
line := os.get_line().trim_space().to_lower() line := os.get_line().trim_space().to_lower()
if compare_strings(line, quit.long_opt) == 0 || compare_strings(line, quit.short_opt) == 0 { if line== quit.long_opt || line== quit.short_opt {
return false return false
} }
} }

View File

@ -507,7 +507,7 @@ fn (ctx &GG) _draw_text(_x, _y int, utext ustring, cfg gx.TextCfg) {
for j := 0; j < ctx.utf_runes.len; j++ { for j := 0; j < ctx.utf_runes.len; j++ {
rune_j := ctx.utf_runes[j] rune_j := ctx.utf_runes[j]
// if string_eq(ctx.utf_runes[j], rune) { // if string_eq(ctx.utf_runes[j], rune) {
if rune_j.eq(_rune) { if rune_j==_rune {
ch = ctx.utf_chars[j] ch = ctx.utf_chars[j]
break break
} }

View File

@ -136,7 +136,7 @@ fn json_parse(s string) *C.cJSON {
// json_string := json_print(encode_User(user)) // json_string := json_print(encode_User(user))
fn json_print(json *C.cJSON) string { fn json_print(json *C.cJSON) string {
s := C.cJSON_PrintUnformatted(json) s := C.cJSON_PrintUnformatted(json)
return tos(s, _strlen(s)) return tos(s, C.strlen(s))
} }
// / cjson wrappers // / cjson wrappers