Skip to content

Commit

Permalink
Use compile time if statements (#712)
Browse files Browse the repository at this point in the history
Akuli authored Jan 27, 2025
1 parent 8a0bb4b commit e014aae
Showing 3 changed files with 43 additions and 67 deletions.
1 change: 1 addition & 0 deletions bootstrap.sh
Original file line number Diff line number Diff line change
@@ -20,6 +20,7 @@ commits=(
1c7ce74933aea8a8862fd1d4409735b9fb7a1d7e # last commit on main that contains the compiler written in C
b339b1b300ba98a2245b493a58dd7fab4c465020 # "match ... with ..." syntax
874d1978044a080173fcdcc4e92736136c97dd61 # "match some_integer:" support
8a0bb4b50ef77932243f4f65ae90be84e763ec45 # evaluating "if WINDOWS:" and such inside functions
)

for commit in ${commits[@]}; do
66 changes: 23 additions & 43 deletions compiler/paths.jou
Original file line number Diff line number Diff line change
@@ -23,53 +23,40 @@ declare dirname(path: byte*) -> byte*
declare stat(path: byte*, buf: byte[1000]*) -> int # lol


def fail_finding_exe() -> noreturn:
# TODO: include os error message (GetLastError / errno)
fprintf(stderr, "error: cannot locate currently running executable, needed for finding the Jou standard library\n")
exit(1)


if WINDOWS:
@public
def find_current_executable() -> byte*:
buf = NULL
for size = 2L; True; size *= 2:
buf = realloc(buf, size)
memset(buf, 0, size)
ret = GetModuleFileNameA(NULL, buf, size as int)
if ret <= 0:
fail_finding_exe()
if ret < size:
# buffer is big enough, it fits
return buf

elif MACOS:
@public
def find_current_executable() -> byte*:
@public
def find_current_executable() -> byte*:
if MACOS:
n = 1
result: byte* = malloc(n)
ret = _NSGetExecutablePath(result, &n) # sets n to desired size
assert ret < 0 # didn't fit
result = realloc(result, n)
ret = _NSGetExecutablePath(result, &n)
if ret != 0:
fail_finding_exe()
return result
if ret == 0:
# success
return result

else:
@public
def find_current_executable() -> byte*:
else:
buf = NULL
for size = 2L; True; size *= 2:
buf = realloc(buf, size)
memset(buf, 0, size)
ret = readlink("/proc/self/exe", buf, size)

if WINDOWS:
ret = GetModuleFileNameA(NULL, buf, size as int)
else:
ret = readlink("/proc/self/exe", buf, size)

if ret <= 0:
fail_finding_exe()
break # error
if ret < size:
# buffer is big enough, it fits
return buf

# TODO: show os error message? (GetLastError / errno)
fprintf(stderr, "error: cannot locate currently running executable, needed for finding the Jou standard library\n")
exit(1)


@public
def find_stdlib() -> byte*:
@@ -110,16 +97,6 @@ def find_stdlib() -> byte*:
fprintf(stderr, " %s\n", checked[i])
exit(1)

# Ignoring return values, because there's currently no way to check errno.
# We need to ignore the error when directory exists already (EEXIST).
# Ideally we wouldn't ignore any other errors.
if WINDOWS:
def my_mkdir(path: byte*) -> None:
_mkdir(path)
else:
def my_mkdir(path: byte*) -> None:
mkdir(path, 0o777) # this is what mkdir in bash does according to strace


def write_gitignore(p: byte*) -> None:
filename: byte* = malloc(strlen(p) + 100)
@@ -139,10 +116,13 @@ def write_gitignore(p: byte*) -> None:
free(filename)


def mkdir_exist_ok(p: byte*) -> None:
def mkdir_exist_ok(path: byte*) -> None:
# TODO: check if errno == EEXIST
# Currently no good way to access EEXIST constant
my_mkdir(p)
if WINDOWS:
_mkdir(path)
else:
mkdir(path, 0o777) # this is what mkdir in bash does according to strace


@public
43 changes: 19 additions & 24 deletions stdlib/errno.jou
Original file line number Diff line number Diff line change
@@ -9,36 +9,31 @@ elif NETBSD:
else:
declare __errno_location() -> int*

# TODO: Ideally we would be able to place the if statements inside the functions.
if WINDOWS:
@public
def set_errno(value: int) -> None:

@public
def set_errno(value: int) -> None:
if WINDOWS:
*_errno() = value
@public
def get_errno() -> int:
return *_errno()
elif MACOS:
@public
def set_errno(value: int) -> None:
elif MACOS:
*__error() = value
@public
def get_errno() -> int:
return *__error()
elif NETBSD:
@public
def set_errno(value: int) -> None:
elif NETBSD:
*__errno() = value
@public
def get_errno() -> int:
return *__errno()
else:
@public
def set_errno(value: int) -> None:
else:
*__errno_location() = value
@public
def get_errno() -> int:


@public
def get_errno() -> int:
if WINDOWS:
return *_errno()
elif MACOS:
return *__error()
elif NETBSD:
return *__errno()
else:
return *__errno_location()


# Convert an error code into a string. Do not modify or free() the returned string.
@public
declare strerror(errno_value: int) -> byte*

0 comments on commit e014aae

Please sign in to comment.