From 568aa742b204294244d5a6c9be1f5f1ce6c1a7c0 Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Sat, 17 Jul 2021 14:44:38 +0300 Subject: [PATCH] v.parser: improve conditions for debugging ast.CastExpr parsing --- vlib/v/ast/table.v | 1 + vlib/v/ast/types.v | 37 ++++++++++++++++++++++++++++--------- vlib/v/checker/checker.v | 5 ++++- vlib/v/gen/c/cgen.v | 2 +- vlib/v/gen/c/dumpexpr.v | 1 + vlib/v/markused/walker.v | 6 +++++- vlib/v/parser/expr.v | 4 ++++ vlib/v/parser/parser.v | 2 +- 8 files changed, 45 insertions(+), 13 deletions(-) diff --git a/vlib/v/ast/table.v b/vlib/v/ast/table.v index e4645d8dcb..674aa7a581 100644 --- a/vlib/v/ast/table.v +++ b/vlib/v/ast/table.v @@ -602,6 +602,7 @@ pub fn (mut t Table) register_type_symbol(typ TypeSymbol) int { } typ_idx = t.type_symbols.len t.type_symbols << typ + t.type_symbols[typ_idx].idx = typ_idx t.type_idxs[typ.name] = typ_idx return typ_idx } diff --git a/vlib/v/ast/types.v b/vlib/v/ast/types.v index 97ef0a4034..f1c2e3b007 100644 --- a/vlib/v/ast/types.v +++ b/vlib/v/ast/types.v @@ -77,6 +77,7 @@ pub mut: mod string is_public bool language Language + idx int } // max of 8 @@ -209,24 +210,42 @@ pub fn (t Type) has_flag(flag TypeFlag) bool { return int(t) & (1 << (int(flag) + 24)) > 0 } +// debug returns a verbose representation of the information in ts, useful for tracing/debugging pub fn (ts TypeSymbol) debug() []string { mut res := []string{} - res << 'parent_idx: $ts.parent_idx' - res << 'mod: $ts.mod' - res << 'name: $ts.name' - res << 'cname: $ts.cname' + ts.dbg_common(mut res) res << 'info: $ts.info' - res << 'kind: $ts.kind' - res << 'is_public: $ts.is_public' - res << 'language: $ts.language' res << 'methods ($ts.methods.len): ' + ts.methods.map(it.str()).join(', ') return res } +// same as .debug(), but without the verbose .info and .methods fields +pub fn (ts TypeSymbol) dbg() []string { + mut res := []string{} + ts.dbg_common(mut res) + return res +} + +fn (ts TypeSymbol) dbg_common(mut res []string) { + res << 'idx: 0x$ts.idx.hex()' + res << 'parent_idx: 0x$ts.parent_idx.hex()' + res << 'mod: $ts.mod' + res << 'name: $ts.name' + res << 'cname: $ts.cname' + res << 'kind: $ts.kind' + res << 'is_public: $ts.is_public' + res << 'language: $ts.language' +} + +pub fn (t Type) str() string { + return 'ast.Type(0x$t.hex() = ${u32(t)})' +} + +// debug returns a verbose representation of the information in the type `t`, useful for tracing/debugging pub fn (t Type) debug() []string { mut res := []string{} - res << 'idx: ${t.idx():5}' - res << 'type: ${t:10}' + res << 'idx: 0x${t.idx().hex():-8}' + res << 'type: 0x${t.hex():-8}' res << 'nr_muls: $t.nr_muls()' if t.has_flag(.optional) { res << 'optional' diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 4e51a1a7e0..5abb4917f3 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -5473,6 +5473,10 @@ pub fn (mut c Checker) cast_expr(mut node ast.CastExpr) ast.Type { } } else { type_name := c.table.type_to_str(node.expr_type) + // dump(node.typ) + // dump(node.expr_type) + // dump(type_name) + // dump(to_type_sym.debug()) c.error('cannot cast `$type_name` to struct', node.pos) } } else if to_type_sym.kind == .interface_ { @@ -5507,7 +5511,6 @@ pub fn (mut c Checker) cast_expr(mut node ast.CastExpr) ast.Type { if node.has_arg { c.expr(node.arg) } - node.typname = c.table.get_type_symbol(node.typ).name return node.typ } diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 085d80ce73..6d6208198e 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -6123,7 +6123,7 @@ fn (mut g Gen) as_cast(node ast.AsCast) { // fill as cast name table for variant in expr_type_sym.info.variants { - idx := variant.str() + idx := u32(variant).str() if idx in g.as_cast_type_names { continue } diff --git a/vlib/v/gen/c/dumpexpr.v b/vlib/v/gen/c/dumpexpr.v index 4f9eaabd23..9813739a8b 100644 --- a/vlib/v/gen/c/dumpexpr.v +++ b/vlib/v/gen/c/dumpexpr.v @@ -39,6 +39,7 @@ fn (mut g Gen) dump_expr_definitions() { g.definitions.writeln('\teprint(int_str(line));') g.definitions.writeln('\teprint(${ctoslit('] ')});') + // g.definitions.writeln('\t/* dump_type: $dump_type | to_string_fn_name: $to_string_fn_name | is_ptr: $is_ptr | ptr_astarisk: $ptr_astarisk | dump_fn_name: $dump_fn_name | cname: $cname */') g.definitions.writeln('\teprint(sexpr);') g.definitions.writeln('\teprint(${ctoslit(': ')});') diff --git a/vlib/v/markused/walker.v b/vlib/v/markused/walker.v index 65ae2ca118..e2c244f893 100644 --- a/vlib/v/markused/walker.v +++ b/vlib/v/markused/walker.v @@ -398,7 +398,11 @@ pub fn (mut w Walker) call_expr(mut node ast.CallExpr) { w.expr(node.left) w.or_block(node.or_block) // - fn_name := if node.is_method { node.receiver_type.str() + '.' + node.name } else { node.name } + fn_name := if node.is_method { + int(node.receiver_type).str() + '.' + node.name + } else { + node.name + } if w.used_fns[fn_name] { return } diff --git a/vlib/v/parser/expr.v b/vlib/v/parser/expr.v index 9dc9a584c9..035ca470c6 100644 --- a/vlib/v/parser/expr.v +++ b/vlib/v/parser/expr.v @@ -171,11 +171,13 @@ pub fn (mut p Parser) check_expr(precedence int) ?ast.Expr { } else if p.is_amp && p.peek_tok.kind == .rsbr && p.peek_token(3).kind != .lcbr { pos := p.tok.position() typ := p.parse_type() + typname := p.table.get_type_symbol(typ).name p.check(.lpar) expr := p.expr(0) p.check(.rpar) node = ast.CastExpr{ typ: typ + typname: typname expr: expr pos: pos } @@ -579,9 +581,11 @@ fn (mut p Parser) prefix_expr() ast.Expr { if mut right is ast.CastExpr && op == .amp { // Handle &Type(x), as well as &&Type(x) etc: mut new_cast_type := right.typ.to_ptr() + nct_sym := p.table.get_type_symbol(new_cast_type) return ast.CastExpr{ ...right typ: new_cast_type + typname: nct_sym.name pos: pos.extend(right.pos) } } diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index 7073a035ab..5d0f1e3c59 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -1400,7 +1400,7 @@ fn (mut p Parser) asm_ios(output bool) []ast.AsmIO { if mut expr is ast.ParExpr { expr = expr.expr } else { - p.error('asm in/output must be incolsed in brackets') + p.error('asm in/output must be enclosed in brackets') } mut alias := '' if p.tok.kind == .key_as {