Skip to content

Commit

Permalink
v: support $if T is $array_dynamic { and $if T is $array_fixed {
Browse files Browse the repository at this point in the history
…in addition to `$if T is $array {` (vlang#19882)
  • Loading branch information
spytheman authored Nov 15, 2023
1 parent c838226 commit 192d6d2
Show file tree
Hide file tree
Showing 8 changed files with 115 additions and 21 deletions.
2 changes: 2 additions & 0 deletions doc/docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -5798,6 +5798,8 @@ V supports the following compile time types:
- `$alias` => matches [Type aliases](#type-aliases).
- `$array` => matches [Arrays](#arrays) and [Fixed Size Arrays](#fixed-size-arrays).
- `$array_dynamic` => matches [Arrays](#arrays), but not [Fixed Size Arrays](#fixed-size-arrays).
- `$array_fixed` => matches [Fixed Size Arrays](#fixed-size-arrays), but not [Arrays](#arrays)
- `$enum` => matches [Enums](#enums).
- `$float` => matches `f32`, `f64` and float literals.
- `$function` => matches [Function Types](#function-types).
Expand Down
6 changes: 6 additions & 0 deletions vlib/v/ast/ast.v
Original file line number Diff line number Diff line change
Expand Up @@ -130,12 +130,15 @@ pub mut:
}

pub enum ComptimeTypeKind {
unknown
map_
int
float
struct_
iface
array
array_fixed
array_dynamic
sum_type
enum_
alias
Expand All @@ -151,12 +154,15 @@ pub:

pub fn (cty ComptimeType) str() string {
return match cty.kind {
.unknown { '\$unknown' }
.map_ { '\$map' }
.int { '\$int' }
.float { '\$float' }
.struct_ { '\$struct' }
.iface { '\$interface' }
.array { '\$array' }
.array_dynamic { '\$array_dynamic' }
.array_fixed { '\$array_fixed' }
.sum_type { '\$sumtype' }
.enum_ { '\$enum' }
.alias { '\$alias' }
Expand Down
9 changes: 9 additions & 0 deletions vlib/v/ast/table.v
Original file line number Diff line number Diff line change
Expand Up @@ -2303,6 +2303,9 @@ pub fn (t &Table) get_generic_names(generic_types []Type) []string {
pub fn (t &Table) is_comptime_type(x Type, y ComptimeType) bool {
x_kind := t.type_kind(x)
match y.kind {
.unknown {
return false
}
.map_ {
return x_kind == .map
}
Expand All @@ -2322,6 +2325,12 @@ pub fn (t &Table) is_comptime_type(x Type, y ComptimeType) bool {
.array {
return x_kind in [.array, .array_fixed]
}
.array_dynamic {
return x_kind == .array
}
.array_fixed {
return x_kind == .array_fixed
}
.sum_type {
return x_kind == .sum_type
}
Expand Down
3 changes: 3 additions & 0 deletions vlib/v/fmt/fmt.v
Original file line number Diff line number Diff line change
Expand Up @@ -757,7 +757,10 @@ pub fn (mut f Fmt) expr(node_ ast.Expr) {
}
ast.ComptimeType {
match node.kind {
.unknown { f.write('\$unknown') }
.array { f.write('\$array') }
.array_dynamic { f.write('\$array_dynamic') }
.array_fixed { f.write('\$array_fixed') }
.struct_ { f.write('\$struct') }
.iface { f.write('\$interface') }
.map_ { f.write('\$map') }
Expand Down
3 changes: 3 additions & 0 deletions vlib/v/gen/golang/golang.v
Original file line number Diff line number Diff line change
Expand Up @@ -660,7 +660,10 @@ pub fn (mut f Gen) expr(node_ ast.Expr) {
}
ast.ComptimeType {
match node.kind {
.unknown { f.write('\$unknown') }
.array { f.write('\$array') }
.array_dynamic { f.write('\$array_dynamic') }
.array_fixed { f.write('\$array_fixed') }
.struct_ { f.write('\$struct') }
.iface { f.write('\$interface') }
.map_ { f.write('\$map') }
Expand Down
49 changes: 29 additions & 20 deletions vlib/v/parser/comptime.v
Original file line number Diff line number Diff line change
Expand Up @@ -11,57 +11,66 @@ import v.token
const (
supported_comptime_calls = ['html', 'tmpl', 'env', 'embed_file', 'pkgconfig', 'compile_error',
'compile_warn', 'res']
comptime_types = ['map', 'array', 'int', 'float', 'struct', 'interface', 'enum',
'sumtype', 'alias', 'function', 'option']
comptime_types = ['map', 'array', 'array_dynamic', 'array_fixed', 'int', 'float',
'struct', 'interface', 'enum', 'sumtype', 'alias', 'function', 'option']
)

fn (mut p Parser) parse_comptime_type() ast.ComptimeType {
mut node := ast.ComptimeType{ast.ComptimeTypeKind.map_, p.tok.pos()}

pos := p.tok.pos()
p.check(.dollar)
name := p.check_name()
if name !in parser.comptime_types {
p.error('unsupported compile-time type `${name}`: only ${parser.comptime_types} are supported')
}
mut cty := ast.ComptimeTypeKind.map_
match name {
mut kind := ast.ComptimeTypeKind.unknown
kind = match name {
'map' {
cty = .map_
.map_
}
'struct' {
cty = .struct_
.struct_
}
'interface' {
cty = .iface
.iface
}
'int' {
cty = .int
.int
}
'float' {
cty = .float
.float
}
'alias' {
cty = .alias
.alias
}
'function' {
cty = .function
.function
}
'array' {
cty = .array
.array
}
'array_fixed' {
.array_fixed
}
'array_dynamic' {
.array_dynamic
}
'enum' {
cty = .enum_
.enum_
}
'sumtype' {
cty = .sum_type
.sum_type
}
'option' {
cty = .option
.option
}
else {}
else {
.unknown
}
}
return ast.ComptimeType{
kind: kind
pos: pos
}
node = ast.ComptimeType{cty, node.pos}
return node
}

// // #include, #flag, #v
Expand Down
56 changes: 56 additions & 0 deletions vlib/v/tests/comptime_kinds_test.v
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,22 @@ fn assert_array[T]() {
}
}

fn assert_array_dynamic[T]() {
$if T is $array_dynamic {
assert true
} $else {
assert false
}
}

fn assert_array_fixed[T]() {
$if T is $array_fixed {
assert true
} $else {
assert false
}
}

fn assert_struct[T]() {
$if T is $struct {
assert true
Expand Down Expand Up @@ -46,6 +62,22 @@ fn assert_not_array[T]() {
}
}

fn assert_not_array_dynamic[T]() {
$if T is $array_dynamic {
assert false
} $else {
assert true
}
}

fn assert_not_array_fixed[T]() {
$if T is $array_fixed {
assert false
} $else {
assert true
}
}

struct Abc {}

struct Bc {}
Expand Down Expand Up @@ -73,6 +105,30 @@ fn test_kind_array() {
assert_not_array[map[int]int]()
}

fn test_kind_array_dynamic() {
assert_array_dynamic[[]int]()
assert_array_dynamic[[]f32]()
assert_array_dynamic[[]string]()

assert_not_array_dynamic[Abc]()
assert_not_array_dynamic[string]()
assert_not_array_dynamic[int]()
assert_not_array_dynamic[map[int]int]()
assert_not_array_dynamic[[3]int]()
}

fn test_kind_array_fixed() {
assert_array_fixed[[3]int]()
assert_array_fixed[[5]f32]()
assert_array_fixed[[6]string]()

assert_not_array_fixed[Abc]()
assert_not_array_fixed[string]()
assert_not_array_fixed[int]()
assert_not_array_fixed[map[int]int]()
assert_not_array_fixed[[]int]()
}

fn test_kind_struct() {
assert_struct[Abc]()
assert_struct[Bc]()
Expand Down
8 changes: 7 additions & 1 deletion vlib/v/tests/comptime_type_test.v
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ type Sumtype = int | string

struct Foo {}

fn dummy_fn() {}

struct Test {
a Abc
b map[string]string
Expand All @@ -20,7 +22,7 @@ struct Test {
f f64
g Alias
h Foo
i fn ()
i fn () = dummy_fn
j Sumtype
k ?int
}
Expand All @@ -37,11 +39,14 @@ fn test_comptime_types() {
mut c_fn := 0
mut c_sum := 0
mut c_option := 0
mut fixeda := 0
$for f in Test.fields {
$if f.typ is $alias {
c_alias++
} $else $if f.typ is $interface {
i++
} $else $if f.typ is $array_fixed {
fixeda++
} $else $if f.typ is $array {
a++
} $else $if f.typ is $map {
Expand All @@ -66,6 +71,7 @@ fn test_comptime_types() {
assert a == 1
assert m == 1
assert e == 1
assert fixeda == 0
assert c_int == 1
assert c_float == 1
assert c_alias == 1
Expand Down

0 comments on commit 192d6d2

Please sign in to comment.