mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
free arrays when they are out of scope
main.v: update help
This commit is contained in:
parent
385f1c856e
commit
40c31f701f
@ -46,23 +46,6 @@ fn (f mut Fn) open_scope() {
|
|||||||
f.scope_level++
|
f.scope_level++
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (f mut Fn) close_scope() {
|
|
||||||
// println('close_scope level=$f.scope_level var_idx=$f.var_idx')
|
|
||||||
// Move back `var_idx` (pointer to the end of the array) till we reach the previous scope level.
|
|
||||||
// This effectivly deletes (closes) current scope.
|
|
||||||
mut i := f.var_idx - 1
|
|
||||||
for; i >= 0; i-- {
|
|
||||||
v := f.local_vars[i]
|
|
||||||
if v.scope_level != f.scope_level {
|
|
||||||
// println('breaking. "$v.name" v.scope_level=$v.scope_level')
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
f.var_idx = i + 1
|
|
||||||
// println('close_scope new var_idx=$f.var_idx\n')
|
|
||||||
f.scope_level--
|
|
||||||
}
|
|
||||||
|
|
||||||
fn (f &Fn) mark_var_used(v Var) {
|
fn (f &Fn) mark_var_used(v Var) {
|
||||||
for i, vv in f.local_vars {
|
for i, vv in f.local_vars {
|
||||||
if vv.name == v.name {
|
if vv.name == v.name {
|
||||||
@ -432,19 +415,11 @@ fn (p mut Parser) check_unused_variables() {
|
|||||||
p.scanner.line_nr = var.line_nr - 1
|
p.scanner.line_nr = var.line_nr - 1
|
||||||
p.error('`$var.name` declared and not used')
|
p.error('`$var.name` declared and not used')
|
||||||
}
|
}
|
||||||
// Very basic automatic memory management at the end of the function.
|
|
||||||
// This is inserted right before the final `}`, so if the object is being returned,
|
|
||||||
// the free method will not be called.
|
|
||||||
if p.pref.is_test && var.typ.contains('array_') {
|
|
||||||
// p.genln('v_${var.typ}_free($var.name); // !!!! XAXA')
|
|
||||||
// p.genln('free(${var.name}.data); // !!!! XAXA')
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Important function with 5 args.
|
// user.register() => "User_register(user)"
|
||||||
// user.say_hi() => "User_say_hi(user)"
|
// method_ph - where to insert "user_register("
|
||||||
// method_ph - where to insert "user_say_hi("
|
|
||||||
// receiver_var - "user" (needed for pthreads)
|
// receiver_var - "user" (needed for pthreads)
|
||||||
// receiver_type - "User"
|
// receiver_type - "User"
|
||||||
fn (p mut Parser) async_fn_call(f Fn, method_ph int, receiver_var, receiver_type string) {
|
fn (p mut Parser) async_fn_call(f Fn, method_ph int, receiver_var, receiver_type string) {
|
||||||
|
@ -977,7 +977,7 @@ fn new_v(args[]string) *V {
|
|||||||
if os.dir_exists(vroot) && os.dir_exists(vroot + '/vlib/builtin') {
|
if os.dir_exists(vroot) && os.dir_exists(vroot + '/vlib/builtin') {
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
println('vlib not found. It should be next to V executable. ')
|
println('vlib not found. It should be next to the V executable. ')
|
||||||
println('Go to https://vlang.io to install V.')
|
println('Go to https://vlang.io to install V.')
|
||||||
exit(1)
|
exit(1)
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,7 @@ mut:
|
|||||||
is_global bool // __global (translated from C only)
|
is_global bool // __global (translated from C only)
|
||||||
is_used bool
|
is_used bool
|
||||||
scope_level int
|
scope_level int
|
||||||
|
is_alloc bool
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Parser {
|
struct Parser {
|
||||||
@ -69,6 +70,7 @@ mut:
|
|||||||
attr string
|
attr string
|
||||||
v_script bool // "V bash", import all os functions into global space
|
v_script bool // "V bash", import all os functions into global space
|
||||||
var_decl_name string // To allow declaring the variable so that it can be used in the struct initialization
|
var_decl_name string // To allow declaring the variable so that it can be used in the struct initialization
|
||||||
|
building_v bool
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -96,6 +98,9 @@ fn (c mut V) new_parser(path string, run Pass) Parser {
|
|||||||
os: c.os
|
os: c.os
|
||||||
run: run
|
run: run
|
||||||
vroot: c.vroot
|
vroot: c.vroot
|
||||||
|
building_v: !c.pref.is_repl && (path.contains('compiler/') ||
|
||||||
|
path.contains('v/vlib'))
|
||||||
|
|
||||||
}
|
}
|
||||||
p.next()
|
p.next()
|
||||||
// p.scanner.debug_tokens()
|
// p.scanner.debug_tokens()
|
||||||
@ -214,8 +219,9 @@ fn (p mut Parser) parse() {
|
|||||||
// $if, $else
|
// $if, $else
|
||||||
p.comp_time()
|
p.comp_time()
|
||||||
case Token.key_global:
|
case Token.key_global:
|
||||||
if !p.pref.translated && !p.pref.is_live && !p.builtin_pkg && !p.building_v() {
|
if !p.pref.translated && !p.pref.is_live &&
|
||||||
//p.error('__global is only allowed in translated code')
|
!p.builtin_pkg && !p.building_v {
|
||||||
|
p.error('__global is only allowed in translated code')
|
||||||
}
|
}
|
||||||
p.next()
|
p.next()
|
||||||
name := p.check_name()
|
name := p.check_name()
|
||||||
@ -988,10 +994,35 @@ fn (p mut Parser) statements_no_curly_end() string {
|
|||||||
}
|
}
|
||||||
//p.fmt_dec()
|
//p.fmt_dec()
|
||||||
// println('close scope line=$p.scanner.line_nr')
|
// println('close scope line=$p.scanner.line_nr')
|
||||||
p.cur_fn.close_scope()
|
p.close_scope()
|
||||||
return last_st_typ
|
return last_st_typ
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn (p mut Parser) close_scope() {
|
||||||
|
// println('close_scope level=$f.scope_level var_idx=$f.var_idx')
|
||||||
|
// Move back `var_idx` (pointer to the end of the array) till we reach the previous scope level.
|
||||||
|
// This effectivly deletes (closes) current scope.
|
||||||
|
mut i := p.cur_fn.var_idx - 1
|
||||||
|
for; i >= 0; i-- {
|
||||||
|
v := p.cur_fn.local_vars[i]
|
||||||
|
if v.scope_level != p.cur_fn.scope_level {
|
||||||
|
// println('breaking. "$v.name" v.scope_level=$v.scope_level')
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if !p.building_v && !v.is_mut && v.is_alloc {
|
||||||
|
if v.typ.starts_with('array_') {
|
||||||
|
p.genln('v_array_free($v.name); // close_scope free')
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
p.genln('free($v.name); // close_scope free')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p.cur_fn.var_idx = i + 1
|
||||||
|
// println('close_scope new var_idx=$f.var_idx\n')
|
||||||
|
p.cur_fn.scope_level--
|
||||||
|
}
|
||||||
|
|
||||||
fn (p mut Parser) genln(s string) {
|
fn (p mut Parser) genln(s string) {
|
||||||
p.cgen.genln(s)
|
p.cgen.genln(s)
|
||||||
}
|
}
|
||||||
@ -1221,6 +1252,7 @@ fn (p mut Parser) var_decl() {
|
|||||||
name: name
|
name: name
|
||||||
typ: typ
|
typ: typ
|
||||||
is_mut: is_mut
|
is_mut: is_mut
|
||||||
|
is_alloc: typ.starts_with('array_')
|
||||||
})
|
})
|
||||||
mut cgen_typ := typ
|
mut cgen_typ := typ
|
||||||
if !or_else {
|
if !or_else {
|
||||||
@ -3115,7 +3147,7 @@ fn (p mut Parser) for_st() {
|
|||||||
p.check(.lcbr)
|
p.check(.lcbr)
|
||||||
p.genln('')
|
p.genln('')
|
||||||
p.statements()
|
p.statements()
|
||||||
p.cur_fn.close_scope()
|
p.close_scope()
|
||||||
p.for_expr_cnt--
|
p.for_expr_cnt--
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3228,7 +3260,7 @@ fn (p mut Parser) return_st() {
|
|||||||
else {
|
else {
|
||||||
ret := p.cgen.cur_line.right(ph)
|
ret := p.cgen.cur_line.right(ph)
|
||||||
p.cgen(p.cur_fn.defer_text)
|
p.cgen(p.cur_fn.defer_text)
|
||||||
if expr_type == 'void*' {
|
if p.cur_fn.defer_text == '' || expr_type == 'void*' {
|
||||||
p.cgen.resetln('return $ret')
|
p.cgen.resetln('return $ret')
|
||||||
} else {
|
} else {
|
||||||
tmp := p.get_tmp()
|
tmp := p.get_tmp()
|
||||||
@ -3369,10 +3401,12 @@ fn is_compile_time_const(s string) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
fn (p &Parser) building_v() bool {
|
fn (p &Parser) building_v() bool {
|
||||||
cur_dir := os.getwd()
|
cur_dir := os.getwd()
|
||||||
return p.file_path.contains('v/compiler') || cur_dir.contains('v/compiler')
|
return p.file_path.contains('v/compiler') || cur_dir.contains('v/compiler')
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
fn (p mut Parser) attribute() {
|
fn (p mut Parser) attribute() {
|
||||||
p.check(.lsbr)
|
p.check(.lsbr)
|
||||||
|
@ -5,13 +5,15 @@
|
|||||||
module builtin
|
module builtin
|
||||||
|
|
||||||
struct array {
|
struct array {
|
||||||
|
is_slice bool
|
||||||
|
pub:
|
||||||
// Using a void pointer allows to implement arrays without generics and without generating
|
// Using a void pointer allows to implement arrays without generics and without generating
|
||||||
// extra code for every type.
|
// extra code for every type.
|
||||||
pub:
|
|
||||||
data voidptr
|
data voidptr
|
||||||
len int
|
len int
|
||||||
cap int
|
cap int
|
||||||
element_size int
|
element_size int
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Private function, used by V (`nums := []int`)
|
// Private function, used by V (`nums := []int`)
|
||||||
@ -144,6 +146,7 @@ pub fn (s array) slice(start, _end int) array {
|
|||||||
data: s.data + start * s.element_size
|
data: s.data + start * s.element_size
|
||||||
len: l
|
len: l
|
||||||
cap: l
|
cap: l
|
||||||
|
is_slice: true
|
||||||
}
|
}
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
@ -215,7 +218,11 @@ pub fn (a []int) str() string {
|
|||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (a []int) free() {
|
//pub fn (a []int) free() {
|
||||||
|
pub fn (a array) free() {
|
||||||
|
if a.is_slice {
|
||||||
|
return
|
||||||
|
}
|
||||||
C.free(a.data)
|
C.free(a.data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -716,12 +716,14 @@ pub fn (s string) free() {
|
|||||||
C.free(s.str)
|
C.free(s.str)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
fn (arr []string) free() {
|
fn (arr []string) free() {
|
||||||
for s in arr {
|
for s in arr {
|
||||||
s.free()
|
s.free()
|
||||||
}
|
}
|
||||||
C.free(arr.data)
|
C.free(arr.data)
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// all_before('23:34:45.234', '.') == '23:34:45'
|
// all_before('23:34:45.234', '.') == '23:34:45'
|
||||||
pub fn (s string) all_before(dot string) string {
|
pub fn (s string) all_before(dot string) string {
|
||||||
|
Loading…
Reference in New Issue
Block a user