| 1 | // Copyright (c) 2019-2024 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 | |
| 5 | module builtin |
| 6 | |
| 7 | fn (a any) toString() |
| 8 | |
| 9 | // panic prints an error message, then exits the process with exit code of 1. |
| 10 | @[noreturn] |
| 11 | pub fn panic(s string) { |
| 12 | eprintln('V panic: ' + s) |
| 13 | eprintln(js_stacktrace()) |
| 14 | exit(1) |
| 15 | } |
| 16 | |
| 17 | // panic_n prints an error message, followed by the given number, then exits the process with exit code of 1. |
| 18 | @[noreturn] |
| 19 | pub fn panic_n(s string, n i64) { |
| 20 | eprintln('V panic: ' + s) |
| 21 | eprintln(js_stacktrace()) |
| 22 | exit(1) |
| 23 | } |
| 24 | |
| 25 | // IError holds information about an error instance. |
| 26 | pub interface IError { |
| 27 | msg() string |
| 28 | code() int |
| 29 | } |
| 30 | |
| 31 | // str returns the message of IError. |
| 32 | pub fn (err IError) str() string { |
| 33 | return match err { |
| 34 | None__ { |
| 35 | 'none' |
| 36 | } |
| 37 | Error { |
| 38 | err.msg() |
| 39 | } |
| 40 | MessageError { |
| 41 | err.str() |
| 42 | } |
| 43 | else { |
| 44 | '${err.type_name()}: ${err.msg()}' |
| 45 | } |
| 46 | } |
| 47 | } |
| 48 | |
| 49 | // Error is the empty default implementation of `IError`. |
| 50 | pub struct Error {} |
| 51 | |
| 52 | // msg returns the message of Error. |
| 53 | pub fn (err Error) msg() string { |
| 54 | return '' |
| 55 | } |
| 56 | |
| 57 | // code returns the code of Error. |
| 58 | pub fn (err Error) code() int { |
| 59 | return 0 |
| 60 | } |
| 61 | |
| 62 | // MessageError is the default implementation of the `IError` interface that is returned by the `error()` function. |
| 63 | struct MessageError { |
| 64 | pub: |
| 65 | msg string |
| 66 | code int |
| 67 | } |
| 68 | |
| 69 | // str returns the message and code of the MessageError. |
| 70 | pub fn (err MessageError) str() string { |
| 71 | return err.msg |
| 72 | } |
| 73 | |
| 74 | // msg returns the message of the MessageError. |
| 75 | pub fn (err MessageError) msg() string { |
| 76 | return err.msg |
| 77 | } |
| 78 | |
| 79 | // code returns the code of MessageError. |
| 80 | pub fn (err MessageError) code() int { |
| 81 | return err.code |
| 82 | } |
| 83 | |
| 84 | pub const none__ = IError(&None__{}) |
| 85 | |
| 86 | struct None__ { |
| 87 | Error |
| 88 | } |
| 89 | |
| 90 | fn (_ None__) str() string { |
| 91 | return 'none' |
| 92 | } |
| 93 | |
| 94 | pub struct Option { |
| 95 | state u8 |
| 96 | err IError = none__ |
| 97 | } |
| 98 | |
| 99 | // str returns the Option type: ok, none, or error. |
| 100 | pub fn (o Option) str() string { |
| 101 | if o.state == 0 { |
| 102 | return 'Option{ ok }' |
| 103 | } |
| 104 | if o.state == 1 { |
| 105 | return 'Option{ none }' |
| 106 | } |
| 107 | return 'Option{ error: "${o.err}" }' |
| 108 | } |
| 109 | |
| 110 | pub struct _option { |
| 111 | state u8 |
| 112 | err IError = none__ |
| 113 | } |
| 114 | |
| 115 | // str returns the Option type: ok, none, or error. |
| 116 | pub fn (o _option) str() string { |
| 117 | if o.state == 0 { |
| 118 | return 'Option{ ok }' |
| 119 | } |
| 120 | if o.state == 1 { |
| 121 | return 'Option{ none }' |
| 122 | } |
| 123 | return 'Option{ error: "${o.err}" }' |
| 124 | } |
| 125 | |
| 126 | // trace_error prints to stderr a string and a backtrace of the error. |
| 127 | fn trace_error(x string) { |
| 128 | eprintln('> ${@FN} | ${x}') |
| 129 | } |
| 130 | |
| 131 | // error returns a default error instance containing the error given in `message`. |
| 132 | // Example: if ouch { return error('an error occurred') } |
| 133 | @[inline] |
| 134 | pub fn error(message string) IError { |
| 135 | // trace_error(message) |
| 136 | return &MessageError{ |
| 137 | msg: message |
| 138 | } |
| 139 | } |
| 140 | |
| 141 | // error_with_code returns a default error instance containing the given `message` and error `code`. |
| 142 | // Example: if ouch { return error_with_code('an error occurred', 1) } |
| 143 | @[inline] |
| 144 | pub fn error_with_code(message string, code int) IError { |
| 145 | // trace_error('${message} | code: ${code}') |
| 146 | return &MessageError{ |
| 147 | msg: message |
| 148 | code: code |
| 149 | } |
| 150 | } |
| 151 | |
| 152 | // free allows for manually freeing memory allocated at the address `ptr`. |
| 153 | // However, this is a no-op on JS backend |
| 154 | @[unsafe] |
| 155 | pub fn free(ptr voidptr) { |
| 156 | _ := ptr |
| 157 | } |
| 158 | |