Reorganized
This commit is contained in:
@@ -0,0 +1,114 @@
|
||||
#include "forth.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
static inline long syscall3(long n, long a1, long a2, long a3) {
|
||||
long ret;
|
||||
__asm__ volatile ("syscall"
|
||||
: "=a"(ret)
|
||||
: "a"(n), "D"(a1), "S"(a2), "d"(a3)
|
||||
: "rcx", "r11", "memory");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline long syscall1(long n, long a1) {
|
||||
long ret;
|
||||
__asm__ volatile ("syscall"
|
||||
: "=a"(ret)
|
||||
: "a"(n), "D"(a1)
|
||||
: "rcx", "r11", "memory");
|
||||
return ret;
|
||||
}
|
||||
|
||||
void forth_putchar(char c) {
|
||||
char ch = c;
|
||||
syscall3(1, 1, (long)&ch, 1);
|
||||
}
|
||||
|
||||
void forth_fflush(void) {
|
||||
}
|
||||
|
||||
int forth_getchar(void) {
|
||||
unsigned char c;
|
||||
long n = syscall3(0, 0, (long)&c, 1);
|
||||
if (n <= 0) return FORTH_EOF;
|
||||
return (int)c;
|
||||
}
|
||||
|
||||
void forth_panic(void) {
|
||||
syscall1(60, 1);
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
int64_t forth_strtoll(const char* str, char** endptr, int base) {
|
||||
const char* s = str;
|
||||
int neg = 0;
|
||||
int64_t val = 0;
|
||||
while (forth_isspace(*s)) s++;
|
||||
if (*s == '-') { neg = 1; s++; }
|
||||
else if (*s == '+') { s++; }
|
||||
while (*s >= '0' && *s <= '9') {
|
||||
val = val * base + (*s - '0');
|
||||
s++;
|
||||
}
|
||||
if (endptr) *endptr = (char*)s;
|
||||
return neg ? -val : val;
|
||||
}
|
||||
|
||||
static void print_str(const char* s) {
|
||||
while (*s) forth_putchar(*s++);
|
||||
}
|
||||
|
||||
static void print_int(long long v) {
|
||||
char buf[32];
|
||||
int i = 30;
|
||||
int neg = 0;
|
||||
if (v < 0) { neg = 1; v = -v; }
|
||||
buf[31] = '\0';
|
||||
if (v == 0) {
|
||||
buf[i--] = '0';
|
||||
} else {
|
||||
while (v > 0 && i >= 0) {
|
||||
buf[i--] = '0' + (v % 10);
|
||||
v /= 10;
|
||||
}
|
||||
}
|
||||
if (neg) buf[i--] = '-';
|
||||
print_str(&buf[i + 1]);
|
||||
}
|
||||
|
||||
void forth_printf(const char* fmt, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
while (*fmt) {
|
||||
if (*fmt == '%' && *(fmt + 1)) {
|
||||
fmt++;
|
||||
if (*fmt == 's') {
|
||||
print_str(va_arg(ap, const char*));
|
||||
} else if (*fmt == 'c') {
|
||||
forth_putchar((char)va_arg(ap, int));
|
||||
} else if (*fmt == '%') {
|
||||
forth_putchar('%');
|
||||
} else if (*fmt == 'l') {
|
||||
if (*(fmt + 1) == 'l' && (*(fmt + 2) == 'd' || *(fmt + 2) == 'i' || *(fmt + 2) == 'u')) {
|
||||
fmt += 2;
|
||||
print_int(va_arg(ap, long long));
|
||||
}
|
||||
} else if (*fmt == 'd' || *fmt == 'i' || *fmt == 'u') {
|
||||
print_int(va_arg(ap, int));
|
||||
} else {
|
||||
forth_putchar('%');
|
||||
forth_putchar(*fmt);
|
||||
}
|
||||
} else {
|
||||
forth_putchar(*fmt);
|
||||
}
|
||||
fmt++;
|
||||
}
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void _start(void) {
|
||||
forth_run();
|
||||
syscall1(60, 0);
|
||||
__builtin_unreachable();
|
||||
}
|
||||
Reference in New Issue
Block a user