Access variables in structs

This commit is contained in:
2025-09-20 17:44:50 +10:00
parent 39dc320f5d
commit ab4b7e6aae
2 changed files with 83 additions and 49 deletions

View File

@@ -34,7 +34,6 @@
Happy coding!
*/
#include <cinttypes>
#include <iostream>
#include <string>
#include <variant>
@@ -470,6 +469,10 @@ bool isFunction(string in) {
else return false;
}
bool isReferencingStruct(string in) {
return in.find('.') != string::npos;
}
/*
getType function
This function determines the type of a value inside a string based on the is*
@@ -569,6 +572,7 @@ Literal exec(vector<Instruction> in, bool executingFunction) {
if (l.inst == Instructions::Endstruct) {
processingStruct = false;
procStructName = "";
continue;
} else if (l.inst == Instructions::Fun) {
if (l.args.size() < 2) {
error("Could not find all arguments required for Fun inbuilt");
@@ -618,65 +622,92 @@ Literal exec(vector<Instruction> in, bool executingFunction) {
newFunction.args.push_back(newArg);
}
functions[fnName] = newFunction;
structs[procStructName].functions[fnName] = newFunction;
processingFunction = true;
procFnName = fnName;
} else if (l.inst == Instructions::Init) {
if (l.args.size() < 2) {
error("Could not find all arguments required for Init inbuilt");
}
{
Direct varRef;
TypeRef type;
if (holds_alternative<Direct>(l.args[0])) {
varRef = get<Direct>(l.args[0]);
} else {
error("First argument of init must be a direct reference");
}
if (holds_alternative<TypeRef>(l.args[1])) {
type = get<TypeRef>(l.args[1]);
} else {
error("Second argument of init must be a type reference");
}
Literal newVal;
if (type.isCustomType) {
newVal.val = structs[type.customType];
} else {
Literal newVal;
switch (type.type) {
case Types::Int:
newVal.val = 0;
break;
case Types::Double:
newVal.val = double(0.0);
break;
case Types::String:
newVal.val = "";
break;
case Types::Char:
newVal.val = '\0';
break;
case Types::Bool:
newVal.val = false;
break;
default:
error("You dingus you werent supposed to get here");
}
}
variables[varRef.varName] = newVal;
Direct varRef;
TypeRef type;
if (holds_alternative<Direct>(l.args[0])) {
varRef = get<Direct>(l.args[0]);
} else {
error("First argument of init must be a direct reference");
}
if (holds_alternative<TypeRef>(l.args[1])) {
type = get<TypeRef>(l.args[1]);
} else {
error("Second argument of init must be a type reference");
}
Literal newVal;
if (type.isCustomType) {
newVal.val = structs[type.customType];
} else {
switch (type.type) {
case Types::Int:
newVal.val = 0;
break;
case Types::Double:
newVal.val = double(0.0);
break;
case Types::String:
newVal.val = "";
break;
case Types::Char:
newVal.val = '\0';
break;
case Types::Bool:
newVal.val = false;
break;
default:
error("You dingus you werent supposed to get here");
}
}
structs[procStructName].values[varRef.varName] = newVal;
}
continue;
}
// Pre process value references and labels
for (int j = 0; j < l.args.size(); j++) {
if (holds_alternative<ValueRef>(l.args[j])) {
if (variables.find(get<ValueRef>(l.args[j]).varName) != variables.end()) {
l.args[j] = variables[get<ValueRef>(l.args[j]).varName];
string varName = get<ValueRef>(l.args[j]).varName;
if (variables.find(varName) != variables.end()) {
l.args[j] = variables[varName];
} else {
error("Could not find variable " + get<ValueRef>(l.args[j]).varName);
if (isReferencingStruct(varName)) {
string structName;
string varInStruct;
int dotPos = varName.find('.');
if (dotPos != string::npos) {
structName = varName.substr(0, dotPos);
varInStruct = varName.substr(dotPos + 1);
if (variables.find(structName) != variables.end()) {
if (holds_alternative<Struct>(variables[structName].val)) {
Struct structVal = get<Struct>(variables[structName].val);
if (structVal.values.find(varInStruct) != structVal.values.end()) {
l.args[j] = structVal.values[varInStruct];
} else {
error("Could not find property '" + varInStruct + "' in struct '" + structName + "'");
}
} else {
error("Variable '" + structName + "' is not a struct");
}
} else {
error("Could not find struct '" + structName + "'");
}
} else {
error("Invalid struct member access syntax");
}
} else {
error("Could not find variable " + varName);
}
}
} else if (holds_alternative<Line>(l.args[j])) {
Line ln = get<Line>(l.args[j]);
@@ -916,7 +947,12 @@ Literal exec(vector<Instruction> in, bool executingFunction) {
Literal newVal;
if (type.isCustomType) {
newVal.val = structs[type.customType];
if (structs.find(type.customType) == structs.end()) {
error("Unknown struct type: " + type.customType);
}
Struct newStructInstance = structs[type.customType];
newVal.val = newStructInstance;
} else {
switch (type.type) {
case Types::Int:
@@ -2063,7 +2099,7 @@ Literal exec(vector<Instruction> in, bool executingFunction) {
string structName;
if (holds_alternative<TypeRef>(l.args[0])) {
structName = get<TypeRef>(l.args[0]).customType;
} else {
error("First argument of struct must be a type reference");
}

View File

@@ -18,11 +18,9 @@ struct -point
endfun
endstruct
pusharg 43 32
init &myPoint -point
set &myPoint.xpos 17
set &myPoint.ypos 23
println $myPoint.xpos
!myPoint.dingle &out