gen: add `in` for map and string to cgen

pull/4072/head
Joe Conigliaro 2020-03-19 18:32:42 +11:00
parent 28309da1f1
commit 3e70e5f2f1
2 changed files with 27 additions and 7 deletions

View File

@ -134,9 +134,12 @@ pub fn (c mut Checker) infix_expr(infix_expr mut ast.InfixExpr) table.Type {
c.expected_type = left_type
right_type := c.expr(infix_expr.right)
infix_expr.right_type = right_type
right := c.table.get_type_symbol(right_type)
if infix_expr.op == .key_in && !(right.kind in [.array, .map, .string]) {
c.error('infix expr: `in` can only be used with array/map/string.', infix_expr.pos)
}
if !c.table.check(right_type, left_type) {
left := c.table.get_type_symbol(left_type)
right := c.table.get_type_symbol(right_type)
// `array << elm`
// the expressions have different types (array_x and x)
if left.kind == .array && infix_expr.op == .left_shift {

View File

@ -930,12 +930,29 @@ fn (g mut Gen) infix_expr(node ast.InfixExpr) {
g.write(')')
}
else if node.op == .key_in {
styp := g.typ(node.left_type)
g.write('_IN($styp, ')
g.expr(node.left)
g.write(', ')
g.expr(node.right)
g.write(')')
right_sym := g.table.get_type_symbol(node.right_type)
if right_sym.kind == .array {
styp := g.typ(node.left_type)
g.write('_IN($styp, ')
g.expr(node.left)
g.write(', ')
g.expr(node.right)
g.write(')')
}
else if right_sym.kind == .map {
g.write('_IN_MAP(')
g.expr(node.left)
g.write(', ')
g.expr(node.right)
g.write(')')
}
else if right_sym.kind == .string {
g.write('string_contains(')
g.expr(node.right)
g.write(', ')
g.expr(node.left)
g.write(')')
}
}
// arr << val
else if node.op == .left_shift && g.table.get_type_symbol(node.left_type).kind == .array {