parser: add type check for +=, -=, *=, /=
parent
19520ccf4e
commit
aaf3ced750
|
@ -1674,6 +1674,21 @@ fn ($v.name mut $v.typ) ${p.cur_fn.name}(...) {
|
||||||
}
|
}
|
||||||
p.cgen.resetln('memcpy( (& $left), ($etype{$expr}), sizeof( $left ) );')
|
p.cgen.resetln('memcpy( (& $left), ($etype{$expr}), sizeof( $left ) );')
|
||||||
}
|
}
|
||||||
|
// check type for +=, -=, *=, /=.
|
||||||
|
else if tok in [.plus_assign, .minus_assign, .mult_assign, .div_assign] {
|
||||||
|
// special 1. ptrs with += or -= are acceptable.
|
||||||
|
if !(tok in [.plus_assign, .minus_assign] && (is_integer_type(p.assigned_type) || is_pointer_type(p.assigned_type)) && (is_integer_type(expr_type) || is_pointer_type(expr_type))) {
|
||||||
|
// special 2. `str += str` is acceptable
|
||||||
|
if !(tok == .plus_assign && p.assigned_type == expr_type && expr_type == 'string' ) {
|
||||||
|
if !is_number_type(p.assigned_type) {
|
||||||
|
p.error_with_token_index('cannot use assignment operator ${tok.str()} on non-numeric type `$p.assigned_type`', errtok)
|
||||||
|
}
|
||||||
|
if !is_number_type(expr_type) {
|
||||||
|
p.error_with_token_index('cannot use non-numeric type `$expr_type` as assignment operator ${tok.str()} argument', errtok)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
// check type for <<= >>= %= ^= &= |=
|
// check type for <<= >>= %= ^= &= |=
|
||||||
else if tok in [.left_shift_assign, .righ_shift_assign, .mod_assign, .xor_assign, .and_assign, .or_assign] {
|
else if tok in [.left_shift_assign, .righ_shift_assign, .mod_assign, .xor_assign, .and_assign, .or_assign] {
|
||||||
if !is_integer_type(p.assigned_type) {
|
if !is_integer_type(p.assigned_type) {
|
||||||
|
|
|
@ -189,6 +189,7 @@ const (
|
||||||
integer_types = ['int', 'i8', 'char', 'byte', 'i16', 'u16', 'u32', 'i64', 'u64']
|
integer_types = ['int', 'i8', 'char', 'byte', 'i16', 'u16', 'u32', 'i64', 'u64']
|
||||||
float_types = ['f32', 'f64']
|
float_types = ['f32', 'f64']
|
||||||
reserved_type_param_names = ['R', 'S', 'T', 'U', 'W']
|
reserved_type_param_names = ['R', 'S', 'T', 'U', 'W']
|
||||||
|
pointer_types = ['byte*', 'byteptr', 'char*', 'charptr', 'void*', 'voidptr', 'voidptr*', 'intptr']
|
||||||
)
|
)
|
||||||
|
|
||||||
fn is_number_type(typ string) bool {
|
fn is_number_type(typ string) bool {
|
||||||
|
@ -207,6 +208,10 @@ fn is_primitive_type(typ string) bool {
|
||||||
return is_number_type(typ) || typ == 'string'
|
return is_number_type(typ) || typ == 'string'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_pointer_type(typ string) bool {
|
||||||
|
return typ in pointer_types
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
fn (t mut Table) register_enum_val(typ, val string) {
|
fn (t mut Table) register_enum_val(typ, val string) {
|
||||||
if t.enum_vals.len == 0 {
|
if t.enum_vals.len == 0 {
|
||||||
|
|
Loading…
Reference in New Issue