function calling works in theory (can't test yet)
This commit is contained in:
@@ -9,6 +9,11 @@
|
||||
#define HEAP_GET(heap, idx) (&(heap)->heap[(idx)])
|
||||
#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) {
|
||||
switch (val->type.type) {
|
||||
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[] = {
|
||||
&&IF, &&JUMP, &&END,
|
||||
@@ -55,67 +60,67 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
|
||||
IF: {
|
||||
GroundBytecodeValue* cond = HEAP_GET(heap, instruction->args.at[0]);
|
||||
if (cond->as.Bool) {
|
||||
return instruction->args.at[1];
|
||||
return JUMP(instruction->args.at[1]);
|
||||
}
|
||||
return -1;
|
||||
return CONTINUE;
|
||||
}
|
||||
JUMP: {
|
||||
return instruction->args.at[0];
|
||||
return JUMP(instruction->args.at[0]);
|
||||
}
|
||||
END: {
|
||||
return -2;
|
||||
return END( HEAP_GET(heap, instruction->args.at[0])->as.Int );
|
||||
}
|
||||
INPUT: {
|
||||
char* input = linenoise("");
|
||||
HEAP_SET(heap, instruction->args.at[0], Ground.New.BytecodeValue(Ground.New.Value.String(Ground.New.String(input))));
|
||||
free(input);
|
||||
return -1;
|
||||
return CONTINUE;
|
||||
}
|
||||
PRINT: {
|
||||
for (GroundSize i = 0; i < instruction->args.len; i++) {
|
||||
printValue(HEAP_GET(heap, instruction->args.at[i]));
|
||||
}
|
||||
return -1;
|
||||
return CONTINUE;
|
||||
}
|
||||
PRINTLN: {
|
||||
for (GroundSize i = 0; i < instruction->args.len; i++) {
|
||||
printValue(HEAP_GET(heap, instruction->args.at[i]));
|
||||
}
|
||||
printf("\n");
|
||||
return -1;
|
||||
return CONTINUE;
|
||||
}
|
||||
SET: {
|
||||
HEAP_SET(heap, instruction->args.at[0], *HEAP_GET(heap, instruction->args.at[1]));
|
||||
return -1;
|
||||
return CONTINUE;
|
||||
}
|
||||
GETTYPE: {
|
||||
Ground.Log.Warning("GETTYPE is deprecated");
|
||||
return -1;
|
||||
return CONTINUE;
|
||||
}
|
||||
EXISTS: {
|
||||
Ground.Log.Warning("EXISTS is deprecated");
|
||||
return -1;
|
||||
return CONTINUE;
|
||||
}
|
||||
SETLIST: {
|
||||
return -1;
|
||||
return CONTINUE;
|
||||
}
|
||||
SETLISTAT: {
|
||||
return -1;
|
||||
return CONTINUE;
|
||||
}
|
||||
GETLISTAT: {
|
||||
return -1;
|
||||
return CONTINUE;
|
||||
}
|
||||
GETLISTSIZE: {
|
||||
return -1;
|
||||
return CONTINUE;
|
||||
}
|
||||
LISTAPPEND: {
|
||||
return -1;
|
||||
return CONTINUE;
|
||||
}
|
||||
GETSTRSIZE: {
|
||||
return -1;
|
||||
return CONTINUE;
|
||||
}
|
||||
GETSTRCHARAT: {
|
||||
return -1;
|
||||
return CONTINUE;
|
||||
}
|
||||
ADD: {
|
||||
GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[2]);
|
||||
@@ -186,7 +191,7 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
|
||||
break;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
return CONTINUE;
|
||||
}
|
||||
SUBTRACT: {
|
||||
GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[2]);
|
||||
@@ -236,7 +241,7 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
|
||||
break;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
return CONTINUE;
|
||||
}
|
||||
MULTIPLY: {
|
||||
GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[2]);
|
||||
@@ -286,7 +291,7 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
|
||||
break;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
return CONTINUE;
|
||||
}
|
||||
DIVIDE: {
|
||||
GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[2]);
|
||||
@@ -336,7 +341,7 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
|
||||
break;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
return CONTINUE;
|
||||
}
|
||||
EQUAL: {
|
||||
GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[2]);
|
||||
@@ -407,7 +412,7 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
|
||||
break;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
return CONTINUE;
|
||||
}
|
||||
INEQUAL: {
|
||||
GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[2]);
|
||||
@@ -478,11 +483,11 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
|
||||
break;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
return CONTINUE;
|
||||
}
|
||||
NOT: {
|
||||
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: {
|
||||
GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[2]);
|
||||
@@ -529,7 +534,7 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
|
||||
break;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
return CONTINUE;
|
||||
}
|
||||
LESSER: {
|
||||
GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[2]);
|
||||
@@ -576,7 +581,7 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
|
||||
break;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
return CONTINUE;
|
||||
}
|
||||
AND: {
|
||||
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));
|
||||
|
||||
return -1;
|
||||
return CONTINUE;
|
||||
}
|
||||
OR: {
|
||||
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));
|
||||
|
||||
return -1;
|
||||
return CONTINUE;
|
||||
}
|
||||
XOR: {
|
||||
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));
|
||||
|
||||
return -1;
|
||||
return CONTINUE;
|
||||
}
|
||||
NEG: {
|
||||
return -1;
|
||||
return CONTINUE;
|
||||
}
|
||||
SHIFT: {
|
||||
return -1;
|
||||
return CONTINUE;
|
||||
}
|
||||
STOI: {
|
||||
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");
|
||||
}
|
||||
|
||||
return -1;
|
||||
return CONTINUE;
|
||||
}
|
||||
STOD: {
|
||||
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");
|
||||
}
|
||||
|
||||
return -1;
|
||||
return CONTINUE;
|
||||
}
|
||||
ITOC: {
|
||||
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));
|
||||
|
||||
return -1;
|
||||
return CONTINUE;
|
||||
}
|
||||
CTOI: {
|
||||
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));
|
||||
|
||||
return -1;
|
||||
return CONTINUE;
|
||||
}
|
||||
TOSTRING: {
|
||||
GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[1]);
|
||||
@@ -682,7 +687,7 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
|
||||
}
|
||||
case GroundType_String: {
|
||||
*in = Ground.New.BytecodeValue(Ground.New.Value.String(final->as.String));
|
||||
return -1;
|
||||
return CONTINUE;
|
||||
}
|
||||
|
||||
default: {
|
||||
@@ -694,76 +699,120 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
|
||||
|
||||
*in = Ground.New.BytecodeValue(Ground.New.Value.String(Ground.New.String(buf)));
|
||||
|
||||
return -1;
|
||||
return CONTINUE;
|
||||
}
|
||||
FUN: {
|
||||
// no-op
|
||||
return -1;
|
||||
// make a copy of the current state and attach it to the function
|
||||
GroundBytecodeFunction* function = &HEAP_GET(heap, instruction->args.at[0])->as.Function;
|
||||
|
||||
if (function->closure == NULL) {}
|
||||
|
||||
return CONTINUE;
|
||||
}
|
||||
RETURN: {
|
||||
return -1;
|
||||
return RETURN( *HEAP_GET(heap, instruction->args.at[0]) );
|
||||
}
|
||||
ENDFUN: {
|
||||
// no-op
|
||||
return -1;
|
||||
return CONTINUE;
|
||||
}
|
||||
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: {
|
||||
return -1;
|
||||
return CONTINUE;
|
||||
}
|
||||
STRUCT: {
|
||||
// no-op
|
||||
return -1;
|
||||
return CONTINUE;
|
||||
}
|
||||
ENDSTRUCT: {
|
||||
// no-op
|
||||
return -1;
|
||||
return CONTINUE;
|
||||
}
|
||||
INIT: {
|
||||
return -1;
|
||||
return CONTINUE;
|
||||
}
|
||||
GETFIELD: {
|
||||
return -1;
|
||||
return CONTINUE;
|
||||
}
|
||||
SETFIELD: {
|
||||
return -1;
|
||||
return CONTINUE;
|
||||
}
|
||||
USE: {
|
||||
return -1;
|
||||
return CONTINUE;
|
||||
}
|
||||
EXTERN: {
|
||||
return -1;
|
||||
return CONTINUE;
|
||||
}
|
||||
CREATELABEL: {
|
||||
// no-op
|
||||
return -1;
|
||||
return CONTINUE;
|
||||
}
|
||||
PAUSE: {
|
||||
return -1;
|
||||
return CONTINUE;
|
||||
}
|
||||
DROP: {
|
||||
GroundBytecodeValue* in = HEAP_GET(heap, instruction->args.at[0]);
|
||||
Ground.Free.BytecodeValue(in);
|
||||
*in = Ground.New.BytecodeValue(Ground.New.Value.Int(0));
|
||||
return -1;
|
||||
return CONTINUE;
|
||||
}
|
||||
LICENSE: {
|
||||
return -1;
|
||||
return CONTINUE;
|
||||
}
|
||||
ERRORCMD: {
|
||||
return -1;
|
||||
return CONTINUE;
|
||||
}
|
||||
THROW: {
|
||||
return -1;
|
||||
return CONTINUE;
|
||||
}
|
||||
CATCH: {
|
||||
return -1;
|
||||
return CONTINUE;
|
||||
}
|
||||
|
||||
Ground.Log.Error("operation fell through in Ground.Instruction.execute()");
|
||||
Ground.Flags.error = true;
|
||||
|
||||
return -1;
|
||||
return CONTINUE;
|
||||
}
|
||||
|
||||
@@ -1,18 +1,22 @@
|
||||
#include "../../../include/ground.h"
|
||||
#include <stdint.h>
|
||||
|
||||
void _GroundBytecodeProgramExecute(GroundBytecodeProgram* program, GroundBytecodeHeap* heap) {
|
||||
GroundBytecodeValue _GroundBytecodeProgramExecute(GroundBytecodeProgram* program, GroundBytecodeHeap* heap) {
|
||||
GroundSize i = 0;
|
||||
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) {
|
||||
return;
|
||||
return Ground.New.BytecodeValue(Ground.New.Value.Int(1));
|
||||
}
|
||||
|
||||
switch (status) {
|
||||
case -1: i++; break;
|
||||
case -2: return;
|
||||
default: i = status; break;
|
||||
switch (status.type) {
|
||||
|
||||
case _GER_CONTINUE: i++; 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);
|
||||
|
||||
GroundBytecodeValue _GroundCopyBytecodeValue(GroundBytecodeValue* value);
|
||||
|
||||
|
||||
void _GroundListAppend(GroundList* list, GroundValue value);
|
||||
|
||||
@@ -99,10 +101,10 @@ void _GroundLogWarning(const char* message);
|
||||
void _GroundLogPrintErrors();
|
||||
|
||||
|
||||
void _GroundBytecodeProgramExecute(GroundBytecodeProgram* program, GroundBytecodeHeap* heap);
|
||||
GroundBytecodeValue _GroundBytecodeProgramExecute(GroundBytecodeProgram* program, GroundBytecodeHeap* heap);
|
||||
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);
|
||||
GroundBytecode _GroundBytecodeLoad(const char* path);
|
||||
|
||||
Reference in New Issue
Block a user