Moved type checking into the type checking function

This commit is contained in:
2022-09-09 19:39:05 +01:00
parent 22d0fe596a
commit f2443fbde0
2 changed files with 53 additions and 42 deletions

View File

@@ -1531,23 +1531,6 @@ static bool execIndexAssign(Interpreter* interpreter) {
return false; return false;
} }
//TODO: come back to this
// //check const-ness of "first" within "compound"
// Literal type = getScopeType(interpreter->scope, idn);
// if ((AS_TYPE(type).typeOf == LITERAL_ARRAY && AS_TYPE(((Literal*)(AS_TYPE(type).subtypes))[0]).constant) || (AS_TYPE(type).typeOf == LITERAL_DICTIONARY && AS_TYPE(((Literal*)(AS_TYPE(type).subtypes))[1]).constant)) {
// interpreter->errorOutput("couldn't assign to constant within compound within index assigning notation\n");
// freeLiteral(assign);
// freeLiteral(third);
// freeLiteral(second);
// freeLiteral(first);
// freeLiteral(compound);
// if (freeIdn) {
// freeLiteral(idn);
// }
// freeLiteral(type);
// return false;
// }
//get the index function //get the index function
Literal func = TO_NULL_LITERAL; Literal func = TO_NULL_LITERAL;
char* keyStr = "_index"; char* keyStr = "_index";
@@ -1564,7 +1547,6 @@ static bool execIndexAssign(Interpreter* interpreter) {
if (freeIdn) { if (freeIdn) {
freeLiteral(idn); freeLiteral(idn);
} }
// freeLiteral(type);
freeLiteral(func); freeLiteral(func);
freeLiteral(key); freeLiteral(key);
return false; return false;
@@ -1603,7 +1585,6 @@ static bool execIndexAssign(Interpreter* interpreter) {
if (freeIdn) { if (freeIdn) {
freeLiteral(idn); freeLiteral(idn);
} }
// freeLiteral(type);
freeLiteral(func); freeLiteral(func);
freeLiteral(key); freeLiteral(key);
return false; return false;
@@ -1668,12 +1649,11 @@ static bool execIndexAssign(Interpreter* interpreter) {
freeLiteral(idn); freeLiteral(idn);
idn = popLiteralArray(&interpreter->stack); idn = popLiteralArray(&interpreter->stack);
compound = idn; compound = idn;
// freeIdn = true;
} }
if (IS_IDENTIFIER(idn) && !setScopeVariable(interpreter->scope, idn, result, true)) { if (IS_IDENTIFIER(idn) && !setScopeVariable(interpreter->scope, idn, result, true)) {
interpreter->errorOutput("Incorrect type assigned to compound member: "); interpreter->errorOutput("Incorrect type assigned to compound member ");
printLiteralCustom(result, interpreter->errorOutput); printLiteralCustom(idn, interpreter->errorOutput);
interpreter->errorOutput("\n"); interpreter->errorOutput("\n");
//clean up //clean up
@@ -1686,7 +1666,6 @@ static bool execIndexAssign(Interpreter* interpreter) {
freeLiteral(idn); freeLiteral(idn);
} }
freeLiteral(func); freeLiteral(func);
// freeLiteral(type);
freeLiteral(key); freeLiteral(key);
freeLiteral(op); freeLiteral(op);
freeLiteralArray(&arguments); freeLiteralArray(&arguments);
@@ -1704,7 +1683,6 @@ static bool execIndexAssign(Interpreter* interpreter) {
freeLiteral(idn); freeLiteral(idn);
} }
freeLiteral(func); freeLiteral(func);
// freeLiteral(type);
freeLiteral(key); freeLiteral(key);
freeLiteral(op); freeLiteral(op);
freeLiteralArray(&arguments); freeLiteralArray(&arguments);

View File

@@ -22,7 +22,12 @@ static void freeAncestorChain(Scope* scope) {
} }
//return false if invalid type //return false if invalid type
static bool checkType(Literal typeLiteral, Literal value) { static bool checkType(Literal typeLiteral, Literal original, Literal value, bool constCheck) {
//for constants, fail if original != value
if (constCheck && AS_TYPE(typeLiteral).constant && !literalsAreEqual(original, value)) {
return false;
}
//for any types //for any types
if (AS_TYPE(typeLiteral).typeOf == LITERAL_ANY) { if (AS_TYPE(typeLiteral).typeOf == LITERAL_ANY) {
return true; return true;
@@ -65,9 +70,18 @@ static bool checkType(Literal typeLiteral, Literal value) {
return false; return false;
} }
//if null, assume it's a new entry
if (IS_NULL(original)) {
return true;
}
//check children //check children
for (int i = 0; i < AS_ARRAY(value)->count; i++) { for (int i = 0; i < AS_ARRAY(value)->count; i++) {
if (!checkType(((Literal*)(AS_TYPE(typeLiteral).subtypes))[0], AS_ARRAY(value)->literals[i])) { if (AS_ARRAY(original)->count <= i) {
return true; //assume new entry pushed
}
if (!checkType(((Literal*)(AS_TYPE(typeLiteral).subtypes))[0], AS_ARRAY(original)->literals[i], AS_ARRAY(value)->literals[i], constCheck)) {
return false; return false;
} }
} }
@@ -83,20 +97,42 @@ static bool checkType(Literal typeLiteral, Literal value) {
return false; return false;
} }
//check children //if null, assume it's a new entry
if (IS_NULL(original)) {
return true;
}
//check each child of value against the child of original
for (int i = 0; i < AS_DICTIONARY(value)->capacity; i++) { for (int i = 0; i < AS_DICTIONARY(value)->capacity; i++) {
//only assigned and non-tombstoned keys if (IS_NULL(AS_DICTIONARY(value)->entries[i].key)) { //only non-tombstones
if (!IS_NULL(AS_DICTIONARY(value)->entries[i].key)) { continue;
if (!checkType(((Literal*)(AS_TYPE(typeLiteral).subtypes))[0], AS_DICTIONARY(value)->entries[i].key)) { }
//find the internal child of original that matches this child of value
_entry* ptr = NULL;
for (int j = 0; j < AS_DICTIONARY(original)->capacity; j++) {
if (literalsAreEqual(AS_DICTIONARY(original)->entries[j].key, AS_DICTIONARY(value)->entries[i].key)) {
ptr = &AS_DICTIONARY(original)->entries[j];
break;
}
}
//if not found, assume it's a new entry
if (!ptr) {
continue;
}
//check the type of key and value
if (!checkType(((Literal*)(AS_TYPE(typeLiteral).subtypes))[0], ptr->key, AS_DICTIONARY(value)->entries[i].key, constCheck)) {
return false; return false;
} }
if (!checkType(((Literal*)(AS_TYPE(typeLiteral).subtypes))[1], AS_DICTIONARY(value)->entries[i].value)) { if (!checkType(((Literal*)(AS_TYPE(typeLiteral).subtypes))[1], ptr->value, AS_DICTIONARY(value)->entries[i].value, constCheck)) {
return false; return false;
} }
} }
} }
}
if (AS_TYPE(typeLiteral).typeOf == LITERAL_FUNCTION && !IS_FUNCTION(value)) { if (AS_TYPE(typeLiteral).typeOf == LITERAL_FUNCTION && !IS_FUNCTION(value)) {
return false; return false;
@@ -220,15 +256,11 @@ bool setScopeVariable(Scope* scope, Literal key, Literal value, bool constCheck)
//type checking //type checking
Literal typeLiteral = getLiteralDictionary(&scope->types, key); Literal typeLiteral = getLiteralDictionary(&scope->types, key);
Literal original = getLiteralDictionary(&scope->variables, key);
if (!checkType(typeLiteral, value)) { if (!checkType(typeLiteral, original, value, constCheck)) {
freeLiteral(typeLiteral);
return false;
}
//const check
if (constCheck && (AS_TYPE(typeLiteral).constant)) {
freeLiteral(typeLiteral); freeLiteral(typeLiteral);
freeLiteral(original);
return false; return false;
} }
@@ -236,6 +268,7 @@ bool setScopeVariable(Scope* scope, Literal key, Literal value, bool constCheck)
setLiteralDictionary(&scope->variables, key, value); setLiteralDictionary(&scope->variables, key, value);
freeLiteral(typeLiteral); freeLiteral(typeLiteral);
freeLiteral(original);
return true; return true;
} }