生成C代码
编译器本质上就是一门语言生成另一门语言的过程。
V目前的编译思路是:编译生成对应的C代码,然后调用C编译器来生成可执行文件。
V语言的开发重点在编译器前端,C就是编译器后端。
现在也生成了js代码,估计也会生成wasm代码。
或者考虑基于LLVM,生成LLVM IR。
或者直接生成机器码。
生成C代码
使用-o参数就可以,把当前目录的main.v代码生成main.c代码:
v -o main.c ./main.v
V代码编译后,生成单个文件的C代码。
通过查看V代码生成的C代码,可以更容易理解V编译器是如何编译的。
基本类型对应
V的基本类型通过C的类型别名typedef来实现:
//int类型没有类型别名,直接就是C的int类型
typedef int64_t i64;
typedef int16_t i16;
typedef int8_t i8;
typedef uint64_t u64;
typedef uint32_t u32;
typedef uint8_t u8;
typedef uint16_t u16;
//typedef uint8_t byte;
typedef uint32_t rune;
typedef size_t usize;
typedef ptrdiff_t isize;
#ifndef VNOFLOAT
typedef float f32;
typedef double f64;
#else
typedef int32_t f32;
typedef int64_t f64;
#endif
typedef int64_t int_literal;
#ifndef VNOFLOAT
typedef double float_literal;
#else
typedef int64_t float_literal;
#endif
typedef unsigned char* byteptr; //字节指针
typedef void* voidptr;//通用指针
typedef char* charptr; //C字符指针
typedef u8 array_fixed_byte_300 [300];
typedef struct sync__Channel* chan;
#ifndef __cplusplus
#ifndef bool
#ifdef CUSTOM_DEFINE_4bytebool
typedef int bool;
#else
typedef u8 bool; //布尔类型在C里面默认通过u8类型来实现,1字节
#endif
#define true 1 //true是整数常量1
#define false 0 //false是整数常量0
#endif
#endif
代码对照表
常量
int类型常量,生成C的宏定义,其他类型常量,生成C的全局变量。这样就很好理解,V语言中的常量可以是任何类型,跟变量一样,甚至可以是函数调用的结果。
常量的不可修改,由V编译器负责检查。
V代码:
const (
i = 1 // int类型的常量
pi = 3.14 //非int类型的常量
s = 'abc' //非int类型的常量
)
C代码:
//整数类型的常量通过C宏定义
#define _const_main__i 1
const f64 _const_main__pi = 3.14;
string _const_main__s;
_const_main__s = _SLIT("abc");
VV_LOCAL_SYMBOL void main__main(void) {
println(int_literal_str(_const_main__i));
println(float_literal_str(_const_main__pi));
println(_const_main__s);
}
//V代码
const (
a=i8(11)
b=i16(12)
c=i64(13)
d=byte(14)
e=u16(15)
f=u32(16)
g=u64(17)
h=f32(1.1)
i=f64(1.2)
bb=true
)
//C代码
i8 _const_a; // inited later
i16 _const_b; // inited later
i64 _const_c; // inited later
byte _const_d; // inited later
u16 _const_e; // inited later
u32 _const_f; // inited later
u64 _const_g; // inited later
f32 _const_h; // inited later
f64 _const_i; // inited later
bool _const_bb; // inited later
void _vinit() { //然后在_vinit函数进行初始化
_const_a = ((i8)(11));
_const_b = ((i16)(12));
_const_c = ((i64)(13));
_const_d = ((byte)(14));
_const_e = ((u16)(15));
_const_f = ((u32)(16));
_const_g = ((u64)(17));
_const_h = ((f32)(1.1));
_const_i = ((f64)(1.2));
_const_bb = true;
}
枚举
V的枚举生成等价的C枚举,枚举的pub属性在C中没有对应,由V编译器负责控制。
V代码:
pub enum Color {
blue = 1 //如果没有指定初始值,默认从0开始,然后往下递增1
green
white
black
}
fn main() {
c := Color.blue
println(c)
}
C代码:
typedef enum {
main__Color__blue = 1, // 1
main__Color__green, // 1+1
main__Color__white, // 1+2
main__Color__black, // 1+3
} main__Color;
main__Color c = main__Color__blue;
模块
V的模块,在生成对应C代码后,只是对应元素名称的前缀,毕竟C语言中没有模块的概念。
常量,结构体,接口,类型等一级元素生成C代码后的名称规则是:模块名__名称
,用双下划线区隔。例如:mymodule模块中的add()函数生成C代码后的名称为:mymodule__add()
。
结构体的方法等二级元素生成C代码后的名称规则是:模块名__类名_方法名
,用单下划线区隔。例如:模块中的Color结构体的str()方法生成C代码后的名称为:mymodule__Color_str()
。
V代码:
module main
pub fn main() {
println('abcd')
}
struct MyStruct {
x int
y int
}
pub fn (my_struct MyStruct) add() {
}
C代码:
void main__main(void) {
println(_SLIT("abcd"));
}
struct main__MyStruct {
int x;
int y;
};
void main__MyStruct_add(main__MyStruct my_struct) {
}
函数
模块中的函数,生成等价的C的函数。
V代码:
module main
fn main() {
println('from main')
add(1, 3)
}
// pub的模块访问控制由V编译器负责检查,C没有pub的对应
pub fn add(x int, y int) int {
if x > 0 {
return x + y
} else {
return x + y
}
}
C代码:
//生成函数声明段
VV_LOCAL_SYMBOL void main__main(void);
int add(int x, int y);
//主函数生成主函数
int main(int ___argc, char** ___argv){
g_main_argc = ___argc;
g_main_argv = ___argv;
#if defined(_VGCBOEHM)
GC_set_pages_executable(0);
GC_INIT();
#endif
_vinit(___argc, (voidptr)___argv);
main__main();
_vcleanup();
return 0;
}
//函数实现段
VV_LOCAL_SYMBOL void main__main(void) {
println(_SLIT("from main"));
main__add(1, 3);
}
int main__add(int x, int y) {
if (x > 0) {
int _t1 = x + y;
return _t1;
} else {
int _t2 = x + y;
return _t2;
}
return 0;
}
函数defer语句
C没有defer语句,V编译的时候就是把函数中的defer语句去掉,然后按后进先出的顺序,放在defer语句之后的所有return语句前,以及函数末尾,有各自独立的代码块。
V代码:
fn main() {
defer {
defer_fn1()
}
defer {
defer_fn2()
}
println('main start')
if 1 < 2 {
return
}
if 1 == 1 {
return
}
println('main end')
}
fn defer_fn1() {
println('from defer_fn1')
}
fn defer_fn2() {
println('from defer_fn2')
}
C代码:
VV_LOCAL_SYMBOL void main__main(void) {
bool main__main_defer_0 = false;
bool main__main_defer_1 = false;
main__main_defer_0 = true;
main__main_defer_1 = true;
println(_SLIT("main start"));
//defer语句之后的所有return语句之前
if (true) {
// Defer begin
if (main__main_defer_1) {
main__defer_fn2();
}
// Defer end
// Defer begin
if (main__main_defer_0) {
main__defer_fn1();
}
// Defer end
return;
}
//defer语句之后的所有return语句之前
if (true) {
// Defer begin
if (main__main_defer_1) {
main__defer_fn2();
}
// Defer end
// Defer begin
if (main__main_defer_0) {
main__defer_fn1();
}
// Defer end
return;
}
println(_SLIT("main end"));
//放在函数的最后
// Defer begin
if (main__main_defer_1) {
main__defer_fn2();
}
// Defer end
// Defer begin
if (main__main_defer_0) {
main__defer_fn1();
}
// Defer end
}
VV_LOCAL_SYMBOL void main__defer_fn1(void) {
println(_SLIT("from defer_fn1"));
}
VV_LOCAL_SYMBOL void main__defer_fn2(void) {
println(_SLIT("from defer_fn2"));
}
函数不确定个数参数
不确定参数就是根据返回值的类型,编译时动态生成一个C数组,作为函数的最后一个参数。
V代码:
fn my_fn(i int, s string, others ...string) {
println(i)
println(s)
println(others[0])
println(others[1])
println(others[2])
}
fn main() {
my_fn(1, 'abc', 'de', 'fg', 'hi')
}
C代码:
struct array {
int element_size;
voidptr data;
int offset;
int len;
int cap;
ArrayFlags flags;
};
typedef array Array_string;
VV_LOCAL_SYMBOL void main__my_fn(int i, string s, Array_string others) {
println(int_str(i));
println(s);
println((*(string*)array_get(others, 0)));
println((*(string*)array_get(others, 1)));
println((*(string*)array_get(others, 2)));
}
VV_LOCAL_SYMBOL void main__main(void) {
main__my_fn(1, _SLIT("abc"), new_array_from_c_array(3, 3, sizeof(string), _MOV((string[3]){_SLIT("de"), _SLIT("fg"), _SLIT("hi")})));
}
//C代码
struct varg_string { //自动生成不确定参数结构体
int len;
string args[4];
};
void main__my_fn(int i, string s, varg_string *others) {
printf("%d\n", i);
println(s);
println(others->args[0]);
println(others->args[1]);
println(others->args[2]);
}
void main__main() {
main__my_fn(
1, tos3("abc"),
&(varg_string){.len = 3, .args = {tos3("de"), tos3("fg"), tos3("hi")}});
}
函数多返回值
C的函数返回值只有1个,V的函数多返回值,就是把多返回值的组合,编译时动态生成一个结构体,然后返回结构体。并且生成的返回值组合的结构体,还可以给其他相同类型的多返回值的函数公用。
V代码:
fn foo() (int, int) { //多返回值
return 2, 3
}
fn multi_return_fn(a int, b int) (int, int) {
return a + 1, b + 1 //可以返回表达式
}
fn main() {
a, b := foo()
println(a) // 2
println(b) // 3
}
C代码:
typedef struct multi_return_int_int multi_return_int_int;
struct multi_return_int_int {
int arg0;
int arg1;
};
VV_LOCAL_SYMBOL multi_return_int_int main__multi_return_fn(int a, int b);
//生成的返回值组合的结构体,还可以给其他函数共用
VV_LOCAL_SYMBOL multi_return_int_int main__multi_return_fn(int a, int b) {
return (multi_return_int_int){.arg0=a + 1, .arg1=b + 1};
}
VV_LOCAL_SYMBOL void main__main(void) {
multi_return_int_int mr_271 = main__foo();
int a = mr_271.arg0;
int b = mr_271.arg1;
println(int_str(a));
println(int_str(b));
}
数组
V的数组是用struct来实现的,生成C代码也是struct。
V代码:
fn main() {
a := [1, 3, 5]
b := ['a', 'b', 'c']
println(a)
println(b)
}
C代码:
//第一部分: 从内置的vlib/built/array.v生成
typedef struct array array;
struct array {
int element_size;
voidptr data;
int offset;
int len;
int cap;
ArrayFlags flags;
};
//第二部分:从内置的vlib/built/array.v生成
typedef array Array_string;
typedef array Array_u8;
typedef array Array_int;
typedef array Array_voidptr;
typedef array Array_VCastTypeIndexName;
typedef array Array_MethodArgs;
typedef array Array_u8_ptr;
typedef array Array_rune;
typedef array Array_u64;
typedef array Array_u32;
typedef array Array_strconv__Uint128;
typedef array Array_f64;
//第三部分:数组使用的代码,字面量方式创建
VV_LOCAL_SYMBOL void main__main(void) {
Array_int a = new_array_from_c_array_noscan(3, 3, sizeof(int), _MOV((int[3]){1, 3, 5}));
Array_string b = new_array_from_c_array(3, 3, sizeof(string), _MOV((string[3]){_SLIT("a"), _SLIT("b"), _SLIT("c")}));
println(Array_int_str(a));
println(Array_string_str(b));
}
字符串
V的字符串是用struct来实现的,生成C代码也是struct。
V代码:
fn main(){
mystr:='abc'
mystr2:="def"
println(mystr)
println(mystr2)
}
C代码:
#define _SLIT(s) ((string){.str=(byteptr)("" s), .len=(sizeof(s)-1), .is_lit=1})
typedef struct string string;
struct string {
u8* str;
int len;
int is_lit;
};
VV_LOCAL_SYMBOL void main__main(void) {
string mystr = _SLIT("abc");
string mystr2 = _SLIT("def");
println(mystr);
println(mystr2);
}
字典
V的字典是用struct来实现的,生成C代码也是struct。
V代码:
fn main() {
mut m := map[string]int{}
m['one'] = 1
m['two'] = 2
println(m['one'])
println(m['bad_key'])
}
C代码:
typedef struct map map;
typedef map Map_string_int;
struct map {
int key_bytes;
int value_bytes;
u32 even_index;
u8 cached_hashbits;
u8 shift;
DenseArray key_values;
u32* metas;
u32 extra_metas;
bool has_string_keys;
MapHashFn hash_fn;
MapEqFn key_eq_fn;
MapCloneFn clone_fn;
MapFreeFn free_fn;
int len;
};
struct DenseArray {
int key_bytes;
int value_bytes;
int cap;
int len;
u32 deletes;
u8* all_deleted;
u8* keys;
u8* values;
};
typedef u64 (*MapHashFn)(voidptr);
typedef bool (*MapEqFn)(voidptr, voidptr);
typedef void (*MapCloneFn)(voidptr, voidptr);
typedef void (*MapFreeFn)(voidptr);
VV_LOCAL_SYMBOL map new_map_noscan_value(int key_bytes, int value_bytes, u64 (*hash_fn)(voidptr ), bool (*key_eq_fn)(voidptr , voidptr ), void (*clone_fn)(voidptr , voidptr ), void (*free_fn)(voidptr )) {
int metasize = ((int)(sizeof(u32) * (_const_init_capicity + _const_extra_metas_inc)));
bool has_string_keys = _us32_lt(sizeof(voidptr),key_bytes);
return ((map){
.key_bytes = key_bytes,
.value_bytes = value_bytes,
.even_index = _const_init_even_index,
.cached_hashbits = _const_max_cached_hashbits,
.shift = _const_init_log_capicity,
.key_values = new_dense_array_noscan(key_bytes, false, value_bytes, true),
.metas = ((u32*)(vcalloc_noscan(metasize))),
.extra_metas = _const_extra_metas_inc,
.has_string_keys = has_string_keys,
.hash_fn = (voidptr)hash_fn,
.key_eq_fn = (voidptr)key_eq_fn,
.clone_fn = (voidptr)clone_fn,
.free_fn = (voidptr)free_fn,
.len = 0,
});
}
VV_LOCAL_SYMBOL void main__main(void) {
Map_string_int m = new_map_noscan_value(sizeof(string), sizeof(int), &map_hash_string, &map_eq_string, &map_clone_string, &map_free_string)
;
map_set(&m, &(string[]){_SLIT("one")}, &(int[]) { 1 });
map_set(&m, &(string[]){_SLIT("two")}, &(int[]) { 2 });
println(int_str((*(int*)map_get(ADDR(map, m), &(string[]){_SLIT("one")}, &(int[]){ 0 }))));
println(int_str((*(int*)map_get(ADDR(map, m), &(string[]){_SLIT("bad_key")}, &(int[]){ 0 }))));
}
结构体
生成对应的C结构体:
V代码:
pub struct Point {
x int
y int
}
pub fn (p Point) str() string {
return 'x is ${p.x},y is:${p.y}'
}
fn main() {
p := Point{
x: 1
y: 3
}
println(p)
}
C代码:
//结构体和函数声明段
typedef struct main__Point main__Point;
string main__Point_str(main__Point p);
//结构体和函数实现段
struct main__Point {
int x;
int y;
};
string main__Point_str(main__Point p) {
string _t1 = str_intp(3, _MOV((StrIntpData[]){{_SLIT("x is "), /*100 &int*/0xfe07, {.d_i32 = p.x}}, {_SLIT(",y is:"), /*100 &int*/0xfe07, {.d_i32 = p.y}}, {_SLIT0, 0, { .d_c = 0 }}}));
return _t1;
}
VV_LOCAL_SYMBOL void main__main(void) {
main__Point p = ((main__Point){.x = 1,.y = 3,});
println(main__Point_str(p));
}
结构体方法
结构体方法生成C函数,只是函数的第一个参数是对应结构体类型的指针,
生成的C函数命名规则是:结构体名_方法名
。
V代码:
pub fn (mut a array) insert(i int, val voidptr) {
...
}
C代码:
void array_insert(array *a, int i, void *val) { //默认第一个参数是对应类型指针
...
}
结构体访问控制
访问控制在C代码中没有体现,全部在V编译器中控制。
V代码:
struct Foo {
a int //私有,不可变(默认).在模块内部可访问,不可修改;模块外不可访问,不可修改
mut:
b int // 私有,可变.在模块内部可访问,可修改,模块外部不可访问,不可修改
c int // (相同访问控制的字段可以放在一起)
pub:
d int // 公共,不可变,只读.在模块内部和外部都可以访问,但是不可修改
pub mut:
e int //公共,模块内部可访问,可修改;模块外部可访问,但是不可修改
__global:
f int // 全局字段,模块内部和外部都可访问,可修改,这样等于破坏了封装性,不推荐使用
}
fn main() {
f := Foo{}
println(f)
}
C代码:
typedef struct main__Foo main__Foo;
struct main__Foo {
int a;
int b;
int c;
int d;
int e;
int f;
};
VV_LOCAL_SYMBOL void main__main(void) {
main__Foo f = ((main__Foo){.a = 0,.b = 0,.c = 0,.d = 0,.e = 0,.f = 0,});
println(main__Foo_str(f));
}
流程控制语句
条件
if语句,生成C if语句:
V代码:
fn main() {
a := 10
b := 20
if a < b {
println('a<b')
} else if a > b {
println('a>b')
} else {
println('a=b')
}
}
C代码:
VV_LOCAL_SYMBOL void main__main(void) {
int a = 10;
int b = 20;
if (a < b) {
println(_SLIT("a<b"));
} else if (a > b) {
println(_SLIT("a>b"));
} else {
println(_SLIT("a=b"));
}
}
if表达式语句,生成C的三元运算符 ? :
V代码:
fn main() {
num := 777
s := if num % 2 == 0 {
'even'
} else {
'odd'
}
println(s) // "odd"
}
C代码:
VV_LOCAL_SYMBOL void main__main(void) {
int num = 777;
string s = (num % 2 == 0 ? (_SLIT("even")) : (_SLIT("odd")));
println(s);
}
分支
match语句,生成C的if-else if-else语句。
V代码:
fn main() {
os:='macos'
match os {
'windows' {
println('windows')
}
'linux' {
println('linux')
}
'macos' {
println('macos')
}
else {
println('unknow')
}
}
C代码:
VV_LOCAL_SYMBOL void main__main(void) {
string os = _SLIT("macos");
if (string__eq(os, _SLIT("windows"))) {
println(_SLIT("windows"));
}
else if (string__eq(os, _SLIT("linux"))) {
println(_SLIT("linux"));
}
else if (string__eq(os, _SLIT("macos"))) {
println(_SLIT("macos"));
}
else {
println(_SLIT("unknow"));
}
}
match表达式语句,生成嵌套的三元运算符语句。
V代码:
fn main() {
os := 'macos'
price := match os {
'windows' {
100
}
'linux' {
120
}
'macos' {
150
}
else {
0
}
}
println(price) //输出150
}
C代码:
VV_LOCAL_SYMBOL void main__main(void) {
string os = _SLIT("macos");
int price = ((string__eq(os, _SLIT("windows")))? (100) : (string__eq(os, _SLIT("linux")))? (120) : (string__eq(os, _SLIT("macos")))? (150) : (0));
println(int_str(price));
}
循环
步长:for i=0;i<100;i++ {}
V代码:
fn main() {
for i := 0; i < 10; i++ {
//跳过6
if i == 6 {
continue
}
println(i)
}
}
C代码:
VV_LOCAL_SYMBOL void main__main(void) {
for (int i = 0; i < 10; i++) {
if (i == 6) {
continue;
}
println(int_str(i));
}
}
循环:for i<100 {}
V代码:
fn main() {
mut sum := 0
mut i := 0
for i <= 100 {
sum += i
i++
}
println(sum) // 输出"5050"
}
C代码:
VV_LOCAL_SYMBOL void main__main(void) {
int sum = 0;
int i = 0;
for (;;) {
if (!(i <= 100)) break;
sum += i;
i++;
}
println(int_str(sum));
}
无限循环:for {}
V代码:
fn main() {
mut num := 0
for {
num++
if num >= 10 {
break
}
}
println(num) // "10"
}
C代码:
VV_LOCAL_SYMBOL void main__main(void) {
int num = 0;
for (;;) {
num++;
if (num >= 10) {
break;
}
}
println(int_str(num));
}
遍历:for i in xxx {}
V代码:
fn main() {
numbers := [1, 2, 3, 4, 5]
for i, num in numbers {
println('for-in')
}
}
C代码:
VV_LOCAL_SYMBOL void main__main(void) {
Array_int numbers = new_array_from_c_array_noscan(5, 5, sizeof(int), _MOV((int[5]){1, 2, 3, 4, 5}));
for (int i = 0; i < numbers.len; ++i) {
int num = ((int*)numbers.data)[i];
println(_SLIT("for-in"));
}
}
类型定义
类型定义type生成C的类型别名typedef。
V代码:
pub struct Point {
x int
y int
}
type Myint = int
type MyPoint = Point
C代码:
typedef struct main__Point main__Point;
typedef int main__Myint;
typedef main__Point main__MyPoint;
struct main__Point {
int x;
int y;
};
接口
在编译时穷举所有实现了接口的结构体,构造接口的结构体,接口结构体包含了一个匿名联合体和类型id。然后为每一个实现了接口的联合体生成一个创建函数,返回接口的结构体,并通过类型id标识具体的类型。
V代码:
module main
//接口要求结构体要实现方法为 pub fn (s MyStruct) write(a string) string
pub interface Foo {
write(string) string
}
struct MyStruct {}
pub fn (s MyStruct) write(a string) string {
return a
}
fn main() {
s1 := MyStruct{}
fn1(s1)
}
fn fn1(s Foo) {
println(s.write('Foo'))
}
C代码:
static char * v_typeof_interface_main__Foo(int sidx);
typedef struct main__Foo main__Foo;
typedef struct main__MyStruct main__MyStruct;
typedef struct main__MyStruct2 main__MyStruct2;
//实现了接口的结构体
struct main__MyStruct {
EMPTY_STRUCT_DECLARATION;
};
struct main__MyStruct2 {
EMPTY_STRUCT_DECLARATION;
};
//结构体的接口实现方法
string main__MyStruct_write(main__MyStruct s, string a) {
return a;
}
//结构体的接口实现方法
string main__MyStruct2_write(main__MyStruct2 s, string a) {
return a;
}
//接口的结构体,编译时穷举所有实现了该接口的结构体,包在匿名联合体内,并通过类型id标识
struct main__Foo {
union {
void* _object;
main__MyStruct* _main__MyStruct;
voidptr* _voidptr;
main__MyStruct2* _main__MyStruct2;
};
int _typ;
};
// Methods wrapper for interface "main__Foo"
static inline string main__MyStruct_write_Interface_main__Foo_method_wrapper(main__MyStruct* s, string a) {
return main__MyStruct_write(*s, a);
}
static inline string main__MyStruct2_write_Interface_main__Foo_method_wrapper(main__MyStruct2* s, string a) {
return main__MyStruct2_write(*s, a);
}
struct _main__Foo_interface_methods {
string (*_method_write)(void* _, string );
};
struct _main__Foo_interface_methods main__Foo_name_table[3] = {
{
._method_write = (void*) main__MyStruct_write_Interface_main__Foo_method_wrapper,
},
{
._method_write = (void*) 0,
},
{
._method_write = (void*) main__MyStruct2_write_Interface_main__Foo_method_wrapper,
},
};
//把具体的结构体转换成接口结构体函数
static main__Foo I_main__MyStruct_to_Interface_main__Foo(main__MyStruct* x);
const int _main__Foo_main__MyStruct_index = 0;
static main__Foo I_voidptr_to_Interface_main__Foo(voidptr* x);
const int _main__Foo_voidptr_index = 1;
static main__Foo I_main__MyStruct2_to_Interface_main__Foo(main__MyStruct2* x);
const int _main__Foo_main__MyStruct2_index = 2;
// Casting functions for converting "main__MyStruct" to interface "main__Foo"
static inline main__Foo I_main__MyStruct_to_Interface_main__Foo(main__MyStruct* x) {
return (main__Foo) {
._main__MyStruct = x,
._typ = _main__Foo_main__MyStruct_index,
};
}
// Casting functions for converting "voidptr" to interface "main__Foo"
static inline main__Foo I_voidptr_to_Interface_main__Foo(voidptr* x) {
return (main__Foo) {
._voidptr = x,
._typ = _main__Foo_voidptr_index,
};
}
// Casting functions for converting "main__MyStruct2" to interface "main__Foo"
static inline main__Foo I_main__MyStruct2_to_Interface_main__Foo(main__MyStruct2* x) {
return (main__Foo) {
._main__MyStruct2 = x,
._typ = _main__Foo_main__MyStruct2_index,
};
}
//
static char * v_typeof_interface_main__Foo(int sidx) { /* main.Foo */
if (sidx == _main__Foo_main__MyStruct_index) return "MyStruct";
if (sidx == _main__Foo_voidptr_index) return "voidptr";
if (sidx == _main__Foo_main__MyStruct2_index) return "MyStruct2";
return "unknown Foo";
}
static int v_typeof_interface_idx_main__Foo(int sidx) { /* main.Foo */
if (sidx == _main__Foo_main__MyStruct_index) return 95;
if (sidx == _main__Foo_voidptr_index) return 2;
if (sidx == _main__Foo_main__MyStruct2_index) return 96;
return 94;
}
//主函数
VV_LOCAL_SYMBOL void main__main(void) {
main__MyStruct *s1 = HEAP(main__MyStruct, (((main__MyStruct){EMPTY_STRUCT_INITIALIZATION})));
main__fn1(/*&main.Foo*/I_main__MyStruct_to_Interface_main__Foo(&(*(s1))));
}
VV_LOCAL_SYMBOL void main__fn1(main__Foo s) {
println(main__Foo_name_table[s._typ]._method_write(s._object, _SLIT("Foo")));
}
泛型
泛型函数/方法
编译时,穷举所有泛型函数实际调用的所有类型,为每一个实际调用的类型,生成对应版本的C函数。
V代码:
module main
fn simple[T](p T) T { // 泛型作为函数的参数,返回值
return p
}
fn multi[T, U](a T, b U) (T, U) { // 多个泛型
return a, b
}
fn main() {
//实际调用过:int,string,bool类型
simple(1)
simple('abc')
simple(true)
//实际调用过:int+string,f64+bool这两种类型的组合
multi(1,'abc')
multi(1.2,true)
}
C代码:
VV_LOCAL_SYMBOL int main__simple_T_int(int p);
VV_LOCAL_SYMBOL string main__simple_T_string(string p);
VV_LOCAL_SYMBOL bool main__simple_T_bool(bool p);
VV_LOCAL_SYMBOL multi_return_int_string main__multi_T_int_string(int a, string b);
VV_LOCAL_SYMBOL multi_return_f64_bool main__multi_T_f64_bool(f64 a, bool b);
//实际调用过:int,string,bool类型
VV_LOCAL_SYMBOL int main__simple_T_int(int p) {
return p;
}
VV_LOCAL_SYMBOL string main__simple_T_string(string p) {
return p;
}
VV_LOCAL_SYMBOL bool main__simple_T_bool(bool p) {
return p;
}
//实际调用过:int+string,f64+bool这两种类型的组合
VV_LOCAL_SYMBOL multi_return_int_string main__multi_T_int_string(int a, string b) {
return (multi_return_int_string){.arg0=a, .arg1=b};
}
VV_LOCAL_SYMBOL multi_return_f64_bool main__multi_T_f64_bool(f64 a, bool b) {
return (multi_return_f64_bool){.arg0=a, .arg1=b};
}
VV_LOCAL_SYMBOL void main__main(void) {
main__simple_T_int(1);
main__simple_T_string(_SLIT("abc"));
main__simple_T_bool(true);
main__multi_T_int_string(1, _SLIT("abc"));
main__multi_T_f64_bool(1.2, true);
}
泛型结构体
编译时,穷举所有泛型类型实际调用的所有类型,为每一个实际调用的类型,生成对应版本的C结构体。
V代码:
module main
struct Info[T] { //泛型结构体
data T //泛型作为字段的类型
}
struct Foo[A, B] {
mut: // 多个泛型
a A
b B
}
fn main() {
i := Info[int]{
data: 1
}
s := Info[string]{
data: 'abc'
}
b := Info[bool]{
data: true
}
println(i)
println(s)
println(b)
x := Foo[int, string]{
a: 1
b: 'abc'
}
y := Foo[f64, bool]{
a: 1.2
b: true
}
println(x)
println(y)
}
C代码:
typedef struct main__Info_T_string main__Info_T_string;
typedef struct main__Info_T_int main__Info_T_int;
typedef struct main__Info_T_bool main__Info_T_bool;
typedef struct main__Foo_T_int_string main__Foo_T_int_string;
typedef struct main__Foo_T_f64_bool main__Foo_T_f64_bool;
struct main__Info_T_string {
string data;
};
struct main__Info_T_int {
int data;
};
struct main__Info_T_bool {
bool data;
};
struct main__Foo_T_int_string {
int a;
string b;
};
struct main__Foo_T_f64_bool {
f64 a;
bool b;
};
VV_LOCAL_SYMBOL void main__main(void) {
main__Info_T_int i = ((main__Info_T_int){.data = 1,});
main__Info_T_string s = ((main__Info_T_string){.data = _SLIT("abc"),});
main__Info_T_bool b = ((main__Info_T_bool){.data = true,});
println(main__Info_T_int_str(i));
println(main__Info_T_string_str(s));
println(main__Info_T_bool_str(b));
main__Foo_T_int_string x = ((main__Foo_T_int_string){.a = 1,.b = _SLIT("abc"),});
main__Foo_T_f64_bool y = ((main__Foo_T_f64_bool){.a = 1.2,.b = true,});
println(main__Foo_T_int_string_str(x));
println(main__Foo_T_f64_bool_str(y));
}
泛型接口
编译时,穷举所有泛型接口实际调用的所有类型,为每一个实际调用的类型,生成对应版本的C结构体。
V代码:
//定义泛型接口
interface Gettable[T] {
get() T
}
struct Animal[T] {
metadata T
}
// Animal实现泛型接口
fn (a Animal[T]) get[T]() T {
return a.metadata
}
struct Mineral[T] {
value T
}
// Mineral也实现泛型接口
fn (m Mineral[T]) get[T]() T {
return m.value
}
fn extract[T](xs []Gettable[T]) []T { //使用泛型接口
return xs.map(it.get())
}
fn extract_basic[T](xs Gettable[T]) T { //使用泛型接口
return xs.get()
}
fn main() {
a := Animal[int]{123}
b := Animal[int]{456}
c := Mineral[int]{789}
arr := [Gettable[int](a), Gettable[int](b), Gettable[int](c)]
println(typeof(arr).name) //输出:[]Gettable[int]
x := extract[int](arr)
println(x)
aa := extract_basic(a)
bb := extract_basic(b)
cc := extract_basic(c)
println('${aa} | ${bb} | ${cc}') //输出:123 | 456 | 789
}
C代码:
#define HEAP(type, expr) ((type*)memdup((void*)&((type[]){expr}[0]), sizeof(type)))
//
typedef struct main__Animal_T_int main__Animal_T_int;
typedef struct main__Mineral_T_int main__Mineral_T_int;
typedef struct main__Gettable main__Gettable;
typedef struct main__Gettable_T_int main__Gettable_T_int;
static char * v_typeof_interface_main__Gettable_T_int(int sidx);
VV_LOCAL_SYMBOL Array_int main__extract_T_int(Array_main__Gettable_T_int xs);
VV_LOCAL_SYMBOL int main__extract_basic_T_int(main__Gettable_T_int xs);
static main__Gettable_T_int I_main__Animal_T_int_to_Interface_main__Gettable_T_int(main__Animal_T_int* x);
const int _main__Gettable_T_int_main__Animal_T_int_index = 0;
static main__Gettable_T_int I_voidptr_to_Interface_main__Gettable_T_int(voidptr* x);
const int _main__Gettable_T_int_voidptr_index = 1;
static main__Gettable_T_int I_main__Mineral_T_int_to_Interface_main__Gettable_T_int(main__Mineral_T_int* x);
const int _main__Gettable_T_int_main__Mineral_T_int_index = 2;
// ^^^ number of types for interface main__Gettable_T_int: 3
// Methods wrapper for interface "main__Gettable_T_int"
static inline int main__Animal_T_int_get_T_int_Interface_main__Gettable_T_int_method_wrapper(main__Animal_T_int* a) {
return main__Animal_T_int_get_T_int(*a);
}
static inline int main__Mineral_T_int_get_T_int_Interface_main__Gettable_T_int_method_wrapper(main__Mineral_T_int* m) {
return main__Mineral_T_int_get_T_int(*m);
}
struct _main__Gettable_T_int_interface_methods {
int (*_method_get)(void* _);
};
struct _main__Gettable_T_int_interface_methods main__Gettable_T_int_name_table[3] = {
{
._method_get = (void*) main__Animal_T_int_get_T_int_Interface_main__Gettable_T_int_method_wrapper,
},
{
._method_get = (void*) 0,
},
{
._method_get = (void*) main__Mineral_T_int_get_T_int_Interface_main__Gettable_T_int_method_wrapper,
},
};
// Casting functions for converting "main__Animal_T_int" to interface "main__Gettable_T_int"
static inline main__Gettable_T_int I_main__Animal_T_int_to_Interface_main__Gettable_T_int(main__Animal_T_int* x) {
return (main__Gettable_T_int) {
._main__Animal_T_int = x,
._typ = _main__Gettable_T_int_main__Animal_T_int_index,
};
}
// Casting functions for converting "voidptr" to interface "main__Gettable_T_int"
static inline main__Gettable_T_int I_voidptr_to_Interface_main__Gettable_T_int(voidptr* x) {
return (main__Gettable_T_int) {
._voidptr = x,
._typ = _main__Gettable_T_int_voidptr_index,
};
}
// Casting functions for converting "main__Mineral_T_int" to interface "main__Gettable_T_int"
static inline main__Gettable_T_int I_main__Mineral_T_int_to_Interface_main__Gettable_T_int(main__Mineral_T_int* x) {
return (main__Gettable_T_int) {
._main__Mineral_T_int = x,
._typ = _main__Gettable_T_int_main__Mineral_T_int_index,
};
}
VV_LOCAL_SYMBOL Array_int main__extract_T_int(Array_main__Gettable_T_int xs) {
Array_int _t2 = {0};
Array_main__Gettable_T_int _t2_orig = xs;
int _t2_len = _t2_orig.len;
_t2 = __new_array_noscan(0, _t2_len, sizeof(int));
for (int _t3 = 0; _t3 < _t2_len; ++_t3) {
main__Gettable_T_int it = ((main__Gettable_T_int*) _t2_orig.data)[_t3];
int ti = main__Gettable_T_int_name_table[it._typ]._method_get(it._object);
array_push_noscan((array*)&_t2, &ti);
}
Array_int _t1 =_t2;
return _t1;
}
VV_LOCAL_SYMBOL int main__extract_basic_T_int(main__Gettable_T_int xs) {
int _t1 = main__Gettable_T_int_name_table[xs._typ]._method_get(xs._object);
return _t1;
}
VV_LOCAL_SYMBOL Array_int main__extract_T_int(Array_main__Gettable_T_int xs) {
Array_int _t2 = {0};
Array_main__Gettable_T_int _t2_orig = xs;
int _t2_len = _t2_orig.len;
_t2 = __new_array_noscan(0, _t2_len, sizeof(int));
for (int _t3 = 0; _t3 < _t2_len; ++_t3) {
main__Gettable_T_int it = ((main__Gettable_T_int*) _t2_orig.data)[_t3];
int ti = main__Gettable_T_int_name_table[it._typ]._method_get(it._object);
array_push_noscan((array*)&_t2, &ti);
}
Array_int _t1 =_t2;
return _t1;
}
VV_LOCAL_SYMBOL int main__extract_basic_T_int(main__Gettable_T_int xs) {
int _t1 = main__Gettable_T_int_name_table[xs._typ]._method_get(xs._object);
return _t1;
}
//泛型结构体,实际调用的结构体
struct main__Animal_T_int {
int metadata;
};
struct main__Mineral_T_int {
int value;
};
//泛型接口,实际调用的结构体
struct main__Gettable_T_int {
union {
void* _object;
main__Animal_T_int* _main__Animal_T_int;
voidptr* _voidptr;
main__Mineral_T_int* _main__Mineral_T_int;
};
int _typ;
};
//主函数
VV_LOCAL_SYMBOL void main__main(void) {
main__Animal_T_int *a = HEAP(main__Animal_T_int, (((main__Animal_T_int){.metadata = 123,})));
main__Animal_T_int *b = HEAP(main__Animal_T_int, (((main__Animal_T_int){.metadata = 456,})));
main__Mineral_T_int *c = HEAP(main__Mineral_T_int, (((main__Mineral_T_int){.value = 789,})));
Array_main__Gettable_T_int arr = new_array_from_c_array(3, 3, sizeof(main__Gettable_T_int), _MOV((main__Gettable_T_int[3]){/*&main.Gettable[int]*/I_main__Animal_T_int_to_Interface_main__Gettable_T_int(&(*(a))), /*&main.Gettable[int]*/I_main__Animal_T_int_to_Interface_main__Gettable_T_int(&(*(b))), /*&main.Gettable[int]*/I_main__Mineral_T_int_to_Interface_main__Gettable_T_int(&(*(c)))}));
println(_SLIT("[]Gettable[int]"));
Array_int x = main__extract_T_int(arr);
println(Array_int_str(x));
int aa = main__extract_basic_T_int(/*&main.Gettable[int]*/I_main__Animal_T_int_to_Interface_main__Gettable_T_int(&(*(a))));
int bb = main__extract_basic_T_int(/*&main.Gettable[int]*/I_main__Animal_T_int_to_Interface_main__Gettable_T_int(&(*(b))));
int cc = main__extract_basic_T_int(/*&main.Gettable[int]*/I_main__Mineral_T_int_to_Interface_main__Gettable_T_int(&(*(c))));
println( str_intp(4, _MOV((StrIntpData[]){{_SLIT0, /*100 &int*/0xfe07, {.d_i32 = aa}}, {_SLIT(" | "), /*100 &int*/0xfe07, {.d_i32 = bb}}, {_SLIT(" | "), /*100 &int*/0xfe07, {.d_i32 = cc}}, {_SLIT0, 0, { .d_c = 0 }}})));
}
泛型联合类型
编译时,也是穷举所有实际调用的类型,生成对应的C结构体。
V代码:
struct None {}
//定义泛型联合类型,把泛型作为联合类型中的子类
type MyOption[T] = Error | None | T
fn unwrap_if[T](o MyOption[T]) T {
if o is T {
return o
}
panic('no value')
}
fn main() {
y := MyOption[bool](false)
println(unwrap_if(y)) //输出false
}
C代码:
typedef struct main__MyOption_T_bool main__MyOption_T_bool;
VV_LOCAL_SYMBOL bool main__unwrap_if_T_bool(main__MyOption_T_bool o);
struct main__MyOption_T_bool {
union {
Error* _Error;
main__None* _main__None;
bool* _bool;
};
int _typ;
};
static inline main__MyOption_T_bool bool_to_sumtype_main__MyOption_T_bool(bool* x) {
bool* ptr = memdup(x, sizeof(bool));
return (main__MyOption_T_bool){ ._bool = ptr, ._typ = 18};
}
char * v_typeof_sumtype_main__MyOption_T_bool(int sidx) { /* main.MyOption[bool] */
switch(sidx) {
case 97: return "MyOption[bool]";
case 75: return "Error";
case 94: return "None";
case 18: return "bool";
default: return "unknown MyOption[bool]";
}
}
int v_typeof_sumtype_idx_main__MyOption_T_bool(int sidx) { /* main.MyOption[bool] */
switch(sidx) {
case 97: return 97;
case 75: return 75;
case 94: return 94;
case 18: return 18;
default: return 97;
}
}
//
VV_LOCAL_SYMBOL bool main__unwrap_if_T_bool(main__MyOption_T_bool o) {
if ((o)._typ == 18 /* bool */) {
return (*o._bool);
}
_v_panic(_SLIT("no value"));
VUNREACHABLE();
return 0;
}
//
VV_LOCAL_SYMBOL void main__main(void) {
main__MyOption_T_bool y = bool_to_sumtype_main__MyOption_T_bool(ADDR(bool, (false)));
println(main__unwrap_if_T_bool(y) ? _SLIT("true") : _SLIT("false"));
}
错误处理
跟函数的多返回值类似,编译器为每一种返回类型,生成一个对应类型的结构体,全局共用。
V代码:
module main
// ?表示疑问,表示可能返回期望的类型,也可能返回一个空值none
pub fn return_type_or_none(x int) ?int {
match x {
0 { return none }
else { return x }
}
}
// !表示警告,表示可能返回期望的类型,也可能返回一个错误IError
pub fn return_type_or_error(x int) !int {
match x {
0 { return error('error: x can not be 0') }
else { return x }
}
}
fn main() {
v1 := return_type_or_none(0) or {
match err {
none { 10 } //如果返回空值none,可以指定默认值
else { panic(err) }
}
}
println(v1)
v2 := return_type_or_none(1) or {
match err {
none { 10 } //如果返回空值none,可以指定默认值
else { panic(err) }
}
}
println(v2)
v3 := return_type_or_error(2) or { panic(err) }
println(v3)
v4 := return_type_or_error(0) or { panic(err) }
println(v4)
}
C代码:
typedef struct _option_int _option_int;
typedef struct _result_int _result_int;
struct IError {
union {
void* _object;
None__* _None__;
voidptr* _voidptr;
Error* _Error;
MessageError* _MessageError;
};
int _typ;
string* msg;
int* code;
};
struct _option_int { //整型的选项类型
byte state;
IError err;
byte data[sizeof(int) > 1 ? sizeof(int) : 1];
};
struct _result_int { //整型的错误类型
bool is_error;
IError err;
byte data[sizeof(int) > 1 ? sizeof(int) : 1];
};
_option_int main__return_type_or_none(int x) {
switch (x) {
case 0: {
return (_option_int){ .state=2, .err=_const_none__, .data={EMPTY_STRUCT_INITIALIZATION} };
}
default: {
_option_int _t2;
_option_ok(&(int[]) { x }, (_option*)(&_t2), sizeof(int));
return _t2;
}
}
return (_option_int){0};
}
_result_int main__return_type_or_error(int x) {
switch (x) {
case 0: {
return (_result_int){ .is_error=true, .err=_v_error(_SLIT("error: x can not be 0")), .data={EMPTY_STRUCT_INITIALIZATION} };
}
default: {
_result_int _t2;
_result_ok(&(int[]) { x }, (_result*)(&_t2), sizeof(int));
return _t2;
}
}
return (_result_int){0};
}
VV_LOCAL_SYMBOL void main__main(void) {
_option_int _t1 = main__return_type_or_none(0);
if (_t1.state != 0) {
IError err = _t1.err;
int_literal _t2 = 0;
if (err._typ == _IError_None___index) {
_t2 = 10;
}
else {
_v_panic(IError_str(err));
VUNREACHABLE();
}
*(int*) _t1.data = _t2;
}
int v1 = (*(int*)_t1.data);
println(int_str(v1));
_option_int _t3 = main__return_type_or_none(1);
if (_t3.state != 0) {
IError err = _t3.err;
int_literal _t4 = 0;
if (err._typ == _IError_None___index) {
_t4 = 10;
}
else {
_v_panic(IError_str(err));
VUNREACHABLE();
}
*(int*) _t3.data = _t4;
}
int v2 = (*(int*)_t3.data);
println(int_str(v2));
_result_int _t5 = main__return_type_or_error(2);
if (_t5.is_error) {
IError err = _t5.err;
_v_panic(IError_str(err));
VUNREACHABLE();
;
}
int v3 = (*(int*)_t5.data);
println(int_str(v3));
_result_int _t6 = main__return_type_or_error(0);
if (_t6.is_error) {
IError err = _t6.err;
_v_panic(IError_str(err));
VUNREACHABLE();
;
}
int v4 = (*(int*)_t6.data);
println(int_str(v4));
}
联合类型
联合类型,使用C结构体,结构体中包含一个匿名联合体,以及类型id。并且为联合类型的每一个类型,自动生成一个创建函数。
V代码:
struct User {
name string
age int
}
pub fn (m &User) str() string {
return 'name:${m.name},age:${m.age}'
}
type MySum = User | int | string //联合类型声明
pub fn add(ms MySum) {
match ms {
int {
println('ms is int,value is ${ms.str()}')
}
string {
println('ms is string,value is ${ms}')
}
User {
println('ms is User,value is ${ms.str()}')
}
}
}
pub fn main() {
i := 1
add(i)
s := 'abc'
add(s)
u := User{
name: 'n'
age: 10
}
add(u)
}
C代码:
typedef struct main__MySum main__MySum;
void main__add(main__MySum ms);
struct main__User {
string name;
int age;
};
struct main__MySum { //联合类型结构体
union { //匿名联合体
main__User* _main__User;
int* _int;
string* _string;
};
int _typ; //类型id
};
string main__User_str(main__User* m) {
string _t1 = str_intp(3, _MOV((StrIntpData[]){{_SLIT("name:"), /*115 &string*/0xfe10, {.d_s = m->name}}, {_SLIT(",age:"), /*100 &int*/0xfe07, {.d_i32 = m->age}}, {_SLIT0, 0, { .d_c = 0 }}}));
return _t1;
}
void main__add(main__MySum ms) {
if (ms._typ == 7 /* int */) {
println( str_intp(2, _MOV((StrIntpData[]){{_SLIT("ms is int,value is "), /*115 &string*/0xfe10, {.d_s = int_str((*ms._int))}}, {_SLIT0, 0, { .d_c = 0 }}})));
}
else if (ms._typ == 20 /* string */) {
println( str_intp(2, _MOV((StrIntpData[]){{_SLIT("ms is string,value is "), /*115 &string*/0xfe10, {.d_s = (*ms._string)}}, {_SLIT0, 0, { .d_c = 0 }}})));
}
else if (ms._typ == 94 /* main.User */) {
println( str_intp(2, _MOV((StrIntpData[]){{_SLIT("ms is User,value is "), /*115 &string*/0xfe10, {.d_s = main__User_str(&(*ms._main__User))}}, {_SLIT0, 0, { .d_c = 0 }}})));
}
}
//联合类型有几个类型,就有几个创建函数,统一转换成联合体类型
//整型的创建函数
static inline main__MySum int_to_sumtype_main__MySum(int* x) {
int* ptr = memdup(x, sizeof(int));
return (main__MySum){ ._int = ptr, ._typ = 7};
}
//字符串类型的创建函数
static inline main__MySum string_to_sumtype_main__MySum(string* x) {
string* ptr = memdup(x, sizeof(string));
return (main__MySum){ ._string = ptr, ._typ = 20};
}
//User类型的创建函数
static inline main__MySum main__User_to_sumtype_main__MySum(main__User* x) {
main__User* ptr = memdup(x, sizeof(main__User));
return (main__MySum){ ._main__User = ptr, ._typ = 94};
}
void main__main(void) {
int i = 1;
main__add(int_to_sumtype_main__MySum(&i));
string s = _SLIT("abc");
main__add(string_to_sumtype_main__MySum(&s));
main__User u = ((main__User){.name = _SLIT("n"),.age = 10,});
main__add(main__User_to_sumtype_main__MySum(&u));
}
运算符重载
编译时,将重载运算符,转换成普通C函数。
V代码:
module main
struct Vec {
x int
y int
}
//四则运算符
pub fn (a Vec) + (b Vec) Vec {
return Vec{a.x + b.x, a.y + b.y}
}
pub fn (a Vec) - (b Vec) Vec {
return Vec{a.x - b.x, a.y - b.y}
}
pub fn (a Vec) * (b Vec) Vec {
return Vec{a.x * b.x, a.y * b.y}
}
pub fn (a Vec) / (b Vec) Vec {
return Vec{a.x / b.x, a.y / b.y}
}
fn (a Vec) % (b Vec) Vec {
return Vec{a.x % b.x, a.y % b.y}
}
//比较运算符,只需要重载<和==,其他比较运算符不用自己定义,编译器会基于<和==自动生成
fn (a Vec) == (b Vec) bool {
return a.x == b.x && a.y == b.y
}
fn (a Vec) < (b Vec) bool {
return a.x < b.x && a.y < b.y
}
fn (a Vec) str() string {
return '{${a.x}, ${a.y}}'
}
fn main() {
mut a := Vec{8, 15}
b := Vec{4, 5}
//四则运算符
println(a + b) // {12,20}
println(a - b) // {4,10}
println(a * b) // {32,75}
println(a / b) // {2,3}
println(a % b) // {0,0}
//分配运算符,分配运算符不用自己定义,会基于四则运算符自动生成
a += b
println('a+=b is: ${a}')
a -= b
println('a-=b is: ${a}')
a *= b
println('a*=b is: ${a}')
a /= b
println('a/=b is: ${a}')
//比较运算符
println(a == b) // false
println(a != b) // true
println(a > b) // true
println(a >= b) // true
println(a < b) // false
println(a <= b) // false
}
C代码:
typedef struct main__Vec main__Vec;
struct main__Vec {
int x;
int y;
};
//将重载运算符,转换成普通C函数
main__Vec main__Vec__plus(main__Vec a, main__Vec b) {
main__Vec _t1 = ((main__Vec){.x = a.x + b.x,.y = a.y + b.y,});
return _t1;
}
main__Vec main__Vec__minus(main__Vec a, main__Vec b) {
main__Vec _t1 = ((main__Vec){.x = a.x - b.x,.y = a.y - b.y,});
return _t1;
}
main__Vec main__Vec__mult(main__Vec a, main__Vec b) {
main__Vec _t1 = ((main__Vec){.x = a.x * b.x,.y = a.y * b.y,});
return _t1;
}
main__Vec main__Vec__div(main__Vec a, main__Vec b) {
main__Vec _t1 = ((main__Vec){.x = a.x / b.x,.y = a.y / b.y,});
return _t1;
}
VV_LOCAL_SYMBOL main__Vec main__Vec__mod(main__Vec a, main__Vec b) {
main__Vec _t1 = ((main__Vec){.x = a.x % b.x,.y = a.y % b.y,});
return _t1;
}
VV_LOCAL_SYMBOL bool main__Vec__eq(main__Vec a, main__Vec b) {
bool _t1 = a.x == b.x && a.y == b.y;
return _t1;
}
VV_LOCAL_SYMBOL bool main__Vec__lt(main__Vec a, main__Vec b) {
bool _t1 = a.x < b.x && a.y < b.y;
return _t1;
}
VV_LOCAL_SYMBOL string main__Vec_str(main__Vec a) {
string _t1 = str_intp(3, _MOV((StrIntpData[]){{_SLIT("{"), /*100 &int*/0xfe07, {.d_i32 = a.x}}, {_SLIT(", "), /*100 &int*/0xfe07, {.d_i32 = a.y}}, {_SLIT("}"), 0, { .d_c = 0 }}}));
return _t1;
}
//主函数
VV_LOCAL_SYMBOL void main__main(void) {
main__Vec a = ((main__Vec){.x = 8,.y = 15,});
main__Vec b = ((main__Vec){.x = 4,.y = 5,});
println(main__Vec_str(main__Vec__plus(a, b)));
println(main__Vec_str(main__Vec__minus(a, b)));
println(main__Vec_str(main__Vec__mult(a, b)));
println(main__Vec_str(main__Vec__div(a, b)));
println(main__Vec_str(main__Vec__mod(a, b)));
a = main__Vec__plus(a, b);
println( str_intp(2, _MOV((StrIntpData[]){{_SLIT("a+=b is: "), /*115 &main.Vec*/0xfe10, {.d_s = main__Vec_str(a)}}, {_SLIT0, 0, { .d_c = 0 }}})));
a = main__Vec__minus(a, b);
println( str_intp(2, _MOV((StrIntpData[]){{_SLIT("a-=b is: "), /*115 &main.Vec*/0xfe10, {.d_s = main__Vec_str(a)}}, {_SLIT0, 0, { .d_c = 0 }}})));
a = main__Vec__mult(a, b);
println( str_intp(2, _MOV((StrIntpData[]){{_SLIT("a*=b is: "), /*115 &main.Vec*/0xfe10, {.d_s = main__Vec_str(a)}}, {_SLIT0, 0, { .d_c = 0 }}})));
a = main__Vec__div(a, b);
println( str_intp(2, _MOV((StrIntpData[]){{_SLIT("a/=b is: "), /*115 &main.Vec*/0xfe10, {.d_s = main__Vec_str(a)}}, {_SLIT0, 0, { .d_c = 0 }}})));
println(main__Vec__eq(a, b) ? _SLIT("true") : _SLIT("false"));
println(!main__Vec__eq(a, b) ? _SLIT("true") : _SLIT("false"));
println(main__Vec__lt(b, a) ? _SLIT("true") : _SLIT("false"));
println(!main__Vec__lt(a, b) ? _SLIT("true") : _SLIT("false"));
println(main__Vec__lt(a, b) ? _SLIT("true") : _SLIT("false"));
println(!main__Vec__lt(b, a) ? _SLIT("true") : _SLIT("false"));
}
条件编译
判断操作系统
V代码:
fn main() {
$if windows {
println('windows')
}
$if linux {
println('linux')
}
$if macos {
println('mac')
}
}
C代码:
VV_LOCAL_SYMBOL void main__main(void) {
println(_SLIT("mac"));
}
判断操作系统位数
V代码:
fn main() {
mut x := 0
$if x32 {
println('system is 32 bit')
x = 1
}
$if x64 {
println('system is 64 bit')
x = 2
}
}
C代码:
#if INTPTR_MAX == INT32_MAX
#define TARGET_IS_32BIT 1
#elif INTPTR_MAX == INT64_MAX
#define TARGET_IS_64BIT 1
#else
#error "The environment is not 32 or 64-bit."
#endif
VV_LOCAL_SYMBOL void main__main(void) {
int x = 0;
#if defined(TARGET_IS_32BIT)
{
println(_SLIT("system is 32 bit"));
x = 1;
}
#endif
#if defined(TARGET_IS_64BIT)
{
println(_SLIT("system is 64 bit"));
x = 2;
}
#endif
}
判断大端序/小端序
V代码:
fn main() {
mut x := 0
$if little_endian {
println('system is little endian')
x = 1
}
$if big_endian {
println('system is big endian')
x = 2
}
}
C代码:
#if defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ || defined(__BYTE_ORDER) && __BYTE_ORDER == __BIG_ENDIAN || defined(__BIG_ENDIAN__) || defined(__ARMEB__) || defined(__THUMBEB__) || defined(__AARCH64EB__) || defined(_MIBSEB) || defined(__MIBSEB) || defined(__MIBSEB__)
#define TARGET_ORDER_IS_BIG 1
#elif defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ || defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN || defined(__LITTLE_ENDIAN__) || defined(__ARMEL__) || defined(__THUMBEL__) || defined(__AARCH64EL__) || defined(_MIPSEL) || defined(__MIPSEL) || defined(__MIPSEL__) || defined(_M_AMD64) || defined(_M_X64) || defined(_M_IX86)
#define TARGET_ORDER_IS_LITTLE 1
#else
#error "Unknown architecture endianness"
#endif
VV_LOCAL_SYMBOL void main__main(void) {
int x = 0;
#if defined(TARGET_ORDER_IS_LITTLE)
{
println(_SLIT("system is little endian"));
x = 1;
}
#endif
#if defined(TARGET_ORDER_IS_BIG)
{
println(_SLIT("system is big endian"));
x = 2;
}
#endif
}
内联汇编代码
生成等价的C内联汇编代码:
V代码:
fn main() {
a := 100
b := 20
mut c := 0
asm amd64 {
mov eax, a
add eax, b
mov c, eax
; =r (c) // output
; r (a) // input
r (b)
}
println('a: ${a}') // 100
println('b: ${b}') // 20
println('c: ${c}') // 120
}
C代码:
VV_LOCAL_SYMBOL void main__main(void) {
int a = 100;
int b = 20;
int c = 0;
__asm__ (
"mov %[a], %%eax;"
"add %[b], %%eax;"
"mov %%eax, %[c];"
: [c] "=r" (c)
: [a] "r" (a),
[b] "r" (b)
);
println( str_intp(2, _MOV((StrIntpData[]){{_SLIT("a: "), /*100 &int*/0xfe07, {.d_i32 = a}}, {_SLIT0, 0, { .d_c = 0 }}})));
println( str_intp(2, _MOV((StrIntpData[]){{_SLIT("b: "), /*100 &int*/0xfe07, {.d_i32 = b}}, {_SLIT0, 0, { .d_c = 0 }}})));
println( str_intp(2, _MOV((StrIntpData[]){{_SLIT("c: "), /*100 &int*/0xfe07, {.d_i32 = c}}, {_SLIT0, 0, { .d_c = 0 }}})));
}
最后更新于