| 1 | import v.checker |
| 2 | import v.ast |
| 3 | import v.table |
| 4 | import v.gen |
| 5 | import v.token |
| 6 | |
| 7 | fn string_inter_lit(mut c checker.Checker, mut node ast.StringInterLiteral) table.Type { |
| 8 | for i, expr in node.exprs { |
| 9 | ftyp := c.expr(expr) |
| 10 | node.expr_types << ftyp |
| 11 | typ := c.table.unalias_num_type(ftyp) |
| 12 | mut fmt := node.fmts[i] |
| 13 | // analyze and validate format specifier |
| 14 | if fmt !in [`E`, `F`, `G`, `e`, `f`, `g`, `d`, `u`, `x`, `X`, `o`, `c`, `s`, `p`, `_`] { |
| 15 | c.error('unknown format specifier `${fmt:c}`', node.fmt_poss[i]) |
| 16 | } |
| 17 | if node.precisions[i] != 987698 && !typ.is_float() { |
| 18 | c.error('precision specification only valid for float types', node.fmt_poss[i]) |
| 19 | } |
| 20 | if node.pluss[i] && !typ.is_number() { |
| 21 | c.error('plus prefix only allowed for numbers', node.fmt_poss[i]) |
| 22 | } |
| 23 | if (typ.is_unsigned() && fmt !in [`u`, `x`, `X`, `o`, `c`]) |
| 24 | || (typ.is_signed() && fmt !in [`d`, `x`, `X`, `o`, `c`]) |
| 25 | || (typ.is_int_literal() && fmt !in [`d`, `c`, `x`, `X`, `o`, `u`, `x`, `X`, `o`]) |
| 26 | || (typ.is_float() && fmt !in [`E`, `F`, `G`, `e`, `f`, `g`]) |
| 27 | || (typ.is_pointer() && fmt !in [`p`, `x`, `X`]) |
| 28 | || (typ.is_string() && fmt != `s`) |
| 29 | || (typ.idx() in [table.i64_type_idx, table.f64_type_idx] && fmt == `c`) { |
| 30 | c.error('illegal format specifier `${fmt:c}` for type `${c.table.get_type_name(ftyp)}`', |
| 31 | node.fmt_poss[i]) |
| 32 | } |
| 33 | node.need_fmts[i] = fmt != c.get_default_fmt(ftyp, typ) |
| 34 | } |
| 35 | |
| 36 | return table.string_type |
| 37 | } |
| 38 | |
| 39 | fn get_some_val(a_test f64, b_test f64, c_test f64, d_test f64, e_test f64, f_test f64) f64 { |
| 40 | return a_test * b_test * c_test * d_test + e_test * f_test * a_test * d_test + |
| 41 | a_test * b_test * c_test |
| 42 | } |
| 43 | |
| 44 | fn main() { |
| 45 | a, b, r, d := 5.3, 7.5, 4.4, 6.6 |
| 46 | if a + b + r * d + a + b + r * d > a + b + r * d + a * b + r { |
| 47 | println('ok') |
| 48 | } |
| 49 | v_str := 'v' |
| 50 | s := []string{} |
| 51 | s << ' `${v_str}`' |
| 52 | println(s) |
| 53 | println('this is quite a long string' + |
| 54 | ' that is followed by an even longer part that should go to another line') |
| 55 | if (a == b && b > r) || d > r || a < b || (b < d && a + b > r) |
| 56 | || (a + b + d >= 0 && r < 0) || (a > b && d - r < b) { |
| 57 | println('ok') |
| 58 | } |
| 59 | } |
| 60 | |
| 61 | fn gen_str_for_multi_return(mut g gen.Gen, |
| 62 | info table.MultiReturn, styp string, str_fn_name string) { |
| 63 | for i, _ in info.types { |
| 64 | println('\tstrings__Builder_write(&sb, _STR("\'%.*s\\000\'", 2, a.arg${i}));') |
| 65 | } |
| 66 | } |
| 67 | |
| 68 | struct Parser { |
| 69 | peek_tok token.Token |
| 70 | peek_tok2 token.Token |
| 71 | peek_tok3 token.Token |
| 72 | } |
| 73 | |
| 74 | fn (mut p Parser) name_expr() { |
| 75 | if p.peek_tok.kind == .lpar |
| 76 | || (p.peek_tok.kind == .lt && p.peek_tok2.kind == .name && p.peek_tok3.kind == .gt) { |
| 77 | println(p.peek_tok.lit) |
| 78 | } |
| 79 | } |
| 80 | |
| 81 | fn set_nr_muls(t table.Type, nr_muls int) table.Type { |
| 82 | return int(t) & 0xff00ffff | (nr_muls << 16) |
| 83 | } |
| 84 | |
| 85 | // Test what exprs are treated as multiline. The ternary if only functions as a wrapper. |
| 86 | // When one expr in a branch doesn't fit a single line, the whole if will be unwrapped. |
| 87 | fn multiline_exprs() { |
| 88 | // StructInit with at least one field |
| 89 | _ := if true { |
| 90 | Foo{} |
| 91 | } else { |
| 92 | Foo{ |
| 93 | val: 123 |
| 94 | } |
| 95 | } |
| 96 | // ConcatExpr with a multiline child expr |
| 97 | _, _ := if true { |
| 98 | 1, Foo{ |
| 99 | val: 123 |
| 100 | } |
| 101 | } else { |
| 102 | 2, Foo{} |
| 103 | } |
| 104 | } |
| 105 | |