mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
v2: typeof()
This commit is contained in:
parent
837bffd03a
commit
a9724fd38d
@ -641,6 +641,8 @@ pub:
|
||||
pub struct TypeOf {
|
||||
pub:
|
||||
expr Expr
|
||||
mut:
|
||||
expr_type table.Type
|
||||
}
|
||||
|
||||
pub struct LineComment {
|
||||
|
@ -779,6 +779,7 @@ pub fn (c mut Checker) expr(node ast.Expr) table.Type {
|
||||
return it.typ
|
||||
}
|
||||
ast.TypeOf {
|
||||
it.expr_type = c.expr(it.expr)
|
||||
return table.string_type
|
||||
}
|
||||
/*
|
||||
|
@ -107,12 +107,34 @@ pub fn (g mut Gen) init() {
|
||||
g.definitions.writeln('\nstring _STR_TMP(const char*, ...);\n')
|
||||
g.write_builtin_types()
|
||||
g.write_typedef_types()
|
||||
g.write_typeof_functions()
|
||||
g.write_str_definitions()
|
||||
g.write_sorted_types()
|
||||
g.write_multi_return_types()
|
||||
g.definitions.writeln('// end of definitions #endif')
|
||||
}
|
||||
|
||||
pub fn (g mut Gen) write_typeof_functions() {
|
||||
g.writeln('// >> typeof() support for sum types')
|
||||
for typ in g.table.types {
|
||||
if typ.kind == .sum_type {
|
||||
sum_info := typ.info as table.SumType
|
||||
tidx := g.table.find_type_idx( typ.name )
|
||||
g.writeln('char * v_typeof_sumtype_${tidx}(int sidx) { /* ${typ.name} */ ')
|
||||
g.writeln(' switch(sidx) {')
|
||||
g.writeln(' case $tidx: return "$typ.name";')
|
||||
for v in sum_info.variants {
|
||||
subtype := g.table.get_type_symbol(v)
|
||||
g.writeln(' case $v: return "$subtype.name";')
|
||||
}
|
||||
g.writeln(' default: return "unknown ${typ.name}";')
|
||||
g.writeln(' }')
|
||||
g.writeln('}')
|
||||
}
|
||||
}
|
||||
g.writeln('// << typeof() support for sum types')
|
||||
}
|
||||
|
||||
// V type to C type
|
||||
pub fn (g mut Gen) typ(t table.Type) string {
|
||||
nr_muls := table.type_nr_muls(t)
|
||||
@ -188,7 +210,7 @@ pub fn (g mut Gen) write_typedef_types() {
|
||||
else {
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -772,7 +794,7 @@ fn (g mut Gen) free_scope_vars(pos int) {
|
||||
else {
|
||||
g.writeln('// other ' + t)
|
||||
}
|
||||
}
|
||||
}
|
||||
g.writeln('string_free($var.name); // autofreed')
|
||||
}
|
||||
}
|
||||
@ -1165,7 +1187,7 @@ fn (g mut Gen) expr(node ast.Expr) {
|
||||
g.write('$type_idx /* $sym.name */')
|
||||
}
|
||||
ast.TypeOf {
|
||||
g.write('tos3("TYPEOF_TODO")')
|
||||
g.typeof_expr(it)
|
||||
}
|
||||
else {
|
||||
// #printf("node=%d\n", node.typ);
|
||||
@ -1174,6 +1196,20 @@ fn (g mut Gen) expr(node ast.Expr) {
|
||||
}
|
||||
}
|
||||
|
||||
fn (g mut Gen) typeof_expr(node ast.TypeOf) {
|
||||
sym := g.table.get_type_symbol(node.expr_type)
|
||||
if sym.kind == .sum_type {
|
||||
// When encountering a .sum_type, typeof() should be done at runtime,
|
||||
// because the subtype of the expression may change:
|
||||
sum_type_idx := table.type_idx( node.expr_type )
|
||||
g.write('tos3( /* ${sym.name} */ v_typeof_sumtype_${sum_type_idx}( (')
|
||||
g.expr(node.expr)
|
||||
g.write(').typ ))')
|
||||
}else{
|
||||
g.write('tos3("${sym.name}")')
|
||||
}
|
||||
}
|
||||
|
||||
fn (g mut Gen) infix_expr(node ast.InfixExpr) {
|
||||
// println('infix_expr() op="$node.op.str()" line_nr=$node.pos.line_nr')
|
||||
// g.write('/*infix*/')
|
||||
|
66
vlib/v/tests/typeof_simple_types_test.v
Normal file
66
vlib/v/tests/typeof_simple_types_test.v
Normal file
@ -0,0 +1,66 @@
|
||||
struct Abc {
|
||||
x int
|
||||
}
|
||||
|
||||
struct Xyz {
|
||||
y int
|
||||
}
|
||||
|
||||
struct XxYyZz {
|
||||
y int
|
||||
}
|
||||
|
||||
type MySumType = Abc | Xyz
|
||||
|
||||
type AnotherSumType = XxYyZz | int
|
||||
|
||||
type SuperSumType = MySumType | AnotherSumType | string
|
||||
|
||||
fn test_typeof_for_builtin_int_types() {
|
||||
assert typeof(1) == 'int'
|
||||
assert typeof(i64(1)) == 'i64'
|
||||
assert typeof(u32(1)) == 'u32'
|
||||
assert typeof(u64(1)) == 'u64'
|
||||
}
|
||||
|
||||
fn test_typeof_for_builtin_float_types() {
|
||||
assert typeof(f32(1.0)) == 'f32'
|
||||
assert typeof(1.0) == 'f64'
|
||||
}
|
||||
|
||||
fn test_typeof_for_builtin_string_type() {
|
||||
assert typeof('abc') == 'string'
|
||||
assert typeof('/v/nv/vlib/v/tests/typeof_simple_types_test.v') == 'string'
|
||||
assert typeof('22') == 'string'
|
||||
}
|
||||
|
||||
fn test_typeof_for_structs() {
|
||||
assert typeof(Abc{}) == 'Abc'
|
||||
assert typeof(Xyz{}) == 'Xyz'
|
||||
}
|
||||
|
||||
//
|
||||
fn mysumtype_typeof(x MySumType) string {
|
||||
return typeof(x)
|
||||
}
|
||||
|
||||
fn test_typeof_for_sumtypes() {
|
||||
z_abc := Abc{}
|
||||
z_xyz := Xyz{}
|
||||
assert mysumtype_typeof(z_abc) == 'Abc'
|
||||
assert mysumtype_typeof(z_xyz) == 'Xyz'
|
||||
}
|
||||
|
||||
//
|
||||
fn supersumtype_typeof(x SuperSumType) string {
|
||||
return typeof(x)
|
||||
}
|
||||
|
||||
fn mst(x MySumType) MySumType {
|
||||
return x
|
||||
}
|
||||
|
||||
fn test_typeof_for_sumtypes_of_sumtypes() {
|
||||
assert supersumtype_typeof('abc') == 'string'
|
||||
assert supersumtype_typeof(mst(Abc{})) == 'MySumType'
|
||||
}
|
Loading…
Reference in New Issue
Block a user