!in operator
							parent
							
								
									1b6ae00966
								
							
						
					
					
						commit
						581d836de6
					
				| 
						 | 
				
			
			@ -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,7 +753,7 @@ 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 ) {
 | 
			
		||||
					if cint := const_int_value(obj) {
 | 
			
		||||
						fixed_size = cint
 | 
			
		||||
					}
 | 
			
		||||
				} else {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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 {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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)
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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]
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue