2022-01-04 12:21:08 +03:00
|
|
|
// Copyright (c) 2019-2022 Alexander Medvednikov. All rights reserved.
|
2019-06-23 05:21:30 +03:00
|
|
|
// Use of this source code is governed by an MIT license
|
|
|
|
// that can be found in the LICENSE file.
|
2021-11-16 20:31:42 +03:00
|
|
|
[has_globals]
|
2019-06-22 21:20:28 +03:00
|
|
|
module builtin
|
|
|
|
|
|
|
|
// isnil returns true if an object is nil (only for C objects).
|
2021-05-06 00:31:25 +03:00
|
|
|
[inline]
|
2019-06-22 21:20:28 +03:00
|
|
|
pub fn isnil(v voidptr) bool {
|
|
|
|
return v == 0
|
|
|
|
}
|
|
|
|
|
2020-02-04 10:29:50 +03:00
|
|
|
/*
|
2019-12-19 23:52:45 +03:00
|
|
|
fn on_panic(f fn(int)int) {
|
2019-06-22 21:20:28 +03:00
|
|
|
// TODO
|
|
|
|
}
|
2020-02-04 10:29:50 +03:00
|
|
|
*/
|
2019-06-22 21:20:28 +03:00
|
|
|
|
2021-01-30 19:54:05 +03:00
|
|
|
struct VCastTypeIndexName {
|
|
|
|
tindex int
|
|
|
|
tname string
|
|
|
|
}
|
|
|
|
|
2021-05-19 10:35:56 +03:00
|
|
|
// will be filled in cgen
|
|
|
|
__global as_cast_type_indexes []VCastTypeIndexName
|
2020-02-03 09:02:54 +03:00
|
|
|
|
2020-10-15 13:32:28 +03:00
|
|
|
fn __as_cast(obj voidptr, obj_type int, expected_type int) voidptr {
|
2020-04-25 09:36:53 +03:00
|
|
|
if obj_type != expected_type {
|
2021-03-14 10:37:38 +03:00
|
|
|
mut obj_name := as_cast_type_indexes[0].tname.clone()
|
|
|
|
mut expected_name := as_cast_type_indexes[0].tname.clone()
|
2021-01-30 19:54:05 +03:00
|
|
|
for x in as_cast_type_indexes {
|
|
|
|
if x.tindex == obj_type {
|
2021-03-14 10:37:38 +03:00
|
|
|
obj_name = x.tname.clone()
|
2021-01-30 19:54:05 +03:00
|
|
|
}
|
|
|
|
if x.tindex == expected_type {
|
2021-03-14 10:37:38 +03:00
|
|
|
expected_name = x.tname.clone()
|
2021-01-30 19:54:05 +03:00
|
|
|
}
|
|
|
|
}
|
2022-11-15 16:53:13 +03:00
|
|
|
panic('as cast: cannot cast `${obj_name}` to `${expected_name}`')
|
2020-04-25 09:36:53 +03:00
|
|
|
}
|
|
|
|
return obj
|
|
|
|
}
|
2020-06-01 14:43:31 +03:00
|
|
|
|
2021-12-16 16:59:46 +03:00
|
|
|
// VAssertMetaInfo is used during assertions. An instance of it is filled in by
|
|
|
|
// compile time generated code, when an assertion fails.
|
2020-07-01 01:53:53 +03:00
|
|
|
pub struct VAssertMetaInfo {
|
2020-06-01 14:43:31 +03:00
|
|
|
pub:
|
|
|
|
fpath string // the source file path of the assertion
|
|
|
|
line_nr int // the line number of the assertion
|
|
|
|
fn_name string // the function name in which the assertion is
|
|
|
|
src string // the actual source line of the assertion
|
|
|
|
op string // the operation of the assertion, i.e. '==', '<', 'call', etc ...
|
|
|
|
llabel string // the left side of the infix expressions as source
|
|
|
|
rlabel string // the right side of the infix expressions as source
|
|
|
|
lvalue string // the stringified *actual value* of the left side of a failed assertion
|
|
|
|
rvalue string // the stringified *actual value* of the right side of a failed assertion
|
2022-08-03 01:14:01 +03:00
|
|
|
message string // the value of the `message` from `assert cond, message`
|
|
|
|
has_msg bool // false for assertions like `assert cond`, true for `assert cond, 'oh no'`
|
2020-06-01 14:43:31 +03:00
|
|
|
}
|
2021-01-30 19:54:05 +03:00
|
|
|
|
2021-12-16 16:59:46 +03:00
|
|
|
// free frees the memory occupied by the assertion meta data. It is called automatically by
|
|
|
|
// the code, that V's test framework generates, after all other callbacks have been called.
|
2021-08-13 18:37:34 +03:00
|
|
|
[manualfree; unsafe]
|
|
|
|
pub fn (ami &VAssertMetaInfo) free() {
|
|
|
|
unsafe {
|
|
|
|
ami.fpath.free()
|
|
|
|
ami.fn_name.free()
|
|
|
|
ami.src.free()
|
|
|
|
ami.op.free()
|
|
|
|
ami.llabel.free()
|
|
|
|
ami.rlabel.free()
|
|
|
|
ami.lvalue.free()
|
|
|
|
ami.rvalue.free()
|
2022-08-03 01:14:01 +03:00
|
|
|
ami.message.free()
|
2021-08-13 18:37:34 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-01 14:43:31 +03:00
|
|
|
fn __print_assert_failure(i &VAssertMetaInfo) {
|
2022-11-15 16:53:13 +03:00
|
|
|
eprintln('${i.fpath}:${i.line_nr + 1}: FAIL: fn ${i.fn_name}: assert ${i.src}')
|
2020-06-13 17:20:45 +03:00
|
|
|
if i.op.len > 0 && i.op != 'call' {
|
2022-11-15 16:53:13 +03:00
|
|
|
eprintln(' left value: ${i.llabel} = ${i.lvalue}')
|
2020-06-22 17:52:03 +03:00
|
|
|
if i.rlabel == i.rvalue {
|
2022-11-15 16:53:13 +03:00
|
|
|
eprintln(' right value: ${i.rlabel}')
|
2021-01-30 19:54:05 +03:00
|
|
|
} else {
|
2022-11-15 16:53:13 +03:00
|
|
|
eprintln(' right value: ${i.rlabel} = ${i.rvalue}')
|
2020-06-22 17:52:03 +03:00
|
|
|
}
|
2022-08-03 01:14:01 +03:00
|
|
|
if i.has_msg {
|
2022-11-15 16:53:13 +03:00
|
|
|
eprintln(' message: ${i.message}')
|
2022-08-03 01:14:01 +03:00
|
|
|
}
|
2020-06-01 14:43:31 +03:00
|
|
|
}
|
|
|
|
}
|
2020-07-03 16:10:39 +03:00
|
|
|
|
2021-02-05 23:02:29 +03:00
|
|
|
// MethodArgs holds type information for function and/or method arguments.
|
2020-08-27 16:00:44 +03:00
|
|
|
pub struct MethodArgs {
|
2020-07-03 16:10:39 +03:00
|
|
|
pub:
|
2021-03-07 16:28:43 +03:00
|
|
|
typ int
|
|
|
|
name string
|
2020-07-03 16:10:39 +03:00
|
|
|
}
|
2020-07-25 01:02:44 +03:00
|
|
|
|
2021-02-05 23:02:29 +03:00
|
|
|
// FunctionData holds information about a parsed function.
|
2020-07-25 01:02:44 +03:00
|
|
|
pub struct FunctionData {
|
|
|
|
pub:
|
2020-09-28 07:13:38 +03:00
|
|
|
name string
|
|
|
|
attrs []string
|
|
|
|
args []MethodArgs
|
|
|
|
return_type int
|
|
|
|
typ int
|
2020-07-25 01:02:44 +03:00
|
|
|
}
|
|
|
|
|
2021-02-05 23:02:29 +03:00
|
|
|
// FieldData holds information about a field. Fields reside on structs.
|
2020-07-25 01:02:44 +03:00
|
|
|
pub struct FieldData {
|
|
|
|
pub:
|
2022-12-26 17:05:14 +03:00
|
|
|
name string // the name of the field f
|
|
|
|
typ int // the internal TypeID of the field f,
|
|
|
|
unaliased_typ int // if f's type was an alias of int, this will be TypeID(int)
|
|
|
|
//
|
|
|
|
attrs []string // the attributes of the field f
|
|
|
|
is_pub bool // f is in a `pub:` section
|
|
|
|
is_mut bool // f is in a `mut:` section
|
|
|
|
//
|
|
|
|
is_shared bool // `f shared Abc`
|
|
|
|
is_atomic bool // `f atomic int` , TODO
|
|
|
|
is_optional bool // `f ?string` , TODO
|
|
|
|
//
|
|
|
|
is_array bool // `f []string` , TODO
|
|
|
|
is_map bool // `f map[string]int` , TODO
|
|
|
|
is_chan bool // `f chan int` , TODO
|
|
|
|
is_struct bool // `f Abc` where Abc is a struct , TODO
|
|
|
|
//
|
|
|
|
indirections u8 // 0 for `f int`, 1 for `f &int`, 2 for `f &&int` , TODO
|
2020-07-25 01:02:44 +03:00
|
|
|
}
|
2021-04-25 18:29:26 +03:00
|
|
|
|
2021-07-23 12:33:55 +03:00
|
|
|
pub enum AttributeKind {
|
2021-04-25 18:29:26 +03:00
|
|
|
plain // [name]
|
|
|
|
string // ['name']
|
|
|
|
number // [123]
|
|
|
|
comptime_define // [if name]
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct StructAttribute {
|
|
|
|
pub:
|
|
|
|
name string
|
|
|
|
has_arg bool
|
|
|
|
arg string
|
|
|
|
kind AttributeKind
|
|
|
|
}
|