function calling works in theory (can't test yet)
This commit is contained in:
@@ -336,6 +336,23 @@ struct GroundBytecode {
|
|||||||
GroundBytecodeHeap heap;
|
GroundBytecodeHeap heap;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// --- Internal Ground components, avoid use outside of Ground ---
|
||||||
|
|
||||||
|
enum GroundExecutionResultType {
|
||||||
|
_GER_CONTINUE, _GER_JUMP, _GER_RETURN, _GER_END
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GroundExecutionResult {
|
||||||
|
enum GroundExecutionResultType type;
|
||||||
|
union {
|
||||||
|
GroundBytecodeValue value;
|
||||||
|
GroundSize line;
|
||||||
|
GroundInt end;
|
||||||
|
} as;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// INTERFACE
|
// INTERFACE
|
||||||
//
|
//
|
||||||
@@ -428,6 +445,8 @@ struct _Ground {
|
|||||||
GroundState (*State) (GroundState* in);
|
GroundState (*State) (GroundState* in);
|
||||||
|
|
||||||
GroundIdentifier* (*Identifier) (GroundIdentifier* in);
|
GroundIdentifier* (*Identifier) (GroundIdentifier* in);
|
||||||
|
|
||||||
|
GroundBytecodeValue (*BytecodeValue) (GroundBytecodeValue* in);
|
||||||
} Copy;
|
} Copy;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
@@ -481,11 +500,11 @@ struct _Ground {
|
|||||||
void (*save) (GroundBytecode* bytecode, const char* path);
|
void (*save) (GroundBytecode* bytecode, const char* path);
|
||||||
GroundBytecode (*load) (const char* path);
|
GroundBytecode (*load) (const char* path);
|
||||||
struct {
|
struct {
|
||||||
void (*execute) (GroundBytecodeProgram* program, GroundBytecodeHeap* heap);
|
GroundBytecodeValue (*execute) (GroundBytecodeProgram* program, GroundBytecodeHeap* heap);
|
||||||
void (*optimise) (GroundBytecodeProgram* program);
|
void (*optimise) (GroundBytecodeProgram* program);
|
||||||
} Program;
|
} Program;
|
||||||
struct {
|
struct {
|
||||||
int64_t (*execute) (GroundBytecodeInstruction* instruction, GroundBytecodeHeap* heap);
|
struct GroundExecutionResult (*execute) (GroundBytecodeInstruction* instruction, GroundBytecodeHeap* heap);
|
||||||
} Instruction;
|
} Instruction;
|
||||||
struct {
|
struct {
|
||||||
void (*set) (GroundBytecodeHeap* heap, GroundSize idx, GroundValue value);
|
void (*set) (GroundBytecodeHeap* heap, GroundSize idx, GroundValue value);
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ sources = files(
|
|||||||
|
|
||||||
'src/Copy/Identifier.c',
|
'src/Copy/Identifier.c',
|
||||||
|
|
||||||
|
'src/Copy/BytecodeValue.c',
|
||||||
|
|
||||||
'src/Free/Function.c',
|
'src/Free/Function.c',
|
||||||
'src/Free/List.c',
|
'src/Free/List.c',
|
||||||
'src/Free/Object.c',
|
'src/Free/Object.c',
|
||||||
|
|||||||
@@ -9,6 +9,11 @@
|
|||||||
#define HEAP_GET(heap, idx) (&(heap)->heap[(idx)])
|
#define HEAP_GET(heap, idx) (&(heap)->heap[(idx)])
|
||||||
#define HEAP_SET(heap, idx, val) ((heap)->heap[(idx)] = (val))
|
#define HEAP_SET(heap, idx, val) ((heap)->heap[(idx)] = (val))
|
||||||
|
|
||||||
|
#define CONTINUE (struct GroundExecutionResult) { _GER_CONTINUE }
|
||||||
|
#define JUMP(idx) (struct GroundExecutionResult) { .type = _GER_JUMP, .as.line = idx }
|
||||||
|
#define END(res) (struct GroundExecutionResult) { .type = _GER_END, .as.end = res }
|
||||||
|
#define RETURN(val) (struct GroundExecutionResult) { .type = _GER_RETURN, .as.value = val }
|
||||||
|
|
||||||
static void printValue(GroundBytecodeValue* val) {
|
static void printValue(GroundBytecodeValue* val) {
|
||||||
switch (val->type.type) {
|
switch (val->type.type) {
|
||||||
case GroundType_Int:
|
case GroundType_Int:
|
||||||
@@ -32,7 +37,7 @@ static void printValue(GroundBytecodeValue* val) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction, GroundBytecodeHeap* heap) {
|
struct GroundExecutionResult _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction, GroundBytecodeHeap* heap) {
|
||||||
|
|
||||||
static const void* jumpTable[] = {
|
static const void* jumpTable[] = {
|
||||||
&&IF, &&JUMP, &&END,
|
&&IF, &&JUMP, &&END,
|
||||||
@@ -55,67 +60,67 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
|
|||||||
IF: {
|
IF: {
|
||||||
GroundBytecodeValue* cond = HEAP_GET(heap, instruction->args.at[0]);
|
GroundBytecodeValue* cond = HEAP_GET(heap, instruction->args.at[0]);
|
||||||
if (cond->as.Bool) {
|
if (cond->as.Bool) {
|
||||||
return instruction->args.at[1];
|
return JUMP(instruction->args.at[1]);
|
||||||
}
|
}
|
||||||
return -1;
|
return CONTINUE;
|
||||||
}
|
}
|
||||||
JUMP: {
|
JUMP: {
|
||||||
return instruction->args.at[0];
|
return JUMP(instruction->args.at[0]);
|
||||||
}
|
}
|
||||||
END: {
|
END: {
|
||||||
return -2;
|
return END( HEAP_GET(heap, instruction->args.at[0])->as.Int );
|
||||||
}
|
}
|
||||||
INPUT: {
|
INPUT: {
|
||||||
char* input = linenoise("");
|
char* input = linenoise("");
|
||||||
HEAP_SET(heap, instruction->args.at[0], Ground.New.BytecodeValue(Ground.New.Value.String(Ground.New.String(input))));
|
HEAP_SET(heap, instruction->args.at[0], Ground.New.BytecodeValue(Ground.New.Value.String(Ground.New.String(input))));
|
||||||
free(input);
|
free(input);
|
||||||
return -1;
|
return CONTINUE;
|
||||||
}
|
}
|
||||||
PRINT: {
|
PRINT: {
|
||||||
for (GroundSize i = 0; i < instruction->args.len; i++) {
|
for (GroundSize i = 0; i < instruction->args.len; i++) {
|
||||||
printValue(HEAP_GET(heap, instruction->args.at[i]));
|
printValue(HEAP_GET(heap, instruction->args.at[i]));
|
||||||
}
|
}
|
||||||
return -1;
|
return CONTINUE;
|
||||||
}
|
}
|
||||||
PRINTLN: {
|
PRINTLN: {
|
||||||
for (GroundSize i = 0; i < instruction->args.len; i++) {
|
for (GroundSize i = 0; i < instruction->args.len; i++) {
|
||||||
printValue(HEAP_GET(heap, instruction->args.at[i]));
|
printValue(HEAP_GET(heap, instruction->args.at[i]));
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
return -1;
|
return CONTINUE;
|
||||||
}
|
}
|
||||||
SET: {
|
SET: {
|
||||||
HEAP_SET(heap, instruction->args.at[0], *HEAP_GET(heap, instruction->args.at[1]));
|
HEAP_SET(heap, instruction->args.at[0], *HEAP_GET(heap, instruction->args.at[1]));
|
||||||
return -1;
|
return CONTINUE;
|
||||||
}
|
}
|
||||||
GETTYPE: {
|
GETTYPE: {
|
||||||
Ground.Log.Warning("GETTYPE is deprecated");
|
Ground.Log.Warning("GETTYPE is deprecated");
|
||||||
return -1;
|
return CONTINUE;
|
||||||
}
|
}
|
||||||
EXISTS: {
|
EXISTS: {
|
||||||
Ground.Log.Warning("EXISTS is deprecated");
|
Ground.Log.Warning("EXISTS is deprecated");
|
||||||
return -1;
|
return CONTINUE;
|
||||||
}
|
}
|
||||||
SETLIST: {
|
SETLIST: {
|
||||||
return -1;
|
return CONTINUE;
|
||||||
}
|
}
|
||||||
SETLISTAT: {
|
SETLISTAT: {
|
||||||
return -1;
|
return CONTINUE;
|
||||||
}
|
}
|
||||||
GETLISTAT: {
|
GETLISTAT: {
|
||||||
return -1;
|
return CONTINUE;
|
||||||
}
|
}
|
||||||
GETLISTSIZE: {
|
GETLISTSIZE: {
|
||||||
return -1;
|
return CONTINUE;
|
||||||
}
|
}
|
||||||
LISTAPPEND: {
|
LISTAPPEND: {
|
||||||
return -1;
|
return CONTINUE;
|
||||||
}
|
}
|
||||||
GETSTRSIZE: {
|
GETSTRSIZE: {
|
||||||
return -1;
|
return CONTINUE;
|
||||||
}
|
}
|
||||||
GETSTRCHARAT: {
|
GETSTRCHARAT: {
|
||||||
return -1;
|
return CONTINUE;
|
||||||
}
|
}
|
||||||
ADD: {
|
ADD: {
|
||||||
GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[2]);
|
GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[2]);
|
||||||
@@ -186,7 +191,7 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -1;
|
return CONTINUE;
|
||||||
}
|
}
|
||||||
SUBTRACT: {
|
SUBTRACT: {
|
||||||
GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[2]);
|
GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[2]);
|
||||||
@@ -236,7 +241,7 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -1;
|
return CONTINUE;
|
||||||
}
|
}
|
||||||
MULTIPLY: {
|
MULTIPLY: {
|
||||||
GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[2]);
|
GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[2]);
|
||||||
@@ -286,7 +291,7 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -1;
|
return CONTINUE;
|
||||||
}
|
}
|
||||||
DIVIDE: {
|
DIVIDE: {
|
||||||
GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[2]);
|
GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[2]);
|
||||||
@@ -336,7 +341,7 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -1;
|
return CONTINUE;
|
||||||
}
|
}
|
||||||
EQUAL: {
|
EQUAL: {
|
||||||
GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[2]);
|
GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[2]);
|
||||||
@@ -407,7 +412,7 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -1;
|
return CONTINUE;
|
||||||
}
|
}
|
||||||
INEQUAL: {
|
INEQUAL: {
|
||||||
GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[2]);
|
GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[2]);
|
||||||
@@ -478,11 +483,11 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -1;
|
return CONTINUE;
|
||||||
}
|
}
|
||||||
NOT: {
|
NOT: {
|
||||||
HEAP_SET(heap, instruction->args.at[1], Ground.New.BytecodeValue(Ground.New.Value.Bool(!HEAP_GET(heap, instruction->args.at[0])->as.Bool)));
|
HEAP_SET(heap, instruction->args.at[1], Ground.New.BytecodeValue(Ground.New.Value.Bool(!HEAP_GET(heap, instruction->args.at[0])->as.Bool)));
|
||||||
return -1;
|
return CONTINUE;
|
||||||
}
|
}
|
||||||
GREATER: {
|
GREATER: {
|
||||||
GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[2]);
|
GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[2]);
|
||||||
@@ -529,7 +534,7 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -1;
|
return CONTINUE;
|
||||||
}
|
}
|
||||||
LESSER: {
|
LESSER: {
|
||||||
GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[2]);
|
GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[2]);
|
||||||
@@ -576,7 +581,7 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -1;
|
return CONTINUE;
|
||||||
}
|
}
|
||||||
AND: {
|
AND: {
|
||||||
GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[2]);
|
GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[2]);
|
||||||
@@ -585,7 +590,7 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
|
|||||||
|
|
||||||
*final = Ground.New.BytecodeValue(Ground.New.Value.Bool(left->as.Bool && right->as.Bool));
|
*final = Ground.New.BytecodeValue(Ground.New.Value.Bool(left->as.Bool && right->as.Bool));
|
||||||
|
|
||||||
return -1;
|
return CONTINUE;
|
||||||
}
|
}
|
||||||
OR: {
|
OR: {
|
||||||
GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[2]);
|
GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[2]);
|
||||||
@@ -594,7 +599,7 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
|
|||||||
|
|
||||||
*final = Ground.New.BytecodeValue(Ground.New.Value.Bool(left->as.Bool || right->as.Bool));
|
*final = Ground.New.BytecodeValue(Ground.New.Value.Bool(left->as.Bool || right->as.Bool));
|
||||||
|
|
||||||
return -1;
|
return CONTINUE;
|
||||||
}
|
}
|
||||||
XOR: {
|
XOR: {
|
||||||
GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[2]);
|
GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[2]);
|
||||||
@@ -603,13 +608,13 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
|
|||||||
|
|
||||||
*final = Ground.New.BytecodeValue(Ground.New.Value.Bool(left->as.Bool != right->as.Bool));
|
*final = Ground.New.BytecodeValue(Ground.New.Value.Bool(left->as.Bool != right->as.Bool));
|
||||||
|
|
||||||
return -1;
|
return CONTINUE;
|
||||||
}
|
}
|
||||||
NEG: {
|
NEG: {
|
||||||
return -1;
|
return CONTINUE;
|
||||||
}
|
}
|
||||||
SHIFT: {
|
SHIFT: {
|
||||||
return -1;
|
return CONTINUE;
|
||||||
}
|
}
|
||||||
STOI: {
|
STOI: {
|
||||||
GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[1]);
|
GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[1]);
|
||||||
@@ -624,7 +629,7 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
|
|||||||
Ground.Log.Error("Failed converting string to double");
|
Ground.Log.Error("Failed converting string to double");
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return CONTINUE;
|
||||||
}
|
}
|
||||||
STOD: {
|
STOD: {
|
||||||
GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[1]);
|
GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[1]);
|
||||||
@@ -639,7 +644,7 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
|
|||||||
Ground.Log.Error("Failed converting string to double");
|
Ground.Log.Error("Failed converting string to double");
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return CONTINUE;
|
||||||
}
|
}
|
||||||
ITOC: {
|
ITOC: {
|
||||||
GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[1]);
|
GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[1]);
|
||||||
@@ -647,7 +652,7 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
|
|||||||
|
|
||||||
*final = Ground.New.BytecodeValue(Ground.New.Value.Char((char)in->as.Int));
|
*final = Ground.New.BytecodeValue(Ground.New.Value.Char((char)in->as.Int));
|
||||||
|
|
||||||
return -1;
|
return CONTINUE;
|
||||||
}
|
}
|
||||||
CTOI: {
|
CTOI: {
|
||||||
GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[1]);
|
GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[1]);
|
||||||
@@ -655,7 +660,7 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
|
|||||||
|
|
||||||
*final = Ground.New.BytecodeValue(Ground.New.Value.Int((int64_t)in->as.Char));
|
*final = Ground.New.BytecodeValue(Ground.New.Value.Int((int64_t)in->as.Char));
|
||||||
|
|
||||||
return -1;
|
return CONTINUE;
|
||||||
}
|
}
|
||||||
TOSTRING: {
|
TOSTRING: {
|
||||||
GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[1]);
|
GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[1]);
|
||||||
@@ -682,7 +687,7 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
|
|||||||
}
|
}
|
||||||
case GroundType_String: {
|
case GroundType_String: {
|
||||||
*in = Ground.New.BytecodeValue(Ground.New.Value.String(final->as.String));
|
*in = Ground.New.BytecodeValue(Ground.New.Value.String(final->as.String));
|
||||||
return -1;
|
return CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
@@ -694,76 +699,120 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
|
|||||||
|
|
||||||
*in = Ground.New.BytecodeValue(Ground.New.Value.String(Ground.New.String(buf)));
|
*in = Ground.New.BytecodeValue(Ground.New.Value.String(Ground.New.String(buf)));
|
||||||
|
|
||||||
return -1;
|
return CONTINUE;
|
||||||
}
|
}
|
||||||
FUN: {
|
FUN: {
|
||||||
// no-op
|
// make a copy of the current state and attach it to the function
|
||||||
return -1;
|
GroundBytecodeFunction* function = &HEAP_GET(heap, instruction->args.at[0])->as.Function;
|
||||||
|
|
||||||
|
if (function->closure == NULL) {}
|
||||||
|
|
||||||
|
return CONTINUE;
|
||||||
}
|
}
|
||||||
RETURN: {
|
RETURN: {
|
||||||
return -1;
|
return RETURN( *HEAP_GET(heap, instruction->args.at[0]) );
|
||||||
}
|
}
|
||||||
ENDFUN: {
|
ENDFUN: {
|
||||||
// no-op
|
// no-op
|
||||||
return -1;
|
return CONTINUE;
|
||||||
}
|
}
|
||||||
CALL: {
|
CALL: {
|
||||||
return -1;
|
// call !function $value... &returnIdx
|
||||||
|
GroundBytecodeFunction* function = &HEAP_GET(heap, instruction->args.at[0])->as.Function;
|
||||||
|
|
||||||
|
if (function->isNativeFunction) {
|
||||||
|
// TODO implement calling native functions
|
||||||
|
return CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (function->closure == NULL) {
|
||||||
|
Ground.Log.Error("unexpected NULL closure in Ground.Bytecode.Instruction.execute");
|
||||||
|
Ground.Flags.error = true;
|
||||||
|
return CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// amount of captured variables + amount of function args
|
||||||
|
GroundSize heapSize = function->closure->len + function->args.count;
|
||||||
|
|
||||||
|
GroundBytecodeHeap newHeap = { malloc(sizeof(GroundBytecodeValue) * heapSize), heapSize, heapSize };
|
||||||
|
if (newHeap.heap == NULL) {
|
||||||
|
Ground.Log.Error("malloc failed in Ground.Bytecode.Instruction.execute");
|
||||||
|
Ground.Flags.error = true;
|
||||||
|
return CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// load function arguments into the heap
|
||||||
|
for (GroundSize i = 0; i < function->args.count; i++) {
|
||||||
|
newHeap.heap[i] = Ground.Copy.BytecodeValue(HEAP_GET(heap, i + 1)); // +1 because arg 1 is where fn args start
|
||||||
|
}
|
||||||
|
|
||||||
|
// function arguments are the first indexes, copy after
|
||||||
|
for (GroundSize i = function->args.count; i < newHeap.len; i++) {
|
||||||
|
newHeap.heap[i] = Ground.Copy.BytecodeValue(&function->closure->heap[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now we run the thingy
|
||||||
|
GroundBytecodeValue result = Ground.Bytecode.Program.execute(function->program.ground, &newHeap);
|
||||||
|
|
||||||
|
// And store the result
|
||||||
|
HEAP_SET(heap, instruction->args.at[instruction->args.len - 1], result);
|
||||||
|
|
||||||
|
return CONTINUE;
|
||||||
}
|
}
|
||||||
CALLMETHOD: {
|
CALLMETHOD: {
|
||||||
return -1;
|
return CONTINUE;
|
||||||
}
|
}
|
||||||
STRUCT: {
|
STRUCT: {
|
||||||
// no-op
|
// no-op
|
||||||
return -1;
|
return CONTINUE;
|
||||||
}
|
}
|
||||||
ENDSTRUCT: {
|
ENDSTRUCT: {
|
||||||
// no-op
|
// no-op
|
||||||
return -1;
|
return CONTINUE;
|
||||||
}
|
}
|
||||||
INIT: {
|
INIT: {
|
||||||
return -1;
|
return CONTINUE;
|
||||||
}
|
}
|
||||||
GETFIELD: {
|
GETFIELD: {
|
||||||
return -1;
|
return CONTINUE;
|
||||||
}
|
}
|
||||||
SETFIELD: {
|
SETFIELD: {
|
||||||
return -1;
|
return CONTINUE;
|
||||||
}
|
}
|
||||||
USE: {
|
USE: {
|
||||||
return -1;
|
return CONTINUE;
|
||||||
}
|
}
|
||||||
EXTERN: {
|
EXTERN: {
|
||||||
return -1;
|
return CONTINUE;
|
||||||
}
|
}
|
||||||
CREATELABEL: {
|
CREATELABEL: {
|
||||||
// no-op
|
// no-op
|
||||||
return -1;
|
return CONTINUE;
|
||||||
}
|
}
|
||||||
PAUSE: {
|
PAUSE: {
|
||||||
return -1;
|
return CONTINUE;
|
||||||
}
|
}
|
||||||
DROP: {
|
DROP: {
|
||||||
GroundBytecodeValue* in = HEAP_GET(heap, instruction->args.at[0]);
|
GroundBytecodeValue* in = HEAP_GET(heap, instruction->args.at[0]);
|
||||||
Ground.Free.BytecodeValue(in);
|
Ground.Free.BytecodeValue(in);
|
||||||
*in = Ground.New.BytecodeValue(Ground.New.Value.Int(0));
|
*in = Ground.New.BytecodeValue(Ground.New.Value.Int(0));
|
||||||
return -1;
|
return CONTINUE;
|
||||||
}
|
}
|
||||||
LICENSE: {
|
LICENSE: {
|
||||||
return -1;
|
return CONTINUE;
|
||||||
}
|
}
|
||||||
ERRORCMD: {
|
ERRORCMD: {
|
||||||
return -1;
|
return CONTINUE;
|
||||||
}
|
}
|
||||||
THROW: {
|
THROW: {
|
||||||
return -1;
|
return CONTINUE;
|
||||||
}
|
}
|
||||||
CATCH: {
|
CATCH: {
|
||||||
return -1;
|
return CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ground.Log.Error("operation fell through in Ground.Instruction.execute()");
|
Ground.Log.Error("operation fell through in Ground.Instruction.execute()");
|
||||||
Ground.Flags.error = true;
|
Ground.Flags.error = true;
|
||||||
|
|
||||||
return -1;
|
return CONTINUE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,22 @@
|
|||||||
#include "../../../include/ground.h"
|
#include "../../../include/ground.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
void _GroundBytecodeProgramExecute(GroundBytecodeProgram* program, GroundBytecodeHeap* heap) {
|
GroundBytecodeValue _GroundBytecodeProgramExecute(GroundBytecodeProgram* program, GroundBytecodeHeap* heap) {
|
||||||
GroundSize i = 0;
|
GroundSize i = 0;
|
||||||
while (i < program->len) {
|
while (i < program->len) {
|
||||||
int64_t status = Ground.Bytecode.Instruction.execute(&program->at[i], heap);
|
struct GroundExecutionResult status = Ground.Bytecode.Instruction.execute(&program->at[i], heap);
|
||||||
if (Ground.Flags.error) {
|
if (Ground.Flags.error) {
|
||||||
return;
|
return Ground.New.BytecodeValue(Ground.New.Value.Int(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (status) {
|
switch (status.type) {
|
||||||
case -1: i++; break;
|
|
||||||
case -2: return;
|
case _GER_CONTINUE: i++; break;
|
||||||
default: i = status; break;
|
case _GER_RETURN: return status.as.value;
|
||||||
|
case _GER_JUMP: i = status.as.line; break;
|
||||||
|
case _GER_END: exit(status.as.end);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return Ground.New.BytecodeValue(Ground.New.Value.Int(0));
|
||||||
}
|
}
|
||||||
|
|||||||
22
src/Copy/BytecodeValue.c
Normal file
22
src/Copy/BytecodeValue.c
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
#include "../../include/ground.h"
|
||||||
|
|
||||||
|
GroundBytecodeValue _GroundCopyBytecodeValue(GroundBytecodeValue* value) {
|
||||||
|
GroundBytecodeValue newValue = *value;
|
||||||
|
switch (value->type.type) {
|
||||||
|
case GroundType_Int:
|
||||||
|
case GroundType_Double:
|
||||||
|
case GroundType_Bool:
|
||||||
|
case GroundType_Char:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GroundType_String: {
|
||||||
|
newValue.as.String = Ground.Copy.String(&value->as.String);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Implement copying for everything else
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return newValue;
|
||||||
|
}
|
||||||
@@ -66,6 +66,8 @@ GroundState _GroundCopyState(GroundState* in);
|
|||||||
|
|
||||||
GroundIdentifier* _GroundCopyIdentifier(GroundIdentifier* identifier);
|
GroundIdentifier* _GroundCopyIdentifier(GroundIdentifier* identifier);
|
||||||
|
|
||||||
|
GroundBytecodeValue _GroundCopyBytecodeValue(GroundBytecodeValue* value);
|
||||||
|
|
||||||
|
|
||||||
void _GroundListAppend(GroundList* list, GroundValue value);
|
void _GroundListAppend(GroundList* list, GroundValue value);
|
||||||
|
|
||||||
@@ -99,10 +101,10 @@ void _GroundLogWarning(const char* message);
|
|||||||
void _GroundLogPrintErrors();
|
void _GroundLogPrintErrors();
|
||||||
|
|
||||||
|
|
||||||
void _GroundBytecodeProgramExecute(GroundBytecodeProgram* program, GroundBytecodeHeap* heap);
|
GroundBytecodeValue _GroundBytecodeProgramExecute(GroundBytecodeProgram* program, GroundBytecodeHeap* heap);
|
||||||
void _GroundBytecodeProgramOptimise(GroundBytecodeProgram* program);
|
void _GroundBytecodeProgramOptimise(GroundBytecodeProgram* program);
|
||||||
|
|
||||||
int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction, GroundBytecodeHeap* heap);
|
struct GroundExecutionResult _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction, GroundBytecodeHeap* heap);
|
||||||
|
|
||||||
void _GroundBytecodeSave(GroundBytecode* bytecode, const char* path);
|
void _GroundBytecodeSave(GroundBytecode* bytecode, const char* path);
|
||||||
GroundBytecode _GroundBytecodeLoad(const char* path);
|
GroundBytecode _GroundBytecodeLoad(const char* path);
|
||||||
|
|||||||
Reference in New Issue
Block a user