stuff
This commit is contained in:
141
src/Bytecode/load.c
Normal file
141
src/Bytecode/load.c
Normal file
@@ -0,0 +1,141 @@
|
||||
#include "../../include/ground.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
static GroundValue readValue(FILE* f) {
|
||||
GroundValue v = {0};
|
||||
uint8_t tag;
|
||||
if (fread(&tag, 1, 1, f) != 1) {
|
||||
Ground.Log.Error("failed to read value type in Ground.Bytecode.load");
|
||||
Ground.Flags.error = true;
|
||||
return v;
|
||||
}
|
||||
|
||||
switch (tag) {
|
||||
case 0: {
|
||||
v.type.type = GroundType_Int;
|
||||
fread(&v.as.Int, 8, 1, f);
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
v.type.type = GroundType_Double;
|
||||
fread(&v.as.Double, 8, 1, f);
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
v.type.type = GroundType_Char;
|
||||
fread(&v.as.Char, 1, 1, f);
|
||||
break;
|
||||
}
|
||||
case 3: {
|
||||
v.type.type = GroundType_Bool;
|
||||
fread(&v.as.Bool, 1, 1, f);
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
v.type.type = GroundType_String;
|
||||
uint64_t len;
|
||||
fread(&len, 8, 1, f);
|
||||
v.as.String.cstr = malloc(len + 1);
|
||||
if (v.as.String.cstr == NULL) {
|
||||
Ground.Log.Error("malloc failed in Ground.Bytecode.load");
|
||||
Ground.Flags.error = true;
|
||||
return v;
|
||||
}
|
||||
fread(v.as.String.cstr, 1, len, f);
|
||||
v.as.String.cstr[len] = '\0';
|
||||
v.as.String.len = len;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
Ground.Log.Error("unknown value type in Ground.Bytecode.load");
|
||||
Ground.Flags.error = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
GroundBytecode _GroundBytecodeLoad(const char* path) {
|
||||
GroundBytecode bc = {0};
|
||||
|
||||
FILE* f = fopen(path, "rb");
|
||||
if (f == NULL) {
|
||||
Ground.Log.Error("failed to open file for reading in Ground.Bytecode.load");
|
||||
Ground.Flags.error = true;
|
||||
return bc;
|
||||
}
|
||||
|
||||
char magic[8];
|
||||
memset(magic, 0, 8);
|
||||
if (fread(magic, 7, 1, f) != 1 || memcmp(magic, "GRNDbc", 6) != 0) {
|
||||
Ground.Log.Error("bad magic in Ground.Bytecode.load");
|
||||
Ground.Flags.error = true;
|
||||
fclose(f);
|
||||
return bc;
|
||||
}
|
||||
|
||||
uint32_t version;
|
||||
fread(&version, 4, 1, f);
|
||||
|
||||
uint64_t count;
|
||||
fread(&count, 8, 1, f);
|
||||
if (count > 0) {
|
||||
bc.heap.heap = malloc(sizeof(GroundValue) * count);
|
||||
if (bc.heap.heap == NULL) {
|
||||
Ground.Log.Error("malloc failed in Ground.Bytecode.load");
|
||||
Ground.Flags.error = true;
|
||||
fclose(f);
|
||||
return bc;
|
||||
}
|
||||
for (uint64_t i = 0; i < count; i++) {
|
||||
bc.heap.heap[i] = readValue(f);
|
||||
if (Ground.Flags.error) {
|
||||
fclose(f);
|
||||
return bc;
|
||||
}
|
||||
}
|
||||
bc.heap.capacity = count;
|
||||
bc.heap.len = count;
|
||||
}
|
||||
|
||||
fread(&count, 8, 1, f);
|
||||
if (count > 0) {
|
||||
bc.program.at = malloc(sizeof(GroundBytecodeInstruction) * count);
|
||||
if (bc.program.at == NULL) {
|
||||
Ground.Log.Error("malloc failed in Ground.Bytecode.load");
|
||||
Ground.Flags.error = true;
|
||||
fclose(f);
|
||||
return bc;
|
||||
}
|
||||
bc.program.capacity = count;
|
||||
bc.program.len = count;
|
||||
|
||||
for (uint64_t i = 0; i < count; i++) {
|
||||
uint8_t type;
|
||||
fread(&type, 1, 1, f);
|
||||
bc.program.at[i].type = (enum GroundInstructionType)type;
|
||||
|
||||
uint64_t argCount;
|
||||
fread(&argCount, 8, 1, f);
|
||||
if (argCount > 0) {
|
||||
bc.program.at[i].args.at = malloc(sizeof(GroundSize) * argCount);
|
||||
if (bc.program.at[i].args.at == NULL) {
|
||||
Ground.Log.Error("malloc failed in Ground.Bytecode.load");
|
||||
Ground.Flags.error = true;
|
||||
fclose(f);
|
||||
return bc;
|
||||
}
|
||||
fread(bc.program.at[i].args.at, sizeof(GroundSize), argCount, f);
|
||||
} else {
|
||||
bc.program.at[i].args.at = NULL;
|
||||
}
|
||||
bc.program.at[i].args.len = argCount;
|
||||
bc.program.at[i].args.capacity = argCount;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
return bc;
|
||||
}
|
||||
Reference in New Issue
Block a user