From f7c1b78ec2f8ddda9bb6528130dbc2f58b766245 Mon Sep 17 00:00:00 2001 From: joe-conigliaro Date: Sat, 21 Dec 2019 13:33:59 +1100 Subject: [PATCH] clean up generic structs --- vlib/compiler/fn.v | 28 +--------------------------- vlib/compiler/parser.v | 32 +++++++++++++++++++++++--------- vlib/compiler/struct.v | 27 +++++++++++++++------------ 3 files changed, 39 insertions(+), 48 deletions(-) diff --git a/vlib/compiler/fn.v b/vlib/compiler/fn.v index a17c59fc23..c0761a4a1f 100644 --- a/vlib/compiler/fn.v +++ b/vlib/compiler/fn.v @@ -474,8 +474,7 @@ fn (p mut Parser) fn_decl() { } } p.set_current_fn( EmptyFn ) - //p.skip_fn_body() - p.skip_block(true) + p.skip_fn_body() return } else { @@ -603,22 +602,6 @@ fn (p mut Parser) fn_decl() { p.returns = false } -[inline] -fn (p mut Parser) skip_block(inside_lcbr bool) { - mut cbr_depth := if inside_lcbr { 1 } else { 0 } - for { - if p.tok == .lcbr { - cbr_depth++ - } - if p.tok == .rcbr { - cbr_depth-- - if cbr_depth == 0 { break } - } - p.next() - } - p.check(.rcbr) -} - [inline] // Skips the entire function's body in the first pass. fn (p mut Parser) skip_fn_body() { @@ -788,20 +771,11 @@ fn (p mut Parser) fn_call(f mut Fn, method_ph int, receiver_var, receiver_type s mut generic_param_types := []string if p.tok == .lt { p.check(.lt) - mut i := 0 for { param_type := p.check_name() generic_param_types << param_type if p.tok != .comma { break } p.check(.comma) - if p.tokens[i].tok == .gt { - p.error('explicit type arguments are not allowed; remove `<...>`') - } - else if p.tokens[i].tok == .lpar { - // probably a typo, do not concern the user with the above error message - break - } - i++ } p.check(.gt) // mut i := p.token_idx diff --git a/vlib/compiler/parser.v b/vlib/compiler/parser.v index 75d930193b..b30063fc5c 100644 --- a/vlib/compiler/parser.v +++ b/vlib/compiler/parser.v @@ -1090,21 +1090,18 @@ fn (p mut Parser) get_type() string { p.error('type `$t.name` is private') } } - // generic struct + // generic struct init if p.peek() == .lt { p.next() p.check(.lt) typ = '${typ}_T' - mut type_params := []string - for p.tok != .gt { + for { type_param := p.check_name() - type_params << type_param - if p.generic_dispatch.inst.size > 0 { - if type_param in p.generic_dispatch.inst { - typ = '${typ}_' + p.generic_dispatch.inst[type_param] - } + if type_param in p.generic_dispatch.inst { + typ = '${typ}_' + p.generic_dispatch.inst[type_param] } - if p.tok == .comma { p.check(.comma) } + if p.tok != .comma { break } + p.check(.comma) } p.check(.gt) return typ @@ -3008,6 +3005,23 @@ fn (p &Parser) is_expr_fn_call(start_tok_idx int) (bool,string) { return is_fn_call,expr } +[inline] +// skip any block of code in curley braces `{}` +fn (p mut Parser) skip_block(inside_first_lcbr bool) { + mut cbr_depth := if inside_first_lcbr { 1 } else { 0 } + for { + if p.tok == .lcbr { + cbr_depth++ + } + if p.tok == .rcbr { + cbr_depth-- + if cbr_depth == 0 { break } + } + p.next() + } + p.check(.rcbr) +} + fn todo_remove() { x64.new_gen('f') } diff --git a/vlib/compiler/struct.v b/vlib/compiler/struct.v index 084f71d369..e80afde804 100644 --- a/vlib/compiler/struct.v +++ b/vlib/compiler/struct.v @@ -105,10 +105,10 @@ fn (p mut Parser) struct_decl(generic_param_types []string) { kind := if is_union { 'union' } else { 'struct' } p.gen_typedef('typedef $kind $name $name;') } + // TODO: handle error parser_idx := p.v.get_file_parser_index(p.file_path) or { 0 } //if !p.scanner.is_vh { // parser_idx = p.v.get_file_parser_index(p.file_path) or { panic('cant find parser idx for $p.file_path') } - // println('HERE: $parser_idx') //} // Register the type mut is_ph := false @@ -145,17 +145,20 @@ fn (p mut Parser) struct_decl(generic_param_types []string) { p.table.register_type(typ) return } - // generic template - if is_generic && !is_generic_instance { - p.table.register_type(typ) - p.table.generic_struct_params[typ.name] = generic_types.keys() - //} - // TODO: re are skipping genrcic struct in gen (cgen.v) we can go as normal and remove this - p.skip_block(false) - return - } - if is_generic_instance { - typ.rename_generic_struct(generic_types) + // generic struct + if is_generic { + // template + if !is_generic_instance { + p.table.register_type(typ) + p.table.generic_struct_params[typ.name] = generic_types.keys() + // NOTE: remove to store fields in generic struct template + p.skip_block(false) + return + } + // instance + else { + typ.rename_generic_struct(generic_types) + } } p.fspace() p.check(.lcbr)