feat: port lua scripting language

This commit is contained in:
2026-03-27 21:53:33 +01:00
parent 88ff98c325
commit d197665fdd
131 changed files with 46362 additions and 358 deletions
+12 -22
View File
@@ -96,22 +96,9 @@ ALL_OBJS := $(TCC_OBJS) $(COMPAT_OBJS) $(ASM_OBJS)
TARGET := $(BINDIR)/tcc.elf
# ---- CRT objects (compiled for linking by TCC) ----
CRT_CFLAGS := \
-std=gnu11 \
-O2 \
-nostdinc \
-ffreestanding \
-fno-stack-protector \
-fno-PIC \
-m64 \
-march=x86-64 \
-mno-red-zone \
-fno-tree-loop-distribute-patterns \
-isystem $(PROG_INC)/libc \
-isystem $(shell $(CC) -print-file-name=include)
# ---- CRT objects (staged from shared libc) ----
SHARED_CRT_DIR := $(LIBDIR)/libc
CRT_DIR := ../../bin/lib/tcc/lib
CRT_OBJS := $(CRT_DIR)/crt1.o $(CRT_DIR)/crti.o $(CRT_DIR)/crtn.o
@@ -133,17 +120,20 @@ $(OBJDIR)/%.o: %.S Makefile
@mkdir -p $(OBJDIR)
$(CC) $(CFLAGS) -c $< -o $@
$(CRT_DIR)/crt1.o: crt/crt1.c
@mkdir -p $(CRT_DIR)
$(CC) $(CRT_CFLAGS) -c $< -o $@
$(SHARED_CRT_DIR)/liblibc.a $(SHARED_CRT_DIR)/crt1.o $(SHARED_CRT_DIR)/crti.o $(SHARED_CRT_DIR)/crtn.o:
$(MAKE) -C $(SHARED_CRT_DIR)
$(CRT_DIR)/crti.o: crt/crti.c
$(CRT_DIR)/crt1.o: $(SHARED_CRT_DIR)/crt1.o
@mkdir -p $(CRT_DIR)
$(CC) $(CRT_CFLAGS) -c $< -o $@
cp $< $@
$(CRT_DIR)/crtn.o: crt/crtn.c
$(CRT_DIR)/crti.o: $(SHARED_CRT_DIR)/crti.o
@mkdir -p $(CRT_DIR)
$(CC) $(CRT_CFLAGS) -c $< -o $@
cp $< $@
$(CRT_DIR)/crtn.o: $(SHARED_CRT_DIR)/crtn.o
@mkdir -p $(CRT_DIR)
cp $< $@
$(CRT_DIR)/libc.a: $(LIBDIR)/libc/liblibc.a
@mkdir -p $(CRT_DIR)
-77
View File
@@ -1,77 +0,0 @@
/*
* crt1.c
* C runtime startup for TCC-compiled programs on MontaukOS
* Copyright (c) 2026 Daniel Hammer
*
* Provides _start, which:
* 1. Gets command-line arguments from kernel
* 2. Parses them into argc/argv
* 3. Calls main(argc, argv)
* 4. Calls exit(return value)
*/
/* Syscall wrappers (inline asm, no header dependencies) */
static inline long _sys0(long nr) {
long ret;
__asm__ volatile("syscall" : "=a"(ret) : "a"(nr)
: "rcx", "r11", "rdi", "rsi", "rdx", "r8", "r9", "r10", "memory");
return ret;
}
static inline long _sys1(long nr, long a1) {
long ret;
__asm__ volatile(
"mov %[a1], %%rdi\n\t"
"syscall"
: "=a"(ret)
: "a"(nr), [a1] "r"(a1)
: "rcx", "r11", "rdi", "rsi", "rdx", "r8", "r9", "r10", "memory");
return ret;
}
static inline long _sys2(long nr, long a1, long a2) {
long ret;
__asm__ volatile(
"mov %[a1], %%rdi\n\t"
"mov %[a2], %%rsi\n\t"
"syscall"
: "=a"(ret)
: "a"(nr), [a1] "r"(a1), [a2] "r"(a2)
: "rcx", "r11", "rdi", "rsi", "rdx", "r8", "r9", "r10", "memory");
return ret;
}
#define SYS_EXIT 0
#define SYS_GETARGS 25
extern int main(int argc, char **argv);
void _start(void) {
char argbuf[256];
int len = (int)_sys2(SYS_GETARGS, (long)argbuf, (long)sizeof(argbuf));
char *argv[32];
int argc = 0;
/* argv[0] = program name */
argv[argc++] = "prog";
if (len > 0) {
if (len > 255) len = 255;
argbuf[len] = '\0';
char *p = argbuf;
while (*p && argc < 31) {
while (*p == ' ') p++;
if (*p == '\0') break;
argv[argc++] = p;
while (*p && *p != ' ') p++;
if (*p) *p++ = '\0';
}
}
argv[argc] = (void*)0;
int ret = main(argc, argv);
_sys1(SYS_EXIT, (long)ret);
__builtin_unreachable();
}
-7
View File
@@ -1,7 +0,0 @@
/*
* crti.c
* Init section prologue (minimal for MontaukOS)
* Copyright (c) 2026 Daniel Hammer
*/
/* Empty -- MontaukOS userspace has no global constructors */
-7
View File
@@ -1,7 +0,0 @@
/*
* crtn.c
* Init section epilogue (minimal for MontaukOS)
* Copyright (c) 2026 Daniel Hammer
*/
/* Empty -- MontaukOS userspace has no global destructors */
-126
View File
@@ -10,83 +10,9 @@
#include <stddef.h>
#include <stdint.h>
/* ====================================================================
setjmp / longjmp (implemented in setjmp.S)
==================================================================== */
typedef unsigned long jmp_buf[8]; /* rbx, rbp, r12-r15, rsp, rip */
int setjmp(jmp_buf env);
void longjmp(jmp_buf env, int val) __attribute__((noreturn));
/* ====================================================================
time stubs (for __DATE__ / __TIME__ macros)
==================================================================== */
typedef long time_t;
struct tm {
int tm_sec;
int tm_min;
int tm_hour;
int tm_mday;
int tm_mon;
int tm_year;
int tm_wday;
int tm_yday;
int tm_isdst;
};
static inline time_t time(time_t *t) {
if (t) *t = 0;
return 0;
}
static inline struct tm *localtime(const time_t *t) {
static struct tm tm0 = {
.tm_sec = 0, .tm_min = 0, .tm_hour = 12,
.tm_mday = 1, .tm_mon = 0, .tm_year = 126, /* 2026 */
.tm_wday = 4, .tm_yday = 0, .tm_isdst = 0
};
(void)t;
return &tm0;
}
/* ====================================================================
gettimeofday stub (for timing in tcc.c)
==================================================================== */
struct timeval {
long tv_sec;
long tv_usec;
};
struct timezone {
int tz_minuteswest;
int tz_dsttime;
};
static inline int gettimeofday(struct timeval *tv, struct timezone *tz) {
if (tv) { tv->tv_sec = 0; tv->tv_usec = 0; }
(void)tz;
return 0;
}
/* getcwd is provided by libc now */
char *getcwd(char *buf, size_t size);
/* ====================================================================
POSIX file access stubs
==================================================================== */
#define R_OK 4
#define W_OK 2
#define X_OK 1
#define F_OK 0
/* Check if file exists by trying to open it */
int access(const char *path, int mode);
/* chmod - no-op on MontaukOS */
static inline int chmod(const char *path, unsigned int mode) {
(void)path; (void)mode;
@@ -117,24 +43,6 @@ static inline char *realpath(const char *path, char *resolved) {
return resolved;
}
/* ====================================================================
strtof / strtold stubs
==================================================================== */
/* These are declared extern in tcc.h for non-Win32.
We provide no-op stubs since the libc has no FP parse. */
static inline float strtof(const char *nptr, char **endptr) {
(void)nptr;
if (endptr) *endptr = (char*)nptr;
return 0.0f;
}
static inline long double strtold(const char *nptr, char **endptr) {
(void)nptr;
if (endptr) *endptr = (char*)nptr;
return 0.0L;
}
/* dlfcn stubs not needed -- TCC_IS_NATIVE is disabled for MontaukOS */
/* ====================================================================
@@ -158,38 +66,12 @@ static inline int unlink(const char *path) {
return remove(path);
}
/* fputc (should be in libc but isn't yet) */
static inline int fputc(int c, FILE *stream) {
unsigned char ch = (unsigned char)c;
size_t n = fwrite(&ch, 1, 1, stream);
return n == 1 ? c : -1;
}
/* fdopen - MontaukOS doesn't have fd-to-FILE conversion.
TCC uses fdopen after creating a file with open().
We return NULL and let TCC fall back to error path,
or we can use a workaround. */
FILE *fdopen(int fd, const char *mode);
/* strerror */
static inline const char *strerror(int errnum) {
(void)errnum;
return "error";
}
/* ====================================================================
String functions missing from MontaukOS libc
==================================================================== */
static inline char *strpbrk(const char *s, const char *accept) {
for (; *s; s++) {
for (const char *a = accept; *a; a++) {
if (*s == *a) return (char *)s;
}
}
return NULL;
}
/* ====================================================================
Process stubs
==================================================================== */
@@ -199,12 +81,4 @@ static inline int execvp(const char *file, char *const argv[]) {
return -1;
}
/* ====================================================================
Floating-point parsing and math
==================================================================== */
double strtod(const char *nptr, char **endptr);
double ldexp(double x, int n);
long double ldexpl(long double x, int n);
#endif /* MONTAUK_COMPAT_H */
-111
View File
@@ -37,24 +37,9 @@ static inline long _sys2(long nr, long a1, long a2) {
return ret;
}
#define SYS_OPEN 6
#define SYS_GETSIZE 8
#define SYS_CLOSE 9
#define SYS_GETARGS 25
/* ====================================================================
access() - check if a file exists
==================================================================== */
int access(const char *path, int mode) {
(void)mode;
if (path == NULL) return -1;
int h = (int)_sys1(SYS_OPEN, (long)path);
if (h < 0) return -1;
_sys1(SYS_CLOSE, (long)h);
return 0;
}
/* ====================================================================
fdopen - wrap a raw fd in a FILE (needed by tccelf.c)
==================================================================== */
@@ -78,102 +63,6 @@ FILE *fdopen(int fd, const char *mode) {
return f;
}
/* ====================================================================
Floating point support (needed by TCC for parsing float literals)
==================================================================== */
double ldexp(double x, int n) {
/* Use bit manipulation via union for exact results */
if (x == 0.0 || n == 0) return x;
while (n > 0) { x *= 2.0; n--; }
while (n < 0) { x *= 0.5; n++; }
return x;
}
long double ldexpl(long double x, int n) {
return (long double)ldexp((double)x, n);
}
double strtod(const char *nptr, char **endptr) {
double result = 0.0;
double sign = 1.0;
const char *s = nptr;
while (*s == ' ' || *s == '\t' || *s == '\n') s++;
if (*s == '-') { sign = -1.0; s++; }
else if (*s == '+') s++;
/* Integer part */
while (*s >= '0' && *s <= '9')
result = result * 10.0 + (*s++ - '0');
/* Fractional part */
if (*s == '.') {
s++;
double frac = 0.1;
while (*s >= '0' && *s <= '9') {
result += (*s++ - '0') * frac;
frac *= 0.1;
}
}
/* Exponent */
if (*s == 'e' || *s == 'E') {
s++;
int exp_sign = 1, exp_val = 0;
if (*s == '-') { exp_sign = -1; s++; }
else if (*s == '+') s++;
while (*s >= '0' && *s <= '9')
exp_val = exp_val * 10 + (*s++ - '0');
double exp_mult = 1.0;
for (int i = 0; i < exp_val; i++)
exp_mult *= 10.0;
if (exp_sign > 0) result *= exp_mult;
else result /= exp_mult;
}
/* Hex float (0x...p...) */
if (nptr[0] == '0' && (nptr[1] == 'x' || nptr[1] == 'X')) {
s = nptr + 2;
result = 0.0;
while (1) {
int d;
if (*s >= '0' && *s <= '9') d = *s - '0';
else if (*s >= 'a' && *s <= 'f') d = *s - 'a' + 10;
else if (*s >= 'A' && *s <= 'F') d = *s - 'A' + 10;
else break;
result = result * 16.0 + d;
s++;
}
if (*s == '.') {
s++;
double frac = 1.0 / 16.0;
while (1) {
int d;
if (*s >= '0' && *s <= '9') d = *s - '0';
else if (*s >= 'a' && *s <= 'f') d = *s - 'a' + 10;
else if (*s >= 'A' && *s <= 'F') d = *s - 'A' + 10;
else break;
result += d * frac;
frac /= 16.0;
s++;
}
}
if (*s == 'p' || *s == 'P') {
s++;
int exp_sign = 1, exp_val = 0;
if (*s == '-') { exp_sign = -1; s++; }
else if (*s == '+') s++;
while (*s >= '0' && *s <= '9')
exp_val = exp_val * 10 + (*s++ - '0');
result = ldexp(result, exp_sign * exp_val);
}
}
if (endptr) *endptr = (char *)s;
return sign * result;
}
/* ====================================================================
strtoll / strtoull (needed by TCC, not in MontaukOS libc)
==================================================================== */
+5
View File
@@ -32,6 +32,11 @@
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <math.h>
#include <setjmp.h>
#include <time.h>
#include <unistd.h>
#include <sys/time.h>
#include "montauk_compat.h"
/* Stubs for functions in libc headers but not relevant here */