parent
818220de45
commit
3956ea4665
|
@ -1,7 +1,13 @@
|
||||||
vlib/v/checker/tests/assign_mut.vv:3:11: error: expecting `:=` (e.g. `mut x :=`)
|
vlib/v/checker/tests/assign_mut.vv:3:9: error: `mut` not allowed with `=` (use `:=` to declare a variable)
|
||||||
1 | fn main() {
|
1 | fn main() {
|
||||||
2 | mut z := 1
|
2 | mut z := 1
|
||||||
3 | mut z = 1
|
3 | mut z = 1
|
||||||
| ^
|
| ^
|
||||||
4 | mut i := 2
|
4 | mut i := 2
|
||||||
5 | i, mut z = 2,3
|
5 | i, mut z = 2,3
|
||||||
|
vlib/v/checker/tests/assign_mut.vv:5:12: error: `mut` not allowed with `=` (use `:=` to declare a variable)
|
||||||
|
3 | mut z = 1
|
||||||
|
4 | mut i := 2
|
||||||
|
5 | i, mut z = 2,3
|
||||||
|
| ^
|
||||||
|
6 | }
|
||||||
|
|
|
@ -212,7 +212,7 @@ pub fn (t &Table) get_type_symbol(typ Type) &TypeSymbol {
|
||||||
return &t.types[idx]
|
return &t.types[idx]
|
||||||
}
|
}
|
||||||
// this should never happen
|
// this should never happen
|
||||||
panic('get_type_symbol: invalid type (typ=$typ idx=$idx). Compiler bug. This should never happen.')
|
panic('get_type_symbol: invalid type (typ=$typ idx=$idx). Compiler bug. This should never happen')
|
||||||
}
|
}
|
||||||
|
|
||||||
// get_final_type_symbol follows aliases until it gets to a "real" Type
|
// get_final_type_symbol follows aliases until it gets to a "real" Type
|
||||||
|
@ -228,318 +228,7 @@ pub fn (t &Table) get_final_type_symbol(typ Type) &TypeSymbol {
|
||||||
return &t.types[idx]
|
return &t.types[idx]
|
||||||
}
|
}
|
||||||
// this should never happen
|
// this should never happen
|
||||||
panic('get_final_type_symbol: invalid type (typ=$typ idx=$idx). Compiler bug. This should never happen.')
|
panic('get_final_type_symbol: invalid type (typ=$typ idx=$idx). Compiler bug. This should never happen')
|
||||||
}
|
|
||||||
|
|
||||||
[inline]
|
|
||||||
pub fn (t &Table) get_type_name(typ Type) string {
|
|
||||||
typ_sym := t.get_type_symbol(typ)
|
|
||||||
return typ_sym.name
|
|
||||||
}
|
|
||||||
|
|
||||||
[inline]
|
|
||||||
pub fn (t &Table) unalias_num_type(typ Type) Type {
|
|
||||||
sym := t.get_type_symbol(typ)
|
|
||||||
if sym.kind == .alias {
|
|
||||||
pt := (sym.info as Alias).parent_type
|
|
||||||
if pt <= f64_type && pt >= void_type {
|
|
||||||
return pt
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return typ
|
|
||||||
}
|
|
||||||
|
|
||||||
// this will override or register builtin type
|
|
||||||
// allows prexisitng types added in register_builtins
|
|
||||||
// to be overriden with their real type info
|
|
||||||
[inline]
|
|
||||||
pub fn (mut t Table) register_builtin_type_symbol(typ TypeSymbol) int {
|
|
||||||
existing_idx := t.type_idxs[typ.name]
|
|
||||||
if existing_idx > 0 {
|
|
||||||
if existing_idx >= string_type_idx {
|
|
||||||
if existing_idx == string_type_idx {
|
|
||||||
existing_type := t.types[existing_idx]
|
|
||||||
t.types[existing_idx] = {
|
|
||||||
typ |
|
|
||||||
kind: existing_type.kind
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
t.types[existing_idx] = typ
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return existing_idx
|
|
||||||
}
|
|
||||||
return t.register_type_symbol(typ)
|
|
||||||
}
|
|
||||||
|
|
||||||
[inline]
|
|
||||||
pub fn (mut t Table) register_type_symbol(typ TypeSymbol) int {
|
|
||||||
// println('register_type_symbol( $typ.name )')
|
|
||||||
existing_idx := t.type_idxs[typ.name]
|
|
||||||
if existing_idx > 0 {
|
|
||||||
ex_type := t.types[existing_idx]
|
|
||||||
match ex_type.kind {
|
|
||||||
.placeholder {
|
|
||||||
// override placeholder
|
|
||||||
// println('overriding type placeholder `$typ.name`')
|
|
||||||
t.types[existing_idx] = {
|
|
||||||
typ |
|
|
||||||
methods: ex_type.methods
|
|
||||||
}
|
|
||||||
return existing_idx
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if ex_type.kind == typ.kind {
|
|
||||||
return existing_idx
|
|
||||||
}
|
|
||||||
// panic('cannot register type `$typ.name`, another type with this name exists')
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
typ_idx := t.types.len
|
|
||||||
t.types << typ
|
|
||||||
t.type_idxs[typ.name] = typ_idx
|
|
||||||
return typ_idx
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn (t &Table) known_type(name string) bool {
|
|
||||||
t.find_type(name) or {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
[inline]
|
|
||||||
pub fn (t &Table) array_name(elem_type Type, nr_dims int) string {
|
|
||||||
elem_type_sym := t.get_type_symbol(elem_type)
|
|
||||||
return // Copyright (c) 2019-2020 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 table
|
|
||||||
|
|
||||||
pub struct Table {
|
|
||||||
pub mut:
|
|
||||||
types []TypeSymbol
|
|
||||||
type_idxs map[string]int
|
|
||||||
fns map[string]Fn
|
|
||||||
imports []string // List of all imports
|
|
||||||
modules []string // Topologically sorted list of all modules registered by the application
|
|
||||||
cflags []cflag.CFlag
|
|
||||||
redefined_fns []string
|
|
||||||
fn_gen_types map[string][]Type // for generic functions
|
|
||||||
cmod_prefix string // needed for table.type_to_str(Type) while vfmt; contains `os.`
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Fn {
|
|
||||||
pub:
|
|
||||||
args []Param
|
|
||||||
return_type Type
|
|
||||||
return_type_source_name string
|
|
||||||
is_variadic bool
|
|
||||||
language Language
|
|
||||||
is_generic bool
|
|
||||||
is_pub bool
|
|
||||||
is_deprecated bool
|
|
||||||
is_unsafe bool
|
|
||||||
is_placeholder bool
|
|
||||||
mod string
|
|
||||||
ctdefine string // compile time define. myflag, when [if myflag] tag
|
|
||||||
attrs []Attr
|
|
||||||
pub mut:
|
|
||||||
name string
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Param {
|
|
||||||
pub:
|
|
||||||
pos token.Position
|
|
||||||
name string
|
|
||||||
is_mut bool
|
|
||||||
typ Type
|
|
||||||
type_source_name string
|
|
||||||
is_hidden bool // interface first arg
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Var {
|
|
||||||
pub:
|
|
||||||
name string
|
|
||||||
is_mut bool
|
|
||||||
mut:
|
|
||||||
typ Type
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new_table() &Table {
|
|
||||||
mut t := &Table{}
|
|
||||||
t.register_builtin_type_symbols()
|
|
||||||
return t
|
|
||||||
}
|
|
||||||
|
|
||||||
// used to compare fn's & for naming anon fn's
|
|
||||||
pub fn (f &Fn) signature() string {
|
|
||||||
mut sig := ''
|
|
||||||
for i, arg in f.args {
|
|
||||||
// TODO: for now ignore mut/pts in sig for now
|
|
||||||
typ := arg.typ.set_nr_muls(0)
|
|
||||||
// if arg.is_mut {
|
|
||||||
// sig += 'mut_'
|
|
||||||
// }
|
|
||||||
// sig += '$arg.typ'
|
|
||||||
sig += '$typ'
|
|
||||||
if i < f.args.len - 1 {
|
|
||||||
sig += '_'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sig += '_$f.return_type'
|
|
||||||
return sig
|
|
||||||
}
|
|
||||||
|
|
||||||
// source_signature generates the signature of a function which looks like in the V source
|
|
||||||
pub fn (f &Fn) source_signature() string {
|
|
||||||
mut sig := '('
|
|
||||||
for i, arg in f.args {
|
|
||||||
if arg.is_mut {
|
|
||||||
sig += 'mut '
|
|
||||||
}
|
|
||||||
sig += '$arg.type_source_name'
|
|
||||||
if i < f.args.len - 1 {
|
|
||||||
sig += ', '
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sig += ') $f.return_type_source_name'
|
|
||||||
return sig
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn (f &Fn) is_same_method_as(func &Fn) bool {
|
|
||||||
if f.return_type != func.return_type {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if f.args.len != func.args.len {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
for i in 1 .. f.args.len {
|
|
||||||
if f.args[i].typ != func.args[i].typ {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn (t &Table) find_fn(name string) ?Fn {
|
|
||||||
f := t.fns[name]
|
|
||||||
if f.name.str != 0 {
|
|
||||||
// TODO
|
|
||||||
return f
|
|
||||||
}
|
|
||||||
return none
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn (t &Table) known_fn(name string) bool {
|
|
||||||
t.find_fn(name) or {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn (mut t Table) register_fn(new_fn Fn) {
|
|
||||||
// println('reg fn $new_fn.name nr_args=$new_fn.args.len')
|
|
||||||
t.fns[new_fn.name] = new_fn
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn (mut t TypeSymbol) register_method(new_fn Fn) {
|
|
||||||
// println('reg me $new_fn.name nr_args=$new_fn.args.len')
|
|
||||||
t.methods << new_fn
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn (t &Table) type_has_method(s &TypeSymbol, name string) bool {
|
|
||||||
// println('type_has_method($s.name, $name) types.len=$t.types.len s.parent_idx=$s.parent_idx')
|
|
||||||
if _ := t.type_find_method(s, name) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// search from current type up through each parent looking for method
|
|
||||||
pub fn (t &Table) type_find_method(s &TypeSymbol, name string) ?Fn {
|
|
||||||
// println('type_find_method($s.name, $name) types.len=$t.types.len s.parent_idx=$s.parent_idx')
|
|
||||||
mut ts := s
|
|
||||||
for {
|
|
||||||
if method := ts.find_method(name) {
|
|
||||||
return method
|
|
||||||
}
|
|
||||||
if ts.parent_idx == 0 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
ts = &t.types[ts.parent_idx]
|
|
||||||
}
|
|
||||||
return none
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn (t &Table) struct_has_field(s &TypeSymbol, name string) bool {
|
|
||||||
// println('struct_has_field($s.name, $name) types.len=$t.types.len s.parent_idx=$s.parent_idx')
|
|
||||||
if _ := t.struct_find_field(s, name) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// search from current type up through each parent looking for field
|
|
||||||
pub fn (t &Table) struct_find_field(s &TypeSymbol, name string) ?Field {
|
|
||||||
// println('struct_find_field($s.name, $name) types.len=$t.types.len s.parent_idx=$s.parent_idx')
|
|
||||||
mut ts := s
|
|
||||||
for {
|
|
||||||
if ts.info is Struct {
|
|
||||||
struct_info := ts.info as Struct
|
|
||||||
if field := struct_info.find_field(name) {
|
|
||||||
return field
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ts.parent_idx == 0 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
ts = &t.types[ts.parent_idx]
|
|
||||||
}
|
|
||||||
return none
|
|
||||||
}
|
|
||||||
|
|
||||||
[inline]
|
|
||||||
pub fn (t &Table) find_type_idx(name string) int {
|
|
||||||
return t.type_idxs[name]
|
|
||||||
}
|
|
||||||
|
|
||||||
[inline]
|
|
||||||
pub fn (t &Table) find_type(name string) ?TypeSymbol {
|
|
||||||
idx := t.type_idxs[name]
|
|
||||||
if idx > 0 {
|
|
||||||
return t.types[idx]
|
|
||||||
}
|
|
||||||
return none
|
|
||||||
}
|
|
||||||
|
|
||||||
[inline]
|
|
||||||
pub fn (t &Table) get_type_symbol(typ Type) &TypeSymbol {
|
|
||||||
// println('get_type_symbol $typ')
|
|
||||||
idx := typ.idx()
|
|
||||||
if idx > 0 {
|
|
||||||
return &t.types[idx]
|
|
||||||
}
|
|
||||||
// this should never happen
|
|
||||||
panic('get_type_symbol: invalid type (typ=$typ idx=$idx). Compiler bug. This should never happen.')
|
|
||||||
}
|
|
||||||
|
|
||||||
// get_final_type_symbol follows aliases until it gets to a "real" Type
|
|
||||||
[inline]
|
|
||||||
pub fn (t &Table) get_final_type_symbol(typ Type) &TypeSymbol {
|
|
||||||
idx := typ.idx()
|
|
||||||
if idx > 0 {
|
|
||||||
current_type := t.types[idx]
|
|
||||||
if current_type.kind == .alias {
|
|
||||||
alias_info := current_type.info as Alias
|
|
||||||
return t.get_final_type_symbol(alias_info.parent_type)
|
|
||||||
}
|
|
||||||
return &t.types[idx]
|
|
||||||
}
|
|
||||||
// this should never happen
|
|
||||||
panic('get_final_type_symbol: invalid type (typ=$typ idx=$idx). Compiler bug. This should never happen.')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[inline]
|
[inline]
|
||||||
|
@ -628,654 +317,7 @@ pub fn (t &Table) array_name(elem_type Type, nr_dims int) string {
|
||||||
'_ptr'.repeat(elem_type.nr_muls())
|
'_ptr'.repeat(elem_type.nr_muls())
|
||||||
} else {
|
} else {
|
||||||
''
|
''
|
||||||
} +
|
} + if nr_dims > 1 {
|
||||||
if nr_dims > 1 {
|
|
||||||
'_${nr_dims}d'
|
|
||||||
} else {
|
|
||||||
''
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// array_source_name generates the original name for the v source.
|
|
||||||
// e. g. []int
|
|
||||||
[inline]
|
|
||||||
pub fn (t &Table) array_source_name(elem_type Type) string {
|
|
||||||
elem_type_sym := t.get_type_symbol(elem_type)
|
|
||||||
ptr := if elem_type.is_ptr() { '&' } else { '' }
|
|
||||||
return '[]$ptr$elem_type_sym.source_name'
|
|
||||||
}
|
|
||||||
|
|
||||||
[inline]
|
|
||||||
pub fn (t &Table) array_fixed_name(elem_type Type, size, nr_dims int) string {
|
|
||||||
elem_type_sym := t.get_type_symbol(elem_type)
|
|
||||||
return // Copyright (c) 2019-2020 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 table
|
|
||||||
|
|
||||||
pub struct Table {
|
|
||||||
pub mut:
|
|
||||||
types []TypeSymbol
|
|
||||||
type_idxs map[string]int
|
|
||||||
fns map[string]Fn
|
|
||||||
imports []string // List of all imports
|
|
||||||
modules []string // Topologically sorted list of all modules registered by the application
|
|
||||||
cflags []cflag.CFlag
|
|
||||||
redefined_fns []string
|
|
||||||
fn_gen_types map[string][]Type // for generic functions
|
|
||||||
cmod_prefix string // needed for table.type_to_str(Type) while vfmt; contains `os.`
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Fn {
|
|
||||||
pub:
|
|
||||||
args []Param
|
|
||||||
return_type Type
|
|
||||||
return_type_source_name string
|
|
||||||
is_variadic bool
|
|
||||||
language Language
|
|
||||||
is_generic bool
|
|
||||||
is_pub bool
|
|
||||||
is_deprecated bool
|
|
||||||
is_unsafe bool
|
|
||||||
is_placeholder bool
|
|
||||||
mod string
|
|
||||||
ctdefine string // compile time define. myflag, when [if myflag] tag
|
|
||||||
attrs []Attr
|
|
||||||
pub mut:
|
|
||||||
name string
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Param {
|
|
||||||
pub:
|
|
||||||
pos token.Position
|
|
||||||
name string
|
|
||||||
is_mut bool
|
|
||||||
typ Type
|
|
||||||
type_source_name string
|
|
||||||
is_hidden bool // interface first arg
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Var {
|
|
||||||
pub:
|
|
||||||
name string
|
|
||||||
is_mut bool
|
|
||||||
mut:
|
|
||||||
typ Type
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new_table() &Table {
|
|
||||||
mut t := &Table{}
|
|
||||||
t.register_builtin_type_symbols()
|
|
||||||
return t
|
|
||||||
}
|
|
||||||
|
|
||||||
// used to compare fn's & for naming anon fn's
|
|
||||||
pub fn (f &Fn) signature() string {
|
|
||||||
mut sig := ''
|
|
||||||
for i, arg in f.args {
|
|
||||||
// TODO: for now ignore mut/pts in sig for now
|
|
||||||
typ := arg.typ.set_nr_muls(0)
|
|
||||||
// if arg.is_mut {
|
|
||||||
// sig += 'mut_'
|
|
||||||
// }
|
|
||||||
// sig += '$arg.typ'
|
|
||||||
sig += '$typ'
|
|
||||||
if i < f.args.len - 1 {
|
|
||||||
sig += '_'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sig += '_$f.return_type'
|
|
||||||
return sig
|
|
||||||
}
|
|
||||||
|
|
||||||
// source_signature generates the signature of a function which looks like in the V source
|
|
||||||
pub fn (f &Fn) source_signature() string {
|
|
||||||
mut sig := '('
|
|
||||||
for i, arg in f.args {
|
|
||||||
if arg.is_mut {
|
|
||||||
sig += 'mut '
|
|
||||||
}
|
|
||||||
sig += '$arg.type_source_name'
|
|
||||||
if i < f.args.len - 1 {
|
|
||||||
sig += ', '
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sig += ') $f.return_type_source_name'
|
|
||||||
return sig
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn (f &Fn) is_same_method_as(func &Fn) bool {
|
|
||||||
if f.return_type != func.return_type {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if f.args.len != func.args.len {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
for i in 1 .. f.args.len {
|
|
||||||
if f.args[i].typ != func.args[i].typ {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn (t &Table) find_fn(name string) ?Fn {
|
|
||||||
f := t.fns[name]
|
|
||||||
if f.name.str != 0 {
|
|
||||||
// TODO
|
|
||||||
return f
|
|
||||||
}
|
|
||||||
return none
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn (t &Table) known_fn(name string) bool {
|
|
||||||
t.find_fn(name) or {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn (mut t Table) register_fn(new_fn Fn) {
|
|
||||||
// println('reg fn $new_fn.name nr_args=$new_fn.args.len')
|
|
||||||
t.fns[new_fn.name] = new_fn
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn (mut t TypeSymbol) register_method(new_fn Fn) {
|
|
||||||
// println('reg me $new_fn.name nr_args=$new_fn.args.len')
|
|
||||||
t.methods << new_fn
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn (t &Table) type_has_method(s &TypeSymbol, name string) bool {
|
|
||||||
// println('type_has_method($s.name, $name) types.len=$t.types.len s.parent_idx=$s.parent_idx')
|
|
||||||
if _ := t.type_find_method(s, name) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// search from current type up through each parent looking for method
|
|
||||||
pub fn (t &Table) type_find_method(s &TypeSymbol, name string) ?Fn {
|
|
||||||
// println('type_find_method($s.name, $name) types.len=$t.types.len s.parent_idx=$s.parent_idx')
|
|
||||||
mut ts := s
|
|
||||||
for {
|
|
||||||
if method := ts.find_method(name) {
|
|
||||||
return method
|
|
||||||
}
|
|
||||||
if ts.parent_idx == 0 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
ts = &t.types[ts.parent_idx]
|
|
||||||
}
|
|
||||||
return none
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn (t &Table) struct_has_field(s &TypeSymbol, name string) bool {
|
|
||||||
// println('struct_has_field($s.name, $name) types.len=$t.types.len s.parent_idx=$s.parent_idx')
|
|
||||||
if _ := t.struct_find_field(s, name) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// search from current type up through each parent looking for field
|
|
||||||
pub fn (t &Table) struct_find_field(s &TypeSymbol, name string) ?Field {
|
|
||||||
// println('struct_find_field($s.name, $name) types.len=$t.types.len s.parent_idx=$s.parent_idx')
|
|
||||||
mut ts := s
|
|
||||||
for {
|
|
||||||
if ts.info is Struct {
|
|
||||||
struct_info := ts.info as Struct
|
|
||||||
if field := struct_info.find_field(name) {
|
|
||||||
return field
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ts.parent_idx == 0 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
ts = &t.types[ts.parent_idx]
|
|
||||||
}
|
|
||||||
return none
|
|
||||||
}
|
|
||||||
|
|
||||||
[inline]
|
|
||||||
pub fn (t &Table) find_type_idx(name string) int {
|
|
||||||
return t.type_idxs[name]
|
|
||||||
}
|
|
||||||
|
|
||||||
[inline]
|
|
||||||
pub fn (t &Table) find_type(name string) ?TypeSymbol {
|
|
||||||
idx := t.type_idxs[name]
|
|
||||||
if idx > 0 {
|
|
||||||
return t.types[idx]
|
|
||||||
}
|
|
||||||
return none
|
|
||||||
}
|
|
||||||
|
|
||||||
[inline]
|
|
||||||
pub fn (t &Table) get_type_symbol(typ Type) &TypeSymbol {
|
|
||||||
// println('get_type_symbol $typ')
|
|
||||||
idx := typ.idx()
|
|
||||||
if idx > 0 {
|
|
||||||
return &t.types[idx]
|
|
||||||
}
|
|
||||||
// this should never happen
|
|
||||||
panic('get_type_symbol: invalid type (typ=$typ idx=$idx). Compiler bug. This should never happen.')
|
|
||||||
}
|
|
||||||
|
|
||||||
// get_final_type_symbol follows aliases until it gets to a "real" Type
|
|
||||||
[inline]
|
|
||||||
pub fn (t &Table) get_final_type_symbol(typ Type) &TypeSymbol {
|
|
||||||
idx := typ.idx()
|
|
||||||
if idx > 0 {
|
|
||||||
current_type := t.types[idx]
|
|
||||||
if current_type.kind == .alias {
|
|
||||||
alias_info := current_type.info as Alias
|
|
||||||
return t.get_final_type_symbol(alias_info.parent_type)
|
|
||||||
}
|
|
||||||
return &t.types[idx]
|
|
||||||
}
|
|
||||||
// this should never happen
|
|
||||||
panic('get_final_type_symbol: invalid type (typ=$typ idx=$idx). Compiler bug. This should never happen.')
|
|
||||||
}
|
|
||||||
|
|
||||||
[inline]
|
|
||||||
pub fn (t &Table) get_type_name(typ Type) string {
|
|
||||||
typ_sym := t.get_type_symbol(typ)
|
|
||||||
return typ_sym.name
|
|
||||||
}
|
|
||||||
|
|
||||||
[inline]
|
|
||||||
pub fn (t &Table) unalias_num_type(typ Type) Type {
|
|
||||||
sym := t.get_type_symbol(typ)
|
|
||||||
if sym.kind == .alias {
|
|
||||||
pt := (sym.info as Alias).parent_type
|
|
||||||
if pt <= f64_type && pt >= void_type {
|
|
||||||
return pt
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return typ
|
|
||||||
}
|
|
||||||
|
|
||||||
// this will override or register builtin type
|
|
||||||
// allows prexisitng types added in register_builtins
|
|
||||||
// to be overriden with their real type info
|
|
||||||
[inline]
|
|
||||||
pub fn (mut t Table) register_builtin_type_symbol(typ TypeSymbol) int {
|
|
||||||
existing_idx := t.type_idxs[typ.name]
|
|
||||||
if existing_idx > 0 {
|
|
||||||
if existing_idx >= string_type_idx {
|
|
||||||
if existing_idx == string_type_idx {
|
|
||||||
existing_type := t.types[existing_idx]
|
|
||||||
t.types[existing_idx] = {
|
|
||||||
typ |
|
|
||||||
kind: existing_type.kind
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
t.types[existing_idx] = typ
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return existing_idx
|
|
||||||
}
|
|
||||||
return t.register_type_symbol(typ)
|
|
||||||
}
|
|
||||||
|
|
||||||
[inline]
|
|
||||||
pub fn (mut t Table) register_type_symbol(typ TypeSymbol) int {
|
|
||||||
// println('register_type_symbol( $typ.name )')
|
|
||||||
existing_idx := t.type_idxs[typ.name]
|
|
||||||
if existing_idx > 0 {
|
|
||||||
ex_type := t.types[existing_idx]
|
|
||||||
match ex_type.kind {
|
|
||||||
.placeholder {
|
|
||||||
// override placeholder
|
|
||||||
// println('overriding type placeholder `$typ.name`')
|
|
||||||
t.types[existing_idx] = {
|
|
||||||
typ |
|
|
||||||
methods: ex_type.methods
|
|
||||||
}
|
|
||||||
return existing_idx
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if ex_type.kind == typ.kind {
|
|
||||||
return existing_idx
|
|
||||||
}
|
|
||||||
// panic('cannot register type `$typ.name`, another type with this name exists')
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
typ_idx := t.types.len
|
|
||||||
t.types << typ
|
|
||||||
t.type_idxs[typ.name] = typ_idx
|
|
||||||
return typ_idx
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn (t &Table) known_type(name string) bool {
|
|
||||||
t.find_type(name) or {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
[inline]
|
|
||||||
pub fn (t &Table) array_name(elem_type Type, nr_dims int) string {
|
|
||||||
elem_type_sym := t.get_type_symbol(elem_type)
|
|
||||||
return // Copyright (c) 2019-2020 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 table
|
|
||||||
|
|
||||||
pub struct Table {
|
|
||||||
pub mut:
|
|
||||||
types []TypeSymbol
|
|
||||||
type_idxs map[string]int
|
|
||||||
fns map[string]Fn
|
|
||||||
imports []string // List of all imports
|
|
||||||
modules []string // Topologically sorted list of all modules registered by the application
|
|
||||||
cflags []cflag.CFlag
|
|
||||||
redefined_fns []string
|
|
||||||
fn_gen_types map[string][]Type // for generic functions
|
|
||||||
cmod_prefix string // needed for table.type_to_str(Type) while vfmt; contains `os.`
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Fn {
|
|
||||||
pub:
|
|
||||||
args []Param
|
|
||||||
return_type Type
|
|
||||||
return_type_source_name string
|
|
||||||
is_variadic bool
|
|
||||||
language Language
|
|
||||||
is_generic bool
|
|
||||||
is_pub bool
|
|
||||||
is_deprecated bool
|
|
||||||
is_unsafe bool
|
|
||||||
is_placeholder bool
|
|
||||||
mod string
|
|
||||||
ctdefine string // compile time define. myflag, when [if myflag] tag
|
|
||||||
attrs []Attr
|
|
||||||
pub mut:
|
|
||||||
name string
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Param {
|
|
||||||
pub:
|
|
||||||
pos token.Position
|
|
||||||
name string
|
|
||||||
is_mut bool
|
|
||||||
typ Type
|
|
||||||
type_source_name string
|
|
||||||
is_hidden bool // interface first arg
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Var {
|
|
||||||
pub:
|
|
||||||
name string
|
|
||||||
is_mut bool
|
|
||||||
mut:
|
|
||||||
typ Type
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new_table() &Table {
|
|
||||||
mut t := &Table{}
|
|
||||||
t.register_builtin_type_symbols()
|
|
||||||
return t
|
|
||||||
}
|
|
||||||
|
|
||||||
// used to compare fn's & for naming anon fn's
|
|
||||||
pub fn (f &Fn) signature() string {
|
|
||||||
mut sig := ''
|
|
||||||
for i, arg in f.args {
|
|
||||||
// TODO: for now ignore mut/pts in sig for now
|
|
||||||
typ := arg.typ.set_nr_muls(0)
|
|
||||||
// if arg.is_mut {
|
|
||||||
// sig += 'mut_'
|
|
||||||
// }
|
|
||||||
// sig += '$arg.typ'
|
|
||||||
sig += '$typ'
|
|
||||||
if i < f.args.len - 1 {
|
|
||||||
sig += '_'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sig += '_$f.return_type'
|
|
||||||
return sig
|
|
||||||
}
|
|
||||||
|
|
||||||
// source_signature generates the signature of a function which looks like in the V source
|
|
||||||
pub fn (f &Fn) source_signature() string {
|
|
||||||
mut sig := '('
|
|
||||||
for i, arg in f.args {
|
|
||||||
if arg.is_mut {
|
|
||||||
sig += 'mut '
|
|
||||||
}
|
|
||||||
sig += '$arg.type_source_name'
|
|
||||||
if i < f.args.len - 1 {
|
|
||||||
sig += ', '
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sig += ') $f.return_type_source_name'
|
|
||||||
return sig
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn (f &Fn) is_same_method_as(func &Fn) bool {
|
|
||||||
if f.return_type != func.return_type {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if f.args.len != func.args.len {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
for i in 1 .. f.args.len {
|
|
||||||
if f.args[i].typ != func.args[i].typ {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn (t &Table) find_fn(name string) ?Fn {
|
|
||||||
f := t.fns[name]
|
|
||||||
if f.name.str != 0 {
|
|
||||||
// TODO
|
|
||||||
return f
|
|
||||||
}
|
|
||||||
return none
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn (t &Table) known_fn(name string) bool {
|
|
||||||
t.find_fn(name) or {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn (mut t Table) register_fn(new_fn Fn) {
|
|
||||||
// println('reg fn $new_fn.name nr_args=$new_fn.args.len')
|
|
||||||
t.fns[new_fn.name] = new_fn
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn (mut t TypeSymbol) register_method(new_fn Fn) {
|
|
||||||
// println('reg me $new_fn.name nr_args=$new_fn.args.len')
|
|
||||||
t.methods << new_fn
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn (t &Table) type_has_method(s &TypeSymbol, name string) bool {
|
|
||||||
// println('type_has_method($s.name, $name) types.len=$t.types.len s.parent_idx=$s.parent_idx')
|
|
||||||
if _ := t.type_find_method(s, name) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// search from current type up through each parent looking for method
|
|
||||||
pub fn (t &Table) type_find_method(s &TypeSymbol, name string) ?Fn {
|
|
||||||
// println('type_find_method($s.name, $name) types.len=$t.types.len s.parent_idx=$s.parent_idx')
|
|
||||||
mut ts := s
|
|
||||||
for {
|
|
||||||
if method := ts.find_method(name) {
|
|
||||||
return method
|
|
||||||
}
|
|
||||||
if ts.parent_idx == 0 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
ts = &t.types[ts.parent_idx]
|
|
||||||
}
|
|
||||||
return none
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn (t &Table) struct_has_field(s &TypeSymbol, name string) bool {
|
|
||||||
// println('struct_has_field($s.name, $name) types.len=$t.types.len s.parent_idx=$s.parent_idx')
|
|
||||||
if _ := t.struct_find_field(s, name) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// search from current type up through each parent looking for field
|
|
||||||
pub fn (t &Table) struct_find_field(s &TypeSymbol, name string) ?Field {
|
|
||||||
// println('struct_find_field($s.name, $name) types.len=$t.types.len s.parent_idx=$s.parent_idx')
|
|
||||||
mut ts := s
|
|
||||||
for {
|
|
||||||
if ts.info is Struct {
|
|
||||||
struct_info := ts.info as Struct
|
|
||||||
if field := struct_info.find_field(name) {
|
|
||||||
return field
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ts.parent_idx == 0 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
ts = &t.types[ts.parent_idx]
|
|
||||||
}
|
|
||||||
return none
|
|
||||||
}
|
|
||||||
|
|
||||||
[inline]
|
|
||||||
pub fn (t &Table) find_type_idx(name string) int {
|
|
||||||
return t.type_idxs[name]
|
|
||||||
}
|
|
||||||
|
|
||||||
[inline]
|
|
||||||
pub fn (t &Table) find_type(name string) ?TypeSymbol {
|
|
||||||
idx := t.type_idxs[name]
|
|
||||||
if idx > 0 {
|
|
||||||
return t.types[idx]
|
|
||||||
}
|
|
||||||
return none
|
|
||||||
}
|
|
||||||
|
|
||||||
[inline]
|
|
||||||
pub fn (t &Table) get_type_symbol(typ Type) &TypeSymbol {
|
|
||||||
// println('get_type_symbol $typ')
|
|
||||||
idx := typ.idx()
|
|
||||||
if idx > 0 {
|
|
||||||
return &t.types[idx]
|
|
||||||
}
|
|
||||||
// this should never happen
|
|
||||||
panic('get_type_symbol: invalid type (typ=$typ idx=$idx). Compiler bug. This should never happen.')
|
|
||||||
}
|
|
||||||
|
|
||||||
// get_final_type_symbol follows aliases until it gets to a "real" Type
|
|
||||||
[inline]
|
|
||||||
pub fn (t &Table) get_final_type_symbol(typ Type) &TypeSymbol {
|
|
||||||
idx := typ.idx()
|
|
||||||
if idx > 0 {
|
|
||||||
current_type := t.types[idx]
|
|
||||||
if current_type.kind == .alias {
|
|
||||||
alias_info := current_type.info as Alias
|
|
||||||
return t.get_final_type_symbol(alias_info.parent_type)
|
|
||||||
}
|
|
||||||
return &t.types[idx]
|
|
||||||
}
|
|
||||||
// this should never happen
|
|
||||||
panic('get_final_type_symbol: invalid type (typ=$typ idx=$idx). Compiler bug. This should never happen.')
|
|
||||||
}
|
|
||||||
|
|
||||||
[inline]
|
|
||||||
pub fn (t &Table) get_type_name(typ Type) string {
|
|
||||||
typ_sym := t.get_type_symbol(typ)
|
|
||||||
return typ_sym.name
|
|
||||||
}
|
|
||||||
|
|
||||||
[inline]
|
|
||||||
pub fn (t &Table) unalias_num_type(typ Type) Type {
|
|
||||||
sym := t.get_type_symbol(typ)
|
|
||||||
if sym.kind == .alias {
|
|
||||||
pt := (sym.info as Alias).parent_type
|
|
||||||
if pt <= f64_type && pt >= void_type {
|
|
||||||
return pt
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return typ
|
|
||||||
}
|
|
||||||
|
|
||||||
// this will override or register builtin type
|
|
||||||
// allows prexisitng types added in register_builtins
|
|
||||||
// to be overriden with their real type info
|
|
||||||
[inline]
|
|
||||||
pub fn (mut t Table) register_builtin_type_symbol(typ TypeSymbol) int {
|
|
||||||
existing_idx := t.type_idxs[typ.name]
|
|
||||||
if existing_idx > 0 {
|
|
||||||
if existing_idx >= string_type_idx {
|
|
||||||
if existing_idx == string_type_idx {
|
|
||||||
existing_type := t.types[existing_idx]
|
|
||||||
t.types[existing_idx] = {
|
|
||||||
typ |
|
|
||||||
kind: existing_type.kind
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
t.types[existing_idx] = typ
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return existing_idx
|
|
||||||
}
|
|
||||||
return t.register_type_symbol(typ)
|
|
||||||
}
|
|
||||||
|
|
||||||
[inline]
|
|
||||||
pub fn (mut t Table) register_type_symbol(typ TypeSymbol) int {
|
|
||||||
// println('register_type_symbol( $typ.name )')
|
|
||||||
existing_idx := t.type_idxs[typ.name]
|
|
||||||
if existing_idx > 0 {
|
|
||||||
ex_type := t.types[existing_idx]
|
|
||||||
match ex_type.kind {
|
|
||||||
.placeholder {
|
|
||||||
// override placeholder
|
|
||||||
// println('overriding type placeholder `$typ.name`')
|
|
||||||
t.types[existing_idx] = {
|
|
||||||
typ |
|
|
||||||
methods: ex_type.methods
|
|
||||||
}
|
|
||||||
return existing_idx
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if ex_type.kind == typ.kind {
|
|
||||||
return existing_idx
|
|
||||||
}
|
|
||||||
// panic('cannot register type `$typ.name`, another type with this name exists')
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
typ_idx := t.types.len
|
|
||||||
t.types << typ
|
|
||||||
t.type_idxs[typ.name] = typ_idx
|
|
||||||
return typ_idx
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn (t &Table) known_type(name string) bool {
|
|
||||||
t.find_type(name) or {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
[inline]
|
|
||||||
pub fn (t &Table) array_name(elem_type Type, nr_dims int) string {
|
|
||||||
elem_type_sym := t.get_type_symbol(elem_type)
|
|
||||||
return 'array_$elem_type_sym.name' + if elem_type.is_ptr() {
|
|
||||||
'_ptr'.repeat(elem_type.nr_muls())
|
|
||||||
} else {
|
|
||||||
''
|
|
||||||
} +
|
|
||||||
if nr_dims > 1 {
|
|
||||||
'_${nr_dims}d'
|
'_${nr_dims}d'
|
||||||
} else {
|
} else {
|
||||||
''
|
''
|
||||||
|
@ -1298,8 +340,7 @@ pub fn (t &Table) array_fixed_name(elem_type Type, size, nr_dims int) string {
|
||||||
'_ptr'
|
'_ptr'
|
||||||
} else {
|
} else {
|
||||||
''
|
''
|
||||||
} +
|
} + if nr_dims > 1 {
|
||||||
if nr_dims > 1 {
|
|
||||||
'_${nr_dims}d'
|
'_${nr_dims}d'
|
||||||
} else {
|
} else {
|
||||||
''
|
''
|
||||||
|
@ -1355,7 +396,7 @@ pub fn (t &Table) map_source_name(key_type, value_type Type) string {
|
||||||
key_type_sym := t.get_type_symbol(key_type)
|
key_type_sym := t.get_type_symbol(key_type)
|
||||||
value_type_sym := t.get_type_symbol(value_type)
|
value_type_sym := t.get_type_symbol(value_type)
|
||||||
ptr := if value_type.is_ptr() { '&' } else { '' }
|
ptr := if value_type.is_ptr() { '&' } else { '' }
|
||||||
return 'map[$key_type_sym.source_name]$ptr$value_type_sym.source_name'
|
return 'map[${key_type_sym.source_name}]$ptr$value_type_sym.source_name'
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut t Table) find_or_register_chan(elem_type Type, is_mut bool) int {
|
pub fn (mut t Table) find_or_register_chan(elem_type Type, is_mut bool) int {
|
||||||
|
|
Loading…
Reference in New Issue