v icon indicating copy to clipboard operation
v copied to clipboard

v: refactor typeof(expr) feature [DRAFT]

Open felipensp opened this issue 1 year ago • 6 comments

Describe the feature

The plan is make typeof(expr) generate instance of TypeData with type information.

Use Case

Possible fields:

struct TypeData {
  typ int // type idx
  name string // type name
  is_ptr bool // is it an ptr?
  parent_typ TypeData // for alias, the parent type
  attributes []StructAttribute // attributes, we must rename this StructAttribute too
  variants []TypeData // for sum type, its variant types 
  fields []FieldData // for struct and interface
  methods []FuncData // for struct and interface
  values []EnumData // for enum
}

Examples:

$if typeof(T) is string { /* do something */ } // similar to $if T is string {
$if typeof(param) is int { /* do something */ } // similar to $if param is int {
$if typeof(T).name == 'MyType' { /* do something */ }

$if typeof(T) is $sumtype { // similar to $if T is $sumtype {
  $for v in typeof(T).variants { // similar to T.variants
    dump(v.typ)
  }
}

dump(typeof(T).name)
dump(typeof(T).typ)

fn dump_fields[T](param T) {
  typ := typeof(param)
  $if typ is $struct {
    $for f in typ.fields {
      println('${f.typ} -- ${f.name}')
    }
  }
}

a := 1
dump(typeof(a).name == 'int') // true
b := SumType(1)
dump(typeof(b).name == 'SumType') // true
c := [1]
dump(typeof(c).indirections == 1) // true

Breaking changes

  • Remove typeof[expr]().field_name syntax.

Proposed Solution

No response

Other Information

No response

Acknowledgements

  • [X] I may be able to implement this feature request
  • [X] This feature might incur a breaking change

Version used

latest

Environment details (OS name and version, etc.)

Linux

[!NOTE] You can use the 👍 reaction to increase the issue's priority for developers.

Please note that only the 👍 reaction to the issue itself counts as a vote. Other reactions and those to comments will not be taken into account.

felipensp avatar Jan 04 '24 13:01 felipensp

@spytheman feel free to edit the FR with your suggestions.

felipensp avatar Jan 04 '24 13:01 felipensp

What is the chance of have something like

struct TypeData {
...
nr_muls int
}

This can help to avoid need use

#ifdef __GNUC__
#define IS_POINTER(x) __builtin_types_compatible_p(__typeof__(x), void *)
#else
#define IS_POINTER(x) (((void*)(x) == (void*)0) != ((void*)&(x) == (void*)0))
#endif

To verify if it is pointer

enghitalo avatar Jan 04 '24 17:01 enghitalo

What is the chance of have something like

struct TypeData {
...
indirections int
}

This can help to avoid need use

#ifdef __GNUC__
#define IS_POINTER(x) __builtin_types_compatible_p(__typeof__(x), void *)
#else
#define IS_POINTER(x) (((void*)(x) == (void*)0) != ((void*)&(x) == (void*)0))
#endif

To verify if it is pointer

Yes, the indirectionsone from FieldData must be in the new TypeData and an is_ptr field too.

felipensp avatar Jan 04 '24 17:01 felipensp

@felipensp Just for FieldData? I was thing in something like

fn main() {
	a := 'a'
	pa := &a
	ppa := &pa
	pppa := &ppa

	assert count_nr_muls(a) == 0
	assert count_nr_muls(pa) == 1
	assert count_nr_muls(ppa) == 2
	assert count_nr_muls(pppa) == 3
}

fn count_nr_muls[T](val T) int {
	return typeof[T]().nr_muls
}

enghitalo avatar Jan 04 '24 17:01 enghitalo

Use typeof[T](), not typeof(T) .

spytheman avatar Jan 09 '24 18:01 spytheman

Use typeof[T](), not typeof(T) .

Please try again.](code.v:14:21: error: invalid field .nr_muls for type typeof[T]())

enghitalo avatar Jan 09 '24 20:01 enghitalo