Files
noom/src/main.c
2026-05-26 18:25:10 +03:00

265 lines
7.0 KiB
C

#include <stdio.h> // for now
#include "helper.h"
#include "error.h"
#include "types.h"
void tab(noom_uint_t amount) {
amount *= 2;
for (noom_uint_t i = 0; i < amount; i++) {
putchar(' ');
}
}
void print_node(const noomP_Node *node, noom_uint_t depth) {
tab(depth);
printf("{\n");
tab(depth + 1);
printf("type: %s\n", noomP_formatNodeType(node->type));
tab(depth + 1);
printf("location: %lld\n", node->source_offset);
tab(depth + 1);
printf("subnodes:\n");
for (noom_uint_t i = 0; i < node->subnodec; i++) {
print_node(node->subnodes[i], depth + 1);
}
tab(depth);
printf("}\n");
}
int the_theoretical_function_to_execute_your_code_that_should_be_replaced_later(const char *code, const char *filename) {
noomP_Parser parser;
noomP_Node *program;
// goodbye "shitass" you will be missed
int success = noomP_parse(code, filename, NOOM_VERSION_54, &program, &parser);
if (success == 0) {
puts("LEX OUTPUT:");
fputs("\x1b[48;2;10;10;10m", stdout);
noom_uint_t pos = 0;
while (1) {
noomL_Token token;
noomL_ErrorType err = noomL_lex(code, pos, &token, NOOM_VERSION_54);
if (err) break;
if (token.type == NOOML_TOKEN_KEYWORD) {
fputs("\x1b[38;2;207;142;109m", stdout);
for (noom_uint_t i = 0; i < token.length; i++) putchar((code + token.offset)[i]);
} else if (token.type == NOOML_TOKEN_WHITESPACE) {
for (noom_uint_t i = 0; i < token.length; i++) putchar((code + token.offset)[i]);
} else if (token.type == NOOML_TOKEN_IDENTIFIER) {
fputs("\x1b[38;2;255;255;255m", stdout);
for (noom_uint_t i = 0; i < token.length; i++) putchar((code + token.offset)[i]);
} else if (token.type == NOOML_TOKEN_SYMBOL) {
fputs("\x1b[38;2;0;255;255m", stdout);
for (noom_uint_t i = 0; i < token.length; i++) putchar((code + token.offset)[i]);
} else if (token.type == NOOML_TOKEN_STRING) {
fputs("\x1b[38;2;255;0;0m", stdout);
for (noom_uint_t i = 0; i < token.length; i++) putchar((code + token.offset)[i]);
} else if (token.type == NOOML_TOKEN_NUMBER) {
fputs("\x1b[38;2;0;255;0m", stdout);
for (noom_uint_t i = 0; i < token.length; i++) putchar((code + token.offset)[i]);
} else {
fputs("\x1b[0m\n", stdout);
printf("%s ", noomL_formatTokenType(token.type));
for (noom_uint_t i = 0; i < token.length; i++) putchar((code + token.offset)[i]);
fputs("\x1b[48;2;10;10;10m", stdout);
putchar('\n');
}
pos += token.length;
if (token.type == NOOML_TOKEN_EOF) break;
}
puts("\x1b[0m");
puts("PARSE OUTPUT:");
print_node(program, 0);
}
else {
noom_uint_t bleh = noom_format_error(&parser, NULL, 0);
char* buf = noom_alloc(bleh);
noom_format_error(&parser, buf, bleh);
fputs(buf, stdout);
noom_free(buf);
}
// freeing time
noomP_Node *last_node = parser.last_node;
while (last_node) {
noomP_Node *next = last_node->previous_node;
// subnodes could be null if we OOM'd during a realloc of it
if (last_node->subnodes) noom_free(last_node->subnodes);
noom_free(last_node);
last_node = next;
}
return success;
}
static char* read_file(const char* filename) {
FILE* file = fopen(filename, "r");
if (file == 0) {
fprintf(stderr, "Failed to open '%s'.\n", filename);
return 0;
}
fseek(file, 0, SEEK_END);
const unsigned long filesize = ftell(file);
fseek(file, 0, SEEK_SET);
char* buffer = noom_alloc(filesize + 1);
if (fread(buffer, 1, filesize, file) != filesize) {
fprintf(stderr, "Reached the end of the file\n");
return 0;
}
buffer[filesize] = '\0';
fclose(file);
return buffer;
}
static char* read_stdin() {
noom_uint_t capacity = 4096;
noom_uint_t size = 0;
char* buffer = noom_alloc(capacity);
size_t n;
while ((n = fread(buffer + size, 1, capacity - size, stdin)) > 0) {
size += n;
if (size == capacity) {
capacity *= 2;
buffer = noom_realloc(buffer, capacity);
}
}
buffer[size] = '\0';
return buffer;
}
// code stolen from my different project
static int read_prompt(char* buf, int buf_size, char* prompt, const int required) {
do {
printf("%s", prompt);
if (!fgets(buf, buf_size, stdin)) return 1;
const size_t len = noom_strlen(buf);
if (len > 0 && buf[len - 1] != '\n') {
while (getchar() != '\n' && !feof(stdin)) ;
}
else if (len > 0) {
buf[len - 1] = '\0';
}
} while (buf[0] == '\0' && required);
return 0;
}
int main(int argc, char **argv) {
const char *err = 0;
struct {
noom_bool_t enter_repl;
noom_bool_t use_stdin;
const char* script_exec;
const char* script_path;
noom_bool_t do_i_already_know_what_to_do;
} params = {0};
if (argc < 2) {
params.enter_repl = 1;
params.do_i_already_know_what_to_do = 1;
}
for (int i = 1; i < argc; i++) {
if (noom_strcmp(argv[i], "-") == 0) {
params.use_stdin = 1;
params.do_i_already_know_what_to_do = 1;
continue;
}
if (noom_strcmp(argv[i], "--") == 0) {
if (++i >= argc) break;
if (params.do_i_already_know_what_to_do) {
err = "too many arguments";
goto die;
}
params.script_exec = argv[i];
params.do_i_already_know_what_to_do = 1;
continue;
}
if (argv[i][0] != '-') {
if (params.do_i_already_know_what_to_do) {
err = "too many arguments";
goto die;
}
params.script_path = argv[i];
params.do_i_already_know_what_to_do = 1;
continue;
}
if (argv[i][1] == 'e') {
if (params.do_i_already_know_what_to_do) {
goto die;
}
/* "-estat" or "-e stat" */
if (argv[i][2] != '\0') {
params.script_exec = argv[i] + 2;
params.do_i_already_know_what_to_do = 1;
continue;
}
if (++i >= argc) {
err = "-e needs an argument";
goto die;
}
params.script_exec = argv[i];
params.do_i_already_know_what_to_do = 1;
}
if (argv[i][1] == 'v') {
puts(NOOM_VERSION_TEXT);
return 0;
}
err = "unknown option";
goto die;
}
if (!params.do_i_already_know_what_to_do) {
err = "script not set";
goto die;
}
if (params.script_exec || params.script_path) {
if (params.script_exec) {
return the_theoretical_function_to_execute_your_code_that_should_be_replaced_later(params.script_exec, "(command line)");
}
char* code = read_file(params.script_path);
if (code == 0) return 1;
return the_theoretical_function_to_execute_your_code_that_should_be_replaced_later(code, params.script_path);
}
if (params.use_stdin) {
char* code = read_stdin();
if (code == 0) return 1;
return the_theoretical_function_to_execute_your_code_that_should_be_replaced_later(code, "stdin");
}
if (params.enter_repl) {
puts(NOOM_VERSION_TEXT);
for (;;) {
char code[4096];
if (read_prompt(code, sizeof(code), "> ", 1)) return 0;
the_theoretical_function_to_execute_your_code_that_should_be_replaced_later(code, "(noom input)");
}
}
die:
fprintf(stderr, "%s: %s\n"
"usage: %s [options] [script [args]]\n"
"Available options are:\n"
" - execute stdin\n"
" -e stat execute string 'stat'\n"
" -v show version\n",
argv[0], err, argv[0]);
return 1;
}