Strip semicolons; Make odin strip-semicolon replace .. with ..= if used as a binary operator

This commit is contained in:
gingerBill
2021-09-06 20:15:59 +01:00
parent 3bf005bfc5
commit 0434281f73
21 changed files with 999 additions and 968 deletions
+48 -48
View File
@@ -11,72 +11,72 @@ when ODIN_OS == "windows" {
@(default_calling_convention="c") @(default_calling_convention="c")
foreign libc { foreign libc {
// 7.3.5 Trigonometric functions // 7.3.5 Trigonometric functions
cacos :: proc(z: complex_double) -> complex_double ---; cacos :: proc(z: complex_double) -> complex_double ---
cacosf :: proc(z: complex_float) -> complex_float ---; cacosf :: proc(z: complex_float) -> complex_float ---
casin :: proc(z: complex_double) -> complex_double ---; casin :: proc(z: complex_double) -> complex_double ---
casinf :: proc(z: complex_float) -> complex_float ---; casinf :: proc(z: complex_float) -> complex_float ---
catan :: proc(z: complex_double) -> complex_double ---; catan :: proc(z: complex_double) -> complex_double ---
catanf :: proc(z: complex_float) -> complex_float ---; catanf :: proc(z: complex_float) -> complex_float ---
ccos :: proc(z: complex_double) -> complex_double ---; ccos :: proc(z: complex_double) -> complex_double ---
ccosf :: proc(z: complex_float) -> complex_float ---; ccosf :: proc(z: complex_float) -> complex_float ---
csin :: proc(z: complex_double) -> complex_double ---; csin :: proc(z: complex_double) -> complex_double ---
csinf :: proc(z: complex_float) -> complex_float ---; csinf :: proc(z: complex_float) -> complex_float ---
ctan :: proc(z: complex_double) -> complex_double ---; ctan :: proc(z: complex_double) -> complex_double ---
ctanf :: proc(z: complex_float) -> complex_float ---; ctanf :: proc(z: complex_float) -> complex_float ---
// 7.3.6 Hyperbolic functions // 7.3.6 Hyperbolic functions
cacosh :: proc(z: complex_double) -> complex_double ---; cacosh :: proc(z: complex_double) -> complex_double ---
cacoshf :: proc(z: complex_float) -> complex_float ---; cacoshf :: proc(z: complex_float) -> complex_float ---
casinh :: proc(z: complex_double) -> complex_double ---; casinh :: proc(z: complex_double) -> complex_double ---
casinhf :: proc(z: complex_float) -> complex_float ---; casinhf :: proc(z: complex_float) -> complex_float ---
catanh :: proc(z: complex_double) -> complex_double ---; catanh :: proc(z: complex_double) -> complex_double ---
catanhf :: proc(z: complex_float) -> complex_float ---; catanhf :: proc(z: complex_float) -> complex_float ---
ccosh :: proc(z: complex_double) -> complex_double ---; ccosh :: proc(z: complex_double) -> complex_double ---
ccoshf :: proc(z: complex_float) -> complex_float ---; ccoshf :: proc(z: complex_float) -> complex_float ---
csinh :: proc(z: complex_double) -> complex_double ---; csinh :: proc(z: complex_double) -> complex_double ---
csinhf :: proc(z: complex_float) -> complex_float ---; csinhf :: proc(z: complex_float) -> complex_float ---
ctanh :: proc(z: complex_double) -> complex_double ---; ctanh :: proc(z: complex_double) -> complex_double ---
ctanhf :: proc(z: complex_float) -> complex_float ---; ctanhf :: proc(z: complex_float) -> complex_float ---
// 7.3.7 Exponential and logarithmic functions // 7.3.7 Exponential and logarithmic functions
cexp :: proc(z: complex_double) -> complex_double ---; cexp :: proc(z: complex_double) -> complex_double ---
cexpf :: proc(z: complex_float) -> complex_float ---; cexpf :: proc(z: complex_float) -> complex_float ---
clog :: proc(z: complex_double) -> complex_double ---; clog :: proc(z: complex_double) -> complex_double ---
clogf :: proc(z: complex_float) -> complex_float ---; clogf :: proc(z: complex_float) -> complex_float ---
// 7.3.8 Power and absolute-value functions // 7.3.8 Power and absolute-value functions
cabs :: proc(z: complex_double) -> complex_double ---; cabs :: proc(z: complex_double) -> complex_double ---
cabsf :: proc(z: complex_float) -> complex_float ---; cabsf :: proc(z: complex_float) -> complex_float ---
cpow :: proc(z: complex_double) -> complex_double ---; cpow :: proc(z: complex_double) -> complex_double ---
cpowf :: proc(z: complex_float) -> complex_float ---; cpowf :: proc(z: complex_float) -> complex_float ---
csqrt :: proc(z: complex_double) -> complex_double ---; csqrt :: proc(z: complex_double) -> complex_double ---
csqrtf :: proc(z: complex_float) -> complex_float ---; csqrtf :: proc(z: complex_float) -> complex_float ---
// 7.3.9 Manipulation functions // 7.3.9 Manipulation functions
carg :: proc(z: complex_double) -> double ---; carg :: proc(z: complex_double) -> double ---
cargf :: proc(z: complex_float) -> float ---; cargf :: proc(z: complex_float) -> float ---
cimag :: proc(z: complex_double) -> double ---; cimag :: proc(z: complex_double) -> double ---
cimagf :: proc(z: complex_float) -> float ---; cimagf :: proc(z: complex_float) -> float ---
conj :: proc(z: complex_double) -> complex_double ---; conj :: proc(z: complex_double) -> complex_double ---
conjf :: proc(z: complex_float) -> complex_float ---; conjf :: proc(z: complex_float) -> complex_float ---
cproj :: proc(z: complex_double) -> complex_double ---; cproj :: proc(z: complex_double) -> complex_double ---
cprojf :: proc(z: complex_float) -> complex_float ---; cprojf :: proc(z: complex_float) -> complex_float ---
creal :: proc(z: complex_double) -> double ---; creal :: proc(z: complex_double) -> double ---
crealf :: proc(z: complex_float) -> float ---; crealf :: proc(z: complex_float) -> float ---
} }
import builtin "core:builtin" import builtin "core:builtin"
complex_float :: distinct builtin.complex64; complex_float :: distinct builtin.complex64
complex_double :: distinct builtin.complex128; complex_double :: distinct builtin.complex128
// Cannot implement _Complex_I or _Imaginary_I in Odin, thus // Cannot implement _Complex_I or _Imaginary_I in Odin, thus
// complex and imaginary cannot be implement either. // complex and imaginary cannot be implement either.
CMPLX :: #force_inline proc(x, y: double) -> complex_double { CMPLX :: #force_inline proc(x, y: double) -> complex_double {
return builtin.complex(x, y); return builtin.complex(x, y)
} }
CMPLXF :: #force_inline proc(x, y: float) -> complex_float { CMPLXF :: #force_inline proc(x, y: float) -> complex_float {
return builtin.complex(x, y); return builtin.complex(x, y)
} }
+14 -14
View File
@@ -11,20 +11,20 @@ when ODIN_OS == "windows" {
@(default_calling_convention="c") @(default_calling_convention="c")
foreign libc { foreign libc {
// 7.4.1 Character classification functions // 7.4.1 Character classification functions
isalnum :: proc(c: int) -> int ---; isalnum :: proc(c: int) -> int ---
isalpha :: proc(c: int) -> int ---; isalpha :: proc(c: int) -> int ---
isblank :: proc(c: int) -> int ---; isblank :: proc(c: int) -> int ---
iscntrl :: proc(c: int) -> int ---; iscntrl :: proc(c: int) -> int ---
isdigit :: proc(c: int) -> int ---; isdigit :: proc(c: int) -> int ---
isgraph :: proc(c: int) -> int ---; isgraph :: proc(c: int) -> int ---
islower :: proc(c: int) -> int ---; islower :: proc(c: int) -> int ---
isprint :: proc(c: int) -> int ---; isprint :: proc(c: int) -> int ---
ispunct :: proc(c: int) -> int ---; ispunct :: proc(c: int) -> int ---
isspace :: proc(c: int) -> int ---; isspace :: proc(c: int) -> int ---
isupper :: proc(c: int) -> int ---; isupper :: proc(c: int) -> int ---
isxdigit :: proc(c: int) -> int ---; isxdigit :: proc(c: int) -> int ---
// 7.4.2 Character case mapping functions // 7.4.2 Character case mapping functions
tolower :: proc(c: int) -> int ---; tolower :: proc(c: int) -> int ---
toupper :: proc(c: int) -> int ---; toupper :: proc(c: int) -> int ---
} }
+9 -9
View File
@@ -17,12 +17,12 @@ when ODIN_OS == "linux" || ODIN_OS == "freebsd" {
@(default_calling_convention="c") @(default_calling_convention="c")
foreign libc { foreign libc {
@(link_name="__libc_errno_location") @(link_name="__libc_errno_location")
_get_errno :: proc() -> ^int ---; _get_errno :: proc() -> ^int ---
} }
EDOM :: 33; EDOM :: 33
EILSEQ :: 84; EILSEQ :: 84
ERANGE :: 34; ERANGE :: 34
} }
when ODIN_OS == "windows" { when ODIN_OS == "windows" {
@@ -30,12 +30,12 @@ when ODIN_OS == "windows" {
@(default_calling_convention="c") @(default_calling_convention="c")
foreign libc { foreign libc {
@(link_name="_errno") @(link_name="_errno")
_get_errno :: proc() -> ^int ---; _get_errno :: proc() -> ^int ---
} }
EDOM :: 33; EDOM :: 33
EILSEQ :: 42; EILSEQ :: 42
ERANGE :: 34; ERANGE :: 34
} }
// Odin has no way to make an identifier "errno" behave as a function call to // Odin has no way to make an identifier "errno" behave as a function call to
@@ -43,5 +43,5 @@ when ODIN_OS == "windows" {
// error value to errno. To work around this, just expose it as a function like // error value to errno. To work around this, just expose it as a function like
// it actually is. // it actually is.
errno :: #force_inline proc() -> ^int { errno :: #force_inline proc() -> ^int {
return _get_errno(); return _get_errno()
} }
+268 -268
View File
@@ -17,210 +17,210 @@ when ODIN_OS == "windows" {
@(default_calling_convention="c") @(default_calling_convention="c")
foreign libc { foreign libc {
// 7.12.4 Trigonometric functions // 7.12.4 Trigonometric functions
@(link_name="acos") libc_acos :: proc(x: double) -> double ---; @(link_name="acos") libc_acos :: proc(x: double) -> double ---
@(link_name="acosf") libc_acosf :: proc(x: float) -> float ---; @(link_name="acosf") libc_acosf :: proc(x: float) -> float ---
@(link_name="asin") libc_asin :: proc(x: double) -> double ---; @(link_name="asin") libc_asin :: proc(x: double) -> double ---
@(link_name="asinf") libc_asinf :: proc(x: float) -> float ---; @(link_name="asinf") libc_asinf :: proc(x: float) -> float ---
@(link_name="atan") libc_atan :: proc(x: double) -> double ---; @(link_name="atan") libc_atan :: proc(x: double) -> double ---
@(link_name="atanf") libc_atanf :: proc(x: float) -> float ---; @(link_name="atanf") libc_atanf :: proc(x: float) -> float ---
@(link_name="atan2") libc_atan2 :: proc(y: double, x: double) -> double ---; @(link_name="atan2") libc_atan2 :: proc(y: double, x: double) -> double ---
@(link_name="atan2f") libc_atan2f :: proc(y: float, x: float) -> float ---; @(link_name="atan2f") libc_atan2f :: proc(y: float, x: float) -> float ---
@(link_name="cos") libc_cos :: proc(x: double) -> double ---; @(link_name="cos") libc_cos :: proc(x: double) -> double ---
@(link_name="cosf") libc_cosf :: proc(x: float) -> float ---; @(link_name="cosf") libc_cosf :: proc(x: float) -> float ---
@(link_name="sin") libc_sin :: proc(x: double) -> double ---; @(link_name="sin") libc_sin :: proc(x: double) -> double ---
@(link_name="sinf") libc_sinf :: proc(x: float) -> float ---; @(link_name="sinf") libc_sinf :: proc(x: float) -> float ---
@(link_name="tan") libc_tan :: proc(x: double) -> double ---; @(link_name="tan") libc_tan :: proc(x: double) -> double ---
@(link_name="tanf") libc_tanf :: proc(x: float) -> float ---; @(link_name="tanf") libc_tanf :: proc(x: float) -> float ---
// 7.12.5 Hyperbolic functions // 7.12.5 Hyperbolic functions
@(link_name="acosh") libc_acosh :: proc(x: double) -> double ---; @(link_name="acosh") libc_acosh :: proc(x: double) -> double ---
@(link_name="acoshf") libc_acoshf :: proc(x: float) -> float ---; @(link_name="acoshf") libc_acoshf :: proc(x: float) -> float ---
@(link_name="asinh") libc_asinh :: proc(x: double) -> double ---; @(link_name="asinh") libc_asinh :: proc(x: double) -> double ---
@(link_name="asinhf") libc_asinhf :: proc(x: float) -> float ---; @(link_name="asinhf") libc_asinhf :: proc(x: float) -> float ---
@(link_name="atanh") libc_atanh :: proc(x: double) -> double ---; @(link_name="atanh") libc_atanh :: proc(x: double) -> double ---
@(link_name="atanhf") libc_atanhf :: proc(x: float) -> float ---; @(link_name="atanhf") libc_atanhf :: proc(x: float) -> float ---
@(link_name="cosh") libc_cosh :: proc(x: double) -> double ---; @(link_name="cosh") libc_cosh :: proc(x: double) -> double ---
@(link_name="coshf") libc_coshf :: proc(x: float) -> float ---; @(link_name="coshf") libc_coshf :: proc(x: float) -> float ---
@(link_name="sinh") libc_sinh :: proc(x: double) -> double ---; @(link_name="sinh") libc_sinh :: proc(x: double) -> double ---
@(link_name="sinhf") libc_sinhf :: proc(x: float) -> float ---; @(link_name="sinhf") libc_sinhf :: proc(x: float) -> float ---
@(link_name="tanh") libc_tanh :: proc(x: double) -> double ---; @(link_name="tanh") libc_tanh :: proc(x: double) -> double ---
@(link_name="tanhf") libc_tanhf :: proc(x: float) -> float ---; @(link_name="tanhf") libc_tanhf :: proc(x: float) -> float ---
// 7.12.6 Exponential and logarithmic functions // 7.12.6 Exponential and logarithmic functions
@(link_name="exp") libc_exp :: proc(x: double) -> double ---; @(link_name="exp") libc_exp :: proc(x: double) -> double ---
@(link_name="expf") libc_expf :: proc(x: float) -> float ---; @(link_name="expf") libc_expf :: proc(x: float) -> float ---
@(link_name="exp2") libc_exp2 :: proc(x: double) -> double ---; @(link_name="exp2") libc_exp2 :: proc(x: double) -> double ---
@(link_name="exp2f") libc_exp2f :: proc(x: float) -> float ---; @(link_name="exp2f") libc_exp2f :: proc(x: float) -> float ---
@(link_name="expm1") libc_expm1 :: proc(x: double) -> double ---; @(link_name="expm1") libc_expm1 :: proc(x: double) -> double ---
@(link_name="expm1f") libc_expm1f :: proc(x: float) -> float ---; @(link_name="expm1f") libc_expm1f :: proc(x: float) -> float ---
@(link_name="frexp") libc_frexp :: proc(value: double, exp: ^int) -> double ---; @(link_name="frexp") libc_frexp :: proc(value: double, exp: ^int) -> double ---
@(link_name="frexpf") libc_frexpf :: proc(value: float, exp: ^int) -> float ---; @(link_name="frexpf") libc_frexpf :: proc(value: float, exp: ^int) -> float ---
@(link_name="ilogb") libc_ilogb :: proc(x: double) -> int ---; @(link_name="ilogb") libc_ilogb :: proc(x: double) -> int ---
@(link_name="ilogbf") libc_ilogbf :: proc(x: float) -> int ---; @(link_name="ilogbf") libc_ilogbf :: proc(x: float) -> int ---
@(link_name="ldexp") libc_ldexp :: proc(x: double, exp: int) -> double ---; @(link_name="ldexp") libc_ldexp :: proc(x: double, exp: int) -> double ---
@(link_name="ldexpf") libc_ldexpf :: proc(x: float, exp: int) -> float ---; @(link_name="ldexpf") libc_ldexpf :: proc(x: float, exp: int) -> float ---
@(link_name="log") libc_log :: proc(x: double) -> double ---; @(link_name="log") libc_log :: proc(x: double) -> double ---
@(link_name="logf") libc_logf :: proc(x: float) -> float ---; @(link_name="logf") libc_logf :: proc(x: float) -> float ---
@(link_name="log10") libc_log10 :: proc(x: double) -> double ---; @(link_name="log10") libc_log10 :: proc(x: double) -> double ---
@(link_name="log10f") libc_log10f :: proc(x: float) -> float ---; @(link_name="log10f") libc_log10f :: proc(x: float) -> float ---
@(link_name="log1p") libc_log1p :: proc(x: double) -> double ---; @(link_name="log1p") libc_log1p :: proc(x: double) -> double ---
@(link_name="log1pf") libc_log1pf :: proc(x: float) -> float ---; @(link_name="log1pf") libc_log1pf :: proc(x: float) -> float ---
@(link_name="log2") libc_log2 :: proc(x: double) -> double ---; @(link_name="log2") libc_log2 :: proc(x: double) -> double ---
@(link_name="log2f") libc_log2f :: proc(x: float) -> float ---; @(link_name="log2f") libc_log2f :: proc(x: float) -> float ---
@(link_name="logb") libc_logb :: proc(x: double) -> double ---; @(link_name="logb") libc_logb :: proc(x: double) -> double ---
@(link_name="logbf") libc_logbf :: proc(x: float) -> float ---; @(link_name="logbf") libc_logbf :: proc(x: float) -> float ---
@(link_name="modf") libc_modf :: proc(value: double, iptr: ^double) -> double ---; @(link_name="modf") libc_modf :: proc(value: double, iptr: ^double) -> double ---
@(link_name="modff") libc_modff :: proc(value: float, iptr: ^float) -> float ---; @(link_name="modff") libc_modff :: proc(value: float, iptr: ^float) -> float ---
@(link_name="scalbn") libc_scalbn :: proc(x: double, n: int) -> double ---; @(link_name="scalbn") libc_scalbn :: proc(x: double, n: int) -> double ---
@(link_name="scalbnf") libc_scalbnf :: proc(x: float, n: int) -> float ---; @(link_name="scalbnf") libc_scalbnf :: proc(x: float, n: int) -> float ---
@(link_name="scalbln") libc_scalbln :: proc(x: double, n: long) -> double ---; @(link_name="scalbln") libc_scalbln :: proc(x: double, n: long) -> double ---
@(link_name="scalblnf") libc_scalblnf :: proc(x: float, n: long) -> float ---; @(link_name="scalblnf") libc_scalblnf :: proc(x: float, n: long) -> float ---
// 7.12.7 Power and absolute-value functions // 7.12.7 Power and absolute-value functions
@(link_name="cbrt") libc_cbrt :: proc(x: double) -> double ---; @(link_name="cbrt") libc_cbrt :: proc(x: double) -> double ---
@(link_name="cbrtf") libc_cbrtf :: proc(x: float) -> float ---; @(link_name="cbrtf") libc_cbrtf :: proc(x: float) -> float ---
@(link_name="fabs") libc_fabs :: proc(x: double) -> double ---; @(link_name="fabs") libc_fabs :: proc(x: double) -> double ---
@(link_name="fabsf") libc_fabsf :: proc(x: float) -> float ---; @(link_name="fabsf") libc_fabsf :: proc(x: float) -> float ---
@(link_name="hypot") libc_hypot :: proc(x: double, y: double) -> double ---; @(link_name="hypot") libc_hypot :: proc(x: double, y: double) -> double ---
@(link_name="hypotf") libc_hypotf :: proc(x: float, y: float) -> float ---; @(link_name="hypotf") libc_hypotf :: proc(x: float, y: float) -> float ---
@(link_name="pow") libc_pow :: proc(x: double, y: double) -> double ---; @(link_name="pow") libc_pow :: proc(x: double, y: double) -> double ---
@(link_name="powf") libc_powf :: proc(x: float, y: float) -> float ---; @(link_name="powf") libc_powf :: proc(x: float, y: float) -> float ---
@(link_name="sqrt") libc_sqrt :: proc(x: double) -> double ---; @(link_name="sqrt") libc_sqrt :: proc(x: double) -> double ---
@(link_name="sqrtf") libc_sqrtf :: proc(x: float) -> float ---; @(link_name="sqrtf") libc_sqrtf :: proc(x: float) -> float ---
// 7.12.8 Error and gamma functions // 7.12.8 Error and gamma functions
@(link_name="erf") libc_erf :: proc(x: double) -> double ---; @(link_name="erf") libc_erf :: proc(x: double) -> double ---
@(link_name="erff") libc_erff :: proc(x: float) -> float ---; @(link_name="erff") libc_erff :: proc(x: float) -> float ---
@(link_name="erfc") libc_erfc :: proc(x: double) -> double ---; @(link_name="erfc") libc_erfc :: proc(x: double) -> double ---
@(link_name="erfcf") libc_erfcf :: proc(x: float) -> float ---; @(link_name="erfcf") libc_erfcf :: proc(x: float) -> float ---
@(link_name="lgamma") libc_lgamma :: proc(x: double) -> double ---; @(link_name="lgamma") libc_lgamma :: proc(x: double) -> double ---
@(link_name="lgammaf") libc_lgammaf :: proc(x: float) -> float ---; @(link_name="lgammaf") libc_lgammaf :: proc(x: float) -> float ---
@(link_name="tgamma") libc_tgamma :: proc(x: double) -> double ---; @(link_name="tgamma") libc_tgamma :: proc(x: double) -> double ---
@(link_name="tgammaf") libc_tgammaf :: proc(x: float) -> float ---; @(link_name="tgammaf") libc_tgammaf :: proc(x: float) -> float ---
// 7.12.9 Nearest integer functions // 7.12.9 Nearest integer functions
@(link_name="ceil") libc_ceil :: proc(x: double) -> double ---; @(link_name="ceil") libc_ceil :: proc(x: double) -> double ---
@(link_name="ceilf") libc_ceilf :: proc(x: float) -> float ---; @(link_name="ceilf") libc_ceilf :: proc(x: float) -> float ---
@(link_name="floor") libc_floor :: proc(x: double) -> double ---; @(link_name="floor") libc_floor :: proc(x: double) -> double ---
@(link_name="floorf") libc_floorf :: proc(x: float) -> float ---; @(link_name="floorf") libc_floorf :: proc(x: float) -> float ---
@(link_name="nearbyint") libc_nearbyint :: proc(x: double) -> double ---; @(link_name="nearbyint") libc_nearbyint :: proc(x: double) -> double ---
@(link_name="nearbyintf") libc_nearbyintf :: proc(x: float) -> float ---; @(link_name="nearbyintf") libc_nearbyintf :: proc(x: float) -> float ---
@(link_name="rint") libc_rint :: proc(x: double) -> double ---; @(link_name="rint") libc_rint :: proc(x: double) -> double ---
@(link_name="rintf") libc_rintf :: proc(x: float) -> float ---; @(link_name="rintf") libc_rintf :: proc(x: float) -> float ---
@(link_name="lrint") libc_lrint :: proc(x: double) -> long ---; @(link_name="lrint") libc_lrint :: proc(x: double) -> long ---
@(link_name="lrintf") libc_lrintf :: proc(x: float) -> long ---; @(link_name="lrintf") libc_lrintf :: proc(x: float) -> long ---
@(link_name="llrint") libc_llrint :: proc(x: double) -> longlong ---; @(link_name="llrint") libc_llrint :: proc(x: double) -> longlong ---
@(link_name="llrintf") libc_llrintf :: proc(x: float) -> longlong ---; @(link_name="llrintf") libc_llrintf :: proc(x: float) -> longlong ---
@(link_name="round") libc_round :: proc(x: double) -> double ---; @(link_name="round") libc_round :: proc(x: double) -> double ---
@(link_name="roundf") libc_roundf :: proc(x: float) -> float ---; @(link_name="roundf") libc_roundf :: proc(x: float) -> float ---
@(link_name="lround") libc_lround :: proc(x: double) -> long ---; @(link_name="lround") libc_lround :: proc(x: double) -> long ---
@(link_name="lroundf") libc_lroundf :: proc(x: float) -> long ---; @(link_name="lroundf") libc_lroundf :: proc(x: float) -> long ---
@(link_name="llround") libc_llround :: proc(x: double) -> longlong ---; @(link_name="llround") libc_llround :: proc(x: double) -> longlong ---
@(link_name="llroundf") libc_llroundf :: proc(x: float) -> longlong ---; @(link_name="llroundf") libc_llroundf :: proc(x: float) -> longlong ---
@(link_name="trunc") libc_trunc :: proc(x: double) -> double ---; @(link_name="trunc") libc_trunc :: proc(x: double) -> double ---
@(link_name="truncf") libc_truncf :: proc(x: float) -> float ---; @(link_name="truncf") libc_truncf :: proc(x: float) -> float ---
// 7.12.10 Remainder functions // 7.12.10 Remainder functions
@(link_name="fmod") libc_fmod :: proc(x: double, y: double) -> double ---; @(link_name="fmod") libc_fmod :: proc(x: double, y: double) -> double ---
@(link_name="fmodf") libc_fmodf :: proc(x: float, y: float) -> float ---; @(link_name="fmodf") libc_fmodf :: proc(x: float, y: float) -> float ---
@(link_name="remainder") libc_remainder :: proc(x: double, y: double) -> double ---; @(link_name="remainder") libc_remainder :: proc(x: double, y: double) -> double ---
@(link_name="remainderf") libc_remainderf :: proc(x: float, y: float) -> float ---; @(link_name="remainderf") libc_remainderf :: proc(x: float, y: float) -> float ---
@(link_name="remquo") libc_remquo :: proc(x: double, y: double, quo: ^int) -> double ---; @(link_name="remquo") libc_remquo :: proc(x: double, y: double, quo: ^int) -> double ---
@(link_name="remquof") libc_remquof :: proc(x: float, y: float, quo: ^int) -> float ---; @(link_name="remquof") libc_remquof :: proc(x: float, y: float, quo: ^int) -> float ---
// 7.12.11 Manipulation functions // 7.12.11 Manipulation functions
@(link_name="copysign") libc_copysign :: proc(x: double, y: double) -> double ---; @(link_name="copysign") libc_copysign :: proc(x: double, y: double) -> double ---
@(link_name="copysignf") libc_copysignf :: proc(x: float, y: float) -> float ---; @(link_name="copysignf") libc_copysignf :: proc(x: float, y: float) -> float ---
@(link_name="nan") libc_nan :: proc(tagp: cstring) -> double ---; @(link_name="nan") libc_nan :: proc(tagp: cstring) -> double ---
@(link_name="nanf") libc_nanf :: proc(tagp: cstring) -> float ---; @(link_name="nanf") libc_nanf :: proc(tagp: cstring) -> float ---
@(link_name="nextafter") libc_nextafter :: proc(x: double, y: double) -> double ---; @(link_name="nextafter") libc_nextafter :: proc(x: double, y: double) -> double ---
@(link_name="nextafterf") libc_nextafterf :: proc(x: float, y: float) -> float ---; @(link_name="nextafterf") libc_nextafterf :: proc(x: float, y: float) -> float ---
// 7.12.12 Maximum, minimum, and positive difference functions // 7.12.12 Maximum, minimum, and positive difference functions
@(link_name="fdim") libc_fdim :: proc(x: double, y: double) -> double ---; @(link_name="fdim") libc_fdim :: proc(x: double, y: double) -> double ---
@(link_name="fdimf") libc_fdimf :: proc(x: float, y: float) -> float ---; @(link_name="fdimf") libc_fdimf :: proc(x: float, y: float) -> float ---
@(link_name="fmax") libc_fmax :: proc(x: double, y: double) -> double ---; @(link_name="fmax") libc_fmax :: proc(x: double, y: double) -> double ---
@(link_name="fmaxf") libc_fmaxf :: proc(x: float, y: float) -> float ---; @(link_name="fmaxf") libc_fmaxf :: proc(x: float, y: float) -> float ---
@(link_name="fmin") libc_fmin :: proc(x: double, y: double) -> double ---; @(link_name="fmin") libc_fmin :: proc(x: double, y: double) -> double ---
@(link_name="fminf") libc_fminf :: proc(x: float, y: float) -> float ---; @(link_name="fminf") libc_fminf :: proc(x: float, y: float) -> float ---
@(link_name="fma") libc_fma :: proc(x, y, z: double) -> double ---; @(link_name="fma") libc_fma :: proc(x, y, z: double) -> double ---
@(link_name="fmaf") libc_fmaf :: proc(x, y, z: float) -> float ---; @(link_name="fmaf") libc_fmaf :: proc(x, y, z: float) -> float ---
} }
@(private="file") @(private="file")
_nan_bit_pattern := ~u64(0); _nan_bit_pattern := ~u64(0)
// On amd64 Windows and Linux, float_t and double_t are respectively both // On amd64 Windows and Linux, float_t and double_t are respectively both
// their usual types. On x86 it's not possible to define these types correctly // their usual types. On x86 it's not possible to define these types correctly
// since they would be long double which Odin does have support for. // since they would be long double which Odin does have support for.
float_t :: float; float_t :: float
double_t :: double; double_t :: double
NAN := transmute(double)(_nan_bit_pattern); NAN := transmute(double)(_nan_bit_pattern)
INFINITY :: 1e5000; INFINITY :: 1e5000
HUGE_VALF :: INFINITY; HUGE_VALF :: INFINITY
HUGE_VAL :: double(INFINITY); HUGE_VAL :: double(INFINITY)
MATH_ERRNO :: 1; MATH_ERRNO :: 1
MATH_ERREXCEPT :: 2; MATH_ERREXCEPT :: 2
math_errhandling :: 2; // Windows, Linux, macOS all use this mode. math_errhandling :: 2 // Windows, Linux, macOS all use this mode.
FP_ILOGBNAN :: -1 - int((~uint(0)) >> 1); FP_ILOGBNAN :: -1 - int((~uint(0)) >> 1)
FP_ILOGB0 :: FP_ILOGBNAN; FP_ILOGB0 :: FP_ILOGBNAN
// Number classification constants. These do not have to match libc since we // Number classification constants. These do not have to match libc since we
// implement our own classification functions as libc requires they be macros, // implement our own classification functions as libc requires they be macros,
// which means libc does not export standard functions for them. // which means libc does not export standard functions for them.
FP_NAN :: 0; FP_NAN :: 0
FP_INFINITE :: 1; FP_INFINITE :: 1
FP_ZERO :: 2; FP_ZERO :: 2
FP_NORMAL :: 3; FP_NORMAL :: 3
FP_SUBNORMAL :: 4; FP_SUBNORMAL :: 4
@(private) @(private)
_fpclassify :: #force_inline proc(x: double) -> int { _fpclassify :: #force_inline proc(x: double) -> int {
u := transmute(uint64_t)x; u := transmute(uint64_t)x
e := u >> 52 & 0x7ff; e := u >> 52 & 0x7ff
if e == 0 do return FP_SUBNORMAL if (u << 1) != 0 else FP_ZERO; if e == 0 do return FP_SUBNORMAL if (u << 1) != 0 else FP_ZERO
if e == 0x7ff do return FP_NAN if (u << 12) != 0 else FP_INFINITE; if e == 0x7ff do return FP_NAN if (u << 12) != 0 else FP_INFINITE
return FP_NORMAL; return FP_NORMAL
} }
@(private) @(private)
_fpclassifyf :: #force_inline proc(x: float) -> int { _fpclassifyf :: #force_inline proc(x: float) -> int {
u := transmute(uint32_t)x; u := transmute(uint32_t)x
e := u >> 23 & 0xff; e := u >> 23 & 0xff
if e == 0 do return FP_SUBNORMAL if (u << 1) != 0 else FP_ZERO; if e == 0 do return FP_SUBNORMAL if (u << 1) != 0 else FP_ZERO
if e == 0xff do return FP_NAN if (u << 9) != 0 else FP_INFINITE; if e == 0xff do return FP_NAN if (u << 9) != 0 else FP_INFINITE
return FP_NORMAL; return FP_NORMAL
} }
@(private) @(private)
_signbit :: #force_inline proc(x: double) -> int { _signbit :: #force_inline proc(x: double) -> int {
return int(transmute(uint64_t)x >> 63); return int(transmute(uint64_t)x >> 63)
} }
@(private) @(private)
_signbitf :: #force_inline proc(x: float) -> int { _signbitf :: #force_inline proc(x: float) -> int {
return int(transmute(uint32_t)x >> 31); return int(transmute(uint32_t)x >> 31)
} }
isfinite :: #force_inline proc(x: $T) where intrinsics.type_is_float(T) { isfinite :: #force_inline proc(x: $T) where intrinsics.type_is_float(T) {
return fpclassify(x) == FP_INFINITE; return fpclassify(x) == FP_INFINITE
} }
isinf :: #force_inline proc(x: $T) where intrinsics.type_is_float(T) { isinf :: #force_inline proc(x: $T) where intrinsics.type_is_float(T) {
return fpclassify(x) > FP_INFINITE; return fpclassify(x) > FP_INFINITE
} }
isnan :: #force_inline proc(x: $T) where intrinsics.type_is_float(T) { isnan :: #force_inline proc(x: $T) where intrinsics.type_is_float(T) {
return fpclassify(x) == FP_NAN; return fpclassify(x) == FP_NAN
} }
isnormal :: #force_inline proc(x: $T) where intrinsics.type_is_float(T) { isnormal :: #force_inline proc(x: $T) where intrinsics.type_is_float(T) {
return fpclassify(x) == FP_NORMAL; return fpclassify(x) == FP_NORMAL
} }
// These are special in that they avoid float exceptions. They cannot just be // These are special in that they avoid float exceptions. They cannot just be
@@ -228,173 +228,173 @@ isnormal :: #force_inline proc(x: $T) where intrinsics.type_is_float(T) {
// "sticky" state that propagates and affects maths results. These need // "sticky" state that propagates and affects maths results. These need
// to be implemented natively in Odin assuming isunordered to prevent that. // to be implemented natively in Odin assuming isunordered to prevent that.
isgreater :: #force_inline proc(x, y: $T) where intrinsics.type_is_float(T) { isgreater :: #force_inline proc(x, y: $T) where intrinsics.type_is_float(T) {
return !isunordered(x, y) && x > y; return !isunordered(x, y) && x > y
} }
isgreaterequal :: #force_inline proc(x, y: $T) where intrinsics.type_is_float(T) { isgreaterequal :: #force_inline proc(x, y: $T) where intrinsics.type_is_float(T) {
return !isunordered(x, y) && x >= y; return !isunordered(x, y) && x >= y
} }
isless :: #force_inline proc(x, y: $T) where intrinsics.type_is_float(T) { isless :: #force_inline proc(x, y: $T) where intrinsics.type_is_float(T) {
return !isunordered(x, y) && x < y; return !isunordered(x, y) && x < y
} }
islessequal :: #force_inline proc(x, y: $T) where intrinsics.type_is_float(T) { islessequal :: #force_inline proc(x, y: $T) where intrinsics.type_is_float(T) {
return !isunordered(x, y) && x <= y; return !isunordered(x, y) && x <= y
} }
islessgreater :: #force_inline proc(x, y: $T) where intrinsics.type_is_float(T) { islessgreater :: #force_inline proc(x, y: $T) where intrinsics.type_is_float(T) {
return !isunordered(x, y) && x <= y; return !isunordered(x, y) && x <= y
} }
isunordered :: #force_inline proc(x, y: $T) where intrinsics.type_is_float(T) { isunordered :: #force_inline proc(x, y: $T) where intrinsics.type_is_float(T) {
if isnan(x) { if isnan(x) {
// Force evaluation of y to propagate exceptions for ordering semantics. // Force evaluation of y to propagate exceptions for ordering semantics.
// To ensure correct semantics of IEEE 754 this cannot be compiled away. // To ensure correct semantics of IEEE 754 this cannot be compiled away.
sink: T; sink: T
intrinsics.volatile_store(&sink, intrinsics.volatile_load(&y)); intrinsics.volatile_store(&sink, intrinsics.volatile_load(&y))
return true; return true
} }
return isnan(y); return isnan(y)
} }
fpclassify :: proc{_fpclassify, _fpclassifyf}; fpclassify :: proc{_fpclassify, _fpclassifyf}
signbit :: proc{_signbit, _signbitf}; signbit :: proc{_signbit, _signbitf}
// Emulate tgmath.h behavior with explicit procedure overloading here. // Emulate tgmath.h behavior with explicit procedure overloading here.
acos :: proc{libc_acos, libc_acosf, cacos, cacosf}; acos :: proc{libc_acos, libc_acosf, cacos, cacosf}
asin :: proc{libc_asin, libc_asinf, casin, casinf}; asin :: proc{libc_asin, libc_asinf, casin, casinf}
atan :: proc{libc_atan, libc_atanf, catan, catanf}; atan :: proc{libc_atan, libc_atanf, catan, catanf}
atan2 :: proc{libc_atan2, libc_atan2f}; atan2 :: proc{libc_atan2, libc_atan2f}
cos :: proc{libc_cos, libc_cosf, ccos, ccosf}; cos :: proc{libc_cos, libc_cosf, ccos, ccosf}
sin :: proc{libc_sin, libc_sinf, csin, csinf}; sin :: proc{libc_sin, libc_sinf, csin, csinf}
tan :: proc{libc_tan, libc_tanf, ctan, ctanf}; tan :: proc{libc_tan, libc_tanf, ctan, ctanf}
acosh :: proc{libc_acosh, libc_acoshf, cacosh, cacoshf}; acosh :: proc{libc_acosh, libc_acoshf, cacosh, cacoshf}
asinh :: proc{libc_asinh, libc_asinhf, casinh, casinhf}; asinh :: proc{libc_asinh, libc_asinhf, casinh, casinhf}
atanh :: proc{libc_atanh, libc_atanhf, catanh, catanhf}; atanh :: proc{libc_atanh, libc_atanhf, catanh, catanhf}
cosh :: proc{libc_cosh, libc_coshf, ccosh, ccoshf}; cosh :: proc{libc_cosh, libc_coshf, ccosh, ccoshf}
sinh :: proc{libc_sinh, libc_sinhf, csinh, csinhf}; sinh :: proc{libc_sinh, libc_sinhf, csinh, csinhf}
tanh :: proc{libc_tanh, libc_tanhf, ctanh, ctanhf}; tanh :: proc{libc_tanh, libc_tanhf, ctanh, ctanhf}
exp :: proc{libc_exp, libc_expf, cexp, cexpf}; exp :: proc{libc_exp, libc_expf, cexp, cexpf}
exp2 :: proc{libc_exp2, libc_exp2f}; exp2 :: proc{libc_exp2, libc_exp2f}
expm1 :: proc{libc_expm1, libc_expm1f}; expm1 :: proc{libc_expm1, libc_expm1f}
frexp :: proc{libc_frexp, libc_frexpf}; frexp :: proc{libc_frexp, libc_frexpf}
ilogb :: proc{libc_ilogb, libc_ilogbf}; ilogb :: proc{libc_ilogb, libc_ilogbf}
ldexp :: proc{libc_ldexp, libc_ldexpf}; ldexp :: proc{libc_ldexp, libc_ldexpf}
log :: proc{libc_log, libc_logf, clog, clogf}; log :: proc{libc_log, libc_logf, clog, clogf}
log10 :: proc{libc_log10, libc_log10f}; log10 :: proc{libc_log10, libc_log10f}
log1p :: proc{libc_log1p, libc_log1pf}; log1p :: proc{libc_log1p, libc_log1pf}
log2 :: proc{libc_log2, libc_log2f}; log2 :: proc{libc_log2, libc_log2f}
logb :: proc{libc_logb, libc_logbf}; logb :: proc{libc_logb, libc_logbf}
modf :: proc{libc_modf, libc_modff}; modf :: proc{libc_modf, libc_modff}
scalbn :: proc{libc_scalbn, libc_scalbnf}; scalbn :: proc{libc_scalbn, libc_scalbnf}
scalbln :: proc{libc_scalbln, libc_scalblnf}; scalbln :: proc{libc_scalbln, libc_scalblnf}
cbrt :: proc{libc_cbrt, libc_cbrtf}; cbrt :: proc{libc_cbrt, libc_cbrtf}
fabs :: proc{libc_fabs, libc_fabsf, cabs, cabsf}; fabs :: proc{libc_fabs, libc_fabsf, cabs, cabsf}
hypot :: proc{libc_hypot, libc_hypotf}; hypot :: proc{libc_hypot, libc_hypotf}
pow :: proc{libc_pow, libc_powf, cpow, cpowf}; pow :: proc{libc_pow, libc_powf, cpow, cpowf}
sqrt :: proc{libc_sqrt, libc_sqrtf, csqrt, csqrtf}; sqrt :: proc{libc_sqrt, libc_sqrtf, csqrt, csqrtf}
erf :: proc{libc_erf, libc_erff}; erf :: proc{libc_erf, libc_erff}
erfc :: proc{libc_erfc, libc_erfcf}; erfc :: proc{libc_erfc, libc_erfcf}
lgamma :: proc{libc_lgamma, libc_lgammaf}; lgamma :: proc{libc_lgamma, libc_lgammaf}
tgamma :: proc{libc_tgamma, libc_tgammaf}; tgamma :: proc{libc_tgamma, libc_tgammaf}
ceil :: proc{libc_ceil, libc_ceilf}; ceil :: proc{libc_ceil, libc_ceilf}
floor :: proc{libc_floor, libc_floorf}; floor :: proc{libc_floor, libc_floorf}
nearbyint :: proc{libc_nearbyint, libc_nearbyintf}; nearbyint :: proc{libc_nearbyint, libc_nearbyintf}
rint :: proc{libc_rint, libc_rintf}; rint :: proc{libc_rint, libc_rintf}
lrint :: proc{libc_lrint, libc_lrintf}; lrint :: proc{libc_lrint, libc_lrintf}
llrint :: proc{libc_llrint, libc_llrintf}; llrint :: proc{libc_llrint, libc_llrintf}
round :: proc{libc_round, libc_roundf}; round :: proc{libc_round, libc_roundf}
lround :: proc{libc_lround, libc_lroundf}; lround :: proc{libc_lround, libc_lroundf}
llround :: proc{libc_llround, libc_llroundf}; llround :: proc{libc_llround, libc_llroundf}
trunc :: proc{libc_trunc, libc_truncf}; trunc :: proc{libc_trunc, libc_truncf}
fmod :: proc{libc_fmod, libc_fmodf}; fmod :: proc{libc_fmod, libc_fmodf}
remainder :: proc{libc_remainder, libc_remainderf}; remainder :: proc{libc_remainder, libc_remainderf}
remquo :: proc{libc_remquo, libc_remquof}; remquo :: proc{libc_remquo, libc_remquof}
copysign :: proc{libc_copysign, libc_copysignf}; copysign :: proc{libc_copysign, libc_copysignf}
nextafter :: proc{libc_nextafter, libc_nextafterf}; nextafter :: proc{libc_nextafter, libc_nextafterf}
fdim :: proc{libc_fdim, libc_fdimf}; fdim :: proc{libc_fdim, libc_fdimf}
fmax :: proc{libc_fmax, libc_fmaxf}; fmax :: proc{libc_fmax, libc_fmaxf}
fmin :: proc{libc_fmin, libc_fminf}; fmin :: proc{libc_fmin, libc_fminf}
fma :: proc{libc_fma, libc_fmaf}; fma :: proc{libc_fma, libc_fmaf}
// But retain the 'f' suffix-variant functions as well so they can be used, // But retain the 'f' suffix-variant functions as well so they can be used,
// a trick is used here where we use explicit procedrual overloading of one // a trick is used here where we use explicit procedrual overloading of one
// procedure. This is done because the foreign block is marked @(private) and // procedure. This is done because the foreign block is marked @(private) and
// aliasing functions does not remove privateness from the entity. // aliasing functions does not remove privateness from the entity.
acosf :: proc{libc_acosf}; acosf :: proc{libc_acosf}
asinf :: proc{libc_asinf}; asinf :: proc{libc_asinf}
atanf :: proc{libc_atanf}; atanf :: proc{libc_atanf}
atan2f :: proc{libc_atan2f}; atan2f :: proc{libc_atan2f}
cosf :: proc{libc_cosf}; cosf :: proc{libc_cosf}
sinf :: proc{libc_sinf}; sinf :: proc{libc_sinf}
tanf :: proc{libc_tanf}; tanf :: proc{libc_tanf}
acoshf :: proc{libc_acoshf}; acoshf :: proc{libc_acoshf}
asinhf :: proc{libc_asinhf}; asinhf :: proc{libc_asinhf}
atanhf :: proc{libc_atanhf}; atanhf :: proc{libc_atanhf}
coshf :: proc{libc_coshf}; coshf :: proc{libc_coshf}
sinhf :: proc{libc_sinhf}; sinhf :: proc{libc_sinhf}
tanhf :: proc{libc_tanhf}; tanhf :: proc{libc_tanhf}
expf :: proc{libc_expf}; expf :: proc{libc_expf}
exp2f :: proc{libc_exp2f}; exp2f :: proc{libc_exp2f}
expm1f :: proc{libc_expm1f}; expm1f :: proc{libc_expm1f}
frexpf :: proc{libc_frexpf}; frexpf :: proc{libc_frexpf}
ilogbf :: proc{libc_ilogbf}; ilogbf :: proc{libc_ilogbf}
ldexpf :: proc{libc_ldexpf}; ldexpf :: proc{libc_ldexpf}
logf :: proc{libc_logf}; logf :: proc{libc_logf}
log10f :: proc{libc_log10f}; log10f :: proc{libc_log10f}
log1pf :: proc{libc_log1pf}; log1pf :: proc{libc_log1pf}
log2f :: proc{libc_log2f}; log2f :: proc{libc_log2f}
logbf :: proc{libc_logbf}; logbf :: proc{libc_logbf}
modff :: proc{libc_modff}; modff :: proc{libc_modff}
scalbnf :: proc{libc_scalbnf}; scalbnf :: proc{libc_scalbnf}
scalblnf :: proc{libc_scalblnf}; scalblnf :: proc{libc_scalblnf}
cbrtf :: proc{libc_cbrtf}; cbrtf :: proc{libc_cbrtf}
fabsf :: proc{libc_fabsf}; fabsf :: proc{libc_fabsf}
hypotf :: proc{libc_hypotf}; hypotf :: proc{libc_hypotf}
powf :: proc{libc_powf}; powf :: proc{libc_powf}
sqrtf :: proc{libc_sqrtf}; sqrtf :: proc{libc_sqrtf}
erff :: proc{libc_erff}; erff :: proc{libc_erff}
erfcf :: proc{libc_erfcf}; erfcf :: proc{libc_erfcf}
lgammaf :: proc{libc_lgammaf}; lgammaf :: proc{libc_lgammaf}
tgammaf :: proc{libc_tgammaf}; tgammaf :: proc{libc_tgammaf}
ceilf :: proc{libc_ceilf}; ceilf :: proc{libc_ceilf}
floorf :: proc{libc_floorf}; floorf :: proc{libc_floorf}
nearbyintf :: proc{libc_nearbyintf}; nearbyintf :: proc{libc_nearbyintf}
rintf :: proc{libc_rintf}; rintf :: proc{libc_rintf}
lrintf :: proc{libc_lrintf}; lrintf :: proc{libc_lrintf}
llrintf :: proc{libc_llrintf}; llrintf :: proc{libc_llrintf}
roundf :: proc{libc_roundf}; roundf :: proc{libc_roundf}
lroundf :: proc{libc_lroundf}; lroundf :: proc{libc_lroundf}
llroundf :: proc{libc_llroundf}; llroundf :: proc{libc_llroundf}
truncf :: proc{libc_truncf}; truncf :: proc{libc_truncf}
fmodf :: proc{libc_fmodf}; fmodf :: proc{libc_fmodf}
remainderf :: proc{libc_remainderf}; remainderf :: proc{libc_remainderf}
remquof :: proc{libc_remquof}; remquof :: proc{libc_remquof}
copysignf :: proc{libc_copysignf}; copysignf :: proc{libc_copysignf}
nextafterf :: proc{libc_nextafterf}; nextafterf :: proc{libc_nextafterf}
fdimf :: proc{libc_fdimf}; fdimf :: proc{libc_fdimf}
fmaxf :: proc{libc_fmaxf}; fmaxf :: proc{libc_fmaxf}
fminf :: proc{libc_fminf}; fminf :: proc{libc_fminf}
fmaf :: proc{libc_fmaf}; fmaf :: proc{libc_fmaf}
// These two functions are special and not made type generic in tgmath.h since // These two functions are special and not made type generic in tgmath.h since
// they only differ by their return type. // they only differ by their return type.
nan :: proc{libc_nan}; nan :: proc{libc_nan}
nanf :: proc{libc_nanf}; nanf :: proc{libc_nanf}
+4 -4
View File
@@ -31,7 +31,7 @@ when ODIN_OS == "windows" {
// the RDX register will contain zero and correctly set the flag to disable // the RDX register will contain zero and correctly set the flag to disable
// stack unwinding. // stack unwinding.
@(link_name="_setjmp") @(link_name="_setjmp")
setjmp :: proc(env: ^jmp_buf, hack: rawptr = nil) -> int ---; setjmp :: proc(env: ^jmp_buf, hack: rawptr = nil) -> int ---
} }
} else { } else {
@(default_calling_convention="c") @(default_calling_convention="c")
@@ -42,14 +42,14 @@ when ODIN_OS == "windows" {
// necessarily export a symbol named setjmp but rather _setjmp in the case // necessarily export a symbol named setjmp but rather _setjmp in the case
// of musl, glibc, BSD libc, and msvcrt. // of musl, glibc, BSD libc, and msvcrt.
@(link_name="_setjmp") @(link_name="_setjmp")
setjmp :: proc(env: ^jmp_buf) -> int ---; setjmp :: proc(env: ^jmp_buf) -> int ---
} }
} }
@(default_calling_convention="c") @(default_calling_convention="c")
foreign libc { foreign libc {
// 7.13.2 Restore calling environment // 7.13.2 Restore calling environment
longjmp :: proc(env: ^jmp_buf, val: int) -> ! ---; longjmp :: proc(env: ^jmp_buf, val: int) -> ! ---
} }
// The C99 Rationale describes jmp_buf as being an array type for backward // The C99 Rationale describes jmp_buf as being an array type for backward
@@ -62,4 +62,4 @@ foreign libc {
// strictly conformant C implementation is 16 on the platforms we care about. // strictly conformant C implementation is 16 on the platforms we care about.
// The choice of 4096 bytes for storage of this type is more than enough on all // The choice of 4096 bytes for storage of this type is more than enough on all
// relevant platforms. // relevant platforms.
jmp_buf :: struct #align 16 { _: [4096]char, }; jmp_buf :: struct #align 16 { _: [4096]char, }
+21 -21
View File
@@ -8,36 +8,36 @@ when ODIN_OS == "windows" {
foreign import libc "system:c" foreign import libc "system:c"
} }
sig_atomic_t :: distinct atomic_int; sig_atomic_t :: distinct atomic_int
@(default_calling_convention="c") @(default_calling_convention="c")
foreign libc { foreign libc {
signal :: proc(sig: int, func: proc "c" (int)) -> proc "c" (int) ---; signal :: proc(sig: int, func: proc "c" (int)) -> proc "c" (int) ---
raise :: proc(sig: int) -> int ---; raise :: proc(sig: int) -> int ---
} }
when ODIN_OS == "windows" { when ODIN_OS == "windows" {
SIG_ERR :: rawptr(~uintptr(0)); SIG_ERR :: rawptr(~uintptr(0))
SIG_DFL :: rawptr(uintptr(0)); SIG_DFL :: rawptr(uintptr(0))
SIG_IGN :: rawptr(uintptr(1)); SIG_IGN :: rawptr(uintptr(1))
SIGABRT :: 22; SIGABRT :: 22
SIGFPE :: 8; SIGFPE :: 8
SIGILL :: 4; SIGILL :: 4
SIGINT :: 2; SIGINT :: 2
SIGSEGV :: 11; SIGSEGV :: 11
SIGTERM :: 15; SIGTERM :: 15
} }
when ODIN_OS == "linux" || ODIN_OS == "freebsd" || ODIN_OS == "darwin" { when ODIN_OS == "linux" || ODIN_OS == "freebsd" || ODIN_OS == "darwin" {
SIG_ERR :: rawptr(~uintptr(0)); SIG_ERR :: rawptr(~uintptr(0))
SIG_DFL :: rawptr(uintptr(0)); SIG_DFL :: rawptr(uintptr(0))
SIG_IGN :: rawptr(uintptr(1)); SIG_IGN :: rawptr(uintptr(1))
SIGABRT :: 6; SIGABRT :: 6
SIGFPE :: 8; SIGFPE :: 8
SIGILL :: 4; SIGILL :: 4
SIGINT :: 2; SIGINT :: 2
SIGSEGV :: 11; SIGSEGV :: 11
SIGTERM :: 15; SIGTERM :: 15
} }
+7 -7
View File
@@ -9,9 +9,9 @@ import "core:mem"
@(private="file") @(private="file")
@(default_calling_convention="none") @(default_calling_convention="none")
foreign _ { foreign _ {
@(link_name="llvm.va_start") _va_start :: proc(arglist: ^i8) ---; @(link_name="llvm.va_start") _va_start :: proc(arglist: ^i8) ---
@(link_name="llvm.va_end") _va_end :: proc(arglist: ^i8) ---; @(link_name="llvm.va_end") _va_end :: proc(arglist: ^i8) ---
@(link_name="llvm.va_copy") _va_copy :: proc(dst, src: ^i8) ---; @(link_name="llvm.va_copy") _va_copy :: proc(dst, src: ^i8) ---
} }
// Since there are no types in C with an alignment larger than that of // Since there are no types in C with an alignment larger than that of
@@ -22,18 +22,18 @@ foreign _ {
// relevant platforms. // relevant platforms.
va_list :: struct #align 16 { va_list :: struct #align 16 {
_: [4096]u8, _: [4096]u8,
}; }
va_start :: #force_inline proc(ap: ^va_list, _: any) { va_start :: #force_inline proc(ap: ^va_list, _: any) {
_va_start(cast(^i8)ap); _va_start(cast(^i8)ap)
} }
va_end :: #force_inline proc(ap: ^va_list) { va_end :: #force_inline proc(ap: ^va_list) {
_va_end(cast(^i8)ap); _va_end(cast(^i8)ap)
} }
va_copy :: #force_inline proc(dst, src: ^va_list) { va_copy :: #force_inline proc(dst, src: ^va_list) {
_va_copy(cast(^i8)dst, cast(^i8)src); _va_copy(cast(^i8)dst, cast(^i8)src)
} }
// We cannot provide va_arg as there is no way to create "C" style procedures // We cannot provide va_arg as there is no way to create "C" style procedures
+172 -172
View File
@@ -4,16 +4,16 @@ package libc
import "core:intrinsics" import "core:intrinsics"
ATOMIC_BOOL_LOCK_FREE :: true; ATOMIC_BOOL_LOCK_FREE :: true
ATOMIC_CHAR_LOCK_FREE :: true; ATOMIC_CHAR_LOCK_FREE :: true
ATOMIC_CHAR16_T_LOCK_FREE :: true; ATOMIC_CHAR16_T_LOCK_FREE :: true
ATOMIC_CHAR32_T_LOCK_FREE :: true; ATOMIC_CHAR32_T_LOCK_FREE :: true
ATOMIC_WCHAR_T_LOCK_FREE :: true; ATOMIC_WCHAR_T_LOCK_FREE :: true
ATOMIC_SHORT_LOCK_FREE :: true; ATOMIC_SHORT_LOCK_FREE :: true
ATOMIC_INT_LOCK_FREE :: true; ATOMIC_INT_LOCK_FREE :: true
ATOMIC_LONG_LOCK_FREE :: true; ATOMIC_LONG_LOCK_FREE :: true
ATOMIC_LLONG_LOCK_FREE :: true; ATOMIC_LLONG_LOCK_FREE :: true
ATOMIC_POINTER_LOCK_FREE :: true; ATOMIC_POINTER_LOCK_FREE :: true
// 7.17.3 Order and consistency // 7.17.3 Order and consistency
memory_order :: enum int { memory_order :: enum int {
@@ -25,152 +25,152 @@ memory_order :: enum int {
seq_cst, seq_cst,
} }
memory_order_relaxed :: memory_order.relaxed; memory_order_relaxed :: memory_order.relaxed
memory_order_consume :: memory_order.consume; memory_order_consume :: memory_order.consume
memory_order_acquire :: memory_order.acquire; memory_order_acquire :: memory_order.acquire
memory_order_release :: memory_order.release; memory_order_release :: memory_order.release
memory_order_acq_rel :: memory_order.acq_rel; memory_order_acq_rel :: memory_order.acq_rel
memory_order_seq_cst :: memory_order.seq_cst; memory_order_seq_cst :: memory_order.seq_cst
// 7.17.2 Initialization // 7.17.2 Initialization
ATOMIC_VAR_INIT :: #force_inline proc(value: $T) -> T { ATOMIC_VAR_INIT :: #force_inline proc(value: $T) -> T {
return value; return value
} }
atomic_init :: #force_inline proc(obj: ^$T, value: T) { atomic_init :: #force_inline proc(obj: ^$T, value: T) {
intrinsics.atomic_store(obj, value); intrinsics.atomic_store(obj, value)
} }
kill_dependency :: #force_inline proc(value: $T) -> T { kill_dependency :: #force_inline proc(value: $T) -> T {
return value; return value
} }
// 7.17.4 Fences // 7.17.4 Fences
atomic_thread_fence :: #force_inline proc(order: memory_order) { atomic_thread_fence :: #force_inline proc(order: memory_order) {
switch (order) { switch (order) {
case .relaxed: case .relaxed:
return; return
case .consume: case .consume:
intrinsics.atomic_fence_acq(); intrinsics.atomic_fence_acq()
case .acquire: case .acquire:
intrinsics.atomic_fence_acq(); intrinsics.atomic_fence_acq()
case .release: case .release:
intrinsics.atomic_fence_rel(); intrinsics.atomic_fence_rel()
case .acq_rel: case .acq_rel:
intrinsics.atomic_fence_acqrel(); intrinsics.atomic_fence_acqrel()
case .seq_cst: case .seq_cst:
intrinsics.atomic_fence_acqrel(); intrinsics.atomic_fence_acqrel()
} }
} }
atomic_signal_fence :: #force_inline proc(order: memory_order) { atomic_signal_fence :: #force_inline proc(order: memory_order) {
atomic_thread_fence(order); atomic_thread_fence(order)
} }
// 7.17.5 Lock-free property // 7.17.5 Lock-free property
atomic_is_lock_free :: #force_inline proc(obj: ^$T) -> bool { atomic_is_lock_free :: #force_inline proc(obj: ^$T) -> bool {
return size_of(T) <= 8 && (intrinsics.type_is_integer(T) || intrinsics.type_is_pointer(T)); return size_of(T) <= 8 && (intrinsics.type_is_integer(T) || intrinsics.type_is_pointer(T))
} }
// 7.17.6 Atomic integer types // 7.17.6 Atomic integer types
atomic_bool :: distinct bool; atomic_bool :: distinct bool
atomic_char :: distinct char; atomic_char :: distinct char
atomic_schar :: distinct char; atomic_schar :: distinct char
atomic_uchar :: distinct uchar; atomic_uchar :: distinct uchar
atomic_short :: distinct short; atomic_short :: distinct short
atomic_ushort :: distinct ushort; atomic_ushort :: distinct ushort
atomic_int :: distinct int; atomic_int :: distinct int
atomic_uint :: distinct uint; atomic_uint :: distinct uint
atomic_long :: distinct long; atomic_long :: distinct long
atomic_ulong :: distinct ulong; atomic_ulong :: distinct ulong
atomic_llong :: distinct longlong; atomic_llong :: distinct longlong
atomic_ullong :: distinct ulonglong; atomic_ullong :: distinct ulonglong
atomic_char16_t :: distinct char16_t; atomic_char16_t :: distinct char16_t
atomic_char32_t :: distinct char32_t; atomic_char32_t :: distinct char32_t
atomic_wchar_t :: distinct wchar_t; atomic_wchar_t :: distinct wchar_t
atomic_int_least8_t :: distinct int_least8_t; atomic_int_least8_t :: distinct int_least8_t
atomic_uint_least8_t :: distinct uint_least8_t; atomic_uint_least8_t :: distinct uint_least8_t
atomic_int_least16_t :: distinct int_least16_t; atomic_int_least16_t :: distinct int_least16_t
atomic_uint_least16_t :: distinct uint_least16_t; atomic_uint_least16_t :: distinct uint_least16_t
atomic_int_least32_t :: distinct int_least32_t; atomic_int_least32_t :: distinct int_least32_t
atomic_uint_least32_t :: distinct uint_least32_t; atomic_uint_least32_t :: distinct uint_least32_t
atomic_int_least64_t :: distinct int_least64_t; atomic_int_least64_t :: distinct int_least64_t
atomic_uint_least64_t :: distinct uint_least64_t; atomic_uint_least64_t :: distinct uint_least64_t
atomic_int_fast8_t :: distinct int_fast8_t; atomic_int_fast8_t :: distinct int_fast8_t
atomic_uint_fast8_t :: distinct uint_fast8_t; atomic_uint_fast8_t :: distinct uint_fast8_t
atomic_int_fast16_t :: distinct int_fast16_t; atomic_int_fast16_t :: distinct int_fast16_t
atomic_uint_fast16_t :: distinct uint_fast16_t; atomic_uint_fast16_t :: distinct uint_fast16_t
atomic_int_fast32_t :: distinct int_fast32_t; atomic_int_fast32_t :: distinct int_fast32_t
atomic_uint_fast32_t :: distinct uint_fast32_t; atomic_uint_fast32_t :: distinct uint_fast32_t
atomic_int_fast64_t :: distinct int_fast64_t; atomic_int_fast64_t :: distinct int_fast64_t
atomic_uint_fast64_t :: distinct uint_fast64_t; atomic_uint_fast64_t :: distinct uint_fast64_t
atomic_intptr_t :: distinct intptr_t; atomic_intptr_t :: distinct intptr_t
atomic_uintptr_t :: distinct uintptr_t; atomic_uintptr_t :: distinct uintptr_t
atomic_size_t :: distinct size_t; atomic_size_t :: distinct size_t
atomic_ptrdiff_t :: distinct ptrdiff_t; atomic_ptrdiff_t :: distinct ptrdiff_t
atomic_intmax_t :: distinct intmax_t; atomic_intmax_t :: distinct intmax_t
atomic_uintmax_t :: distinct uintmax_t; atomic_uintmax_t :: distinct uintmax_t
// 7.17.7 Operations on atomic types // 7.17.7 Operations on atomic types
atomic_store :: #force_inline proc(object: ^$T, desired: T) { atomic_store :: #force_inline proc(object: ^$T, desired: T) {
intrinsics.atomic_store(object, desired); intrinsics.atomic_store(object, desired)
} }
atomic_store_explicit :: #force_inline proc(object: ^$T, desired: T, order: memory_order) { atomic_store_explicit :: #force_inline proc(object: ^$T, desired: T, order: memory_order) {
assert(order != .consume); assert(order != .consume)
assert(order != .acquire); assert(order != .acquire)
assert(order != .acq_rel); assert(order != .acq_rel)
#partial switch (order) { #partial switch (order) {
case .relaxed: case .relaxed:
intrinsics.atomic_store_relaxed(object, desired); intrinsics.atomic_store_relaxed(object, desired)
case .release: case .release:
intrinsics.atomic_store_rel(object, desired); intrinsics.atomic_store_rel(object, desired)
case .seq_cst: case .seq_cst:
intrinsics.atomic_store(object, desired); intrinsics.atomic_store(object, desired)
} }
} }
atomic_load :: #force_inline proc(object: ^$T) -> T { atomic_load :: #force_inline proc(object: ^$T) -> T {
return intrinsics.atomic_load(object); return intrinsics.atomic_load(object)
} }
atomic_load_explicit :: #force_inline proc(object: ^$T, order: memory_order) { atomic_load_explicit :: #force_inline proc(object: ^$T, order: memory_order) {
assert(order != .release); assert(order != .release)
assert(order != .acq_rel); assert(order != .acq_rel)
#partial switch (order) { #partial switch (order) {
case .relaxed: case .relaxed:
return intrinsics.atomic_load_relaxed(object); return intrinsics.atomic_load_relaxed(object)
case .consume: case .consume:
return intrinsics.atomic_load_acq(object); return intrinsics.atomic_load_acq(object)
case .acquire: case .acquire:
return intrinsics.atomic_load_acq(object); return intrinsics.atomic_load_acq(object)
case .seq_cst: case .seq_cst:
return intrinsics.atomic_load(object); return intrinsics.atomic_load(object)
} }
} }
atomic_exchange :: #force_inline proc(object: ^$T, desired: T) -> T { atomic_exchange :: #force_inline proc(object: ^$T, desired: T) -> T {
return intrinsics.atomic_xchg(object, desired); return intrinsics.atomic_xchg(object, desired)
} }
atomic_exchange_explicit :: #force_inline proc(object: ^$T, desired: T, order: memory_order) -> T { atomic_exchange_explicit :: #force_inline proc(object: ^$T, desired: T, order: memory_order) -> T {
switch (order) { switch (order) {
case .relaxed: case .relaxed:
return intrinsics.atomic_xchg_relaxed(object, desired); return intrinsics.atomic_xchg_relaxed(object, desired)
case .consume: case .consume:
return intrinsics.atomic_xchg_acq(object, desired); return intrinsics.atomic_xchg_acq(object, desired)
case .acquire: case .acquire:
return intrinsics.atomic_xchg_acq(object, desired); return intrinsics.atomic_xchg_acq(object, desired)
case .release: case .release:
return intrinsics.atomic_xchg_rel(object, desired); return intrinsics.atomic_xchg_rel(object, desired)
case .acq_rel: case .acq_rel:
return intrinsics.atomic_xchg_acqrel(object, desired); return intrinsics.atomic_xchg_acqrel(object, desired)
case .seq_cst: case .seq_cst:
return intrinsics.atomic_xchg(object, desired); return intrinsics.atomic_xchg(object, desired)
} }
return false; return false
} }
// C does not allow failure memory order to be order_release or acq_rel. // C does not allow failure memory order to be order_release or acq_rel.
@@ -190,227 +190,227 @@ atomic_exchange_explicit :: #force_inline proc(object: ^$T, desired: T, order: m
// [success = acquire, failure = relaxed] => acq_failrelaxed // [success = acquire, failure = relaxed] => acq_failrelaxed
// [success = acq_rel, failure = relaxed] => acqrel_failrelaxed // [success = acq_rel, failure = relaxed] => acqrel_failrelaxed
atomic_compare_exchange_strong :: #force_inline proc(object, expected: ^$T, desired: T) { atomic_compare_exchange_strong :: #force_inline proc(object, expected: ^$T, desired: T) {
value, ok := intrinsics.atomic_cxchg(object, expected^, desired); value, ok := intrinsics.atomic_cxchg(object, expected^, desired)
if !ok do expected^ = value; if !ok do expected^ = value
return ok; return ok
} }
atomic_compare_exchange_strong_explicit :: #force_inline proc(object, expected: ^$T, desired: T, success, failure: memory_order) { atomic_compare_exchange_strong_explicit :: #force_inline proc(object, expected: ^$T, desired: T, success, failure: memory_order) {
assert(failure != .release); assert(failure != .release)
assert(failure != .acq_rel); assert(failure != .acq_rel)
value: T; ok: bool; value: T; ok: bool
#partial switch (failure) { #partial switch (failure) {
case .seq_cst: case .seq_cst:
assert(success != .relaxed); assert(success != .relaxed)
#partial switch (success) { #partial switch (success) {
case .seq_cst: case .seq_cst:
value, ok := intrinsics.atomic_cxchg(object, expected^, desired); value, ok := intrinsics.atomic_cxchg(object, expected^, desired)
case .acquire: case .acquire:
value, ok := intrinsics.atomic_cxchg_acq(object, expected^, desired); value, ok := intrinsics.atomic_cxchg_acq(object, expected^, desired)
case .consume: case .consume:
value, ok := intrinsics.atomic_cxchg_acq(object, expected^, desired); value, ok := intrinsics.atomic_cxchg_acq(object, expected^, desired)
case .release: case .release:
value, ok := intrinsics.atomic_cxchg_rel(object, expected^, desired); value, ok := intrinsics.atomic_cxchg_rel(object, expected^, desired)
case .acq_rel: case .acq_rel:
value, ok := intrinsics.atomic_cxchg_acqrel(object, expected^, desired); value, ok := intrinsics.atomic_cxchg_acqrel(object, expected^, desired)
} }
case .relaxed: case .relaxed:
assert(success != .release); assert(success != .release)
#partial switch (success) { #partial switch (success) {
case .relaxed: case .relaxed:
value, ok := intrinsics.atomic_cxchg_relaxed(object, expected^, desired); value, ok := intrinsics.atomic_cxchg_relaxed(object, expected^, desired)
case .seq_cst: case .seq_cst:
value, ok := intrinsics.atomic_cxchg_failrelaxed(object, expected^, desired); value, ok := intrinsics.atomic_cxchg_failrelaxed(object, expected^, desired)
case .acquire: case .acquire:
value, ok := intrinsics.atomic_cxchg_acq_failrelaxed(object, expected^, desired); value, ok := intrinsics.atomic_cxchg_acq_failrelaxed(object, expected^, desired)
case .consume: case .consume:
value, ok := intrinsics.atomic_cxchg_acq_failrelaxed(object, expected^, desired); value, ok := intrinsics.atomic_cxchg_acq_failrelaxed(object, expected^, desired)
case .acq_rel: case .acq_rel:
value, ok := intrinsics.atomic_cxchg_acqrel_failrelaxed(object, expected^, desired); value, ok := intrinsics.atomic_cxchg_acqrel_failrelaxed(object, expected^, desired)
} }
case .consume: case .consume:
fallthrough; fallthrough
case .acquire: case .acquire:
assert(success == .seq_cst); assert(success == .seq_cst)
value, ok := intrinsics.atomic_cxchg_failacq(object, expected^, desired); value, ok := intrinsics.atomic_cxchg_failacq(object, expected^, desired)
} }
if !ok do expected^ = value; if !ok do expected^ = value
return ok; return ok
} }
atomic_compare_exchange_weak :: #force_inline proc(object, expected: ^$T, desired: T) { atomic_compare_exchange_weak :: #force_inline proc(object, expected: ^$T, desired: T) {
value, ok := intrinsics.atomic_cxchgweak(object, expected^, desired); value, ok := intrinsics.atomic_cxchgweak(object, expected^, desired)
if !ok do expected^ = value; if !ok do expected^ = value
return ok; return ok
} }
atomic_compare_exchange_weak_explicit :: #force_inline proc(object, expected: ^$T, desited: T, success, failure: memory_order) { atomic_compare_exchange_weak_explicit :: #force_inline proc(object, expected: ^$T, desited: T, success, failure: memory_order) {
assert(failure != .release); assert(failure != .release)
assert(failure != .acq_rel); assert(failure != .acq_rel)
value: T; ok: bool; value: T; ok: bool
#partial switch (failure) { #partial switch (failure) {
case .seq_cst: case .seq_cst:
assert(success != .relaxed); assert(success != .relaxed)
#partial switch (success) { #partial switch (success) {
case .seq_cst: case .seq_cst:
value, ok := intrinsics.atomic_cxchgweak(object, expected^, desired); value, ok := intrinsics.atomic_cxchgweak(object, expected^, desired)
case .acquire: case .acquire:
value, ok := intrinsics.atomic_cxchgweak_acq(object, expected^, desired); value, ok := intrinsics.atomic_cxchgweak_acq(object, expected^, desired)
case .consume: case .consume:
value, ok := intrinsics.atomic_cxchgweak_acq(object, expected^, desired); value, ok := intrinsics.atomic_cxchgweak_acq(object, expected^, desired)
case .release: case .release:
value, ok := intrinsics.atomic_cxchgweak_rel(object, expected^, desired); value, ok := intrinsics.atomic_cxchgweak_rel(object, expected^, desired)
case .acq_rel: case .acq_rel:
value, ok := intrinsics.atomic_cxchgweak_acqrel(object, expected^, desired); value, ok := intrinsics.atomic_cxchgweak_acqrel(object, expected^, desired)
} }
case .relaxed: case .relaxed:
assert(success != .release); assert(success != .release)
#partial switch (success) { #partial switch (success) {
case .relaxed: case .relaxed:
value, ok := intrinsics.atomic_cxchgweak_relaxed(object, expected^, desired); value, ok := intrinsics.atomic_cxchgweak_relaxed(object, expected^, desired)
case .seq_cst: case .seq_cst:
value, ok := intrinsics.atomic_cxchgweak_failrelaxed(object, expected^, desired); value, ok := intrinsics.atomic_cxchgweak_failrelaxed(object, expected^, desired)
case .acquire: case .acquire:
value, ok := intrinsics.atomic_cxchgweak_acq_failrelaxed(object, expected^, desired); value, ok := intrinsics.atomic_cxchgweak_acq_failrelaxed(object, expected^, desired)
case .consume: case .consume:
value, ok := intrinsics.atomic_cxchgweak_acq_failrelaxed(object, expected^, desired); value, ok := intrinsics.atomic_cxchgweak_acq_failrelaxed(object, expected^, desired)
case .acq_rel: case .acq_rel:
value, ok := intrinsics.atomic_cxchgweak_acqrel_failrelaxed(object, expected^, desired); value, ok := intrinsics.atomic_cxchgweak_acqrel_failrelaxed(object, expected^, desired)
} }
case .consume: case .consume:
fallthrough; fallthrough
case .acquire: case .acquire:
assert(success == .seq_cst); assert(success == .seq_cst)
value, ok := intrinsics.atomic_cxchgweak_failacq(object, expected^, desired); value, ok := intrinsics.atomic_cxchgweak_failacq(object, expected^, desired)
} }
if !ok do expected^ = value; if !ok do expected^ = value
return ok; return ok
} }
// 7.17.7.5 The atomic_fetch and modify generic functions // 7.17.7.5 The atomic_fetch and modify generic functions
atomic_fetch_add :: #force_inline proc(object: ^$T, operand: T) -> T { atomic_fetch_add :: #force_inline proc(object: ^$T, operand: T) -> T {
return intrinsics.atomic_add(object, operand); return intrinsics.atomic_add(object, operand)
} }
atomic_fetch_add_explicit :: #force_inline proc(object: ^$T, operand: T, order: memory_order) -> T { atomic_fetch_add_explicit :: #force_inline proc(object: ^$T, operand: T, order: memory_order) -> T {
switch (order) { switch (order) {
case .relaxed: case .relaxed:
return intrinsics.atomic_add_relaxed(object, operand); return intrinsics.atomic_add_relaxed(object, operand)
case .consume: case .consume:
return intrinsics.atomic_add_acq(object, operand); return intrinsics.atomic_add_acq(object, operand)
case .acquire: case .acquire:
return intrinsics.atomic_add_acq(object, operand); return intrinsics.atomic_add_acq(object, operand)
case .release: case .release:
return intrinsics.atomic_add_rel(object, operand); return intrinsics.atomic_add_rel(object, operand)
case .acq_rel: case .acq_rel:
return intrinsics.atomic_add_acqrel(object, operand); return intrinsics.atomic_add_acqrel(object, operand)
case .seq_cst: case .seq_cst:
return intrinsics.atomic_add(object, operand); return intrinsics.atomic_add(object, operand)
} }
} }
atomic_fetch_sub :: #force_inline proc(object: ^$T, operand: T) -> T { atomic_fetch_sub :: #force_inline proc(object: ^$T, operand: T) -> T {
return intrinsics.atomic_sub(object, operand); return intrinsics.atomic_sub(object, operand)
} }
atomic_fetch_sub_explicit :: #force_inline proc(object: ^$T, operand: T, order: memory_order) -> T { atomic_fetch_sub_explicit :: #force_inline proc(object: ^$T, operand: T, order: memory_order) -> T {
switch (order) { switch (order) {
case .relaxed: case .relaxed:
return intrinsics.atomic_sub_relaxed(object, operand); return intrinsics.atomic_sub_relaxed(object, operand)
case .consume: case .consume:
return intrinsics.atomic_sub_acq(object, operand); return intrinsics.atomic_sub_acq(object, operand)
case .acquire: case .acquire:
return intrinsics.atomic_sub_acq(object, operand); return intrinsics.atomic_sub_acq(object, operand)
case .release: case .release:
return intrinsics.atomic_sub_rel(object, operand); return intrinsics.atomic_sub_rel(object, operand)
case .acq_rel: case .acq_rel:
return intrinsics.atomic_sub_acqrel(object, operand); return intrinsics.atomic_sub_acqrel(object, operand)
case .seq_cst: case .seq_cst:
return intrinsics.atomic_sub(object, operand); return intrinsics.atomic_sub(object, operand)
} }
} }
atomic_fetch_or :: #force_inline proc(object: ^$T, operand: T) -> T { atomic_fetch_or :: #force_inline proc(object: ^$T, operand: T) -> T {
return intrinsics.atomic_or(object, operand); return intrinsics.atomic_or(object, operand)
} }
atomic_fetch_or_explicit :: #force_inline proc(object: ^$T, operand: T, order: memory_order) -> T { atomic_fetch_or_explicit :: #force_inline proc(object: ^$T, operand: T, order: memory_order) -> T {
switch (order) { switch (order) {
case .relaxed: case .relaxed:
return intrinsics.atomic_or_relaxed(object, operand); return intrinsics.atomic_or_relaxed(object, operand)
case .consume: case .consume:
return intrinsics.atomic_or_acq(object, operand); return intrinsics.atomic_or_acq(object, operand)
case .acquire: case .acquire:
return intrinsics.atomic_or_acq(object, operand); return intrinsics.atomic_or_acq(object, operand)
case .release: case .release:
return intrinsics.atomic_or_rel(object, operand); return intrinsics.atomic_or_rel(object, operand)
case .acq_rel: case .acq_rel:
return intrinsics.atomic_or_acqrel(object, operand); return intrinsics.atomic_or_acqrel(object, operand)
case .seq_cst: case .seq_cst:
return intrinsics.atomic_or(object, operand); return intrinsics.atomic_or(object, operand)
} }
} }
atomic_fetch_xor :: #force_inline proc(object: ^$T, operand: T) -> T { atomic_fetch_xor :: #force_inline proc(object: ^$T, operand: T) -> T {
return intrinsics.atomic_xor(object, operand); return intrinsics.atomic_xor(object, operand)
} }
atomic_fetch_xor_explicit :: #force_inline proc(object: ^$T, operand: T, order: memory_order) -> T { atomic_fetch_xor_explicit :: #force_inline proc(object: ^$T, operand: T, order: memory_order) -> T {
switch (order) { switch (order) {
case .relaxed: case .relaxed:
return intrinsics.atomic_xor_relaxed(object, operand); return intrinsics.atomic_xor_relaxed(object, operand)
case .consume: case .consume:
return intrinsics.atomic_xor_acq(object, operand); return intrinsics.atomic_xor_acq(object, operand)
case .acquire: case .acquire:
return intrinsics.atomic_xor_acq(object, operand); return intrinsics.atomic_xor_acq(object, operand)
case .release: case .release:
return intrinsics.atomic_xor_rel(object, operand); return intrinsics.atomic_xor_rel(object, operand)
case .acq_rel: case .acq_rel:
return intrinsics.atomic_xor_acqrel(object, operand); return intrinsics.atomic_xor_acqrel(object, operand)
case .seq_cst: case .seq_cst:
return intrinsics.atomic_xor(object, operand); return intrinsics.atomic_xor(object, operand)
} }
} }
atomic_fetch_and :: #force_inline proc(object: ^$T, operand: T) -> T { atomic_fetch_and :: #force_inline proc(object: ^$T, operand: T) -> T {
return intrinsics.atomic_and(object, operand); return intrinsics.atomic_and(object, operand)
} }
atomic_fetch_and_explicit :: #force_inline proc(object: ^$T, operand: T, order: memory_order) -> T { atomic_fetch_and_explicit :: #force_inline proc(object: ^$T, operand: T, order: memory_order) -> T {
switch (order) { switch (order) {
case .relaxed: case .relaxed:
return intrinsics.atomic_and_relaxed(object, operand); return intrinsics.atomic_and_relaxed(object, operand)
case .consume: case .consume:
return intrinsics.atomic_and_acq(object, operand); return intrinsics.atomic_and_acq(object, operand)
case .acquire: case .acquire:
return intrinsics.atomic_and_acq(object, operand); return intrinsics.atomic_and_acq(object, operand)
case .release: case .release:
return intrinsics.atomic_and_rel(object, operand); return intrinsics.atomic_and_rel(object, operand)
case .acq_rel: case .acq_rel:
return intrinsics.atomic_and_acqrel(object, operand); return intrinsics.atomic_and_acqrel(object, operand)
case .seq_cst: case .seq_cst:
return intrinsics.atomic_and(object, operand); return intrinsics.atomic_and(object, operand)
} }
} }
// 7.17.8 Atomic flag type and operations // 7.17.8 Atomic flag type and operations
atomic_flag :: distinct atomic_bool; atomic_flag :: distinct atomic_bool
atomic_flag_test_and_set :: #force_inline proc(flag: ^atomic_flag) -> bool { atomic_flag_test_and_set :: #force_inline proc(flag: ^atomic_flag) -> bool {
return bool(atomic_exchange(flag, atomic_flag(true))); return bool(atomic_exchange(flag, atomic_flag(true)))
} }
atomic_flag_test_and_set_explicit :: #force_inline proc(flag: ^atomic_flag, order: memory_order) -> bool { atomic_flag_test_and_set_explicit :: #force_inline proc(flag: ^atomic_flag, order: memory_order) -> bool {
return bool(atomic_exchange_explicit(flag, atomic_flag(true), order)); return bool(atomic_exchange_explicit(flag, atomic_flag(true), order))
} }
atomic_flag_clear :: #force_inline proc(flag: ^atomic_flag) { atomic_flag_clear :: #force_inline proc(flag: ^atomic_flag) {
atomic_store(flag, atomic_flag(false)); atomic_store(flag, atomic_flag(false))
} }
atomic_flag_clear_explicit :: #force_inline proc(flag: ^atomic_flag, order: memory_order) { atomic_flag_clear_explicit :: #force_inline proc(flag: ^atomic_flag, order: memory_order) {
atomic_store_explicit(flag, atomic_flag(false), order); atomic_store_explicit(flag, atomic_flag(false), order)
} }
+77 -77
View File
@@ -8,128 +8,128 @@ when ODIN_OS == "windows" {
// 7.21 Input/output // 7.21 Input/output
FILE :: struct {}; FILE :: struct {}
// MSVCRT compatible. // MSVCRT compatible.
when ODIN_OS == "windows" { when ODIN_OS == "windows" {
_IOFBF :: 0x0000; _IOFBF :: 0x0000
_IONBF :: 0x0004; _IONBF :: 0x0004
_IOLBF :: 0x0040; _IOLBF :: 0x0040
BUFSIZ :: 512; BUFSIZ :: 512
EOF :: int(-1); EOF :: int(-1)
FOPEN_MAX :: 20; FOPEN_MAX :: 20
FILENAME_MAX :: 260; FILENAME_MAX :: 260
L_tmpnam :: 15; // "\\" + 12 + NUL L_tmpnam :: 15 // "\\" + 12 + NUL
SEEK_SET :: 0; SEEK_SET :: 0
SEEK_CUR :: 1; SEEK_CUR :: 1
SEEK_END :: 2; SEEK_END :: 2
TMP_MAX :: 32767; // SHRT_MAX TMP_MAX :: 32767 // SHRT_MAX
fpos_t :: distinct i64; fpos_t :: distinct i64
@(private="file") @(private="file")
@(default_calling_convention="c") @(default_calling_convention="c")
foreign libc { foreign libc {
__acrt_iob_func :: proc (index: uint) -> ^FILE ---; __acrt_iob_func :: proc (index: uint) -> ^FILE ---
} }
stdin := __acrt_iob_func(0); stdin := __acrt_iob_func(0)
stdout := __acrt_iob_func(1); stdout := __acrt_iob_func(1)
stderr := __acrt_iob_func(2); stderr := __acrt_iob_func(2)
} }
// GLIBC and MUSL compatible. // GLIBC and MUSL compatible.
when ODIN_OS == "linux" { when ODIN_OS == "linux" {
fpos_t :: struct #raw_union { _: [16]char, _: longlong, _: double, }; fpos_t :: struct #raw_union { _: [16]char, _: longlong, _: double, }
_IOFBF :: 0; _IOFBF :: 0
_IOLBF :: 1; _IOLBF :: 1
_IONBF :: 2; _IONBF :: 2
BUFSIZ :: 1024; BUFSIZ :: 1024
EOF :: int(-1); EOF :: int(-1)
FOPEN_MAX :: 1000; FOPEN_MAX :: 1000
FILENAME_MAX :: 4096; FILENAME_MAX :: 4096
L_tmpnam :: 20; L_tmpnam :: 20
SEEK_SET :: 0; SEEK_SET :: 0
SEEK_CUR :: 1; SEEK_CUR :: 1
SEEK_END :: 2; SEEK_END :: 2
TMP_MAX :: 10000; TMP_MAX :: 10000
foreign libc { foreign libc {
stderr: ^FILE; stderr: ^FILE
stdin: ^FILE; stdin: ^FILE
stdout: ^FILE; stdout: ^FILE
} }
} }
@(default_calling_convention="c") @(default_calling_convention="c")
foreign libc { foreign libc {
// 7.21.4 Operations on files // 7.21.4 Operations on files
remove :: proc(filename: cstring) -> int ---; remove :: proc(filename: cstring) -> int ---
rename :: proc(old, new: cstring) -> int ---; rename :: proc(old, new: cstring) -> int ---
tmpfile :: proc() -> ^FILE ---; tmpfile :: proc() -> ^FILE ---
tmpnam :: proc(s: ^char) -> ^char ---; tmpnam :: proc(s: ^char) -> ^char ---
// 7.21.5 File access functions // 7.21.5 File access functions
fclose :: proc(stream: ^FILE) -> int ---; fclose :: proc(stream: ^FILE) -> int ---
fflush :: proc(stream: ^FILE) -> int ---; fflush :: proc(stream: ^FILE) -> int ---
fopen :: proc(filename, mode: cstring) -> ^FILE ---; fopen :: proc(filename, mode: cstring) -> ^FILE ---
freopen :: proc(filename, mode: cstring, stream: ^FILE) -> ^FILE ---; freopen :: proc(filename, mode: cstring, stream: ^FILE) -> ^FILE ---
setbuf :: proc(stream: ^FILE, buf: ^char) ---; setbuf :: proc(stream: ^FILE, buf: ^char) ---
setvbuf :: proc(stream: ^FILE, buf: ^char, mode: int, size: size_t) -> int ---; setvbuf :: proc(stream: ^FILE, buf: ^char, mode: int, size: size_t) -> int ---
// 7.21.6 Formatted input/output functions // 7.21.6 Formatted input/output functions
fprintf :: proc(stream: ^FILE, format: cstring, #c_vararg args: ..any) -> int ---; fprintf :: proc(stream: ^FILE, format: cstring, #c_vararg args: ..any) -> int ---
fscanf :: proc(stream: ^FILE, format: cstring, #c_vararg args: ..any) -> int ---; fscanf :: proc(stream: ^FILE, format: cstring, #c_vararg args: ..any) -> int ---
printf :: proc(format: cstring, #c_vararg args: ..any) -> int ---; printf :: proc(format: cstring, #c_vararg args: ..any) -> int ---
scanf :: proc(format: cstring, #c_vararg args: ..any) -> int ---; scanf :: proc(format: cstring, #c_vararg args: ..any) -> int ---
snprintf :: proc(s: ^char, format: cstring, #c_vararg args: ..any) -> int ---; snprintf :: proc(s: ^char, format: cstring, #c_vararg args: ..any) -> int ---
sscanf :: proc(s, format: cstring, #c_vararg args: ..any) -> int ---; sscanf :: proc(s, format: cstring, #c_vararg args: ..any) -> int ---
vfprintf :: proc(stream: ^FILE, format: cstring, arg: ^va_list) -> int ---; vfprintf :: proc(stream: ^FILE, format: cstring, arg: ^va_list) -> int ---
vfscanf :: proc(stream: ^FILE, format: cstring, arg: ^va_list) -> int ---; vfscanf :: proc(stream: ^FILE, format: cstring, arg: ^va_list) -> int ---
vprintf :: proc(format: cstring, arg: ^va_list) -> int ---; vprintf :: proc(format: cstring, arg: ^va_list) -> int ---
vscanf :: proc(format: cstring, arg: ^va_list) -> int ---; vscanf :: proc(format: cstring, arg: ^va_list) -> int ---
vsnprintf :: proc(s: ^char, n: size_t, format: cstring, arg: ^va_list) -> int ---; vsnprintf :: proc(s: ^char, n: size_t, format: cstring, arg: ^va_list) -> int ---
vsprintf :: proc(s: ^char, format: cstring, arg: ^va_list) -> int ---; vsprintf :: proc(s: ^char, format: cstring, arg: ^va_list) -> int ---
vsscanf :: proc(s, format: cstring, arg: ^va_list) -> int ---; vsscanf :: proc(s, format: cstring, arg: ^va_list) -> int ---
// 7.21.7 Character input/output functions // 7.21.7 Character input/output functions
fgetc :: proc(stream: ^FILE) -> int ---; fgetc :: proc(stream: ^FILE) -> int ---
fgets :: proc(s: ^char, n: int, stream: ^FILE) -> ^char ---; fgets :: proc(s: ^char, n: int, stream: ^FILE) -> ^char ---
fputc :: proc(s: cstring, stream: ^FILE) -> int ---; fputc :: proc(s: cstring, stream: ^FILE) -> int ---
getc :: proc(stream: ^FILE) -> int ---; getc :: proc(stream: ^FILE) -> int ---
getchar :: proc() -> int ---; getchar :: proc() -> int ---
putc :: proc(c: int, stream: ^FILE) -> int ---; putc :: proc(c: int, stream: ^FILE) -> int ---
putchar :: proc() -> int ---; putchar :: proc() -> int ---
puts :: proc(s: cstring) -> int ---; puts :: proc(s: cstring) -> int ---
ungetc :: proc(c: int, stream: ^FILE) -> int ---; ungetc :: proc(c: int, stream: ^FILE) -> int ---
fread :: proc(ptr: rawptr, size: size_t, stream: ^FILE) -> size_t ---; fread :: proc(ptr: rawptr, size: size_t, stream: ^FILE) -> size_t ---
fwrite :: proc(ptr: rawptr, size: size_t, nmemb: size_t, stream: ^FILE) -> size_t ---; fwrite :: proc(ptr: rawptr, size: size_t, nmemb: size_t, stream: ^FILE) -> size_t ---
// 7.21.9 File positioning functions // 7.21.9 File positioning functions
fgetpos :: proc(stream: ^FILE, pos: ^fpos_t) -> int ---; fgetpos :: proc(stream: ^FILE, pos: ^fpos_t) -> int ---
fseek :: proc(stream: ^FILE, offset: long, whence: int) -> int ---; fseek :: proc(stream: ^FILE, offset: long, whence: int) -> int ---
fsetpos :: proc(stream: ^FILE, pos: ^fpos_t) -> int ---; fsetpos :: proc(stream: ^FILE, pos: ^fpos_t) -> int ---
ftell :: proc(stream: ^FILE) -> long ---; ftell :: proc(stream: ^FILE) -> long ---
rewind :: proc(stream: ^FILE) ---; rewind :: proc(stream: ^FILE) ---
// 7.21.10 Error-handling functions // 7.21.10 Error-handling functions
clearerr :: proc(stream: ^FILE) ---; clearerr :: proc(stream: ^FILE) ---
feof :: proc(stream: ^FILE) -> int ---; feof :: proc(stream: ^FILE) -> int ---
ferror :: proc(stream: ^FILE) -> int ---; ferror :: proc(stream: ^FILE) -> int ---
perror :: proc(s: cstring) ---; perror :: proc(s: cstring) ---
} }
+46 -46
View File
@@ -9,31 +9,31 @@ when ODIN_OS == "windows" {
} }
when ODIN_OS == "windows" { when ODIN_OS == "windows" {
RAND_MAX :: 0x7fff; RAND_MAX :: 0x7fff
@(private="file") @(private="file")
@(default_calling_convention="c") @(default_calling_convention="c")
foreign libc { foreign libc {
___mb_cur_max_func :: proc() -> int ---; ___mb_cur_max_func :: proc() -> int ---
} }
MB_CUR_MAX :: #force_inline proc() -> size_t { MB_CUR_MAX :: #force_inline proc() -> size_t {
return size_t(___mb_cur_max_func()); return size_t(___mb_cur_max_func())
} }
} }
when ODIN_OS == "linux" { when ODIN_OS == "linux" {
RAND_MAX :: 0x7fffffff; RAND_MAX :: 0x7fffffff
// GLIBC and MUSL only // GLIBC and MUSL only
@(private="file") @(private="file")
@(default_calling_convention="c") @(default_calling_convention="c")
foreign libc { foreign libc {
__ctype_get_mb_cur_max :: proc() -> size_t ---; __ctype_get_mb_cur_max :: proc() -> size_t ---
} }
MB_CUR_MAX :: #force_inline proc() -> size_t { MB_CUR_MAX :: #force_inline proc() -> size_t {
return __ctype_get_mb_cur_max(); return __ctype_get_mb_cur_max()
} }
} }
@@ -41,8 +41,8 @@ when ODIN_OS == "linux" {
// to use any two distinct values it wants to indicate success or failure. // to use any two distinct values it wants to indicate success or failure.
// However, nobody actually does and everyone appears to have agreed upon these // However, nobody actually does and everyone appears to have agreed upon these
// values. // values.
EXIT_SUCCESS :: 0; EXIT_SUCCESS :: 0
EXIT_FAILURE :: 1; EXIT_FAILURE :: 1
// C does not declare which order 'quot' and 'rem' should be for the divide // C does not declare which order 'quot' and 'rem' should be for the divide
// structures. An implementation could put 'rem' first. However, nobody actually // structures. An implementation could put 'rem' first. However, nobody actually
@@ -54,56 +54,56 @@ lldiv_t :: struct { quot, rem: longlong, }
@(default_calling_convention="c") @(default_calling_convention="c")
foreign libc { foreign libc {
// 7.22.1 Numeric conversion functions // 7.22.1 Numeric conversion functions
atof :: proc(nptr: cstring) -> double ---; atof :: proc(nptr: cstring) -> double ---
atoi :: proc(nptr: cstring) -> int ---; atoi :: proc(nptr: cstring) -> int ---
atol :: proc(nptr: cstring) -> long ---; atol :: proc(nptr: cstring) -> long ---
atoll :: proc(nptr: cstring) -> longlong ---; atoll :: proc(nptr: cstring) -> longlong ---
strtod :: proc(nptr: cstring, endptr: ^^char) -> double ---; strtod :: proc(nptr: cstring, endptr: ^^char) -> double ---
strtof :: proc(nptr: cstring, endptr: ^^char) -> float ---; strtof :: proc(nptr: cstring, endptr: ^^char) -> float ---
strtol :: proc(nptr: cstring, endptr: ^^char, base: int) -> long ---; strtol :: proc(nptr: cstring, endptr: ^^char, base: int) -> long ---
strtoll :: proc(nptr: cstring, endptr: ^^char, base: int) -> longlong ---; strtoll :: proc(nptr: cstring, endptr: ^^char, base: int) -> longlong ---
strtoul :: proc(nptr: cstring, endptr: ^^char, base: int) -> ulong ---; strtoul :: proc(nptr: cstring, endptr: ^^char, base: int) -> ulong ---
strtoull :: proc(nptr: cstring, endptr: ^^char, base: int) -> ulonglong ---; strtoull :: proc(nptr: cstring, endptr: ^^char, base: int) -> ulonglong ---
// 7.22.2 Pseudo-random sequence generation functions // 7.22.2 Pseudo-random sequence generation functions
rand :: proc() -> int ---; rand :: proc() -> int ---
srand :: proc(seed: uint) ---; srand :: proc(seed: uint) ---
// 7.22.3 Memory management functions // 7.22.3 Memory management functions
aligned_alloc :: proc(aligment, size: size_t) -> rawptr ---; aligned_alloc :: proc(aligment, size: size_t) -> rawptr ---
calloc :: proc(nmemb, size: size_t) -> rawptr ---; calloc :: proc(nmemb, size: size_t) -> rawptr ---
free :: proc(ptr: rawptr) ---; free :: proc(ptr: rawptr) ---
malloc :: proc(size: size_t) -> rawptr ---; malloc :: proc(size: size_t) -> rawptr ---
realloc :: proc(ptr: rawptr, size: size_t) -> rawptr ---; realloc :: proc(ptr: rawptr, size: size_t) -> rawptr ---
// 7.22.4 Communication with the environment // 7.22.4 Communication with the environment
abort :: proc() -> ! ---; abort :: proc() -> ! ---
atexit :: proc(func: proc "c" ()) -> int ---; atexit :: proc(func: proc "c" ()) -> int ---
at_quick_exit :: proc(func: proc "c" ()) -> int ---; at_quick_exit :: proc(func: proc "c" ()) -> int ---
exit :: proc(status: int) -> ! ---; exit :: proc(status: int) -> ! ---
_Exit :: proc(status: int) -> ! ---; _Exit :: proc(status: int) -> ! ---
getenv :: proc(name: cstring) -> ^char ---; getenv :: proc(name: cstring) -> ^char ---
quick_exit :: proc(status: int) -> ! ---; quick_exit :: proc(status: int) -> ! ---
system :: proc(cmd: cstring) -> int ---; system :: proc(cmd: cstring) -> int ---
// 7.22.5 Searching and sorting utilities // 7.22.5 Searching and sorting utilities
bsearch :: proc(key, base: rawptr, nmemb, size: size_t, compar: proc "c" (lhs, rhs: rawptr) -> int) -> rawptr ---; bsearch :: proc(key, base: rawptr, nmemb, size: size_t, compar: proc "c" (lhs, rhs: rawptr) -> int) -> rawptr ---
qsort :: proc(base: rawptr, nmemb, size: size_t, compar: proc "c" (lhs, rhs: rawptr) -> int) ---; qsort :: proc(base: rawptr, nmemb, size: size_t, compar: proc "c" (lhs, rhs: rawptr) -> int) ---
// 7.22.6 Integer arithmetic functions // 7.22.6 Integer arithmetic functions
abs :: proc(j: int) -> int ---; abs :: proc(j: int) -> int ---
labs :: proc(j: long) -> long ---; labs :: proc(j: long) -> long ---
llabs :: proc(j: longlong) -> longlong ---; llabs :: proc(j: longlong) -> longlong ---
div :: proc(numer, denom: int) -> div_t ---; div :: proc(numer, denom: int) -> div_t ---
ldiv :: proc(numer, denom: long) -> ldiv_t ---; ldiv :: proc(numer, denom: long) -> ldiv_t ---
lldiv :: proc(numer, denom: longlong) -> lldiv_t ---; lldiv :: proc(numer, denom: longlong) -> lldiv_t ---
// 7.22.7 Multibyte/wide character conversion functions // 7.22.7 Multibyte/wide character conversion functions
mblen :: proc(s: cstring, n: size_t) -> int ---; mblen :: proc(s: cstring, n: size_t) -> int ---
mbtowc :: proc(pwc: ^wchar_t, s: cstring, n: size_t) -> int ---; mbtowc :: proc(pwc: ^wchar_t, s: cstring, n: size_t) -> int ---
wctomb :: proc(s: ^char, wc: wchar_t) -> int ---; wctomb :: proc(s: ^char, wc: wchar_t) -> int ---
// 7.22.8 Multibyte/wide string conversion functions // 7.22.8 Multibyte/wide string conversion functions
mbstowcs :: proc(pwcs: ^wchar_t, s: cstring, n: size_t) -> size_t ---; mbstowcs :: proc(pwcs: ^wchar_t, s: cstring, n: size_t) -> size_t ---
wcstombs :: proc(s: ^char, pwcs: ^wchar_t, n: size_t) -> size_t ---; wcstombs :: proc(s: ^char, pwcs: ^wchar_t, n: size_t) -> size_t ---
} }
+21 -21
View File
@@ -11,33 +11,33 @@ when ODIN_OS == "windows" {
foreign libc { foreign libc {
// 7.24.2 Copying functions // 7.24.2 Copying functions
memcpy :: proc(s1, s2: rawptr, n: size_t) -> rawptr ---; memcpy :: proc(s1, s2: rawptr, n: size_t) -> rawptr ---
memmove :: proc(s1, s2: rawptr, n: size_t) -> rawptr ---; memmove :: proc(s1, s2: rawptr, n: size_t) -> rawptr ---
strcpy :: proc(s1: ^char, s2: cstring) -> ^char ---; strcpy :: proc(s1: ^char, s2: cstring) -> ^char ---
strncpy :: proc(s1: ^char, s2: cstring, n: size_t) -> ^char ---; strncpy :: proc(s1: ^char, s2: cstring, n: size_t) -> ^char ---
// 7.24.3 Concatenation functions // 7.24.3 Concatenation functions
strcat :: proc(s1: ^char, s2: cstring) -> ^char ---; strcat :: proc(s1: ^char, s2: cstring) -> ^char ---
strncat :: proc(s1: ^char, s2: cstring, n: size_t) -> ^char ---; strncat :: proc(s1: ^char, s2: cstring, n: size_t) -> ^char ---
// 7.24.4 Comparison functions // 7.24.4 Comparison functions
memcmp :: proc(s1, s2: rawptr, n: size_t) -> int ---; memcmp :: proc(s1, s2: rawptr, n: size_t) -> int ---
strcmp :: proc(s1, s2: cstring) -> int ---; strcmp :: proc(s1, s2: cstring) -> int ---
strcoll :: proc(s1, s2: cstring) -> int ---; strcoll :: proc(s1, s2: cstring) -> int ---
strncmp :: proc(s1, s2: cstring, n: size_t) -> int ---; strncmp :: proc(s1, s2: cstring, n: size_t) -> int ---
strxfrm :: proc(s1: ^char, s2: cstring, n: size_t) -> size_t ---; strxfrm :: proc(s1: ^char, s2: cstring, n: size_t) -> size_t ---
// 7.24.5 Search functions // 7.24.5 Search functions
memchr :: proc(s: rawptr, c: int, n: size_t) -> rawptr ---; memchr :: proc(s: rawptr, c: int, n: size_t) -> rawptr ---
strchr :: proc(s: cstring, c: int) -> ^char ---; strchr :: proc(s: cstring, c: int) -> ^char ---
strcspn :: proc(s1, s2: cstring) -> size_t ---; strcspn :: proc(s1, s2: cstring) -> size_t ---
strpbrk :: proc(s1, s2: cstring) -> ^char ---; strpbrk :: proc(s1, s2: cstring) -> ^char ---
strrchr :: proc(s: ^char, c: int) -> ^char ---; strrchr :: proc(s: ^char, c: int) -> ^char ---
strcpn :: proc(s1, s2: cstring) -> ^char ---; strcpn :: proc(s1, s2: cstring) -> ^char ---
strtok :: proc(s1: ^char, s2: cstring) -> ^char ---; strtok :: proc(s1: ^char, s2: cstring) -> ^char ---
// 7.24.6 Miscellaneous functions // 7.24.6 Miscellaneous functions
memset :: proc(s: rawptr, c: int, n: size_t) -> rawptr ---; memset :: proc(s: rawptr, c: int, n: size_t) -> rawptr ---
strerror :: proc(errnum: int) -> ^char ---; strerror :: proc(errnum: int) -> ^char ---
strlen :: proc(s: cstring) -> size_t ---; strlen :: proc(s: cstring) -> size_t ---
} }
+79 -79
View File
@@ -2,8 +2,8 @@ package libc
// 7.26 Threads // 7.26 Threads
thrd_start_t :: proc "c" (rawptr) -> int; thrd_start_t :: proc "c" (rawptr) -> int
tss_dtor_t :: proc "c" (rawptr); tss_dtor_t :: proc "c" (rawptr)
when ODIN_OS == "windows" { when ODIN_OS == "windows" {
foreign import libc { foreign import libc {
@@ -11,23 +11,23 @@ when ODIN_OS == "windows" {
"system:msvcprt.lib" "system:msvcprt.lib"
} }
thrd_success :: 0; // _Thrd_success thrd_success :: 0 // _Thrd_success
thrd_nomem :: 1; // _Thrd_nomem thrd_nomem :: 1 // _Thrd_nomem
thrd_timedout :: 2; // _Thrd_timedout thrd_timedout :: 2 // _Thrd_timedout
thrd_busy :: 3; // _Thrd_busy thrd_busy :: 3 // _Thrd_busy
thrd_error :: 4; // _Thrd_error thrd_error :: 4 // _Thrd_error
mtx_plain :: 1; // _Mtx_plain mtx_plain :: 1 // _Mtx_plain
mtx_recursive :: 0x100; // _Mtx_recursive mtx_recursive :: 0x100 // _Mtx_recursive
mtx_timed :: 4; // _Mtx_timed mtx_timed :: 4 // _Mtx_timed
TSS_DTOR_ITERATIONS :: 4; // _TSS_DTOR_ITERATIONS_IMP TSS_DTOR_ITERATIONS :: 4 // _TSS_DTOR_ITERATIONS_IMP
once_flag :: distinct i8; // _Once_flag_imp_t once_flag :: distinct i8 // _Once_flag_imp_t
thrd_t :: struct { _: rawptr, _: uint, } // _Thrd_t thrd_t :: struct { _: rawptr, _: uint, } // _Thrd_t
tss_t :: distinct int; // _Tss_imp_t tss_t :: distinct int // _Tss_imp_t
cnd_t :: distinct rawptr; // _Cnd_imp_t cnd_t :: distinct rawptr // _Cnd_imp_t
mtx_t :: distinct rawptr; // _Mtx_imp_t mtx_t :: distinct rawptr // _Mtx_imp_t
// MSVCRT does not expose the C11 symbol names as what they are in C11 // MSVCRT does not expose the C11 symbol names as what they are in C11
// because they held off implementing <threads.h> and C11 support for so // because they held off implementing <threads.h> and C11 support for so
@@ -38,38 +38,38 @@ when ODIN_OS == "windows" {
@(default_calling_convention="c") @(default_calling_convention="c")
foreign libc { foreign libc {
// 7.26.2 Initialization functions // 7.26.2 Initialization functions
@(link_name="_Call_once") call_once :: proc(flag: ^once_flag, func: proc "c" ()) ---; @(link_name="_Call_once") call_once :: proc(flag: ^once_flag, func: proc "c" ()) ---
// 7.26.3 Condition variable functions // 7.26.3 Condition variable functions
@(link_name="_Cnd_broadcast") cnd_broadcast :: proc(cond: ^cnd_t) -> int ---; @(link_name="_Cnd_broadcast") cnd_broadcast :: proc(cond: ^cnd_t) -> int ---
@(link_name="_Cnd_destroy") cnd_destroy :: proc(cond: ^cnd_t) ---; @(link_name="_Cnd_destroy") cnd_destroy :: proc(cond: ^cnd_t) ---
@(link_name="_Cnd_init") cnd_init :: proc(cond: ^cnd_t) -> int ---; @(link_name="_Cnd_init") cnd_init :: proc(cond: ^cnd_t) -> int ---
@(link_name="_Cnd_signal") cnd_signal :: proc(cond: ^cnd_t) -> int ---; @(link_name="_Cnd_signal") cnd_signal :: proc(cond: ^cnd_t) -> int ---
@(link_name="_Cnd_timedwait") cnd_timedwait :: proc(cond: ^cnd_t, ts: ^timespec) -> int ---; @(link_name="_Cnd_timedwait") cnd_timedwait :: proc(cond: ^cnd_t, ts: ^timespec) -> int ---
@(link_name="_Cnd_wait") cnd_wait :: proc(cond: ^cnd_t, mtx: ^mtx_t) -> int ---; @(link_name="_Cnd_wait") cnd_wait :: proc(cond: ^cnd_t, mtx: ^mtx_t) -> int ---
// 7.26.4 Mutex functions // 7.26.4 Mutex functions
@(link_name="_Mtx_destroy") mtx_destroy :: proc(mtx: ^mtx_t) ---; @(link_name="_Mtx_destroy") mtx_destroy :: proc(mtx: ^mtx_t) ---
@(link_name="_Mtx_init") mtx_init :: proc(mtx: ^mtx_t, type: int) -> int ---; @(link_name="_Mtx_init") mtx_init :: proc(mtx: ^mtx_t, type: int) -> int ---
@(link_name="_Mtx_lock") mtx_lock :: proc(mtx: ^mtx_t) -> int ---; @(link_name="_Mtx_lock") mtx_lock :: proc(mtx: ^mtx_t) -> int ---
@(link_name="_Mtx_timedlock") mtx_timedlock :: proc(mtx: ^mtx_t, ts: ^timespec) -> int ---; @(link_name="_Mtx_timedlock") mtx_timedlock :: proc(mtx: ^mtx_t, ts: ^timespec) -> int ---
@(link_name="_Mtx_trylock") mtx_trylock :: proc(mtx: ^mtx_t) -> int ---; @(link_name="_Mtx_trylock") mtx_trylock :: proc(mtx: ^mtx_t) -> int ---
@(link_name="_Mtx_unlock") mtx_unlock :: proc(mtx: ^mtx_t) -> int ---; @(link_name="_Mtx_unlock") mtx_unlock :: proc(mtx: ^mtx_t) -> int ---
// 7.26.5 Thread functions // 7.26.5 Thread functions
@(link_name="_Thrd_create") thrd_create :: proc(thr: ^thrd_t, func: thrd_start_t, arg: rawptr) -> int ---; @(link_name="_Thrd_create") thrd_create :: proc(thr: ^thrd_t, func: thrd_start_t, arg: rawptr) -> int ---
@(link_name="_Thrd_current") thrd_current :: proc() -> thrd_t ---; @(link_name="_Thrd_current") thrd_current :: proc() -> thrd_t ---
@(link_name="_Thrd_detach") thrd_detach :: proc(thr: thrd_t) -> int ---; @(link_name="_Thrd_detach") thrd_detach :: proc(thr: thrd_t) -> int ---
@(link_name="_Thrd_equal") thrd_equal :: proc(lhs, rhs: thrd_t) -> int ---; @(link_name="_Thrd_equal") thrd_equal :: proc(lhs, rhs: thrd_t) -> int ---
@(link_name="_Thrd_exit") thrd_exit :: proc(res: int) -> ! ---; @(link_name="_Thrd_exit") thrd_exit :: proc(res: int) -> ! ---
@(link_name="_Thrd_join") thrd_join :: proc(thr: thrd_t, res: ^int) -> int ---; @(link_name="_Thrd_join") thrd_join :: proc(thr: thrd_t, res: ^int) -> int ---
@(link_name="_Thrd_sleep") thrd_sleep :: proc(duration, remaining: ^timespec) -> int ---; @(link_name="_Thrd_sleep") thrd_sleep :: proc(duration, remaining: ^timespec) -> int ---
@(link_name="_Thrd_yield") thrd_yield :: proc() ---; @(link_name="_Thrd_yield") thrd_yield :: proc() ---
// 7.26.6 Thread-specific storage functions // 7.26.6 Thread-specific storage functions
@(link_name="_Tss_create") tss_create :: proc(key: ^tss_t, dtor: tss_dtor_t) -> int ---; @(link_name="_Tss_create") tss_create :: proc(key: ^tss_t, dtor: tss_dtor_t) -> int ---
@(link_name="_Tss_delete") tss_delete :: proc(key: tss_t) ---; @(link_name="_Tss_delete") tss_delete :: proc(key: tss_t) ---
@(link_name="_Tss_get") tss_get :: proc(key: tss_t) -> rawptr ---; @(link_name="_Tss_get") tss_get :: proc(key: tss_t) -> rawptr ---
@(link_name="_Tss_set") tss_set :: proc(key: tss_t, val: rawptr) -> int ---; @(link_name="_Tss_set") tss_set :: proc(key: tss_t, val: rawptr) -> int ---
} }
} }
@@ -80,59 +80,59 @@ when ODIN_OS == "linux" {
"system:pthread" "system:pthread"
} }
thrd_success :: 0; thrd_success :: 0
thrd_busy :: 1; thrd_busy :: 1
thrd_error :: 2; thrd_error :: 2
thrd_nomem :: 3; thrd_nomem :: 3
thrd_timedout :: 4; thrd_timedout :: 4
mtx_plain :: 0; mtx_plain :: 0
mtx_recursive :: 1; mtx_recursive :: 1
mtx_timed :: 2; mtx_timed :: 2
TSS_DTOR_ITERATIONS :: 4; TSS_DTOR_ITERATIONS :: 4
once_flag :: distinct int; once_flag :: distinct int
thrd_t :: distinct ulong; thrd_t :: distinct ulong
tss_t :: distinct uint; tss_t :: distinct uint
cnd_t :: struct #raw_union { _: [12]int, _: [12 * size_of(int) / size_of(rawptr)]rawptr, }; cnd_t :: struct #raw_union { _: [12]int, _: [12 * size_of(int) / size_of(rawptr)]rawptr, }
mtx_t :: struct #raw_union { _: [10 when size_of(long) == 8 else 6]int, _: [5 when size_of(long) == 8 else 6]rawptr, }; mtx_t :: struct #raw_union { _: [10 when size_of(long) == 8 else 6]int, _: [5 when size_of(long) == 8 else 6]rawptr, }
@(default_calling_convention="c") @(default_calling_convention="c")
foreign libc { foreign libc {
// 7.26.2 Initialization functions // 7.26.2 Initialization functions
call_once :: proc(flag: ^once_flag, func: proc "c" ()) ---; call_once :: proc(flag: ^once_flag, func: proc "c" ()) ---
// 7.26.3 Condition variable functions // 7.26.3 Condition variable functions
cnd_broadcast :: proc(cond: ^cnd_t) -> int ---; cnd_broadcast :: proc(cond: ^cnd_t) -> int ---
cnd_destroy :: proc(cond: ^cnd_t) ---; cnd_destroy :: proc(cond: ^cnd_t) ---
cnd_init :: proc(cond: ^cnd_t) -> int ---; cnd_init :: proc(cond: ^cnd_t) -> int ---
cnd_signal :: proc(cond: ^cnd_t) -> int ---; cnd_signal :: proc(cond: ^cnd_t) -> int ---
cnd_timedwait :: proc(cond: ^cnd_t, ts: ^timespec) -> int ---; cnd_timedwait :: proc(cond: ^cnd_t, ts: ^timespec) -> int ---
cnd_wait :: proc(cond: ^cnd_t, mtx: ^mtx_t) -> int ---; cnd_wait :: proc(cond: ^cnd_t, mtx: ^mtx_t) -> int ---
// 7.26.4 Mutex functions // 7.26.4 Mutex functions
mtx_destroy :: proc(mtx: ^mtx_t) ---; mtx_destroy :: proc(mtx: ^mtx_t) ---
mtx_init :: proc(mtx: ^mtx_t, type: int) -> int ---; mtx_init :: proc(mtx: ^mtx_t, type: int) -> int ---
mtx_lock :: proc(mtx: ^mtx_t) -> int ---; mtx_lock :: proc(mtx: ^mtx_t) -> int ---
mtx_timedlock :: proc(mtx: ^mtx_t, ts: ^timespec) -> int ---; mtx_timedlock :: proc(mtx: ^mtx_t, ts: ^timespec) -> int ---
mtx_trylock :: proc(mtx: ^mtx_t) -> int ---; mtx_trylock :: proc(mtx: ^mtx_t) -> int ---
mtx_unlock :: proc(mtx: ^mtx_t) -> int ---; mtx_unlock :: proc(mtx: ^mtx_t) -> int ---
// 7.26.5 Thread functions // 7.26.5 Thread functions
thrd_create :: proc(thr: ^thrd_t, func: thrd_start_t, arg: rawptr) -> int ---; thrd_create :: proc(thr: ^thrd_t, func: thrd_start_t, arg: rawptr) -> int ---
thrd_current :: proc() -> thrd_t ---; thrd_current :: proc() -> thrd_t ---
thrd_detach :: proc(thr: thrd_t) -> int ---; thrd_detach :: proc(thr: thrd_t) -> int ---
thrd_equal :: proc(lhs, rhs: thrd_t) -> int ---; thrd_equal :: proc(lhs, rhs: thrd_t) -> int ---
thrd_exit :: proc(res: int) -> ! ---; thrd_exit :: proc(res: int) -> ! ---
thrd_join :: proc(thr: thrd_t, res: ^int) -> int ---; thrd_join :: proc(thr: thrd_t, res: ^int) -> int ---
thrd_sleep :: proc(duration, remaining: ^timespec) -> int ---; thrd_sleep :: proc(duration, remaining: ^timespec) -> int ---
thrd_yield :: proc() ---; thrd_yield :: proc() ---
// 7.26.6 Thread-specific storage functions // 7.26.6 Thread-specific storage functions
tss_create :: proc(key: ^tss_t, dtor: tss_dtor_t) -> int ---; tss_create :: proc(key: ^tss_t, dtor: tss_dtor_t) -> int ---
tss_delete :: proc(key: tss_t) ---; tss_delete :: proc(key: tss_t) ---
tss_get :: proc(key: tss_t) -> rawptr ---; tss_get :: proc(key: tss_t) -> rawptr ---
tss_set :: proc(key: tss_t, val: rawptr) -> int ---; tss_set :: proc(key: tss_t, val: rawptr) -> int ---
} }
} }
+28 -28
View File
@@ -13,25 +13,25 @@ when ODIN_OS == "windows" {
when ODIN_OS == "windows" { when ODIN_OS == "windows" {
foreign libc { foreign libc {
// 7.27.2 Time manipulation functions // 7.27.2 Time manipulation functions
clock :: proc() -> clock_t ---; clock :: proc() -> clock_t ---
@(link_name="_difftime64") difftime :: proc(time1, time2: time_t) -> double ---; @(link_name="_difftime64") difftime :: proc(time1, time2: time_t) -> double ---
mktime :: proc(timeptr: ^tm) -> time_t ---; mktime :: proc(timeptr: ^tm) -> time_t ---
@(link_name="_time64") time :: proc(timer: ^time_t) -> time_t ---; @(link_name="_time64") time :: proc(timer: ^time_t) -> time_t ---
@(link_name="_timespec64_get") timespec_get :: proc(ts: ^timespec, base: int) -> int ---; @(link_name="_timespec64_get") timespec_get :: proc(ts: ^timespec, base: int) -> int ---
// 7.27.3 Time conversion functions // 7.27.3 Time conversion functions
asctime :: proc(timeptr: ^tm) -> ^char ---; asctime :: proc(timeptr: ^tm) -> ^char ---
@(link_name="_ctime64") ctime :: proc(timer: ^time_t) -> ^char ---; @(link_name="_ctime64") ctime :: proc(timer: ^time_t) -> ^char ---
@(link_name="_gmtime64") gmtime :: proc(timer: ^time_t) -> ^tm ---; @(link_name="_gmtime64") gmtime :: proc(timer: ^time_t) -> ^tm ---
@(link_name="_localtime64") localtime :: proc(timer: ^time_t) -> ^tm ---; @(link_name="_localtime64") localtime :: proc(timer: ^time_t) -> ^tm ---
strftime :: proc(s: ^char, maxsize: size_t, format: cstring, timeptr: ^tm) -> size_t ---; strftime :: proc(s: ^char, maxsize: size_t, format: cstring, timeptr: ^tm) -> size_t ---
} }
CLOCKS_PER_SEC :: 1000; CLOCKS_PER_SEC :: 1000
TIME_UTC :: 1; TIME_UTC :: 1
clock_t :: distinct long; clock_t :: distinct long
time_t :: distinct i64; time_t :: distinct i64
timespec :: struct #align 8 { timespec :: struct #align 8 {
tv_sec: time_t, tv_sec: time_t,
@@ -47,26 +47,26 @@ when ODIN_OS == "linux" || ODIN_OS == "freebsd" {
@(default_calling_convention="c") @(default_calling_convention="c")
foreign libc { foreign libc {
// 7.27.2 Time manipulation functions // 7.27.2 Time manipulation functions
clock :: proc() -> clock_t ---; clock :: proc() -> clock_t ---
difftime :: proc(time1, time2: time_t) -> double ---; difftime :: proc(time1, time2: time_t) -> double ---
mktime :: proc(timeptr: ^tm) -> time_t ---; mktime :: proc(timeptr: ^tm) -> time_t ---
time :: proc(timer: ^time_t) -> time_t ---; time :: proc(timer: ^time_t) -> time_t ---
timespec_get :: proc(ts: ^timespec, base: int) -> int ---; timespec_get :: proc(ts: ^timespec, base: int) -> int ---
// 7.27.3 Time conversion functions // 7.27.3 Time conversion functions
asctime :: proc(timeptr: ^tm) -> ^char ---; asctime :: proc(timeptr: ^tm) -> ^char ---
ctime :: proc(timer: ^time_t) -> ^char ---; ctime :: proc(timer: ^time_t) -> ^char ---
gmtime :: proc(timer: ^time_t) -> ^tm ---; gmtime :: proc(timer: ^time_t) -> ^tm ---
localtime :: proc(timer: ^time_t) -> ^tm ---; localtime :: proc(timer: ^time_t) -> ^tm ---
strftime :: proc(s: ^char, maxsize: size_t, format: cstring, timeptr: ^tm) -> size_t ---; strftime :: proc(s: ^char, maxsize: size_t, format: cstring, timeptr: ^tm) -> size_t ---
} }
CLOCKS_PER_SEC :: 1000000; CLOCKS_PER_SEC :: 1000000
TIME_UTC :: 1; TIME_UTC :: 1
time_t :: distinct i64; time_t :: distinct i64
clock_t :: long; clock_t :: long
timespec :: struct { timespec :: struct {
tv_sec: time_t, tv_sec: time_t,
+58 -58
View File
@@ -2,81 +2,81 @@ package libc
import builtin "core:builtin" import builtin "core:builtin"
char :: builtin.u8; // assuming -funsigned-char char :: builtin.u8 // assuming -funsigned-char
short :: builtin.i16; short :: builtin.i16
int :: builtin.i32; int :: builtin.i32
long :: builtin.i32 when (ODIN_OS == "windows" || size_of(builtin.rawptr) == 4) else builtin.i64; long :: builtin.i32 when (ODIN_OS == "windows" || size_of(builtin.rawptr) == 4) else builtin.i64
longlong :: builtin.i64; longlong :: builtin.i64
uchar :: builtin.u8; uchar :: builtin.u8
ushort :: builtin.u16; ushort :: builtin.u16
uint :: builtin.u32; uint :: builtin.u32
ulong :: builtin.u32 when (ODIN_OS == "windows" || size_of(builtin.rawptr) == 4) else builtin.u64; ulong :: builtin.u32 when (ODIN_OS == "windows" || size_of(builtin.rawptr) == 4) else builtin.u64
ulonglong :: builtin.u64; ulonglong :: builtin.u64
bool :: distinct builtin.b8; bool :: distinct builtin.b8
size_t :: builtin.uint; size_t :: builtin.uint
wchar_t :: builtin.u16 when (ODIN_OS == "windows") else builtin.u32; wchar_t :: builtin.u16 when (ODIN_OS == "windows") else builtin.u32
float :: builtin.f32; float :: builtin.f32
double :: builtin.f64; double :: builtin.f64
// 7.20.1 Integer types // 7.20.1 Integer types
int8_t :: builtin.i8; int8_t :: builtin.i8
uint8_t :: builtin.u8; uint8_t :: builtin.u8
int16_t :: builtin.i16; int16_t :: builtin.i16
uint16_t :: builtin.u16; uint16_t :: builtin.u16
int32_t :: builtin.i32; int32_t :: builtin.i32
uint32_t :: builtin.u32; uint32_t :: builtin.u32
int64_t :: builtin.i64; int64_t :: builtin.i64
uint64_t :: builtin.u64; uint64_t :: builtin.u64
// These are all the same in multiple libc's for multiple architectures. // These are all the same in multiple libc's for multiple architectures.
int_least8_t :: builtin.i8; int_least8_t :: builtin.i8
uint_least8_t :: builtin.u8; uint_least8_t :: builtin.u8
int_least16_t :: builtin.i16; int_least16_t :: builtin.i16
uint_least16_t :: builtin.u16; uint_least16_t :: builtin.u16
int_least32_t :: builtin.i32; int_least32_t :: builtin.i32
uint_least32_t :: builtin.u32; uint_least32_t :: builtin.u32
int_least64_t :: builtin.i64; int_least64_t :: builtin.i64
uint_least64_t :: builtin.u64; uint_least64_t :: builtin.u64
// Same on Windows, Linux, and FreeBSD // Same on Windows, Linux, and FreeBSD
when ODIN_ARCH == "386" || ODIN_ARCH == "amd64" { when ODIN_ARCH == "386" || ODIN_ARCH == "amd64" {
int_fast8_t :: builtin.i8; int_fast8_t :: builtin.i8
uint_fast8_t :: builtin.u8; uint_fast8_t :: builtin.u8
int_fast16_t :: builtin.i32; int_fast16_t :: builtin.i32
uint_fast16_t :: builtin.u32; uint_fast16_t :: builtin.u32
int_fast32_t :: builtin.i32; int_fast32_t :: builtin.i32
uint_fast32_t :: builtin.u32; uint_fast32_t :: builtin.u32
int_fast64_t :: builtin.i64; int_fast64_t :: builtin.i64
uint_fast64_t :: builtin.u64; uint_fast64_t :: builtin.u64
} }
intptr_t :: builtin.int; intptr_t :: builtin.int
uintptr_t :: builtin.uintptr; uintptr_t :: builtin.uintptr
ptrdiff_t :: distinct intptr_t; ptrdiff_t :: distinct intptr_t
intmax_t :: builtin.i64; intmax_t :: builtin.i64
uintmax_t :: builtin.u64; uintmax_t :: builtin.u64
// Copy C's rules for type promotion here by forcing the type on the literals. // Copy C's rules for type promotion here by forcing the type on the literals.
INT8_MAX :: int(0x7f); INT8_MAX :: int(0x7f)
INT16_MAX :: int(0x7fff); INT16_MAX :: int(0x7fff)
INT32_MAX :: int(0x7fffffff); INT32_MAX :: int(0x7fffffff)
INT64_MAX :: longlong(0x7fffffffffffffff); INT64_MAX :: longlong(0x7fffffffffffffff)
UINT8_MAX :: int(0xff); UINT8_MAX :: int(0xff)
UINT16_MAX :: int(0xffff); UINT16_MAX :: int(0xffff)
UINT32_MAX :: uint(0xffffffff); UINT32_MAX :: uint(0xffffffff)
UINT64_MAX :: ulonglong(0xffffffffffffffff); UINT64_MAX :: ulonglong(0xffffffffffffffff)
INT8_MIN :: ~INT8_MAX; INT8_MIN :: ~INT8_MAX
INT16_MIN :: ~INT16_MAX; INT16_MIN :: ~INT16_MAX
INT32_MIN :: ~INT32_MAX; INT32_MIN :: ~INT32_MAX
INT64_MIN :: ~INT64_MAX; INT64_MIN :: ~INT64_MAX
NULL :: rawptr(uintptr(0)); NULL :: rawptr(uintptr(0))
NDEBUG :: !ODIN_DEBUG; NDEBUG :: !ODIN_DEBUG
+6 -6
View File
@@ -11,11 +11,11 @@ when ODIN_OS == "windows" {
@(default_calling_convention="c") @(default_calling_convention="c")
foreign libc { foreign libc {
// 7.28.1 Restartable multibyte/wide character conversion functions // 7.28.1 Restartable multibyte/wide character conversion functions
mbrtoc16 :: proc(pc16: ^char16_t, s: cstring, n: size_t, ps: ^mbstate_t) -> size_t ---; mbrtoc16 :: proc(pc16: ^char16_t, s: cstring, n: size_t, ps: ^mbstate_t) -> size_t ---
c16rtomb :: proc(s: ^char, c16: char16_t, ps: ^mbstate_t) -> size_t ---; c16rtomb :: proc(s: ^char, c16: char16_t, ps: ^mbstate_t) -> size_t ---
mbrtoc32 :: proc(pc32: ^char32_t, s: cstring, n: size_t, ps: ^mbstate_t) -> size_t ---; mbrtoc32 :: proc(pc32: ^char32_t, s: cstring, n: size_t, ps: ^mbstate_t) -> size_t ---
c32rtomb :: proc(s: ^char, c32: char32_t, ps: ^mbstate_t) -> size_t ---; c32rtomb :: proc(s: ^char, c32: char32_t, ps: ^mbstate_t) -> size_t ---
} }
char16_t :: uint_least16_t; char16_t :: uint_least16_t
char32_t :: uint_least32_t; char32_t :: uint_least32_t
+62 -62
View File
@@ -11,88 +11,88 @@ when ODIN_OS == "windows" {
@(default_calling_convention="c") @(default_calling_convention="c")
foreign libc { foreign libc {
// 7.29.2 Formatted wide character input/output functions // 7.29.2 Formatted wide character input/output functions
fwprintf :: proc(stream: ^FILE, format: ^wchar_t, #c_vararg arg: ..any) -> int ---; fwprintf :: proc(stream: ^FILE, format: ^wchar_t, #c_vararg arg: ..any) -> int ---
fwscanf :: proc(stream: ^FILE, format: ^wchar_t, #c_vararg arg: ..any) -> int ---; fwscanf :: proc(stream: ^FILE, format: ^wchar_t, #c_vararg arg: ..any) -> int ---
swprintf :: proc(stream: ^FILE, n: size_t, format: ^wchar_t, #c_vararg arg: ..any) -> int ---; swprintf :: proc(stream: ^FILE, n: size_t, format: ^wchar_t, #c_vararg arg: ..any) -> int ---
swscanf :: proc(s, format: ^wchar_t, #c_vararg arg: ..any) -> int ---; swscanf :: proc(s, format: ^wchar_t, #c_vararg arg: ..any) -> int ---
vfwprintf :: proc(stream: ^FILE, format: ^wchar_t, arg: va_list) -> int ---; vfwprintf :: proc(stream: ^FILE, format: ^wchar_t, arg: va_list) -> int ---
vfwscanf :: proc(stream: ^FILE, format: ^wchar_t, arg: va_list) -> int ---; vfwscanf :: proc(stream: ^FILE, format: ^wchar_t, arg: va_list) -> int ---
vswprintf :: proc(s: ^wchar_t, n: size_t, format: ^wchar_t, arg: va_list) -> int ---; vswprintf :: proc(s: ^wchar_t, n: size_t, format: ^wchar_t, arg: va_list) -> int ---
vswscanf :: proc(s, format: ^wchar_t, arg: va_list) -> int ---; vswscanf :: proc(s, format: ^wchar_t, arg: va_list) -> int ---
vwprintf :: proc(format: ^wchar_t, arg: va_list) -> int ---; vwprintf :: proc(format: ^wchar_t, arg: va_list) -> int ---
vwscanf :: proc(format: ^wchar_t, arg: va_list) -> int ---; vwscanf :: proc(format: ^wchar_t, arg: va_list) -> int ---
wprintf :: proc(format: ^wchar_t, #c_vararg arg: ..any) -> int ---; wprintf :: proc(format: ^wchar_t, #c_vararg arg: ..any) -> int ---
wscanf :: proc(format: ^wchar_t, #c_vararg arg: ..any) -> int ---; wscanf :: proc(format: ^wchar_t, #c_vararg arg: ..any) -> int ---
// 7.29.3 Wide character input/output functions // 7.29.3 Wide character input/output functions
fwgetc :: proc(stream: ^FILE) -> wint_t ---; fwgetc :: proc(stream: ^FILE) -> wint_t ---
fgetws :: proc(s: ^wchar_t, n: int, stream: ^FILE) -> wchar_t ---; fgetws :: proc(s: ^wchar_t, n: int, stream: ^FILE) -> wchar_t ---
fputwc :: proc(c: wchar_t, stream: ^FILE) -> wint_t ---; fputwc :: proc(c: wchar_t, stream: ^FILE) -> wint_t ---
fputws :: proc(s: ^wchar_t, stream: ^FILE) -> int ---; fputws :: proc(s: ^wchar_t, stream: ^FILE) -> int ---
fwide :: proc(stream: ^FILE, mode: int) -> int ---; fwide :: proc(stream: ^FILE, mode: int) -> int ---
getwc :: proc(stream: ^FILE) -> wint_t ---; getwc :: proc(stream: ^FILE) -> wint_t ---
getwchar :: proc() -> wint_t ---; getwchar :: proc() -> wint_t ---
putwc :: proc(c: wchar_t, stream: ^FILE) -> wint_t ---; putwc :: proc(c: wchar_t, stream: ^FILE) -> wint_t ---
putwchar :: proc(c: wchar_t) -> wint_t ---; putwchar :: proc(c: wchar_t) -> wint_t ---
ungetwc :: proc(c: wchar_t, stream: ^FILE) -> wint_t ---; ungetwc :: proc(c: wchar_t, stream: ^FILE) -> wint_t ---
// 7.29.4 General wide string utilities // 7.29.4 General wide string utilities
wcstod :: proc(nptr: ^wchar_t, endptr: ^^wchar_t) -> double ---; wcstod :: proc(nptr: ^wchar_t, endptr: ^^wchar_t) -> double ---
wcstof :: proc(nptr: ^wchar_t, endptr: ^^wchar_t) -> float ---; wcstof :: proc(nptr: ^wchar_t, endptr: ^^wchar_t) -> float ---
wcstol :: proc(nptr: ^wchar_t, endptr: ^^wchar_t, base: int) -> long ---; wcstol :: proc(nptr: ^wchar_t, endptr: ^^wchar_t, base: int) -> long ---
wcstoll :: proc(nptr: ^wchar_t, endptr: ^^wchar_t, base: int) -> longlong ---; wcstoll :: proc(nptr: ^wchar_t, endptr: ^^wchar_t, base: int) -> longlong ---
wcstoul :: proc(nptr: ^wchar_t, endptr: ^^wchar_t, base: int) -> ulong ---; wcstoul :: proc(nptr: ^wchar_t, endptr: ^^wchar_t, base: int) -> ulong ---
wcstoull :: proc(nptr: ^wchar_t, endptr: ^^wchar_t, base: int) -> ulonglong ---; wcstoull :: proc(nptr: ^wchar_t, endptr: ^^wchar_t, base: int) -> ulonglong ---
// 7.29.4.2 Wide string copying functions // 7.29.4.2 Wide string copying functions
wcscpy :: proc(s1, s2: ^wchar_t) -> ^wchar_t ---; wcscpy :: proc(s1, s2: ^wchar_t) -> ^wchar_t ---
wcsncpy :: proc(s1, s2: ^wchar_t, n: size_t) -> ^wchar_t ---; wcsncpy :: proc(s1, s2: ^wchar_t, n: size_t) -> ^wchar_t ---
wmemcpy :: proc(s1, s2: ^wchar_t, n: size_t) -> ^wchar_t ---; wmemcpy :: proc(s1, s2: ^wchar_t, n: size_t) -> ^wchar_t ---
wmemmove :: proc(s1, s2: ^wchar_t, n: size_t) -> ^wchar_t ---; wmemmove :: proc(s1, s2: ^wchar_t, n: size_t) -> ^wchar_t ---
// 7.29.4.3 Wide string concatenation functions // 7.29.4.3 Wide string concatenation functions
wcscat :: proc(s1, s2: ^wchar_t) -> ^wchar_t ---; wcscat :: proc(s1, s2: ^wchar_t) -> ^wchar_t ---
wcsncat :: proc(s1, s2: ^wchar_t, n: size_t) -> ^wchar_t ---; wcsncat :: proc(s1, s2: ^wchar_t, n: size_t) -> ^wchar_t ---
// 7.29.4.4 Wide string comparison functions // 7.29.4.4 Wide string comparison functions
wcscmp :: proc(s1, s2: ^wchar_t) -> int ---; wcscmp :: proc(s1, s2: ^wchar_t) -> int ---
wcscoll :: proc(s1, s2: ^wchar_t) -> int ---; wcscoll :: proc(s1, s2: ^wchar_t) -> int ---
wcsncmp :: proc(s1, s2: ^wchar_t, n: size_t) -> int ---; wcsncmp :: proc(s1, s2: ^wchar_t, n: size_t) -> int ---
wcsxfrm :: proc(s1, s2: ^wchar_t, n: size_t) -> size_t ---; wcsxfrm :: proc(s1, s2: ^wchar_t, n: size_t) -> size_t ---
wmemcmp :: proc(s1, s2: ^wchar_t, n: size_t) -> int ---; wmemcmp :: proc(s1, s2: ^wchar_t, n: size_t) -> int ---
// 7.29.4.5 Wide string search functions // 7.29.4.5 Wide string search functions
wcschr :: proc(s: ^wchar_t, c: wchar_t) -> ^wchar_t ---; wcschr :: proc(s: ^wchar_t, c: wchar_t) -> ^wchar_t ---
wcscspn :: proc(s1, s2: ^wchar_t) -> size_t ---; wcscspn :: proc(s1, s2: ^wchar_t) -> size_t ---
wcspbrk :: proc(s1, s2: ^wchar_t) -> ^wchar_t ---; wcspbrk :: proc(s1, s2: ^wchar_t) -> ^wchar_t ---
wcsrchr :: proc(s: ^wchar_t, c: wchar_t) -> ^wchar_t ---; wcsrchr :: proc(s: ^wchar_t, c: wchar_t) -> ^wchar_t ---
wcsspn :: proc(s1, s2: ^wchar_t) -> size_t ---; wcsspn :: proc(s1, s2: ^wchar_t) -> size_t ---
wcsstr :: proc(s1, s2: ^wchar_t) -> ^wchar_t ---; wcsstr :: proc(s1, s2: ^wchar_t) -> ^wchar_t ---
wcstok :: proc(s1, s2: ^wchar_t, ptr: ^^wchar_t) -> ^wchar_t ---; wcstok :: proc(s1, s2: ^wchar_t, ptr: ^^wchar_t) -> ^wchar_t ---
wmemchr :: proc(s: ^wchar_t, c: wchar_t, n: size_t) -> ^wchar_t ---; wmemchr :: proc(s: ^wchar_t, c: wchar_t, n: size_t) -> ^wchar_t ---
// 7.29.4.6 Miscellaneous functions // 7.29.4.6 Miscellaneous functions
wcslen :: proc(s: ^wchar_t) -> size_t ---; wcslen :: proc(s: ^wchar_t) -> size_t ---
wmemset :: proc(s: ^wchar_t, c: wchar_t, n: size_t) -> ^wchar_t ---; wmemset :: proc(s: ^wchar_t, c: wchar_t, n: size_t) -> ^wchar_t ---
// 7.29.5 Wide character time conversion functions // 7.29.5 Wide character time conversion functions
wcsftime :: proc(s: ^wchar_t, maxsize: size_t, format: ^wchar_t, timeptr: ^tm) -> size_t ---; wcsftime :: proc(s: ^wchar_t, maxsize: size_t, format: ^wchar_t, timeptr: ^tm) -> size_t ---
// 7.29.6.1 Single-byte/wide character conversion functions // 7.29.6.1 Single-byte/wide character conversion functions
btowc :: proc(c: int) -> wint_t ---; btowc :: proc(c: int) -> wint_t ---
wctob :: proc(c: wint_t) -> int ---; wctob :: proc(c: wint_t) -> int ---
// 7.29.6.2 Conversion state functions // 7.29.6.2 Conversion state functions
mbsinit :: proc(ps: ^mbstate_t) -> int ---; mbsinit :: proc(ps: ^mbstate_t) -> int ---
// 7.29.6.3 Restartable multibyte/wide character conversion functions // 7.29.6.3 Restartable multibyte/wide character conversion functions
mbrlen :: proc(s: cstring, n: size_t, ps: ^mbstate_t) -> size_t ---; mbrlen :: proc(s: cstring, n: size_t, ps: ^mbstate_t) -> size_t ---
mbrtowc :: proc(pwc: ^wchar_t, s: cstring, n: size_t, ps: ^mbstate_t) -> size_t ---; mbrtowc :: proc(pwc: ^wchar_t, s: cstring, n: size_t, ps: ^mbstate_t) -> size_t ---
wcrtomb :: proc(s: ^char, wc: wchar_t, ps: ^mbstate_t) -> size_t ---; wcrtomb :: proc(s: ^char, wc: wchar_t, ps: ^mbstate_t) -> size_t ---
// 7.29.6.4 Restartable multibyte/wide string conversion functions // 7.29.6.4 Restartable multibyte/wide string conversion functions
mbsrtowcs :: proc(dst: ^wchar_t, src: ^cstring, len: size_t, ps: ^mbstate_t) -> size_t ---; mbsrtowcs :: proc(dst: ^wchar_t, src: ^cstring, len: size_t, ps: ^mbstate_t) -> size_t ---
wcsrtombs :: proc(dst: ^char, src: ^^wchar_t, len: size_t, ps: ^mbstate_t) -> size_t ---; wcsrtombs :: proc(dst: ^char, src: ^^wchar_t, len: size_t, ps: ^mbstate_t) -> size_t ---
} }
// Large enough and aligned enough for any wide-spread in-use libc. // Large enough and aligned enough for any wide-spread in-use libc.
@@ -100,9 +100,9 @@ mbstate_t :: struct #align 16 { _: [32]char, }
// Odin does not have default argument promotion so the need for a separate type // Odin does not have default argument promotion so the need for a separate type
// here isn't necessary, though make it distinct just to be safe. // here isn't necessary, though make it distinct just to be safe.
wint_t :: distinct wchar_t; wint_t :: distinct wchar_t
// Calculate these values correctly regardless of what type wchar_t actually is. // Calculate these values correctly regardless of what type wchar_t actually is.
WINT_MIN :: 0; WINT_MIN :: 0
WINT_MAX :: 1 << (size_of(wint_t) * 8); WINT_MAX :: 1 << (size_of(wint_t) * 8)
WEOF :: ~wint_t(0); WEOF :: ~wint_t(0)
+22 -22
View File
@@ -9,40 +9,40 @@ when ODIN_OS == "windows" {
} }
when ODIN_OS == "windows" { when ODIN_OS == "windows" {
wctrans_t :: distinct wchar_t; wctrans_t :: distinct wchar_t
wctype_t :: distinct ushort; wctype_t :: distinct ushort
} }
when ODIN_OS == "linux" { when ODIN_OS == "linux" {
wctrans_t :: distinct rawptr; wctrans_t :: distinct rawptr
wctype_t :: distinct ulong; wctype_t :: distinct ulong
} }
@(default_calling_convention="c") @(default_calling_convention="c")
foreign libc { foreign libc {
// 7.30.2.1 Wide character classification functions // 7.30.2.1 Wide character classification functions
iswalnum :: proc(wc: wint_t) -> int ---; iswalnum :: proc(wc: wint_t) -> int ---
iswalpha :: proc(wc: wint_t) -> int ---; iswalpha :: proc(wc: wint_t) -> int ---
iswblank :: proc(wc: wint_t) -> int ---; iswblank :: proc(wc: wint_t) -> int ---
iswcntrl :: proc(wc: wint_t) -> int ---; iswcntrl :: proc(wc: wint_t) -> int ---
iswdigit :: proc(wc: wint_t) -> int ---; iswdigit :: proc(wc: wint_t) -> int ---
iswgraph :: proc(wc: wint_t) -> int ---; iswgraph :: proc(wc: wint_t) -> int ---
iswlower :: proc(wc: wint_t) -> int ---; iswlower :: proc(wc: wint_t) -> int ---
iswprint :: proc(wc: wint_t) -> int ---; iswprint :: proc(wc: wint_t) -> int ---
iswpunct :: proc(wc: wint_t) -> int ---; iswpunct :: proc(wc: wint_t) -> int ---
iswspace :: proc(wc: wint_t) -> int ---; iswspace :: proc(wc: wint_t) -> int ---
iswupper :: proc(wc: wint_t) -> int ---; iswupper :: proc(wc: wint_t) -> int ---
iswxdigit :: proc(wc: wint_t) -> int ---; iswxdigit :: proc(wc: wint_t) -> int ---
// 7.30.2.2 Extensible wide character classification functions // 7.30.2.2 Extensible wide character classification functions
iswctype :: proc(wc: wint_t, desc: wctype_t) -> int ---; iswctype :: proc(wc: wint_t, desc: wctype_t) -> int ---
wctype :: proc(property: cstring) -> wctype_t ---; wctype :: proc(property: cstring) -> wctype_t ---
// 7.30.3 Wide character case mapping utilities // 7.30.3 Wide character case mapping utilities
towlower :: proc(wc: wint_t) -> wint_t ---; towlower :: proc(wc: wint_t) -> wint_t ---
towupper :: proc(wc: wint_t) -> wint_t ---; towupper :: proc(wc: wint_t) -> wint_t ---
// 7.30.3.2 Extensible wide character case mapping functions // 7.30.3.2 Extensible wide character case mapping functions
towctrans :: proc(wc: wint_t, desc: wctrans_t) -> wint_t ---; towctrans :: proc(wc: wint_t, desc: wctrans_t) -> wint_t ---
wctrans :: proc(property: cstring) -> wctrans_t ---; wctrans :: proc(property: cstring) -> wctrans_t ---
} }
+22 -22
View File
@@ -41,17 +41,17 @@ accept_ranges := [5]Accept_Range{
} }
accept_sizes := [256]u8{ accept_sizes := [256]u8{
0x00..0x7f = 0xf0, 0x00..=0x7f = 0xf0,
0x80..0xc1 = 0xf1, 0x80..=0xc1 = 0xf1,
0xc2..0xdf = 0x02, 0xc2..=0xdf = 0x02,
0xe0 = 0x13, 0xe0 = 0x13,
0xe1..0xec = 0x03, 0xe1..=0xec = 0x03,
0xed = 0x23, 0xed = 0x23,
0xee..0xef = 0x03, 0xee..=0xef = 0x03,
0xf0 = 0x34, 0xf0 = 0x34,
0xf1..0xf3 = 0x04, 0xf1..=0xf3 = 0x04,
0xf4 = 0x44, 0xf4 = 0x44,
0xf5..0xff = 0xf1, 0xf5..=0xff = 0xf1,
} }
encode_rune :: proc(c: rune) -> ([4]u8, int) { encode_rune :: proc(c: rune) -> ([4]u8, int) {
@@ -379,15 +379,15 @@ full_rune_in_string :: proc(s: string) -> bool {
_first := [256]u8{ _first := [256]u8{
0x00..0x7f = 0xf0, // ascii, size 1 0x00..=0x7f = 0xf0, // ascii, size 1
0x80..0xc1 = 0xf1, // invalid, size 1 0x80..=0xc1 = 0xf1, // invalid, size 1
0xc2..0xdf = 0x02, // accept 1, size 2 0xc2..=0xdf = 0x02, // accept 1, size 2
0xe0 = 0x13, // accept 1, size 3 0xe0 = 0x13, // accept 1, size 3
0xe1..0xec = 0x03, // accept 0, size 3 0xe1..=0xec = 0x03, // accept 0, size 3
0xed = 0x23, // accept 2, size 3 0xed = 0x23, // accept 2, size 3
0xee..0xef = 0x03, // accept 0, size 3 0xee..=0xef = 0x03, // accept 0, size 3
0xf0 = 0x34, // accept 3, size 4 0xf0 = 0x34, // accept 3, size 4
0xf1..0xf3 = 0x04, // accept 0, size 4 0xf1..=0xf3 = 0x04, // accept 0, size 4
0xf4 = 0x44, // accept 4, size 4 0xf4 = 0x44, // accept 4, size 4
0xf5..0xff = 0xf1, // ascii, size 1 0xf5..=0xff = 0xf1, // ascii, size 1
} }
+29 -3
View File
@@ -2026,7 +2026,7 @@ gbFileError write_file_with_stripped_tokens(gbFile *f, AstFile *file, i64 *writt
i32 const end_offset = cast(i32)(file->tokenizer.end - file->tokenizer.start); i32 const end_offset = cast(i32)(file->tokenizer.end - file->tokenizer.start);
for_array(i, file->tokens) { for_array(i, file->tokens) {
Token *token = &file->tokens[i]; Token *token = &file->tokens[i];
if (token->flags & TokenFlag_Remove) { if (token->flags & (TokenFlag_Remove|TokenFlag_Replace)) {
i32 offset = token->pos.offset; i32 offset = token->pos.offset;
i32 to_write = offset-prev_offset; i32 to_write = offset-prev_offset;
if (!gb_file_write(f, file_data+prev_offset, to_write)) { if (!gb_file_write(f, file_data+prev_offset, to_write)) {
@@ -2034,6 +2034,16 @@ gbFileError write_file_with_stripped_tokens(gbFile *f, AstFile *file, i64 *writt
} }
written += to_write; written += to_write;
prev_offset = token_pos_end(*token).offset; prev_offset = token_pos_end(*token).offset;
}
if (token->flags & TokenFlag_Replace) {
if (token->kind == Token_Ellipsis) {
if (!gb_file_write(f, "..=", 3)) {
return gbFileError_Invalid;
}
written += 3;
} else {
return gbFileError_Invalid;
}
} }
} }
if (end_offset > prev_offset) { if (end_offset > prev_offset) {
@@ -2054,7 +2064,6 @@ int strip_semicolons(Parser *parser) {
AstPackage *pkg = parser->packages[i]; AstPackage *pkg = parser->packages[i];
file_count += pkg->files.count; file_count += pkg->files.count;
} }
gb_printf_err("File count to be stripped of unneeded tokens: %td\n", file_count);
auto generated_files = array_make<StripSemicolonFile>(permanent_allocator(), 0, file_count); auto generated_files = array_make<StripSemicolonFile>(permanent_allocator(), 0, file_count);
@@ -2062,6 +2071,20 @@ int strip_semicolons(Parser *parser) {
AstPackage *pkg = parser->packages[i]; AstPackage *pkg = parser->packages[i];
for_array(j, pkg->files) { for_array(j, pkg->files) {
AstFile *file = pkg->files[j]; AstFile *file = pkg->files[j];
bool nothing_to_change = true;
for_array(i, file->tokens) {
Token *token = &file->tokens[i];
if (token->flags) {
nothing_to_change = false;
break;
}
}
if (nothing_to_change) {
continue;
}
String old_fullpath = copy_string(permanent_allocator(), file->fullpath); String old_fullpath = copy_string(permanent_allocator(), file->fullpath);
// assumes .odin extension // assumes .odin extension
@@ -2074,6 +2097,9 @@ int strip_semicolons(Parser *parser) {
} }
} }
gb_printf_err("File count to be stripped of unneeded tokens: %td\n", generated_files.count);
isize generated_count = 0; isize generated_count = 0;
bool failed = false; bool failed = false;
@@ -2169,7 +2195,7 @@ int strip_semicolons(Parser *parser) {
} }
} }
gb_printf_err("Files stripped of unneeded token: %td\n", file_count); gb_printf_err("Files stripped of unneeded token: %td\n", generated_files.count);
return cast(int)failed; return cast(int)failed;
+4
View File
@@ -1376,6 +1376,10 @@ Token expect_operator(AstFile *f) {
syntax_error(f->curr_token, "Expected an non-range operator, got '%.*s'", syntax_error(f->curr_token, "Expected an non-range operator, got '%.*s'",
LIT(p)); LIT(p));
} }
if (f->curr_token.kind == Token_Ellipsis) {
f->tokens[f->curr_token_index].flags |= TokenFlag_Replace;
}
advance_token(f); advance_token(f);
return prev; return prev;
} }
+2 -1
View File
@@ -236,7 +236,8 @@ TokenPos token_pos_add_column(TokenPos pos) {
} }
enum TokenFlag : u8 { enum TokenFlag : u8 {
TokenFlag_Remove = 1<<1, TokenFlag_Remove = 1<<1,
TokenFlag_Replace = 1<<2,
}; };
struct Token { struct Token {