parser: add type check for +=, -=, *=, /=

pull/3779/head
SleepyRoy 2020-02-19 05:14:52 +08:00 committed by GitHub
parent 19520ccf4e
commit aaf3ced750
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 20 additions and 0 deletions

View File

@ -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) {

View File

@ -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 {