Misc stuff, probably crashes
This commit is contained in:
@@ -20,6 +20,12 @@ typedef struct GroundInstruction GroundInstruction;
|
||||
typedef struct GroundProgram GroundProgram;
|
||||
typedef struct GroundState GroundState;
|
||||
|
||||
typedef struct GroundBytecodeValue GroundBytecodeValue;
|
||||
typedef struct GroundBytecodeList GroundBytecodeList;
|
||||
typedef struct GroundBytecodeFunction GroundBytecodeFunction;
|
||||
typedef struct GroundBytecodeStruct GroundBytecodeStruct;
|
||||
typedef struct GroundBytecodeObject GroundBytecodeObject;
|
||||
typedef struct GroundBytecodeError GroundBytecodeError;
|
||||
typedef struct GroundBytecodeProgram GroundBytecodeProgram;
|
||||
typedef struct GroundBytecodeInstruction GroundBytecodeInstruction;
|
||||
typedef struct GroundBytecodeHeap GroundBytecodeHeap;
|
||||
@@ -261,6 +267,49 @@ struct GroundIdentifier {
|
||||
GroundSize referenceCount;
|
||||
};
|
||||
|
||||
struct GroundBytecodeList {
|
||||
GroundSize capacity;
|
||||
GroundSize count;
|
||||
GroundBytecodeValue* at;
|
||||
};
|
||||
struct GroundBytecodeFunction {
|
||||
struct {
|
||||
GroundSize capacity;
|
||||
GroundSize count;
|
||||
GroundFunctionArg* at;
|
||||
} args;
|
||||
|
||||
bool isNativeFunction;
|
||||
|
||||
union {
|
||||
void* native;
|
||||
GroundBytecodeProgram* ground;
|
||||
} program;
|
||||
|
||||
GroundBytecodeHeap* closure;
|
||||
|
||||
GroundSize _requiredSize;
|
||||
};
|
||||
struct GroundBytecodeStruct {};
|
||||
struct GroundBytecodeObject {};
|
||||
|
||||
struct GroundBytecodeValue {
|
||||
union {
|
||||
GroundInt Int;
|
||||
GroundDouble Double;
|
||||
GroundChar Char;
|
||||
GroundBool Bool;
|
||||
GroundString String;
|
||||
|
||||
GroundBytecodeList List;
|
||||
GroundBytecodeFunction Function;
|
||||
GroundBytecodeStruct Struct;
|
||||
GroundBytecodeObject Object;
|
||||
} as;
|
||||
|
||||
GroundType type;
|
||||
};
|
||||
|
||||
struct GroundBytecodeProgram {
|
||||
GroundBytecodeInstruction* at;
|
||||
GroundSize capacity;
|
||||
@@ -277,7 +326,7 @@ struct GroundBytecodeInstruction {
|
||||
};
|
||||
|
||||
struct GroundBytecodeHeap {
|
||||
GroundValue* heap;
|
||||
GroundBytecodeValue* heap;
|
||||
GroundSize capacity;
|
||||
GroundSize len;
|
||||
};
|
||||
@@ -340,7 +389,8 @@ struct _Ground {
|
||||
|
||||
GroundIdentifier* (*Identifier) (const char* id);
|
||||
|
||||
GroundBytecode (*Bytecode) (GroundProgram* program, GroundState* state);
|
||||
GroundBytecode (*Bytecode) (GroundProgram* program, GroundState* state);
|
||||
GroundBytecodeValue (*BytecodeValue) (GroundValue value);
|
||||
|
||||
} New;
|
||||
|
||||
@@ -359,6 +409,8 @@ struct _Ground {
|
||||
void (*State) (GroundState* state);
|
||||
|
||||
void (*Identifier) (GroundIdentifier* identifier);
|
||||
|
||||
void (*BytecodeValue) (GroundBytecodeValue* value);
|
||||
} Free;
|
||||
|
||||
// Creates a copy of the memory held by the specified struct
|
||||
@@ -388,8 +440,9 @@ struct _Ground {
|
||||
} Instruction;
|
||||
|
||||
struct {
|
||||
void (*append) (GroundProgram* program, GroundInstruction instruction);
|
||||
void (*execute) (GroundProgram* program, GroundState* state);
|
||||
void (*append) (GroundProgram* program, GroundInstruction instruction);
|
||||
void (*execute) (GroundProgram* program, GroundState* state);
|
||||
GroundProgram (*preprocess) (GroundProgram* program, GroundState* state);
|
||||
} Program;
|
||||
|
||||
struct {
|
||||
@@ -447,6 +500,8 @@ struct _Ground {
|
||||
char* (*Program)(GroundProgram* program);
|
||||
char* (*String)(GroundString* string);
|
||||
char* (*Value)(GroundValue* value);
|
||||
|
||||
char* (*BytecodeValue)(GroundBytecodeValue* value);
|
||||
} Stringify;
|
||||
};
|
||||
|
||||
|
||||
@@ -39,6 +39,8 @@ sources = files(
|
||||
|
||||
'src/Free/Identifier.c',
|
||||
|
||||
'src/Free/BytecodeValue.c',
|
||||
|
||||
'src/Function/appendInstruction.c',
|
||||
'src/Function/appendArg.c',
|
||||
|
||||
@@ -74,6 +76,7 @@ sources = files(
|
||||
'src/New/Identifier.c',
|
||||
|
||||
'src/New/Bytecode.c',
|
||||
'src/New/BytecodeValue.c',
|
||||
|
||||
'src/New/NativeFunction.c',
|
||||
|
||||
@@ -93,6 +96,7 @@ sources = files(
|
||||
|
||||
'src/Program/append.c',
|
||||
'src/Program/execute.c',
|
||||
'src/Program/preprocess.c',
|
||||
|
||||
'src/State/findCatch.c',
|
||||
'src/State/findLabel.c',
|
||||
@@ -105,6 +109,8 @@ sources = files(
|
||||
'src/Stringify/String.c',
|
||||
'src/Stringify/Value.c',
|
||||
|
||||
'src/Stringify/BytecodeValue.c',
|
||||
|
||||
'src/Struct/addField.c',
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "../../../include/ground.h"
|
||||
|
||||
GroundValue* _GroundBytecodeHeapGet(GroundBytecodeHeap* heap, GroundSize idx) {
|
||||
GroundBytecodeValue* _GroundBytecodeHeapGet(GroundBytecodeHeap* heap, GroundSize idx) {
|
||||
return &heap->heap[idx];
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "../../../include/ground.h"
|
||||
|
||||
void _GroundBytecodeHeapSet(GroundBytecodeHeap* heap, GroundSize idx, GroundValue value) {
|
||||
void _GroundBytecodeHeapSet(GroundBytecodeHeap* heap, GroundSize idx, GroundBytecodeValue value) {
|
||||
heap->heap[idx] = value;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#define HEAP_GET(heap, idx) (&(heap)->heap[(idx)])
|
||||
#define HEAP_SET(heap, idx, val) ((heap)->heap[(idx)] = (val))
|
||||
|
||||
static void printValue(GroundValue* val) {
|
||||
static void printValue(GroundBytecodeValue* val) {
|
||||
switch (val->type.type) {
|
||||
case GroundType_Int:
|
||||
printf("%" PRId64, val->as.Int);
|
||||
@@ -53,7 +53,7 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
|
||||
goto *jumpTable[instruction->type];
|
||||
|
||||
IF: {
|
||||
GroundValue* cond = HEAP_GET(heap, instruction->args.at[0]);
|
||||
GroundBytecodeValue* cond = HEAP_GET(heap, instruction->args.at[0]);
|
||||
if (cond->as.Bool) {
|
||||
return instruction->args.at[1];
|
||||
}
|
||||
@@ -67,7 +67,7 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
|
||||
}
|
||||
INPUT: {
|
||||
char* input = linenoise("");
|
||||
HEAP_SET(heap, instruction->args.at[0], 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);
|
||||
return -1;
|
||||
}
|
||||
@@ -118,19 +118,19 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
|
||||
return -1;
|
||||
}
|
||||
ADD: {
|
||||
GroundValue* final = HEAP_GET(heap, instruction->args.at[2]);
|
||||
GroundValue* left = HEAP_GET(heap, instruction->args.at[0]);
|
||||
GroundValue* right = HEAP_GET(heap, instruction->args.at[1]);
|
||||
GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[2]);
|
||||
GroundBytecodeValue* left = HEAP_GET(heap, instruction->args.at[0]);
|
||||
GroundBytecodeValue* right = HEAP_GET(heap, instruction->args.at[1]);
|
||||
|
||||
switch (left->type.type) {
|
||||
case GroundType_Int: {
|
||||
switch (right->type.type) {
|
||||
case GroundType_Int: {
|
||||
*final = Ground.New.Value.Int(left->as.Int + right->as.Int);
|
||||
*final = Ground.New.BytecodeValue(Ground.New.Value.Int(left->as.Int + right->as.Int));
|
||||
break;
|
||||
}
|
||||
case GroundType_Double: {
|
||||
*final = Ground.New.Value.Double(left->as.Int + right->as.Double);
|
||||
*final = Ground.New.BytecodeValue(Ground.New.Value.Double(left->as.Int + right->as.Double));
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
@@ -144,11 +144,11 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
|
||||
case GroundType_Double: {
|
||||
switch (right->type.type) {
|
||||
case GroundType_Int: {
|
||||
*final = Ground.New.Value.Double(left->as.Double + right->as.Int);
|
||||
*final = Ground.New.BytecodeValue(Ground.New.Value.Double(left->as.Double + right->as.Int));
|
||||
break;
|
||||
}
|
||||
case GroundType_Double: {
|
||||
*final = Ground.New.Value.Double(left->as.Double + right->as.Double);
|
||||
*final = Ground.New.BytecodeValue(Ground.New.Value.Double(left->as.Double + right->as.Double));
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
@@ -170,7 +170,7 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
|
||||
break;
|
||||
}
|
||||
sprintf(buf, "%s%s", left->as.String.cstr, right->as.String.cstr);
|
||||
*final = Ground.New.Value.String(Ground.New.String(buf));
|
||||
*final = Ground.New.BytecodeValue(Ground.New.Value.String(Ground.New.String(buf)));
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
@@ -189,19 +189,19 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
|
||||
return -1;
|
||||
}
|
||||
SUBTRACT: {
|
||||
GroundValue* final = HEAP_GET(heap, instruction->args.at[2]);
|
||||
GroundValue* left = HEAP_GET(heap, instruction->args.at[0]);
|
||||
GroundValue* right = HEAP_GET(heap, instruction->args.at[1]);
|
||||
GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[2]);
|
||||
GroundBytecodeValue* left = HEAP_GET(heap, instruction->args.at[0]);
|
||||
GroundBytecodeValue* right = HEAP_GET(heap, instruction->args.at[1]);
|
||||
|
||||
switch (left->type.type) {
|
||||
case GroundType_Int: {
|
||||
switch (right->type.type) {
|
||||
case GroundType_Int: {
|
||||
*final = Ground.New.Value.Int(left->as.Int - right->as.Int);
|
||||
*final = Ground.New.BytecodeValue(Ground.New.Value.Int(left->as.Int - right->as.Int));
|
||||
break;
|
||||
}
|
||||
case GroundType_Double: {
|
||||
*final = Ground.New.Value.Double(left->as.Int - right->as.Double);
|
||||
*final = Ground.New.BytecodeValue(Ground.New.Value.Double(left->as.Int - right->as.Double));
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
@@ -215,11 +215,11 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
|
||||
case GroundType_Double: {
|
||||
switch (right->type.type) {
|
||||
case GroundType_Int: {
|
||||
*final = Ground.New.Value.Double(left->as.Double - right->as.Int);
|
||||
*final = Ground.New.BytecodeValue(Ground.New.Value.Double(left->as.Double - right->as.Int));
|
||||
break;
|
||||
}
|
||||
case GroundType_Double: {
|
||||
*final = Ground.New.Value.Double(left->as.Double - right->as.Double);
|
||||
*final = Ground.New.BytecodeValue(Ground.New.Value.Double(left->as.Double - right->as.Double));
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
@@ -239,19 +239,19 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
|
||||
return -1;
|
||||
}
|
||||
MULTIPLY: {
|
||||
GroundValue* final = HEAP_GET(heap, instruction->args.at[2]);
|
||||
GroundValue* left = HEAP_GET(heap, instruction->args.at[0]);
|
||||
GroundValue* right = HEAP_GET(heap, instruction->args.at[1]);
|
||||
GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[2]);
|
||||
GroundBytecodeValue* left = HEAP_GET(heap, instruction->args.at[0]);
|
||||
GroundBytecodeValue* right = HEAP_GET(heap, instruction->args.at[1]);
|
||||
|
||||
switch (left->type.type) {
|
||||
case GroundType_Int: {
|
||||
switch (right->type.type) {
|
||||
case GroundType_Int: {
|
||||
*final = Ground.New.Value.Int(left->as.Int * right->as.Int);
|
||||
*final = Ground.New.BytecodeValue(Ground.New.Value.Int(left->as.Int * right->as.Int));
|
||||
break;
|
||||
}
|
||||
case GroundType_Double: {
|
||||
*final = Ground.New.Value.Double(left->as.Int * right->as.Double);
|
||||
*final = Ground.New.BytecodeValue(Ground.New.Value.Double(left->as.Int * right->as.Double));
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
@@ -265,11 +265,11 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
|
||||
case GroundType_Double: {
|
||||
switch (right->type.type) {
|
||||
case GroundType_Int: {
|
||||
*final = Ground.New.Value.Double(left->as.Double * right->as.Int);
|
||||
*final = Ground.New.BytecodeValue(Ground.New.Value.Double(left->as.Double * right->as.Int));
|
||||
break;
|
||||
}
|
||||
case GroundType_Double: {
|
||||
*final = Ground.New.Value.Double(left->as.Double * right->as.Double);
|
||||
*final = Ground.New.BytecodeValue(Ground.New.Value.Double(left->as.Double * right->as.Double));
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
@@ -289,19 +289,19 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
|
||||
return -1;
|
||||
}
|
||||
DIVIDE: {
|
||||
GroundValue* final = HEAP_GET(heap, instruction->args.at[2]);
|
||||
GroundValue* left = HEAP_GET(heap, instruction->args.at[0]);
|
||||
GroundValue* right = HEAP_GET(heap, instruction->args.at[1]);
|
||||
GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[2]);
|
||||
GroundBytecodeValue* left = HEAP_GET(heap, instruction->args.at[0]);
|
||||
GroundBytecodeValue* right = HEAP_GET(heap, instruction->args.at[1]);
|
||||
|
||||
switch (left->type.type) {
|
||||
case GroundType_Int: {
|
||||
switch (right->type.type) {
|
||||
case GroundType_Int: {
|
||||
*final = Ground.New.Value.Int(left->as.Int / right->as.Int);
|
||||
*final = Ground.New.BytecodeValue(Ground.New.Value.Int(left->as.Int / right->as.Int));
|
||||
break;
|
||||
}
|
||||
case GroundType_Double: {
|
||||
*final = Ground.New.Value.Double(left->as.Int / right->as.Double);
|
||||
*final = Ground.New.BytecodeValue(Ground.New.Value.Double(left->as.Int / right->as.Double));
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
@@ -315,11 +315,11 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
|
||||
case GroundType_Double: {
|
||||
switch (right->type.type) {
|
||||
case GroundType_Int: {
|
||||
*final = Ground.New.Value.Double(left->as.Double / right->as.Int);
|
||||
*final = Ground.New.BytecodeValue(Ground.New.Value.Double(left->as.Double / right->as.Int));
|
||||
break;
|
||||
}
|
||||
case GroundType_Double: {
|
||||
*final = Ground.New.Value.Double(left->as.Double / right->as.Double);
|
||||
*final = Ground.New.BytecodeValue(Ground.New.Value.Double(left->as.Double / right->as.Double));
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
@@ -339,23 +339,23 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
|
||||
return -1;
|
||||
}
|
||||
EQUAL: {
|
||||
GroundValue* final = HEAP_GET(heap, instruction->args.at[2]);
|
||||
GroundValue* left = HEAP_GET(heap, instruction->args.at[0]);
|
||||
GroundValue* right = HEAP_GET(heap, instruction->args.at[1]);
|
||||
GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[2]);
|
||||
GroundBytecodeValue* left = HEAP_GET(heap, instruction->args.at[0]);
|
||||
GroundBytecodeValue* right = HEAP_GET(heap, instruction->args.at[1]);
|
||||
|
||||
switch (left->type.type) {
|
||||
case GroundType_Int: {
|
||||
switch (right->type.type) {
|
||||
case GroundType_Int: {
|
||||
*final = Ground.New.Value.Bool(left->as.Int == right->as.Int);
|
||||
*final = Ground.New.BytecodeValue(Ground.New.Value.Bool(left->as.Int == right->as.Int));
|
||||
break;
|
||||
}
|
||||
case GroundType_Double: {
|
||||
*final = Ground.New.Value.Bool(left->as.Int == right->as.Double);
|
||||
*final = Ground.New.BytecodeValue(Ground.New.Value.Bool(left->as.Int == right->as.Double));
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
*final = Ground.New.Value.Bool(false);
|
||||
*final = Ground.New.BytecodeValue(Ground.New.Value.Bool(false));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -364,15 +364,15 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
|
||||
case GroundType_Double: {
|
||||
switch (right->type.type) {
|
||||
case GroundType_Int: {
|
||||
*final = Ground.New.Value.Bool(left->as.Double == right->as.Int);
|
||||
*final = Ground.New.BytecodeValue(Ground.New.Value.Bool(left->as.Double == right->as.Int));
|
||||
break;
|
||||
}
|
||||
case GroundType_Double: {
|
||||
*final = Ground.New.Value.Bool(left->as.Double == right->as.Double);
|
||||
*final = Ground.New.BytecodeValue(Ground.New.Value.Bool(left->as.Double == right->as.Double));
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
*final = Ground.New.Value.Bool(false);
|
||||
*final = Ground.New.BytecodeValue(Ground.New.Value.Bool(false));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -380,53 +380,53 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
|
||||
}
|
||||
case GroundType_Char: {
|
||||
if (right->type.type == GroundType_Char) {
|
||||
*final = Ground.New.Value.Bool(left->as.Char == right->as.Char);
|
||||
*final = Ground.New.BytecodeValue(Ground.New.Value.Bool(left->as.Char == right->as.Char));
|
||||
} else {
|
||||
*final = Ground.New.Value.Bool(false);
|
||||
*final = Ground.New.BytecodeValue(Ground.New.Value.Bool(false));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GroundType_Bool: {
|
||||
if (right->type.type == GroundType_Bool) {
|
||||
*final = Ground.New.Value.Bool(left->as.Bool == right->as.Bool);
|
||||
*final = Ground.New.BytecodeValue(Ground.New.Value.Bool(left->as.Bool == right->as.Bool));
|
||||
} else {
|
||||
*final = Ground.New.Value.Bool(false);
|
||||
*final = Ground.New.BytecodeValue(Ground.New.Value.Bool(false));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GroundType_String: {
|
||||
if (right->type.type == GroundType_String) {
|
||||
*final = Ground.New.Value.Bool(strcmp(left->as.String.cstr, right->as.String.cstr) == 0);
|
||||
*final = Ground.New.BytecodeValue(Ground.New.Value.Bool(strcmp(left->as.String.cstr, right->as.String.cstr) == 0));
|
||||
} else {
|
||||
*final = Ground.New.Value.Bool(false);
|
||||
*final = Ground.New.BytecodeValue(Ground.New.Value.Bool(false));
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
*final = Ground.New.Value.Bool(false);
|
||||
*final = Ground.New.BytecodeValue(Ground.New.Value.Bool(false));
|
||||
break;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
INEQUAL: {
|
||||
GroundValue* final = HEAP_GET(heap, instruction->args.at[2]);
|
||||
GroundValue* left = HEAP_GET(heap, instruction->args.at[0]);
|
||||
GroundValue* right = HEAP_GET(heap, instruction->args.at[1]);
|
||||
GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[2]);
|
||||
GroundBytecodeValue* left = HEAP_GET(heap, instruction->args.at[0]);
|
||||
GroundBytecodeValue* right = HEAP_GET(heap, instruction->args.at[1]);
|
||||
|
||||
switch (left->type.type) {
|
||||
case GroundType_Int: {
|
||||
switch (right->type.type) {
|
||||
case GroundType_Int: {
|
||||
*final = Ground.New.Value.Bool(left->as.Int != right->as.Int);
|
||||
*final = Ground.New.BytecodeValue(Ground.New.Value.Bool(left->as.Int != right->as.Int));
|
||||
break;
|
||||
}
|
||||
case GroundType_Double: {
|
||||
*final = Ground.New.Value.Bool(left->as.Int != right->as.Double);
|
||||
*final = Ground.New.BytecodeValue(Ground.New.Value.Bool(left->as.Int != right->as.Double));
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
*final = Ground.New.Value.Bool(true);
|
||||
*final = Ground.New.BytecodeValue(Ground.New.Value.Bool(true));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -435,15 +435,15 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
|
||||
case GroundType_Double: {
|
||||
switch (right->type.type) {
|
||||
case GroundType_Int: {
|
||||
*final = Ground.New.Value.Bool(left->as.Double != right->as.Int);
|
||||
*final = Ground.New.BytecodeValue(Ground.New.Value.Bool(left->as.Double != right->as.Int));
|
||||
break;
|
||||
}
|
||||
case GroundType_Double: {
|
||||
*final = Ground.New.Value.Bool(left->as.Double != right->as.Double);
|
||||
*final = Ground.New.BytecodeValue(Ground.New.Value.Bool(left->as.Double != right->as.Double));
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
*final = Ground.New.Value.Bool(true);
|
||||
*final = Ground.New.BytecodeValue(Ground.New.Value.Bool(true));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -451,57 +451,57 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
|
||||
}
|
||||
case GroundType_Char: {
|
||||
if (right->type.type == GroundType_Char) {
|
||||
*final = Ground.New.Value.Bool(left->as.Char != right->as.Char);
|
||||
*final = Ground.New.BytecodeValue(Ground.New.Value.Bool(left->as.Char != right->as.Char));
|
||||
} else {
|
||||
*final = Ground.New.Value.Bool(true);
|
||||
*final = Ground.New.BytecodeValue(Ground.New.Value.Bool(true));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GroundType_Bool: {
|
||||
if (right->type.type == GroundType_Bool) {
|
||||
*final = Ground.New.Value.Bool(left->as.Bool != right->as.Bool);
|
||||
*final = Ground.New.BytecodeValue(Ground.New.Value.Bool(left->as.Bool != right->as.Bool));
|
||||
} else {
|
||||
*final = Ground.New.Value.Bool(true);
|
||||
*final = Ground.New.BytecodeValue(Ground.New.Value.Bool(true));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GroundType_String: {
|
||||
if (right->type.type == GroundType_String) {
|
||||
*final = Ground.New.Value.Bool(strcmp(left->as.String.cstr, right->as.String.cstr) != 0);
|
||||
*final = Ground.New.BytecodeValue(Ground.New.Value.Bool(strcmp(left->as.String.cstr, right->as.String.cstr) != 0));
|
||||
} else {
|
||||
*final = Ground.New.Value.Bool(true);
|
||||
*final = Ground.New.BytecodeValue(Ground.New.Value.Bool(true));
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
*final = Ground.New.Value.Bool(false);
|
||||
*final = Ground.New.BytecodeValue(Ground.New.Value.Bool(false));
|
||||
break;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
NOT: {
|
||||
HEAP_SET(heap, instruction->args.at[1], 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;
|
||||
}
|
||||
GREATER: {
|
||||
GroundValue* final = HEAP_GET(heap, instruction->args.at[2]);
|
||||
GroundValue* left = HEAP_GET(heap, instruction->args.at[0]);
|
||||
GroundValue* right = HEAP_GET(heap, instruction->args.at[1]);
|
||||
GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[2]);
|
||||
GroundBytecodeValue* left = HEAP_GET(heap, instruction->args.at[0]);
|
||||
GroundBytecodeValue* right = HEAP_GET(heap, instruction->args.at[1]);
|
||||
|
||||
switch (left->type.type) {
|
||||
case GroundType_Int: {
|
||||
switch (right->type.type) {
|
||||
case GroundType_Int: {
|
||||
*final = Ground.New.Value.Bool(left->as.Int > right->as.Int);
|
||||
*final = Ground.New.BytecodeValue(Ground.New.Value.Bool(left->as.Int > right->as.Int));
|
||||
break;
|
||||
}
|
||||
case GroundType_Double: {
|
||||
*final = Ground.New.Value.Bool(left->as.Int > right->as.Double);
|
||||
*final = Ground.New.BytecodeValue(Ground.New.Value.Bool(left->as.Int > right->as.Double));
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
*final = Ground.New.Value.Bool(true);
|
||||
*final = Ground.New.BytecodeValue(Ground.New.Value.Bool(true));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -510,45 +510,45 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
|
||||
case GroundType_Double: {
|
||||
switch (right->type.type) {
|
||||
case GroundType_Int: {
|
||||
*final = Ground.New.Value.Bool(left->as.Double > right->as.Int);
|
||||
*final = Ground.New.BytecodeValue(Ground.New.Value.Bool(left->as.Double > right->as.Int));
|
||||
break;
|
||||
}
|
||||
case GroundType_Double: {
|
||||
*final = Ground.New.Value.Bool(left->as.Double > right->as.Double);
|
||||
*final = Ground.New.BytecodeValue(Ground.New.Value.Bool(left->as.Double > right->as.Double));
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
*final = Ground.New.Value.Bool(true);
|
||||
*final = Ground.New.BytecodeValue(Ground.New.Value.Bool(true));
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
*final = Ground.New.Value.Bool(false);
|
||||
*final = Ground.New.BytecodeValue(Ground.New.Value.Bool(false));
|
||||
break;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
LESSER: {
|
||||
GroundValue* final = HEAP_GET(heap, instruction->args.at[2]);
|
||||
GroundValue* left = HEAP_GET(heap, instruction->args.at[0]);
|
||||
GroundValue* right = HEAP_GET(heap, instruction->args.at[1]);
|
||||
GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[2]);
|
||||
GroundBytecodeValue* left = HEAP_GET(heap, instruction->args.at[0]);
|
||||
GroundBytecodeValue* right = HEAP_GET(heap, instruction->args.at[1]);
|
||||
|
||||
switch (left->type.type) {
|
||||
case GroundType_Int: {
|
||||
switch (right->type.type) {
|
||||
case GroundType_Int: {
|
||||
*final = Ground.New.Value.Bool(left->as.Int < right->as.Int);
|
||||
*final = Ground.New.BytecodeValue(Ground.New.Value.Bool(left->as.Int < right->as.Int));
|
||||
break;
|
||||
}
|
||||
case GroundType_Double: {
|
||||
*final = Ground.New.Value.Bool(left->as.Int < right->as.Double);
|
||||
*final = Ground.New.BytecodeValue(Ground.New.Value.Bool(left->as.Int < right->as.Double));
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
*final = Ground.New.Value.Bool(true);
|
||||
*final = Ground.New.BytecodeValue(Ground.New.Value.Bool(true));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -557,51 +557,51 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
|
||||
case GroundType_Double: {
|
||||
switch (right->type.type) {
|
||||
case GroundType_Int: {
|
||||
*final = Ground.New.Value.Bool(left->as.Double < right->as.Int);
|
||||
*final = Ground.New.BytecodeValue(Ground.New.Value.Bool(left->as.Double < right->as.Int));
|
||||
break;
|
||||
}
|
||||
case GroundType_Double: {
|
||||
*final = Ground.New.Value.Bool(left->as.Double < right->as.Double);
|
||||
*final = Ground.New.BytecodeValue(Ground.New.Value.Bool(left->as.Double < right->as.Double));
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
*final = Ground.New.Value.Bool(true);
|
||||
*final = Ground.New.BytecodeValue(Ground.New.Value.Bool(true));
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
*final = Ground.New.Value.Bool(false);
|
||||
*final = Ground.New.BytecodeValue(Ground.New.Value.Bool(false));
|
||||
break;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
AND: {
|
||||
GroundValue* final = HEAP_GET(heap, instruction->args.at[2]);
|
||||
GroundValue* left = HEAP_GET(heap, instruction->args.at[0]);
|
||||
GroundValue* right = HEAP_GET(heap, instruction->args.at[1]);
|
||||
GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[2]);
|
||||
GroundBytecodeValue* left = HEAP_GET(heap, instruction->args.at[0]);
|
||||
GroundBytecodeValue* right = HEAP_GET(heap, instruction->args.at[1]);
|
||||
|
||||
*final = 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;
|
||||
}
|
||||
OR: {
|
||||
GroundValue* final = HEAP_GET(heap, instruction->args.at[2]);
|
||||
GroundValue* left = HEAP_GET(heap, instruction->args.at[0]);
|
||||
GroundValue* right = HEAP_GET(heap, instruction->args.at[1]);
|
||||
GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[2]);
|
||||
GroundBytecodeValue* left = HEAP_GET(heap, instruction->args.at[0]);
|
||||
GroundBytecodeValue* right = HEAP_GET(heap, instruction->args.at[1]);
|
||||
|
||||
*final = 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;
|
||||
}
|
||||
XOR: {
|
||||
GroundValue* final = HEAP_GET(heap, instruction->args.at[2]);
|
||||
GroundValue* left = HEAP_GET(heap, instruction->args.at[0]);
|
||||
GroundValue* right = HEAP_GET(heap, instruction->args.at[1]);
|
||||
GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[2]);
|
||||
GroundBytecodeValue* left = HEAP_GET(heap, instruction->args.at[0]);
|
||||
GroundBytecodeValue* right = HEAP_GET(heap, instruction->args.at[1]);
|
||||
|
||||
*final = 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;
|
||||
}
|
||||
@@ -612,12 +612,12 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
|
||||
return -1;
|
||||
}
|
||||
STOI: {
|
||||
GroundValue* final = HEAP_GET(heap, instruction->args.at[1]);
|
||||
GroundValue* in = HEAP_GET(heap, instruction->args.at[0]);
|
||||
GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[1]);
|
||||
GroundBytecodeValue* in = HEAP_GET(heap, instruction->args.at[0]);
|
||||
|
||||
char* status = NULL;
|
||||
|
||||
*final = Ground.New.Value.Int(strtoll(in->as.String.cstr, &status, 0));
|
||||
*final = Ground.New.BytecodeValue(Ground.New.Value.Int(strtoll(in->as.String.cstr, &status, 0)));
|
||||
|
||||
if (status != in->as.String.cstr) {
|
||||
Ground.Flags.error = true;
|
||||
@@ -627,12 +627,12 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
|
||||
return -1;
|
||||
}
|
||||
STOD: {
|
||||
GroundValue* final = HEAP_GET(heap, instruction->args.at[1]);
|
||||
GroundValue* in = HEAP_GET(heap, instruction->args.at[0]);
|
||||
GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[1]);
|
||||
GroundBytecodeValue* in = HEAP_GET(heap, instruction->args.at[0]);
|
||||
|
||||
char* status = NULL;
|
||||
|
||||
*final = Ground.New.Value.Double(strtod(in->as.String.cstr, &status));
|
||||
*final = Ground.New.BytecodeValue(Ground.New.Value.Double(strtod(in->as.String.cstr, &status)));
|
||||
|
||||
if (status != in->as.String.cstr) {
|
||||
Ground.Flags.error = true;
|
||||
@@ -642,24 +642,24 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
|
||||
return -1;
|
||||
}
|
||||
ITOC: {
|
||||
GroundValue* final = HEAP_GET(heap, instruction->args.at[1]);
|
||||
GroundValue* in = HEAP_GET(heap, instruction->args.at[0]);
|
||||
GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[1]);
|
||||
GroundBytecodeValue* in = HEAP_GET(heap, instruction->args.at[0]);
|
||||
|
||||
*final = Ground.New.Value.Char((char)in->as.Int);
|
||||
*final = Ground.New.BytecodeValue(Ground.New.Value.Char((char)in->as.Int));
|
||||
|
||||
return -1;
|
||||
}
|
||||
CTOI: {
|
||||
GroundValue* final = HEAP_GET(heap, instruction->args.at[1]);
|
||||
GroundValue* in = HEAP_GET(heap, instruction->args.at[0]);
|
||||
GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[1]);
|
||||
GroundBytecodeValue* in = HEAP_GET(heap, instruction->args.at[0]);
|
||||
|
||||
*final = Ground.New.Value.Int((int64_t)in->as.Char);
|
||||
*final = Ground.New.BytecodeValue(Ground.New.Value.Int((int64_t)in->as.Char));
|
||||
|
||||
return -1;
|
||||
}
|
||||
TOSTRING: {
|
||||
GroundValue* final = HEAP_GET(heap, instruction->args.at[1]);
|
||||
GroundValue* in = HEAP_GET(heap, instruction->args.at[0]);
|
||||
GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[1]);
|
||||
GroundBytecodeValue* in = HEAP_GET(heap, instruction->args.at[0]);
|
||||
|
||||
char buf[4096];
|
||||
|
||||
@@ -681,7 +681,7 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
|
||||
break;
|
||||
}
|
||||
case GroundType_String: {
|
||||
*in = Ground.New.Value.String(final->as.String);
|
||||
*in = Ground.New.BytecodeValue(Ground.New.Value.String(final->as.String));
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -692,7 +692,7 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
|
||||
}
|
||||
}
|
||||
|
||||
*in = Ground.New.Value.String(Ground.New.String(buf));
|
||||
*in = Ground.New.BytecodeValue(Ground.New.Value.String(Ground.New.String(buf)));
|
||||
|
||||
return -1;
|
||||
}
|
||||
@@ -744,9 +744,9 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
|
||||
return -1;
|
||||
}
|
||||
DROP: {
|
||||
GroundValue* in = HEAP_GET(heap, instruction->args.at[0]);
|
||||
Ground.Free.Value(in);
|
||||
*in = Ground.New.Value.Int(0);
|
||||
GroundBytecodeValue* in = HEAP_GET(heap, instruction->args.at[0]);
|
||||
Ground.Free.BytecodeValue(in);
|
||||
*in = Ground.New.BytecodeValue(Ground.New.Value.Int(0));
|
||||
return -1;
|
||||
}
|
||||
LICENSE: {
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
static GroundValue readValue(FILE* f) {
|
||||
GroundValue v = {0};
|
||||
static GroundBytecodeValue readValue(FILE* f) {
|
||||
GroundBytecodeValue v = {0};
|
||||
uint8_t tag;
|
||||
if (fread(&tag, 1, 1, f) != 1) {
|
||||
Ground.Log.Error("failed to read value type in Ground.Bytecode.load");
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "../../include/ground.h"
|
||||
#include <stdio.h>
|
||||
|
||||
static void writeValue(FILE* f, GroundValue* v) {
|
||||
static void writeValue(FILE* f, GroundBytecodeValue* v) {
|
||||
switch (v->type.type) {
|
||||
case GroundType_Int: {
|
||||
uint8_t tag = 0;
|
||||
|
||||
33
src/Free/BytecodeValue.c
Normal file
33
src/Free/BytecodeValue.c
Normal file
@@ -0,0 +1,33 @@
|
||||
#include "../../include/ground.h"
|
||||
|
||||
void _GroundFreeBytecodeValue(GroundBytecodeValue* in) {
|
||||
|
||||
// TODO: Implement all this
|
||||
|
||||
switch (in->type.type) {
|
||||
case GroundType_String: {
|
||||
Ground.Free.String(&in->as.String);
|
||||
break;
|
||||
}
|
||||
case GroundType_List: {
|
||||
// Ground.Free.List(&in->as.List);
|
||||
break;
|
||||
}
|
||||
case GroundType_Function: {
|
||||
// Ground.Free.Function(&in->as.Function);
|
||||
break;
|
||||
}
|
||||
case GroundType_Struct: {
|
||||
// Ground.Free.Struct(&in->as.Struct);
|
||||
break;
|
||||
}
|
||||
case GroundType_Object: {
|
||||
// Ground.Free.Object(&in->as.Object);
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -196,7 +196,7 @@ GroundBytecode _GroundNewBytecode(GroundProgram* program, GroundState* state) {
|
||||
|
||||
// Copy constants into heap at their assigned offsets
|
||||
HASH_ITER(hh, state->variables, s, tmp) {
|
||||
bytecode.heap.heap[s->_offset] = Ground.Copy.Value(&s->value);
|
||||
bytecode.heap.heap[s->_offset] = Ground.New.BytecodeValue(Ground.Copy.Value(&s->value));
|
||||
if (Ground.Flags.error) return bytecode;
|
||||
}
|
||||
|
||||
|
||||
50
src/New/BytecodeValue.c
Normal file
50
src/New/BytecodeValue.c
Normal file
@@ -0,0 +1,50 @@
|
||||
#include "../../include/ground.h"
|
||||
|
||||
GroundBytecodeValue _GroundNewBytecodeValue(GroundValue value) {
|
||||
|
||||
GroundBytecodeValue bv = {
|
||||
.type = value.type
|
||||
};
|
||||
|
||||
switch (value.type.type) {
|
||||
// Literal values, no need for compilcated copy
|
||||
case GroundType_Int: {
|
||||
bv.as.Int = value.as.Int;
|
||||
break;
|
||||
}
|
||||
case GroundType_Double: {
|
||||
bv.as.Double = value.as.Double;
|
||||
break;
|
||||
}
|
||||
case GroundType_Bool: {
|
||||
bv.as.Bool = value.as.Bool;
|
||||
break;
|
||||
}
|
||||
case GroundType_Char: {
|
||||
bv.as.Char = value.as.Char;
|
||||
break;
|
||||
}
|
||||
case GroundType_String: {
|
||||
bv.as.String = Ground.Copy.String(&value.as.String);
|
||||
break;
|
||||
}
|
||||
case GroundType_Function: {
|
||||
// TODO - convert to bytecode function
|
||||
break;
|
||||
}
|
||||
case GroundType_List: {
|
||||
// TODO - convert to bytecode list
|
||||
break;
|
||||
}
|
||||
case GroundType_Struct: {
|
||||
// TODO - convert to bytecode struct
|
||||
break;
|
||||
}
|
||||
case GroundType_Object: {
|
||||
// TODO - convert to bytecode object
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return bv;
|
||||
}
|
||||
@@ -1,11 +1,14 @@
|
||||
#include "../../include/ground.h"
|
||||
|
||||
void _GroundProgramExecute(GroundProgram* program, GroundState* state) {
|
||||
|
||||
// TODO:
|
||||
// - Preprocess functions
|
||||
// - Preprocess structs
|
||||
// - Add them to state
|
||||
|
||||
Ground.Internal.run(program, state);
|
||||
// Preprocess program, then run
|
||||
GroundProgram pp = Ground.Program.preprocess(program, state);
|
||||
if (Ground.Flags.error) {
|
||||
return;
|
||||
}
|
||||
Ground.Internal.run(&pp, state);
|
||||
if (Ground.Flags.error) {
|
||||
return;
|
||||
}
|
||||
Ground.Free.Program(&pp);
|
||||
}
|
||||
|
||||
113
src/Program/preprocess.c
Normal file
113
src/Program/preprocess.c
Normal file
@@ -0,0 +1,113 @@
|
||||
#include "../../include/ground.h"
|
||||
|
||||
GroundProgram _GroundProgramPreprocess(GroundProgram* program, GroundState* state) {
|
||||
|
||||
GroundProgram newProgram = Ground.New.Program();
|
||||
|
||||
for (GroundSize i = 0; i < program->len; i++) {
|
||||
switch (program->at[i].type) {
|
||||
case GroundInstruction_FUN: {
|
||||
|
||||
GroundFunction function = Ground.New.Function(state);
|
||||
|
||||
// Parse signature
|
||||
GroundInstruction* sig = &program->at[i];
|
||||
char* id = sig->args.at[0].as.ref->string;
|
||||
|
||||
for (GroundSize j = 1; i < sig->args.len - 1; i++) {
|
||||
GroundArg* arg = &sig->args.at[j];
|
||||
|
||||
// Ignore type annotations, this can be taken care of in another function
|
||||
if (arg->type == GroundArg_TypeRef) {
|
||||
continue;
|
||||
}
|
||||
char* argId = arg->as.ref->string;
|
||||
Ground.Function.appendArg(&function, argId);
|
||||
}
|
||||
|
||||
// Add instructions to function
|
||||
GroundSize funCount = 1;
|
||||
GroundSize structCount = 0;
|
||||
|
||||
for (;;) {
|
||||
i++;
|
||||
if (i >= program->len) {
|
||||
Ground.Flags.error = true;
|
||||
Ground.Log.Error("expecting ENDFUN instruction, reached end of program in Ground.Program.Preprocess");
|
||||
return newProgram;
|
||||
}
|
||||
GroundInstruction* inst = &program->at[i];
|
||||
switch (inst->type) {
|
||||
case GroundInstruction_FUN: {
|
||||
funCount++;
|
||||
break;
|
||||
}
|
||||
case GroundInstruction_ENDFUN: {
|
||||
if (funCount < 1) {
|
||||
Ground.Flags.error = true;
|
||||
Ground.Log.Error("extra ENDFUN instruction (expecting ENDSTRUCT before) in Ground.Program.Preprocess");
|
||||
return newProgram;
|
||||
}
|
||||
funCount--;
|
||||
break;
|
||||
}
|
||||
case GroundInstruction_STRUCT: {
|
||||
structCount++;
|
||||
break;
|
||||
}
|
||||
case GroundInstruction_ENDSTRUCT: {
|
||||
if (structCount < 1) {
|
||||
Ground.Flags.error = true;
|
||||
Ground.Log.Error("extra ENDSTRUCT instruction (expecting ENDFUN before) in Ground.Program.Preprocess");
|
||||
return newProgram;
|
||||
}
|
||||
structCount--;
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
|
||||
if (funCount == 0 && structCount == 0) {
|
||||
// We done
|
||||
break;
|
||||
}
|
||||
|
||||
Ground.Function.appendInstruction(&function, *inst);
|
||||
}
|
||||
|
||||
// Preprocess function's body
|
||||
GroundProgram functionBody = Ground.Program.preprocess(function.program.ground, function.closure);
|
||||
if (Ground.Flags.error) {
|
||||
return newProgram;
|
||||
}
|
||||
|
||||
Ground.Free.Program(function.program.ground);
|
||||
*function.program.ground = functionBody;
|
||||
|
||||
GroundVariable* var = malloc(sizeof(GroundVariable));
|
||||
if (var == NULL) {
|
||||
Ground.Flags.error = true;
|
||||
Ground.Log.Error("malloc failed in Ground.Program.Preprocess");
|
||||
return newProgram;
|
||||
}
|
||||
|
||||
snprintf(var->name, 2047, "%s", id);
|
||||
var->value = Ground.New.Value.Function(function);
|
||||
|
||||
HASH_ADD_STR(state->variables, name, var);
|
||||
|
||||
break;
|
||||
}
|
||||
case GroundInstruction_STRUCT: {
|
||||
// TODO: Preprocess structs
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
Ground.Program.append(&newProgram, program->at[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return newProgram;
|
||||
|
||||
}
|
||||
67
src/Stringify/BytecodeValue.c
Normal file
67
src/Stringify/BytecodeValue.c
Normal file
@@ -0,0 +1,67 @@
|
||||
#include "../../include/ground.h"
|
||||
#include <inttypes.h>
|
||||
|
||||
char* _GroundStringifyBytecodeValue(GroundBytecodeValue* value) {
|
||||
switch (value->type.type) {
|
||||
case GroundType_Int: {
|
||||
char* buf = malloc(snprintf(NULL, 0, "%" PRId64, value->as.Int) + 1);
|
||||
if (buf == NULL) {
|
||||
Ground.Flags.error = true;
|
||||
Ground.Log.Error("malloc failed in Ground.Stringify.Value");
|
||||
return NULL;
|
||||
}
|
||||
sprintf(buf, "%" PRId64, value->as.Int);
|
||||
return buf;
|
||||
}
|
||||
case GroundType_Double: {
|
||||
char* buf = malloc(snprintf(NULL, 0, "%f", value->as.Double) + 1);
|
||||
if (buf == NULL) {
|
||||
Ground.Flags.error = true;
|
||||
Ground.Log.Error("malloc failed in Ground.Stringify.Value");
|
||||
return NULL;
|
||||
}
|
||||
sprintf(buf, "%f", value->as.Double);
|
||||
return buf;
|
||||
}
|
||||
case GroundType_Char: {
|
||||
char* buf = malloc(snprintf(NULL, 0, "%c", value->as.Char) + 1);
|
||||
if (buf == NULL) {
|
||||
Ground.Flags.error = true;
|
||||
Ground.Log.Error("malloc failed in Ground.Stringify.Value");
|
||||
return NULL;
|
||||
}
|
||||
sprintf(buf, "%c", value->as.Char);
|
||||
return buf;
|
||||
}
|
||||
case GroundType_Bool: {
|
||||
char* buf = malloc(6); // max(len(true), len(false)) + 1
|
||||
if (buf == NULL) {
|
||||
Ground.Flags.error = true;
|
||||
Ground.Log.Error("malloc failed in Ground.Stringify.Value");
|
||||
return NULL;
|
||||
}
|
||||
sprintf(buf, value->as.Bool ? "true" : "false");
|
||||
return buf;
|
||||
}
|
||||
case GroundType_String: {
|
||||
return Ground.Stringify.String(&value->as.String);
|
||||
}
|
||||
case GroundType_List: {
|
||||
// TODO implement list stringification
|
||||
}
|
||||
case GroundType_Function: {
|
||||
// TODO implement function stringification
|
||||
}
|
||||
case GroundType_Struct: {
|
||||
// TODO implement struct stringification
|
||||
}
|
||||
case GroundType_Object: {
|
||||
// TODO implement object stringification
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Ground.Flags.error = true;
|
||||
Ground.Log.Error("FIXME implement all cases in Ground.Stringify.Value");
|
||||
return NULL;
|
||||
}
|
||||
@@ -7,7 +7,7 @@ char* _GroundStringifyHeap(GroundBytecodeHeap* heap) {
|
||||
Estr heapString = CREATE_ESTR("");
|
||||
|
||||
for (GroundSize i = 0; i < heap->len; i++) {
|
||||
char* string = Ground.Stringify.Value(&heap->heap[i]);
|
||||
char* string = Ground.Stringify.BytecodeValue(&heap->heap[i]);
|
||||
if (Ground.Flags.error) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -82,6 +82,7 @@ int main(int argc, char** argv) {
|
||||
}
|
||||
case ARGS_DISASSEMBLE: {
|
||||
fprintf(stderr, "Not yet implemented");
|
||||
|
||||
break;
|
||||
}
|
||||
case ARGS_HELP: {
|
||||
|
||||
@@ -33,6 +33,7 @@ GroundType _GroundNewType(enum GroundTypeType type, ...);
|
||||
GroundIdentifier* _GroundNewIdentifier(const char* id);
|
||||
|
||||
GroundBytecode _GroundNewBytecode (GroundProgram* program, GroundState* state);
|
||||
GroundBytecodeValue _GroundNewBytecodeValue(GroundValue value);
|
||||
|
||||
void _GroundFreeValue(GroundValue* in);
|
||||
void _GroundFreeList(GroundList* in);
|
||||
@@ -48,6 +49,8 @@ void _GroundFreeState(GroundState* in);
|
||||
|
||||
void _GroundFreeIdentifier(GroundIdentifier* identifier);
|
||||
|
||||
void _GroundFreeBytecodeValue(GroundBytecodeValue* in);
|
||||
|
||||
|
||||
GroundValue _GroundCopyValue(GroundValue* in);
|
||||
GroundList _GroundCopyList(GroundList* in);
|
||||
@@ -73,6 +76,7 @@ int64_t _GroundInstructionExecute(GroundInstruction* instruction, GroundValue* h
|
||||
|
||||
void _GroundProgramAppend(GroundProgram* program, GroundInstruction instruction);
|
||||
void _GroundProgramExecute(GroundProgram* program, GroundState* state);
|
||||
GroundProgram _GroundProgramPreprocess(GroundProgram* program, GroundState* state);
|
||||
|
||||
|
||||
void _GroundFunctionAppendInstruction(GroundFunction* function, GroundInstruction instruction);
|
||||
@@ -114,6 +118,8 @@ char* _GroundStringifyProgram(GroundProgram* program);
|
||||
char* _GroundStringifyString(GroundString* string);
|
||||
char* _GroundStringifyValue(GroundValue* value);
|
||||
|
||||
char* _GroundStringifyBytecodeValue(GroundBytecodeValue* value);
|
||||
|
||||
|
||||
struct _Ground Ground = {
|
||||
|
||||
@@ -158,6 +164,7 @@ struct _Ground Ground = {
|
||||
.Identifier = _GroundNewIdentifier,
|
||||
|
||||
.Bytecode = _GroundNewBytecode,
|
||||
.BytecodeValue = _GroundNewBytecodeValue,
|
||||
},
|
||||
|
||||
.Free = {
|
||||
@@ -174,6 +181,8 @@ struct _Ground Ground = {
|
||||
.State = _GroundFreeState,
|
||||
|
||||
.Identifier = _GroundFreeIdentifier,
|
||||
|
||||
.BytecodeValue = _GroundFreeBytecodeValue,
|
||||
},
|
||||
|
||||
.Copy = {
|
||||
@@ -204,6 +213,7 @@ struct _Ground Ground = {
|
||||
.Program = {
|
||||
.append = _GroundProgramAppend,
|
||||
.execute = _GroundProgramExecute,
|
||||
.preprocess = _GroundProgramPreprocess,
|
||||
},
|
||||
|
||||
.Function = {
|
||||
@@ -256,5 +266,7 @@ struct _Ground Ground = {
|
||||
.Program = _GroundStringifyProgram,
|
||||
.String = _GroundStringifyString,
|
||||
.Value = _GroundStringifyValue,
|
||||
|
||||
.BytecodeValue = _GroundStringifyBytecodeValue,
|
||||
},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user