Compare commits

..

7 Commits

8 changed files with 128 additions and 3 deletions

View File

@@ -82,7 +82,7 @@ build
- [x] Return values (type checked) - [x] Return values (type checked)
- [x] Arguments for functions - [x] Arguments for functions
- [x] Jumping within functions - [x] Jumping within functions
- [ ] Custom data structures - [x] Custom data structures
- [ ] Working with external libraries - [ ] Working with external libraries
## Debugger ## Debugger
@@ -114,6 +114,7 @@ Supported instructions so far:
* inequal * inequal
* greater * greater
* lesser * lesser
* not
* jump * jump
* if * if
* @ (label creation) * @ (label creation)

View File

@@ -14,7 +14,7 @@
#include <uthash.h> #include <uthash.h>
typedef enum GroundInstType { typedef enum GroundInstType {
IF, JUMP, END, INPUT, PRINT, PRINTLN, SET, GETTYPE, EXISTS, SETLIST, SETLISTAT, GETLISTAT, GETLISTSIZE, LISTAPPEND, GETSTRSIZE, GETSTRCHARAT, ADD, SUBTRACT, MULTIPLY, DIVIDE, EQUAL, INEQUAL, NOT, GREATER, LESSER, STOI, STOD, TOSTRING, FUN, RETURN, ENDFUN, PUSHARG, CALL, STRUCT, ENDSTRUCT, INIT, USE, EXTERN, CREATELABEL, PAUSE, DROP, ERRORCMD IF, JUMP, END, INPUT, PRINT, PRINTLN, SET, GETTYPE, EXISTS, SETLIST, SETLISTAT, GETLISTAT, GETLISTSIZE, LISTAPPEND, GETSTRSIZE, GETSTRCHARAT, ADD, SUBTRACT, MULTIPLY, DIVIDE, EQUAL, INEQUAL, NOT, GREATER, LESSER, STOI, STOD, TOSTRING, FUN, RETURN, ENDFUN, PUSHARG, CALL, STRUCT, ENDSTRUCT, INIT, GETFIELD, SETFIELD, USE, EXTERN, CREATELABEL, PAUSE, DROP, ERRORCMD
} GroundInstType; } GroundInstType;
typedef enum GroundValueType { typedef enum GroundValueType {
@@ -58,6 +58,7 @@ typedef struct GroundError {
*/ */
typedef struct GroundValue { typedef struct GroundValue {
GroundValueType type; GroundValueType type;
struct GroundStruct* customType;
union { union {
int64_t intVal; int64_t intVal;
double doubleVal; double doubleVal;
@@ -170,6 +171,7 @@ GroundProgram groundCreateProgram();
void groundAddInstructionToProgram(GroundProgram* program, GroundInstruction instruction); void groundAddInstructionToProgram(GroundProgram* program, GroundInstruction instruction);
GroundValue groundRunProgram(GroundProgram* program); GroundValue groundRunProgram(GroundProgram* program);
void groundPrintProgram(GroundProgram* program); void groundPrintProgram(GroundProgram* program);
char* groundCompileProgram(GroundProgram* program);
GroundInstruction groundCreateInstruction(GroundInstType type); GroundInstruction groundCreateInstruction(GroundInstType type);
void groundAddValueToInstruction(GroundInstruction* inst, GroundValue value); void groundAddValueToInstruction(GroundInstruction* inst, GroundValue value);

View File

@@ -221,6 +221,33 @@ char* compileGroundProgram(GroundProgram* program) {
break; break;
} }
case NOT: {
if (gi.args.length < 2) {
runtimeError(TOO_FEW_ARGS, "Expecting 2 args", &gi, i);
}
if (gi.args.length > 2) {
runtimeError(TOO_MANY_ARGS, "Expecting 2 args", &gi, i);
}
if (gi.args.args[0].type != VALUE && gi.args.args[0].type != VALREF) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting an Int (for now) for arg 1", &gi, i);
}
if (gi.args.args[1].type != DIRREF) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting a DirectRef", &gi, i);
}
char* varName = gi.args.args[1].value.refName;
APPEND_ESTR(start, " ; not\n");
APPEND_ESTR(start, " mov rax, ");
APPEND_ESTR(start, processValueString(gi.args.args[0]));
APPEND_ESTR(start, "\n");
APPEND_ESTR(start, " xor rax, 1\n");
APPEND_ESTR(start, " mov [");
APPEND_ESTR(start, varName);
APPEND_ESTR(start, "], rax\n");
break;
}
case ADD: { case ADD: {
if (gi.args.length < 3) { if (gi.args.length < 3) {
runtimeError(TOO_FEW_ARGS, "Expecting 2 args for add instruction", &gi, i); runtimeError(TOO_FEW_ARGS, "Expecting 2 args for add instruction", &gi, i);

View File

@@ -1,5 +1,6 @@
#include "parser.h" #include "parser.h"
#include "interpreter.h" #include "interpreter.h"
#include "compiler.h"
#include "types.h" #include "types.h"
#include <stdlib.h> #include <stdlib.h>
@@ -123,3 +124,7 @@ void groundAddValueToScope(GroundScope* gs, const char* name, GroundValue value)
void groundAddFieldToStruct(GroundStruct* gstruct, char* name, GroundValue field) { void groundAddFieldToStruct(GroundStruct* gstruct, char* name, GroundValue field) {
addFieldToStruct(gstruct, name, field); addFieldToStruct(gstruct, name, field);
} }
char* groundCompileProgram(GroundProgram* program) {
return compileGroundProgram(program);
}

View File

@@ -2028,6 +2028,77 @@ GroundValue interpretGroundInstruction(GroundInstruction inst, GroundScope* scop
break; break;
} }
/*
* OBJECTS
* Allows manipulation of Ground objects.
*/
// getfield $obj &field &result
case GETFIELD: {
if (in->args.length < 3) {
runtimeError(TOO_FEW_ARGS, "Expecting 3 args", in, currentInstruction);
}
if (in->args.length > 3) {
runtimeError(TOO_MANY_ARGS, "Expecting 3 args", in, currentInstruction);
}
if (in->args.args[0].type != VALUE) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting an Object for arg 1", in, currentInstruction);
}
if (in->args.args[0].value.value.type != CUSTOM) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting an Object for arg 1", in, currentInstruction);
}
if (in->args.args[1].type != DIRREF) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting a DirectRef for arg 2", in, currentInstruction);
}
if (in->args.args[2].type != DIRREF) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting a DirectRef for arg 3", in, currentInstruction);
}
GroundObjectField* field = findField(*in->args.args[0].value.value.data.customVal, in->args.args[1].value.refName);
if (field == NULL) {
runtimeError(UNKNOWN_VARIABLE, "Struct does not contain that field", in, currentInstruction);
}
addVariable(scope->variables, in->args.args[2].value.refName, field->value);
break;
}
// setfield &obj &field $value
case SETFIELD: {
if (in->args.length < 3) {
runtimeError(TOO_FEW_ARGS, "Expecting 3 args", in, currentInstruction);
}
if (in->args.length > 3) {
runtimeError(TOO_MANY_ARGS, "Expecting 3 args", in, currentInstruction);
}
if (in->args.args[0].type != DIRREF) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting a DirectRef to an Object for arg 1", in, currentInstruction);
}
if (in->args.args[1].type != DIRREF) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting a DirectRef for arg 2", in, currentInstruction);
}
if (in->args.args[2].type != VALUE) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting a Value for arg 3", in, currentInstruction);
}
GroundVariable* var = findVariable(*scope->variables, in->args.args[0].value.refName);
if (var == NULL) {
runtimeError(UNKNOWN_VARIABLE, "Could not find that object", in, currentInstruction);
}
if (var->value.type != CUSTOM) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting a DirectRef to an Object for arg 1", in, currentInstruction);
}
GroundObjectField* field = findField(*var->value.data.customVal, in->args.args[1].value.refName);
if (field == NULL) {
runtimeError(UNKNOWN_VARIABLE, "Struct does not contain that field", in, currentInstruction);
}
if (field->value.type != in->args.args[2].value.value.type) {
runtimeError(ARG_TYPE_MISMATCH, "Field type and provided type do not match", in, currentInstruction);
}
field->value = copyGroundValue(&in->args.args[2].value.value);
break;
}
case DROP: { case DROP: {
if (in->args.length < 1) { if (in->args.length < 1) {
runtimeError(TOO_FEW_ARGS, "Expecting 1 arg", in, currentInstruction); runtimeError(TOO_FEW_ARGS, "Expecting 1 arg", in, currentInstruction);

View File

@@ -168,6 +168,8 @@ static GroundInstType getInstructionType(const char* inst) {
if (strcmp(inst, "struct") == 0) return STRUCT; if (strcmp(inst, "struct") == 0) return STRUCT;
if (strcmp(inst, "endstruct") == 0) return ENDSTRUCT; if (strcmp(inst, "endstruct") == 0) return ENDSTRUCT;
if (strcmp(inst, "init") == 0) return INIT; if (strcmp(inst, "init") == 0) return INIT;
if (strcmp(inst, "getfield") == 0) return GETFIELD;
if (strcmp(inst, "setfield") == 0) return SETFIELD;
if (strcmp(inst, "use") == 0) return USE; if (strcmp(inst, "use") == 0) return USE;
if (strcmp(inst, "extern") == 0) return EXTERN; if (strcmp(inst, "extern") == 0) return EXTERN;
if (strcmp(inst, "drop") == 0) return DROP; if (strcmp(inst, "drop") == 0) return DROP;

View File

@@ -9,7 +9,7 @@
#include "include/uthash.h" #include "include/uthash.h"
typedef enum GroundInstType { typedef enum GroundInstType {
IF, JUMP, END, INPUT, PRINT, PRINTLN, SET, GETTYPE, EXISTS, SETLIST, SETLISTAT, GETLISTAT, GETLISTSIZE, LISTAPPEND, GETSTRSIZE, GETSTRCHARAT, ADD, SUBTRACT, MULTIPLY, DIVIDE, EQUAL, INEQUAL, NOT, GREATER, LESSER, STOI, STOD, TOSTRING, FUN, RETURN, ENDFUN, PUSHARG, CALL, STRUCT, ENDSTRUCT, INIT, USE, EXTERN, CREATELABEL, PAUSE, DROP, ERRORCMD IF, JUMP, END, INPUT, PRINT, PRINTLN, SET, GETTYPE, EXISTS, SETLIST, SETLISTAT, GETLISTAT, GETLISTSIZE, LISTAPPEND, GETSTRSIZE, GETSTRCHARAT, ADD, SUBTRACT, MULTIPLY, DIVIDE, EQUAL, INEQUAL, NOT, GREATER, LESSER, STOI, STOD, TOSTRING, FUN, RETURN, ENDFUN, PUSHARG, CALL, STRUCT, ENDSTRUCT, INIT, GETFIELD, SETFIELD, USE, EXTERN, CREATELABEL, PAUSE, DROP, ERRORCMD
} GroundInstType; } GroundInstType;
typedef enum GroundValueType { typedef enum GroundValueType {

17
tests/struct.grnd Normal file
View File

@@ -0,0 +1,17 @@
struct -point
init &x -int
init &y -int
endstruct
init &mypoint -point
setfield &mypoint &x 53
setfield &mypoint &y 32
getfield $mypoint &x &value
println $value
getfield $mypoint &y &value
println $value