checker/cgen: interface match
parent
c4241f90e6
commit
f87e872fa2
|
@ -439,6 +439,7 @@ pub mut:
|
|||
cond_type table.Type // type of `x` in `match x {`
|
||||
expected_type table.Type // for debugging only
|
||||
is_sum_type bool
|
||||
is_interface bool
|
||||
}
|
||||
|
||||
pub struct MatchBranch {
|
||||
|
|
|
@ -1039,7 +1039,7 @@ pub fn (mut c Checker) call_fn(mut call_expr ast.CallExpr) table.Type {
|
|||
return f.return_type
|
||||
}
|
||||
|
||||
fn (mut c Checker) type_implements(typ, inter_typ table.Type, pos token.Position) {
|
||||
fn (mut c Checker) type_implements(typ, inter_typ table.Type, pos token.Position) bool {
|
||||
typ_sym := c.table.get_type_symbol(typ)
|
||||
inter_sym := c.table.get_type_symbol(inter_typ)
|
||||
styp := c.table.type_to_str(typ)
|
||||
|
@ -1048,6 +1048,7 @@ fn (mut c Checker) type_implements(typ, inter_typ table.Type, pos token.Position
|
|||
if !imethod.is_same_method_as(method) {
|
||||
c.error('`$styp` incorrectly implements method `$imethod.name` of interface `$inter_sym.name`, expected `${c.table.fn_to_str(imethod)}`',
|
||||
pos)
|
||||
return false
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
@ -1057,6 +1058,7 @@ fn (mut c Checker) type_implements(typ, inter_typ table.Type, pos token.Position
|
|||
if typ !in inter_info.types && typ_sym.kind != .interface_ {
|
||||
inter_info.types << typ
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// return the actual type of the expression, once the optional is handled
|
||||
|
@ -2037,11 +2039,11 @@ pub fn (mut c Checker) match_expr(mut node ast.MatchExpr) table.Type {
|
|||
if cond_type == 0 {
|
||||
c.error('match 0 cond type', node.pos)
|
||||
}
|
||||
type_sym := c.table.get_type_symbol(cond_type)
|
||||
if type_sym.kind != .sum_type {
|
||||
cond_type_sym := c.table.get_type_symbol(cond_type)
|
||||
if cond_type_sym.kind !in [.sum_type, .interface_] {
|
||||
node.is_sum_type = false
|
||||
}
|
||||
c.match_exprs(mut node, type_sym)
|
||||
c.match_exprs(mut node, cond_type_sym)
|
||||
c.expected_type = cond_type
|
||||
mut ret_type := table.void_type
|
||||
for branch in node.branches {
|
||||
|
@ -2049,12 +2051,17 @@ pub fn (mut c Checker) match_expr(mut node ast.MatchExpr) table.Type {
|
|||
c.expected_type = cond_type
|
||||
typ := c.expr(expr)
|
||||
typ_sym := c.table.get_type_symbol(typ)
|
||||
if !node.is_sum_type && !c.check_types(typ, cond_type) {
|
||||
exp_sym := c.table.get_type_symbol(cond_type)
|
||||
c.error('cannot use `$typ_sym.name` as `$exp_sym.name` in `match`', node.pos)
|
||||
if node.is_sum_type || node.is_interface {
|
||||
ok := if cond_type_sym.kind == .sum_type {
|
||||
// TODO verify sum type
|
||||
true // c.check_types(typ, cond_type)
|
||||
} else {
|
||||
c.type_implements(typ, cond_type, node.pos)
|
||||
}
|
||||
if !ok {
|
||||
c.error('cannot use `$typ_sym.name` as `$cond_type_sym.name` in `match`',
|
||||
node.pos)
|
||||
}
|
||||
// TODO:
|
||||
if typ_sym.kind == .sum_type {
|
||||
}
|
||||
}
|
||||
c.stmts(branch.stmts)
|
||||
|
|
|
@ -1888,9 +1888,14 @@ fn (mut g Gen) match_expr(node ast.MatchExpr) {
|
|||
for i, expr in branch.exprs {
|
||||
if node.is_sum_type {
|
||||
g.expr(node.cond)
|
||||
sym := g.table.get_type_symbol(node.cond_type)
|
||||
// branch_sym := g.table.get_type_symbol(branch.typ)
|
||||
if sym.kind == .sum_type {
|
||||
g.write('.typ == ')
|
||||
// g.write('${tmp}.typ == ')
|
||||
// sum_type_str
|
||||
} else if sym.kind == .interface_ {
|
||||
// g.write('._interface_idx == _${sym.name}_${branch_sym} ')
|
||||
g.write('._interface_idx == ')
|
||||
}
|
||||
} else if type_sym.kind == .string {
|
||||
g.write('string_eq(')
|
||||
//
|
||||
|
|
|
@ -12,7 +12,7 @@ import v.util
|
|||
import v.errors
|
||||
import os
|
||||
import runtime
|
||||
import sync
|
||||
//import sync
|
||||
import time
|
||||
|
||||
pub struct Parser {
|
||||
|
@ -140,6 +140,7 @@ pub fn parse_file(path string, b_table &table.Table, comments_mode scanner.Comme
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
struct Queue {
|
||||
mut:
|
||||
idx int
|
||||
|
@ -171,10 +172,12 @@ fn (mut q Queue) run() {
|
|||
println('run done(idx=$idx)')
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
pub fn parse_files(paths []string, table &table.Table, pref &pref.Preferences, global_scope &ast.Scope) []ast.File {
|
||||
// println('nr_cpus= $nr_cpus')
|
||||
$if macos {
|
||||
/*
|
||||
if pref.is_parallel && paths[0].contains('/array.v') {
|
||||
println('\n\n\nparse_files() nr_files=$paths.len')
|
||||
println(paths)
|
||||
|
@ -194,6 +197,7 @@ pub fn parse_files(paths []string, table &table.Table, pref &pref.Preferences, g
|
|||
println('all done')
|
||||
return q.parsed_ast_files
|
||||
}
|
||||
*/
|
||||
}
|
||||
if false {
|
||||
// TODO: remove this; it just prevents warnings about unused time and runtime
|
||||
|
|
|
@ -247,3 +247,13 @@ fn new_animal() Animal {
|
|||
fn new_animal2() Animal {
|
||||
return new_animal()
|
||||
}
|
||||
|
||||
/*
|
||||
fn animal_match(a Animal) {
|
||||
match a {
|
||||
Dog { println('(dog)') }
|
||||
Cat { println('(cat)') }
|
||||
else {}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue