fmt: re-run on checker.v and cgen.v
parent
11871d9544
commit
e918f8faf2
|
@ -80,7 +80,7 @@ pub fn (mut c Checker) check_scope_vars(sc &ast.Scope) {
|
||||||
}
|
}
|
||||||
// TODO: fix all of these warnings
|
// TODO: fix all of these warnings
|
||||||
// if obj.is_mut && !obj.is_changed {
|
// if obj.is_mut && !obj.is_changed {
|
||||||
// c.warn('`$obj.name` is declared as mutable, but it was never changed', obj.pos)
|
// c.warn('`$obj.name` is declared as mutable, but it was never changed', obj.pos)
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
else {}
|
else {}
|
||||||
|
@ -190,7 +190,8 @@ fn (mut c Checker) check_file_in_main(file ast.File) bool {
|
||||||
if stmt is ast.AliasTypeDecl {
|
if stmt is ast.AliasTypeDecl {
|
||||||
alias_decl := stmt as ast.AliasTypeDecl
|
alias_decl := stmt as ast.AliasTypeDecl
|
||||||
if alias_decl.is_pub {
|
if alias_decl.is_pub {
|
||||||
c.warn('type alias `$alias_decl.name` $no_pub_in_main_warning', alias_decl.pos)
|
c.warn('type alias `$alias_decl.name` $no_pub_in_main_warning',
|
||||||
|
alias_decl.pos)
|
||||||
}
|
}
|
||||||
} else if stmt is ast.SumTypeDecl {
|
} else if stmt is ast.SumTypeDecl {
|
||||||
sum_decl := stmt as ast.SumTypeDecl
|
sum_decl := stmt as ast.SumTypeDecl
|
||||||
|
@ -308,7 +309,8 @@ pub fn (mut c Checker) struct_decl(decl ast.StructDecl) {
|
||||||
if sym.kind == .struct_ {
|
if sym.kind == .struct_ {
|
||||||
info := sym.info as table.Struct
|
info := sym.info as table.Struct
|
||||||
if info.is_ref_only && !field.typ.is_ptr() {
|
if info.is_ref_only && !field.typ.is_ptr() {
|
||||||
c.error('`$sym.name` type can only be used as a reference: `&$sym.name`', field.pos)
|
c.error('`$sym.name` type can only be used as a reference: `&$sym.name`',
|
||||||
|
field.pos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if field.has_default_expr {
|
if field.has_default_expr {
|
||||||
|
@ -317,8 +319,8 @@ pub fn (mut c Checker) struct_decl(decl ast.StructDecl) {
|
||||||
if !c.check_types(field_expr_type, field.typ) {
|
if !c.check_types(field_expr_type, field.typ) {
|
||||||
field_expr_type_sym := c.table.get_type_symbol(field_expr_type)
|
field_expr_type_sym := c.table.get_type_symbol(field_expr_type)
|
||||||
field_type_sym := c.table.get_type_symbol(field.typ)
|
field_type_sym := c.table.get_type_symbol(field.typ)
|
||||||
c.error('default expression for field `$field.name` ' + 'has type `$field_expr_type_sym.name`, but should be `$field_type_sym.name`',
|
c.error('default expression for field `$field.name` ' +
|
||||||
field.default_expr.position())
|
'has type `$field_expr_type_sym.name`, but should be `$field_type_sym.name`', field.default_expr.position())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -394,7 +396,8 @@ pub fn (mut c Checker) struct_init(mut struct_init ast.StructInit) table.Type {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if field_name in inited_fields {
|
if field_name in inited_fields {
|
||||||
c.error('duplicate field name in struct literal: `$field_name`', field.pos)
|
c.error('duplicate field name in struct literal: `$field_name`',
|
||||||
|
field.pos)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -512,7 +515,8 @@ pub fn (mut c Checker) infix_expr(mut infix_expr ast.InfixExpr) table.Type {
|
||||||
pos := if left_type == promoted_type { left_pos } else { right_pos }
|
pos := if left_type == promoted_type { left_pos } else { right_pos }
|
||||||
name := if left_type == promoted_type { left.name } else { right.name }
|
name := if left_type == promoted_type { left.name } else { right.name }
|
||||||
if infix_expr.op == .mod {
|
if infix_expr.op == .mod {
|
||||||
c.error('float modulo not allowed, use math.fmod() instead', pos)
|
c.error('float modulo not allowed, use math.fmod() instead',
|
||||||
|
pos)
|
||||||
} else {
|
} else {
|
||||||
c.error('$side type of `$infix_expr.op.str()` cannot be non-integer type $name',
|
c.error('$side type of `$infix_expr.op.str()` cannot be non-integer type $name',
|
||||||
pos)
|
pos)
|
||||||
|
@ -520,8 +524,10 @@ pub fn (mut c Checker) infix_expr(mut infix_expr ast.InfixExpr) table.Type {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if infix_expr.op in [.div, .mod] {
|
if infix_expr.op in [.div, .mod] {
|
||||||
if (infix_expr.right is ast.IntegerLiteral && infix_expr.right.str() ==
|
if (infix_expr.right is ast.IntegerLiteral &&
|
||||||
'0') || (infix_expr.right is ast.FloatLiteral && infix_expr.right.str().f64() == 0.0) {
|
infix_expr.right.str() == '0') ||
|
||||||
|
(infix_expr.right is ast.FloatLiteral &&
|
||||||
|
infix_expr.right.str().f64() == 0.0) {
|
||||||
oper := if infix_expr.op == .div { 'division' } else { 'modulo' }
|
oper := if infix_expr.op == .div { 'division' } else { 'modulo' }
|
||||||
c.error('$oper by zero', right_pos)
|
c.error('$oper by zero', right_pos)
|
||||||
}
|
}
|
||||||
|
@ -594,8 +600,8 @@ pub fn (mut c Checker) infix_expr(mut infix_expr ast.InfixExpr) table.Type {
|
||||||
if left_type == table.bool_type && infix_expr.op !in [.eq, .ne, .logical_or, .and] {
|
if left_type == table.bool_type && infix_expr.op !in [.eq, .ne, .logical_or, .and] {
|
||||||
c.error('bool types only have the following operators defined: `==`, `!=`, `||`, and `&&`',
|
c.error('bool types only have the following operators defined: `==`, `!=`, `||`, and `&&`',
|
||||||
infix_expr.pos)
|
infix_expr.pos)
|
||||||
} else if left_type == table.string_type && infix_expr.op !in [.plus, .eq, .ne, .lt, .gt,
|
} else if left_type == table.string_type &&
|
||||||
.le, .ge] {
|
infix_expr.op !in [.plus, .eq, .ne, .lt, .gt, .le, .ge] {
|
||||||
// TODO broken !in
|
// TODO broken !in
|
||||||
c.error('string types only have the following operators defined: `==`, `!=`, `<`, `>`, `<=`, `>=`, and `+`',
|
c.error('string types only have the following operators defined: `==`, `!=`, `<`, `>`, `<=`, `>=`, and `+`',
|
||||||
infix_expr.pos)
|
infix_expr.pos)
|
||||||
|
@ -698,13 +704,13 @@ fn (mut c Checker) check_map_and_filter(is_map bool, elem_typ table.Type, call_e
|
||||||
ast.AnonFn {
|
ast.AnonFn {
|
||||||
if it.decl.args.len > 1 {
|
if it.decl.args.len > 1 {
|
||||||
c.error('function needs exactly 1 argument', call_expr.pos)
|
c.error('function needs exactly 1 argument', call_expr.pos)
|
||||||
} else if is_map && (it.decl.return_type != elem_typ || it.decl.args[0].typ !=
|
} else if is_map && (it.decl.return_type != elem_typ || it.decl.args[0].typ != elem_typ) {
|
||||||
elem_typ) {
|
|
||||||
c.error('type mismatch, should use `fn(a $elem_sym.name) $elem_sym.name {...}`',
|
c.error('type mismatch, should use `fn(a $elem_sym.name) $elem_sym.name {...}`',
|
||||||
call_expr.pos)
|
call_expr.pos)
|
||||||
} else if !is_map && (it.decl.return_type != table.bool_type || it.decl.args[0].typ !=
|
} else if !is_map && (it.decl.return_type != table.bool_type ||
|
||||||
elem_typ) {
|
it.decl.args[0].typ != elem_typ) {
|
||||||
c.error('type mismatch, should use `fn(a $elem_sym.name) bool {...}`', call_expr.pos)
|
c.error('type mismatch, should use `fn(a $elem_sym.name) bool {...}`',
|
||||||
|
call_expr.pos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast.Ident {
|
ast.Ident {
|
||||||
|
@ -718,8 +724,8 @@ fn (mut c Checker) check_map_and_filter(is_map bool, elem_typ table.Type, call_e
|
||||||
} else if is_map && (func.return_type != elem_typ || func.args[0].typ != elem_typ) {
|
} else if is_map && (func.return_type != elem_typ || func.args[0].typ != elem_typ) {
|
||||||
c.error('type mismatch, should use `fn(a $elem_sym.name) $elem_sym.name {...}`',
|
c.error('type mismatch, should use `fn(a $elem_sym.name) $elem_sym.name {...}`',
|
||||||
call_expr.pos)
|
call_expr.pos)
|
||||||
} else if !is_map && (func.return_type != table.bool_type || func.args[0].typ !=
|
} else if !is_map && (func.return_type != table.bool_type ||
|
||||||
elem_typ) {
|
func.args[0].typ != elem_typ) {
|
||||||
c.error('type mismatch, should use `fn(a $elem_sym.name) bool {...}`',
|
c.error('type mismatch, should use `fn(a $elem_sym.name) bool {...}`',
|
||||||
call_expr.pos)
|
call_expr.pos)
|
||||||
}
|
}
|
||||||
|
@ -735,15 +741,14 @@ pub fn (mut c Checker) call_method(mut call_expr ast.CallExpr) table.Type {
|
||||||
call_expr.left_type = left_type
|
call_expr.left_type = left_type
|
||||||
left_type_sym := c.table.get_type_symbol(c.unwrap_generic(left_type))
|
left_type_sym := c.table.get_type_symbol(c.unwrap_generic(left_type))
|
||||||
method_name := call_expr.name
|
method_name := call_expr.name
|
||||||
|
|
||||||
if left_type.has_flag(.optional) {
|
if left_type.has_flag(.optional) {
|
||||||
c.error('optional type cannot be called directly', call_expr.left.position())
|
c.error('optional type cannot be called directly', call_expr.left.position())
|
||||||
return table.void_type
|
return table.void_type
|
||||||
}
|
}
|
||||||
// TODO: remove this for actual methods, use only for compiler magic
|
// TODO: remove this for actual methods, use only for compiler magic
|
||||||
// FIXME: Argument count != 1 will break these
|
// FIXME: Argument count != 1 will break these
|
||||||
if left_type_sym.kind == .array && method_name in ['filter', 'clone', 'repeat', 'reverse',
|
if left_type_sym.kind == .array &&
|
||||||
'map', 'slice'] {
|
method_name in ['filter', 'clone', 'repeat', 'reverse', 'map', 'slice'] {
|
||||||
mut elem_typ := table.void_type
|
mut elem_typ := table.void_type
|
||||||
if method_name in ['filter', 'map'] {
|
if method_name in ['filter', 'map'] {
|
||||||
array_info := left_type_sym.info as table.Array
|
array_info := left_type_sym.info as table.Array
|
||||||
|
@ -796,20 +801,22 @@ pub fn (mut c Checker) call_method(mut call_expr ast.CallExpr) table.Type {
|
||||||
if arg_sym.kind == .array {
|
if arg_sym.kind == .array {
|
||||||
info := arg_sym.info as table.Array
|
info := arg_sym.info as table.Array
|
||||||
sym := c.table.get_type_symbol(info.elem_type)
|
sym := c.table.get_type_symbol(info.elem_type)
|
||||||
if sym.kind != elem_sym.kind && ((elem_sym.kind == .int && sym.kind != .any_int) ||
|
if sym.kind != elem_sym.kind &&
|
||||||
|
((elem_sym.kind == .int && sym.kind != .any_int) ||
|
||||||
(elem_sym.kind == .f64 && sym.kind != .any_float)) {
|
(elem_sym.kind == .f64 && sym.kind != .any_float)) {
|
||||||
c.error('type mismatch, should use `$elem_sym.name[]`', arg_expr.position())
|
c.error('type mismatch, should use `$elem_sym.name[]`', arg_expr.position())
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if arg_sym.kind != elem_sym.kind && ((elem_sym.kind == .int && arg_sym.kind !=
|
if arg_sym.kind != elem_sym.kind &&
|
||||||
.any_int) || (elem_sym.kind == .f64 && arg_sym.kind != .any_float)) {
|
((elem_sym.kind == .int && arg_sym.kind != .any_int) ||
|
||||||
|
(elem_sym.kind == .f64 && arg_sym.kind != .any_float)) {
|
||||||
c.error('type mismatch, should use `$elem_sym.name`', arg_expr.position())
|
c.error('type mismatch, should use `$elem_sym.name`', arg_expr.position())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if method := c.table.type_find_method(left_type_sym, method_name) {
|
if method := c.table.type_find_method(left_type_sym, method_name) {
|
||||||
if !method.is_pub && !c.is_builtin_mod && !c.pref.is_test && left_type_sym.mod != c.mod &&
|
if !method.is_pub && !c.is_builtin_mod && !c.pref.is_test &&
|
||||||
left_type_sym.mod != '' { // method.mod != c.mod {
|
left_type_sym.mod != c.mod && left_type_sym.mod != '' { // method.mod != c.mod {
|
||||||
// If a private method is called outside of the module
|
// If a private method is called outside of the module
|
||||||
// its receiver type is defined in, show an error.
|
// its receiver type is defined in, show an error.
|
||||||
// println('warn $method_name lef.mod=$left_type_sym.mod c.mod=$c.mod')
|
// println('warn $method_name lef.mod=$left_type_sym.mod c.mod=$c.mod')
|
||||||
|
@ -819,8 +826,8 @@ pub fn (mut c Checker) call_method(mut call_expr ast.CallExpr) table.Type {
|
||||||
c.fail_if_immutable(call_expr.left)
|
c.fail_if_immutable(call_expr.left)
|
||||||
// call_expr.is_mut = true
|
// call_expr.is_mut = true
|
||||||
}
|
}
|
||||||
if method.return_type == table.void_type && method.ctdefine.len > 0 && method.ctdefine !in
|
if method.return_type == table.void_type &&
|
||||||
c.pref.compile_defines {
|
method.ctdefine.len > 0 && method.ctdefine !in c.pref.compile_defines {
|
||||||
call_expr.should_be_skipped = true
|
call_expr.should_be_skipped = true
|
||||||
}
|
}
|
||||||
nr_args := if method.args.len == 0 { 0 } else { method.args.len - 1 }
|
nr_args := if method.args.len == 0 { 0 } else { method.args.len - 1 }
|
||||||
|
@ -845,9 +852,9 @@ pub fn (mut c Checker) call_method(mut call_expr ast.CallExpr) table.Type {
|
||||||
c.expected_type = exp_arg_typ
|
c.expected_type = exp_arg_typ
|
||||||
got_arg_typ := c.expr(arg.expr)
|
got_arg_typ := c.expr(arg.expr)
|
||||||
call_expr.args[i].typ = got_arg_typ
|
call_expr.args[i].typ = got_arg_typ
|
||||||
if method.is_variadic && got_arg_typ.has_flag(.variadic) && call_expr.args.len -
|
if method.is_variadic && got_arg_typ.has_flag(.variadic) && call_expr.args.len - 1 > i {
|
||||||
1 > i {
|
c.error('when forwarding a varg variable, it must be the final argument',
|
||||||
c.error('when forwarding a varg variable, it must be the final argument', call_expr.pos)
|
call_expr.pos)
|
||||||
}
|
}
|
||||||
if exp_arg_sym.kind == .interface_ {
|
if exp_arg_sym.kind == .interface_ {
|
||||||
c.type_implements(got_arg_typ, exp_arg_typ, arg.expr.position())
|
c.type_implements(got_arg_typ, exp_arg_typ, arg.expr.position())
|
||||||
|
@ -857,7 +864,7 @@ pub fn (mut c Checker) call_method(mut call_expr ast.CallExpr) table.Type {
|
||||||
got_arg_sym := c.table.get_type_symbol(got_arg_typ)
|
got_arg_sym := c.table.get_type_symbol(got_arg_typ)
|
||||||
// str method, allow type with str method if fn arg is string
|
// str method, allow type with str method if fn arg is string
|
||||||
// if exp_arg_sym.kind == .string && got_arg_sym.has_method('str') {
|
// if exp_arg_sym.kind == .string && got_arg_sym.has_method('str') {
|
||||||
// continue
|
// continue
|
||||||
// }
|
// }
|
||||||
if got_arg_typ != table.void_type {
|
if got_arg_typ != table.void_type {
|
||||||
c.error('cannot use type `$got_arg_sym.str()` as type `$exp_arg_sym.str()` in argument ${i+1} to `${left_type_sym.name}.$method_name`',
|
c.error('cannot use type `$got_arg_sym.str()` as type `$exp_arg_sym.str()` in argument ${i+1} to `${left_type_sym.name}.$method_name`',
|
||||||
|
@ -1003,7 +1010,8 @@ pub fn (mut c Checker) call_fn(mut call_expr ast.CallExpr) table.Type {
|
||||||
c.warn('function `$f.name` has been deprecated', call_expr.pos)
|
c.warn('function `$f.name` has been deprecated', call_expr.pos)
|
||||||
}
|
}
|
||||||
call_expr.return_type = f.return_type
|
call_expr.return_type = f.return_type
|
||||||
if f.return_type == table.void_type && f.ctdefine.len > 0 && f.ctdefine !in c.pref.compile_defines {
|
if f.return_type == table.void_type &&
|
||||||
|
f.ctdefine.len > 0 && f.ctdefine !in c.pref.compile_defines {
|
||||||
call_expr.should_be_skipped = true
|
call_expr.should_be_skipped = true
|
||||||
}
|
}
|
||||||
if f.language != .v || call_expr.language != .v {
|
if f.language != .v || call_expr.language != .v {
|
||||||
|
@ -1058,7 +1066,8 @@ pub fn (mut c Checker) call_fn(mut call_expr ast.CallExpr) table.Type {
|
||||||
typ_sym := c.table.get_type_symbol(typ)
|
typ_sym := c.table.get_type_symbol(typ)
|
||||||
arg_typ_sym := c.table.get_type_symbol(arg.typ)
|
arg_typ_sym := c.table.get_type_symbol(arg.typ)
|
||||||
if f.is_variadic && typ.has_flag(.variadic) && call_expr.args.len - 1 > i {
|
if f.is_variadic && typ.has_flag(.variadic) && call_expr.args.len - 1 > i {
|
||||||
c.error('when forwarding a varg variable, it must be the final argument', call_expr.pos)
|
c.error('when forwarding a varg variable, it must be the final argument',
|
||||||
|
call_expr.pos)
|
||||||
}
|
}
|
||||||
if arg.is_mut && !call_arg.is_mut {
|
if arg.is_mut && !call_arg.is_mut {
|
||||||
c.error('`$arg.name` is a mutable argument, you need to provide `mut`: `${call_expr.name}(mut ...)`',
|
c.error('`$arg.name` is a mutable argument, you need to provide `mut`: `${call_expr.name}(mut ...)`',
|
||||||
|
@ -1260,7 +1269,7 @@ pub fn (mut c Checker) return_stmt(mut return_stmt ast.Return) {
|
||||||
return_stmt.pos)
|
return_stmt.pos)
|
||||||
return
|
return
|
||||||
} else if return_stmt.exprs.len == 0 && !(c.expected_type == table.void_type ||
|
} else if return_stmt.exprs.len == 0 && !(c.expected_type == table.void_type ||
|
||||||
c.table.get_type_symbol(c.expected_type).kind == .void) {
|
c.table.get_type_symbol(c.expected_type).kind == .void) {
|
||||||
c.error('too few arguments to return', return_stmt.pos)
|
c.error('too few arguments to return', return_stmt.pos)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -1359,7 +1368,9 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) {
|
||||||
mut right_len := assign_stmt.right.len
|
mut right_len := assign_stmt.right.len
|
||||||
if right_first is ast.CallExpr || right_first is ast.IfExpr || right_first is ast.MatchExpr {
|
if right_first is ast.CallExpr || right_first is ast.IfExpr || right_first is ast.MatchExpr {
|
||||||
right_type0 := c.expr(right_first)
|
right_type0 := c.expr(right_first)
|
||||||
assign_stmt.right_types = [c.check_expr_opt_call(right_first, right_type0)]
|
assign_stmt.right_types = [
|
||||||
|
c.check_expr_opt_call(right_first, right_type0)
|
||||||
|
]
|
||||||
right_type_sym0 := c.table.get_type_symbol(right_type0)
|
right_type_sym0 := c.table.get_type_symbol(right_type0)
|
||||||
if right_type_sym0.kind == .multi_return {
|
if right_type_sym0.kind == .multi_return {
|
||||||
assign_stmt.right_types = right_type_sym0.mr_info().types
|
assign_stmt.right_types = right_type_sym0.mr_info().types
|
||||||
|
@ -1444,7 +1455,8 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) {
|
||||||
if !left_sym.is_number() && left_type != table.string_type && !left_sym.is_pointer() {
|
if !left_sym.is_number() && left_type != table.string_type && !left_sym.is_pointer() {
|
||||||
c.error('operator += not defined on left operand type `$left_sym.name`',
|
c.error('operator += not defined on left operand type `$left_sym.name`',
|
||||||
left.position())
|
left.position())
|
||||||
} else if !right_sym.is_number() && right_type != table.string_type && !right_sym.is_pointer() {
|
} else if !right_sym.is_number() && right_type != table.string_type &&
|
||||||
|
!right_sym.is_pointer() {
|
||||||
c.error('operator += not defined on right operand type `$right_sym.name`',
|
c.error('operator += not defined on right operand type `$right_sym.name`',
|
||||||
right.position())
|
right.position())
|
||||||
}
|
}
|
||||||
|
@ -1523,7 +1535,8 @@ pub fn (mut c Checker) array_init(mut array_init ast.ArrayInit) table.Type {
|
||||||
if array_init.exprs.len == 0 {
|
if array_init.exprs.len == 0 {
|
||||||
type_sym := c.table.get_type_symbol(c.expected_type)
|
type_sym := c.table.get_type_symbol(c.expected_type)
|
||||||
if type_sym.kind != .array {
|
if type_sym.kind != .array {
|
||||||
c.error('array_init: no type specified (maybe: `[]Type{}` instead of `[]`)', array_init.pos)
|
c.error('array_init: no type specified (maybe: `[]Type{}` instead of `[]`)',
|
||||||
|
array_init.pos)
|
||||||
return table.void_type
|
return table.void_type
|
||||||
}
|
}
|
||||||
// TODO: seperate errors once bug is fixed with `x := if expr { ... } else { ... }`
|
// TODO: seperate errors once bug is fixed with `x := if expr { ... } else { ... }`
|
||||||
|
@ -1581,7 +1594,8 @@ pub fn (mut c Checker) array_init(mut array_init ast.ArrayInit) table.Type {
|
||||||
array_init.interface_types = interface_types
|
array_init.interface_types = interface_types
|
||||||
}
|
}
|
||||||
if array_init.is_fixed {
|
if array_init.is_fixed {
|
||||||
idx := c.table.find_or_register_array_fixed(elem_type, array_init.exprs.len, 1)
|
idx := c.table.find_or_register_array_fixed(elem_type, array_init.exprs.len,
|
||||||
|
1)
|
||||||
array_init.typ = table.new_type(idx)
|
array_init.typ = table.new_type(idx)
|
||||||
} else {
|
} else {
|
||||||
sym := c.table.get_type_symbol(elem_type)
|
sym := c.table.get_type_symbol(elem_type)
|
||||||
|
@ -1589,7 +1603,8 @@ pub fn (mut c Checker) array_init(mut array_init ast.ArrayInit) table.Type {
|
||||||
array_init.typ = table.new_type(idx)
|
array_init.typ = table.new_type(idx)
|
||||||
}
|
}
|
||||||
array_init.elem_type = elem_type
|
array_init.elem_type = elem_type
|
||||||
} else if array_init.is_fixed && array_init.exprs.len == 1 && array_init.elem_type != table.void_type {
|
} else if array_init.is_fixed && array_init.exprs.len == 1 &&
|
||||||
|
array_init.elem_type != table.void_type {
|
||||||
// [50]byte
|
// [50]byte
|
||||||
mut fixed_size := 1
|
mut fixed_size := 1
|
||||||
match array_init.exprs[0] {
|
match array_init.exprs[0] {
|
||||||
|
@ -1604,8 +1619,7 @@ pub fn (mut c Checker) array_init(mut array_init ast.ArrayInit) table.Type {
|
||||||
// scope.find(it.name) or {
|
// scope.find(it.name) or {
|
||||||
// c.error('undefined ident: `$it.name`', array_init.pos)
|
// c.error('undefined ident: `$it.name`', array_init.pos)
|
||||||
// }
|
// }
|
||||||
mut full_const_name := if it.mod == 'main' { it.name } else { it.mod + '.' +
|
mut full_const_name := if it.mod == 'main' { it.name } else { it.mod + '.' + it.name }
|
||||||
it.name }
|
|
||||||
if obj := c.file.global_scope.find_const(full_const_name) {
|
if obj := c.file.global_scope.find_const(full_const_name) {
|
||||||
if cint := const_int_value(obj) {
|
if cint := const_int_value(obj) {
|
||||||
fixed_size = cint
|
fixed_size = cint
|
||||||
|
@ -1619,7 +1633,8 @@ pub fn (mut c Checker) array_init(mut array_init ast.ArrayInit) table.Type {
|
||||||
c.error('expecting `int` for fixed size', array_init.pos)
|
c.error('expecting `int` for fixed size', array_init.pos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
idx := c.table.find_or_register_array_fixed(array_init.elem_type, fixed_size, 1)
|
idx := c.table.find_or_register_array_fixed(array_init.elem_type, fixed_size,
|
||||||
|
1)
|
||||||
array_type := table.new_type(idx)
|
array_type := table.new_type(idx)
|
||||||
array_init.typ = array_type
|
array_init.typ = array_type
|
||||||
}
|
}
|
||||||
|
@ -1771,7 +1786,8 @@ fn (mut c Checker) stmt(node ast.Stmt) {
|
||||||
value_type := c.table.value_type(typ)
|
value_type := c.table.value_type(typ)
|
||||||
if value_type == table.void_type || typ.has_flag(.optional) {
|
if value_type == table.void_type || typ.has_flag(.optional) {
|
||||||
if typ != table.void_type {
|
if typ != table.void_type {
|
||||||
c.error('for in: cannot index `${c.table.type_to_str(typ)}`', it.cond.position())
|
c.error('for in: cannot index `${c.table.type_to_str(typ)}`',
|
||||||
|
it.cond.position())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
it.cond_type = typ
|
it.cond_type = typ
|
||||||
|
@ -1882,7 +1898,11 @@ pub fn (mut c Checker) expr(node ast.Expr) table.Type {
|
||||||
c.cur_fn = &node.decl
|
c.cur_fn = &node.decl
|
||||||
c.stmts(node.decl.stmts)
|
c.stmts(node.decl.stmts)
|
||||||
c.cur_fn = keep_fn
|
c.cur_fn = keep_fn
|
||||||
return if node.is_called { node.decl.return_type } else { node.typ }
|
return if node.is_called {
|
||||||
|
node.decl.return_type
|
||||||
|
} else {
|
||||||
|
node.typ
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ast.ArrayInit {
|
ast.ArrayInit {
|
||||||
return c.array_init(mut node)
|
return c.array_init(mut node)
|
||||||
|
@ -1925,10 +1945,11 @@ pub fn (mut c Checker) expr(node ast.Expr) table.Type {
|
||||||
ast.CastExpr {
|
ast.CastExpr {
|
||||||
node.expr_type = c.expr(node.expr)
|
node.expr_type = c.expr(node.expr)
|
||||||
sym := c.table.get_type_symbol(node.expr_type)
|
sym := c.table.get_type_symbol(node.expr_type)
|
||||||
if node.typ == table.string_type && !(sym.kind in [.byte, .byteptr] || (sym.kind ==
|
if node.typ == table.string_type && !(sym.kind in [.byte, .byteptr] ||
|
||||||
.array && sym.name == 'array_byte')) {
|
(sym.kind == .array && sym.name == 'array_byte')) {
|
||||||
type_name := c.table.type_to_str(node.expr_type)
|
type_name := c.table.type_to_str(node.expr_type)
|
||||||
c.error('cannot cast type `$type_name` to string, use `x.str()` instead', node.pos)
|
c.error('cannot cast type `$type_name` to string, use `x.str()` instead',
|
||||||
|
node.pos)
|
||||||
}
|
}
|
||||||
if node.expr_type == table.string_type {
|
if node.expr_type == table.string_type {
|
||||||
mut error_msg := 'cannot cast a string'
|
mut error_msg := 'cannot cast a string'
|
||||||
|
@ -1957,7 +1978,10 @@ pub fn (mut c Checker) expr(node ast.Expr) table.Type {
|
||||||
if node.is_vweb {
|
if node.is_vweb {
|
||||||
// TODO assoc parser bug
|
// TODO assoc parser bug
|
||||||
pref := *c.pref
|
pref := *c.pref
|
||||||
pref2 := {pref|is_vweb: true}
|
pref2 := {
|
||||||
|
pref |
|
||||||
|
is_vweb: true
|
||||||
|
}
|
||||||
mut c2 := new_checker(c.table, pref2)
|
mut c2 := new_checker(c.table, pref2)
|
||||||
c2.check(node.vweb_tmpl)
|
c2.check(node.vweb_tmpl)
|
||||||
c.warnings << c2.warnings
|
c.warnings << c2.warnings
|
||||||
|
@ -2124,7 +2148,8 @@ pub fn (mut c Checker) ident(mut ident ast.Ident) table.Type {
|
||||||
// incase var was not marked as used yet (vweb tmpl)
|
// incase var was not marked as used yet (vweb tmpl)
|
||||||
obj.is_used = true
|
obj.is_used = true
|
||||||
if ident.pos.pos < obj.pos.pos {
|
if ident.pos.pos < obj.pos.pos {
|
||||||
c.error('undefined variable `$ident.name` (used before declaration)', ident.pos)
|
c.error('undefined variable `$ident.name` (used before declaration)',
|
||||||
|
ident.pos)
|
||||||
}
|
}
|
||||||
mut typ := obj.typ
|
mut typ := obj.typ
|
||||||
if typ == 0 {
|
if typ == 0 {
|
||||||
|
@ -2185,8 +2210,8 @@ pub fn (mut c Checker) ident(mut ident ast.Ident) table.Type {
|
||||||
}
|
}
|
||||||
// Non-anon-function object (not a call), e.g. `onclick(my_click)`
|
// Non-anon-function object (not a call), e.g. `onclick(my_click)`
|
||||||
if func := c.table.find_fn(name) {
|
if func := c.table.find_fn(name) {
|
||||||
fn_type := table.new_type(c.table.find_or_register_fn_type(ident.mod, func, false,
|
fn_type := table.new_type(c.table.find_or_register_fn_type(ident.mod, func,
|
||||||
true))
|
false, true))
|
||||||
ident.name = name
|
ident.name = name
|
||||||
ident.kind = .function
|
ident.kind = .function
|
||||||
ident.info = ast.IdentFn{
|
ident.info = ast.IdentFn{
|
||||||
|
@ -2247,7 +2272,7 @@ pub fn (mut c Checker) match_expr(mut node ast.MatchExpr) table.Type {
|
||||||
if node.is_sum_type || node.is_interface {
|
if node.is_sum_type || node.is_interface {
|
||||||
ok := if cond_type_sym.kind == .sum_type {
|
ok := if cond_type_sym.kind == .sum_type {
|
||||||
// TODO verify sum type
|
// TODO verify sum type
|
||||||
//true // c.check_types(typ, cond_type)
|
// true // c.check_types(typ, cond_type)
|
||||||
info := cond_type_sym.info as table.SumType
|
info := cond_type_sym.info as table.SumType
|
||||||
typ in info.variants
|
typ in info.variants
|
||||||
} else {
|
} else {
|
||||||
|
@ -2319,13 +2344,13 @@ fn (mut c Checker) match_exprs(mut node ast.MatchExpr, type_sym table.TypeSymbol
|
||||||
v_str := c.table.type_to_str(v)
|
v_str := c.table.type_to_str(v)
|
||||||
if v_str !in branch_exprs {
|
if v_str !in branch_exprs {
|
||||||
is_exhaustive = false
|
is_exhaustive = false
|
||||||
unhandled << '`$v_str`'
|
unhandled << ' `$v_str`'
|
||||||
}
|
}
|
||||||
} }
|
} }
|
||||||
table.Enum { for v in it.vals {
|
table.Enum { for v in it.vals {
|
||||||
if v !in branch_exprs {
|
if v !in branch_exprs {
|
||||||
is_exhaustive = false
|
is_exhaustive = false
|
||||||
unhandled << '`.$v`'
|
unhandled << ' `.$v`'
|
||||||
}
|
}
|
||||||
} }
|
} }
|
||||||
else { is_exhaustive = false }
|
else { is_exhaustive = false }
|
||||||
|
@ -2449,7 +2474,8 @@ pub fn (mut c Checker) postfix_expr(node ast.PostfixExpr) table.Type {
|
||||||
// if !typ.is_number() {
|
// if !typ.is_number() {
|
||||||
if !typ_sym.is_number() {
|
if !typ_sym.is_number() {
|
||||||
println(typ_sym.kind.str())
|
println(typ_sym.kind.str())
|
||||||
c.error('invalid operation: $node.op.str() (non-numeric type `$typ_sym.name`)', node.pos)
|
c.error('invalid operation: $node.op.str() (non-numeric type `$typ_sym.name`)',
|
||||||
|
node.pos)
|
||||||
} else {
|
} else {
|
||||||
c.fail_if_immutable(node.expr)
|
c.fail_if_immutable(node.expr)
|
||||||
}
|
}
|
||||||
|
@ -2654,7 +2680,7 @@ fn (mut c Checker) sql_expr(node ast.SqlExpr) table.Type {
|
||||||
return node.typ
|
return node.typ
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut c Checker) sql_insert_expr(node ast.SqlStmt ) table.Type {
|
fn (mut c Checker) sql_insert_expr(node ast.SqlStmt) table.Type {
|
||||||
c.expr(node.db_expr)
|
c.expr(node.db_expr)
|
||||||
return table.void_type
|
return table.void_type
|
||||||
}
|
}
|
||||||
|
@ -2695,8 +2721,8 @@ fn (mut c Checker) fn_decl(it ast.FnDecl) {
|
||||||
}
|
}
|
||||||
sym.methods.delete(idx)
|
sym.methods.delete(idx)
|
||||||
//
|
//
|
||||||
c.error('cannot define new methods on non-local `$sym.name` (' + 'current module is `$c.mod`, `$sym.name` is from `$sym.mod`)',
|
c.error('cannot define new methods on non-local `$sym.name` (' +
|
||||||
it.pos)
|
'current module is `$c.mod`, `$sym.name` is from `$sym.mod`)', it.pos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if it.language == .v {
|
if it.language == .v {
|
||||||
|
@ -2711,7 +2737,8 @@ fn (mut c Checker) fn_decl(it ast.FnDecl) {
|
||||||
c.expected_type = table.void_type
|
c.expected_type = table.void_type
|
||||||
c.cur_fn = &it
|
c.cur_fn = &it
|
||||||
c.stmts(it.stmts)
|
c.stmts(it.stmts)
|
||||||
if it.language == .v && !it.no_body && it.return_type != table.void_type && !c.returns &&
|
if it.language == .v && !it.no_body &&
|
||||||
|
it.return_type != table.void_type && !c.returns &&
|
||||||
it.name !in ['panic', 'exit'] {
|
it.name !in ['panic', 'exit'] {
|
||||||
c.error('missing return at end of function `$it.name`', it.pos)
|
c.error('missing return at end of function `$it.name`', it.pos)
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,33 +14,9 @@ import v.depgraph
|
||||||
// NB: keywords after 'new' are reserved in C++
|
// NB: keywords after 'new' are reserved in C++
|
||||||
const (
|
const (
|
||||||
c_reserved = ['delete', 'exit', 'unix', 'error', 'calloc', 'malloc', 'free', 'panic', 'auto',
|
c_reserved = ['delete', 'exit', 'unix', 'error', 'calloc', 'malloc', 'free', 'panic', 'auto',
|
||||||
'char',
|
'char', 'default', 'do', 'double', 'extern', 'float', 'inline', 'int', 'long', 'register',
|
||||||
'default',
|
'restrict', 'short', 'signed', 'sizeof', 'static', 'switch', 'typedef', 'union', 'unsigned',
|
||||||
'do',
|
'void', 'volatile', 'while', 'new', 'namespace', 'class', 'typename']
|
||||||
'double',
|
|
||||||
'extern',
|
|
||||||
'float',
|
|
||||||
'inline',
|
|
||||||
'int',
|
|
||||||
'long',
|
|
||||||
'register',
|
|
||||||
'restrict',
|
|
||||||
'short',
|
|
||||||
'signed',
|
|
||||||
'sizeof',
|
|
||||||
'static',
|
|
||||||
'switch',
|
|
||||||
'typedef',
|
|
||||||
'union',
|
|
||||||
'unsigned',
|
|
||||||
'void',
|
|
||||||
'volatile',
|
|
||||||
'while',
|
|
||||||
'new',
|
|
||||||
'namespace',
|
|
||||||
'class',
|
|
||||||
'typename'
|
|
||||||
]
|
|
||||||
// same order as in token.Kind
|
// same order as in token.Kind
|
||||||
cmp_str = ['eq', 'ne', 'gt', 'lt', 'ge', 'le']
|
cmp_str = ['eq', 'ne', 'gt', 'lt', 'ge', 'le']
|
||||||
// when operands are switched
|
// when operands are switched
|
||||||
|
@ -436,8 +412,7 @@ typedef struct {
|
||||||
.alias {
|
.alias {
|
||||||
parent := &g.table.types[typ.parent_idx]
|
parent := &g.table.types[typ.parent_idx]
|
||||||
styp := typ.name.replace('.', '__')
|
styp := typ.name.replace('.', '__')
|
||||||
is_c_parent := parent.name.len > 2 && parent.name[0] == `C` && parent.name[1] ==
|
is_c_parent := parent.name.len > 2 && parent.name[0] == `C` && parent.name[1] == `.`
|
||||||
`.`
|
|
||||||
parent_styp := if is_c_parent { 'struct ' + parent.name[2..].replace('.', '__') } else { parent.name.replace('.',
|
parent_styp := if is_c_parent { 'struct ' + parent.name[2..].replace('.', '__') } else { parent.name.replace('.',
|
||||||
'__') }
|
'__') }
|
||||||
g.type_definitions.writeln('typedef $parent_styp $styp;')
|
g.type_definitions.writeln('typedef $parent_styp $styp;')
|
||||||
|
@ -662,7 +637,7 @@ fn (mut g Gen) stmt(node ast.Stmt) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast.FnDecl {
|
ast.FnDecl {
|
||||||
//g.tmp_count = 0 TODO
|
// g.tmp_count = 0 TODO
|
||||||
mut skip := false
|
mut skip := false
|
||||||
pos := g.out.buf.len
|
pos := g.out.buf.len
|
||||||
if g.pref.build_mode == .build_module {
|
if g.pref.build_mode == .build_module {
|
||||||
|
@ -684,13 +659,15 @@ fn (mut g Gen) stmt(node ast.Stmt) {
|
||||||
// just remember `it`; main code will be generated in finish()
|
// just remember `it`; main code will be generated in finish()
|
||||||
g.fn_main = node
|
g.fn_main = node
|
||||||
} else {
|
} else {
|
||||||
if node.name == 'backtrace' || node.name == 'backtrace_symbols' || node.name ==
|
if node.name == 'backtrace' ||
|
||||||
'backtrace_symbols_fd' {
|
node.name == 'backtrace_symbols' ||
|
||||||
|
node.name == 'backtrace_symbols_fd' {
|
||||||
g.write('\n#ifndef __cplusplus\n')
|
g.write('\n#ifndef __cplusplus\n')
|
||||||
}
|
}
|
||||||
g.gen_fn_decl(node)
|
g.gen_fn_decl(node)
|
||||||
if node.name == 'backtrace' || node.name == 'backtrace_symbols' || node.name ==
|
if node.name == 'backtrace' ||
|
||||||
'backtrace_symbols_fd' {
|
node.name == 'backtrace_symbols' ||
|
||||||
|
node.name == 'backtrace_symbols_fd' {
|
||||||
g.write('\n#endif\n')
|
g.write('\n#endif\n')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -770,9 +747,9 @@ fn (mut g Gen) stmt(node ast.Stmt) {
|
||||||
g.write_autofree_stmts_when_needed(node)
|
g.write_autofree_stmts_when_needed(node)
|
||||||
g.return_statement(node)
|
g.return_statement(node)
|
||||||
}
|
}
|
||||||
ast.SqlStmt{
|
ast.SqlStmt {
|
||||||
g.sql_insert_expr(node)
|
g.sql_insert_expr(node)
|
||||||
}
|
}
|
||||||
ast.StructDecl {
|
ast.StructDecl {
|
||||||
name := if node.language == .c { node.name.replace('.', '__') } else { c_name(node.name) }
|
name := if node.language == .c { node.name.replace('.', '__') } else { c_name(node.name) }
|
||||||
// g.writeln('typedef struct {')
|
// g.writeln('typedef struct {')
|
||||||
|
@ -915,9 +892,8 @@ fn (mut g Gen) expr_with_cast(expr ast.Expr, got_type, expected_type table.Type)
|
||||||
got_is_ptr := got_type.is_ptr()
|
got_is_ptr := got_type.is_ptr()
|
||||||
expected_is_ptr := expected_type.is_ptr()
|
expected_is_ptr := expected_type.is_ptr()
|
||||||
neither_void := table.voidptr_type !in [got_type, expected_type]
|
neither_void := table.voidptr_type !in [got_type, expected_type]
|
||||||
if got_is_ptr && !expected_is_ptr && neither_void && expected_sym.kind !in [.interface_,
|
if got_is_ptr && !expected_is_ptr && neither_void &&
|
||||||
.placeholder
|
expected_sym.kind !in [.interface_, .placeholder] {
|
||||||
] {
|
|
||||||
got_deref_type := got_type.deref()
|
got_deref_type := got_type.deref()
|
||||||
deref_sym := g.table.get_type_symbol(got_deref_type)
|
deref_sym := g.table.get_type_symbol(got_deref_type)
|
||||||
deref_will_match := expected_type in [got_type, got_deref_type, deref_sym.parent_idx]
|
deref_will_match := expected_type in [got_type, got_deref_type, deref_sym.parent_idx]
|
||||||
|
@ -1594,9 +1570,6 @@ fn (mut g Gen) expr(node ast.Expr) {
|
||||||
ast.SqlExpr {
|
ast.SqlExpr {
|
||||||
g.sql_select_expr(node)
|
g.sql_select_expr(node)
|
||||||
}
|
}
|
||||||
//ast.SqlInsertExpr {
|
|
||||||
//g.sql_insert_expr(node)
|
|
||||||
//}
|
|
||||||
ast.StringLiteral {
|
ast.StringLiteral {
|
||||||
if node.is_raw {
|
if node.is_raw {
|
||||||
escaped_val := node.val.replace_each(['"', '\\"', '\\', '\\\\'])
|
escaped_val := node.val.replace_each(['"', '\\"', '\\', '\\\\'])
|
||||||
|
@ -1865,8 +1838,8 @@ fn (mut g Gen) infix_expr(node ast.InfixExpr) {
|
||||||
}
|
}
|
||||||
} else if unaliased_left.idx() in [table.u32_type_idx, table.u64_type_idx] && unaliased_right.is_signed() &&
|
} else if unaliased_left.idx() in [table.u32_type_idx, table.u64_type_idx] && unaliased_right.is_signed() &&
|
||||||
node.op in [.eq, .ne, .gt, .lt, .ge, .le] {
|
node.op in [.eq, .ne, .gt, .lt, .ge, .le] {
|
||||||
bitsize := if unaliased_left.idx() == table.u32_type_idx && unaliased_right.idx() !=
|
bitsize := if unaliased_left.idx() == table.u32_type_idx &&
|
||||||
table.i64_type_idx { 32 } else { 64 }
|
unaliased_right.idx() != table.i64_type_idx { 32 } else { 64 }
|
||||||
g.write('_us${bitsize}_${cmp_str[int(node.op)-int(token.Kind.eq)]}(')
|
g.write('_us${bitsize}_${cmp_str[int(node.op)-int(token.Kind.eq)]}(')
|
||||||
g.expr(node.left)
|
g.expr(node.left)
|
||||||
g.write(',')
|
g.write(',')
|
||||||
|
@ -1874,8 +1847,8 @@ fn (mut g Gen) infix_expr(node ast.InfixExpr) {
|
||||||
g.write(')')
|
g.write(')')
|
||||||
} else if unaliased_right.idx() in [table.u32_type_idx, table.u64_type_idx] && unaliased_left.is_signed() &&
|
} else if unaliased_right.idx() in [table.u32_type_idx, table.u64_type_idx] && unaliased_left.is_signed() &&
|
||||||
node.op in [.eq, .ne, .gt, .lt, .ge, .le] {
|
node.op in [.eq, .ne, .gt, .lt, .ge, .le] {
|
||||||
bitsize := if unaliased_right.idx() == table.u32_type_idx && unaliased_left.idx() !=
|
bitsize := if unaliased_right.idx() == table.u32_type_idx &&
|
||||||
table.i64_type_idx { 32 } else { 64 }
|
unaliased_left.idx() != table.i64_type_idx { 32 } else { 64 }
|
||||||
g.write('_us${bitsize}_${cmp_rev[int(node.op)-int(token.Kind.eq)]}(')
|
g.write('_us${bitsize}_${cmp_rev[int(node.op)-int(token.Kind.eq)]}(')
|
||||||
g.expr(node.right)
|
g.expr(node.right)
|
||||||
g.write(',')
|
g.write(',')
|
||||||
|
@ -1917,8 +1890,7 @@ fn (mut g Gen) match_expr(node ast.MatchExpr) {
|
||||||
g.writeln('// match 0')
|
g.writeln('// match 0')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
is_expr := (node.is_expr && node.return_type != table.void_type) || g.inside_ternary >
|
is_expr := (node.is_expr && node.return_type != table.void_type) || g.inside_ternary > 0
|
||||||
0
|
|
||||||
if is_expr {
|
if is_expr {
|
||||||
g.inside_ternary++
|
g.inside_ternary++
|
||||||
// g.write('/* EM ret type=${g.typ(node.return_type)} expected_type=${g.typ(node.expected_type)} */')
|
// g.write('/* EM ret type=${g.typ(node.return_type)} expected_type=${g.typ(node.expected_type)} */')
|
||||||
|
@ -2315,7 +2287,6 @@ fn (mut g Gen) return_statement(node ast.Return) {
|
||||||
sym := g.table.get_type_symbol(g.fn_decl.return_type)
|
sym := g.table.get_type_symbol(g.fn_decl.return_type)
|
||||||
fn_return_is_multi := sym.kind == .multi_return
|
fn_return_is_multi := sym.kind == .multi_return
|
||||||
fn_return_is_optional := g.fn_decl.return_type.has_flag(.optional)
|
fn_return_is_optional := g.fn_decl.return_type.has_flag(.optional)
|
||||||
|
|
||||||
if node.exprs.len == 0 {
|
if node.exprs.len == 0 {
|
||||||
if fn_return_is_optional {
|
if fn_return_is_optional {
|
||||||
tmp := g.new_tmp_var()
|
tmp := g.new_tmp_var()
|
||||||
|
@ -2414,8 +2385,8 @@ fn (mut g Gen) return_statement(node ast.Return) {
|
||||||
// normal return
|
// normal return
|
||||||
return_sym := g.table.get_type_symbol(node.types[0])
|
return_sym := g.table.get_type_symbol(node.types[0])
|
||||||
// `return opt_ok(expr)` for functions that expect an optional
|
// `return opt_ok(expr)` for functions that expect an optional
|
||||||
if fn_return_is_optional && !node.types[0].has_flag(.optional) && return_sym.name !=
|
if fn_return_is_optional && !node.types[0].has_flag(.optional) &&
|
||||||
'Option' {
|
return_sym.name != 'Option' {
|
||||||
styp := g.base_type(g.fn_decl.return_type)
|
styp := g.base_type(g.fn_decl.return_type)
|
||||||
opt_type := g.typ(g.fn_decl.return_type)
|
opt_type := g.typ(g.fn_decl.return_type)
|
||||||
// Create a tmp for this option
|
// Create a tmp for this option
|
||||||
|
@ -2597,14 +2568,14 @@ fn (mut g Gen) struct_init(struct_init ast.StructInit) {
|
||||||
}
|
}
|
||||||
// The rest of the fields are zeroed.
|
// The rest of the fields are zeroed.
|
||||||
// `inited_fields` is a list of fields that have been init'ed, they are skipped
|
// `inited_fields` is a list of fields that have been init'ed, they are skipped
|
||||||
//mut nr_fields := 0
|
// mut nr_fields := 0
|
||||||
if sym.kind == .struct_ {
|
if sym.kind == .struct_ {
|
||||||
info := sym.info as table.Struct
|
info := sym.info as table.Struct
|
||||||
if info.is_union && struct_init.fields.len > 1 {
|
if info.is_union && struct_init.fields.len > 1 {
|
||||||
verror('union must not have more than 1 initializer')
|
verror('union must not have more than 1 initializer')
|
||||||
}
|
}
|
||||||
//g.zero_struct_fields(info, inited_fields)
|
// g.zero_struct_fields(info, inited_fields)
|
||||||
//nr_fields = info.fields.len
|
// nr_fields = info.fields.len
|
||||||
for field in info.fields {
|
for field in info.fields {
|
||||||
if field.name in inited_fields {
|
if field.name in inited_fields {
|
||||||
sfield := struct_init.fields[inited_fields[field.name]]
|
sfield := struct_init.fields[inited_fields[field.name]]
|
||||||
|
@ -2639,7 +2610,6 @@ fn (mut g Gen) struct_init(struct_init ast.StructInit) {
|
||||||
g.zero_struct_field(field)
|
g.zero_struct_field(field)
|
||||||
initialized = true
|
initialized = true
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
// if struct_init.fields.len == 0 && info.fields.len == 0 {
|
// if struct_init.fields.len == 0 && info.fields.len == 0 {
|
||||||
if !initialized {
|
if !initialized {
|
||||||
|
@ -2662,9 +2632,8 @@ fn (mut g Gen) zero_struct_field(field table.Field) {
|
||||||
g.writeln(',')
|
g.writeln(',')
|
||||||
}
|
}
|
||||||
|
|
||||||
//fn (mut g Gen) zero_struct_fields(info table.Struct, inited_fields map[string]int) {
|
// fn (mut g Gen) zero_struct_fields(info table.Struct, inited_fields map[string]int) {
|
||||||
//}
|
// }
|
||||||
|
|
||||||
// { user | name: 'new name' }
|
// { user | name: 'new name' }
|
||||||
fn (mut g Gen) assoc(node ast.Assoc) {
|
fn (mut g Gen) assoc(node ast.Assoc) {
|
||||||
g.writeln('// assoc')
|
g.writeln('// assoc')
|
||||||
|
@ -3026,8 +2995,8 @@ fn (mut g Gen) string_inter_literal(node ast.StringInterLiteral) {
|
||||||
} else if node.expr_types[i] == table.bool_type {
|
} else if node.expr_types[i] == table.bool_type {
|
||||||
g.expr(expr)
|
g.expr(expr)
|
||||||
g.write(' ? _SLIT("true") : _SLIT("false")')
|
g.write(' ? _SLIT("true") : _SLIT("false")')
|
||||||
} else if node.expr_types[i].is_number() || node.expr_types[i].is_pointer() || node.fmts[i] ==
|
} else if node.expr_types[i].is_number() || node.expr_types[i].is_pointer() ||
|
||||||
`d` {
|
node.fmts[i] == `d` {
|
||||||
if node.expr_types[i].is_signed() && node.fmts[i] in [`x`, `X`, `o`] {
|
if node.expr_types[i].is_signed() && node.fmts[i] in [`x`, `X`, `o`] {
|
||||||
// convert to unsigned first befors C's integer propagation strikes
|
// convert to unsigned first befors C's integer propagation strikes
|
||||||
if node.expr_types[i] == table.i8_type {
|
if node.expr_types[i] == table.i8_type {
|
||||||
|
@ -3338,8 +3307,8 @@ fn (mut g Gen) or_block(var_name string, or_block ast.OrExpr, return_type table.
|
||||||
g.writeln('\tstring err = ${cvar_name}.v_error;')
|
g.writeln('\tstring err = ${cvar_name}.v_error;')
|
||||||
g.writeln('\tint errcode = ${cvar_name}.ecode;')
|
g.writeln('\tint errcode = ${cvar_name}.ecode;')
|
||||||
stmts := or_block.stmts
|
stmts := or_block.stmts
|
||||||
if stmts.len > 0 && stmts[or_block.stmts.len - 1] is ast.ExprStmt && (stmts[stmts.len -
|
if stmts.len > 0 && stmts[or_block.stmts.len - 1] is ast.ExprStmt &&
|
||||||
1] as ast.ExprStmt).typ != table.void_type {
|
(stmts[stmts.len - 1] as ast.ExprStmt).typ != table.void_type {
|
||||||
g.indent++
|
g.indent++
|
||||||
for i, stmt in stmts {
|
for i, stmt in stmts {
|
||||||
if i == stmts.len - 1 {
|
if i == stmts.len - 1 {
|
||||||
|
@ -3542,7 +3511,8 @@ fn (mut g Gen) comp_if_to_ifdef(name string, is_comptime_optional bool) string {
|
||||||
return 'TARGET_ORDER_IS_BIG'
|
return 'TARGET_ORDER_IS_BIG'
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if is_comptime_optional || (g.pref.compile_defines_all.len > 0 && name in g.pref.compile_defines_all) {
|
if is_comptime_optional || (g.pref.compile_defines_all.len > 0 &&
|
||||||
|
name in g.pref.compile_defines_all) {
|
||||||
return 'CUSTOM_DEFINE_$name'
|
return 'CUSTOM_DEFINE_$name'
|
||||||
}
|
}
|
||||||
verror('bad os ifdef name "$name"')
|
verror('bad os ifdef name "$name"')
|
||||||
|
@ -4206,7 +4176,8 @@ fn (mut g Gen) gen_str_for_multi_return(info table.MultiReturn, styp, str_fn_nam
|
||||||
sym_has_str_method, str_method_expects_ptr, _ := sym.str_method_info()
|
sym_has_str_method, str_method_expects_ptr, _ := sym.str_method_info()
|
||||||
mut arg_str_fn_name := ''
|
mut arg_str_fn_name := ''
|
||||||
if sym_has_str_method {
|
if sym_has_str_method {
|
||||||
arg_str_fn_name = if is_arg_ptr { field_styp.replace('*', '') + '_str' } else { field_styp + '_str' }
|
arg_str_fn_name = if is_arg_ptr { field_styp.replace('*', '') + '_str' } else { field_styp +
|
||||||
|
'_str' }
|
||||||
} else {
|
} else {
|
||||||
arg_str_fn_name = styp_to_str_fn_name(field_styp)
|
arg_str_fn_name = styp_to_str_fn_name(field_styp)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue