Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F7538870
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
14 KB
Referenced Files
None
Subscribers
None
View Options
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
Details
Attached
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)
Attached To
Mode
rANT Ant
Attached
Detach File
Event Timeline
Log In to Comment