cgen: support `typeof(expr).name` (#6253)
							parent
							
								
									95ce9f33a9
								
							
						
					
					
						commit
						5d3d14da53
					
				|  | @ -1474,6 +1474,14 @@ pub fn (mut c Checker) selector_expr(mut selector_expr ast.SelectorExpr) table.T | |||
| 		c.error('unknown selector expression', selector_expr.pos) | ||||
| 		return table.void_type | ||||
| 	} | ||||
| 	if selector_expr.expr is ast.TypeOf as left { | ||||
| 		if selector_expr.field_name == 'name' { | ||||
| 			return table.string_type | ||||
| 		} else { | ||||
| 			c.error('expected `.name`, not `.$selector_expr.field_name` after `typeof` expression', | ||||
| 				selector_expr.pos) | ||||
| 		} | ||||
| 	} | ||||
| 	selector_expr.expr_type = typ | ||||
| 	sym := c.table.get_type_symbol(c.unwrap_generic(typ)) | ||||
| 	field_name := selector_expr.field_name | ||||
|  |  | |||
|  | @ -2102,6 +2102,11 @@ fn (mut g Gen) expr(node ast.Expr) { | |||
| 			g.struct_init(node) | ||||
| 		} | ||||
| 		ast.SelectorExpr { | ||||
| 			if node.expr is ast.TypeOf as left { | ||||
| 				// typeof(expr).name
 | ||||
| 				g.typeof_name(left) | ||||
| 				return | ||||
| 			} | ||||
| 			sym := g.table.get_type_symbol(node.expr_type) | ||||
| 			if sym.kind == .array_fixed { | ||||
| 				assert node.field_name == 'len' | ||||
|  | @ -2157,6 +2162,22 @@ fn (mut g Gen) expr(node ast.Expr) { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| // typeof(expr).name
 | ||||
| fn (mut g Gen) typeof_name(node ast.TypeOf) { | ||||
| 	sym := g.table.get_type_symbol(node.expr_type) | ||||
| 	if sym.kind == .array { | ||||
| 		info := sym.info as table.Array | ||||
| 		mut s := g.table.get_type_name(info.elem_type) | ||||
| 		s = util.strip_main_name(s) | ||||
| 		g.write('tos_lit("[]$s")') | ||||
| 	} else if sym.kind == .sum_type { | ||||
| 		// new typeof() must be known at compile-time
 | ||||
| 		g.write('tos_lit("${util.strip_main_name(sym.name)}")') | ||||
| 	} else { | ||||
| 		g.typeof_expr(node) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| fn (mut g Gen) typeof_expr(node ast.TypeOf) { | ||||
| 	sym := g.table.get_type_symbol(node.expr_type) | ||||
| 	if sym.kind == .sum_type { | ||||
|  |  | |||
|  | @ -6,6 +6,7 @@ fn test_typeof_on_simple_expressions() { | |||
| 	assert typeof(f64(1.0) * 12.2) == 'f64' | ||||
| 	// assert typeof(1.0 * f32(12.2)) == 'f32'
 | ||||
| 	assert typeof(a) == 'int' | ||||
| 	assert typeof(a).name == 'int' | ||||
| 	// a2 := 123
 | ||||
| 	// assert typeof(a2) == 'any_int'
 | ||||
| 	// assert typeof(42) == 'any_int'
 | ||||
|  | @ -19,6 +20,7 @@ fn test_typeof_on_atypes() { | |||
| 	astring := []string{} | ||||
| 	assert typeof(aint) == 'array_int' | ||||
| 	assert typeof(astring) == 'array_string' | ||||
| 	assert typeof(astring).name == '[]string' | ||||
| } | ||||
| 
 | ||||
| struct FooBar { | ||||
|  | @ -27,10 +29,12 @@ struct FooBar { | |||
| 
 | ||||
| fn test_typeof_on_structs() { | ||||
| 	assert typeof(FooBar{}) == 'FooBar' | ||||
| 	astruct_static := [2]FooBar | ||||
| 	astruct_static := [2]FooBar{} | ||||
| 	astruct_dynamic := [FooBar{}, FooBar{}] | ||||
| 	assert typeof(astruct_static) == '[2]FooBar' | ||||
| 	assert typeof(astruct_static).name == '[2]FooBar' | ||||
| 	assert typeof(astruct_dynamic) == 'array_FooBar' | ||||
| 	assert typeof(astruct_dynamic).name == '[]FooBar' | ||||
| } | ||||
| 
 | ||||
| type MySumType = int | f32 | FooBar | ||||
|  | @ -51,6 +55,9 @@ fn test_typeof_on_sumtypes() { | |||
| 	assert typeof(a) == 'int' | ||||
| 	assert typeof(b) == 'f32' | ||||
| 	assert typeof(c) == 'FooBar' | ||||
| 	assert typeof(a).name == 'MySumType' | ||||
| 	assert typeof(b).name == 'MySumType' | ||||
| 	assert typeof(c).name == 'MySumType' | ||||
| } | ||||
| 
 | ||||
| //
 | ||||
|  | @ -96,4 +103,8 @@ fn test_typeof_on_fn() { | |||
| 	assert typeof(myfn2) == 'fn ()' | ||||
| 	assert typeof(myfn3) == 'fn (int, string) byte' | ||||
| 	assert typeof(myfn4) == 'fn () i8' | ||||
| 	assert typeof(myfn).name == typeof(myfn) | ||||
| 	assert typeof(myfn2).name == typeof(myfn2) | ||||
| 	assert typeof(myfn3).name == typeof(myfn3) | ||||
| 	assert typeof(myfn4).name == typeof(myfn4) | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue