v2: typeof()
parent
837bffd03a
commit
a9724fd38d
|
@ -641,6 +641,8 @@ pub:
|
||||||
pub struct TypeOf {
|
pub struct TypeOf {
|
||||||
pub:
|
pub:
|
||||||
expr Expr
|
expr Expr
|
||||||
|
mut:
|
||||||
|
expr_type table.Type
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct LineComment {
|
pub struct LineComment {
|
||||||
|
|
|
@ -779,6 +779,7 @@ pub fn (c mut Checker) expr(node ast.Expr) table.Type {
|
||||||
return it.typ
|
return it.typ
|
||||||
}
|
}
|
||||||
ast.TypeOf {
|
ast.TypeOf {
|
||||||
|
it.expr_type = c.expr(it.expr)
|
||||||
return table.string_type
|
return table.string_type
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -107,12 +107,34 @@ pub fn (g mut Gen) init() {
|
||||||
g.definitions.writeln('\nstring _STR_TMP(const char*, ...);\n')
|
g.definitions.writeln('\nstring _STR_TMP(const char*, ...);\n')
|
||||||
g.write_builtin_types()
|
g.write_builtin_types()
|
||||||
g.write_typedef_types()
|
g.write_typedef_types()
|
||||||
|
g.write_typeof_functions()
|
||||||
g.write_str_definitions()
|
g.write_str_definitions()
|
||||||
g.write_sorted_types()
|
g.write_sorted_types()
|
||||||
g.write_multi_return_types()
|
g.write_multi_return_types()
|
||||||
g.definitions.writeln('// end of definitions #endif')
|
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
|
// V type to C type
|
||||||
pub fn (g mut Gen) typ(t table.Type) string {
|
pub fn (g mut Gen) typ(t table.Type) string {
|
||||||
nr_muls := table.type_nr_muls(t)
|
nr_muls := table.type_nr_muls(t)
|
||||||
|
@ -1165,7 +1187,7 @@ fn (g mut Gen) expr(node ast.Expr) {
|
||||||
g.write('$type_idx /* $sym.name */')
|
g.write('$type_idx /* $sym.name */')
|
||||||
}
|
}
|
||||||
ast.TypeOf {
|
ast.TypeOf {
|
||||||
g.write('tos3("TYPEOF_TODO")')
|
g.typeof_expr(it)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// #printf("node=%d\n", node.typ);
|
// #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) {
|
fn (g mut Gen) infix_expr(node ast.InfixExpr) {
|
||||||
// println('infix_expr() op="$node.op.str()" line_nr=$node.pos.line_nr')
|
// println('infix_expr() op="$node.op.str()" line_nr=$node.pos.line_nr')
|
||||||
// g.write('/*infix*/')
|
// g.write('/*infix*/')
|
||||||
|
|
|
@ -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