Akuli / jou

Yet another programming language
MIT License
11 stars 4 forks source link

We can't set variable value outside the function #383

Closed littlewhitecloud closed 9 months ago

littlewhitecloud commented 1 year ago

I am working on the stdlib and I write code like this:

# System functions
import "stdlib/str.jou"

declare getenv(varname: byte*) -> byte*

def is_windows() -> bool:
    return getenv("OS") != NULL and strstr(getenv("OS"), "Windows") != NULL

def is_macos() -> bool:
    return getenv("OSTYPE") != NULL and starts_with(getenv("OSTYPE"), "darwin")

def platform() -> byte*:
    return getenv("OS")

WINDOWS = is_windows()
MACOS = is_macos()

and it tell me:

jou sys.jou
compiler error in file "sys.jou", line 15: expected a definition or declaration, got a variable name 'WINDOWS'
The process failed with status 1.

So how can I give a value to variable outside the functions?

Akuli commented 1 year ago

Jou doesn't do something magically and hide it. If you say WINDOWS = is_windows(), Jou will not run the is_windows() function when the program starts. If you want something to run when the program starts, it needs to go to the main() function or _windows_startup.jou.

But instead of having these functions in the stdlib, it would be better if you could detect the OS at compile time rather than at runtime. Maybe there would be special compile-time constants WINDOWS and MACOS. This way it would be possible to declare functions that don't exist in all systems. For example:

if WINDOWS:
    declare GetModuleFileNameA(hModule: void*, lpFilename: byte*, nSize: int) -> int
elif MACOS:
    declare _NSGetExecutablePath(buf: byte*, bufsize: int*) -> int
else:
    declare readlink(linkpath: byte*, result: byte*, result_size: long) -> long

def find_current_executable() -> byte*:
    if WINDOWS:
        # use GetModuleFileNameA()
    elif MACOS:
        # use _NSGetExecutablePath() 
    else:
        # use readlink()

Currently this is not possible, because:

As a temporary solution that made this kinda work, I added some spaghetti with a few hard-coded function names to the compiler:

https://github.com/Akuli/jou/blob/914200d20bfbcd17d660c18689ac2f910a94c2da/src/codegen.c#L189-L196

Akuli commented 9 months ago

There is a separate issue #385 about compile-time if statements. I don't think we need this issue anymore, but feel free to ask more questions here or in other issues if anything is still unclear :)