From 624f22e27e7f173b24fb45a259f9ba727428bae5 Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Tue, 22 Sep 2020 05:28:29 +0200 Subject: [PATCH] all: mutability check (part 1); enable mutable sumtype args --- vlib/builtin/array.v | 2 +- vlib/strconv/f64_str.v | 2 +- vlib/strconv/format.v | 12 ++--- vlib/time/parse.v | 22 ++++----- vlib/v/ast/ast.v | 25 +++++----- vlib/v/ast/scope.v | 4 +- vlib/v/ast/str.v | 104 +++++++++++++++++++-------------------- vlib/v/checker/checker.v | 24 +++++---- vlib/v/parser/fn.v | 2 +- vlib/v/parser/if_match.v | 1 + vlib/v/scanner/scanner.v | 45 ++++++++--------- vlib/vweb/tmpl/tmpl.v | 4 +- 12 files changed, 122 insertions(+), 125 deletions(-) diff --git a/vlib/builtin/array.v b/vlib/builtin/array.v index 777fd9e766..4b4e3bdabb 100644 --- a/vlib/builtin/array.v +++ b/vlib/builtin/array.v @@ -145,7 +145,7 @@ pub fn (a array) repeat(count int) array { // array.sort sorts array in-place using given `compare` function as comparator pub fn (mut a array) sort_with_compare(compare voidptr) { - C.qsort(a.data, a.len, a.element_size, compare) + C.qsort(mut a.data, a.len, a.element_size, compare) } // array.insert diff --git a/vlib/strconv/f64_str.v b/vlib/strconv/f64_str.v index ae718f81ef..0da50bf595 100644 --- a/vlib/strconv/f64_str.v +++ b/vlib/strconv/f64_str.v @@ -274,7 +274,7 @@ fn f64_to_decimal(mant u64, exp u64) Dec64 { e10 = int(q) + e2 i := -e2 - int(q) k := pow5_bits(i) - pow5_num_bits_64 - mut j := int(q) - k + j := int(q) - k mul := pow5_split_64[i] vr = mul_shift_64(u64(4) * m2 , mul, j) vp = mul_shift_64(u64(4) * m2 + u64(2) , mul, j) diff --git a/vlib/strconv/format.v b/vlib/strconv/format.v index 0959f826ca..b4dccd7fd1 100644 --- a/vlib/strconv/format.v +++ b/vlib/strconv/format.v @@ -472,7 +472,7 @@ pub fn v_sprintf(str string, pt ... voidptr) string{ } // single char, manage it here - if ch == `c` && status == .field_char { + if ch == `c` && status == .field_char { v_sprintf_panic(p_index, pt.len) d1 := unsafe {*(&byte(pt[p_index]))} res.write_b(d1) @@ -777,7 +777,7 @@ pub fn v_sprintf(str string, pt ... voidptr) string{ if ch in [`f`, `F`] { v_sprintf_panic(p_index, pt.len) x := unsafe {*(&f64(pt[p_index]))} - mut positive := x >= f64(0.0) + positive := x >= f64(0.0) len1 = if len1 >= 0 { len1 } else { def_len1 } s := format_fl(f64(x), {pad_ch: pad_ch, len0: len0, len1: len1, positive: positive, sign_flag: sign, allign: allign}) res.write(if ch == `F` {s.to_upper()} else {s}) @@ -789,7 +789,7 @@ pub fn v_sprintf(str string, pt ... voidptr) string{ else if ch in [`e`, `E`] { v_sprintf_panic(p_index, pt.len) x := unsafe {*(&f64(pt[p_index]))} - mut positive := x >= f64(0.0) + positive := x >= f64(0.0) len1 = if len1 >= 0 { len1 } else { def_len1 } s := format_es(f64(x), {pad_ch: pad_ch, len0: len0, len1: len1, positive: positive, sign_flag: sign, allign: allign}) res.write(if ch == `E` {s.to_upper()} else {s}) @@ -801,7 +801,7 @@ pub fn v_sprintf(str string, pt ... voidptr) string{ else if ch in [`g`, `G`] { v_sprintf_panic(p_index, pt.len) x := unsafe {*(&f64(pt[p_index]))} - mut positive := x >= f64(0.0) + positive := x >= f64(0.0) mut s := "" tx := fabs(x) if tx < 999_999.0 && tx >= 0.00001 { @@ -844,11 +844,11 @@ pub fn v_sprintf(str string, pt ... voidptr) string{ return res.str() } -[inline] +[inline] fn v_sprintf_panic( idx, len int) { if idx >= len { panic('${idx+1} % conversion specifiers, but given only ${len} args') - } + } } fn fabs(x f64) f64 { diff --git a/vlib/time/parse.v b/vlib/time/parse.v index 1b48f3cca0..be4a3cd914 100644 --- a/vlib/time/parse.v +++ b/vlib/time/parse.v @@ -55,17 +55,17 @@ pub fn parse_rfc2822(s string) ?Time { // also checks and support for leapseconds should be added in future PR pub fn parse_iso8601(s string) ?Time { - mut year := 0 - mut month := 0 - mut day := 0 - mut hour := 0 - mut minute := 0 - mut second := 0 - mut mic_second := 0 - mut time_char := `a` - mut plus_min := `a` - mut offset_hour := 0 - mut offset_min := 0 + year := 0 + month := 0 + day := 0 + hour := 0 + minute := 0 + second := 0 + mic_second := 0 + time_char := `a` + plus_min := `a` + offset_hour := 0 + offset_min := 0 count := unsafe {C.sscanf(charptr(s.str), "%4d-%2d-%2d%c%2d:%2d:%2d.%6d%c%2d:%2d", &year, &month, &day, &time_char, &hour, &minute, diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index fc6f892328..82ea0ec0af 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -12,9 +12,9 @@ pub type TypeDecl = AliasTypeDecl | FnTypeDecl | SumTypeDecl pub type Expr = AnonFn | ArrayInit | AsCast | Assoc | BoolLiteral | CallExpr | CastExpr | ChanInit | CharLiteral | Comment | ComptimeCall | ConcatExpr | EnumVal | FloatLiteral | Ident | IfExpr | IfGuardExpr | IndexExpr | InfixExpr | IntegerLiteral | Likely | LockExpr | - MapInit | MatchExpr | None | OrExpr | ParExpr | PostfixExpr | PrefixExpr | RangeExpr | SelectExpr | - SelectorExpr | SizeOf | SqlExpr | StringInterLiteral | StringLiteral | StructInit | Type | - TypeOf | UnsafeExpr + MapInit | MatchExpr | None | 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 | EnumDecl | ExprStmt | FnDecl | ForCStmt | ForInStmt | ForStmt | GlobalDecl | GoStmt | @@ -491,8 +491,8 @@ pub mut: pub struct UnsafeExpr { pub: - expr Expr - pos token.Position + expr Expr + pos token.Position } pub struct LockExpr { @@ -966,7 +966,8 @@ pub fn (expr Expr) is_blank_ident() bool { pub fn (expr Expr) position() token.Position { // all uncommented have to be implemented - match mut expr { + match expr { + // KEKW2 AnonFn { return expr.decl.pos } @@ -1084,8 +1085,8 @@ pub fn (expr Expr) is_lvalue() bool { pub fn (expr Expr) is_expr() bool { match expr { - IfExpr {return expr.is_expr} - MatchExpr {return expr.is_expr} + IfExpr { return expr.is_expr } + MatchExpr { return expr.is_expr } else {} } return true @@ -1151,16 +1152,12 @@ pub fn (stmt Stmt) position() token.Position { // field table.Field.default_expr, which should be ast.Expr pub fn fe2ex(x table.FExpr) Expr { res := Expr{} - unsafe { - C.memcpy(&res, &x, sizeof(Expr)) - } + unsafe {C.memcpy(&res, &x, sizeof(Expr))} return res } pub fn ex2fe(x Expr) table.FExpr { res := table.FExpr{} - unsafe { - C.memcpy(&res, &x, sizeof(table.FExpr)) - } + unsafe {C.memcpy(&res, &x, sizeof(table.FExpr))} return res } diff --git a/vlib/v/ast/scope.v b/vlib/v/ast/scope.v index 691ca2b4a8..78dfecd5e8 100644 --- a/vlib/v/ast/scope.v +++ b/vlib/v/ast/scope.v @@ -37,8 +37,7 @@ pub fn (s &Scope) find_with_scope(name string) ?(ScopeObject, &Scope) { } pub fn (s &Scope) find(name string) ?ScopeObject { - for sc := s; true; sc = sc.parent - { + for sc := s; true; sc = sc.parent { if name in sc.objects { return sc.objects[name] } @@ -85,6 +84,7 @@ pub fn (s &Scope) known_var(name string) bool { } pub fn (mut s Scope) update_var_type(name string, typ table.Type) { + s.end_pos = s.end_pos // TODO mut bug match mut s.objects[name] { Var { if it.typ == typ { diff --git a/vlib/v/ast/str.v b/vlib/v/ast/str.v index ca9203d31b..e70a39ebdc 100644 --- a/vlib/v/ast/str.v +++ b/vlib/v/ast/str.v @@ -13,17 +13,12 @@ pub fn (node &FnDecl) modname() string { } mut pamod := node.name.all_before_last('.') if pamod == node.name.after('.') { - pamod = if node.is_builtin { - 'builtin' - } else { - 'main' - } + pamod = if node.is_builtin { 'builtin' } else { 'main' } } return pamod } // These methods are used only by vfmt, vdoc, and for debugging. - pub fn (node &FnDecl) stringify(t &table.Table, cur_mod string) string { mut f := strings.new_builder(30) if node.is_pub { @@ -32,7 +27,7 @@ pub fn (node &FnDecl) stringify(t &table.Table, cur_mod string) string { mut receiver := '' if node.is_method { mut styp := util.no_cur_mod(t.type_to_str(node.receiver.typ), cur_mod) - mut m := if node.rec_mut { node.receiver.typ.share().str() + ' ' } else { '' } + m := if node.rec_mut { node.receiver.typ.share().str() + ' ' } else { '' } if node.rec_mut { styp = styp[1..] // remove & } @@ -51,11 +46,10 @@ pub fn (node &FnDecl) stringify(t &table.Table, cur_mod string) string { mut name := if node.is_anon { '' } else { node.name.after('.') } if node.language == .c { name = 'C.$name' - } - else if node.language == .js { + } else if node.language == .js { name = 'JS.$name' } - f.write('fn ${receiver}${name}') + f.write('fn $receiver$name') if node.is_generic { f.write('') } @@ -70,8 +64,8 @@ pub fn (node &FnDecl) stringify(t &table.Table, cur_mod string) string { continue } is_last_arg := i == node.args.len - 1 - should_add_type := is_last_arg || node.args[i + 1].typ != arg.typ || (node.is_variadic && - i == node.args.len - 2) + should_add_type := is_last_arg || node.args[i + 1].typ != arg.typ || + (node.is_variadic && i == node.args.len - 2) if arg.is_mut { f.write(arg.typ.share().str() + ' ') } @@ -105,7 +99,7 @@ pub fn (node &FnDecl) stringify(t &table.Table, cur_mod string) string { } pub fn (x &InfixExpr) str() string { - return '${x.left.str()} $x.op.str() ${x.right.str()}' + return '$x.left.str() $x.op.str() $x.right.str()' } // Expressions in string interpolations may have to be put in braces if they @@ -116,14 +110,14 @@ pub fn (x &InfixExpr) str() string { // This method creates the format specifier (including the colon) or an empty // string if none is needed and also returns (as bool) if the expression // must be enclosed in braces. - pub fn (lit &StringInterLiteral) get_fspec_braces(i int) (string, bool) { mut res := []string{} - needs_fspec := lit.need_fmts[i] || lit.pluss[i] || (lit.fills[i] && lit.fwidths[i] >= 0) || lit.fwidths[i] != 0 || lit.precisions[i] != 0 + needs_fspec := lit.need_fmts[i] || lit.pluss[i] || + (lit.fills[i] && lit.fwidths[i] >= 0) || lit.fwidths[i] != 0 || lit.precisions[i] != 0 mut needs_braces := needs_fspec if !needs_braces { - if i+1 < lit.vals.len && lit.vals[i+1].len > 0 { - next_char := lit.vals[i+1][0] + if i + 1 < lit.vals.len && lit.vals[i + 1].len > 0 { + next_char := lit.vals[i + 1][0] if util.is_func_char(next_char) || next_char == `.` || next_char == `(` { needs_braces = true } @@ -181,90 +175,94 @@ pub fn (lit &StringInterLiteral) get_fspec_braces(i int) (string, bool) { pub fn (x Expr) str() string { match x { BoolLiteral { - return it.val.str() + return x.val.str() } CastExpr { - return '${it.typname}(${it.expr.str()})' + return '${x.typname}($x.expr.str())' } CallExpr { - sargs := args2str(it.args) - if it.is_method { - return '${it.left.str()}.${it.name}($sargs)' + sargs := args2str(x.args) + if x.is_method { + return '${x.left.str()}.${x.name}($sargs)' } - return '${it.mod}.${it.name}($sargs)' + return '${x.mod}.${x.name}($sargs)' } CharLiteral { - return '`$it.val`' + return '`$x.val`' } EnumVal { - return '.${it.val}' + return '.$x.val' } FloatLiteral { - return it.val + return x.val } Ident { - return it.name + return x.name } IndexExpr { - return '${it.left.str()}[${it.index.str()}]' + return '$x.left.str()[$x.index.str()]' } IntegerLiteral { - return it.val + return x.val } InfixExpr { - return '${it.left.str()} $it.op.str() ${it.right.str()}' + return '$x.left.str() $x.op.str() $x.right.str()' } ParExpr { - return '($it.expr)' + return '($x.expr)' } PrefixExpr { - return it.op.str() + it.right.str() + return x.op.str() + x.right.str() } RangeExpr { mut s := '..' - if it.has_low {s = '$it.low ' + s} - if it.has_high {s = s + ' $it.high'} + if x.has_low { + s = '$x.low ' + s + } + if x.has_high { + s = s + ' $x.high' + } return s } SelectorExpr { - return '${it.expr.str()}.${it.field_name}' + return '${x.expr.str()}.$x.field_name' } SizeOf { - return 'sizeof($it.expr)' + return 'sizeof($x.expr)' } StringInterLiteral { mut res := []string{} res << "'" - for i, val in it.vals { + for i, val in x.vals { res << val - if i >= it.exprs.len { + if i >= x.exprs.len { break } res << '$' - fspec_str, needs_braces := it.get_fspec_braces(i) + fspec_str, needs_braces := x.get_fspec_braces(i) if needs_braces { res << '{' - res << it.exprs[i].str() + res << x.exprs[i].str() res << fspec_str res << '}' } else { - res << it.exprs[i].str() + res << x.exprs[i].str() } } res << "'" return res.join('') } StringLiteral { - return '"$it.val"' + return '"$x.val"' } TypeOf { - return 'typeof(${it.expr.str()})' + return 'typeof($x.expr.str())' } Likely { - return '_likely_(${it.expr.str()})' + return '_likely_($x.expr.str())' } UnsafeExpr { - return 'unsafe { $it.expr }' + return 'unsafe { $x.expr }' } else {} } @@ -273,9 +271,9 @@ pub fn (x Expr) str() string { pub fn (a CallArg) str() string { if a.is_mut { - return 'mut ${a.expr.str()}' + return 'mut $a.expr.str()' } - return '${a.expr.str()}' + return '$a.expr.str()' } pub fn args2str(args []CallArg) string { @@ -290,7 +288,7 @@ pub fn (node Stmt) str() string { match node { AssignStmt { mut out := '' - for i, left in it.left { + for i, left in node.left { if left is Ident { var_info := left.var_info() if var_info.is_mut { @@ -302,20 +300,20 @@ pub fn (node Stmt) str() string { out += ',' } } - out += ' $it.op.str() ' - for i, val in it.right { + out += ' $node.op.str() ' + for i, val in node.right { out += val.str() - if i < it.right.len - 1 { + if i < node.right.len - 1 { out += ',' } } return out } ExprStmt { - return it.expr.str() + return node.expr.str() } FnDecl { - return 'fn ${it.name}() { $it.stmts.len stmts }' + return 'fn ${node.name}() { $node.stmts.len stmts }' } else { return '[unhandled stmt str type: ${typeof(node)} ]' diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 2b0404ebdc..29de12d9a3 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -96,10 +96,11 @@ pub fn (mut c Checker) check_scope_vars(sc &ast.Scope) { } } } - // TODO: fix all of these warnings - // if obj.is_mut && !obj.is_changed { - // c.warn('`$obj.name` is declared as mutable, but it was never changed', obj.pos) - // } + if obj.is_mut && !obj.is_changed && !c.is_builtin_mod && obj.name != 'it' { + // if obj.is_mut && !obj.is_changed && !c.is_builtin { //TODO C error bad field not checked + // c.warn('`$obj.name` is declared as mutable, but it was never changed', + // obj.pos) + } } else {} } @@ -555,7 +556,7 @@ pub fn (mut c Checker) infix_expr(mut infix_expr ast.InfixExpr) table.Type { c.expected_type = former_expected_type } c.expected_type = table.void_type - mut left_type := c.expr(infix_expr.left) + left_type := c.expr(infix_expr.left) // left_type = c.unwrap_genric(c.expr(infix_expr.left)) infix_expr.left_type = left_type c.expected_type = left_type @@ -816,6 +817,7 @@ pub fn (mut c Checker) infix_expr(mut infix_expr ast.InfixExpr) table.Type { } // returns name and position of variable that needs write lock +// also sets `is_changed` to true (TODO update the name to reflect this?) fn (mut c Checker) fail_if_immutable(expr ast.Expr) (string, token.Position) { mut to_lock := '' // name of variable that needs lock mut pos := token.Position{} // and its position @@ -1518,7 +1520,7 @@ pub fn (mut c Checker) check_expr_opt_call(expr ast.Expr, ret_type table.Type) t return ret_type } -pub fn (mut c Checker) check_or_expr(mut or_expr ast.OrExpr, ret_type table.Type) { +pub fn (mut c Checker) check_or_expr(or_expr ast.OrExpr, ret_type table.Type) { if or_expr.kind == .propagate { if !c.cur_fn.return_type.has_flag(.optional) && c.cur_fn.name != 'main.main' { c.error('to propagate the optional call, `$c.cur_fn.name` must itself return an optional', @@ -1536,7 +1538,7 @@ pub fn (mut c Checker) check_or_expr(mut or_expr ast.OrExpr, ret_type table.Type // allow `f() or {}` return } - mut last_stmt := or_expr.stmts[stmts_len - 1] + last_stmt := or_expr.stmts[stmts_len - 1] if ret_type != table.void_type { match mut last_stmt { ast.ExprStmt { @@ -2932,7 +2934,7 @@ pub fn (mut c Checker) match_expr(mut node ast.MatchExpr) table.Type { // since it is used in c.match_exprs() it saves checking twice node.cond_type = cond_type if cond_type == 0 { - c.error('match 0 cond type', node.pos) + c.error('compiler bug: match 0 cond type', node.pos) } cond_type_sym := c.table.get_type_symbol(cond_type) if cond_type_sym.kind !in [.sum_type, .interface_] { @@ -2981,7 +2983,11 @@ pub fn (mut c Checker) match_expr(mut node ast.MatchExpr) table.Type { // node.expected_type = c.expected_type // } node.return_type = ret_type - // println('!m $expr_type') + if node.is_mut { + // Mark `x` in `match mut x {` as changed, and ensure it's mutable + // TODO2 enable when code is fixed + // c.fail_if_immutable(node.cond) + } return ret_type } diff --git a/vlib/v/parser/fn.v b/vlib/v/parser/fn.v index de7a572fc5..d53227d563 100644 --- a/vlib/v/parser/fn.v +++ b/vlib/v/parser/fn.v @@ -568,7 +568,7 @@ fn (p &Parser) fileis(s string) bool { fn (mut p Parser) check_fn_mutable_arguments(typ table.Type, pos token.Position) { sym := p.table.get_type_symbol(typ) - if sym.kind !in [.array, .struct_, .map, .placeholder] && !typ.is_ptr() { + if sym.kind !in [.array, .struct_, .map, .placeholder, .sum_type] && !typ.is_ptr() { p.error_with_pos('mutable arguments are only allowed for arrays, maps, and structs\n' + 'return values instead: `fn foo(mut n $sym.name) {` => `fn foo(n $sym.name) $sym.name {`', pos) diff --git a/vlib/v/parser/if_match.v b/vlib/v/parser/if_match.v index d635c9cf54..90143d7182 100644 --- a/vlib/v/parser/if_match.v +++ b/vlib/v/parser/if_match.v @@ -229,6 +229,7 @@ fn (mut p Parser) match_expr() ast.MatchExpr { typ: typ.to_ptr() pos: cond_pos is_used: true + is_changed: true // TODO mut unchanged warning hack, remove is_mut: is_mut }) } diff --git a/vlib/v/scanner/scanner.v b/vlib/v/scanner/scanner.v index 0fc0cb90f4..90b90a220c 100644 --- a/vlib/v/scanner/scanner.v +++ b/vlib/v/scanner/scanner.v @@ -44,7 +44,7 @@ pub mut: is_fmt bool // Used only for skipping ${} in strings, since we need literal // string values when generating formatted code. comments_mode CommentsMode - is_inside_toplvl_statement bool // *only* used in comments_mode: .toplevel_comments, toggled by parser + is_inside_toplvl_statement bool // *only* used in comments_mode: .toplevel_comments, toggled by parser all_tokens []token.Token // *only* used in comments_mode: .toplevel_comments, contains all tokens tidx int eofs int @@ -178,8 +178,8 @@ fn (mut s Scanner) ident_name() string { return name } -// ident_fn_name look ahead and return name of function if possible, otherwise empty string -fn (mut s Scanner) ident_fn_name() string { +// ident_fn_name looks ahead and returns name of the function if possible, otherwise an empty string +fn (s &Scanner) ident_fn_name() string { start := s.pos mut pos := s.pos pos++ @@ -221,9 +221,8 @@ fn (mut s Scanner) ident_fn_name() string { if pos <= start || pos >= s.text.len { return '' } - if s.text[start_pos].is_digit() || end_pos > s.text.len || - end_pos <= start_pos || end_pos <= start || - start_pos < start { + if s.text[start_pos].is_digit() || end_pos > s.text.len || end_pos <= start_pos || + end_pos <= start || start_pos < start { return '' } fn_name := s.text[start_pos..end_pos] @@ -231,7 +230,7 @@ fn (mut s Scanner) ident_fn_name() string { } // ident_mod_name look ahead and return name of module this file belongs to if possible, otherwise empty string -fn (mut s Scanner) ident_mod_name() string { +fn (s &Scanner) ident_mod_name() string { start := s.pos mut pos := s.pos pos++ @@ -259,7 +258,7 @@ fn (mut s Scanner) ident_mod_name() string { } // ident_struct_name look ahead and return name of last encountered struct if possible, otherwise empty string -fn (mut s Scanner) ident_struct_name() string { +fn (s &Scanner) ident_struct_name() string { start := s.pos mut pos := s.pos // Return last known stuct_name encountered to avoid using high order/anonymous function definitions @@ -303,9 +302,8 @@ fn (mut s Scanner) ident_struct_name() string { return '' } start_pos := pos + 1 - if s.text[start_pos].is_digit() || end_pos > s.text.len || - end_pos <= start_pos || end_pos <= start || - start_pos <= start { + if s.text[start_pos].is_digit() || end_pos > s.text.len || end_pos <= start_pos || + end_pos <= start || start_pos <= start { return '' } struct_name := s.text[start_pos..end_pos] @@ -354,8 +352,7 @@ fn (mut s Scanner) ident_bin_number() string { } if s.text[s.pos - 1] == num_sep { s.error('cannot use `_` at the end of a numeric literal') - } - else if start_pos + 2 == s.pos { + } else if start_pos + 2 == s.pos { s.pos-- // adjust error position s.error('number part of this binary is not provided') } else if has_wrong_digit { @@ -394,8 +391,7 @@ fn (mut s Scanner) ident_hex_number() string { } if s.text[s.pos - 1] == num_sep { s.error('cannot use `_` at the end of a numeric literal') - } - else if start_pos + 2 == s.pos { + } else if start_pos + 2 == s.pos { s.pos-- // adjust error position s.error('number part of this hexadecimal is not provided') } else if has_wrong_digit { @@ -434,8 +430,7 @@ fn (mut s Scanner) ident_oct_number() string { } if s.text[s.pos - 1] == num_sep { s.error('cannot use `_` at the end of a numeric literal') - } - else if start_pos + 2 == s.pos { + } else if start_pos + 2 == s.pos { s.pos-- // adjust error position s.error('number part of this octal is not provided') } else if has_wrong_digit { @@ -455,7 +450,7 @@ fn (mut s Scanner) ident_dec_number() string { // scan integer part for s.pos < s.text.len { c := s.text[s.pos] - if c == num_sep && s.text[s.pos + 1] == num_sep { + if c == num_sep && s.text[s.pos + 1] == num_sep { s.error('cannot use `_` consecutively') } if !c.is_digit() && c != num_sep { @@ -546,8 +541,7 @@ fn (mut s Scanner) ident_dec_number() string { // error check: 5e s.pos-- // adjust error position s.error('exponent has no digits') - } else if s.pos < s.text.len && - s.text[s.pos] == `.` && !is_range && !call_method { + } else if s.pos < s.text.len && s.text[s.pos] == `.` && !is_range && !call_method { // error check: 1.23.4, 123.e+3.4 if has_exp { s.error('exponential part should be integer') @@ -608,7 +602,7 @@ pub fn (mut s Scanner) scan_all_tokens_in_buffer() { cmode := s.comments_mode s.comments_mode = .parse_comments for { - mut t := s.text_scan() + t := s.text_scan() s.all_tokens << t if t.kind == .eof { break @@ -1093,7 +1087,7 @@ fn (mut s Scanner) text_scan() token.Token { start := s.pos + 1 s.ignore_line() mut comment_line_end := s.pos - if s.text[s.pos-1] == `\r` { + if s.text[s.pos - 1] == `\r` { comment_line_end-- } else { // fix line_nr, \n was read; the comment is marked on the next line @@ -1216,7 +1210,8 @@ fn (mut s Scanner) ident_string() string { } // Don't allow \0 if c == `0` && s.pos > 2 && s.text[s.pos - 1] == slash { - if (s.pos < s.text.len - 1 && s.text[s.pos + 1].is_digit()) || s.count_symbol_before(s.pos - 1, slash) % 2 == 0 { + if (s.pos < s.text.len - 1 && s.text[s.pos + 1].is_digit()) || + s.count_symbol_before(s.pos - 1, slash) % 2 == 0 { } else if !is_cstr && !is_raw { s.error(r'cannot use `\0` (NULL character) in the string literal') } @@ -1236,8 +1231,8 @@ fn (mut s Scanner) ident_string() string { break } // $var - if prevc == `$` && util.is_name_char(c) && !is_raw && - s.count_symbol_before(s.pos - 2, slash) % 2 == 0 { + if prevc == `$` && util.is_name_char(c) && !is_raw && s.count_symbol_before(s.pos - 2, slash) % + 2 == 0 { s.is_inside_string = true s.is_inter_start = true s.pos -= 2 diff --git a/vlib/vweb/tmpl/tmpl.v b/vlib/vweb/tmpl/tmpl.v index d0ef9266c0..fcfda8846f 100644 --- a/vlib/vweb/tmpl/tmpl.v +++ b/vlib/vweb/tmpl/tmpl.v @@ -13,7 +13,7 @@ const ( // compile_file compiles the content of a file by the given path as a template pub fn compile_file(path, fn_name string) string { - mut html := os.read_file(path) or { + html := os.read_file(path) or { panic('html failed') } return compile_template(html, fn_name) @@ -82,7 +82,7 @@ _ = footer pos := line.index('@include ') or { continue } - mut file_name := line[pos + 9..] + file_name := line[pos + 9..] file_path := os.join_path('templates', '${file_name}.html') mut file_content := os.read_file(file_path) or { panic('reading file $file_name failed')