From 849cde245c93855248101c1b636e847a85e79224 Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Sat, 6 Mar 2021 19:09:28 +0200 Subject: [PATCH] v: support dump(expr) (#9160) --- cmd/tools/vcheck-md.v | 2 +- examples/dump_factorial.v | 10 ++ vlib/v/ast/ast.v | 19 +++- vlib/v/checker/checker.v | 13 ++- vlib/v/checker/tests/dump_of_void_expr.out | 5 + vlib/v/checker/tests/dump_of_void_expr.vv | 3 + vlib/v/fmt/fmt.v | 5 + vlib/v/gen/c/cgen.v | 9 +- vlib/v/gen/c/dumpexpr.v | 39 ++++++++ vlib/v/gen/js/js.v | 103 +++++++++++++-------- vlib/v/markused/walker.v | 3 + vlib/v/parser/parser.v | 5 +- vlib/v/parser/pratt.v | 11 +++ vlib/v/table/table.v | 5 +- vlib/v/tests/inout/dump_expression.out | 7 ++ vlib/v/tests/inout/dump_expression.vv | 29 ++++++ vlib/v/token/token.v | 2 + vlib/v/vmod/vmod.v | 2 +- 18 files changed, 219 insertions(+), 53 deletions(-) create mode 100644 examples/dump_factorial.v create mode 100644 vlib/v/checker/tests/dump_of_void_expr.out create mode 100644 vlib/v/checker/tests/dump_of_void_expr.vv create mode 100644 vlib/v/gen/c/dumpexpr.v create mode 100644 vlib/v/tests/inout/dump_expression.out create mode 100644 vlib/v/tests/inout/dump_expression.vv diff --git a/cmd/tools/vcheck-md.v b/cmd/tools/vcheck-md.v index 5fcba74c2c..59698486a0 100644 --- a/cmd/tools/vcheck-md.v +++ b/cmd/tools/vcheck-md.v @@ -204,7 +204,7 @@ fn (mut f MDFile) parse_line(lnumber int, line string) { } } -fn (mut f MDFile) dump() { +fn (mut f MDFile) debug() { for e in f.examples { eprintln('f.path: $f.path | example: $e') } diff --git a/examples/dump_factorial.v b/examples/dump_factorial.v new file mode 100644 index 0000000000..9b5fc0feb9 --- /dev/null +++ b/examples/dump_factorial.v @@ -0,0 +1,10 @@ +fn factorial(n u32) u32 { + if dump(n <= 1) { + return dump(1) + } + return dump(n * factorial(n - 1)) +} + +fn main() { + println(factorial(5)) +} diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index d3f5031ff7..418cfd55a8 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -11,10 +11,10 @@ pub type TypeDecl = AliasTypeDecl | FnTypeDecl | SumTypeDecl pub type Expr = AnonFn | ArrayDecompose | ArrayInit | AsCast | Assoc | AtExpr | BoolLiteral | CTempVar | CallExpr | CastExpr | ChanInit | CharLiteral | Comment | ComptimeCall | - ComptimeSelector | ConcatExpr | EnumVal | FloatLiteral | GoExpr | Ident | IfExpr | - IfGuardExpr | IndexExpr | InfixExpr | IntegerLiteral | Likely | LockExpr | MapInit | - MatchExpr | None | OffsetOf | OrExpr | ParExpr | PostfixExpr | PrefixExpr | RangeExpr | - SelectExpr | SelectorExpr | SizeOf | SqlExpr | StringInterLiteral | StringLiteral | + ComptimeSelector | ConcatExpr | DumpExpr | EnumVal | FloatLiteral | GoExpr | Ident | + IfExpr | IfGuardExpr | IndexExpr | InfixExpr | IntegerLiteral | Likely | LockExpr | + MapInit | MatchExpr | None | OffsetOf | OrExpr | ParExpr | PostfixExpr | PrefixExpr | + RangeExpr | SelectExpr | SelectorExpr | SizeOf | SqlExpr | StringInterLiteral | StringLiteral | StructInit | Type | TypeOf | UnsafeExpr pub type Stmt = AssertStmt | AssignStmt | Block | BranchStmt | CompFor | ConstDecl | DeferStmt | @@ -1114,6 +1114,15 @@ pub mut: expr_type table.Type } +pub struct DumpExpr { +pub: + expr Expr + pos token.Position +pub mut: + expr_type table.Type + cname string // filled in the checker +} + pub struct Comment { pub: text string @@ -1240,7 +1249,7 @@ pub fn (expr Expr) position() token.Position { return expr.decl.pos } ArrayDecompose, ArrayInit, AsCast, Assoc, AtExpr, BoolLiteral, CallExpr, CastExpr, ChanInit, - CharLiteral, ConcatExpr, Comment, ComptimeCall, ComptimeSelector, EnumVal, FloatLiteral, + CharLiteral, ConcatExpr, Comment, ComptimeCall, ComptimeSelector, EnumVal, DumpExpr, FloatLiteral, GoExpr, Ident, IfExpr, IndexExpr, IntegerLiteral, Likely, LockExpr, MapInit, MatchExpr, None, OffsetOf, OrExpr, ParExpr, PostfixExpr, PrefixExpr, RangeExpr, SelectExpr, SelectorExpr, SizeOf, SqlExpr, StringInterLiteral, StringLiteral, StructInit, Type, TypeOf, UnsafeExpr diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 3d574124f8..483439da05 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -1866,7 +1866,7 @@ pub fn (mut c Checker) call_fn(mut call_expr ast.CallExpr) table.Type { && f.ctdefine !in c.pref.compile_defines { call_expr.should_be_skipped = true } - // dont check number of args for JS functions since arguments are not required + // dont check number of args for JS functions since arguments are not required if call_expr.language != .js { min_required_args := if f.is_variadic { f.params.len - 1 } else { f.params.len } if call_expr.args.len < min_required_args { @@ -3716,6 +3716,17 @@ pub fn (mut c Checker) expr(node ast.Expr) table.Type { ast.ConcatExpr { return c.concat_expr(mut node) } + ast.DumpExpr { + node.expr_type = c.expr(node.expr) + if node.expr_type.idx() == table.void_type_idx { + c.error('dump expression can not be void', node.expr.position()) + return table.void_type + } + tsym := c.table.get_type_symbol(node.expr_type) + c.table.dumps[int(node.expr_type)] = tsym.cname + node.cname = tsym.cname + return node.expr_type + } ast.EnumVal { return c.enum_val(mut node) } diff --git a/vlib/v/checker/tests/dump_of_void_expr.out b/vlib/v/checker/tests/dump_of_void_expr.out new file mode 100644 index 0000000000..ac6f1b51ca --- /dev/null +++ b/vlib/v/checker/tests/dump_of_void_expr.out @@ -0,0 +1,5 @@ +vlib/v/checker/tests/dump_of_void_expr.vv:3:6: error: dump expression can not be void + 1 | fn abc() {} + 2 | + 3 | dump(abc()) + | ~~~~~ diff --git a/vlib/v/checker/tests/dump_of_void_expr.vv b/vlib/v/checker/tests/dump_of_void_expr.vv new file mode 100644 index 0000000000..57e8597bcc --- /dev/null +++ b/vlib/v/checker/tests/dump_of_void_expr.vv @@ -0,0 +1,3 @@ +fn abc() {} + +dump(abc()) diff --git a/vlib/v/fmt/fmt.v b/vlib/v/fmt/fmt.v index 6ff978bb06..a2a7e9ba2c 100644 --- a/vlib/v/fmt/fmt.v +++ b/vlib/v/fmt/fmt.v @@ -900,6 +900,11 @@ pub fn (mut f Fmt) expr(node ast.Expr) { ast.CTempVar { eprintln('ast.CTempVar of $node.orig.str() should be generated/used only in cgen') } + ast.DumpExpr { + f.write('dump(') + f.expr(node.expr) + f.write(')') + } ast.AnonFn { f.fn_decl(node.decl) } diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 4f907e0186..63b1620da8 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -266,6 +266,8 @@ pub fn gen(files []ast.File, table &table.Table, pref &pref.Preferences) string g.definitions.writeln('int _v_type_idx_${typ.cname}() { return $idx; };') } } + // + g.dump_expr_definitions() // v files are finished, what remains is pure C code g.gen_vlines_reset() if g.pref.build_mode != .build_module { @@ -2698,6 +2700,9 @@ fn (mut g Gen) expr(node ast.Expr) { g.write("L'$node.val'") } } + ast.DumpExpr { + g.dump_expr(node) + } ast.AtExpr { g.comp_at(node) } @@ -2965,7 +2970,9 @@ fn (mut g Gen) selector_expr(node ast.SelectorExpr) { g.write('(*(') } if sym.kind == .array_fixed { - assert node.field_name == 'len' + if node.field_name != 'len' { + g.error('field_name should be `len`', node.pos) + } info := sym.info as table.ArrayFixed g.write('$info.size') return diff --git a/vlib/v/gen/c/dumpexpr.v b/vlib/v/gen/c/dumpexpr.v new file mode 100644 index 0000000000..560fc88fa0 --- /dev/null +++ b/vlib/v/gen/c/dumpexpr.v @@ -0,0 +1,39 @@ +module c + +import v.ast + +fn (mut g Gen) dump_expr(node ast.DumpExpr) { + sexpr := ctoslit(node.expr.str()) + fpath := cestring(g.file.path) + line := node.pos.line_nr + 1 + if 'nop_dump' in g.pref.compile_defines { + g.expr(node.expr) + return + } + g.write(' _v_dump_expr_${node.cname}(${ctoslit(fpath)}, $line, $sexpr, ') + g.expr(node.expr) + g.write(' )') +} + +fn (mut g Gen) dump_expr_definitions() { + if g.pref.build_mode == .build_module { + for _, cname in g.table.dumps { + g.definitions.writeln('$cname _v_dump_expr_${cname}(string fpath, int line, string sexpr, $cname x);') + } + } else { + for dump_type, cname in g.table.dumps { + to_string_fn_name := g.gen_str_for_type(dump_type) + g.definitions.writeln('$cname _v_dump_expr_${cname}(string fpath, int line, string sexpr, $cname x) {') + g.definitions.writeln('\teprint(${ctoslit('[')});') + g.definitions.writeln('\teprint(fpath);') + g.definitions.writeln('\teprint(${ctoslit(':')});') + g.definitions.writeln('\teprint(int_str(line));') + g.definitions.writeln('\teprint(${ctoslit('] ')});') + g.definitions.writeln('\teprint(sexpr);') + g.definitions.writeln('\teprint(${ctoslit(': ')});') + g.definitions.writeln('\teprintln(${to_string_fn_name}(x));') + g.definitions.writeln('\treturn x;') + g.definitions.writeln('}') + } + } +} diff --git a/vlib/v/gen/js/js.v b/vlib/v/gen/js/js.v index ad4b474076..9a09b05f00 100644 --- a/vlib/v/gen/js/js.v +++ b/vlib/v/gen/js/js.v @@ -10,19 +10,19 @@ import v.depgraph const ( // https://ecma-international.org/ecma-262/#sec-reserved-words - js_reserved = ['await', 'break', 'case', 'catch', 'class', 'const', 'continue', 'debugger', + js_reserved = ['await', 'break', 'case', 'catch', 'class', 'const', 'continue', 'debugger', 'default', 'delete', 'do', 'else', 'enum', 'export', 'extends', 'finally', 'for', 'function', 'if', 'implements', 'import', 'in', 'instanceof', 'interface', 'let', 'new', 'package', 'private', 'protected', 'public', 'return', 'static', 'super', 'switch', 'this', 'throw', 'try', 'typeof', 'var', 'void', 'while', 'with', 'yield', 'Number', 'String', 'Boolean', 'Array', 'Map'] // used to generate type structs - v_types = ['i8', 'i16', 'int', 'i64', 'byte', 'u16', 'u32', 'u64', 'f32', 'f64', 'int_literal', - 'float_literal', 'size_t', 'bool', 'string', 'map', 'array'] - shallow_equatables = [table.Kind.i8, .i16, .int, .i64, .byte, .u16, .u32, .u64, .f32, .f64, .int_literal, - .float_literal, .size_t, .bool, .string] - tabs = ['', '\t', '\t\t', '\t\t\t', '\t\t\t\t', '\t\t\t\t\t', '\t\t\t\t\t\t', '\t\t\t\t\t\t\t', - '\t\t\t\t\t\t\t\t', '\t\t\t\t\t\t\t\t\t', '\t\t\t\t\t\t\t\t\t', '\t\t\t\t\t\t\t\t\t'] + v_types = ['i8', 'i16', 'int', 'i64', 'byte', 'u16', 'u32', 'u64', 'f32', 'f64', + 'int_literal', 'float_literal', 'size_t', 'bool', 'string', 'map', 'array'] + shallow_equatables = [table.Kind.i8, .i16, .int, .i64, .byte, .u16, .u32, .u64, .f32, .f64, + .int_literal, .float_literal, .size_t, .bool, .string] + tabs = ['', '\t', '\t\t', '\t\t\t', '\t\t\t\t', '\t\t\t\t\t', '\t\t\t\t\t\t', + '\t\t\t\t\t\t\t', '\t\t\t\t\t\t\t\t', '\t\t\t\t\t\t\t\t\t', '\t\t\t\t\t\t\t\t\t', '\t\t\t\t\t\t\t\t\t'] ) struct Namespace { @@ -60,8 +60,8 @@ mut: method_fn_decls map[string][]ast.FnDecl builtin_fns []string // Functions defined in `builtin` empty_line bool - cast_stack []table.Type - call_stack []ast.CallExpr + cast_stack []table.Type + call_stack []ast.CallExpr } pub fn gen(files []ast.File, table &table.Table, pref &pref.Preferences) string { @@ -115,7 +115,7 @@ pub fn gen(files []ast.File, table &table.Table, pref &pref.Preferences) string mut out := g.hashes() + g.definitions.str() // equality check for js objects // TODO: Fix msvc bug that's preventing $embed_file('fast_deep_equal.js') - //unsafe { + // unsafe { // mut eq_fn := $embed_file('fast_deep_equal.js') // out += eq_fn.data().vstring() //} @@ -447,6 +447,9 @@ fn (mut g JsGen) expr(node ast.Expr) { ast.CTempVar { g.write('/* ast.CTempVar: node.name */') } + ast.DumpExpr { + g.write('/* ast.DumpExpr: $node.expr */') + } ast.AnonFn { g.gen_fn_decl(node.decl) } @@ -689,10 +692,12 @@ fn (mut g JsGen) gen_assign_stmt(stmt ast.AssignStmt) { } else { g.write(' $op ') // TODO: Multiple types?? - should_cast := g.table.type_kind(stmt.left_types.first()) in shallow_equatables + should_cast := g.table.type_kind(stmt.left_types.first()) in js.shallow_equatables if should_cast { g.cast_stack << stmt.left_types.first() - if g.file.mod.name == 'builtin' { g.write('new ') } + if g.file.mod.name == 'builtin' { + g.write('new ') + } g.write('${g.typ(stmt.left_types.first())}(') } g.expr(val) @@ -845,7 +850,9 @@ fn (mut g JsGen) gen_method_decl(it ast.FnDecl) { } g.fn_args(args, it.is_variadic) if it.is_method { - if args.len > 0 { g.write(', ') } + if args.len > 0 { + g.write(', ') + } g.write('${it.params[0].name} = this') } g.writeln(') {') @@ -926,13 +933,23 @@ fn (mut g JsGen) gen_for_in_stmt(it ast.ForInStmt) { if val !in ['', '_'] { g.write('\tconst $val = ') if it.kind == .string { - if g.file.mod.name == 'builtin' { g.write('new ') } + if g.file.mod.name == 'builtin' { + g.write('new ') + } g.write('byte(') } g.expr(it.cond) - g.write(if it.kind == .array { '.arr' } else if it.kind == .string { '.str' } else { '.val' }) + g.write(if it.kind == .array { + '.arr' + } else if it.kind == .string { + '.str' + } else { + '.val' + }) g.write('[$i]') - if it.kind == .string { g.write(')') } + if it.kind == .string { + g.write(')') + } g.writeln(';') } g.stmts(it.stmts) @@ -1369,11 +1386,13 @@ fn (mut g JsGen) gen_infix_expr(it ast.InfixExpr) { r_sym := g.table.get_type_symbol(it.right_type) is_not := it.op in [.not_in, .not_is, .ne] - if is_not { g.write('!(') } + if is_not { + g.write('!(') + } if it.op == .eq || it.op == .ne { // Shallow equatables - if l_sym.kind in shallow_equatables && r_sym.kind in shallow_equatables { + if l_sym.kind in js.shallow_equatables && r_sym.kind in js.shallow_equatables { g.expr(it.left) g.write('.eq(') g.expr(it.right) @@ -1404,7 +1423,9 @@ fn (mut g JsGen) gen_infix_expr(it ast.InfixExpr) { '.includes(' }) g.expr(it.left) - if l_sym.kind == .string { g.write('.str') } + if l_sym.kind == .string { + g.write('.str') + } g.write(')') } else if it.op in [.key_is, .not_is] { // foo is Foo g.expr(it.left) @@ -1423,7 +1444,7 @@ fn (mut g JsGen) gen_infix_expr(it ast.InfixExpr) { g.cast_stack << greater_typ } g.expr(it.left) - g.write(' ${it.op} ') + g.write(' $it.op ') g.expr(it.right) if is_arithmetic && needs_cast { @@ -1432,7 +1453,9 @@ fn (mut g JsGen) gen_infix_expr(it ast.InfixExpr) { } } - if is_not { g.write(')') } + if is_not { + g.write(')') + } } fn (mut g JsGen) greater_typ(left table.Type, right table.Type) table.Type { @@ -1560,7 +1583,7 @@ fn (mut g JsGen) gen_string_literal(it ast.StringLiteral) { if g.file.mod.name == 'builtin' { g.write('new ') } - g.write("string(") + g.write('string(') } g.write("'$text'") if should_cast { @@ -1651,15 +1674,15 @@ fn (mut g JsGen) gen_integer_literal_expr(it ast.IntegerLiteral) { // TODO: call.language always seems to be "v", parser bug? if g.call_stack.len > 0 { call := g.call_stack[g.call_stack.len - 1] - //if call.language == .js { - for t in call.args { - if t.expr is ast.IntegerLiteral { - if t.expr == it { - g.write(it.val) - return - } + // if call.language == .js { + for t in call.args { + if t.expr is ast.IntegerLiteral { + if t.expr == it { + g.write(it.val) + return } } + } //} } @@ -1680,24 +1703,24 @@ fn (mut g JsGen) gen_integer_literal_expr(it ast.IntegerLiteral) { fn (mut g JsGen) gen_float_literal_expr(it ast.FloatLiteral) { typ := table.Type(table.f32_type) - + // Don't wrap integers for use in JS.foo functions. // TODO: call.language always seems to be "v", parser bug? if g.call_stack.len > 0 { call := g.call_stack[g.call_stack.len - 1] - //if call.language == .js { - for i, t in call.args { - if t.expr is ast.FloatLiteral { - if t.expr == it { - if call.expected_arg_types[i] in table.integer_type_idxs { - g.write(int(it.val.f64()).str()) - } else { - g.write(it.val) - } - return + // if call.language == .js { + for i, t in call.args { + if t.expr is ast.FloatLiteral { + if t.expr == it { + if call.expected_arg_types[i] in table.integer_type_idxs { + g.write(int(it.val.f64()).str()) + } else { + g.write(it.val) } + return } } + } //} } diff --git a/vlib/v/markused/walker.v b/vlib/v/markused/walker.v index 6ae118593d..c55a7c6144 100644 --- a/vlib/v/markused/walker.v +++ b/vlib/v/markused/walker.v @@ -180,6 +180,9 @@ fn (mut w Walker) expr(node ast.Expr) { w.stmts(node.vweb_tmpl.stmts) } } + ast.DumpExpr { + w.expr(node.expr) + } ast.GoExpr { w.expr(node.go_stmt.call_expr) } diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index 01d33d9ec3..2ba1e34b5d 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -670,6 +670,7 @@ pub fn (mut p Parser) stmt(is_top_level bool) ast.Stmt { p.label_names << name p.next() if p.tok.kind == .key_for { + for_pos := p.tok.position() mut stmt := p.stmt(is_top_level) match mut stmt { ast.ForStmt { @@ -685,7 +686,7 @@ pub fn (mut p Parser) stmt(is_top_level bool) ast.Stmt { return stmt } else { - assert false + p.error_with_pos('unknown kind of For statement', for_pos) } } } @@ -1031,7 +1032,7 @@ fn (mut p Parser) parse_multi_expr(is_top_level bool) ast.Stmt { if node !is ast.CallExpr && (is_top_level || p.tok.kind != .rcbr) && node !is ast.PostfixExpr && !(node is ast.InfixExpr && (node as ast.InfixExpr).op in [.left_shift, .arrow]) && node !is ast.ComptimeCall - && node !is ast.SelectorExpr { + && node !is ast.SelectorExpr && node !is ast.DumpExpr { p.error_with_pos('expression evaluated but not used', node.position()) return ast.Stmt{} } diff --git a/vlib/v/parser/pratt.v b/vlib/v/parser/pratt.v index fcd8b03f60..f1ccf4dba1 100644 --- a/vlib/v/parser/pratt.v +++ b/vlib/v/parser/pratt.v @@ -214,6 +214,17 @@ pub fn (mut p Parser) expr(precedence int) ast.Expr { pos: spos.extend(p.tok.position()) } } + .key_dump { + spos := p.tok.position() + p.next() + p.check(.lpar) + expr := p.expr(0) + p.check(.rpar) + node = ast.DumpExpr{ + expr: expr + pos: spos.extend(p.tok.position()) + } + } .key_offsetof { pos := p.tok.position() p.next() // __offsetof diff --git a/vlib/v/table/table.v b/vlib/v/table/table.v index 029a41b429..0f5540854e 100644 --- a/vlib/v/table/table.v +++ b/vlib/v/table/table.v @@ -12,8 +12,9 @@ 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 + dumps map[int]string // needed for efficiently generating all _v_dump_expr_TNAME() functions + 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 diff --git a/vlib/v/tests/inout/dump_expression.out b/vlib/v/tests/inout/dump_expression.out new file mode 100644 index 0000000000..18cb581dfe --- /dev/null +++ b/vlib/v/tests/inout/dump_expression.out @@ -0,0 +1,7 @@ +[vlib/v/tests/inout/dump_expression.vv:2] 1: 1 +[vlib/v/tests/inout/dump_expression.vv:7] 'a': a +[vlib/v/tests/inout/dump_expression.vv:20] point: Point{ + x: 1 + y: 2 + z: 3 +} diff --git a/vlib/v/tests/inout/dump_expression.vv b/vlib/v/tests/inout/dump_expression.vv new file mode 100644 index 0000000000..026d5ce1cf --- /dev/null +++ b/vlib/v/tests/inout/dump_expression.vv @@ -0,0 +1,29 @@ +fn dump_of_int() { + x := dump(1) + 1 + assert x == 2 +} + +fn dump_of_string() { + x := dump('a') + 'b' + assert x == 'ab' +} + +struct Point { +mut: + x int + y int + z int +} + +fn dump_of_struct() { + point := Point{1, 2, 3} + mut x := dump(point) + x.x += 100 + assert x == Point{101, 2, 3} +} + +fn main() { + dump_of_int() + dump_of_string() + dump_of_struct() +} diff --git a/vlib/v/token/token.v b/vlib/v/token/token.v index d69e1a56a1..8db550706c 100644 --- a/vlib/v/token/token.v +++ b/vlib/v/token/token.v @@ -117,6 +117,7 @@ pub enum Kind { key_true key_type key_typeof + key_dump key_orelse key_union key_pub @@ -274,6 +275,7 @@ fn build_token_str() []string { s[Kind.key_import] = 'import' s[Kind.key_unsafe] = 'unsafe' s[Kind.key_typeof] = 'typeof' + s[Kind.key_dump] = 'dump' s[Kind.key_enum] = 'enum' s[Kind.key_interface] = 'interface' s[Kind.key_pub] = 'pub' diff --git a/vlib/v/vmod/vmod.v b/vlib/v/vmod/vmod.v index 6f29a255a6..e4b8cc8162 100644 --- a/vlib/v/vmod/vmod.v +++ b/vlib/v/vmod/vmod.v @@ -42,7 +42,7 @@ pub fn new_mod_file_cacher() &ModFileCacher { return &ModFileCacher{} } -pub fn (mcache &ModFileCacher) dump() { +pub fn (mcache &ModFileCacher) debug() { $if debug { eprintln('ModFileCacher DUMP:') eprintln(' ModFileCacher.cache:')