Initial project import

This commit is contained in:
Agila Forge Importer committed 2026-07-13 15:20:32 +00:00
commit 23f2d29e32
11957 files changed
+1754577

No files matched your search

@@ -0,0 +1,37 @@
module main
fn main() {
a := 1
b := [1,2,3,4]
// c := b[0
if x == {}
as_cast_a := sum_type_a as
if x == 100 {
}
if y == 200 {
}
// TODO: check line
// arr := [2]{}
// for x in 1..10 {
// println(x)
// }
}
fn fn_a() ? {
}
fn fn_b() {
a := 1
println('hello')
}
@@ -0,0 +1,34 @@
// End-to-end test for v2's conditional struct field parsing.
// Exercises `$if cond { ... }` / `$else $if` / `$else` blocks and the
// per-field `@[if cond ?]` attribute. Compiled and run via the v2 binary.
module main
struct Container {
name string
$if !no_log ? {
logger string = 'default'
}
always int = 42
$if my_feature ? {
feature_val string = 'on'
} $else {
feature_val string = 'off'
}
dev_menu string = 'dev' @[if !no_dev_menu ?]
never_built string = 'nope' @[if absent_flag ?]
}
fn main() {
c := Container{
name: 'app'
}
assert c.name == 'app'
assert c.logger == 'default'
assert c.always == 42
// `my_feature` is not defined → `$else` branch contributes the field.
assert c.feature_val == 'off'
// `no_dev_menu` is not defined → `!no_dev_menu` is true → field kept.
assert c.dev_menu == 'dev'
println('conditional_struct_field_test PASS')
}
@@ -0,0 +1,15 @@
module main
struct StructA {}
fn f[T](x T) {
d := x + x
println(d)
}
fn main() {
f(123)
f('abc')
// f(main)
f(StructA{})
}
@@ -0,0 +1,41 @@
module main
fn main() {
// generic_fn_a[int](1, 'hello')
// generic_fn_b[int, string](1, 'hello')
// generic_fn_a(1, 'hello')
generic_fn_b(1, 'hello')
generic_fn_c(['foo'], {'a': 'apple', 'b': 'bananna'})
generic_fn_d(fn(int, string) {
println(1)
})
generic_fn_e(fn(int, fn(map[string]string) string) {
println(1)
})
}
// fn generic_fn_a[T](param_a T, param_b string) {
// println(param_a)
// println(param_b)
// }
fn generic_fn_b[T,Y](param_a T, param_b Y) {
a := []T{}
b := map[T]int{}
c := map[T]Y{}
dump(a)
dump(b)
dump(c)
}
fn generic_fn_c[T,Y](param_a []T, param_b map[Y]T) {
println(param_a)
}
fn generic_fn_d[T,Y](param_a fn(T, Y)) {
println(param_a)
}
fn generic_fn_e[T,Y]( fn(T, fn(map[Y]Y) Y) ) {
println(param_a)
}
+23
View File
@@ -0,0 +1,23 @@
module main
type Expr = Ident | SelectorExpr
struct Ident {
name string
}
struct SelectorExpr {
lhs Expr
rhs Expr
// op int
}
fn main() {
a := Ident{
name: 'foo'
}
node := Expr(a)
if a.name == 'bar' {
} else if node !in [Ident, SelectorExpr] {
}
}
@@ -0,0 +1,19 @@
# Module Mutable Fields Example
This is a V2 fixture for `pub module_mut:` struct fields.
It demonstrates a field that is public for reading, but mutable only from the
module that declares the struct. A separate `pub mut:` field is included to show
the difference with a publicly mutable field.
The sources are stored as `.vv2` so shared V1/vfmt paths do not parse V2-only
syntax directly. To try it manually, copy the files to temporary `.v` files and
compile them with `-v2`.
Expected behavior:
- `counter.value` can be read from `main`;
- `counter.value` is changed through `state.Counter.inc()`, inside module
`state`;
- `counter.label` can be changed from `main` because it is under `pub mut:`;
- direct external mutation like `counter.value++` must be rejected.
@@ -0,0 +1,17 @@
module main
import state
fn main() {
mut counter := state.new_counter('jobs')
assert counter.value == 0
assert counter.inc() == 1
assert counter.inc() == 2
assert counter.value == 2
counter.label = 'builds'
assert counter.label == 'builds'
// This must stay rejected outside module `state`:
// counter.value++
}
@@ -0,0 +1,19 @@
module state
pub struct Counter {
pub module_mut:
value int
pub mut:
label string
}
pub fn new_counter(label string) Counter {
return Counter{
label: label
}
}
pub fn (mut c Counter) inc() int {
c.value++
return c.value
}
@@ -0,0 +1,13 @@
# Module Storage Example
This is a V2 fixture for module-scoped `__global` storage.
It is intentionally stored as `.vv2` source so shared V1/vfmt paths do not parse
V2-only public module-storage syntax directly. The regression test copies these
files to temporary `.v` files and compiles them with `-v2`.
Run:
```sh
./v test vlib/v2_toberemoved/types/module_storage_test.v
```
@@ -0,0 +1,12 @@
module main
import state
fn main() {
assert state.total_ticks == 0
assert state.tick() == 1
assert state.tick() == 2
state.total_ticks += 10
assert state.total_ticks == 12
assert state.private_tick_count() == 2
}
@@ -0,0 +1,18 @@
module state
__global mut private_ticks = 0
pub __global mut total_ticks = 0
fn bump_private() {
private_ticks += 1
}
pub fn tick() int {
bump_private()
total_ticks += 1
return private_ticks
}
pub fn private_tick_count() int {
return private_ticks
}
@@ -0,0 +1,32 @@
module main
struct StructA {
name string = 'struct a'
b StructB = StructB{}
}
struct StructB {
name string = 'struct b'
c StructC = StructC{}
}
struct StructC {
name string = 'struct c'
d StructD = StructD{}
}
struct StructD {
name string = 'struct d'
e StructE = StructE{}
}
struct StructE {
name string = 'struct e'
}
fn main() {
a := StructA{}
e := a.b.c.d.e
println(e.name)
println(a.b.c.d.e.name)
}
@@ -0,0 +1,20 @@
module main
fn test_main() {
string_literal_raw_a := r'raw string Literal b'
string_literal_inter_a := 'a == abc${a:2f} && and b == abc${b}...'
string_literal_inter_b := '${@MOD}.${@METHOD} - ${fn_call(unsafe { 1 })}'
string_literal_inter_c := '${mod.fn_call(1)} | ${mod.fn_call('a').join(' ')} > out'
// NOTE: d) tests nested quotes of same kind (although why is this allowed?)
string_literal_inter_d := '${mod.fn_call(1)} | ${mod.fn_call(unsafe { 1 }, mod.fn_call('a')).join(' ')} > out'
string_literal_inter_e := '${mod.fn_call(1)} | ${mod.fn_call(mod.fn_call('a')).join(' ')} > out'
// TODO: remember to talk to alex to confirm behaviour of nested strings
// x := 'hello ${foo('${x}')} ${x}'
}
fn test_basic() {
pi := 3.14159265359
pi_name := 'Pi'
pi_symbol := `π`
pi_description := '${pi_name} (${pi_symbol}) is a mathematical constant that is the ratio of a circle\'s circumference to its diameter, approximately equal ${pi:.5}.'
}
+670
View File
@@ -0,0 +1,670 @@
// this file is just to test the scanner & parser so there may
// be a bunch of stuff in here that does not really make sense
/* multi
line
comment */
/*// nested comment a */
/* // nested comment b */
/*/* nested comment c */*/
[has_globals]
module main
import mod_a
import mod_b.submod_a
import mod_c { sym_a, TypeA, TypeB[T] }
#include <header_a.h>
#flag -L lib_a
__global (
global_a string
global_b = 'global_b_value'
)
const (
const_a = 1
const_b = 'two'
)
// we don't want this parsed as `TypeA[unsafe]`
__global global_before_fn_with_attr_a TypeA
[unsafe]
pub fn fn_with_attr_after_global_a() {}
type AliasA = int
type SumTypeA = StructA | int | string | []string
pub type OptionalA = ?int
pub type DatabasePool[T] = fn (tid int) T
pub type C.BOOL = bool
// we don't want this to be parsed as:
// `type FnA = fn() fn...`
type FnA = fn()
fn fn_after_type_fn_a() int {}
// we don't want this to be parsed as:
// `type FnA = fn() ?fn...`
type FnB = fn() ?
fn fn_after_type_fn_b() int {}
pub const const_array_followed_by_attribute_a = ['a', 'b']
[attribute_after_array_init]
fn fn_with_attribute_after_array_init() { println('v') }
[attribute_a]
@[attribute_b]
enum EnumA {
value_a [json: 'ValueA']
value_b @[json: 'ValueB']
// NOTE: will not work with old attribute syntax due to ambiguity
value_c = 2 @[json: 'ValueC']
}
enum EnumB as u16 {
value_a
value_b
}
[attribute_a: 'attribute_a_val'; attribute_b]
@[attribute_c: 'attribute_c_val']
@[attribute_d]
['/product/edit'; post]
struct StructA {
field_a int
field_b string
field_c fn(int) int
field_d string = 'foo'
field_e int = 1 + 2 + (4*4)
// NOTE: will not work with old attribute syntax due to ambiguity
field_f string = 'bar' @[attribute_a; attribute_b]
field_g int = 111 @[attribute_a; attribute_b]
field_h int = field_h_default() @[attribute_a]
}
fn StructA.static_method_a() int {
return 1
}
// TODO: modifiers
struct StructB {
StructA // embedded
mut:
field_a int [attribute_a: 'value_a']
field_b string @[attribute_b: 'value_b']
field_c struct {
field_a string
field_b int = 1
}
}
struct StructC {
StructA
foo.StructA
mut: // TODO: modifiers
field_a int
field_b string
}
struct StructD {
field_a shared int
field_b shared []int = [0]
}
struct StructD {
field_a ?&StructD
}
struct C.StructA {}
interface InterfaceA {
field_a string
method_a() string
method_b(string) string
}
// TODO: modifiers
interface InterfaceB {
InterfaceA // embedded
mut:
method_a(string) string
}
interface InterfaceGenericA[T] {
field_a T
}
fn C.external_fn_a(arg_a int) int
__global total_m = 0
[unsafe]
fn fn_with_comment_and_attribute_a() {}
[attribute_a: 'attribute_a_val'; attribute_b]
[attribute_c: 'attribute_c_val']
[attribute_d]
fn fn_a(arg_a string, arg_b int) int {
println('fn_a(${arg_a}, ${arg_b})')
return 1
}
// TODO: error on missing name/type
// fn fn_b(arg_a string, arg_b, arg_c, arg_d int) int {
fn fn_b(arg_a string, arg_b int, arg_c int, arg_d int) int {
println('fn_b(${arg_a}, ${arg_b}, ${arg_c}, ${arg_d})')
return 1
}
fn fn_c(arg_a [][]StructA, arg_b [4]StructA) [][]StructA {
println('fn_b(${arg_a}, ${arg_b})')
return arg_a
}
fn fn_d(arg_a GenericStructA[int], arg_b moda.GenericStructA[int]) {
println('fn_d(${arg_a}, ${arg_b})')
}
fn C.fn_d(GenericStructA[int], moda.GenericStructA[int])
fn fn_optional_a() ?int {
return 1
}
fn fn_optional_b() ?int {
return fn_optional_a()?
}
fn fn_optional_c() ?&StructD {
a := StructD{
field_a: &StructD{}
}
dump(a.field_a)
dump(a.field_a?.field_a)
assert a.field_a?.field_a == none
return a.field_a?
}
fn fn_opt_c() ?int {
return fn_optional_a()!
}
fn fn_result_a() ! {
return 1
}
fn fn_result_b() !int {
return 1
}
fn fn_multi_return_a() (int, int) {
return 1,2
}
fn fn_multi_return_optional_a() ?(int, int) {
return 1,2
}
fn fn_variadic_a(arg_a int, arg_b ...string) {
fn_variadic_b(...arg_b)
fn_variadic_b(...['a', 'b', 'c', 'd'])
}
fn fn_variadic_b(arg_a ...string) {
println(arg_a)
}
fn fn_arg_struct_int_a(arg_a StructA, arg_b int) {
println(arg_a)
}
fn (rec &StructA) method_a(arg_a string, arg_b int) int {
println('StructA.method_a(${arg_a}, ${arg_b})')
return 1
}
// TODO: operator overload (last missing parser feature, I think :D)
pub fn (a StructA) == (b StructA) bool {
return a.field_a == b.field_a
}
fn channel_test(arg_a chan string) {
ch := chan int{cap: 20}
ch <- 111
rec := <-ch
}
fn spawn_test() {
t := spawn fn() {
for i in 0..100 {
println('${i}...')
}
}()
t.wait()
}
fn fn_result_a() !int {
array_a := [1,2,3,4]
return array_a[0]!
}
fn main_a() {
a := 1
b, c := 1, 2
array_init_a := [1,2,3,4]
array_init_b := [1,2,3,4]!
array_init_c := [array_init_a]
array_init_d := []string{len: 2, cap: 2}
array_init_e := [][]string{}
array_init_f := [2][]int{init:[1]}
array_init_g := [2][][][][]int{}
array_init_h := [2][][][][2]int{}
// TODO: better error for missing `]`
// array_init_i := [['a','b','c','d']
array_init_i := [['a','b','c','d']]
array_init_j := []&StructA{}
array_init_k := [fn(arg_a int) int { return 1 }]
array_init_i := [fn() int { return 1 }()]
array_init_thread_a := []thread int{cap: 16}
expr_a expr_b // TODO: error ?
expr_a; expr_b // TODO: error
map_init_long_string_string := map[string]string{}
map_init_long_string_array_string := map[string][]string{}
mut map_init_short_string_string := {'key_a': 'value_a'}
map_init_short_string_string = {} // test empty
map_init_short_string_array_string := {'key_a': ['value_a', 'value_b']}
map_init_short_ident_string := {key_a: 'value_a'} // unsupported key type
mut map_init_short_enum_value_init_expr := map[EnumA]StructA{}
// make sure we don't chain `StructA{field_a: 1}.value_b` as SelectorExpr
map_init_short_enum_value_init_expr = {
.value_a: StructA{
field_a: 1
}
.value_b: StructA{
field_a: 1
}
.value_c: StructA{
field_a: 1
}
}
struct_init_a := StructA{field_a: 1, field_b: 'v'}
struct_init_b := foo.StructA{field_a: 1, field_b: 'v'}
struct_init_c := StructA{1, 'v'}
// NOTE: no longer supported. will error
// assoc_old_a := {struct_a|field_a: 111}
// assoc_old_b := {
// ...struct_a
// field_a: 1
// }
assoc_current_a := StructA{
...struct_a
// field_a: 1
}
string_literal_v_a := 'string literal a'
string_literal_v_b := "string literal b"
string_literal_c_a := c'c string literal a'
string_literal_raw_a := r'string $literal raw a'
thred_init_a := thread int{cap: 20}
call_a := fn_a('string', 1)
call_b := fn_b('string', 1, a, b)
call_c := array_init_g[0](1)
call_d := struct_a.method_a('string', 1)
call_e := struct_a.field_c(1)
call_f := array_init_k[0]()
call_g := array_init_k[fn() { return 0 }()]()
call_h := array_init_k[array_init_b[0]]()
call_config_syntax_a := fn_arg_struct_int_a(field_a: 1, field_b: 'b', 2)
call_lambda_expr_a := array_init_a.sorted(|x,y| x > y)
call_lambda_expr_b := f(|| 1)
call_selector_a := 'hello v world'
.split(' v ')
.join(' ')
call_comptime_a := $fn_a('string', 1)
// comptime call as expr stmt only
$fn_a('string', 1)
$compile_warn('compile warn')
cast_a := u8(1)
cast_b := &[]u8([1,2,3,4])
// the following casts should error later about not being
// able to cast array types, unless it gets implemented.
cast_c := []u8([1,2,3,4])
cast_d := [][][]u8([[[1,2,3,4]]])
cast_d := ?&?int(a)
fn_literal_a := fn(param_a int, param_b int) int {
return param_a+param_b
}
fn_literal_call_a := fn_literal_a(2, 4)
fn_literal_direct_call_a := fn(param_a int, param_b int) int {
return param_a+param_b
}(2, 4)
fn_literal_capturing_vars_a := fn [infix_a, infix_b] (param_a int, param_b int) int {
return (infix_a+infix_b)*(param_a+param_b)
}
fn_literal_capturing_vars_direct_call_a := fn [infix_a, infix_b] (param_a int, param_b int) int {
return (infix_a+infix_b)*(param_a+param_b)
}(2, 4)
index_a := array_init_a[0]
index_a := array_init_a[a]
index_b := struct_a.field_b[1]
index_c := [StructA{}][0] // direct index after init
index_d := [[1,2,3,4]][0][1] // unlimited chaining (add more examples)
index_e := [fn() []StructA { return [fn() []StructA { return [StructA{}] }()][0] }()[0]][0] // more chaining
index_f := fn() []string { return ['a', 'b'] }()[0]
index_g := array_init_e[0] or { ['e', 'f'] }[0]
index_range_a := array_init_a[0..2]
index_range_b := array_init_a[2..]
index_range_c := array_init_a[..2]
index_range_d := array_init_a[1+2..1+2]
index_range_e := array_init_a[1+2..]
index_range_f := array_init_a[..1+2]
index_range_g := array_init_a[1+2...1+2]
index_range_h := array_init_a[1+2...]
index_range_i := array_init_a[...1+2]
index_range_j := [[1,2,3,4]][0][2..4]
index_range_k := [[1,2,3,4]][0][2...4]
index_or_a := array_init_a[0] or { 1 }
index_or_b := array_init_c[0] or { [5,6,7,8] }[0]
index_or_c := fn() []int { return [array_init_a[0] or { 1 }] }()[0] or { 1 }
index_or_d := match index_a {
int { array_init_a }
else { [5,6,7,8] }
}[0] or { 1 }
infix_a := 1 * 2
infix_b := 1 + 2 * 3 / 4 + 5
infix_c := infix_a * 4 * 2 + 11 / 2
infix_d := a == b && c == d
infix_and_paren_expr_a := ((((infix_b + 1) * 2) + 111) * 2) / 2
infix_and_paren_expr_b := (((((x * array_init_a[0] +
array_init_a[1]) * x + array_init_a[2]) * x + array_init_a[3]) * x +
array_init_a[4]) * x + array_init_a[5]) * x + array_init_a[6]
prefix_a := &StructA{}
prefix_b := &&StructA{}
prefix_c := -infix_a + 2
prefix_optional_a := ?mod_a.StructA{}
prefix_optional_b := ?mod_a.StructA(none)
assert a == 1
assert a == 1, 'a does not equal 1'
assert c <= 2, 'c is greater than 2'
if val := array_init_a[0] {
println(val)
}
if res_a := fn_optional_a() {
println('if guard: ${res_a}')
}
if res_a, res_b := fn_multi_return_optional_a() {
println('if guard: ${res_a}, ${res_b}')
}
if res_a, res_b := fn_optional_a(), fn_optional_b() {
println('if guard: ${res_a}, ${res_b}')
}
if err == IError(MyError{}) {
println('err == IError(MyError{})')
}
if struct_init_a == (StructA{}) {
println('struct_init_a == (StructA{})')
}
// TODO: tricky
// if struct_init_a == StructA{} {
// println('struct_init_a == StructA{}')
// }
// if StructA{} == StructA{} {
// println('StructA{} == StructA{}')
// }
// if struct_init_a is StructA {
// println(1)
// }
if struct_init_a is []StructA {
println(1)
}
if a == 1 {
println('1 a == ${s}')
}
else if a == 2 {
println('2 a == ${s}')
}
else {
println('a == ${s}')
}
if (if a > 0 {
1
} else {
2
}) < 2 {
println('if expr in if cond < 2')
}
if a > 0 { StructA{} } else { StructB{} }.method_a()
$if linux {
println('linux')
}
$else $if windows {
println('windows')
}
$else {
println('other')
}
$if option_a ? {
println('custom option: `v -d option_a`')
}
$if T is $array {
println('T is array')
}
$else $if T is $struct {
println('T is struct')
}
$if T in [?int, ?int] {
println('option int')
}
for val_a in array_init_a {
println(val_a)
}
// TODO: error (unless first 2 are allowed? 0..10 and 0..infinity)
// the third one definitely needs to error
// for val_a in ..10 {}
// for val_a in 0.. {}
// for val_a in .. {}
for val_a in 0..10 {
println(val_a)
}
for key_a, val_a in array_init_a {
println(key_a)
println(val_a)
}
for key_a, mut val_a in array_init_a {
println(key_a)
println(val_a)
}
for idx_a in 0 .. a + 1 {
println(idx_a)
}
for key, value in {
'a': 'apple'
'b': 'bananna'
} {
println('${key}: ${value}')
}
for mut left_node is ast.InfixExpr {
if left_node.op == .and && mut left_node.right is ast.InfixExpr {
if left_node.right.op == .key_is {
println('xx')
}
}
}
for a:=0; a<=100; a++ {
println(a)
}
for mut a:=0; a<=100; {
a++
println(a)
}
for a, b := 0, 1; a < 4; a++ {
println('${a} - ${b}')
}
for a, b, c, d := 0, 1, 2, 3; a < 4; a++ {
println('${a} - ${b}')
}
// currently erroring in this case
// for a := 1 {}
for ; x < 100; {
println(x)
}
for x < 100 {
println(x)
}
for ; ; {
println('infinite loop')
}
for {
println('infinite loop')
}
$for x == 1 {
println('comptime for')
}
$for field in U.fields {
// TODO: parser needs to handle
// currently just skipping past
if val.$(field.name).str() != 'Option(none)' {
fields_len++
}
}
for_label_a: for i := 4; true; i++ {
println(i)
for {
if i < 7 {
continue for_label_a
} else {
break for_label_a
}
}
}
// fn literals
// capture list & generic params
fn [a, b] [T] () {
println('captured vars: ${a}, ${b}')
}[int]()
// capture list only
fn [a, b] () {
println('captured vars: ${a}, ${b}')
}()
// generic params only
fn [T] () {
println(typeof(T))
}[int]()
sumtype_a := SumTypeA(111)
as_cast_a := sumtype_a as int
// NOTE: or for as is not currently supported
// I may remove it unless supported is added
as_cast_b := sumtype_a as int or {
println('cast error')
}
match sumtype_a {
StructA { println('StructA') }
int { println('int') }
string { println('string') }
[]string { println('[]string') }
}
mut ptr_a := &voidptr(0)
unsafe {
*ptr_a = 0
(*ptr_a) = *ptr_a - 1
((*ptr_a)) = *ptr_a - 1
*(ptr_a) = *ptr_a - 1
*((ptr_a)) = *ptr_a - 1
(*(ptr_a)) = *ptr_a - 1
}
mut ptr_b := &voidptr(0)
unsafe {
*ptr_b = 0
}
unsafe_a := unsafe { mut d := 1 d++ d }
unsafe_a := unsafe { mut d := 1; d++; d }
unsafe_b := unsafe {
mut d := 1
d++
d
}
shared array_int_shared_a := []int{}
shared array_string_shared_a := []String{}
lock {
array_int_shared_a << 1
array_int_shared_a << 2
}
lock array_string_shared_a {
array_string_shared_a << 'a'
array_string_shared_a << 'b'
}
lock array_int_shared; rlock array_string_shared {
array_int_shared << 3
println(array_string_shared[0])
}
lock a,b; rlock c,d; lock e,f; rlock g,h {
println('silly lock test')
}
fn_a('string', unsafe {*ptr_a})
{
block_test_a := 1
}
ch_a := chan int{}
_ = <-ch_a or {
println('channel closed')
}
select {
a := <-ch_a
b := <-ch_a { b+=2 }
c := <-ch_a or {
panic('channel closed')
}
500 * time.millisecond {
eprintln('> more than 0.5s passed without a channel being ready')
}
}
__asm {
ldrex tmp, [addr]
strex tmp, value, [addr]
}
sql := 'test_ident_named_sql'
db_a := sqlite.connect('db_a') or {
panic('could not connect to db: ${err}')
}
nr_items := sql db {
select count from items
}
users := sql db {
select from User where name == 'first${user_suffix}'
}
// TODO: REMOVE BELOW - TEMP TESTING OR MOVE TO APPROPRIATE PLACE ABOVE
x.member.free()
x.member.submember1.free()
x.member.submember1.submember2.free()
x.y = cmdline.option(current_args, arg, '10').int()
x.y = cmdline.option(current_args, arg,
'10').int()
assert 'href="${url('/test')}"' == 'href="/test.html"'
assert '"${show_info('abc')}"' == '"abc"'
// TODO: confirm there are no cases where
// there is ambiguity with `|` infix expr
// lines_indents := lines
// .filter(|line| !line.is_blank())``
// .map(|line| line.indent_width())
// TODO:
for mut x is MyType {
println(x)
}
ms := t.swatches[name].elapsed().microseconds()
if !v.pref.is_bare && v.pref.build_mode != .build_module &&
v.pref.os in [.linux, .freebsd, .openbsd, .netbsd, .dragonfly, .solaris, .haiku] {
}
rng.shuffle[T](mut res, config_)!
link_cmd := '${call(it.replace('.c',
'.o')).join(' ')}'
}
@@ -0,0 +1,21 @@
// this file is just to test the parser so there may be a
// bunch of stuff in here that does not really make sense
const len_a = 6
struct StructA {
// NOTE: ideally attributes would not use `[]`
// it would eliminate these issues completely.
// ambiguous: return `!` followed by attribute or
// result w/ fixed array `![attribute_a]func_b`?
// rely on newline and space between `!` and `[`,
// or check later if we are using a var or const?
// try eliminate this type of thing from the syntax.
// TODO/FIXME: currently broken, must fix.
func_a fn() ! [attribute_a]
// this is fine
func_b fn() ![len_a]u8
// fixed - parse as attribute, not as index of `'foo'`
field_c string = 'foo' [attribute_a]
}
@@ -0,0 +1,89 @@
// this file is just to test the parser so there may be a
// bunch of stuff in here that does not really make sense
module main
struct GenericStructA[T] {
field_a T
}
struct GenericStructB[T,U] {
field_a T
field_b U
}
fn fn_generic_a[T](param_a T, param_b string, param_c int) int {
println('fn_generic_a: ${param_a.type}, ${param_b.type}, ${param_c.type}')
return 1
}
fn fn_generic_b[T,Y](param_a T, param_b Y) int {
println('fn_generic_a: ${param_a.type}, ${param_b.type}')
}
fn fn_generic_c[fn[U,I](U, I) U, Y](param_a T, param_b Y) int {
println('fn_generic_c')
return 1
}
fn test_generic_struct_init() {
a := GenericStructA[int] {
field_a: 1
}
}
fn fn_generic_init_a[T](param_a T) {
// TODO: infer correct init after type checking
// eg. array, chan, map, or struct init.
mut a := T{}
for k, v in param_a {
a[k] = v
}
println(a)
}
fn test_generic_init() {
fn_generic_init_a[map[string]string]({'a': 'apple'})
}
// assoc works with generic structs although
// this will probably never be supported or used
fn test_generic_assoc() {
struct_a := GenericStructB[int,int]{field_a: 1, field_b: 2}
assoc_struct_b := GenericStructB[int,int]{
...struct_b
field_a: 10
field_b: 20
}
}
fn test_generic_call() {
call_generic_a := fn_generic_a[GenericStructA](GenericStructA{}, 'string', 1)
fn_generic_b[int,int](1,2)
}
fn test_generic_complex_or_nested() {
fn_generic_c[fn[U,I](U, I) U, I](fn[U,I](param_a U, param_b I) U {}, 1)
fn_generic_b[GenericStructA[Y],int](GenericStructA[int]{}, 1)
fn_generic_b[GenericStructA[Y],GenericStructA[Y]](GenericStructA[int]{}, 1)
struct_a := GenericStructA[int]{field_a: 1}
fn_generic_b[[]string,map[string]string{}](1, 1) // TODO: error
fn_a := fn(param_a string, param_b int, param_c int) {}
fn_b := fn(param_a string, param_b int, param_c int) {}
fn_c := fn(param_a string, param_b int, param_c int) {}
fn_a('a', a < b, a < b, c)
fn_a('a', foo: a < b, a < b, c)
fn_b('a', fn_generic_c[fn[T,Y](int),int](1))
fn_b('a', fn_generic_c[fn[T,Y](int),int](a < if (fn_generic_b[int,int](1,2) > 2) { 1 } else { 2 }, 2), 1)
fn_b('a', moda.fn_generic_b[fn[T,Y](int),int](a < if (fn_generic_b[int,int](1,2) > 2) { 1 } else { 2 }, 2), fn_generic_b[int,int](1,2))
fn_b('a', modb.submodb.fn_generic_b[int,int](fn_generic_b[int,int](fn_generic_b[int,int](1,2) < (fn_generic_b[int,int](1,2) - 2), 2)),fn_generic_b[int,int](1,2))
fn_c(fn_generic_b[GenericStructB[int,int]](GenericStructB<int>{}, 1), moda.fn_generic_b[GenericStructB[int,int]](GenericStructB[int]{}, 1))
fn_c(a < fn_generic_b[GenericStructB[GenericStructA[int],int]](GenericStructB[int]{}, 1), moda.fn_generic_b[GenericStructB[int,int]](GenericStructB<int>{}, 1))
// return if x < 64 { fn_generic_b[int,int](1,2) } else { fn_generic_b[int,int](1, 2) < (fn_generic_b[int,int](1, 2) - 2) }
return fn_generic_b[int,int](1, 2) < b, c > d, e < f, g > h, fn_generic_b[int,int](fn_generic_b[int,int](fn_generic_b[int,int](1, 2), 2), 2) > j, k < l, m
}
@@ -0,0 +1,35 @@
# Target Codegen Example
This is a V2 fixture for target-specific `cleanc` generation.
It is intentionally stored as `.vv2` source so shared V1/vfmt paths do not parse
V2-only or experimental command-line contracts directly. The builder E2E test
reads these files, writes them as temporary `.v` files, and runs the real
`cmd/v2` CLI.
The fixture is a compact demonstration of the supported user-facing contract:
- implicit host OS selection when `-os` is omitted;
- explicit `-os` overrides for concrete targets;
- `-os cross` preserving portable directive guards;
- pure `-freestanding -os none` generation with no concrete OS selected;
- advanced `-fhooks` isolation with `--skip-builtin --skip-type-check`;
- capability-specific `output`, `panic`, and `alloc` hook behavior.
V2 uses `cleanc` by default. `-b` is only needed when selecting a non-default
backend explicitly.
The regression tests keep unsupported/error-only programs inline in the test
file, so this directory stays readable as an example rather than a catalogue of
expected failures.
Fixture roles:
- `target_directives.vv2`: host/default target and concrete `-os` overrides.
- `cross_directives.vv2`: `-os cross` preserving portable directive guards.
- `freestanding_directives.vv2`: freestanding target directive selection.
- `freestanding_none.vv2`: pure `-freestanding -os none` platform contract.
- `freestanding_output.vv2`: `output` hook example.
- `freestanding_panic.vv2`: `panic` hook example.
- `freestanding_alloc.vv2`: `alloc` hook example.
- `freestanding_empty.vv2`: minimal source used for runtime-contract checks.
@@ -0,0 +1,8 @@
module main
#include linux <target_marker_linux.h>
#include macos <target_marker_macos.h>
#include windows <target_marker_windows.h>
#include cross <target_marker_cross.h>
fn main() {}
@@ -0,0 +1,12 @@
module main
struct Box {
value int
}
fn main() {
b := &Box{
value: 7
}
_ = b.value
}
@@ -0,0 +1,8 @@
module main
#include linux <target_marker_linux.h>
#include windows <target_marker_windows.h>
#include freestanding <target_marker_freestanding.h>
#flag freestanding -DPLATFORM_MARKER_FREESTANDING
fn main() {}
@@ -0,0 +1,3 @@
module main
fn main() {}
@@ -0,0 +1,9 @@
module main
#include freestanding <platform_none.h>
#flag freestanding -DPLATFORM_NONE_FREESTANDING
fn C.platform_none_tick() int
fn main() {
_ := C.platform_none_tick()
}
@@ -0,0 +1,5 @@
module main
fn main() {
println('x')
}
@@ -0,0 +1,5 @@
module main
fn main() {
panic('x')
}
@@ -0,0 +1,8 @@
module main
#include linux <target_marker_linux.h>
#include macos <target_marker_macos.h>
#include windows <target_marker_windows.h>
#include freestanding <target_marker_freestanding.h>
fn main() {}
+135
View File
@@ -0,0 +1,135 @@
module main
fn test_typeof_fn() {
assert typeof(fn (s string, x u32) (int, f32)).name == 'fn (string, u32) (int, f32)'
}
fn test_typeof_fn_literal() {
assert typeof(fn (i int) int {return i+1}).name == 'TODO'
}
fn test_typeof_int() {
assert typeof(int).idx == 7
assert typeof(int).name == 'int'
}
fn test_typeof_u32() {
assert typeof(u32).idx == 12
assert typeof(u32).name == 'u32'
}
fn test_typeof_string() {
assert typeof(string).idx == 20
assert typeof(string).name == 'string'
assert typeof[string]().idx == 20
}
fn test_typeof_optional_type() {
assert typeof(?string).name == '?string'
}
fn test_typeof_result_type() {
assert typeof(!string).name == '!string'
}
fn test_typeof_array_type() {
assert typeof([]string).name == '[]string'
assert typeof(['a', 'b']).name == '[]string'
}
fn test_typeof_array_index() {
assert typeof(['a', 'b'][0]).name == 'string'
}
fn test_typeof_map_type() {
assert typeof(map[string]int).name == 'map[string]int'
}
fn test_typeof_nil() {
assert typeof(nil).name == 'nil'
}
fn test_typeof_none() {
assert typeof(none).name == 'none'
}
fn test_typeof_pointer() {
assert typeof(&string).name == '&string'
}
//
struct MyStruct {}
struct MyGenericStruct[T] {}
struct MyGenericStruct2[T, U] {}
fn test_typeof_struct_type() {
assert typeof(MyStruct).name == 'MyStruct'
assert typeof(MyGenericStruct).name == 'MyGenericStruct'
assert typeof(MyGenericStruct[int]).name == 'MyGenericStruct<int>'
assert typeof(MyGenericStruct[string]).name == 'MyGenericStruct<string>'
assert typeof(MyGenericStruct2).name == 'MyGenericStruct2'
assert typeof(MyGenericStruct2[string, int]).name == 'MyGenericStruct2<string, int>'
}
//
union MyUnion {
x int
s string
}
fn test_typeof_union_type() {
assert typeof(MyUnion).name == 'MyUnion'
}
//
type Abc = int | string
fn test_typeof_sumtype() {
assert typeof(Abc).name == 'Abc'
}
//
enum EFoo {
a
b
c
}
fn test_typeof_enum() {
assert typeof(EFoo).name == 'EFoo'
}
//
type AnAlias = int
fn test_typeof_alias() {
assert typeof(AnAlias).name == 'AnAlias'
}
//
fn abc[T](x T) string {
return typeof(T).name
}
fn test_typeof_generic_type() {
assert abc<int>(123) == 'int'
assert abc<string>('xyz') == 'string'
}
//
fn test_typeof_idx_comparison() {
i := 123
u := u32(5)
assert typeof(int).idx == typeof(i).idx
assert typeof(u32).idx == typeof(u).idx
}