Files
armorpaint/base/sources/libs/kong/kong.c
T
luboslenco 8b4284f8dd Update kong
2025-04-11 10:06:07 +02:00

346 lines
7.2 KiB
C

#include "analyzer.h"
#include "compiler.h"
#include "disasm.h"
#include "errors.h"
#include "functions.h"
#include "globals.h"
#include "log.h"
#include "names.h"
#include "parser.h"
#include "tokenizer.h"
#include "transformer.h"
#include "typer.h"
#include "types.h"
#include "backends/cpu.h"
#include "backends/glsl.h"
#include "backends/hlsl.h"
#include "backends/metal.h"
#include "backends/spirv.h"
#include "backends/wgsl.h"
#include "integrations/kore3.h"
#include "dir.h"
#include <assert.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef enum arg_mode { MODE_MODECHECK, MODE_INPUT, MODE_OUTPUT, MODE_PLATFORM, MODE_API, MODE_INTEGRATION } arg_mode;
static void help(void) {
printf("No help is coming.");
}
static void read_file(char *filename) {
FILE *file = fopen(filename, "rb");
if (file == NULL) {
kong_log(LOG_LEVEL_ERROR, "File %s not found.", filename);
exit(1);
}
fseek(file, 0, SEEK_END);
size_t size = ftell(file);
fseek(file, 0, SEEK_SET);
char *data = (char *)malloc(size + 1);
debug_context context = {0};
context.filename = filename;
check(data != NULL, context, "Could not allocate memory to read file %s", filename);
fread(data, 1, size, file);
data[size] = 0;
fclose(file);
tokens tokens = tokenize(filename, data);
free(data);
parse(filename, &tokens);
}
typedef enum integration_kind { INTEGRATION_KORE3 } integration_kind;
////
/*
int main(int argc, char **argv) {
arg_mode mode = MODE_MODECHECK;
char *inputs[256] = {0};
size_t inputs_size = 0;
char *platform = NULL;
api_kind api = API_DEFAULT;
integration_kind integration = INTEGRATION_KORE3;
bool debug = false;
char *output = NULL;
for (int i = 1; i < argc; ++i) {
char *arg = argv[i];
switch (mode) {
case MODE_MODECHECK: {
if (arg[0] == '-') {
if (arg[1] == '-') {
if (strcmp(&arg[2], "in") == 0) {
mode = MODE_INPUT;
}
else if (strcmp(&arg[2], "out") == 0) {
mode = MODE_OUTPUT;
}
else if (strcmp(&arg[2], "platform") == 0) {
mode = MODE_PLATFORM;
}
else if (strcmp(&arg[2], "api") == 0) {
mode = MODE_API;
}
else if (strcmp(&arg[2], "integration") == 0) {
mode = MODE_INTEGRATION;
}
else if (strcmp(&arg[2], "debug") == 0) {
debug = true;
}
else if (strcmp(&arg[2], "help") == 0) {
help();
return 0;
}
else {
kong_log(LOG_LEVEL_WARNING, "Ignoring unknown parameter %s", arg);
}
}
else {
bool ok = true;
if (arg[1] == 0) {
kong_log(LOG_LEVEL_WARNING, "Ignoring lonely -.");
ok = false;
}
if (arg[2] != 0) {
kong_log(LOG_LEVEL_WARNING, "Ignoring parameter %s because the format is not right (one - implies just one letter).", arg);
ok = false;
}
if (ok) {
switch (arg[1]) {
case 'i':
mode = MODE_INPUT;
break;
case 'o':
mode = MODE_OUTPUT;
break;
case 'p':
mode = MODE_PLATFORM;
break;
case 'a':
mode = MODE_API;
break;
case 'n':
mode = MODE_INTEGRATION;
break;
case 'h':
help();
return 0;
default: {
kong_log(LOG_LEVEL_WARNING, "Ignoring unknown parameter %s.", arg);
}
}
}
}
}
else {
kong_log(LOG_LEVEL_WARNING, "Ignoring parameter %s because the syntax is off.", arg);
}
break;
}
case MODE_INPUT: {
inputs[inputs_size] = arg;
inputs_size += 1;
mode = MODE_MODECHECK;
break;
}
case MODE_OUTPUT: {
output = arg;
mode = MODE_MODECHECK;
break;
}
case MODE_PLATFORM: {
platform = arg;
mode = MODE_MODECHECK;
break;
}
case MODE_API: {
if (strcmp(arg, "direct3d11") == 0) {
api = API_DIRECT3D11;
}
else if (strcmp(arg, "direct3d12") == 0) {
api = API_DIRECT3D12;
}
else if (strcmp(arg, "opengl") == 0) {
api = API_OPENGL;
}
else if (strcmp(arg, "metal") == 0) {
api = API_METAL;
}
else if (strcmp(arg, "webgpu") == 0) {
api = API_WEBGPU;
}
else if (strcmp(arg, "vulkan") == 0) {
api = API_VULKAN;
}
else if (strcmp(arg, "default") == 0) {
api = API_DEFAULT;
}
else {
debug_context context = {0};
error(context, "Unknown API %s", arg);
}
mode = MODE_MODECHECK;
break;
}
case MODE_INTEGRATION: {
if (strcmp(arg, "kore3") == 0) {
integration = INTEGRATION_KORE3;
}
else {
debug_context context = {0};
error(context, "Unknown integration %s", arg);
}
mode = MODE_MODECHECK;
break;
}
}
}
debug_context context = {0};
check(platform != NULL, context, "platform parameter not found");
if (api == API_DEFAULT) {
if (strcmp(platform, "windows") == 0) {
api = API_DIRECT3D12;
}
else if (strcmp(platform, "macos") == 0) {
api = API_METAL;
}
else if (strcmp(platform, "linux") == 0) {
api = API_VULKAN;
}
else if (strcmp(platform, "ios") == 0) {
api = API_METAL;
}
else if (strcmp(platform, "android") == 0) {
api = API_VULKAN;
}
else if (strcmp(platform, "wasm") == 0) {
api = API_WEBGPU;
}
}
check(mode == MODE_MODECHECK, context, "Wrong parameter syntax");
check(inputs_size > 0, context, "no input parameters found");
check(output != NULL, context, "output parameter not found");
check(api != API_DEFAULT, context, "api parameter not found");
names_init();
types_init();
functions_init();
globals_init();
for (size_t i = 0; i < inputs_size; ++i) {
directory dir = open_dir(inputs[i]);
file f = read_next_file(&dir);
while (f.valid) {
char path[1024];
strcpy(path, inputs[i]);
strcat(path, "/");
strcat(path, f.name);
size_t length = strlen(path);
size_t dotkong_length = strlen(".kong");
if (length > dotkong_length && strcmp(&path[length - dotkong_length], ".kong") == 0) {
read_file(path);
}
f = read_next_file(&dir);
}
close_dir(&dir);
}
#ifndef NDEBUG
kong_log(LOG_LEVEL_INFO, "Functions:");
for (function_id i = 0; get_function(i) != NULL; ++i) {
kong_log(LOG_LEVEL_INFO, "%s", get_name(get_function(i)->name));
}
kong_log(LOG_LEVEL_INFO, "");
kong_log(LOG_LEVEL_INFO, "Types:");
for (type_id i = 0; get_type(i) != NULL; ++i) {
kong_log(LOG_LEVEL_INFO, "%s (%i)", get_name(get_type(i)->name), i);
}
kong_log(LOG_LEVEL_INFO, "");
#endif
resolve_types();
allocate_globals();
for (function_id i = 0; get_function(i) != NULL; ++i) {
compile_function_block(&get_function(i)->code, get_function(i)->block);
}
analyze();
switch (api) {
case API_VULKAN:
transform(TRANSFORM_FLAG_ONE_COMPONENT_SWIZZLE);
break;
}
#ifndef NDEBUG
disassemble();
#endif
switch (api) {
case API_DIRECT3D11:
case API_DIRECT3D12:
hlsl_export(output, api, debug);
break;
case API_OPENGL:
glsl_export(output);
break;
case API_METAL:
metal_export(output);
break;
case API_WEBGPU:
wgsl_export(output);
break;
case API_VULKAN: {
spirv_export(output, debug);
break;
}
default: {
debug_context context = {0};
error(context, "Unknown API");
}
}
cpu_export(output);
switch (integration) {
case INTEGRATION_KORE3:
kore3_export(output, api);
break;
}
return 0;
}
*/
////