mirror of
https://github.com/Nexoniarz/Finch.git
synced 2026-11-03 00:44:27 +00:00
--target: windows, linux, arm64, macos or a triple, in the compiler written in Finch
Targets, the target's C compiler (FINCH_CC) for linking, C import for the target (--target to libclang, its headers), the AAPCS64 and Microsoft x64 ways of passing structs by value (and the System V one), dllexport for libraries on Windows, .exe names, and running the program through wine or qemu-aarch64. std/ gets time_windows.fch and proc_windows.fch: a module has a version per system (name_windows.fch, name_macos.fch, name_linux.fch) that wins over name.fch. stdin, stdout and stderr work where C makes them macros. Run for real: all 27 programs under tests/run and tests/new pass on ARM64 Linux under qemu and on Windows under Wine (MinGW), structs by value and callbacks included. macOS is only checked as far as clang accepts the IR; there is no emulator for it here.
This commit is contained in:
parent
8c3b5b15b9
commit
750eca3e85
10 changed files with 426 additions and 52 deletions
6
std/finch_win.h
Normal file
6
std/finch_win.h
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
/* The Windows functions std/time_windows.fch needs. Declared here, not by including <windows.h>:
|
||||
libclang can't parse that header with MinGW's intrinsics. Both are in kernel32. */
|
||||
unsigned long long GetTickCount64(void);
|
||||
void Sleep(unsigned long milliseconds);
|
||||
int QueryPerformanceCounter(long long *count);
|
||||
int QueryPerformanceFrequency(long long *frequency);
|
||||
45
std/proc_windows.fch
Normal file
45
std/proc_windows.fch
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
// Programs, for Windows. The same functions as proc.fch (that file is for Linux and macOS).
|
||||
import "stdlib.h"
|
||||
import "process.h"
|
||||
import "direct.h"
|
||||
import "time.h"
|
||||
|
||||
fn run(str command) -> int {
|
||||
return shell(command)
|
||||
}
|
||||
|
||||
fn output(str command) -> str! {
|
||||
tmp := proc_env("TEMP", ".") + "\\finch_out_" + str(getpid()) + "_" + str(int(time(null)))
|
||||
code := shell(command + " > \"" + tmp + "\" 2>&1")
|
||||
text := read_file(tmp) or ""
|
||||
delete_file(tmp)
|
||||
if code != 0 {
|
||||
return error("'" + command + "' exited with code " + str(code) + ": " + text.trim())
|
||||
}
|
||||
return text
|
||||
}
|
||||
|
||||
fn proc_env(str name, str fallback) -> str {
|
||||
v := getenv(name)
|
||||
if v.len == 0 {
|
||||
return fallback
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
fn env(str name, str fallback) -> str {
|
||||
return proc_env(name, fallback)
|
||||
}
|
||||
|
||||
fn pid() -> int {
|
||||
return int(getpid())
|
||||
}
|
||||
|
||||
fn cwd() -> str {
|
||||
[]char buf
|
||||
for i in 0..4096 {
|
||||
buf.push(char(0))
|
||||
}
|
||||
getcwd(buf.ptr, 4096)
|
||||
return str(buf.ptr)
|
||||
}
|
||||
75
std/time_windows.fch
Normal file
75
std/time_windows.fch
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
// Time, for Windows. The same functions as time.fch (that file is for Linux and macOS).
|
||||
import "time.h"
|
||||
import "finch_win.h"
|
||||
|
||||
struct Date {
|
||||
int year
|
||||
int month // 1 to 12
|
||||
int day // 1 to 31
|
||||
int hour
|
||||
int minute
|
||||
int second
|
||||
int weekday // 0 is Sunday
|
||||
int yearday // 1 to 366
|
||||
}
|
||||
|
||||
fn now() -> int {
|
||||
return int(time(null))
|
||||
}
|
||||
|
||||
// milliseconds on a clock that only goes forward (the performance counter: GetTickCount64 ticks every 15 ms)
|
||||
fn millis() -> int {
|
||||
i64 count = 0
|
||||
i64 freq = 1
|
||||
QueryPerformanceFrequency(addr(freq))
|
||||
QueryPerformanceCounter(addr(count))
|
||||
return int(count / freq) * 1000 + int(count % freq) * 1000 / int(freq)
|
||||
}
|
||||
|
||||
fn sleep(int ms) {
|
||||
Sleep(u32(ms))
|
||||
}
|
||||
|
||||
fn parts(tm t) -> Date {
|
||||
return Date(year: int(t.tm_year) + 1900, month: int(t.tm_mon) + 1, day: int(t.tm_mday), hour: int(t.tm_hour),
|
||||
minute: int(t.tm_min), second: int(t.tm_sec), weekday: int(t.tm_wday), yearday: int(t.tm_yday) + 1)
|
||||
}
|
||||
|
||||
fn date(int unix) -> Date {
|
||||
tm t
|
||||
i64 stamp = unix
|
||||
_gmtime64_s(addr(t), addr(stamp))
|
||||
return parts(t)
|
||||
}
|
||||
|
||||
fn local(int unix) -> Date {
|
||||
tm t
|
||||
i64 stamp = unix
|
||||
_localtime64_s(addr(t), addr(stamp))
|
||||
return parts(t)
|
||||
}
|
||||
|
||||
fn format(int unix, str pattern) -> str {
|
||||
tm t
|
||||
i64 stamp = unix
|
||||
_localtime64_s(addr(t), addr(stamp))
|
||||
[]char buf
|
||||
for i in 0..256 {
|
||||
buf.push(char(0))
|
||||
}
|
||||
strftime(buf.ptr, 256, pattern, addr(t))
|
||||
return str(buf.ptr)
|
||||
}
|
||||
|
||||
fn days_in_month(int year, int month) -> int {
|
||||
if month == 2 {
|
||||
if year % 4 == 0 && (year % 100 != 0 || year % 400 == 0) {
|
||||
return 29
|
||||
}
|
||||
return 28
|
||||
}
|
||||
if month == 4 || month == 6 || month == 9 || month == 11 {
|
||||
return 30
|
||||
}
|
||||
return 31
|
||||
}
|
||||
Loading…
Reference in a new issue