Struct value modification

This commit is contained in:
2025-09-20 18:41:22 +10:00
parent ab4b7e6aae
commit 93eec33e60
2 changed files with 78 additions and 66 deletions

View File

@@ -511,6 +511,43 @@ Types getLitType(Literal in) {
return Types::Int;
}
/*
setVal function
This function sets the value of a variable (whether in a struct or not).
*/
void setVal(string varName, Literal value) {
if (isReferencingStruct(varName)) {
string structName;
string varInStruct;
size_t dotPos = varName.find('.'); // Use size_t
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()) {
structVal.values[varInStruct] = value;
variables[structName].val = structVal; // Write back the modified struct
} 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 {
// Handle regular variables (both existing and new)
variables[varName] = value;
}
}
bool processingFunction = false;
string procFnName = "";
@@ -924,7 +961,7 @@ Literal exec(vector<Instruction> in, bool executingFunction) {
}
bool existed = variables.count(varRef.varName) > 0;
variables[varRef.varName] = varContents;
setVal(varRef.varName, varContents);
}
break;
case Instructions::Init:
@@ -1005,7 +1042,9 @@ Literal exec(vector<Instruction> in, bool executingFunction) {
first = false;
}
}
variables[listName].val = listContents;
Literal tmpLit;
tmpLit.val = listContents;
setVal(listName, tmpLit);
}
break;
/*
@@ -1048,7 +1087,7 @@ Literal exec(vector<Instruction> in, bool executingFunction) {
if (holds_alternative<List>(variables[listref.listName].val)) {
if (get<List>(variables[listref.listName].val).val.size() > ref) {
bool existed = variables.count(var.varName) > 0;
variables[var.varName] = get<List>(variables[listref.listName].val).val[ref];
setVal(var.varName, get<List>(variables[listref.listName].val).val[ref]);
} else {
error("Index " + to_string(ref) + " out of range of list " + listref.listName, "rangeError");
}
@@ -1104,7 +1143,7 @@ Literal exec(vector<Instruction> in, bool executingFunction) {
Literal newLit;
newLit.val = instr[ref];
bool existed = variables.count(var.varName) > 0;
variables[var.varName] = newLit;
setVal(var.varName, newLit);
} else {
error("Index " + to_string(ref) + " out of range of string " + instr, "rangeError");
}
@@ -1149,7 +1188,9 @@ Literal exec(vector<Instruction> in, bool executingFunction) {
if (get<List>(variables[listref.listName].val).val.size() > ref) {
List tmpList = get<List>(variables[listref.listName].val);
tmpList.val[ref] = value;
variables[listref.listName].val = tmpList;
Literal tmpLit;
tmpLit.val = tmpList;
setVal(listref.listName, tmpLit);
} else {
error("Index " + to_string(ref) + " out of range of list " + listref.listName, "rangeError");
}
@@ -1189,7 +1230,9 @@ Literal exec(vector<Instruction> in, bool executingFunction) {
}
List tmpList = get<List>(variables[listref.listName].val);
tmpList.val.push_back(value);
variables[listref.listName].val = tmpList;
Literal tmpLit;
tmpLit.val = tmpList;
setVal(listref.listName, tmpLit);
} else {
error("Unknown list: " + listref.listName);
}
@@ -1223,7 +1266,7 @@ Literal exec(vector<Instruction> in, bool executingFunction) {
if (variables.find(ref.listName) != variables.end()) {
newLit.val = int(get<List>(variables[ref.listName].val).val.size());
bool existed = variables.count(var.varName) > 0;
variables[var.varName] = newLit;
setVal(var.varName, newLit);
} else {
error("Couldn't find the list " + ref.listName);
}
@@ -1261,8 +1304,7 @@ Literal exec(vector<Instruction> in, bool executingFunction) {
Literal newLit;
newLit.val = int(ref.size());
bool existed = variables.count(var.varName) > 0;
variables[var.varName] = newLit;
setVal(var.varName, newLit);
break;
}
/*
@@ -1298,7 +1340,7 @@ Literal exec(vector<Instruction> in, bool executingFunction) {
Literal newLit;
newLit.val = stoi(toConv);
bool existed = variables.count(ref.varName) > 0;
variables[ref.varName] = newLit;
setVal(ref.varName, newLit);
} else {
error("Cannot convert the value " + toConv + " to an int", "conversionError");
}
@@ -1337,7 +1379,7 @@ Literal exec(vector<Instruction> in, bool executingFunction) {
Literal newLit;
newLit.val = stod(toConv);
bool existed = variables.count(ref.varName) > 0;
variables[ref.varName] = newLit;
setVal(ref.varName, newLit);
} else {
error("Cannot convert the value " + toConv + " to a decimal", "conversionError");
}
@@ -1385,7 +1427,7 @@ Literal exec(vector<Instruction> in, bool executingFunction) {
}
bool existed = variables.count(ref.varName) > 0;
variables[ref.varName] = newLit;
setVal(ref.varName, newLit);
}
break;
@@ -1405,7 +1447,7 @@ Literal exec(vector<Instruction> in, bool executingFunction) {
Literal userLit;
userLit.val = userIn;
bool existed = variables.count(varRef.varName) > 0;
variables[varRef.varName] = userLit;
setVal(varRef.varName, userLit);
} else {
error("First argument of stdin must be a direct reference");
}
@@ -1465,7 +1507,7 @@ Literal exec(vector<Instruction> in, bool executingFunction) {
}
bool existed = variables.count(varRef.varName) > 0;
variables[varRef.varName] = final;
setVal(varRef.varName, final);
}
break;
/*
@@ -1515,7 +1557,7 @@ Literal exec(vector<Instruction> in, bool executingFunction) {
}
bool existed = variables.count(varRef.varName) > 0;
variables[varRef.varName] = final;
setVal(varRef.varName, final);
}
break;
/*
@@ -1565,7 +1607,7 @@ Literal exec(vector<Instruction> in, bool executingFunction) {
}
bool existed = variables.count(varRef.varName) > 0;
variables[varRef.varName] = final;
setVal(varRef.varName, final);
}
break;
/*
@@ -1627,7 +1669,7 @@ Literal exec(vector<Instruction> in, bool executingFunction) {
}
bool existed = variables.count(varRef.varName) > 0;
variables[varRef.varName] = final;
setVal(varRef.varName, final);
}
break;
/*
@@ -1683,7 +1725,7 @@ Literal exec(vector<Instruction> in, bool executingFunction) {
}
bool existed = variables.count(varRef.varName) > 0;
variables[varRef.varName] = final;
setVal(varRef.varName, final);
}
break;
/*
@@ -1739,40 +1781,7 @@ Literal exec(vector<Instruction> in, bool executingFunction) {
}
bool existed = variables.count(varRef.varName) > 0;
variables[varRef.varName] = final;
}
break;
/*
not instruction
Negates a boolean.
*/
case Instructions::Not:
if (l.args.size() < 2) {
error("Could not find all arguments required for Not inbuilt");
}
{
Literal boolean;
Direct varRef;
if (holds_alternative<Literal>(l.args[0])) {
if (holds_alternative<bool>(get<Literal>(l.args[0]).val)) {
boolean.val = !(get<bool>(get<Literal>(l.args[0]).val));
} else {
error("First argument of not must be a boolean literal");
}
} else {
error("First argument of not must be a boolean literal");
}
if (holds_alternative<Direct>(l.args[1])) {
varRef = get<Direct>(l.args[1]);
} else {
error("Second argument of not must be a direct reference");
}
bool existed = variables.count(varRef.varName) > 0;
variables[varRef.varName] = boolean;
setVal(varRef.varName, final);
}
break;
/*
@@ -1828,7 +1837,7 @@ Literal exec(vector<Instruction> in, bool executingFunction) {
}
bool existed = variables.count(varRef.varName) > 0;
variables[varRef.varName] = final;
setVal(varRef.varName, final);
}
break;
/*
@@ -1884,7 +1893,7 @@ Literal exec(vector<Instruction> in, bool executingFunction) {
}
bool existed = variables.count(varRef.varName) > 0;
variables[varRef.varName] = final;
setVal(varRef.varName, final);
}
break;
/*
@@ -1970,27 +1979,31 @@ Literal exec(vector<Instruction> in, bool executingFunction) {
error("Second argument of gettype must be a direct reference");
}
Literal tmpLit;
switch (type) {
case Types::Int:
variables[ref.varName].val = "int";
tmpLit.val = "int";
break;
case Types::Double:
variables[ref.varName].val = "double";
tmpLit.val = "double";
break;
case Types::Bool:
variables[ref.varName].val = "bool";
tmpLit.val = "bool";
break;
case Types::String:
variables[ref.varName].val = "string";
tmpLit.val = "string";
break;
case Types::Char:
variables[ref.varName].val = "char";
tmpLit.val = "char";
break;
default:
error("Could not get type?? This should never be reached. Please report this issue", "undefinedError");
break;
}
setVal(ref.varName, tmpLit);
}
break;
@@ -2029,7 +2042,9 @@ Literal exec(vector<Instruction> in, bool executingFunction) {
} else {
error("First argument of exists must be a direct, list, or line reference");
}
variables[ref2.varName].val = exists;
Literal tmpLit;
tmpLit.val = exists;
setVal(ref2.varName, tmpLit);
}
break;
/*
@@ -2250,12 +2265,12 @@ Literal exec(vector<Instruction> in, bool executingFunction) {
// Now, assign the return value in the current scope.
if (expectList) {
variables[returnRef] = retVal;
setVal(returnRef, retVal);
} else {
if (holds_alternative<List>(retVal.val)) {
error("Expecting to output a normal literal to a normal literal");
} else {
variables[returnRef] = retVal;
setVal(returnRef, retVal);
}
}
}

View File

@@ -20,8 +20,5 @@ endstruct
init &myPoint -point
set &myPoint.xpos 20
println $myPoint.xpos
!myPoint.dingle &out
println $myPoint