diff --git a/doc/docs.md b/doc/docs.md index f6a5b89d0e..9e90d6cdc9 100644 --- a/doc/docs.md +++ b/doc/docs.md @@ -79,7 +79,7 @@ you can do in V. * [Debugging generated C code](#debugging-generated-c-code) * [Conditional compilation](#conditional-compilation) * [Compile time pseudo variables](#compile-time-pseudo-variables) - * [Reflection via codegen](#reflection-via-codegen) + * [Compile-time reflection](#compile-time-reflection) * [Limited operator overloading](#limited-operator-overloading) * [Inline assembly](#inline-assembly) * [Translating C/C++ to V](#translating-cc-to-v) @@ -2268,26 +2268,38 @@ that does nothing. `if _unlikely_(bool expression) {` similar to `_likely_(x)`, but it hints that the boolean expression is highly improbable. In the JS backend, that does nothing. -## Reflection via codegen + + +## Compile-time reflection Having built-in JSON support is nice, but V also allows you to create efficient -serializers for any data format: +serializers for any data format. V has compile-time `if` and `for` constructs: ```v // TODO: not implemented yet + +struct User { + name string + age int +} + +// Note: T should be passed a struct name only fn decode(data string) T { mut result := T{} - for field in T.fields { - if field.typ == 'string' { - result.$field = get_string(data, field.name) - } else if field.typ == 'int' { - result.$field = get_int(data, field.name) + // compile-time `for` loop + // T.fields gives an array of a field metadata type + $for field in T.fields { + $if field.Type is string { + // $(string_expr) produces an identifier + result.$(field.name) = get_string(data, field.name) + } else $if field.Type is int { + result.$(field.name) = get_int(data, field.name) } } return result } -// generates to: +// `decode` generates: fn decode_User(data string) User { mut result := User{} result.name = get_string(data, 'name')