diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index 8db288e8c0..12cfc35e8c 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -14,9 +14,13 @@ import term const ( c_reserved = ['delete', 'exit', 'unix', 'error', 'calloc', 'malloc', 'free', 'panic', 'auto', - 'char', 'default', 'do', 'double', 'extern', 'float', 'inline', 'int', 'long', 'register', - 'restrict', 'short', 'signed', 'sizeof', 'static', 'switch', 'typedef', 'union', 'unsigned', - 'void', 'volatile', 'while'] + 'char' + 'default' + 'do' + 'double', 'extern', 'float', 'inline', 'int', 'long', 'register', 'restrict', 'short', + 'signed' + 'sizeof', 'static', 'switch', 'typedef', 'union', 'unsigned', 'void', 'volatile', 'while' + ] ) fn foo(t token.Token) { @@ -64,12 +68,13 @@ mut: const ( 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' + ] ) pub fn cgen(files []ast.File, table &table.Table, pref &pref.Preferences) string { - if true { // if - x := 10 // line + if true { // if + x := 10 // line // sep y := 20 } else { @@ -113,7 +118,7 @@ pub fn cgen(files []ast.File, table &table.Table, pref &pref.Preferences) string g.stmts(file.stmts) } if autofree_used { - g.autofree = true // so that void _vcleanup is generated + g.autofree = true // so that void _vcleanup is generated } g.write_variadic_types() // g.write_str_definitions() @@ -140,7 +145,7 @@ pub fn (g Gen) hashes() string { pub fn (var g Gen) init() { g.cheaders.writeln('// Generated by the V compiler') - g.cheaders.writeln('#include ') // int64_t etc + g.cheaders.writeln('#include ') // int64_t etc g.cheaders.writeln(c_builtin_types) g.cheaders.writeln(c_headers) g.definitions.writeln('\nstring _STR(const char*, ...);\n') @@ -219,7 +224,7 @@ pub fn (var g Gen) typ(t table.Type) string { } if !(styp in g.optionals) { // println(styp) - x := styp // .replace('*', '_ptr') // handle option ptrs + x := styp // .replace('*', '_ptr') // handle option ptrs g.typedefs2.writeln('typedef Option $x;') g.optionals << styp } @@ -424,19 +429,16 @@ fn (var g Gen) stmt(node ast.Stmt) { ast.ExprStmt { g.expr(it.expr) expr := it.expr + // no ; after an if expression } match expr { - ast.IfExpr { - // no ; after an if expression - } - else { - if !g.inside_ternary { + ast.IfExpr {} + else { if !g.inside_ternary { g.writeln(';') - } - } + } } } } ast.FnDecl { - g.fn_decl = it // &it + g.fn_decl = it // &it g.gen_fn_decl(it) g.writeln('') } @@ -721,7 +723,7 @@ fn (var g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) { } g.expr(ident) if is_optional { - mr_styp2 := mr_styp[7..] // remove Option_ + mr_styp2 := mr_styp[7..] // remove Option_ g.writeln(' = (*(${mr_styp2}*)${mr_var_name}.data).arg$i;') } else { g.writeln(' = ${mr_var_name}.arg$i;') @@ -758,9 +760,7 @@ fn (var g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) { right_sym := g.table.get_type_symbol(assign_stmt.right_types[i]) var is_fixed_array_init := false match val { - ast.ArrayInit { - is_fixed_array_init = it.is_fixed - } + ast.ArrayInit { is_fixed_array_init = it.is_fixed } else {} } is_decl := assign_stmt.op == .decl_assign @@ -799,15 +799,9 @@ fn (var g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) { fn (var g Gen) gen_clone_assignment(val ast.Expr, right_sym table.TypeSymbol, add_eq bool) bool { var is_ident := false match val { - ast.Ident { - is_ident = true - } - ast.SelectorExpr { - is_ident = true - } - else { - return false - } + ast.Ident { is_ident = true } + ast.SelectorExpr { is_ident = true } + else { return false } } if g.autofree && right_sym.kind == .array && is_ident { // `arr1 = arr2` => `arr1 = arr2.clone()` @@ -988,7 +982,7 @@ fn (var g Gen) expr(node ast.Expr) { g.write('0') g.write(it.val[2..]) } else { - g.write(it.val) // .int().str()) + g.write(it.val) // .int().str()) } } ast.MatchExpr { @@ -1094,7 +1088,6 @@ fn (var g Gen) expr(node ast.Expr) { ast.AnonFn { sym := g.table.get_type_symbol(it.typ) func := it.decl - // TODO: Fix hack and write function implementation directly to definitions pos := g.out.len type_name := g.typ(func.return_type) @@ -1111,11 +1104,9 @@ fn (var g Gen) expr(node ast.Expr) { g.out.writeln('}') g.defer_stmts = [] g.fn_decl = 0 - fn_body := g.out.after(pos) g.definitions.write(fn_body) g.out.go_back(fn_body.len) - g.out.write('&${sym.name}_impl') } else { @@ -1141,7 +1132,7 @@ fn (var g Gen) typeof_expr(node ast.TypeOf) { } else if sym.kind == .function { info := sym.info as table.FnType fn_info := info.func - mut repr := 'fn (' + var repr := 'fn (' for i, arg in fn_info.args { if i > 0 { repr += ', ' @@ -1160,12 +1151,8 @@ fn (var g Gen) typeof_expr(node ast.TypeOf) { fn (var g Gen) enum_expr(node ast.Expr) { match node { - ast.EnumVal { - g.write(it.val) - } - else { - g.expr(node) - } + ast.EnumVal { g.write(it.val) } + else { g.expr(node) } } } @@ -1261,30 +1248,14 @@ fn (var g Gen) infix_expr(node ast.InfixExpr) { right_sym := g.table.get_type_symbol(node.right_type) if node.left_type == table.string_type_idx && node.op != .key_in && node.op != .not_in { fn_name := match node.op { - .plus { - 'string_add(' - } - .eq { - 'string_eq(' - } - .ne { - 'string_ne(' - } - .lt { - 'string_lt(' - } - .le { - 'string_le(' - } - .gt { - 'string_gt(' - } - .ge { - 'string_ge(' - } - else { - '/*node error*/' - } + .plus { 'string_add(' } + .eq { 'string_eq(' } + .ne { 'string_ne(' } + .lt { 'string_lt(' } + .le { 'string_le(' } + .gt { 'string_gt(' } + .ge { 'string_ge(' } + else { '/*node error*/' } } g.write(fn_name) g.expr(node.left) @@ -1358,13 +1329,20 @@ fn (var g Gen) infix_expr(node ast.InfixExpr) { g.write('), $tmp, $styp)') } else { // push a single element + /* elem_type_str := g.typ(info.elem_type) - // g.write('array_push(&') g.write('_PUSH(&') g.expr(node.left) g.write(', (') g.expr_with_cast(node.right, node.right_type, info.elem_type) g.write('), $tmp, $elem_type_str)') +*/ + elem_type_str := g.typ(info.elem_type) + g.write('array_push(&') + g.expr(node.left) + g.write(', &($elem_type_str[]){ ') + g.expr_with_cast(node.right, node.right_type, info.elem_type) + g.write(' })') } } else if (node.left_type == node.right_type) && node.left_type in [table.f32_type_idx, table.f64_type_idx] && node.op in [.eq, .ne] { @@ -1398,7 +1376,7 @@ fn (var g Gen) infix_expr(node ast.InfixExpr) { g.expr(node.right) g.write(')') } else { - need_par := node.op in [.amp, .pipe, .xor] // `x & y == 0` => `(x & y) == 0` in C + need_par := node.op in [.amp, .pipe, .xor] // `x & y == 0` => `(x & y) == 0` in C if need_par { g.write('(') } @@ -1537,7 +1515,7 @@ fn (var g Gen) ident(node ast.Ident) { // `println(x)` => `println(*(int*)x.data)` if it.is_optional && !(g.is_assign_lhs && g.right_is_opt) { g.write('/*opt*/') - styp := g.typ(it.typ)[7..] // Option_int => int TODO perf? + styp := g.typ(it.typ)[7..] // Option_int => int TODO perf? g.write('(*($styp*)${name}.data)') return } @@ -1722,39 +1700,17 @@ fn (var g Gen) index_expr(node ast.IndexExpr) { g.expr(node.index) g.write(') ') op := match g.assign_op { - .mult_assign { - '*' - } - .plus_assign { - '+' - } - .minus_assign { - '-' - } - .div_assign { - '/' - } - .xor_assign { - '^' - } - .mod_assign { - '%' - } - .or_assign { - '|' - } - .and_assign { - '&' - } - .left_shift_assign { - '<<' - } - .right_shift_assign { - '>>' - } - else { - '' - } + .mult_assign { '*' } + .plus_assign { '+' } + .minus_assign { '-' } + .div_assign { '/' } + .xor_assign { '^' } + .mod_assign { '%' } + .or_assign { '|' } + .and_assign { '&' } + .left_shift_assign { '<<' } + .right_shift_assign { '>>' } + else { '' } } g.write(op) } @@ -1824,8 +1780,8 @@ fn (var g Gen) return_statement(node ast.Return) { typ_sym := g.table.get_type_symbol(g.fn_decl.return_type) mr_info := typ_sym.info as table.MultiReturn var styp := g.typ(g.fn_decl.return_type) - if fn_return_is_optional { // && !table.type_is(node.types[0], .optional) && node.types[0] != - styp = styp[7..] // remove 'Option_' + if fn_return_is_optional { // && !table.type_is(node.types[0], .optional) && node.types[0] != + styp = styp[7..] // remove 'Option_' var x := styp if x.ends_with('_ptr') { x = x.replace('_ptr', '*') @@ -1862,13 +1818,13 @@ fn (var g Gen) return_statement(node ast.Return) { // TODO: why? // if !it.is_method { if it.name == 'error' { - is_error = true // TODO check name 'error' + is_error = true // TODO check name 'error' } } else {} } if !is_none && !is_error { - styp := g.typ(g.fn_decl.return_type)[7..] // remove 'Option_' + styp := g.typ(g.fn_decl.return_type)[7..] // remove 'Option_' var x := styp if x.ends_with('_ptr') { x = x.replace('_ptr', '*') @@ -1946,21 +1902,23 @@ fn (var g Gen) struct_init(struct_init ast.StructInit) { styp := g.typ(struct_init.typ) is_amp := g.is_amp if is_amp { - g.out.go_back(1) // delete the & already generated in `prefix_expr() + g.out.go_back(1) // delete the & already generated in `prefix_expr() g.write('($styp*)memdup(&($styp){') } else { g.writeln('($styp){') } // var fields := []string - var inited_fields := []string // TODO this is done in checker, move to ast node - /*if struct_init.fields.len == 0 && struct_init.exprs.len > 0 { + var inited_fields := []string // TODO this is done in checker, move to ast node + /* + if struct_init.fields.len == 0 && struct_init.exprs.len > 0 { // Get fields for {a,b} short syntax. Fields array wasn't set in the parser. for f in info.fields { fields << f.name } } else { fields = struct_init.fields - }*/ + } +*/ // User set fields for i, field in struct_init.fields { field_name := c_name(field.name) @@ -1983,7 +1941,6 @@ fn (var g Gen) struct_init(struct_init ast.StructInit) { g.write('\t.$field_name = ') if field.has_default_expr { g.expr(field.default_expr) - } else { g.write(g.type_default(field.typ)) } @@ -2122,7 +2079,7 @@ const ( ) fn (var g Gen) write_builtin_types() { - var builtin_types := []table.TypeSymbol // builtin types + var builtin_types := []table.TypeSymbol // builtin types // builtin types need to be on top // everything except builtin will get sorted for builtin_name in builtins { @@ -2135,7 +2092,7 @@ fn (var g Gen) write_builtin_types() { // Sort the types, make sure types that are referenced by other types // are added before them. fn (var g Gen) write_sorted_types() { - var types := []table.TypeSymbol // structs that need to be sorted + var types := []table.TypeSymbol // structs that need to be sorted for typ in g.table.types { if !(typ.name in builtins) { types << typ @@ -2379,7 +2336,7 @@ fn (var g Gen) string_inter_literal(node ast.StringInterLiteral) { // `nums.filter(it % 2 == 0)` fn (var g Gen) gen_filter(node ast.CallExpr) { tmp := g.new_tmp_var() - s := g.out.after(g.stmt_start_pos) // the already generated part of current statement + s := g.out.after(g.stmt_start_pos) // the already generated part of current statement g.out.go_back(s.len) // println('filter s="$s"') sym := g.table.get_type_symbol(node.return_type) @@ -2398,7 +2355,7 @@ fn (var g Gen) gen_filter(node ast.CallExpr) { g.expr(node.left) g.writeln('.data)[i];') g.write('if (') - g.expr(node.args[0].expr) // the first arg is the filter condition + g.expr(node.args[0].expr) // the first arg is the filter condition g.writeln(') array_push(&$tmp, &it); \n }') g.write(s) g.write(' ') @@ -2418,8 +2375,8 @@ fn (var g Gen) insert_before(s string) { // `os.cp(...)` => `Option bool tmp = os__cp(...); if (!tmp.ok) { ... }` fn (var g Gen) or_block(var_name string, stmts []ast.Stmt, return_type table.Type) { mr_styp := g.typ(return_type) - mr_styp2 := mr_styp[7..] // remove Option_ - g.writeln(';') // or') + mr_styp2 := mr_styp[7..] // remove Option_ + g.writeln(';') // or') g.writeln('if (!${var_name}.ok) {') g.writeln('\tstring err = ${var_name}.v_error;') g.writeln('\tint errcode = ${var_name}.ecode;') @@ -2469,12 +2426,8 @@ fn (var g Gen) type_of_last_statement(stmts []ast.Stmt) (string, string) { fn (var g Gen) type_of_call_expr(node ast.Expr) string { match node { - ast.CallExpr { - return g.typ(it.return_type) - } - else { - return typeof(node) - } + ast.CallExpr { return g.typ(it.return_type) } + else { return typeof(node) } } return '' } @@ -2504,114 +2457,48 @@ fn (var g Gen) in_optimization(left ast.Expr, right ast.ArrayInit) { fn op_to_fn_name(name string) string { return match name { - '+' { - '_op_plus' - } - '-' { - '_op_minus' - } - '*' { - '_op_mul' - } - '/' { - '_op_div' - } - '%' { - '_op_mod' - } - else { - 'bad op $name' - } + '+' { '_op_plus' } + '-' { '_op_minus' } + '*' { '_op_mul' } + '/' { '_op_div' } + '%' { '_op_mod' } + else { 'bad op $name' } } } fn comp_if_to_ifdef(name string) string { match name { // platforms/os-es: - 'windows' { - return '_WIN32' - } - 'mac' { - return '__APPLE__' - } - 'macos' { - return '__APPLE__' - } - 'linux' { - return '__linux__' - } - 'freebsd' { - return '__FreeBSD__' - } - 'openbsd' { - return '__OpenBSD__' - } - 'netbsd' { - return '__NetBSD__' - } - 'dragonfly' { - return '__DragonFly__' - } - 'msvc' { - return '_MSC_VER' - } - 'android' { - return '__ANDROID__' - } - 'solaris' { - return '__sun' - } - 'haiku' { - return '__haiku__' - } - 'linux_or_macos' { - return '' - } + 'windows' { return '_WIN32' } + 'mac' { return '__APPLE__' } + 'macos' { return '__APPLE__' } + 'linux' { return '__linux__' } + 'freebsd' { return '__FreeBSD__' } + 'openbsd' { return '__OpenBSD__' } + 'netbsd' { return '__NetBSD__' } + 'dragonfly' { return '__DragonFly__' } + 'msvc' { return '_MSC_VER' } + 'android' { return '__ANDROID__' } + 'solaris' { return '__sun' } + 'haiku' { return '__haiku__' } + 'linux_or_macos' { return '' } // - 'js' { - return '_VJS' - } + 'js' { return '_VJS' } // compilers: - 'tinyc' { - return '__TINYC__' - } - 'clang' { - return '__clang__' - } - 'mingw' { - return '__MINGW32__' - } - 'msvc' { - return '_MSC_VER' - } + 'tinyc' { return '__TINYC__' } + 'clang' { return '__clang__' } + 'mingw' { return '__MINGW32__' } + 'msvc' { return '_MSC_VER' } // other: - 'debug' { - return '_VDEBUG' - } - 'glibc' { - return '__GLIBC__' - } - 'prealloc' { - return 'VPREALLOC' - } - 'no_bounds_checking' { - return 'NO_BOUNDS_CHECK' - } - 'x64' { - return 'TARGET_IS_64BIT' - } - 'x32' { - return 'TARGET_IS_32BIT' - } - 'little_endian' { - return 'TARGET_ORDER_IS_LITTLE' - } - 'big_endian' { - return 'TARGET_ORDER_IS_BIG' - } - else { - verror('bad os ifdef name "$name"') - } + 'debug' { return '_VDEBUG' } + 'glibc' { return '__GLIBC__' } + 'prealloc' { return 'VPREALLOC' } + 'no_bounds_checking' { return 'NO_BOUNDS_CHECK' } + 'x64' { return 'TARGET_IS_64BIT' } + 'x32' { return 'TARGET_IS_32BIT' } + 'little_endian' { return 'TARGET_ORDER_IS_LITTLE' } + 'big_endian' { return 'TARGET_ORDER_IS_BIG' } + else { verror('bad os ifdef name "$name"') } } // verror('bad os ifdef name "$name"') return '' @@ -2663,12 +2550,8 @@ fn (g Gen) type_default(typ table.Type) string { } */ match sym.name { - 'string' { - return 'tos3("")' - } - 'rune' { - return '0' - } + 'string' { return 'tos3("")' } + 'rune' { return '0' } else {} } return '{0}' @@ -2899,21 +2782,11 @@ fn (var g Gen) gen_str_for_type(sym table.TypeSymbol, styp string) { } g.str_types << styp match sym.info { - table.Alias { - g.gen_str_default(sym, styp) - } - table.Array, table.ArrayFixed { - g.gen_str_for_array(it, styp) - } - table.Enum { - g.gen_str_for_enum(it, styp) - } - table.Struct { - g.gen_str_for_struct(it, styp) - } - else { - verror("could not generate string method for type \'${styp}\'") - } + table.Alias { g.gen_str_default(sym, styp) } + table.Array { g.gen_str_for_array(it, styp) } + table.Enum { g.gen_str_for_enum(it, styp) } + table.Struct { g.gen_str_for_struct(it, styp) } + else { verror("could not generate string method for type \'${styp}\'") } } } @@ -3037,7 +2910,7 @@ fn (g Gen) type_to_fmt(typ table.Type) string { } else if typ == table.bool_type { return '%.*s' } else if typ in [table.f32_type, table.f64_type] { - return '%g' // g removes trailing zeros unlike %f + return '%g' // g removes trailing zeros unlike %f } return '%d' }