import v.checker import v.ast import v.table import v.gen import v.token fn string_inter_lit(mut c checker.Checker, mut node ast.StringInterLiteral) table.Type { for i, expr in node.exprs { ftyp := c.expr(expr) node.expr_types << ftyp typ := c.table.unalias_num_type(ftyp) mut fmt := node.fmts[i] // analyze and validate format specifier if fmt !in [`E`, `F`, `G`, `e`, `f`, `g`, `d`, `u`, `x`, `X`, `o`, `c`, `s`, `p`, `_`] { c.error('unknown format specifier `${fmt:c}`', node.fmt_poss[i]) } if node.precisions[i] != 987698 && !typ.is_float() { c.error('precision specification only valid for float types', node.fmt_poss[i]) } if node.pluss[i] && !typ.is_number() { c.error('plus prefix only allowed for numbers', node.fmt_poss[i]) } if (typ.is_unsigned() && fmt !in [`u`, `x`, `X`, `o`, `c`]) || (typ.is_signed() && fmt !in [`d`, `x`, `X`, `o`, `c`]) || (typ.is_int_literal() && fmt !in [`d`, `c`, `x`, `X`, `o`, `u`, `x`, `X`, `o`]) || (typ.is_float() && fmt !in [`E`, `F`, `G`, `e`, `f`, `g`]) || (typ.is_pointer() && fmt !in [`p`, `x`, `X`]) || (typ.is_string() && fmt != `s`) || (typ.idx() in [table.i64_type_idx, table.f64_type_idx ] && fmt == `c`) { c.error('illegal format specifier `${fmt:c}` for type `${c.table.get_type_name(ftyp)}`', node.fmt_poss[i]) } node.need_fmts[i] = fmt != c.get_default_fmt(ftyp, typ) } return table.string_type } fn get_some_val(a_test, b_test, c_test, d_test, e_test, f_test f64) f64 { return a_test*b_test*c_test* d_test+e_test*f_test*a_test*d_test+a_test* b_test*c_test } fn main() { a, b, r, d := 5.3, 7.5, 4.4, 6.6 if a+b+ r*d+a+b+r* d > a+b+r*d+ a*b+r { println('ok') } v_str := 'v' s := []string{} s << ' `${v_str}`' println(s) println('this is quite a long string' + ' that is followed by an even longer part that should go to another line') if (a == b && b > r) || (d > r) || (a < b) || (b< d && a+b > r) || (a+b+d >= 0 && r < 0) || (a > b && d-r < b) { println('ok') } } fn gen_str_for_multi_return(mut g gen.Gen, info table.MultiReturn, styp, str_fn_name string) { for i, _ in info.types { println('\tstrings__Builder_write(&sb, _STR("\'%.*s\\000\'", 2, a.arg${i}));') } } struct Parser { peek_tok token.Token peek_tok2 token.Token peek_tok3 token.Token } fn (mut p Parser) name_expr() { if p.peek_tok.kind == .lpar || (p.peek_tok.kind == .lt && p.peek_tok2.kind == .name && p.peek_tok3.kind == .gt) { println(p.peek_tok.lit) } } fn set_nr_muls(t table.Type, nr_muls int) table.Type { return int(t) & 0xff00ffff | (nr_muls << 16) } // Test what exprs are treated as multiline. The ternary if only functions as a wrapper. // When one expr in a branch doesn't fit a single line, the whole if will be unwrapped. fn multiline_exprs() { // StructInit with at least one field _ := if true { Foo{} } else { Foo{ val: 123} } // ConcatExpr with a multiline child expr _, _ := if true { 1, Foo{val: 123} } else { 2, Foo{} } }