v2: typeof()
							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*/')
 | ||||
|  |  | |||
|  | @ -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