Pull stuff in again #17
@@ -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)
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
17
tests/struct.grnd
Normal 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
|
||||||
Reference in New Issue
Block a user