mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
JavaSript backend (early stage)
This commit is contained in:
@@ -58,7 +58,7 @@ fn new_array_from_c_array_no_alloc(len, cap, elm_size int, c_array voidptr) arra
|
||||
}
|
||||
|
||||
// Private function, used by V (`[0; 100]`)
|
||||
fn array_repeat(val voidptr, nr_repeats, elm_size int) array {
|
||||
fn array_repeat_old(val voidptr, nr_repeats, elm_size int) array {
|
||||
arr := array {
|
||||
len: nr_repeats
|
||||
cap: nr_repeats
|
||||
@@ -71,6 +71,35 @@ fn array_repeat(val voidptr, nr_repeats, elm_size int) array {
|
||||
return arr
|
||||
}
|
||||
|
||||
pub fn (a array) repeat(nr_repeats int) array {
|
||||
arr := array {
|
||||
len: nr_repeats
|
||||
cap: nr_repeats
|
||||
element_size: a.element_size
|
||||
data: malloc(nr_repeats * a.element_size)
|
||||
}
|
||||
val := a.data + 0 //nr_repeats * a.element_size
|
||||
for i := 0; i < nr_repeats; i++ {
|
||||
C.memcpy(arr.data + i * a.element_size, val, a.element_size)
|
||||
}
|
||||
return arr
|
||||
}
|
||||
|
||||
// TODO remove
|
||||
pub fn (a array) repeat2(nr_repeats int) array {
|
||||
arr := array {
|
||||
len: nr_repeats
|
||||
cap: nr_repeats
|
||||
element_size: a.element_size
|
||||
data: malloc(nr_repeats * a.element_size)
|
||||
}
|
||||
val := a.data + 0 //nr_repeats * a.element_size
|
||||
for i := 0; i < nr_repeats; i++ {
|
||||
C.memcpy(arr.data + i * a.element_size, val, a.element_size)
|
||||
}
|
||||
return arr
|
||||
}
|
||||
|
||||
pub fn (a mut array) sort_with_compare(compare voidptr) {
|
||||
C.qsort(a.data, a.len, a.element_size, compare)
|
||||
}
|
||||
@@ -232,7 +261,9 @@ pub fn (a []string) str() string {
|
||||
sb.write('[')
|
||||
for i := 0; i < a.len; i++ {
|
||||
val := a[i]
|
||||
sb.write('"$val"')
|
||||
sb.write('"')
|
||||
sb.write(val)
|
||||
sb.write('"')
|
||||
if i < a.len - 1 {
|
||||
sb.write(', ')
|
||||
}
|
||||
|
@@ -141,7 +141,7 @@ fn test_slice() {
|
||||
fn test_push_many() {
|
||||
mut a := [1, 2, 3]
|
||||
b := [4, 5, 6]
|
||||
a << b
|
||||
a << b
|
||||
assert a.len == 6
|
||||
assert a[0] == 1
|
||||
assert a[3] == 4
|
||||
@@ -163,42 +163,44 @@ fn test_reverse() {
|
||||
|
||||
const (
|
||||
N = 5
|
||||
)
|
||||
)
|
||||
|
||||
fn test_fixed() {
|
||||
mut nums := [4]int
|
||||
assert nums[0] == 0
|
||||
assert nums[1] == 0
|
||||
assert nums[2] == 0
|
||||
assert nums[3] == 0
|
||||
nums[1] = 7
|
||||
assert nums[1] == 7
|
||||
/*
|
||||
mut nums := [4]int
|
||||
assert nums[0] == 0
|
||||
assert nums[1] == 0
|
||||
assert nums[2] == 0
|
||||
assert nums[3] == 0
|
||||
nums[1] = 7
|
||||
assert nums[1] == 7
|
||||
///////
|
||||
nums2 := [N]int
|
||||
assert nums2[N - 1] == 0
|
||||
}
|
||||
nums2 := [N]int
|
||||
assert nums2[N - 1] == 0
|
||||
*/
|
||||
}
|
||||
|
||||
fn modify (numbers mut []int) {
|
||||
numbers[0] = 777
|
||||
}
|
||||
|
||||
fn test_mut_slice() {
|
||||
fn test_mut_slice() {
|
||||
mut n := [1,2,3]
|
||||
modify(mut n.left(2))
|
||||
assert n[0] == 777
|
||||
modify(mut n.right(2))
|
||||
assert n[2] == 777
|
||||
modify(mut n.left(2))
|
||||
assert n[0] == 777
|
||||
modify(mut n.right(2))
|
||||
assert n[2] == 777
|
||||
println(n)
|
||||
}
|
||||
|
||||
fn test_clone() {
|
||||
nums := [1, 2, 3, 4, 100]
|
||||
nums2 := nums.clone()
|
||||
assert nums2.len == 5
|
||||
assert nums2.str() == '[1, 2, 3, 4, 100]'
|
||||
assert nums.slice(1, 3).str() == '[2, 3]'
|
||||
}
|
||||
|
||||
nums := [1, 2, 3, 4, 100]
|
||||
nums2 := nums.clone()
|
||||
assert nums2.len == 5
|
||||
assert nums2.str() == '[1, 2, 3, 4, 100]'
|
||||
assert nums.slice(1, 3).str() == '[2, 3]'
|
||||
}
|
||||
|
||||
fn test_doubling() {
|
||||
mut nums := [1, 2, 3, 4, 5]
|
||||
for i := 0; i < nums.len; i++ {
|
||||
|
@@ -213,7 +213,7 @@ pub fn (c byte) is_capital() bool {
|
||||
}
|
||||
|
||||
pub fn (b []byte) clone() []byte {
|
||||
mut res := [byte(0); b.len]
|
||||
mut res := [byte(0)].repeat2(b.len)
|
||||
for i := 0; i < b.len; i++ {
|
||||
res[i] = b[i]
|
||||
}
|
||||
|
130
vlib/builtin/js/array.v
Normal file
130
vlib/builtin/js/array.v
Normal file
@@ -0,0 +1,130 @@
|
||||
// Copyright (c) 2019 Alexander Medvednikov. All rights reserved.
|
||||
// Use of this source code is governed by an MIT license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
module builtin
|
||||
|
||||
import strings
|
||||
|
||||
struct array {
|
||||
pub:
|
||||
data voidptr
|
||||
len int
|
||||
cap int
|
||||
element_size int
|
||||
}
|
||||
|
||||
/*
|
||||
// Private function, used by V (`nums := []int`)
|
||||
fn new_array(mylen, cap, elm_size int) array {
|
||||
arr := array {
|
||||
len: mylen
|
||||
cap: cap
|
||||
element_size: elm_size
|
||||
}
|
||||
return arr
|
||||
}
|
||||
|
||||
|
||||
// TODO
|
||||
pub fn _make(len, cap, elm_size int) array {
|
||||
return new_array(len, cap, elm_size)
|
||||
}
|
||||
|
||||
|
||||
*/
|
||||
fn array_repeat(val voidptr, nr_repeats, elm_size int) array {
|
||||
return val
|
||||
}
|
||||
|
||||
pub fn (a array) repeat2(nr_repeats int) array {
|
||||
#return Array(a[0]).fill(nr_repeats)
|
||||
return a
|
||||
}
|
||||
|
||||
pub fn (a mut array) sort_with_compare(compare voidptr) {
|
||||
}
|
||||
|
||||
pub fn (a mut array) insert(i int, val voidptr) {
|
||||
}
|
||||
|
||||
pub fn (a mut array) prepend(val voidptr) {
|
||||
a.insert(0, val)
|
||||
}
|
||||
|
||||
pub fn (a mut array) delete_elm(idx int) {
|
||||
}
|
||||
|
||||
/*
|
||||
pub fn (a array) first() voidptr {
|
||||
if a.len == 0 {
|
||||
panic('array.first: empty array')
|
||||
}
|
||||
return a.data + 0
|
||||
}
|
||||
|
||||
pub fn (a array) last() voidptr {
|
||||
if a.len == 0 {
|
||||
panic('array.last: empty array')
|
||||
}
|
||||
return a.data + (a.len - 1) * a.element_size
|
||||
}
|
||||
*/
|
||||
|
||||
pub fn (s array) left(n int) array {
|
||||
if n >= s.len {
|
||||
return s
|
||||
}
|
||||
return s.slice(0, n)
|
||||
}
|
||||
|
||||
pub fn (s array) right(n int) array {
|
||||
if n >= s.len {
|
||||
return s
|
||||
}
|
||||
return s.slice(n, s.len)
|
||||
}
|
||||
|
||||
pub fn (s array) slice(start, _end int) array {
|
||||
return s
|
||||
}
|
||||
|
||||
pub fn (a array) reverse() array {
|
||||
return a
|
||||
}
|
||||
|
||||
pub fn (a array) clone() array {
|
||||
return a
|
||||
}
|
||||
|
||||
pub fn (a array) free() {
|
||||
}
|
||||
|
||||
// "[ 'a', 'b', 'c' ]"
|
||||
pub fn (a []string) str() string {
|
||||
mut sb := strings.new_builder(a.len * 3)
|
||||
sb.write('[')
|
||||
for i := 0; i < a.len; i++ {
|
||||
val := a[i]
|
||||
sb.write('"')
|
||||
sb.write(val)
|
||||
sb.write('"')
|
||||
if i < a.len - 1 {
|
||||
sb.write(', ')
|
||||
}
|
||||
}
|
||||
sb.write(']')
|
||||
return sb.str()
|
||||
}
|
||||
|
||||
pub fn (b []byte) hex() string {
|
||||
return 'sdf'
|
||||
}
|
||||
|
||||
pub fn (arr mut array) _push_many(val voidptr, size int) {
|
||||
}
|
||||
|
||||
pub fn free(voidptr) {
|
||||
|
||||
}
|
||||
|
35
vlib/builtin/js/builtin.v
Normal file
35
vlib/builtin/js/builtin.v
Normal file
@@ -0,0 +1,35 @@
|
||||
// Copyright (c) 2019 Alexander Medvednikov. All rights reserved.
|
||||
// Use of this source code is governed by an MIT license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
module builtin
|
||||
|
||||
pub fn exit(code int) {
|
||||
println('js.exit()')
|
||||
}
|
||||
|
||||
// isnil returns true if an object is nil (only for C objects).
|
||||
pub fn isnil(v voidptr) bool {
|
||||
return v == 0
|
||||
}
|
||||
|
||||
pub fn panic(s string) {
|
||||
println('V panic: ' + s)
|
||||
exit(1)
|
||||
}
|
||||
|
||||
pub fn println(s string) {
|
||||
#console.log(s)
|
||||
}
|
||||
|
||||
pub fn eprintln(s string) {
|
||||
#console.log(s)
|
||||
}
|
||||
|
||||
pub fn print(s string) {
|
||||
#console.log(s)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
99
vlib/builtin/js/int.v
Normal file
99
vlib/builtin/js/int.v
Normal file
@@ -0,0 +1,99 @@
|
||||
// Copyright (c) 2019 Alexander Medvednikov. All rights reserved.
|
||||
// Use of this source code is governed by an MIT license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
module builtin
|
||||
|
||||
#include <float.h>
|
||||
#include <math.h>
|
||||
|
||||
pub fn (d double) str() string {
|
||||
return '0'
|
||||
}
|
||||
|
||||
pub fn (d f64) str() string {
|
||||
return '0'
|
||||
}
|
||||
|
||||
pub fn (d f32) str() string {
|
||||
return '0'
|
||||
}
|
||||
|
||||
pub fn ptr_str(ptr voidptr) string {
|
||||
return '0'
|
||||
}
|
||||
|
||||
// compare floats using C epsilon
|
||||
pub fn (a f64) eq(b f64) bool {
|
||||
//return C.fabs(a - b) <= C.DBL_EPSILON
|
||||
return (a - b) <= 0.01
|
||||
}
|
||||
|
||||
// fn (nn i32) str() string {
|
||||
// return i
|
||||
// }
|
||||
pub fn (nn int) str() string {
|
||||
return '0'
|
||||
}
|
||||
|
||||
pub fn (nn u32) str() string {
|
||||
return '0'
|
||||
}
|
||||
|
||||
pub fn (nn u8) str() string {
|
||||
return '0'
|
||||
}
|
||||
|
||||
pub fn (nn i64) str() string {
|
||||
return '0'
|
||||
}
|
||||
|
||||
pub fn (nn u64) str() string {
|
||||
return '0'
|
||||
}
|
||||
|
||||
pub fn (b bool) str() string {
|
||||
if b {
|
||||
return 'true'
|
||||
}
|
||||
return 'false'
|
||||
}
|
||||
|
||||
pub fn (n int) hex() string {
|
||||
return '0'
|
||||
}
|
||||
|
||||
pub fn (n i64) hex() string {
|
||||
return '0'
|
||||
}
|
||||
|
||||
pub fn (a []byte) contains(val byte) bool {
|
||||
for aa in a {
|
||||
if aa == val {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
pub fn (c rune) str() string {
|
||||
return '0'
|
||||
}
|
||||
|
||||
pub fn (c byte) str() string {
|
||||
return '0'
|
||||
}
|
||||
|
||||
pub fn (c byte) is_capital() bool {
|
||||
return c >= `A` && c <= `Z`
|
||||
}
|
||||
|
||||
pub fn (b []byte) clone() []byte {
|
||||
mut res := [byte(0)].repeat2(b.len)
|
||||
for i := 0; i < b.len; i++ {
|
||||
res[i] = b[i]
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
|
70
vlib/builtin/js/map.v
Normal file
70
vlib/builtin/js/map.v
Normal file
@@ -0,0 +1,70 @@
|
||||
// Copyright (c) 2019 Alexander Medvednikov. All rights reserved.
|
||||
// Use of this source code is governed by an MIT license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
module builtin
|
||||
|
||||
import strings
|
||||
|
||||
struct map {
|
||||
obj voidptr
|
||||
}
|
||||
|
||||
//fn (m mut map) insert(n mut mapnode, key string, val voidptr) {
|
||||
//}
|
||||
|
||||
//////fn (n & mapnode) find(key string, out voidptr, element_size int) bool{
|
||||
//return false
|
||||
//}
|
||||
|
||||
// same as `find`, but doesn't return a value. Used by `exists`
|
||||
//fn (n & mapnode) find2(key string, element_size int) bool{
|
||||
//return false
|
||||
//}
|
||||
|
||||
fn (m mut map) _set(key string, val voidptr) {
|
||||
}
|
||||
|
||||
//fn preorder_keys(node &mapnode, keys mut []string, key_i int) int {
|
||||
//return 0
|
||||
//}
|
||||
|
||||
pub fn (m mut map) keys() []string {
|
||||
return ['']
|
||||
}
|
||||
|
||||
fn (m map) get(key string, out voidptr) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
pub fn (m mut map) delete(key string) {
|
||||
}
|
||||
|
||||
fn (m map) _exists(key string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
pub fn (m map) print() {
|
||||
println('<<<<<<<<')
|
||||
println('>>>>>>>>>>')
|
||||
}
|
||||
|
||||
pub fn (m map) free() {
|
||||
// C.free(m.table)
|
||||
// C.free(m.keys_table)
|
||||
}
|
||||
|
||||
pub fn (m map_string) str() string {
|
||||
/*
|
||||
if m.size == 0 {
|
||||
return '{}'
|
||||
}
|
||||
*/
|
||||
mut sb := strings.new_builder(50)
|
||||
sb.writeln('{')
|
||||
for key, val in m {
|
||||
//sb.writeln(' "$key" => "$val"')
|
||||
}
|
||||
sb.writeln('}')
|
||||
return sb.str()
|
||||
}
|
31
vlib/builtin/js/option.v
Normal file
31
vlib/builtin/js/option.v
Normal file
@@ -0,0 +1,31 @@
|
||||
// Copyright (c) 2019 Alexander Medvednikov. All rights reserved.
|
||||
// Use of this source code is governed by an MIT license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
module builtin
|
||||
|
||||
struct Option {
|
||||
data [255]byte
|
||||
error string
|
||||
ok bool
|
||||
}
|
||||
|
||||
// `fn foo() ?Foo { return foo }` => `fn foo() ?Foo { return opt_ok(foo); }`
|
||||
fn opt_ok(data voidptr, size int) Option {
|
||||
if size >= 255 {
|
||||
panic('option size too big')
|
||||
}
|
||||
res := Option {
|
||||
ok: true
|
||||
}
|
||||
C.memcpy(res.data, data, size)
|
||||
return res
|
||||
}
|
||||
|
||||
pub fn error(s string) Option {
|
||||
return Option {
|
||||
error: s
|
||||
}
|
||||
}
|
||||
|
||||
|
318
vlib/builtin/js/string.v
Normal file
318
vlib/builtin/js/string.v
Normal file
@@ -0,0 +1,318 @@
|
||||
// Copyright (c) 2019 Alexander Medvednikov. All rights reserved.
|
||||
// Use of this source code is governed by an MIT license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
module builtin
|
||||
|
||||
struct string {
|
||||
//mut:
|
||||
//hash_cache int
|
||||
pub:
|
||||
str byteptr
|
||||
len int
|
||||
}
|
||||
|
||||
// For C strings only
|
||||
fn C.strlen(s byteptr) int
|
||||
|
||||
fn todo() { }
|
||||
|
||||
|
||||
pub fn (a string) clone() string {
|
||||
return a
|
||||
}
|
||||
|
||||
pub fn (s string) replace(rep, with_ string) string {
|
||||
return s
|
||||
}
|
||||
|
||||
pub fn (s string) int() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
pub fn (s string) i64() i64 {
|
||||
return 0
|
||||
}
|
||||
|
||||
pub fn (s string) f32() f32 {
|
||||
return 0.0
|
||||
}
|
||||
|
||||
pub fn (s string) f64() f64 {
|
||||
return 0.0
|
||||
}
|
||||
|
||||
pub fn (s string) u32() u32 {
|
||||
return u32(0)
|
||||
}
|
||||
|
||||
pub fn (s string) u64() u64 {
|
||||
return u64(0)
|
||||
}
|
||||
|
||||
pub fn (s string) split(delim string) []string {
|
||||
return s.split(delim)
|
||||
}
|
||||
|
||||
pub fn (s string) split_single(delim byte) []string {
|
||||
return s.split(delim.str())
|
||||
}
|
||||
|
||||
pub fn (s string) split_into_lines() []string {
|
||||
return s.split('\n')
|
||||
}
|
||||
|
||||
// 'hello'.left(2) => 'he'
|
||||
pub fn (s string) left(n int) string {
|
||||
if n >= s.len {
|
||||
return s
|
||||
}
|
||||
return s.substr(0, n)
|
||||
}
|
||||
// 'hello'.right(2) => 'llo'
|
||||
pub fn (s string) right(n int) string {
|
||||
if n >= s.len {
|
||||
return ''
|
||||
}
|
||||
return s.substr(n, s.len)
|
||||
}
|
||||
|
||||
pub fn (s string) substr(start, end int) string {
|
||||
return 'a'
|
||||
}
|
||||
|
||||
pub fn (s string) index(p string) int {
|
||||
return -1
|
||||
}
|
||||
|
||||
pub fn (s string) index_any(chars string) int {
|
||||
return -1
|
||||
}
|
||||
|
||||
pub fn (s string) last_index(p string) int {
|
||||
return -1
|
||||
}
|
||||
|
||||
pub fn (s string) index_after(p string, start int) int {
|
||||
return -1
|
||||
}
|
||||
|
||||
// counts occurrences of substr in s
|
||||
pub fn (s string) count(substr string) int {
|
||||
return 0 // TODO can never get here - v doesn't know that
|
||||
}
|
||||
|
||||
pub fn (s string) contains(p string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
pub fn (s string) starts_with(p string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
pub fn (s string) ends_with(p string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// TODO only works with ASCII
|
||||
pub fn (s string) to_lower() string {
|
||||
return s
|
||||
}
|
||||
|
||||
pub fn (s string) to_upper() string {
|
||||
return s
|
||||
}
|
||||
|
||||
pub fn (s string) capitalize() string {
|
||||
return s
|
||||
}
|
||||
|
||||
pub fn (s string) title() string {
|
||||
return s
|
||||
}
|
||||
|
||||
// 'hey [man] how you doin'
|
||||
// find_between('[', ']') == 'man'
|
||||
pub fn (s string) find_between(start, end string) string {
|
||||
start_pos := s.index(start)
|
||||
if start_pos == -1 {
|
||||
return ''
|
||||
}
|
||||
// First get everything to the right of 'start'
|
||||
val := s.right(start_pos + start.len)
|
||||
end_pos := val.index(end)
|
||||
if end_pos == -1 {
|
||||
return val
|
||||
}
|
||||
return val.left(end_pos)
|
||||
}
|
||||
|
||||
// TODO generic
|
||||
pub fn (ar []string) contains(val string) bool {
|
||||
for s in ar {
|
||||
if s == val {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// TODO generic
|
||||
pub fn (ar []int) contains(val int) bool {
|
||||
for i, s in ar {
|
||||
if s == val {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
fn is_space(c byte) bool {
|
||||
return C.isspace(c)
|
||||
}
|
||||
|
||||
pub fn (c byte) is_space() bool {
|
||||
return is_space(c)
|
||||
}
|
||||
|
||||
pub fn (s string) trim_space() string {
|
||||
#return s.str.trim(' ');
|
||||
return ''
|
||||
}
|
||||
|
||||
pub fn (s string) trim(cutset string) string {
|
||||
#return s.str.trim(cutset);
|
||||
return ''
|
||||
}
|
||||
|
||||
pub fn (s string) trim_left(cutset string) string {
|
||||
#return s.str.trimLeft(cutset);
|
||||
return ''
|
||||
}
|
||||
|
||||
pub fn (s string) trim_right(cutset string) string {
|
||||
#return s.str.trimRight(cutset);
|
||||
return ''
|
||||
}
|
||||
|
||||
// fn print_cur_thread() {
|
||||
// //C.printf("tid = %08x \n", pthread_self());
|
||||
// }
|
||||
pub fn (s mut []string) sort() {
|
||||
|
||||
}
|
||||
|
||||
pub fn (s mut []string) sort_ignore_case() {
|
||||
}
|
||||
|
||||
pub fn (s mut []string) sort_by_len() {
|
||||
}
|
||||
|
||||
fn (s string) at(idx int) byte {
|
||||
if idx < 0 || idx >= s.len {
|
||||
panic('string index out of range')
|
||||
}
|
||||
return s.str[idx]
|
||||
}
|
||||
pub fn (c byte) is_digit() bool {
|
||||
return c >= `0` && c <= `9`
|
||||
}
|
||||
|
||||
pub fn (c byte) is_hex_digit() bool {
|
||||
return c.is_digit() || (c >= `a` && c <= `f`) || (c >= `A` && c <= `F`)
|
||||
}
|
||||
|
||||
pub fn (c byte) is_oct_digit() bool {
|
||||
return c >= `0` && c <= `7`
|
||||
}
|
||||
|
||||
pub fn (c byte) is_letter() bool {
|
||||
return (c >= `a` && c <= `z`) || (c >= `A` && c <= `Z`)
|
||||
}
|
||||
|
||||
pub fn (s string) free() {
|
||||
}
|
||||
|
||||
/*
|
||||
fn (arr []string) free() {
|
||||
for s in arr {
|
||||
s.free()
|
||||
}
|
||||
C.free(arr.data)
|
||||
}
|
||||
*/
|
||||
|
||||
// all_before('23:34:45.234', '.') == '23:34:45'
|
||||
pub fn (s string) all_before(dot string) string {
|
||||
pos := s.index(dot)
|
||||
if pos == -1 {
|
||||
return s
|
||||
}
|
||||
return s.left(pos)
|
||||
}
|
||||
|
||||
pub fn (s string) all_before_last(dot string) string {
|
||||
pos := s.last_index(dot)
|
||||
if pos == -1 {
|
||||
return s
|
||||
}
|
||||
return s.left(pos)
|
||||
}
|
||||
|
||||
pub fn (s string) all_after(dot string) string {
|
||||
pos := s.last_index(dot)
|
||||
if pos == -1 {
|
||||
return s
|
||||
}
|
||||
return s.right(pos + dot.len)
|
||||
}
|
||||
|
||||
// fn (s []string) substr(a, b int) string {
|
||||
// return join_strings(s.slice_fast(a, b))
|
||||
// }
|
||||
pub fn (a []string) join(del string) string {
|
||||
return ''
|
||||
}
|
||||
|
||||
pub fn (s []string) join_lines() string {
|
||||
return s.join('\n')
|
||||
}
|
||||
|
||||
pub fn (s string) reverse() string {
|
||||
return s
|
||||
}
|
||||
|
||||
pub fn (s string) limit(max int) string {
|
||||
if s.len <= max {
|
||||
return s
|
||||
}
|
||||
return s.substr(0, max)
|
||||
}
|
||||
|
||||
// TODO is_white_space()
|
||||
pub fn (c byte) is_white() bool {
|
||||
i := int(c)
|
||||
return i == 10 || i == 32 || i == 9 || i == 13 || c == `\r`
|
||||
}
|
||||
|
||||
|
||||
pub fn (s string) hash() int {
|
||||
//mut h := s.hash_cache
|
||||
mut h := 0
|
||||
if h == 0 && s.len > 0 {
|
||||
for c in s {
|
||||
h = h * 31 + int(c)
|
||||
}
|
||||
}
|
||||
return h
|
||||
}
|
||||
|
||||
pub fn (s string) bytes() []byte {
|
||||
if s.len == 0 {
|
||||
return []byte
|
||||
}
|
||||
mut buf := [byte(0)].repeat2(s.len)
|
||||
C.memcpy(buf.data, s.str, s.len)
|
||||
return buf
|
||||
}
|
27
vlib/builtin/js/utf8.v
Normal file
27
vlib/builtin/js/utf8.v
Normal file
@@ -0,0 +1,27 @@
|
||||
// Copyright (c) 2019 Alexander Medvednikov. All rights reserved.
|
||||
// Use of this source code is governed by an MIT license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
module builtin
|
||||
|
||||
pub fn utf8_char_len(b byte) int {
|
||||
return (( 0xe5000000 >> (( b >> 3 ) & 0x1e )) & 3 ) + 1
|
||||
}
|
||||
|
||||
// Convert utf32 to utf8
|
||||
// utf32 == Codepoint
|
||||
pub fn utf32_to_str(code u32) string {
|
||||
return ''
|
||||
}
|
||||
|
||||
// TODO copypasta
|
||||
pub fn utf32_to_str_no_malloc(code u32, buf voidptr) string {
|
||||
return ''
|
||||
}
|
||||
|
||||
// Convert utf8 to utf32
|
||||
pub fn (_rune string) utf32_code() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
|
@@ -169,7 +169,7 @@ fn preorder_keys(node &mapnode, keys mut []string, key_i int) int {
|
||||
}
|
||||
|
||||
pub fn (m mut map) keys() []string {
|
||||
mut keys := [''; m.size]
|
||||
mut keys := [''].repeat2(m.size)
|
||||
if isnil(m.root) {
|
||||
return keys
|
||||
}
|
||||
|
@@ -78,10 +78,9 @@ pub fn (s string) replace(rep, with string) string {
|
||||
if s.len == 0 || rep.len == 0 {
|
||||
return s
|
||||
}
|
||||
// println('"$s" replace "$rep" with "$with" rep.len=$rep.len')
|
||||
// TODO PERF Allocating ints is expensive. Should be a stack array
|
||||
// Get locations of all reps within this string
|
||||
mut idxs := []int{}
|
||||
mut idxs := []int
|
||||
mut rem := s
|
||||
mut rstart := 0
|
||||
for {
|
||||
@@ -352,37 +351,58 @@ pub fn (s string) substr(start, end int) string {
|
||||
return res
|
||||
}
|
||||
|
||||
// KMP search
|
||||
pub fn (s string) index(p string) int {
|
||||
pub fn (s string) index_old(p string) int {
|
||||
if p.len > s.len {
|
||||
return -1
|
||||
}
|
||||
mut prefix := [0; p.len]
|
||||
mut j := 0
|
||||
for i := 1; i < p.len; i++ {
|
||||
for p[j] != p[i] && j > 0 {
|
||||
j = prefix[j - 1]
|
||||
}
|
||||
if p[j] == p[i] {
|
||||
j++
|
||||
}
|
||||
prefix[i] = j
|
||||
}
|
||||
j = 0
|
||||
for i := 0; i < s.len; i++ {
|
||||
for p[j] != s[i] && j > 0 {
|
||||
j = prefix[j - 1]
|
||||
}
|
||||
if p[j] == s[i] {
|
||||
mut i := 0
|
||||
for i < s.len {
|
||||
mut j := 0
|
||||
mut ii := i
|
||||
for j < p.len && s[ii] == p[j] {
|
||||
j++
|
||||
ii++
|
||||
}
|
||||
if j == p.len {
|
||||
return i - p.len + 1
|
||||
}
|
||||
i++
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
// KMP search
|
||||
pub fn (s string) index(p string) int {
|
||||
if p.len > s.len {
|
||||
return -1
|
||||
}
|
||||
mut prefix := [0].repeat2(p.len)
|
||||
mut j := 0
|
||||
for i := 1; i < p.len; i++ {
|
||||
for p[j] != p[i] && j > 0 {
|
||||
j = prefix[j - 1]
|
||||
}
|
||||
if p[j] == p[i] {
|
||||
j++
|
||||
}
|
||||
prefix[i] = j
|
||||
}
|
||||
j = 0
|
||||
for i := 0; i < s.len; i++ {
|
||||
for p[j] != s[i] && j > 0 {
|
||||
j = prefix[j - 1]
|
||||
}
|
||||
if p[j] == s[i] {
|
||||
j++
|
||||
}
|
||||
if j == p.len {
|
||||
return i - p.len + 1
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
|
||||
pub fn (s string) index_any(chars string) int {
|
||||
for c in chars {
|
||||
index := s.index(c.str())
|
||||
@@ -874,7 +894,7 @@ pub fn (s string) bytes() []byte {
|
||||
if s.len == 0 {
|
||||
return []byte
|
||||
}
|
||||
mut buf := [byte(0); s.len]
|
||||
mut buf := [byte(0)].repeat2(s.len)
|
||||
C.memcpy(buf.data, s.str, s.len)
|
||||
return buf
|
||||
}
|
||||
|
22
vlib/os/os.v
22
vlib/os/os.v
@@ -69,25 +69,6 @@ fn C.ftell(fp voidptr) int
|
||||
fn C.getenv(byteptr) byteptr
|
||||
fn C.sigaction(int, voidptr, int)
|
||||
|
||||
fn init_os_args(argc int, argv &byteptr) []string {
|
||||
mut args := []string
|
||||
$if windows {
|
||||
mut args_list := &voidptr(0)
|
||||
mut args_count := 0
|
||||
args_list = C.CommandLineToArgvW(C.GetCommandLine(), &args_count)
|
||||
for i := 0; i < args_count; i++ {
|
||||
args << string_from_wide(&u16(args_list[i]))
|
||||
}
|
||||
|
||||
C.LocalFree(args_list)
|
||||
} $else {
|
||||
for i := 0; i < argc; i++ {
|
||||
args << string(argv[i])
|
||||
}
|
||||
}
|
||||
return args
|
||||
}
|
||||
|
||||
fn parse_windows_cmd_line(cmd byteptr) []string {
|
||||
s := string(cmd)
|
||||
return s.split(' ')
|
||||
@@ -100,8 +81,7 @@ pub fn read_file(path string) ?string {
|
||||
$if windows {
|
||||
fp = C._wfopen(path.to_wide(), mode.to_wide())
|
||||
} $else {
|
||||
cpath := path.str
|
||||
fp = C.fopen(cpath, mode.str)
|
||||
fp = C.fopen(path.str, mode.str)
|
||||
}
|
||||
if isnil(fp) {
|
||||
return error('failed to open file "$path"')
|
||||
|
@@ -7,6 +7,14 @@ const (
|
||||
PathSeparator = '/'
|
||||
)
|
||||
|
||||
fn init_os_args(argc int, argv &byteptr) []string {
|
||||
mut args := []string
|
||||
for i := 0; i < argc; i++ {
|
||||
args << string(argv[i])
|
||||
}
|
||||
return args
|
||||
}
|
||||
|
||||
|
||||
// get_error_msg return error code representation in string.
|
||||
pub fn get_error_msg(code int) string {
|
||||
|
@@ -4,8 +4,8 @@ module os
|
||||
#include <winsock2.h>
|
||||
|
||||
const (
|
||||
PathSeparator = '\\'
|
||||
)
|
||||
PathSeparator = '\\'
|
||||
)
|
||||
|
||||
// Ref - https://docs.microsoft.com/en-us/windows/desktop/winprog/windows-data-types
|
||||
// A handle to an object.
|
||||
@@ -30,7 +30,7 @@ mut:
|
||||
nFileSizeLow u32
|
||||
dwReserved0 u32
|
||||
dwReserved1 u32
|
||||
cFileName [260]u16 // MAX_PATH = 260
|
||||
cFileName [260]u16 // MAX_PATH = 260
|
||||
cAlternateFileName [14]u16 // 14
|
||||
dwFileType u32
|
||||
dwCreatorType u32
|
||||
@@ -38,6 +38,18 @@ mut:
|
||||
}
|
||||
|
||||
|
||||
fn init_os_args(argc int, argv &byteptr) []string {
|
||||
mut args := []string
|
||||
mut args_list := &voidptr(0)
|
||||
mut args_count := 0
|
||||
args_list = C.CommandLineToArgvW(C.GetCommandLine(), &args_count)
|
||||
for i := 0; i < args_count; i++ {
|
||||
args << string_from_wide(&u16(args_list[i]))
|
||||
}
|
||||
C.LocalFree(args_list)
|
||||
return args
|
||||
}
|
||||
|
||||
|
||||
pub fn ls(path string) []string {
|
||||
mut find_file_data := win32finddata{}
|
||||
@@ -54,7 +66,7 @@ pub fn ls(path string) []string {
|
||||
}
|
||||
// NOTE: Should eventually have path struct & os dependant path seperator (eg os.PATH_SEPERATOR)
|
||||
// we need to add files to path eg. c:\windows\*.dll or :\windows\*
|
||||
path_files := '$path\\*'
|
||||
path_files := '$path\\*'
|
||||
// NOTE:TODO: once we have a way to convert utf16 wide character to utf8
|
||||
// we should use FindFirstFileW and FindNextFileW
|
||||
h_find_files := C.FindFirstFile(path_files.to_wide(), &find_file_data)
|
||||
@@ -70,7 +82,7 @@ pub fn ls(path string) []string {
|
||||
}
|
||||
C.FindClose(h_find_files)
|
||||
return dir_files
|
||||
}
|
||||
}
|
||||
|
||||
pub fn dir_exists(path string) bool {
|
||||
_path := path.replace('/', '\\')
|
||||
@@ -82,7 +94,7 @@ pub fn dir_exists(path string) bool {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// mkdir creates a new directory with the specified path.
|
||||
pub fn mkdir(path string) {
|
||||
@@ -93,7 +105,7 @@ pub fn mkdir(path string) {
|
||||
mkdir(_path.all_before_last('\\'))
|
||||
}
|
||||
C.CreateDirectory(_path.to_wide(), 0)
|
||||
}
|
||||
}
|
||||
|
||||
// Ref - https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/get-osfhandle?view=vs-2019
|
||||
// get_file_handle retrieves the operating-system file handle that is associated with the specified file descriptor.
|
||||
@@ -108,10 +120,10 @@ pub fn get_file_handle(path string) HANDLE {
|
||||
}
|
||||
|
||||
// Ref - https://docs.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-getmodulefilenamea
|
||||
// get_module_filename retrieves the fully qualified path for the file that contains the specified module.
|
||||
// get_module_filename retrieves the fully qualified path for the file that contains the specified module.
|
||||
// The module must have been loaded by the current process.
|
||||
pub fn get_module_filename(handle HANDLE) ?string {
|
||||
mut sz := int(4096) // Optimized length
|
||||
mut sz := int(4096) // Optimized length
|
||||
mut buf := &u16(malloc(4096))
|
||||
for {
|
||||
status := C.GetModuleFileName(handle, &buf, sz)
|
||||
@@ -142,15 +154,15 @@ const (
|
||||
SUBLANG_NEUTRAL = 0x00
|
||||
SUBLANG_DEFAULT = 0x01
|
||||
LANG_NEUTRAL = (SUBLANG_NEUTRAL)
|
||||
)
|
||||
)
|
||||
|
||||
// Ref - https://docs.microsoft.com/en-us/windows/win32/debug/system-error-codes--12000-15999-
|
||||
const (
|
||||
MAX_ERROR_CODE = 15841 // ERROR_API_UNAVAILABLE
|
||||
)
|
||||
|
||||
// ptr_win_get_error_msg return string (voidptr)
|
||||
// representation of error, only for windows.
|
||||
// ptr_win_get_error_msg return string (voidptr)
|
||||
// representation of error, only for windows.
|
||||
fn ptr_win_get_error_msg(code u32) voidptr {
|
||||
mut buf := voidptr(0)
|
||||
// Check for code overflow
|
||||
|
@@ -2,10 +2,10 @@
|
||||
// Use of this source code is governed by an MIT license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
module strings
|
||||
module strings
|
||||
|
||||
struct Builder {
|
||||
mut:
|
||||
mut:
|
||||
buf []byte
|
||||
pub:
|
||||
len int
|
||||
@@ -13,19 +13,19 @@ pub:
|
||||
|
||||
pub fn new_builder(initial_size int) Builder {
|
||||
return Builder {
|
||||
buf: _make(0, initial_size, sizeof(byte))
|
||||
//buf: _make(0, initial_size, sizeof(byte))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (b mut Builder) write(s string) {
|
||||
b.buf._push_many(s.str, s.len)
|
||||
//b.buf << []byte(s) // TODO
|
||||
//b.buf << []byte(s) // TODO
|
||||
b.len += s.len
|
||||
}
|
||||
|
||||
pub fn (b mut Builder) writeln(s string) {
|
||||
b.buf._push_many(s.str, s.len)
|
||||
//b.buf << []byte(s) // TODO
|
||||
//b.buf << []byte(s) // TODO
|
||||
b.buf << `\n`
|
||||
b.len += s.len + 1
|
||||
}
|
||||
|
@@ -1,9 +1,11 @@
|
||||
module strings
|
||||
|
||||
#-js
|
||||
|
||||
// use levenshtein distance algorithm to calculate
|
||||
// the distance between between two strings (lower is closer)
|
||||
pub fn levenshtein_distance(a, b string) int {
|
||||
mut f := [int(0); b.len+1]
|
||||
mut f := [0].repeat2(b.len+1)
|
||||
for ca in a {
|
||||
mut j := 1
|
||||
mut fj1 := f[0]
|
||||
|
@@ -1,11 +1,11 @@
|
||||
module strings
|
||||
module strings
|
||||
|
||||
pub fn repeat(c byte, n int) string {
|
||||
if n <= 0 {
|
||||
return ''
|
||||
}
|
||||
mut arr := malloc(n + 1)
|
||||
//mut arr := [byte(0); n + 1]
|
||||
//mut arr := malloc(n + 1)
|
||||
mut arr := [byte(0)].repeat2(n + 1)
|
||||
for i := 0; i < n; i++ {
|
||||
arr[i] = c
|
||||
}
|
||||
|
Reference in New Issue
Block a user