forked from ground/cground
Add struct field access
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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