parent
3aa911a1ad
commit
64040259cb
@ -0,0 +1,5 @@ |
|||||||
|
*.a |
||||||
|
*.o |
||||||
|
aoc.c |
||||||
|
wren_aoc |
||||||
|
wren.h |
@ -0,0 +1,24 @@ |
|||||||
|
var CC: 'gcc' |
||||||
|
var CFLAGS: '-Wall', '-Wextra', '-Werror' |
||||||
|
var LDFLAGS: '-lm' |
||||||
|
|
||||||
|
with public default target 'all' |
||||||
|
\depends 'wren_aoc' |
||||||
|
|
||||||
|
with public target 'wren_aoc' |
||||||
|
\depends 'main.o', 'aoc.o', 'libwren.a' |
||||||
|
\produces '%' |
||||||
|
\fn => _.cmd CC, CFLAGS, @infiles, '-o', @outfile, LDFLAGS |
||||||
|
|
||||||
|
with target {'main.o', 'aoc.o'}, pattern: '%.o' |
||||||
|
\depends '%.c' |
||||||
|
\produces '%.o' |
||||||
|
\fn => _.cmd CC, CFLAGS, @infile, '-o', @outfile, '-c' |
||||||
|
|
||||||
|
with target 'aoc.c' |
||||||
|
\depends 'aoc.wren' |
||||||
|
\produces '%' |
||||||
|
\fn => |
||||||
|
code = _.readfile @infile |
||||||
|
c_code = "extern const char* aoc_mod = \"#{code\gsub('"', '\\"')\gsub('\n', '\\n')}\";\n" |
||||||
|
_.writefile @outfile, c_code |
@ -0,0 +1,3 @@ |
|||||||
|
class AoC { |
||||||
|
foreign static input |
||||||
|
} |
@ -0,0 +1,117 @@ |
|||||||
|
#include <stdio.h> |
||||||
|
#include <string.h> |
||||||
|
#include <stdlib.h> |
||||||
|
|
||||||
|
#include "wren.h" |
||||||
|
|
||||||
|
extern char* aoc_mod; |
||||||
|
|
||||||
|
char* read_file(const char* path) { |
||||||
|
FILE* fp = fopen(path, "rb"); |
||||||
|
if(fp == NULL) return NULL; |
||||||
|
|
||||||
|
fseek(fp, 0, SEEK_END); |
||||||
|
size_t len = ftell(fp); |
||||||
|
fseek(fp, 0, SEEK_SET); |
||||||
|
|
||||||
|
char* out = calloc(len + 1, 1); |
||||||
|
if(out == NULL) { |
||||||
|
fclose(fp); |
||||||
|
return NULL; |
||||||
|
} |
||||||
|
|
||||||
|
if(len != fread(out, 1, len, fp)) { |
||||||
|
fclose(fp); |
||||||
|
free(out); |
||||||
|
return NULL; |
||||||
|
} |
||||||
|
|
||||||
|
fclose(fp); |
||||||
|
return out; |
||||||
|
} |
||||||
|
|
||||||
|
void writeFn(WrenVM* vm, const char* text) { |
||||||
|
(void)(vm); |
||||||
|
printf("%s", text); |
||||||
|
} |
||||||
|
|
||||||
|
void errorFn(WrenVM* vm, WrenErrorType errorType, const char* module, const int line, const char* msg) { |
||||||
|
(void)(vm); |
||||||
|
switch (errorType) { |
||||||
|
case WREN_ERROR_COMPILE: |
||||||
|
printf("[%s line %d] [Error] %s\n", module, line, msg); |
||||||
|
break; |
||||||
|
case WREN_ERROR_STACK_TRACE: |
||||||
|
printf("[%s line %d] in %s\n", module, line, msg); |
||||||
|
break; |
||||||
|
case WREN_ERROR_RUNTIME: |
||||||
|
printf("[Runtime Error] %s\n", msg); |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void load_input(WrenVM* vm) { |
||||||
|
char* data = read_file("input.txt"); |
||||||
|
if(data != NULL) { |
||||||
|
wrenSetSlotString(vm, 0, data); |
||||||
|
free(data); |
||||||
|
} else { |
||||||
|
wrenSetSlotNull(vm, 0); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
WrenForeignMethodFn bindForeignMethodFn(WrenVM* vm, const char* module, const char* className, bool isStatic, const char* signature) { |
||||||
|
(void)(vm); |
||||||
|
if(!strcmp(module, "aoc") && !strcmp(className, "AoC") && isStatic && !strcmp(signature, "input")) { |
||||||
|
return &load_input; |
||||||
|
} |
||||||
|
return NULL; |
||||||
|
} |
||||||
|
|
||||||
|
WrenLoadModuleResult loadModuleFn(WrenVM* vm, const char* name) { |
||||||
|
(void)(vm); |
||||||
|
WrenLoadModuleResult result = {0}; |
||||||
|
if(!strcmp(name, "aoc")) { |
||||||
|
result.source = aoc_mod; |
||||||
|
} |
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
int main(int argc, char** argv) { |
||||||
|
(void)(argc); |
||||||
|
int exit_code = 0; |
||||||
|
|
||||||
|
if(argv[1] == NULL) { |
||||||
|
fprintf(stderr, "Syntax: %s <FILE>\n", argv[0]); |
||||||
|
return 1; |
||||||
|
} |
||||||
|
|
||||||
|
char* code = read_file(argv[1]); |
||||||
|
if(code == NULL) { |
||||||
|
fprintf(stderr, "Couldn't load file\n"); |
||||||
|
return 1; |
||||||
|
} |
||||||
|
|
||||||
|
WrenConfiguration config; |
||||||
|
wrenInitConfiguration(&config); |
||||||
|
|
||||||
|
config.writeFn = &writeFn; |
||||||
|
config.errorFn = &errorFn; |
||||||
|
config.loadModuleFn = &loadModuleFn; |
||||||
|
config.bindForeignMethodFn = &bindForeignMethodFn; |
||||||
|
|
||||||
|
WrenVM* vm = wrenNewVM(&config); |
||||||
|
WrenInterpretResult result = wrenInterpret(vm, "main", code); |
||||||
|
free(code); |
||||||
|
|
||||||
|
if(result == WREN_RESULT_COMPILE_ERROR) { |
||||||
|
fprintf(stderr, "Wren exited with compile error\n"); |
||||||
|
exit_code = 1; |
||||||
|
} else if(result == WREN_RESULT_RUNTIME_ERROR) { |
||||||
|
fprintf(stderr, "Wren exited with runtime error\n"); |
||||||
|
exit_code = 1; |
||||||
|
} |
||||||
|
|
||||||
|
wrenFreeVM(vm); |
||||||
|
return exit_code; |
||||||
|
} |
Loading…
Reference in new issue