Page MenuHomePhorge

No OneTemporary

Size
14 KB
Referenced Files
None
Subscribers
None
diff --git a/meson.build b/meson.build
index 59a8b8d..11a8bf2 100644
--- a/meson.build
+++ b/meson.build
@@ -1,138 +1,138 @@
project('ant', 'c', default_options: [
'optimization=2',
'c_std=gnu23',
'default_library=static'
])
cmake = import('cmake')
include = include_directories('include')
module_files = run_command('sh', '-c',
'cd "$MESON_SOURCE_ROOT" && ls src/modules/*.c',
check: true
).stdout().strip().split()
sources = files(
'src/main.c',
'src/ant.c',
'src/repl.c',
'src/runtime.c',
'src/snapshot.c',
) + files(module_files)
uuid_dep = dependency('uuid', required: true)
llhttp = dependency('llhttp', required: true)
openssl_dep = dependency('openssl', required: true)
libsodium_dep = dependency('libsodium', required: true)
if host_machine.system() == 'darwin'
security_dep = dependency('appleframeworks', modules: ['Security', 'CoreFoundation'], required: true)
endif
tlsuv_opts = cmake.subproject_options()
tlsuv_opts.append_compile_args('c', [
'-Wno-unused-function',
'-Wno-unused-variable',
'-Wno-bitwise-op-parentheses',
'-Wno-sometimes-uninitialized'
])
tlsuv_opts.add_cmake_defines({'BUILD_TESTING': 'OFF'})
tlsuv_dep = cmake.subproject('tlsuv', options: tlsuv_opts).dependency('tlsuv')
zlib_dep = subproject('zlib-ng').get_variable('zlib_ng_dep')
bdwgc_dep = subproject('bdwgc').get_variable('bdwgc_dep')
uthash_dep = subproject('uthash').get_variable('uthash_dep')
yyjson_dep = subproject('yyjson').get_variable('yyjson_dep')
uuidv7_dep = subproject('uuidv7').get_variable('uuidv7_dep')
mongoose_dep = subproject('mongoose').get_variable('mongoose_dep')
argtable3_dep = subproject('argtable3').get_variable('argtable3_dep')
minicoro_dep = subproject('minicoro').get_variable('minicoro_dep')
libffi_dep = subproject('libffi', default_options: [
'warning_level=0',
'tests=false'
]).get_variable('ffi_dep')
libuv_dep = subproject('libuv', default_options: [
'build_tests=false',
'build_benchmarks=false'
]).get_variable('libuv_dep')
git = find_program('git', required: false)
if git.found()
git_commit = run_command(git, 'rev-parse', '--short=10', 'HEAD', check: false)
if git_commit.returncode() == 0
git_hash = git_commit.stdout().strip()
else
git_hash = 'unknown'
endif
else
git_hash = 'unknown'
endif
build_date = run_command('date', '+%Y-%m-%d', check: true).stdout().strip()
version_conf = configuration_data()
-version_conf.set('ANT_VERSION', '0.1.0.24')
+version_conf.set('ANT_VERSION', '0.1.0.25')
version_conf.set('ANT_GIT_HASH', git_hash)
version_conf.set('ANT_BUILD_DATE', build_date)
config_h = configure_file(
input: 'include/config.h.in',
output: 'config.h',
configuration: version_conf
)
build_include = include_directories('.')
add_project_arguments(
'-D JS_DUMP',
'-Wno-unused-function',
'-D NO_EXECUTE_PERMISSION',
language: 'c')
gen_snapshot = executable(
'gen_snapshot',
files('src/tools/gen_snapshot.c'),
include_directories: [include, build_include],
c_args: ['-DANT_SNAPSHOT_GENERATOR'],
native: true
)
snapshot_h = custom_target(
'snapshot',
input: 'src/core/index.js',
output: 'snapshot_data.h',
command: [
gen_snapshot,
'@INPUT@',
'@OUTPUT@',
'VERSION=' + version_conf.get('ANT_VERSION'),
'GIT_HASH=' + version_conf.get('ANT_GIT_HASH'),
'BUILD_DATE=' + version_conf.get('ANT_BUILD_DATE')
],
build_by_default: true
)
ant_deps = [
libffi_dep,
bdwgc_dep, uuid_dep,
llhttp, mongoose_dep,
libuv_dep, argtable3_dep,
tlsuv_dep, libsodium_dep,
yyjson_dep, minicoro_dep,
uuidv7_dep, openssl_dep,
zlib_dep, uthash_dep
]
if host_machine.system() == 'darwin'
ant_deps += [security_dep]
endif
executable(
'ant',
sources + [snapshot_h],
include_directories: [include, build_include],
dependencies: ant_deps
)
diff --git a/src/modules/io.c b/src/modules/io.c
index 414b112..49b6128 100644
--- a/src/modules/io.c
+++ b/src/modules/io.c
@@ -1,276 +1,350 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <ctype.h>
#include <libgen.h>
+#include <uv.h>
#include "runtime.h"
#include "modules/io.h"
#define ANSI_RED "\x1b[31m"
#define ANSI_YELLOW "\x1b[33m"
+#define ANSI_CYAN "\x1b[36m"
+#define ANSI_MAGENTA "\x1b[35m"
#define ANSI_RESET "\x1b[0m"
#define JSON_KEY "\x1b[0m"
#define JSON_STRING "\x1b[32m"
#define JSON_NUMBER "\x1b[33m"
#define JSON_BOOL "\x1b[35m"
#define JSON_NULL "\x1b[90m"
#define JSON_BRACE "\x1b[37m"
#define JSON_FUNC "\x1b[36m"
#define JSON_TAG "\x1b[34m"
#define JSON_REF "\x1b[90m"
void print_value_colored(const char *str, FILE *stream) {
bool in_string = false;
bool escape_next = false;
bool is_key = true;
int bracket_depth = 0;
char string_char = 0;
for (const char *p = str; *p; p++) {
if (escape_next) {
fputc(*p, stream);
escape_next = false;
continue;
}
if (*p == '\\' && in_string) {
fputc(*p, stream);
escape_next = true;
continue;
}
if (*p == '\'' || *p == '"') {
if (!in_string) {
bool use_key_color = is_key && bracket_depth > 0;
fprintf(stream, "%s%c", use_key_color ? JSON_KEY : JSON_STRING, *p);
in_string = true;
string_char = *p;
} else if (*p == string_char) {
fprintf(stream, "%c%s", *p, ANSI_RESET);
in_string = false;
string_char = 0;
} else {
fputc(*p, stream);
}
continue;
}
if (in_string) {
fputc(*p, stream);
continue;
}
if (*p == '[' && strncmp(p, "[Function", 9) == 0) {
fprintf(stream, "%s", JSON_FUNC);
while (*p && *p != ']') fputc(*p++, stream);
if (*p == ']') fputc(*p, stream);
fprintf(stream, "%s", ANSI_RESET);
continue;
}
if (*p == '[' && strncmp(p, "[Circular", 9) == 0) {
fprintf(stream, "%s", JSON_REF);
while (*p && *p != ']') fputc(*p++, stream);
if (*p == ']') fputc(*p, stream);
fprintf(stream, "%s", ANSI_RESET);
continue;
}
if (*p == '<' && strncmp(p, "<ref", 4) == 0) {
fprintf(stream, "%s", JSON_REF);
while (*p && *p != '>') fputc(*p++, stream);
if (*p == '>') fputc(*p, stream);
fprintf(stream, "%s", ANSI_RESET);
continue;
}
if (strncmp(p, "Object [", 8) == 0) {
fprintf(stream, "%sObject [", JSON_TAG);
p += 7;
while (*p && *p != ']') fputc(*++p, stream);
fprintf(stream, "%s", ANSI_RESET);
continue;
}
if (*p == ':') {
fputc(*p, stream);
is_key = false;
continue;
}
if (*p == ',' || *p == '\n') {
fputc(*p, stream);
is_key = true;
continue;
}
if (*p == '{' || *p == '[') {
fprintf(stream, "%s%c%s", JSON_BRACE, *p, ANSI_RESET);
bracket_depth++;
is_key = true;
continue;
}
if (*p == '}' || *p == ']') {
fprintf(stream, "%s%c%s", JSON_BRACE, *p, ANSI_RESET);
bracket_depth--;
continue;
}
if (strncmp(p, "true", 4) == 0 && !isalnum((unsigned char)p[4]) && p[4] != '_') {
fprintf(stream, "%strue%s", JSON_BOOL, ANSI_RESET);
p += 3;
continue;
}
if (strncmp(p, "false", 5) == 0 && !isalnum((unsigned char)p[5]) && p[5] != '_') {
fprintf(stream, "%sfalse%s", JSON_BOOL, ANSI_RESET);
p += 4;
continue;
}
if (strncmp(p, "null", 4) == 0 && !isalnum((unsigned char)p[4]) && p[4] != '_') {
fprintf(stream, "%snull%s", JSON_NULL, ANSI_RESET);
p += 3;
continue;
}
if (strncmp(p, "undefined", 9) == 0 && !isalnum((unsigned char)p[9]) && p[9] != '_') {
fprintf(stream, "%sundefined%s", JSON_NULL, ANSI_RESET);
p += 8;
continue;
}
if (strncmp(p, "Infinity", 8) == 0 && !is_key) {
fprintf(stream, "%sInfinity%s", JSON_NUMBER, ANSI_RESET);
p += 7;
continue;
}
if (strncmp(p, "NaN", 3) == 0 && !isalnum((unsigned char)p[3]) && p[3] != '_' && !is_key) {
fprintf(stream, "%sNaN%s", JSON_NUMBER, ANSI_RESET);
p += 2;
continue;
}
if ((*p >= '0' && *p <= '9') || (*p == '-' && p[1] >= '0' && p[1] <= '9')) {
fprintf(stream, "%s", JSON_NUMBER);
if (*p == '-') fputc(*p++, stream);
while ((*p >= '0' && *p <= '9') || *p == '.' || *p == 'e' || *p == 'E' || *p == '+' || *p == '-') {
fputc(*p, stream);
if (!((p[1] >= '0' && p[1] <= '9') || p[1] == '.' || p[1] == 'e' || p[1] == 'E' || p[1] == '+' || p[1] == '-')) break;
p++;
}
fprintf(stream, "%s", ANSI_RESET);
continue;
}
if (is_key && bracket_depth > 0 && (isalpha((unsigned char)*p) || *p == '_' || *p == '$')) {
fprintf(stream, "%s", JSON_KEY);
while (isalnum((unsigned char)*p) || *p == '_' || *p == '$') {
fputc(*p, stream);
if (!(isalnum((unsigned char)p[1]) || p[1] == '_' || p[1] == '$')) break;
p++;
}
fprintf(stream, "%s", ANSI_RESET);
continue;
}
fputc(*p, stream);
}
}
static void console_print(struct js *js, jsval_t *args, int nargs, const char *color, FILE *stream) {
if (color) fprintf(stream, "%s", color);
for (int i = 0; i < nargs; i++) {
const char *space = i == 0 ? "" : " ";
fprintf(stream, "%s", space);
if (js_type(args[i]) == JS_STR) {
char *str = js_getstr(js, args[i], NULL);
fprintf(stream, "%s", str);
} else {
const char *str = js_str(js, args[i]);
if (color) fprintf(stream, "%s", ANSI_RESET);
print_value_colored(str, stream);
if (color) fprintf(stream, "%s", color);
}
}
if (color) fprintf(stream, "%s", ANSI_RESET);
fputc('\n', stream);
}
static jsval_t js_console_log(struct js *js, jsval_t *args, int nargs) {
console_print(js, args, nargs, NULL, stdout);
return js_mkundef();
}
static jsval_t js_console_error(struct js *js, jsval_t *args, int nargs) {
console_print(js, args, nargs, ANSI_RED, stderr);
return js_mkundef();
}
static jsval_t js_console_warn(struct js *js, jsval_t *args, int nargs) {
console_print(js, args, nargs, ANSI_YELLOW, stderr);
return js_mkundef();
}
static jsval_t js_console_assert(struct js *js, jsval_t *args, int nargs) {
if (nargs < 1) return js_mkundef();
bool is_truthy = js_truthy(js, args[0]);
if (is_truthy) return js_mkundef();
fprintf(stderr, "%sAssertion failed", ANSI_RED);
if (nargs > 1) {
fprintf(stderr, ": ");
for (int i = 1; i < nargs; i++) {
const char *space = i == 1 ? "" : " ";
fprintf(stderr, "%s", space);
if (js_type(args[i]) == JS_STR) {
char *str = js_getstr(js, args[i], NULL);
fprintf(stderr, "%s", str);
} else {
const char *str = js_str(js, args[i]);
fprintf(stderr, "%s", str);
}
}
}
fprintf(stderr, "%s\n", ANSI_RESET);
return js_mkundef();
}
static jsval_t js_console_trace(struct js *js, jsval_t *args, int nargs) {
fprintf(stderr, "Console Trace");
if (nargs > 0 && js_type(args[0]) == JS_STR) {
fprintf(stderr, ": ");
char *str = js_getstr(js, args[0], NULL);
fprintf(stderr, "%s", str);
}
fprintf(stderr, "\n");
js_print_stack_trace(stderr);
return js_mkundef();
}
+static jsval_t js_console_info(struct js *js, jsval_t *args, int nargs) {
+ console_print(js, args, nargs, ANSI_CYAN, stdout);
+ return js_mkundef();
+}
+
+static jsval_t js_console_debug(struct js *js, jsval_t *args, int nargs) {
+ console_print(js, args, nargs, ANSI_MAGENTA, stdout);
+ return js_mkundef();
+}
+
+static jsval_t js_console_clear(struct js *js, jsval_t *args, int nargs) {
+ (void)args;
+ (void)nargs;
+ fprintf(stdout, "\033[2J\033[H");
+ fflush(stdout);
+ return js_mkundef();
+}
+
+static struct { char *label; double start_time; } console_timers[64];
+static int console_timer_count = 0;
+
+static jsval_t js_console_time(struct js *js, jsval_t *args, int nargs) {
+ const char *label = "default";
+ if (nargs > 0 && js_type(args[0]) == JS_STR) {
+ label = js_getstr(js, args[0], NULL);
+ }
+
+ for (int i = 0; i < console_timer_count; i++) {
+ if (strcmp(console_timers[i].label, label) == 0) {
+ fprintf(stderr, "Timer '%s' already exists\n", label);
+ return js_mkundef();
+ }
+ }
+
+ if (console_timer_count < 64) {
+ console_timers[console_timer_count].label = strdup(label);
+ console_timers[console_timer_count].start_time = uv_hrtime() / 1e6;
+ console_timer_count++;
+ }
+
+ return js_mkundef();
+}
+
+static jsval_t js_console_timeEnd(struct js *js, jsval_t *args, int nargs) {
+ const char *label = "default";
+ if (nargs > 0 && js_type(args[0]) == JS_STR) {
+ label = js_getstr(js, args[0], NULL);
+ }
+
+ for (int i = 0; i < console_timer_count; i++) {
+ if (strcmp(console_timers[i].label, label) == 0) {
+ double elapsed = (uv_hrtime() / 1e6) - console_timers[i].start_time;
+ fprintf(stdout, "%s: %.3fms\n", label, elapsed);
+ free(console_timers[i].label);
+ for (int j = i; j < console_timer_count - 1; j++) {
+ console_timers[j] = console_timers[j + 1];
+ }
+ console_timer_count--;
+ return js_mkundef();
+ }
+ }
+
+ fprintf(stderr, "Timer '%s' does not exist\n", label);
+ return js_mkundef();
+}
+
void init_console_module() {
struct js *js = rt->js;
jsval_t console_obj = js_mkobj(js);
js_set(js, console_obj, "log", js_mkfun(js_console_log));
js_set(js, console_obj, "error", js_mkfun(js_console_error));
js_set(js, console_obj, "warn", js_mkfun(js_console_warn));
+ js_set(js, console_obj, "info", js_mkfun(js_console_info));
+ js_set(js, console_obj, "debug", js_mkfun(js_console_debug));
js_set(js, console_obj, "assert", js_mkfun(js_console_assert));
js_set(js, console_obj, "trace", js_mkfun(js_console_trace));
+ js_set(js, console_obj, "time", js_mkfun(js_console_time));
+ js_set(js, console_obj, "timeEnd", js_mkfun(js_console_timeEnd));
+ js_set(js, console_obj, "clear", js_mkfun(js_console_clear));
js_set(js, console_obj, "@@toStringTag", js_mkstr(js, "console", 7));
js_set(js, js_glob(js), "console", console_obj);
}
\ No newline at end of file

File Metadata

Mime Type
text/x-diff
Expires
Wed, Jun 17, 1:07 PM (1 d, 16 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
575374
Default Alt Text
(14 KB)

Event Timeline