diff --git a/src/main.cpp b/src/main.cpp index b97af9e..69d6a91 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -34,7 +34,6 @@ Happy coding! */ -#include #include #include #include @@ -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 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 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(l.args[0])) { - varRef = get(l.args[0]); - } else { - error("First argument of init must be a direct reference"); - } - if (holds_alternative(l.args[1])) { - type = get(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(l.args[0])) { + varRef = get(l.args[0]); + } else { + error("First argument of init must be a direct reference"); + } + if (holds_alternative(l.args[1])) { + type = get(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(l.args[j])) { - if (variables.find(get(l.args[j]).varName) != variables.end()) { - l.args[j] = variables[get(l.args[j]).varName]; + string varName = get(l.args[j]).varName; + if (variables.find(varName) != variables.end()) { + l.args[j] = variables[varName]; } else { - error("Could not find variable " + get(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(variables[structName].val)) { + Struct structVal = get(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(l.args[j])) { Line ln = get(l.args[j]); @@ -916,7 +947,12 @@ Literal exec(vector 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 in, bool executingFunction) { string structName; if (holds_alternative(l.args[0])) { - + structName = get(l.args[0]).customType; } else { error("First argument of struct must be a type reference"); } diff --git a/tests/struct.grnd b/tests/struct.grnd index 513903d..374e0b5 100644 --- a/tests/struct.grnd +++ b/tests/struct.grnd @@ -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