mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
unsafe keyword + make array.free() an unsafe method
This commit is contained in:
parent
f7c00b8180
commit
1b518c158b
@ -234,6 +234,7 @@ pub fn (a array) clone() array {
|
||||
}
|
||||
|
||||
//pub fn (a []int) free() {
|
||||
[unsafe_fn]
|
||||
pub fn (a array) free() {
|
||||
//if a.is_slice {
|
||||
//return
|
||||
|
63
vlib/compiler/enum.v
Normal file
63
vlib/compiler/enum.v
Normal file
@ -0,0 +1,63 @@
|
||||
// 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 compiler
|
||||
|
||||
fn (p mut Parser) enum_decl(_enum_name string) {
|
||||
mut enum_name := _enum_name
|
||||
// Specify full type name
|
||||
if !p.builtin_mod && p.mod != 'main' {
|
||||
enum_name = p.prepend_mod(enum_name)
|
||||
}
|
||||
// Skip empty enums
|
||||
if enum_name != 'int' && !p.first_pass() {
|
||||
p.cgen.typedefs << 'typedef int $enum_name;'
|
||||
}
|
||||
p.check(.lcbr)
|
||||
mut val := 0
|
||||
mut fields := []string
|
||||
for p.tok == .name {
|
||||
field := p.check_name()
|
||||
fields << field
|
||||
p.fgenln('')
|
||||
name := '${mod_gen_name(p.mod)}__${enum_name}_$field'
|
||||
if p.pass == .main {
|
||||
p.cgen.consts << '#define $name $val'
|
||||
}
|
||||
if p.tok == .comma {
|
||||
p.next()
|
||||
}
|
||||
// !!!! NAME free
|
||||
if p.first_pass() {
|
||||
p.table.register_const(name, enum_name, p.mod)
|
||||
}
|
||||
val++
|
||||
}
|
||||
p.table.register_type2(Type {
|
||||
name: enum_name
|
||||
mod: p.mod
|
||||
parent: 'int'
|
||||
cat: TypeCategory.enum_
|
||||
enum_vals: fields.clone()
|
||||
})
|
||||
p.check(.rcbr)
|
||||
p.fgenln('\n')
|
||||
}
|
||||
|
||||
fn (p mut Parser) check_enum_member_access() {
|
||||
T := p.find_type(p.expected_type)
|
||||
if T.cat == .enum_ {
|
||||
p.check(.dot)
|
||||
val := p.check_name()
|
||||
// Make sure this enum value exists
|
||||
if !T.has_enum_val(val) {
|
||||
p.error('enum `$T.name` does not have value `$val`')
|
||||
}
|
||||
p.gen(mod_gen_name(T.mod) + '__' + p.expected_type + '_' + val)
|
||||
} else {
|
||||
p.error('`$T.name` is not an enum')
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -31,6 +31,7 @@ mut:
|
||||
is_method bool
|
||||
returns_error bool
|
||||
is_decl bool // type myfn fn(int, int)
|
||||
is_unsafe bool
|
||||
defer_text []string
|
||||
is_generic bool
|
||||
type_pars []string
|
||||
@ -158,10 +159,11 @@ fn (p mut Parser) clear_vars() {
|
||||
p.var_idx = 0
|
||||
if p.local_vars.len > 0 {
|
||||
if p.pref.autofree {
|
||||
p.local_vars.free()
|
||||
//p.local_vars.free()
|
||||
}
|
||||
p.local_vars = []Var
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Function signatures are added to the top of the .c file in the first run.
|
||||
@ -182,9 +184,10 @@ fn (p mut Parser) fn_decl() {
|
||||
}
|
||||
*/
|
||||
mut f := Fn{
|
||||
mod: p.mod
|
||||
is_public: p.tok == .key_pub
|
||||
}
|
||||
mod: p.mod
|
||||
is_public: p.tok == .key_pub
|
||||
is_unsafe: p.attr == 'unsafe_fn'
|
||||
}
|
||||
is_live := p.attr == 'live' && !p.pref.is_so && p.pref.is_live
|
||||
if p.attr == 'live' && p.first_pass() && !p.pref.is_live && !p.pref.is_so {
|
||||
println('INFO: run `v -live program.v` if you want to use [live] functions')
|
||||
@ -631,6 +634,9 @@ fn (p mut Parser) async_fn_call(f Fn, method_ph int, receiver_var, receiver_type
|
||||
|
||||
// p.tok == fn_name
|
||||
fn (p mut Parser) fn_call(f mut Fn, method_ph int, receiver_var, receiver_type string) {
|
||||
if f.is_unsafe && !p.builtin_mod && !p.inside_unsafe {
|
||||
p.error('you are calling an unsafe function outside of an unsafe block')
|
||||
}
|
||||
if !f.is_public && !f.is_c && !p.pref.is_test && !f.is_interface && f.mod != p.mod {
|
||||
if f.name == 'contains' {
|
||||
println('use `value in numbers` instead of `numbers.contains(value)`')
|
||||
@ -1154,7 +1160,7 @@ fn (p mut Parser) replace_type_params(f &Fn, ti TypeInst) []string {
|
||||
r << fr
|
||||
continue
|
||||
}
|
||||
for fi.starts_with('array_') {
|
||||
for fi.starts_with('array_') {
|
||||
fi = fi.right(6)
|
||||
fr += 'array_'
|
||||
}
|
||||
|
@ -117,6 +117,7 @@ pub mut:
|
||||
pub fn (v mut V) finalize_compilation(){
|
||||
// TODO remove
|
||||
if v.pref.autofree {
|
||||
/*
|
||||
println('started freeing v struct')
|
||||
v.table.typesmap.free()
|
||||
v.table.obf_ids.free()
|
||||
@ -131,6 +132,7 @@ pub fn (v mut V) finalize_compilation(){
|
||||
free(v.table)
|
||||
//for p in parsers {}
|
||||
println('done!')
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -52,6 +52,7 @@ mut:
|
||||
inside_if_expr bool
|
||||
inside_unwrapping_match_statement bool
|
||||
inside_return_expr bool
|
||||
inside_unsafe bool
|
||||
is_struct_init bool
|
||||
if_expr_cnt int
|
||||
for_expr_cnt int // to detect whether `continue` can be used
|
||||
@ -839,47 +840,6 @@ fn (p mut Parser) struct_decl() {
|
||||
p.fgenln('\n')
|
||||
}
|
||||
|
||||
fn (p mut Parser) enum_decl(_enum_name string) {
|
||||
mut enum_name := _enum_name
|
||||
// Specify full type name
|
||||
if !p.builtin_mod && p.mod != 'main' {
|
||||
enum_name = p.prepend_mod(enum_name)
|
||||
}
|
||||
// Skip empty enums
|
||||
if enum_name != 'int' && !p.first_pass() {
|
||||
p.cgen.typedefs << 'typedef int $enum_name;'
|
||||
}
|
||||
p.check(.lcbr)
|
||||
mut val := 0
|
||||
mut fields := []string
|
||||
for p.tok == .name {
|
||||
field := p.check_name()
|
||||
fields << field
|
||||
p.fgenln('')
|
||||
name := '${mod_gen_name(p.mod)}__${enum_name}_$field'
|
||||
if p.pass == .main {
|
||||
p.cgen.consts << '#define $name $val'
|
||||
}
|
||||
if p.tok == .comma {
|
||||
p.next()
|
||||
}
|
||||
// !!!! NAME free
|
||||
if p.first_pass() {
|
||||
p.table.register_const(name, enum_name, p.mod)
|
||||
}
|
||||
val++
|
||||
}
|
||||
p.table.register_type2(Type {
|
||||
name: enum_name
|
||||
mod: p.mod
|
||||
parent: 'int'
|
||||
cat: TypeCategory.enum_
|
||||
enum_vals: fields.clone()
|
||||
})
|
||||
p.check(.rcbr)
|
||||
p.fgenln('\n')
|
||||
}
|
||||
|
||||
// check_name checks for a name token and returns its literal
|
||||
fn (p mut Parser) check_name() string {
|
||||
name := p.lit
|
||||
@ -1316,6 +1276,14 @@ fn (p mut Parser) statement(add_semi bool) string {
|
||||
case TokenKind.hash:
|
||||
p.chash()
|
||||
return ''
|
||||
case TokenKind.key_unsafe:
|
||||
p.next()
|
||||
p.inside_unsafe = true
|
||||
p.check(.lcbr)
|
||||
p.genln('{')
|
||||
p.statements()
|
||||
p.inside_unsafe = false
|
||||
//p.check(.rcbr)
|
||||
case TokenKind.dollar:
|
||||
p.comp_time()
|
||||
case TokenKind.key_if:
|
||||
@ -1828,6 +1796,10 @@ fn (p mut Parser) name_expr() string {
|
||||
p.next()
|
||||
p.check(.dot)
|
||||
val := p.lit
|
||||
if !enum_type.has_enum_val(val) {
|
||||
p.error('enum `$enum_type.name` does not have value `$val`')
|
||||
}
|
||||
|
||||
// println('enum val $val')
|
||||
p.gen(mod_gen_name(enum_type.mod) + '__' + enum_type.name + '_' + val)// `color = main__Color_green`
|
||||
p.next()
|
||||
@ -1910,21 +1882,6 @@ fn (p mut Parser) get_struct_type(name_ string, is_c bool, is_ptr bool) string {
|
||||
return p.struct_init(name)
|
||||
}
|
||||
|
||||
fn (p mut Parser) check_enum_member_access() {
|
||||
T := p.find_type(p.expected_type)
|
||||
if T.cat == .enum_ {
|
||||
p.check(.dot)
|
||||
val := p.check_name()
|
||||
// Make sure this enum value exists
|
||||
if !T.has_enum_val(val) {
|
||||
p.error('enum `$T.name` does not have value `$val`')
|
||||
}
|
||||
p.gen(mod_gen_name(T.mod) + '__' + p.expected_type + '_' + val)
|
||||
} else {
|
||||
p.error('`$T.name` is not an enum')
|
||||
}
|
||||
}
|
||||
|
||||
fn (p mut Parser) get_var_type(name string, is_ptr bool, is_deref bool) string {
|
||||
v := p.find_var_check_new_var(name) or { return "" }
|
||||
if name == '_' {
|
||||
@ -4212,7 +4169,7 @@ fn (p mut Parser) check_unused_imports() {
|
||||
|
||||
fn (p mut Parser) is_next_expr_fn_call() (bool, string) {
|
||||
mut next_expr := p.lit
|
||||
mut is_fn_call := p.peek() == .lpar
|
||||
mut is_fn_call := p.peek() == .lpar
|
||||
if !is_fn_call {
|
||||
mut i := p.token_idx+1
|
||||
for (p.tokens[i].tok == .dot || p.tokens[i].tok == .name) &&
|
||||
|
@ -110,6 +110,7 @@ enum TokenKind {
|
||||
key_union
|
||||
key_pub
|
||||
key_static
|
||||
key_unsafe
|
||||
keyword_end
|
||||
}
|
||||
|
||||
@ -210,6 +211,7 @@ fn build_token_str() []string {
|
||||
s[TokenKind.key_break] = 'break'
|
||||
s[TokenKind.key_import] = 'import'
|
||||
s[TokenKind.key_embed] = 'embed'
|
||||
s[TokenKind.key_unsafe] = 'unsafe'
|
||||
//Tokens[key_typeof] = 'typeof'
|
||||
s[TokenKind.key_default] = 'default'
|
||||
s[TokenKind.key_enum] = 'enum'
|
||||
|
Loading…
Reference in New Issue
Block a user