1 | // Copyright (c) 2019-2023 Alexander Medvednikov. All rights reserved. |
2 | // Use of this source code is governed by an MIT license |
3 | // that can be found in the LICENSE file. |
4 | [has_globals] |
5 | module builtin |
6 | |
7 | // isnil returns true if an object is nil (only for C objects). |
8 | [inline] |
9 | pub fn isnil(v voidptr) bool { |
10 | return v == 0 |
11 | } |
12 | |
13 | /* |
14 | fn on_panic(f fn(int)int) { |
15 | // TODO |
16 | } |
17 | */ |
18 | |
19 | struct VCastTypeIndexName { |
20 | tindex int |
21 | tname string |
22 | } |
23 | |
24 | // will be filled in cgen |
25 | __global as_cast_type_indexes []VCastTypeIndexName |
26 | |
27 | fn __as_cast(obj voidptr, obj_type int, expected_type int) voidptr { |
28 | if obj_type != expected_type { |
29 | mut obj_name := as_cast_type_indexes[0].tname.clone() |
30 | mut expected_name := as_cast_type_indexes[0].tname.clone() |
31 | for x in as_cast_type_indexes { |
32 | if x.tindex == obj_type { |
33 | obj_name = x.tname.clone() |
34 | } |
35 | if x.tindex == expected_type { |
36 | expected_name = x.tname.clone() |
37 | } |
38 | } |
39 | panic('as cast: cannot cast `${obj_name}` to `${expected_name}`') |
40 | } |
41 | return obj |
42 | } |
43 | |
44 | // VAssertMetaInfo is used during assertions. An instance of it is filled in by |
45 | // compile time generated code, when an assertion fails. |
46 | pub struct VAssertMetaInfo { |
47 | pub: |
48 | fpath string // the source file path of the assertion |
49 | line_nr int // the line number of the assertion |
50 | fn_name string // the function name in which the assertion is |
51 | src string // the actual source line of the assertion |
52 | op string // the operation of the assertion, i.e. '==', '<', 'call', etc ... |
53 | llabel string // the left side of the infix expressions as source |
54 | rlabel string // the right side of the infix expressions as source |
55 | lvalue string // the stringified *actual value* of the left side of a failed assertion |
56 | rvalue string // the stringified *actual value* of the right side of a failed assertion |
57 | message string // the value of the `message` from `assert cond, message` |
58 | has_msg bool // false for assertions like `assert cond`, true for `assert cond, 'oh no'` |
59 | } |
60 | |
61 | // free frees the memory occupied by the assertion meta data. It is called automatically by |
62 | // the code, that V's test framework generates, after all other callbacks have been called. |
63 | [manualfree; unsafe] |
64 | pub fn (ami &VAssertMetaInfo) free() { |
65 | unsafe { |
66 | ami.fpath.free() |
67 | ami.fn_name.free() |
68 | ami.src.free() |
69 | ami.op.free() |
70 | ami.llabel.free() |
71 | ami.rlabel.free() |
72 | ami.lvalue.free() |
73 | ami.rvalue.free() |
74 | ami.message.free() |
75 | } |
76 | } |
77 | |
78 | fn __print_assert_failure(i &VAssertMetaInfo) { |
79 | eprintln('${i.fpath}:${i.line_nr + 1}: FAIL: fn ${i.fn_name}: assert ${i.src}') |
80 | if i.op.len > 0 && i.op != 'call' { |
81 | eprintln(' left value: ${i.llabel} = ${i.lvalue}') |
82 | if i.rlabel == i.rvalue { |
83 | eprintln(' right value: ${i.rlabel}') |
84 | } else { |
85 | eprintln(' right value: ${i.rlabel} = ${i.rvalue}') |
86 | } |
87 | } |
88 | if i.has_msg { |
89 | eprintln(' message: ${i.message}') |
90 | } |
91 | } |
92 | |
93 | // MethodArgs holds type information for function and/or method arguments. |
94 | pub struct MethodArgs { |
95 | pub: |
96 | typ int |
97 | name string |
98 | } |
99 | |
100 | // FunctionData holds information about a parsed function. |
101 | pub struct FunctionData { |
102 | pub: |
103 | name string |
104 | attrs []string |
105 | args []MethodArgs |
106 | return_type int |
107 | typ int |
108 | } |
109 | |
110 | pub struct EnumData { |
111 | pub: |
112 | name string |
113 | value i64 |
114 | attrs []string |
115 | } |
116 | |
117 | // FieldData holds information about a field. Fields reside on structs. |
118 | pub struct FieldData { |
119 | pub: |
120 | name string // the name of the field f |
121 | typ int // the internal TypeID of the field f, |
122 | unaliased_typ int // if f's type was an alias of int, this will be TypeID(int) |
123 | // |
124 | attrs []string // the attributes of the field f |
125 | is_pub bool // f is in a `pub:` section |
126 | is_mut bool // f is in a `mut:` section |
127 | // |
128 | is_shared bool // `f shared Abc` |
129 | is_atomic bool // `f atomic int` , TODO |
130 | is_option bool // `f ?string` , TODO |
131 | // |
132 | is_array bool // `f []string` , TODO |
133 | is_map bool // `f map[string]int` , TODO |
134 | is_chan bool // `f chan int` , TODO |
135 | is_enum bool // `f Enum` where Enum is an enum |
136 | is_struct bool // `f Abc` where Abc is a struct , TODO |
137 | is_alias bool // `f MyInt` where `type MyInt = int`, TODO |
138 | // |
139 | indirections u8 // 0 for `f int`, 1 for `f &int`, 2 for `f &&int` , TODO |
140 | } |
141 | |
142 | pub enum AttributeKind { |
143 | plain // [name] |
144 | string // ['name'] |
145 | number // [123] |
146 | comptime_define // [if name] |
147 | } |
148 | |
149 | pub struct StructAttribute { |
150 | pub: |
151 | name string |
152 | has_arg bool |
153 | arg string |
154 | kind AttributeKind |
155 | } |