Replace all remaining C code with V in the compiler and vlib (hoorah!)
parent
554f083543
commit
6824e6e7db
|
@ -57,6 +57,7 @@ pub fn print(s string) {
|
||||||
C.printf('%.*s', s.len, s.str)
|
C.printf('%.*s', s.len, s.str)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__global total_m i64 = 0
|
||||||
pub fn malloc(n int) byteptr {
|
pub fn malloc(n int) byteptr {
|
||||||
if n < 0 {
|
if n < 0 {
|
||||||
panic('malloc(<0)')
|
panic('malloc(<0)')
|
||||||
|
@ -67,10 +68,8 @@ pub fn malloc(n int) byteptr {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef DEBUG_ALLOC
|
#ifdef DEBUG_ALLOC
|
||||||
total := i64(0)
|
total_m += n
|
||||||
# total_m += n;
|
println('\n\n\nmalloc($n) total=$total_m')
|
||||||
# total = total_m;
|
|
||||||
println('\n\n\nmalloc($n) total=$total')
|
|
||||||
print_backtrace()
|
print_backtrace()
|
||||||
#endif
|
#endif
|
||||||
ptr := C.malloc(n)
|
ptr := C.malloc(n)
|
||||||
|
|
|
@ -496,15 +496,17 @@ pub fn (ar[]int) contains(val int) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
pub 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]
|
||||||
# res[i] = val.str;
|
# res[i] = val.str;
|
||||||
}
|
}
|
||||||
# return res;
|
return res;
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
fn is_space(c byte) bool {
|
fn is_space(c byte) bool {
|
||||||
return C.isspace(c)
|
return C.isspace(c)
|
||||||
|
@ -619,8 +621,8 @@ pub fn (s string) ustring() ustring {
|
||||||
runes: new_array(0, s.len, sizeof(int))
|
runes: new_array(0, s.len, sizeof(int))
|
||||||
}
|
}
|
||||||
for i := 0; i < s.len; i++ {
|
for i := 0; i < s.len; i++ {
|
||||||
char_len := 0
|
char_len := utf8_char_len(s.str[i])
|
||||||
# char_len =UTF8_CHAR_LEN(s.str[i]);
|
//# char_len =UTF8_CHAR_LEN(s.str[i]);
|
||||||
// println('cl=$char_len')
|
// println('cl=$char_len')
|
||||||
res.runes << i
|
res.runes << i
|
||||||
i += char_len - 1
|
i += char_len - 1
|
||||||
|
@ -632,18 +634,19 @@ pub fn (s string) ustring() ustring {
|
||||||
// A hack that allows to create ustring without allocations.
|
// A hack that allows to create ustring without allocations.
|
||||||
// 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;
|
__global g_ustring_runes []int
|
||||||
pub 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
|
||||||
}
|
}
|
||||||
# res.runes = g_ustring_runes ;
|
res.runes = g_ustring_runes
|
||||||
# res.runes.len = s.len ;
|
res.runes.len = s.len
|
||||||
mut j := 0
|
mut j := 0
|
||||||
for i := 0; i < s.len; i++ {
|
for i := 0; i < s.len; i++ {
|
||||||
char_len := 0
|
//char_len := 0
|
||||||
# char_len =UTF8_CHAR_LEN(s.str[i]);
|
//# char_len =UTF8_CHAR_LEN(s.str[i]);
|
||||||
|
char_len := utf8_char_len(s.str[i])
|
||||||
res.runes[j] = i
|
res.runes[j] = i
|
||||||
j++
|
j++
|
||||||
i += char_len - 1
|
i += char_len - 1
|
||||||
|
|
244
builtin/utf8.v
244
builtin/utf8.v
|
@ -4,250 +4,10 @@
|
||||||
|
|
||||||
module builtin
|
module builtin
|
||||||
|
|
||||||
pub fn (s string) is_utf8() int {
|
pub fn utf8_char_len(b byte) int {
|
||||||
faulty_bytes := 0
|
return (( 0xe5000000 >> (( b >> 3 ) & 0x1e )) & 3 ) + 1
|
||||||
len := s.len
|
|
||||||
i := 0
|
|
||||||
// # size_t i = 0;
|
|
||||||
# byte * str = s.str;
|
|
||||||
#
|
|
||||||
# while (i < len) {
|
|
||||||
# if (str[i] <= 0x7F) /* 00..7F */ {
|
|
||||||
# i += 1;
|
|
||||||
# }
|
|
||||||
#else if (str[i] >= 0xC2 && str[i] <= 0xDF) /* C2..DF 80..BF */ {
|
|
||||||
# if (i + 1 < len) /* Expect a 2nd byte */ {
|
|
||||||
# if (str[i + 1] < 0x80 || str[i + 1] > 0xBF) {
|
|
||||||
# printf( "After a first byte between C2 and DF, expecting a 2nd byte between 80 and BF");
|
|
||||||
# faulty_bytes = 2;
|
|
||||||
# goto end;
|
|
||||||
# }
|
|
||||||
# }
|
|
||||||
#else {
|
|
||||||
# printf( "After a first byte between C2 and DF, expecting a 2nd byte.");
|
|
||||||
# faulty_bytes = 1;
|
|
||||||
# goto end;
|
|
||||||
# }
|
|
||||||
# i += 2;
|
|
||||||
# }
|
|
||||||
#else if (str[i] == 0xE0) /* E0 A0..BF 80..BF */ {
|
|
||||||
# if (i + 2 < len) /* Expect a 2nd and 3rd byte */ {
|
|
||||||
# if (str[i + 1] < 0xA0 || str[i + 1] > 0xBF) {
|
|
||||||
# printf( "After a first byte of E0, expecting a 2nd byte between A0 and BF.");
|
|
||||||
# faulty_bytes = 2;
|
|
||||||
# goto end;
|
|
||||||
# }
|
|
||||||
# if (str[i + 2] < 0x80 || str[i + 2] > 0xBF) {
|
|
||||||
# printf( "After a first byte of E0, expecting a 3nd byte between 80 and BF.");
|
|
||||||
# faulty_bytes = 3;
|
|
||||||
# goto end;
|
|
||||||
# }
|
|
||||||
# }
|
|
||||||
#else {
|
|
||||||
# printf( "After a first byte of E0, expecting two following bytes.");
|
|
||||||
# faulty_bytes = 1;
|
|
||||||
# goto end;
|
|
||||||
# }
|
|
||||||
# i += 3;
|
|
||||||
# }
|
|
||||||
#else if (str[i] >= 0xE1 && str[i] <= 0xEC) /* E1..EC 80..BF 80..BF */ {
|
|
||||||
# if (i + 2 < len) /* Expect a 2nd and 3rd byte */ {
|
|
||||||
# if (str[i + 1] < 0x80 || str[i + 1] > 0xBF) {
|
|
||||||
# printf( "After a first byte between E1 and EC, expecting the 2nd byte between 80 and BF.");
|
|
||||||
# faulty_bytes = 2;
|
|
||||||
# goto end;
|
|
||||||
# }
|
|
||||||
# if (str[i + 2] < 0x80 || str[i + 2] > 0xBF) {
|
|
||||||
# printf( "After a first byte between E1 and EC, expecting the 3rd byte between 80 and BF.");
|
|
||||||
# faulty_bytes = 3;
|
|
||||||
# goto end;
|
|
||||||
# }
|
|
||||||
# }
|
|
||||||
#else {
|
|
||||||
# printf( "After a first byte between E1 and EC, expecting two following bytes.");
|
|
||||||
# faulty_bytes = 1;
|
|
||||||
# goto end;
|
|
||||||
# }
|
|
||||||
# i += 3;
|
|
||||||
# }
|
|
||||||
#else if (str[i] == 0xED) /* ED 80..9F 80..BF */ {
|
|
||||||
# if (i + 2 < len) /* Expect a 2nd and 3rd byte */ {
|
|
||||||
# if (str[i + 1] < 0x80 || str[i + 1] > 0x9F) {
|
|
||||||
# printf( "After a first byte of ED, expecting 2nd byte between 80 and 9F.");
|
|
||||||
# faulty_bytes = 2;
|
|
||||||
# goto end;
|
|
||||||
# }
|
|
||||||
# if (str[i + 2] < 0x80 || str[i + 2] > 0xBF) {
|
|
||||||
# printf( "After a first byte of ED, expecting 3rd byte between 80 and BF.");
|
|
||||||
# faulty_bytes = 3;
|
|
||||||
# goto end;
|
|
||||||
# }
|
|
||||||
# }
|
|
||||||
#else {
|
|
||||||
# printf( "After a first byte of ED, expecting two following bytes.");
|
|
||||||
# faulty_bytes = 1;
|
|
||||||
# goto end;
|
|
||||||
# }
|
|
||||||
# i += 3;
|
|
||||||
# }
|
|
||||||
#else if (str[i] >= 0xEE && str[i] <= 0xEF) /* EE..EF 80..BF 80..BF */ {
|
|
||||||
# if (i + 2 < len) /* Expect a 2nd and 3rd byte */ {
|
|
||||||
# if (str[i + 1] < 0x80 || str[i + 1] > 0xBF) {
|
|
||||||
# printf( "After a first byte between EE and EF, expecting 2nd byte between 80 and BF.");
|
|
||||||
# faulty_bytes = 2;
|
|
||||||
# goto end;
|
|
||||||
# }
|
|
||||||
# if (str[i + 2] < 0x80 || str[i + 2] > 0xBF) {
|
|
||||||
# printf( "After a first byte between EE and EF, expecting 3rd byte between 80 and BF.");
|
|
||||||
# faulty_bytes = 3;
|
|
||||||
# goto end;
|
|
||||||
# }
|
|
||||||
# }
|
|
||||||
#else {
|
|
||||||
# printf( "After a first byte between EE and EF, two following bytes.");
|
|
||||||
# faulty_bytes = 1;
|
|
||||||
# goto end;
|
|
||||||
# }
|
|
||||||
# i += 3;
|
|
||||||
# }
|
|
||||||
#else if (str[i] == 0xF0) /* F0 90..BF 80..BF 80..BF */ {
|
|
||||||
# if (i + 3 < len) /* Expect a 2nd, 3rd 3th byte */ {
|
|
||||||
# if (str[i + 1] < 0x90 || str[i + 1] > 0xBF) {
|
|
||||||
# printf( "After a first byte of F0, expecting 2nd byte between 90 and BF.");
|
|
||||||
# faulty_bytes = 2;
|
|
||||||
# goto end;
|
|
||||||
# }
|
|
||||||
# if (str[i + 2] < 0x80 || str[i + 2] > 0xBF) {
|
|
||||||
# printf( "After a first byte of F0, expecting 3rd byte between 80 and BF.");
|
|
||||||
# faulty_bytes = 3;
|
|
||||||
# goto end;
|
|
||||||
# }
|
|
||||||
# if (str[i + 3] < 0x80 || str[i + 3] > 0xBF) {
|
|
||||||
# printf( "After a first byte of F0, expecting 4th byte between 80 and BF.");
|
|
||||||
# faulty_bytes = 4;
|
|
||||||
# goto end;
|
|
||||||
# }
|
|
||||||
# }
|
|
||||||
#else {
|
|
||||||
# printf( "After a first byte of F0, expecting three following bytes.");
|
|
||||||
# faulty_bytes = 1;
|
|
||||||
# goto end;
|
|
||||||
# }
|
|
||||||
# i += 4;
|
|
||||||
# }
|
|
||||||
#else if (str[i] >= 0xF1 && str[i] <= 0xF3) /* F1..F3 80..BF 80..BF 80..BF */ {
|
|
||||||
# if (i + 3 < len) /* Expect a 2nd, 3rd 3th byte */ {
|
|
||||||
# if (str[i + 1] < 0x80 || str[i + 1] > 0xBF) {
|
|
||||||
# printf( "After a first byte of F1, F2, or F3, expecting a 2nd byte between 80 and BF.");
|
|
||||||
# faulty_bytes = 2;
|
|
||||||
# goto end;
|
|
||||||
# }
|
|
||||||
# if (str[i + 2] < 0x80 || str[i + 2] > 0xBF) {
|
|
||||||
# printf( "After a first byte of F1, F2, or F3, expecting a 3rd byte between 80 and BF.");
|
|
||||||
# faulty_bytes = 3;
|
|
||||||
# goto end;
|
|
||||||
# }
|
|
||||||
# if (str[i + 3] < 0x80 || str[i + 3] > 0xBF) {
|
|
||||||
# printf( "After a first byte of F1, F2, or F3, expecting a 4th byte between 80 and BF.");
|
|
||||||
# faulty_bytes = 4;
|
|
||||||
# goto end;
|
|
||||||
# }
|
|
||||||
# }
|
|
||||||
#else {
|
|
||||||
# printf( "After a first byte of F1, F2, or F3, expecting three following bytes.");
|
|
||||||
# faulty_bytes = 1;
|
|
||||||
# goto end;
|
|
||||||
# }
|
|
||||||
# i += 4;
|
|
||||||
# }
|
|
||||||
#else if (str[i] == 0xF4) /* F4 80..8F 80..BF 80..BF */ {
|
|
||||||
# if (i + 3 < len) /* Expect a 2nd, 3rd 3th byte */ {
|
|
||||||
# if (str[i + 1] < 0x80 || str[i + 1] > 0x8F) {
|
|
||||||
# printf( "After a first byte of F4, expecting 2nd byte between 80 and 8F.");
|
|
||||||
# faulty_bytes = 2;
|
|
||||||
# goto end;
|
|
||||||
# }
|
|
||||||
# if (str[i + 2] < 0x80 || str[i + 2] > 0xBF) {
|
|
||||||
# printf( "After a first byte of F4, expecting 3rd byte between 80 and BF.");
|
|
||||||
# faulty_bytes = 3;
|
|
||||||
# goto end;
|
|
||||||
# }
|
|
||||||
# if (str[i + 3] < 0x80 || str[i + 3] > 0xBF) {
|
|
||||||
# printf( "After a first byte of F4, expecting 4th byte between 80 and BF.");
|
|
||||||
# faulty_bytes = 4;
|
|
||||||
# goto end;
|
|
||||||
# }
|
|
||||||
# }
|
|
||||||
#else {
|
|
||||||
# printf( "After a first byte of F4, expecting three following bytes.");
|
|
||||||
# faulty_bytes = 1;
|
|
||||||
# goto end;
|
|
||||||
# }
|
|
||||||
# i += 4;
|
|
||||||
# }
|
|
||||||
#else {
|
|
||||||
# printf( "i=%d Expecting bytes in the following ranges: 00..7F C2..F4.",
|
|
||||||
# i);
|
|
||||||
# faulty_bytes = 1;
|
|
||||||
# goto end;
|
|
||||||
# }
|
|
||||||
# }
|
|
||||||
#
|
|
||||||
# end: ;
|
|
||||||
// println('faulty bytes=$faulty_bytes i=$i')
|
|
||||||
// # printf("c='%c'\n", str[i]);
|
|
||||||
ok := faulty_bytes == 0
|
|
||||||
if ok {
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
if !ok {
|
|
||||||
println('utf is bad dalen=$len KEK $s sdf')
|
|
||||||
// s = s.left(i)
|
|
||||||
}
|
|
||||||
return i
|
|
||||||
// return ok
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
fn (s string) runes() []string {
|
|
||||||
res2 := []string{}
|
|
||||||
// res := new_empty_array_with_cap_string(s.len)
|
|
||||||
res := []string{}
|
|
||||||
if !s.is_utf8() {
|
|
||||||
mys := s
|
|
||||||
println('string.me runes bad utf $mys HAHA')
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
for i := 0; i < s.len; i++ {
|
|
||||||
char_len := 0
|
|
||||||
# char_len =UTF8_CHAR_LEN(s.str[i]);
|
|
||||||
switch char_len {
|
|
||||||
case 1:
|
|
||||||
// println('ONE')
|
|
||||||
res <<(char2string(s[i]))
|
|
||||||
case 2:
|
|
||||||
// println('TWO')
|
|
||||||
rune2 := s.substr(i, i + 2)
|
|
||||||
res <<(rune2)
|
|
||||||
i++
|
|
||||||
case 3:
|
|
||||||
// println('TWO')
|
|
||||||
rune3 := s.substr(i, i + 3)
|
|
||||||
res <<(rune3)
|
|
||||||
i++
|
|
||||||
i++
|
|
||||||
case 4:
|
|
||||||
// println('TWO')
|
|
||||||
rune4 := s.substr(i, i + 4)
|
|
||||||
res <<(rune4)
|
|
||||||
i++
|
|
||||||
i++
|
|
||||||
i++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
// Convert utf32 to utf8
|
// Convert utf32 to utf8
|
||||||
// utf32 == Codepoint
|
// utf32 == Codepoint
|
||||||
pub fn utf32_to_str(code u32) string {
|
pub fn utf32_to_str(code u32) string {
|
||||||
|
|
|
@ -517,14 +517,6 @@ fn (p mut Parser) fn_call(f Fn, method_ph int, receiver_var, receiver_type strin
|
||||||
// If we have a method placeholder,
|
// If we have a method placeholder,
|
||||||
// we need to preappend "method(receiver, ...)"
|
// we need to preappend "method(receiver, ...)"
|
||||||
else {
|
else {
|
||||||
// C only knows about functions "array_get", "array_set" etc
|
|
||||||
// TODO I don't need this?
|
|
||||||
// mut cgen_typ := receiver_type.replace('*', '')
|
|
||||||
// if cgen_typ.starts_with('array_') {
|
|
||||||
// cgen_typ = 'array'
|
|
||||||
// }
|
|
||||||
// println('METHOD fn_call name=$cgen_name')
|
|
||||||
// mut method_call := '${cgen_typ}_${cgen_name}('
|
|
||||||
mut method_call := '${cgen_name}('
|
mut method_call := '${cgen_name}('
|
||||||
receiver := f.args.first()
|
receiver := f.args.first()
|
||||||
if receiver.is_mut && !p.expr_var.is_mut {
|
if receiver.is_mut && !p.expr_var.is_mut {
|
||||||
|
@ -550,10 +542,8 @@ fn (p mut Parser) fn_call(f Fn, method_ph int, receiver_var, receiver_type strin
|
||||||
p.cgen.set_placeholder(method_ph, '$cast $method_call')
|
p.cgen.set_placeholder(method_ph, '$cast $method_call')
|
||||||
}
|
}
|
||||||
p.next()
|
p.next()
|
||||||
// p.check(LPAR)
|
|
||||||
p.fn_call_args(f)
|
p.fn_call_args(f)
|
||||||
p.gen(')')
|
p.gen(')')
|
||||||
// p.check(RPAR)
|
|
||||||
p.calling_c = false
|
p.calling_c = false
|
||||||
if is_print {
|
if is_print {
|
||||||
p.cgen.nogen = false
|
p.cgen.nogen = false
|
||||||
|
|
|
@ -257,7 +257,8 @@ void init_consts();')
|
||||||
if c.build_mode == EMBED_VLIB || c.build_mode == DEFAULT_MODE {
|
if c.build_mode == EMBED_VLIB || c.build_mode == DEFAULT_MODE {
|
||||||
// If we declare these for all modes, then when running `v a.v` we'll get
|
// If we declare these for all modes, then when running `v a.v` we'll get
|
||||||
// `/usr/bin/ld: multiple definition of 'total_m'`
|
// `/usr/bin/ld: multiple definition of 'total_m'`
|
||||||
cgen.genln('i64 total_m = 0; // For counting total RAM allocated')
|
// TODO
|
||||||
|
//cgen.genln('i64 total_m = 0; // For counting total RAM allocated')
|
||||||
cgen.genln('int g_test_ok = 1; ')
|
cgen.genln('int g_test_ok = 1; ')
|
||||||
if c.table.imports.contains('json') {
|
if c.table.imports.contains('json') {
|
||||||
cgen.genln('
|
cgen.genln('
|
||||||
|
|
|
@ -72,6 +72,7 @@ mut:
|
||||||
returns bool
|
returns bool
|
||||||
vroot string
|
vroot string
|
||||||
is_c_struct_init bool
|
is_c_struct_init bool
|
||||||
|
can_chash bool
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -141,6 +142,7 @@ fn (p mut Parser) parse() {
|
||||||
}
|
}
|
||||||
p.fgenln('\n')
|
p.fgenln('\n')
|
||||||
p.builtin_pkg = p.pkg == 'builtin'
|
p.builtin_pkg = p.pkg == 'builtin'
|
||||||
|
p.can_chash = p.pkg == 'gg' || p.pkg == 'glm' || p.pkg == 'gl' || p.pkg == 'glfw' // TODO tmp remove
|
||||||
// Import pass - the first and the smallest pass that only analyzes imports
|
// Import pass - the first and the smallest pass that only analyzes imports
|
||||||
p.table.register_package(p.pkg)
|
p.table.register_package(p.pkg)
|
||||||
if p.run == RUN_IMPORTS {
|
if p.run == RUN_IMPORTS {
|
||||||
|
@ -203,7 +205,7 @@ fn (p mut Parser) parse() {
|
||||||
// $if, $else
|
// $if, $else
|
||||||
p.comp_time()
|
p.comp_time()
|
||||||
case GLOBAL:
|
case GLOBAL:
|
||||||
if !p.translated {
|
if !p.translated && !p.builtin_pkg && !p.building_v() {
|
||||||
p.error('__global is only allowed in translated code')
|
p.error('__global is only allowed in translated code')
|
||||||
}
|
}
|
||||||
p.next()
|
p.next()
|
||||||
|
@ -419,7 +421,7 @@ fn (p mut Parser) struct_decl() {
|
||||||
if !is_c {
|
if !is_c {
|
||||||
kind := if is_union{'union'} else { 'struct'}
|
kind := if is_union{'union'} else { 'struct'}
|
||||||
p.gen_typedef('typedef $kind $name $name;')
|
p.gen_typedef('typedef $kind $name $name;')
|
||||||
p.gen_type('$kind $name {')
|
p.gen_type('$kind /*kind*/ $name {')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// V used to have 'type Foo struct', many Go users might use this syntax
|
// V used to have 'type Foo struct', many Go users might use this syntax
|
||||||
|
@ -1010,15 +1012,8 @@ fn (p mut Parser) statement(add_semi bool) string {
|
||||||
// this can be `user = ...` or `user.field = ...`, in both cases `v` is `user`
|
// this can be `user = ...` or `user.field = ...`, in both cases `v` is `user`
|
||||||
fn (p mut Parser) assign_statement(v Var, ph int, is_map bool) {
|
fn (p mut Parser) assign_statement(v Var, ph int, is_map bool) {
|
||||||
p.log('assign_statement() name=$v.name tok=')
|
p.log('assign_statement() name=$v.name tok=')
|
||||||
// p.print_tok()
|
|
||||||
// p.gen(name)
|
|
||||||
// p.assigned_var = name
|
|
||||||
tok := p.tok
|
tok := p.tok
|
||||||
if !v.is_mut && !v.is_arg && !p.translated {
|
if !v.is_mut && !v.is_arg && !p.translated && !v.is_global{
|
||||||
p.error('`$v.name` is immutable')
|
|
||||||
}
|
|
||||||
if !v.is_mut && p.is_play && !p.builtin_pkg && !p.translated {
|
|
||||||
// no mutable args in play
|
|
||||||
p.error('`$v.name` is immutable')
|
p.error('`$v.name` is immutable')
|
||||||
}
|
}
|
||||||
is_str := v.typ == 'string'
|
is_str := v.typ == 'string'
|
||||||
|
@ -1232,7 +1227,7 @@ fn (p mut Parser) name_expr() string {
|
||||||
// //////////////////////////
|
// //////////////////////////
|
||||||
// module ?
|
// module ?
|
||||||
// Allow shadowing (gg = gg.newcontext(); gg.draw_triangle())
|
// Allow shadowing (gg = gg.newcontext(); gg.draw_triangle())
|
||||||
if p.table.known_pkg(name) && !p.cur_fn.known_var(name) {
|
if p.table.known_pkg(name) && !p.cur_fn.known_var(name) && !is_c {
|
||||||
// println('"$name" is a known pkg')
|
// println('"$name" is a known pkg')
|
||||||
pkg := name
|
pkg := name
|
||||||
p.next()
|
p.next()
|
||||||
|
@ -2344,21 +2339,25 @@ fn (p mut Parser) register_array(typ string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// name == 'User'
|
|
||||||
fn (p mut Parser) struct_init(is_c_struct_init bool) string {
|
fn (p mut Parser) struct_init(is_c_struct_init bool) string {
|
||||||
p.is_struct_init = true
|
p.is_struct_init = true
|
||||||
mut typ := p.get_type()
|
mut typ := p.get_type()
|
||||||
p.scanner.fmt_out.cut(typ.len)
|
p.scanner.fmt_out.cut(typ.len)
|
||||||
ptr := typ.contains('*')
|
ptr := typ.contains('*')
|
||||||
|
// TODO tm struct struct bug
|
||||||
|
if typ == 'tm' {
|
||||||
|
p.cgen.lines[p.cgen.lines.len-1] = ''
|
||||||
|
p.cgen.lines[p.cgen.lines.len-2] = ''
|
||||||
|
}
|
||||||
p.check(LCBR)
|
p.check(LCBR)
|
||||||
// tmp := p.get_tmp()
|
// tmp := p.get_tmp()
|
||||||
if !ptr {
|
if !ptr {
|
||||||
if p.is_c_struct_init {
|
if p.is_c_struct_init {
|
||||||
p.gen('(struct $typ){')
|
p.gen('(struct $typ) {')
|
||||||
p.is_c_struct_init = false
|
p.is_c_struct_init = false
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
p.gen('($typ){')
|
p.gen('($typ) {')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -2370,12 +2369,6 @@ fn (p mut Parser) struct_init(is_c_struct_init bool) string {
|
||||||
p.check(RCBR)
|
p.check(RCBR)
|
||||||
return typ
|
return typ
|
||||||
}
|
}
|
||||||
mut type_gen := typ.replace('*', '')
|
|
||||||
// All V types are typedef'ed, C structs aren't, so we need to prepend "struct "
|
|
||||||
if is_c_struct_init {
|
|
||||||
type_gen = 'struct $type_gen'
|
|
||||||
}
|
|
||||||
// p.gen('malloc(sizeof($type_gen)); \n')
|
|
||||||
no_star := typ.replace('*', '')
|
no_star := typ.replace('*', '')
|
||||||
p.gen('ALLOC_INIT($no_star, {')
|
p.gen('ALLOC_INIT($no_star, {')
|
||||||
}
|
}
|
||||||
|
@ -2463,7 +2456,6 @@ fn (p mut Parser) struct_init(is_c_struct_init bool) string {
|
||||||
}
|
}
|
||||||
p.check(RCBR)
|
p.check(RCBR)
|
||||||
p.is_struct_init = false
|
p.is_struct_init = false
|
||||||
// println('struct init typ=$typ')
|
|
||||||
return typ
|
return typ
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2668,13 +2660,15 @@ fn (p mut Parser) chash() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
if !p.can_chash {
|
||||||
|
p.error('bad token `#` (embedding C code is no longer supported)')
|
||||||
|
}
|
||||||
|
//println('HASH!!! $p.file_name $p.scanner.line_nr')
|
||||||
if p.cur_fn.name == '' {
|
if p.cur_fn.name == '' {
|
||||||
// p.error('# outside of fn')
|
// p.error('# outside of fn')
|
||||||
}
|
}
|
||||||
p.genln(hash)
|
p.genln(hash)
|
||||||
}
|
}
|
||||||
// p.cgen.nogen = false
|
|
||||||
// println('HASH=$hash')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_c_pre(hash string) bool {
|
fn is_c_pre(hash string) bool {
|
||||||
|
@ -3134,6 +3128,14 @@ fn is_compile_time_const(s string) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn (p &Parser) building_v() bool {
|
||||||
|
cur_dir := os.getwd()
|
||||||
|
return p.file_path.contains('v/compiler') || cur_dir.contains('v/compiler')
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// fmt helpers
|
// fmt helpers
|
||||||
fn (scanner mut Scanner) fgen(s string) {
|
fn (scanner mut Scanner) fgen(s string) {
|
||||||
/*
|
/*
|
||||||
|
@ -3167,3 +3169,4 @@ fn (p mut Parser) fgenln(s string) {
|
||||||
//p.scanner.fgenln(s)
|
//p.scanner.fgenln(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -644,7 +644,7 @@ fn (table &Table) cgen_name_type_pair(name, typ string) string {
|
||||||
}
|
}
|
||||||
// TODO tm hack, do this for all C struct args
|
// TODO tm hack, do this for all C struct args
|
||||||
else if typ == 'tm' {
|
else if typ == 'tm' {
|
||||||
return 'struct tm $name'
|
return 'struct /*TM*/ tm $name'
|
||||||
}
|
}
|
||||||
return '$typ $name'
|
return '$typ $name'
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,7 +73,7 @@ fn main() {
|
||||||
}
|
}
|
||||||
field = new_field
|
field = new_field
|
||||||
print_field(field)
|
print_field(field)
|
||||||
time.sleep(time.milliseconds(100))
|
time.sleep_ms(100)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,6 @@ fn main() {
|
||||||
go fetcher.fetch()
|
go fetcher.fetch()
|
||||||
}
|
}
|
||||||
println(fetcher.ids)
|
println(fetcher.ids)
|
||||||
time.sleep(time.seconds(5))
|
time.sleep(5)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ const (
|
||||||
TetroSize = 4
|
TetroSize = 4
|
||||||
WinWidth = BlockSize * FieldWidth
|
WinWidth = BlockSize * FieldWidth
|
||||||
WinHeight = BlockSize * FieldHeight
|
WinHeight = BlockSize * FieldHeight
|
||||||
TimerPeriod = time.milliseconds(250) // 250ms
|
TimerPeriod = 250 // ms
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -168,7 +168,7 @@ fn (g mut Game) run() {
|
||||||
g.move_tetro()
|
g.move_tetro()
|
||||||
g.delete_completed_lines()
|
g.delete_completed_lines()
|
||||||
glfw.post_empty_event() // force window redraw
|
glfw.post_empty_event() // force window redraw
|
||||||
time.sleep(TimerPeriod)
|
time.sleep_ms(TimerPeriod)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
21
os/os.v
21
os/os.v
|
@ -26,17 +26,30 @@ import const (
|
||||||
SEEK_END
|
SEEK_END
|
||||||
SA_SIGINFO
|
SA_SIGINFO
|
||||||
SIGSEGV
|
SIGSEGV
|
||||||
|
|
||||||
|
S_IFMT
|
||||||
|
S_IFDIR
|
||||||
)
|
)
|
||||||
|
|
||||||
struct C.stat {
|
struct C.stat {
|
||||||
st_size int
|
st_size int
|
||||||
|
st_mode int
|
||||||
|
}
|
||||||
|
|
||||||
|
struct C.DIR {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
struct C.dirent {
|
||||||
|
d_name byteptr
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct C.sigaction {
|
struct C.sigaction {
|
||||||
mut:
|
mut:
|
||||||
sa_mask int
|
sa_mask int
|
||||||
sa_sigaction int
|
sa_sigaction int
|
||||||
sa_flags int
|
sa_flags int
|
||||||
}
|
}
|
||||||
|
|
||||||
fn C.getline(voidptr, voidptr, voidptr) int
|
fn C.getline(voidptr, voidptr, voidptr) int
|
||||||
|
|
49
os/os_mac.v
49
os/os_mac.v
|
@ -13,15 +13,14 @@ module os
|
||||||
fn log(s string) {
|
fn log(s string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_dir(path string) bool {
|
|
||||||
# struct stat statbuf;
|
pub fn is_dir(path string) bool {
|
||||||
|
statbuf := C.stat{}
|
||||||
cstr := path.cstr()
|
cstr := path.cstr()
|
||||||
# if (stat(cstr, &statbuf) != 0)
|
if C.stat(cstr, &statbuf) != 0 {
|
||||||
{
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
# return S_ISDIR(statbuf.st_mode);
|
return statbuf.st_mode & S_IFMT == S_IFDIR
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn chdir(path string) {
|
fn chdir(path string) {
|
||||||
|
@ -29,35 +28,33 @@ fn chdir(path string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getwd() string {
|
pub fn getwd() string {
|
||||||
cwd := malloc(1024)
|
cwd := malloc(512)
|
||||||
# if (getcwd(cwd, 1024)) return tos2(cwd);
|
if C.getcwd(cwd, 512) == 0 {
|
||||||
return ''
|
return ''
|
||||||
|
}
|
||||||
|
return string(cwd)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ls(path string) []string {
|
pub fn ls(path string) []string {
|
||||||
mut res := []string
|
mut res := []string
|
||||||
# DIR *dir;
|
dir := C.opendir(path.str)
|
||||||
# struct dirent *ent;
|
if isnil(dir) {
|
||||||
# if ((dir = opendir (path.str)) == NULL)
|
|
||||||
{
|
|
||||||
println('ls() couldnt open dir "$path"')
|
println('ls() couldnt open dir "$path"')
|
||||||
print_c_errno()
|
print_c_errno()
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
// print all the files and directories within directory */
|
mut ent := &C.dirent{!}
|
||||||
# while ((ent = readdir (dir)) != NULL) {
|
for {
|
||||||
name := ''
|
ent = C.readdir(dir)
|
||||||
# name = tos_clone(ent->d_name);//, strlen(ent->d_name));
|
if isnil(ent) {
|
||||||
// # printf ("printf ls() %s\n", ent->d_name);
|
break
|
||||||
// println(name)
|
}
|
||||||
if name != '.' && name != '..' && name != '' {
|
name := tos_clone(ent.d_name)
|
||||||
res << name
|
if name != '.' && name != '..' && name != '' {
|
||||||
|
res << name
|
||||||
|
}
|
||||||
}
|
}
|
||||||
# }
|
C.closedir(dir)
|
||||||
# closedir (dir);
|
|
||||||
// res.sort()
|
|
||||||
// println('sorted res')
|
|
||||||
// print_strings(res)
|
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
10
rand/rand.v
10
rand/rand.v
|
@ -4,19 +4,15 @@
|
||||||
|
|
||||||
module rand
|
module rand
|
||||||
|
|
||||||
#include <time.h>
|
import time
|
||||||
|
|
||||||
pub fn seed() {
|
pub fn seed() {
|
||||||
# time_t t;
|
C.srand(time.now().uni)
|
||||||
# srand((unsigned) time(&t));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn next(max int) int {
|
pub fn next(max int) int {
|
||||||
r := 0
|
return C.rand() % max
|
||||||
# r = rand(); // TODO parser bug `rand` module name conflict
|
|
||||||
return r % max
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct C.time_t{}
|
|
||||||
fn C.rand() int
|
fn C.rand() int
|
||||||
|
|
||||||
|
|
17
time/info.v
17
time/info.v
|
@ -1,17 +0,0 @@
|
||||||
// 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 time
|
|
||||||
|
|
||||||
struct Info {
|
|
||||||
pub:
|
|
||||||
year int
|
|
||||||
month int
|
|
||||||
day int
|
|
||||||
hour int
|
|
||||||
minute int
|
|
||||||
second int
|
|
||||||
yday int
|
|
||||||
wday int
|
|
||||||
}
|
|
353
time/time.v
353
time/time.v
|
@ -4,104 +4,277 @@
|
||||||
|
|
||||||
module time
|
module time
|
||||||
|
|
||||||
|
import rand
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
struct Time {
|
struct Time {
|
||||||
sec i64
|
pub:
|
||||||
nsec i32
|
year int
|
||||||
mono i64
|
month int
|
||||||
|
day int
|
||||||
|
hour int
|
||||||
|
minute int
|
||||||
|
second int
|
||||||
|
uni int // TODO it's safe to use "unix" now
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (a Time) + (b Time) Time {
|
fn C.localtime(int) *C.tm
|
||||||
sec := a.sec + b.sec
|
|
||||||
nsec := a.nsec + b.nsec
|
fn remove_me_when_c_bug_is_fixed() { // TODO
|
||||||
return Time{
|
}
|
||||||
sec: sec + i64(nsec)/i64(1000000000)
|
|
||||||
nsec: nsec % i32(1000000000)
|
struct C.tm {
|
||||||
|
tm_year int
|
||||||
|
tm_mon int
|
||||||
|
tm_mday int
|
||||||
|
tm_hour int
|
||||||
|
tm_min int
|
||||||
|
tm_sec int
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn now() Time {
|
||||||
|
t := C.time(0)
|
||||||
|
mut now := &C.tm{!}
|
||||||
|
now = C.localtime(&t)
|
||||||
|
return convert_ctime(now)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn random() Time {
|
||||||
|
return Time {
|
||||||
|
year: rand.next(2) + 201
|
||||||
|
month: rand.next(12) + 1
|
||||||
|
day: rand.next(30) + 1
|
||||||
|
hour: rand.next(24)
|
||||||
|
minute: rand.next(60)
|
||||||
|
second: rand.next(60)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (a Time) - (b Time) Time {
|
pub fn unix(u int) Time {
|
||||||
sec := a.sec - b.sec - i64(1)
|
mut t := &C.tm{!}
|
||||||
nsec := a.nsec - b.nsec + i32(1000000000)
|
t = C.localtime(&u)
|
||||||
t := Time{
|
return convert_ctime(t)
|
||||||
sec: sec + i64(nsec)/i64(1000000000)
|
|
||||||
nsec: nsec % i32(1000000000)
|
|
||||||
}
|
|
||||||
if a.mono <= i64(0) || b.mono <= i64(0) {
|
|
||||||
return t
|
|
||||||
}
|
|
||||||
|
|
||||||
mono := a.mono - b.mono
|
|
||||||
if mono > i64(0) && t.sec >= i64(0) && t.nsec >= i32(0) {
|
|
||||||
return t
|
|
||||||
}
|
|
||||||
if mono < i64(0) && t.sec <= i64(0) && t.nsec <= i32(0) {
|
|
||||||
return t
|
|
||||||
}
|
|
||||||
if mono == i64(0) {
|
|
||||||
return Time{}
|
|
||||||
}
|
|
||||||
return Time{
|
|
||||||
sec: mono / i64(1000000000)
|
|
||||||
nsec: i32(mono%i64(1000000000))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (t Time) days() f64 {
|
pub fn convert_ctime(t tm) Time {
|
||||||
return f64(t.sec)/86400.0
|
return Time {
|
||||||
}
|
year: t.tm_year + 1900
|
||||||
|
month: t.tm_mon + 1
|
||||||
fn (t Time) hours() f64 {
|
day: t.tm_mday
|
||||||
return f64(t.sec)/3600.0
|
hour: t.tm_hour
|
||||||
}
|
minute: t.tm_min
|
||||||
|
second: t.tm_sec
|
||||||
fn (t Time) minutes() f64 {
|
|
||||||
return f64(t.sec)/60.0
|
|
||||||
}
|
|
||||||
|
|
||||||
fn (t Time) seconds() f64 {
|
|
||||||
return f64(t.sec) + f64(t.nsec)/1000000000.0
|
|
||||||
}
|
|
||||||
|
|
||||||
fn (t Time) milliseconds() f64 {
|
|
||||||
return 1000.0*f64(t.sec) + f64(t.nsec)/1000000.0
|
|
||||||
}
|
|
||||||
|
|
||||||
fn (t Time) microseconds() f64 {
|
|
||||||
return 1000000.0*f64(t.sec) + f64(t.nsec)/1000.0
|
|
||||||
}
|
|
||||||
|
|
||||||
fn (t Time) nanoseconds() f64 {
|
|
||||||
return 1000000000.0*f64(t.sec) + f64(t.nsec)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn (t Time) str() string {
|
|
||||||
if t.sec == i64(0) {
|
|
||||||
if t.nsec == i32(0) {
|
|
||||||
return '0s'
|
|
||||||
}
|
|
||||||
if t.nsec < i32(1000) && t.nsec > i32(-1000) {
|
|
||||||
return '${t.nsec}ns'
|
|
||||||
}
|
|
||||||
if t.nsec < i32(1000000) && t.nsec > i32(-1000000) {
|
|
||||||
return '${f64(t.nsec)/1000.0:.1f}µs'
|
|
||||||
}
|
|
||||||
if t.nsec < i32(1000000000) && t.nsec > i32(-1000000000) {
|
|
||||||
return '${f64(t.nsec)/1000000.0:.1f}ms'
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if t.sec < i64(60) && t.sec > i64(-60) {
|
// uni = uni;
|
||||||
return '${f64(t.sec)+f64(t.nsec)/1000000000.0:.1f}s'
|
}
|
||||||
}
|
|
||||||
if t.sec < i64(3600) && t.sec > i64(-3600) {
|
fn (t Time) format_ss() string {
|
||||||
return '${f64(t.sec)/60.0:.1f}m'
|
return '${t.year}-${t.month:02d}-${t.day:02d} ${t.hour:02d}:${t.minute:02d}:${t.second:02d}'
|
||||||
}
|
}
|
||||||
if t.sec < i64(86400) && t.sec > i64(-86400) {
|
|
||||||
return '${f64(t.sec)/3600.0:.1f}h'
|
pub fn (t Time) format() string {
|
||||||
}
|
return '${t.year}-${t.month:02d}-${t.day:02d} ${t.hour:02d}:${t.minute:02d}'
|
||||||
if t.sec < i64(864000) && t.sec > i64(-864000) {
|
}
|
||||||
return '${f64(t.sec)/86400.0:.1f}d'
|
|
||||||
}
|
const (
|
||||||
return '${f64(t.sec)/86400.0:.0f}d'
|
Months = 'JanFebMarAprMayJunJulAugSepOctNovDec'
|
||||||
|
Days = 'MonTueWedThuFriSatSun'
|
||||||
|
)
|
||||||
|
|
||||||
|
pub fn (t Time) smonth() string {
|
||||||
|
i := t.month - 1
|
||||||
|
return Months.substr(i * 3, (i + 1) * 3)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 21:04
|
||||||
|
pub fn (t Time) hhmm() string {
|
||||||
|
return '${t.hour:02d}:${t.minute:02d}'
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
fn (t Time) hhmm_tmp() string {
|
||||||
|
return '${t.hour:02d}:${t.minute:02d}'
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 9:04pm
|
||||||
|
pub fn (t Time) hhmm12() string {
|
||||||
|
mut am := 'am'
|
||||||
|
mut hour = t.hour
|
||||||
|
if t.hour > 11 {
|
||||||
|
am = 'pm'
|
||||||
|
}
|
||||||
|
if t.hour > 12 {
|
||||||
|
hour = hour - 12
|
||||||
|
}
|
||||||
|
if t.hour == 0 {
|
||||||
|
hour = 12
|
||||||
|
}
|
||||||
|
return '$hour:${t.minute:02d} $am'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 21:04:03
|
||||||
|
fn (t Time) hhmmss() string {
|
||||||
|
return '${t.hour:02d}:${t.minute:02d}:${t.second:02d}'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2012-01-05
|
||||||
|
fn (t Time) ymmdd() string {
|
||||||
|
return '${t.year}-${t.month:02d}-${t.day:02d}'
|
||||||
|
}
|
||||||
|
|
||||||
|
// Jul 3
|
||||||
|
fn (t Time) md() string {
|
||||||
|
// jl := t.smonth()
|
||||||
|
s := '${t.smonth()} $t.day'
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (t Time) clean() string {
|
||||||
|
nowe := time.now()
|
||||||
|
// if amtime {
|
||||||
|
// hm = t.Format("3:04 pm")
|
||||||
|
// }
|
||||||
|
// Today
|
||||||
|
if t.month == nowe.month && t.year == nowe.year && t.day == nowe.day {
|
||||||
|
return t.hhmm()
|
||||||
|
}
|
||||||
|
// This week
|
||||||
|
// if time.Since(t) < 24*7*time.Hour {
|
||||||
|
// return t.Weekday().String()[:3] + " " + hm
|
||||||
|
// }
|
||||||
|
// This year
|
||||||
|
if t.year == nowe.year {
|
||||||
|
return '${t.smonth()} ${t.day} ${t.hhmm()}'
|
||||||
|
}
|
||||||
|
return t.format()
|
||||||
|
// return fmt.Sprintf("%4d/%02d/%02d", t.Year(), t.Month(), t.Day()) + " " + hm
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (t Time) clean12() string {
|
||||||
|
nowe := time.now()
|
||||||
|
// if amtime {
|
||||||
|
// hm = t.Format("3:04 pm")
|
||||||
|
// }
|
||||||
|
// Today
|
||||||
|
if t.month == nowe.month && t.year == nowe.year && t.day == nowe.day {
|
||||||
|
return t.hhmm12()
|
||||||
|
}
|
||||||
|
// This week
|
||||||
|
// if time.Since(t) < 24*7*time.Hour {
|
||||||
|
// return t.Weekday().String()[:3] + " " + hm
|
||||||
|
// }
|
||||||
|
// This year
|
||||||
|
if t.year == nowe.year {
|
||||||
|
return '${t.smonth()} ${t.day} ${t.hhmm12()}'
|
||||||
|
}
|
||||||
|
return t.format()
|
||||||
|
// return fmt.Sprintf("%4d/%02d/%02d", t.Year(), t.Month(), t.Day()) + " " + hm
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
// in ms
|
||||||
|
fn ticks() double {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
// `parse` parses time in the following format: "2018-01-27 12:48:34"
|
||||||
|
pub fn parse(s string) Time {
|
||||||
|
// println('parse="$s"')
|
||||||
|
pos := s.index(' ')
|
||||||
|
if pos <= 0 {
|
||||||
|
println('bad time format')
|
||||||
|
return now()
|
||||||
|
}
|
||||||
|
symd := s.left(pos)
|
||||||
|
ymd := symd.split('-')
|
||||||
|
if ymd.len != 3 {
|
||||||
|
println('bad time format')
|
||||||
|
return now()
|
||||||
|
}
|
||||||
|
shms := s.right(pos)
|
||||||
|
hms := shms.split(':')
|
||||||
|
hour := hms[0]
|
||||||
|
minute := hms[1]
|
||||||
|
second := hms[2]
|
||||||
|
// //////////
|
||||||
|
return new_time(Time {
|
||||||
|
year: ymd[0].int()
|
||||||
|
month: ymd[1].int()
|
||||||
|
day: ymd[2].int()
|
||||||
|
hour: hour.int()
|
||||||
|
minute: minute.int()
|
||||||
|
second: second.int()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new_time(t Time) Time {
|
||||||
|
return{t | uni: t.calc_unix()}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (t &Time) calc_unix() int {
|
||||||
|
if t.uni != 0 {
|
||||||
|
return t.uni
|
||||||
|
}
|
||||||
|
tt := C.tm{
|
||||||
|
tm_sec : t.second
|
||||||
|
tm_min : t.minute
|
||||||
|
tm_hour : t.hour
|
||||||
|
tm_mday : t.day
|
||||||
|
tm_mon : t.month-1
|
||||||
|
tm_year : t.year - 1900
|
||||||
|
}
|
||||||
|
return C.mktime(&tt)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO add(d time.Duration)
|
||||||
|
pub fn (t Time) add_seconds(seconds int) Time {
|
||||||
|
return unix(t.uni + seconds)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO use time.Duration instead of seconds
|
||||||
|
fn since(t Time) int {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (t Time) relative() string {
|
||||||
|
now := time.now()
|
||||||
|
secs := now.uni - t.uni
|
||||||
|
if secs <= 30 {
|
||||||
|
// right now or in the future
|
||||||
|
// TODO handle time in the future
|
||||||
|
return 'now'
|
||||||
|
}
|
||||||
|
if secs < 60 {
|
||||||
|
return '1m'
|
||||||
|
}
|
||||||
|
if secs < 3600 {
|
||||||
|
return '${secs/60}m'
|
||||||
|
}
|
||||||
|
if secs < 3600 * 24 {
|
||||||
|
return '${secs/3600}h'
|
||||||
|
}
|
||||||
|
if secs < 3600 * 24 * 5 {
|
||||||
|
return '${secs/3600/24}d'
|
||||||
|
}
|
||||||
|
if secs > 3600 * 24 * 10000 {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
return t.md()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn day_of_week(y, m, d int) int {
|
||||||
|
// TODO please no
|
||||||
|
//# return (d += m < 3 ? y-- : y - 2, 23*m/9 + d + 4 + y/4- y/100 + y/400)%7;
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (t Time) day_of_week() int {
|
||||||
|
return day_of_week(t.year, t.month, t.day)
|
||||||
|
}
|
||||||
|
|
||||||
|
// weekday_str() returns the current day in string (upto 3 characters)
|
||||||
|
pub fn (t Time) weekday_str() string {
|
||||||
|
i := t.day_of_week() - 1
|
||||||
|
return Days.substr(i * 3, (i + 1) * 3)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,84 +4,16 @@
|
||||||
|
|
||||||
module time
|
module time
|
||||||
|
|
||||||
pub fn now() Time {
|
// in ms
|
||||||
# struct timespec t = {0, 0};
|
pub fn ticks() f64 {
|
||||||
# struct timespec m = {0, 0};
|
return f64(0)
|
||||||
# clock_gettime(CLOCK_REALTIME, &t);
|
|
||||||
# clock_gettime(CLOCK_MONOTONIC_RAW, &m);
|
|
||||||
|
|
||||||
res := Time{}
|
|
||||||
# res.sec = t.tv_sec;
|
|
||||||
# res.nsec = t.tv_nsec;
|
|
||||||
# res.mono = 1000000000*m.tv_sec + m.tv_nsec;
|
|
||||||
return res
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sleep(t Time) {
|
pub fn sleep(seconds int) {
|
||||||
if t.sec > i64(0) {
|
C.sleep(seconds)
|
||||||
C.sleep(t.sec)
|
|
||||||
}
|
|
||||||
if t.nsec > i32(0) {
|
|
||||||
C.usleep((t.nsec+i32(999))/i32(1000))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (t Time) local() Info {
|
pub fn sleep_ms(seconds int) {
|
||||||
info := Info{}
|
C.usleep(seconds * 1000)
|
||||||
# struct tm tm;
|
|
||||||
# localtime_r(&t.sec, &tm);
|
|
||||||
# info.year = tm.tm_year + 1900;
|
|
||||||
# info.month = tm.tm_mon + 1;
|
|
||||||
# info.day = tm.tm_mday;
|
|
||||||
# info.hour = tm.tm_hour;
|
|
||||||
# info.minute = tm.tm_min;
|
|
||||||
# info.second = tm.tm_sec;
|
|
||||||
# info.yday = tm.tm_yday;
|
|
||||||
# info.wday = tm.tm_wday;
|
|
||||||
return info
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (t Time) utc() Info {
|
|
||||||
info := Info{}
|
|
||||||
# struct tm tm;
|
|
||||||
# gmtime_r(&t.sec, &tm);
|
|
||||||
# info.year = tm.tm_year + 1900;
|
|
||||||
# info.month = tm.tm_mon + 1;
|
|
||||||
# info.day = tm.tm_mday;
|
|
||||||
# info.hour = tm.tm_hour;
|
|
||||||
# info.minute = tm.tm_min;
|
|
||||||
# info.second = tm.tm_sec;
|
|
||||||
# info.yday = tm.tm_yday;
|
|
||||||
# info.wday = tm.tm_wday;
|
|
||||||
return info
|
|
||||||
}
|
|
||||||
|
|
||||||
fn (t Time) format(fmt string) string {
|
|
||||||
res := ''
|
|
||||||
cfmt := fmt.cstr()
|
|
||||||
# char buf[1024];
|
|
||||||
# struct tm tm;
|
|
||||||
# localtime_r(&t.sec, &tm);
|
|
||||||
# strftime(buf, 1024, cfmt, &tm);
|
|
||||||
# res = tos2(buf);
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
pub fn parse(s, fmt string) ?Time {
|
|
||||||
t := Time{}
|
|
||||||
cs := s.cstr()
|
|
||||||
cfmt := fmt.cstr()
|
|
||||||
ok := 0
|
|
||||||
# struct tm tm;
|
|
||||||
# memset(&tm, 0, sizeof(struct tm));
|
|
||||||
# ok = strptime(cs, cfmt, &tm);
|
|
||||||
if ok == 0 {
|
|
||||||
return error('time.parse: invalid time string')
|
|
||||||
}
|
|
||||||
# t.sec = mktime(&tm);
|
|
||||||
if t.sec < i64(0) {
|
|
||||||
return error('time.parse: invalid time string')
|
|
||||||
}
|
|
||||||
return t
|
|
||||||
}
|
|
||||||
|
|
|
@ -4,66 +4,30 @@
|
||||||
|
|
||||||
module time
|
module time
|
||||||
|
|
||||||
// TODO: nanosecond and monotonic
|
//#flag -framework CoreServices
|
||||||
pub fn now() Time {
|
//#include <CoreServices/CoreServices.h>
|
||||||
# time_t t = time(0);
|
//#include <mach/mach_time.h>
|
||||||
|
|
||||||
res := Time{}
|
// in ms
|
||||||
# res.sec = t;
|
pub fn ticks() f64 {
|
||||||
return res
|
panic('not implemented')
|
||||||
|
/*
|
||||||
|
t := i64(C.mach_absolute_time())
|
||||||
|
# Nanoseconds elapsedNano = AbsoluteToNanoseconds( *(AbsoluteTime *) &t );
|
||||||
|
# return (double)(* (uint64_t *) &elapsedNano) / 1000000;
|
||||||
|
*/
|
||||||
|
return f64(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sleep(t Time) {
|
pub fn sleep(seconds int) {
|
||||||
if t.sec > i64(0) {
|
C.sleep(seconds)
|
||||||
C.sleep(t.sec)
|
|
||||||
}
|
|
||||||
if t.nsec > i32(0) {
|
|
||||||
C.usleep((t.nsec+i32(999))/i32(1000))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Thread safety
|
pub fn usleep(seconds int) {
|
||||||
fn (t Time) local() Info {
|
C.usleep(seconds)
|
||||||
info := Info{}
|
|
||||||
# struct tm *tm = localtime(&t.sec);
|
|
||||||
# info.year = tm->tm_year + 1900;
|
|
||||||
# info.month = tm->tm_mon + 1;
|
|
||||||
# info.day = tm->tm_mday;
|
|
||||||
# info.hour = tm->tm_hour;
|
|
||||||
# info.minute = tm->tm_min;
|
|
||||||
# info.second = tm->tm_sec;
|
|
||||||
# info.yday = tm->tm_yday;
|
|
||||||
# info.wday = tm->tm_wday;
|
|
||||||
return info
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Thread safety
|
pub fn sleep_ms(seconds int) {
|
||||||
fn (t Time) utc() Info {
|
C.usleep(seconds * 1000)
|
||||||
info := Info{}
|
|
||||||
# struct tm *tm = gmtime(&t.sec);
|
|
||||||
# info.year = tm->tm_year + 1900;
|
|
||||||
# info.month = tm->tm_mon + 1;
|
|
||||||
# info.day = tm->tm_mday;
|
|
||||||
# info.hour = tm->tm_hour;
|
|
||||||
# info.minute = tm->tm_min;
|
|
||||||
# info.second = tm->tm_sec;
|
|
||||||
# info.yday = tm->tm_yday;
|
|
||||||
# info.wday = tm->tm_wday;
|
|
||||||
return info
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Thread safety
|
|
||||||
fn (t Time) format(fmt string) string {
|
|
||||||
res := ''
|
|
||||||
cfmt := fmt.cstr()
|
|
||||||
# char buf[1024];
|
|
||||||
# struct tm *tm = localtime(&t.sec);
|
|
||||||
# strftime(buf, 1024, cfmt, tm);
|
|
||||||
# res = tos2(buf);
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Not implemented yet
|
|
||||||
pub fn parse(s string) ?Time {
|
|
||||||
return Time{}
|
|
||||||
}
|
|
||||||
|
|
|
@ -4,63 +4,21 @@
|
||||||
|
|
||||||
module time
|
module time
|
||||||
|
|
||||||
// TODO: nanosecond and monotonic
|
// in ms
|
||||||
pub fn now() Time {
|
fn ticks() double {
|
||||||
# time_t t = time(0);
|
return C.GetTickCount()
|
||||||
|
|
||||||
res := Time{}
|
|
||||||
# res.sec = t;
|
|
||||||
return res
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sleep(t Time) {
|
fn sleep(seconds int) {
|
||||||
if t.sec > i64(0) || t.nsec > i32(0) {
|
C._sleep(seconds * 1000)
|
||||||
C.Sleep(i64(1000)*t.sec+(i64(t.nsec)+i64(999999))/i64(1000000))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Thread safety
|
fn usleep(seconds int) {
|
||||||
fn (t Time) local() Info {
|
panic('usleep not impl')
|
||||||
info := Info{}
|
// C._usleep(seconds)
|
||||||
# struct tm *tm = localtime(&t.sec);
|
|
||||||
# info.year = tm->tm_year + 1900;
|
|
||||||
# info.month = tm->tm_mon + 1;
|
|
||||||
# info.day = tm->tm_mday;
|
|
||||||
# info.hour = tm->tm_hour;
|
|
||||||
# info.minute = tm->tm_min;
|
|
||||||
# info.second = tm->tm_sec;
|
|
||||||
# info.yday = tm->tm_yday;
|
|
||||||
# info.wday = tm->tm_wday;
|
|
||||||
return info
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Thread safety
|
fn sleep_ms(n int) {
|
||||||
fn (t Time) utc() Info {
|
C.Sleep(n)
|
||||||
info := Info{}
|
|
||||||
# struct tm *tm = gmtime(&t.sec);
|
|
||||||
# info.year = tm->tm_year + 1900;
|
|
||||||
# info.month = tm->tm_mon + 1;
|
|
||||||
# info.day = tm->tm_mday;
|
|
||||||
# info.hour = tm->tm_hour;
|
|
||||||
# info.minute = tm->tm_min;
|
|
||||||
# info.second = tm->tm_sec;
|
|
||||||
# info.yday = tm->tm_yday;
|
|
||||||
# info.wday = tm->tm_wday;
|
|
||||||
return info
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Thread safety
|
|
||||||
fn (t Time) format(fmt string) string {
|
|
||||||
res := ''
|
|
||||||
cfmt := fmt.cstr()
|
|
||||||
# char buf[1024];
|
|
||||||
# struct tm *tm = localtime(&t.sec);
|
|
||||||
# strftime(buf, 1024, cfmt, tm);
|
|
||||||
# res = tos2(buf);
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Not implemented yet
|
|
||||||
pub fn parse(s string) ?Time {
|
|
||||||
return Time{}
|
|
||||||
}
|
|
||||||
|
|
66
time/util.v
66
time/util.v
|
@ -1,66 +0,0 @@
|
||||||
// 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 time
|
|
||||||
|
|
||||||
pub fn make(i Info) ?Time {
|
|
||||||
t := Time{}
|
|
||||||
# struct tm tm;
|
|
||||||
# tm.tm_year = i.year - 1900;
|
|
||||||
# tm.tm_mon = i.month - 1;
|
|
||||||
# tm.tm_mday = i.day;
|
|
||||||
# tm.tm_hour = i.hour;
|
|
||||||
# tm.tm_min = i.minute;
|
|
||||||
# tm.tm_sec = i.second;
|
|
||||||
# tm.tm_yday = i.yday;
|
|
||||||
# tm.tm_wday = i.wday;
|
|
||||||
# tm.tm_isdst = 0;
|
|
||||||
# t.sec = mktime(&tm);
|
|
||||||
if t.sec < i64(0) {
|
|
||||||
return error('time.make: invalid time infomation')
|
|
||||||
}
|
|
||||||
return t
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn days(n int) Time {
|
|
||||||
return Time{
|
|
||||||
sec: 86400*n
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn hours(n int) Time {
|
|
||||||
return Time{
|
|
||||||
sec: 3600*n
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn minutes(n int) Time {
|
|
||||||
return Time{
|
|
||||||
sec: 60*n
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn seconds(n int) Time {
|
|
||||||
return Time{
|
|
||||||
sec: n
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn milliseconds(n int) Time {
|
|
||||||
return Time{
|
|
||||||
nsec: 1000000*n
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn microseconds(n int) Time {
|
|
||||||
return Time{
|
|
||||||
nsec: 1000*n
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn nanoseconds(n int) Time {
|
|
||||||
return Time{
|
|
||||||
nsec: n
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue