!in operator

pull/4358/head
Alexander Medvednikov 2020-04-11 21:31:54 +02:00
parent 1b6ae00966
commit 581d836de6
4 changed files with 19 additions and 9 deletions

View File

@ -198,7 +198,7 @@ pub fn (c mut Checker) infix_expr(infix_expr mut ast.InfixExpr) table.Type {
return table.void_type
}
}
if infix_expr.op == .key_in {
if infix_expr.op in [.key_in, .not_in] {
if !(right.kind in [.array, .map, .string]) {
c.error('`in` can only be used with an array/map/string.', infix_expr.pos)
}
@ -209,7 +209,8 @@ pub fn (c mut Checker) infix_expr(infix_expr mut ast.InfixExpr) table.Type {
if left_type == table.void_type || right_type == table.void_type {
return table.void_type
}
c.error('infix expr: cannot use `$right.name` (right) as `$left.name`', infix_expr.pos)
c.error('infix expr: cannot use `$right.name` (right expression) as `$left.name`',
infix_expr.pos)
}
if infix_expr.op.is_relational() {
return table.bool_type
@ -752,9 +753,9 @@ pub fn (c mut Checker) array_init(array_init mut ast.ArrayInit) table.Type {
mut full_const_name := if it.mod == 'main' { it.name } else { it.mod + '.' +
it.name }
if obj := c.file.global_scope.find_const(full_const_name) {
if cint := const_int_value( obj ) {
fixed_size = cint
}
if cint := const_int_value(obj) {
fixed_size = cint
}
} else {
c.error('non existant integer const $full_const_name while initializing the size of a static array',
array_init.pos)
@ -775,7 +776,7 @@ fn const_int_value(cfield ast.ConstField) ?int {
if cint := is_const_integer(cfield) {
return cint.val.int()
}
return none
return none
}
fn is_const_integer(cfield ast.ConstField) ?ast.IntegerLiteral {

View File

@ -1376,7 +1376,10 @@ fn (g mut Gen) infix_expr(node ast.InfixExpr) {
g.write(', ')
g.expr(node.right)
g.write(')')
} else if node.op == .key_in {
} else if node.op in [.key_in, .not_in] {
if node.op == .not_in {
g.write('!')
}
if right_sym.kind == .array {
match node.right {
ast.ArrayInit {

View File

@ -720,6 +720,10 @@ pub fn (s mut Scanner) scan() token.Token {
s.pos++
return s.new_token(.ne, '', 2)
}
else if nextc == `i` && s.text[s.pos+2] == `n` && !s.text[s.pos+3].is_letter() {
s.pos += 2
return s.new_token(.not_in, '', 3)
}
else {
return s.new_token(.not, '', 1)
}

View File

@ -44,6 +44,7 @@ pub enum Kind {
str_dollar
left_shift
right_shift
not_in // !in
// at // @
assign // =
decl_assign // :=
@ -167,6 +168,7 @@ fn build_token_str() []string {
s[Kind.dotdot] = '..'
s[Kind.ellipsis] = '...'
s[Kind.comma] = ','
s[Kind.not_in] = '!in'
// s[Kind.at] = '@'
s[Kind.semicolon] = ';'
s[Kind.colon] = ':'
@ -381,7 +383,7 @@ pub fn (tok Token) precedence() int {
.left_shift_assign, .right_shift_assign, .mult_assign, .xor_assign {
return int(Precedence.assign)
}
.key_in, .key_as {
.key_in, .not_in, .key_as {
return int(Precedence.in_as)
}
.logical_or, .and {
@ -421,7 +423,7 @@ pub fn (k Kind) is_start_of_type() bool {
pub fn (kind Kind) is_infix() bool {
return kind in [.plus, .minus, .mod, .mul, .div, .eq, .ne, .gt, .lt, .key_in,
//
.key_as, .ge, .le, .logical_or, .xor,
.key_as, .ge, .le, .logical_or, .xor, .not_in,
//
.and, .dot, .pipe, .amp, .left_shift, .right_shift]
}