parser: use map[string]Type instead of []Type
parent
4edccce9a3
commit
d078aa360b
|
@ -184,6 +184,7 @@ fn (c mut V) prof_counters() string {
|
|||
//res << 'double ${c.table.cgen_name(f)}_time;'
|
||||
//}
|
||||
// Methods
|
||||
/*
|
||||
for typ in c.table.types {
|
||||
// println('')
|
||||
for f in typ.methods {
|
||||
|
@ -192,6 +193,7 @@ fn (c mut V) prof_counters() string {
|
|||
// println(f.cgen_name())
|
||||
}
|
||||
}
|
||||
*/
|
||||
return res.join(';\n')
|
||||
}
|
||||
|
||||
|
@ -203,6 +205,7 @@ fn (p mut Parser) print_prof_counters() string {
|
|||
//res << 'if ($counter) printf("%%f : $f.name \\n", $counter);'
|
||||
//}
|
||||
// Methods
|
||||
/*
|
||||
for typ in p.table.types {
|
||||
// println('')
|
||||
for f in typ.methods {
|
||||
|
@ -214,6 +217,7 @@ fn (p mut Parser) print_prof_counters() string {
|
|||
// println(f.cgen_name())
|
||||
}
|
||||
}
|
||||
*/
|
||||
return res.join(';\n')
|
||||
}
|
||||
|
||||
|
@ -293,14 +297,24 @@ fn platform_postfix_to_ifdefguard(name string) string {
|
|||
fn (v mut V) c_type_definitions() string {
|
||||
mut types := []Type // structs that need to be sorted
|
||||
mut top_types := []Type // builtin types and types that only have primitive fields
|
||||
for t in v.table.types {
|
||||
mut builtin_types := []Type
|
||||
// builtin types need to be on top
|
||||
builtins := ['string', 'array', 'map', 'Option']
|
||||
for builtin in builtins {
|
||||
typ := v.table.typesmap[builtin]
|
||||
builtin_types << typ
|
||||
v.table.typesmap.delete(builtin)
|
||||
}
|
||||
// split all types
|
||||
for _, t in v.table.typesmap {
|
||||
if !t.name[0].is_capital() {
|
||||
top_types << t
|
||||
continue
|
||||
}
|
||||
mut only_builtin_fields := true
|
||||
for field in t.fields {
|
||||
if field.typ[0].is_capital() {
|
||||
// user types start with a capital or contain __ (defined in another module)
|
||||
if field.typ[0].is_capital() || field.typ.contains('__') {
|
||||
only_builtin_fields = false
|
||||
break
|
||||
}
|
||||
|
@ -311,9 +325,11 @@ fn (v mut V) c_type_definitions() string {
|
|||
}
|
||||
types << t
|
||||
}
|
||||
sort_structs(mut top_types)
|
||||
sort_structs(mut types)
|
||||
// Generate C code
|
||||
return types_to_c(top_types, v.table) + '\n/*----*/\n' +
|
||||
return types_to_c(builtin_types,v.table) + '\n//----\n' +
|
||||
types_to_c(top_types, v.table) + '\n/*----*/\n' +
|
||||
types_to_c(types, v.table)
|
||||
}
|
||||
|
||||
|
|
|
@ -899,6 +899,9 @@ fn (p mut Parser) get_type() string {
|
|||
typ += '__$p.lit'
|
||||
}
|
||||
mut t := p.table.find_type(typ)
|
||||
if typ == 'V' {
|
||||
//println('QQ V res=$t.name')
|
||||
}
|
||||
// "typ" not found? try "mod__typ"
|
||||
if t.name == '' && !p.builtin_mod {
|
||||
// && !p.first_pass() {
|
||||
|
|
127
compiler/table.v
127
compiler/table.v
|
@ -9,7 +9,7 @@ import strings
|
|||
|
||||
struct Table {
|
||||
mut:
|
||||
types []Type
|
||||
typesmap map[string]Type
|
||||
consts []Var
|
||||
fns map[string]Fn
|
||||
generic_fns []GenTable //map[string]GenTable // generic_fns['listen_and_serve'] == ['Blog', 'Forum']
|
||||
|
@ -22,9 +22,6 @@ mut:
|
|||
obfuscate bool
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
struct GenTable {
|
||||
fn_name string
|
||||
mut:
|
||||
|
@ -216,12 +213,7 @@ fn is_primitive_type(typ string) bool {
|
|||
|
||||
fn new_table(obfuscate bool) *Table {
|
||||
mut t := &Table {
|
||||
obf_ids: map[string]int
|
||||
fns: map[string]Fn
|
||||
//generic_fns: map[string]GenTable{}
|
||||
generic_fns: []GenTable
|
||||
obfuscate: obfuscate
|
||||
file_imports: []FileImportTable
|
||||
}
|
||||
t.register_type('int')
|
||||
t.register_type('size_t')
|
||||
|
@ -327,12 +319,8 @@ fn (table &Table) known_type(typ_ string) bool {
|
|||
if typ.ends_with('*') && !typ.contains(' ') {
|
||||
typ = typ.left(typ.len - 1)
|
||||
}
|
||||
for t in table.types {
|
||||
if t.name == typ && !t.is_placeholder {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
t := table.typesmap[typ]
|
||||
return t.name.len > 0 && !t.is_placeholder
|
||||
}
|
||||
|
||||
fn (t &Table) find_fn(name string) Fn {
|
||||
|
@ -358,17 +346,10 @@ fn (t mut Table) register_type(typ string) {
|
|||
if typ.len == 0 {
|
||||
return
|
||||
}
|
||||
for typ2 in t.types {
|
||||
if typ2.name == typ {
|
||||
if typ in t.typesmap {
|
||||
return
|
||||
}
|
||||
}
|
||||
// if t.types.filter( _.name == typ.name).len > 0 {
|
||||
// return
|
||||
// }
|
||||
t.types << Type {
|
||||
name: typ
|
||||
}
|
||||
t.typesmap[typ] = Type{name:typ}
|
||||
}
|
||||
|
||||
fn (p mut Parser) register_type_with_parent(strtyp, parent string) {
|
||||
|
@ -384,19 +365,7 @@ fn (t mut Table) register_type_with_parent(typ, parent string) {
|
|||
if typ.len == 0 {
|
||||
return
|
||||
}
|
||||
// if t.types.filter(_.name == typ) > 0
|
||||
for typ2 in t.types {
|
||||
if typ2.name == typ {
|
||||
return
|
||||
}
|
||||
}
|
||||
/*
|
||||
mut mod := ''
|
||||
if parent == 'array' {
|
||||
mod = 'builtin'
|
||||
}
|
||||
*/
|
||||
t.types << Type {
|
||||
t.typesmap[typ] = Type {
|
||||
name: typ
|
||||
parent: parent
|
||||
//mod: mod
|
||||
|
@ -407,24 +376,14 @@ fn (t mut Table) register_type2(typ Type) {
|
|||
if typ.name.len == 0 {
|
||||
return
|
||||
}
|
||||
for typ2 in t.types {
|
||||
if typ2.name == typ.name {
|
||||
return
|
||||
}
|
||||
}
|
||||
t.types << typ
|
||||
t.typesmap[typ.name] = typ
|
||||
}
|
||||
|
||||
fn (t mut Table) rewrite_type(typ Type) {
|
||||
if typ.name.len == 0 {
|
||||
return
|
||||
}
|
||||
for i, typ2 in t.types {
|
||||
if typ2.name == typ.name {
|
||||
t.types[i] = typ
|
||||
return
|
||||
}
|
||||
}
|
||||
t.typesmap[typ.name] = typ
|
||||
}
|
||||
|
||||
fn (table mut Table) add_field(type_name, field_name, field_type string, is_mut bool, attr string, access_mod AccessMod) {
|
||||
|
@ -432,9 +391,8 @@ fn (table mut Table) add_field(type_name, field_name, field_type string, is_mut
|
|||
print_backtrace()
|
||||
cerror('add_field: empty type')
|
||||
}
|
||||
for i, typ in table.types {
|
||||
if typ.name == type_name {
|
||||
table.types[i].fields << Var {
|
||||
mut t := table.typesmap[type_name]
|
||||
t.fields << Var {
|
||||
name: field_name
|
||||
typ: field_type
|
||||
is_mut: is_mut
|
||||
|
@ -442,30 +400,9 @@ fn (table mut Table) add_field(type_name, field_name, field_type string, is_mut
|
|||
parent_fn: type_name // Name of the parent type
|
||||
access_mod: access_mod
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
print_backtrace()
|
||||
cerror('failed to add_field `$field_name` to type `$type_name`')
|
||||
table.typesmap[type_name] = t
|
||||
}
|
||||
|
||||
/*
|
||||
fn adf(name, typ string, is_mut bool, attr string, access_mod AccessMod) {
|
||||
// if t.name == 'Parser' {
|
||||
// println('adding field $name')
|
||||
// }
|
||||
v := Var {
|
||||
name: name
|
||||
typ: typ
|
||||
is_mut: is_mut
|
||||
attr: attr
|
||||
parent_fn: t.name // Name of the parent type
|
||||
access_mod: access_mod
|
||||
}
|
||||
t.fields << v
|
||||
}
|
||||
*/
|
||||
|
||||
fn (t &Type) has_field(name string) bool {
|
||||
field := t.find_field(name)
|
||||
return (field.name != '')
|
||||
|
@ -503,14 +440,9 @@ fn (table mut Table) add_method(type_name string, f Fn) {
|
|||
print_backtrace()
|
||||
cerror('add_method: empty type')
|
||||
}
|
||||
for i, typ in table.types {
|
||||
if typ.name == type_name {
|
||||
table.types[i].methods << f
|
||||
return
|
||||
}
|
||||
}
|
||||
print_backtrace()
|
||||
cerror('failed to add_method `$f.name` to type `$type_name`')
|
||||
mut t := table.typesmap[type_name]
|
||||
t.methods << f
|
||||
table.typesmap[type_name] = t
|
||||
}
|
||||
|
||||
fn (t &Type) has_method(name string) bool {
|
||||
|
@ -568,26 +500,13 @@ fn (p &Parser) find_type(name string) Type {
|
|||
|
||||
fn (t &Table) find_type(name_ string) Type {
|
||||
mut name := name_
|
||||
debug := name.starts_with('V') && name.len < 3
|
||||
if debug {
|
||||
//println('find_type("$name)"')
|
||||
}
|
||||
if name.ends_with('*') && !name.contains(' ') {
|
||||
name = name.left(name.len - 1)
|
||||
}
|
||||
// TODO PERF use map
|
||||
for i, typ in t.types {
|
||||
if debug {
|
||||
//println('^^ "$typ.name"')
|
||||
}
|
||||
if typ.name == name {
|
||||
return t.types[i]
|
||||
}
|
||||
}
|
||||
if debug {
|
||||
//println('NOT FOUND')
|
||||
}
|
||||
if !(name in t.typesmap) {
|
||||
return Type{}
|
||||
}
|
||||
return t.typesmap[name]
|
||||
}
|
||||
|
||||
fn (p mut Parser) _check_types(got_, expected_ string, throw bool) bool {
|
||||
|
@ -748,14 +667,12 @@ fn type_default(typ string) string {
|
|||
return '{0}'
|
||||
}
|
||||
|
||||
// TODO PERF O(n)
|
||||
fn (t &Table) is_interface(name string) bool {
|
||||
for typ in t.types {
|
||||
if typ.cat == .interface_ && typ.name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
fn (table &Table) is_interface(name string) bool {
|
||||
if !(name in table.typesmap) {
|
||||
return false
|
||||
}
|
||||
t := table.typesmap[name]
|
||||
return t.cat == .interface_
|
||||
}
|
||||
|
||||
// Do we have fn main()?
|
||||
|
|
Loading…
Reference in New Issue