Bool* not_has_element(Variable* A, Variable* B) { Bool* b = has_element(A, B); if(b == NULL) return NULL; b->setValue(!b->getValue()); return b; }
Bool* has_element(Variable* A, Variable* B) { if(A == NULL || B == NULL) { interpreter.error("Error: Void variable in has_element operation.\n"); return NULL; } TypeEnum a = A->getType(); TypeEnum b = B->getType(); if(a != ARRAY && b != ARRAY) { interpreter.error("Error: Has_element not defined for types '%s' and '%s'\n", getTypeString(a).c_str(), getTypeString(b).c_str()); return NULL; } Array* C; Variable* other; TypeEnum otherType; if(a == ARRAY) { C = static_cast<Array*>(A); other = B; otherType = b; } else { C = static_cast<Array*>(B); other = A; otherType = a; } if(otherType != C->getValueType()) { interpreter.error("Error: Has_element not defined for types '%s' and '%s'\n", getTypeString(ARRAY).c_str(), getTypeString(otherType).c_str()); return NULL; } vector<Variable*>& v = C->getValue(); for(vector<Variable*>::iterator e = v.begin(); e != v.end(); e++) { Bool* test = comparison(other, *e, EQUALS); if(test->getValue() == true) return test; delete test; } return new Bool(false); }
Variable* add_assign(Variable* A, Variable* B) { if(A == NULL || B == NULL) { interpreter.error("Error: Void variable in assignment.\n"); return NULL; } if(!A->reference) { interpreter.error("Error: Assigning value to a non-reference variable.\n"); return NULL; } TypeEnum a = A->getType(); TypeEnum b = B->getType(); bool mismatch = false; if(a == STRING) { if(b != STRING) mismatch = true; else { String* C = static_cast<String*>(A); String* D = static_cast<String*>(B); C->setValue(C->getValue() + D->getValue()); } } else if(a == INT) { if(b != BOOL && b != INT && b != FLOAT) mismatch = true; else { Int* C = static_cast<Int*>(A); if(b == BOOL) { Bool* D = static_cast<Bool*>(B); C->setValue(C->getValue() + D->getValue()); } else if(b == INT) { Int* D = static_cast<Int*>(B); C->setValue(C->getValue() + D->getValue()); } else { Float* D = static_cast<Float*>(B); C->setValue(C->getValue() + D->getValue()); } } } else if(a == FLOAT) { if(b != BOOL && b != INT && b != FLOAT) mismatch = true; else { Float* C = static_cast<Float*>(A); if(b == BOOL) { Bool* D = static_cast<Bool*>(B); C->setValue(C->getValue() + D->getValue()); } else if(b == INT) { Int* D = static_cast<Int*>(B); C->setValue(C->getValue() + D->getValue()); } else { Float* D = static_cast<Float*>(B); C->setValue(C->getValue() + D->getValue()); } } } else if(a == BOOL) { if(b != BOOL && b != INT && b != FLOAT) mismatch = true; else { Bool* C = static_cast<Bool*>(A); if(b == BOOL) { Bool* D = static_cast<Bool*>(B); C->setValue(C->getValue() + D->getValue()); } else if(b == INT) { Int* D = static_cast<Int*>(B); C->setValue(C->getValue() + D->getValue()); } else { Float* D = static_cast<Float*>(B); C->setValue(C->getValue() + D->getValue()); } } } else if(a == MACRO) { interpreter.error("Error: Addition operation not defined for type 'macro'.\n"); return NULL; } else if(a == ARRAY) { if(b == ARRAY) { Array* C = static_cast<Array*>(A); Array* D = static_cast<Array*>(B); a = C->getValueType(); b = C->getValueType(); if(a != b) { interpreter.error("Error: Types do not match in assignment: Array<%s> vs Array<%s>\n", C->getValueTypeString().c_str(), D->getValueTypeString().c_str()); return NULL; } C->push_back(D->getValue()); } else { Array* C = static_cast<Array*>(A); if(b == C->getValueType()) { C->push_back(B); } else mismatch = true; } } else if(a == LIST) { // Lists must be concatenated a different way... List* C = static_cast<List*>(A); C->push_back(B); } else if(a == FUNCTION) { interpreter.error("Error: Addition operation not defined for type 'function'.\n"); return NULL; } else if(a == PROCEDURE) { interpreter.error("Error: Addition operation not defined for type 'procedure'.\n"); return NULL; } if(mismatch) { interpreter.error("Error: Types do not match in assignment: %s vs %s\n", A->getTypeString().c_str(), B->getTypeString().c_str()); return NULL; } return A; }
Variable* assign(Variable* A, Variable* B) { if(A == NULL || B == NULL) { interpreter.error("Error: Void variable in assignment.\n"); return NULL; } if(!A->reference) { interpreter.error("Error: Assigning value to a non-reference variable.\n"); return NULL; } TypeEnum a = A->getType(); TypeEnum b = B->getType(); bool mismatch = false; if(a == STRING) { if(b != STRING) mismatch = true; else { String* C = static_cast<String*>(A); String* D = static_cast<String*>(B); C->setValue(D->getValue()); } } else if(a == INT) { if(b != BOOL && b != INT && b != FLOAT) mismatch = true; else { Int* C = static_cast<Int*>(A); if(b == BOOL) { Bool* D = static_cast<Bool*>(B); C->setValue(D->getValue()); } else if(b == INT) { Int* D = static_cast<Int*>(B); C->setValue(D->getValue()); } else { Float* D = static_cast<Float*>(B); C->setValue(D->getValue()); } } } else if(a == FLOAT) { if(b != BOOL && b != INT && b != FLOAT) mismatch = true; else { Float* C = static_cast<Float*>(A); if(b == BOOL) { Bool* D = static_cast<Bool*>(B); C->setValue(D->getValue()); } else if(b == INT) { Int* D = static_cast<Int*>(B); C->setValue(D->getValue()); } else { Float* D = static_cast<Float*>(B); C->setValue(D->getValue()); } } } else if(a == BOOL) { if(b != BOOL && b != INT && b != FLOAT) mismatch = true; else { Bool* C = static_cast<Bool*>(A); if(b == BOOL) { Bool* D = static_cast<Bool*>(B); C->setValue(D->getValue()); } else if(b == INT) { Int* D = static_cast<Int*>(B); C->setValue(D->getValue()); } else { Float* D = static_cast<Float*>(B); C->setValue(D->getValue()); } } } else if(a == MACRO) { if(b != MACRO) mismatch = true; else { Macro* C = static_cast<Macro*>(A); Macro* D = static_cast<Macro*>(B); C->setValue(D->getValue()); } } else if(a == ARRAY) { if(b != ARRAY) mismatch = true; else { Array* C = static_cast<Array*>(A); Array* D = static_cast<Array*>(B); a = C->getValueType(); b = D->getValueType(); if(a != b) { interpreter.error("Error: Types do not match in assignment: Array<%s> vs Array<%s>\n", C->getValueTypeString().c_str(), D->getValueTypeString().c_str()); return NULL; } C->setValue(D->getValue()); } } else if(a == LIST) { if(b != LIST) mismatch = true; else { List* C = static_cast<List*>(A); List* D = static_cast<List*>(B); C->setValue(D->getValue()); } } else if(a == FUNCTION) { if(b != FUNCTION) mismatch = true; else { Function* C = static_cast<Function*>(A); Function* D = static_cast<Function*>(B); C->setValue(D->getValue()); } } else if(a == PROCEDURE) { if(b != PROCEDURE) mismatch = true; else { Procedure* C = static_cast<Procedure*>(A); Procedure* D = static_cast<Procedure*>(B); C->setValue(D->getValue()); } } if(mismatch) { interpreter.error("Error: Types do not match in assignment: %s vs %s\n", A->getTypeString().c_str(), B->getTypeString().c_str()); return NULL; } return A; }
Bool* comparison(Variable* A, Variable* B, OperatorEnum oper) { if(A == NULL || B == NULL) { interpreter.error("Error: Void variable in assignment.\n"); return NULL; } TypeEnum a = A->getType(); TypeEnum b = B->getType(); bool mismatch = false; if(a == STRING) { if(b != STRING) mismatch = true; else { String* C = static_cast<String*>(A); String* D = static_cast<String*>(B); switch(oper) { case EQUALS: return new Bool(C->getValue() == D->getValue()); case NOT_GREATER: case LESS_EQUAL: return new Bool(C->getValue() <= D->getValue()); case NOT_LESS: case GREATER_EQUAL: return new Bool(C->getValue() >= D->getValue()); case LESS: return new Bool(C->getValue() < D->getValue()); case GREATER: return new Bool(C->getValue() > D->getValue()); case NOT_EQUALS: return new Bool(C->getValue() != D->getValue()); default: UI_debug_pile("Pile Error: Bad operator passed to comparison().\n"); return NULL; } } } else if(a == INT) { if(b != BOOL && b != INT && b != FLOAT) mismatch = true; else { Int* C = static_cast<Int*>(A); if(b == BOOL) { Bool* D = static_cast<Bool*>(B); switch(oper) { case EQUALS: return new Bool(C->getValue() == D->getValue()); case NOT_GREATER: case LESS_EQUAL: return new Bool(C->getValue() <= D->getValue()); case NOT_LESS: case GREATER_EQUAL: return new Bool(C->getValue() >= D->getValue()); case LESS: return new Bool(C->getValue() < D->getValue()); case GREATER: return new Bool(C->getValue() > D->getValue()); case AND: return new Bool(C->getValue() && D->getValue()); case OR: return new Bool(C->getValue() || D->getValue()); case NOT_EQUALS: return new Bool(C->getValue() != D->getValue()); default: UI_debug_pile("Pile Error: Bad operator passed to comparison().\n"); return NULL; } } else if(b == INT) { Int* D = static_cast<Int*>(B); switch(oper) { case EQUALS: return new Bool(C->getValue() == D->getValue()); case NOT_GREATER: case LESS_EQUAL: return new Bool(C->getValue() <= D->getValue()); case NOT_LESS: case GREATER_EQUAL: return new Bool(C->getValue() >= D->getValue()); case LESS: return new Bool(C->getValue() < D->getValue()); case GREATER: return new Bool(C->getValue() > D->getValue()); case AND: return new Bool(C->getValue() && D->getValue()); case OR: return new Bool(C->getValue() || D->getValue()); case NOT_EQUALS: return new Bool(C->getValue() != D->getValue()); default: UI_debug_pile("Pile Error: Bad operator passed to comparison().\n"); return NULL; } } else { Float* D = static_cast<Float*>(B); switch(oper) { case EQUALS: return new Bool(C->getValue() == D->getValue()); case NOT_GREATER: case LESS_EQUAL: return new Bool(C->getValue() <= D->getValue()); case NOT_LESS: case GREATER_EQUAL: return new Bool(C->getValue() >= D->getValue()); case LESS: return new Bool(C->getValue() < D->getValue()); case GREATER: return new Bool(C->getValue() > D->getValue()); case AND: return new Bool(C->getValue() && D->getValue()); case OR: return new Bool(C->getValue() || D->getValue()); case NOT_EQUALS: return new Bool(C->getValue() != D->getValue()); default: UI_debug_pile("Pile Error: Bad operator passed to comparison().\n"); return NULL; } } } } else if(a == FLOAT) { if(b != BOOL && b != INT && b != FLOAT) mismatch = true; else { Float* C = static_cast<Float*>(A); if(b == BOOL) { Bool* D = static_cast<Bool*>(B); switch(oper) { case EQUALS: return new Bool(C->getValue() == D->getValue()); case NOT_GREATER: case LESS_EQUAL: return new Bool(C->getValue() <= D->getValue()); case NOT_LESS: case GREATER_EQUAL: return new Bool(C->getValue() >= D->getValue()); case LESS: return new Bool(C->getValue() < D->getValue()); case GREATER: return new Bool(C->getValue() > D->getValue()); case AND: return new Bool(C->getValue() && D->getValue()); case OR: return new Bool(C->getValue() || D->getValue()); case NOT_EQUALS: return new Bool(C->getValue() != D->getValue()); default: UI_debug_pile("Pile Error: Bad operator passed to comparison().\n"); return NULL; } } else if(b == INT) { Int* D = static_cast<Int*>(B); switch(oper) { case EQUALS: return new Bool(C->getValue() == D->getValue()); case NOT_GREATER: case LESS_EQUAL: return new Bool(C->getValue() <= D->getValue()); case NOT_LESS: case GREATER_EQUAL: return new Bool(C->getValue() >= D->getValue()); case LESS: return new Bool(C->getValue() < D->getValue()); case GREATER: return new Bool(C->getValue() > D->getValue()); case AND: return new Bool(C->getValue() && D->getValue()); case OR: return new Bool(C->getValue() || D->getValue()); case NOT_EQUALS: return new Bool(C->getValue() != D->getValue()); default: UI_debug_pile("Pile Error: Bad operator passed to comparison().\n"); return NULL; } } else { Float* D = static_cast<Float*>(B); switch(oper) { case EQUALS: return new Bool(C->getValue() == D->getValue()); case NOT_GREATER: case LESS_EQUAL: return new Bool(C->getValue() <= D->getValue()); case NOT_LESS: case GREATER_EQUAL: return new Bool(C->getValue() >= D->getValue()); case LESS: return new Bool(C->getValue() < D->getValue()); case GREATER: return new Bool(C->getValue() > D->getValue()); case AND: return new Bool(C->getValue() && D->getValue()); case OR: return new Bool(C->getValue() || D->getValue()); case NOT_EQUALS: return new Bool(C->getValue() != D->getValue()); default: UI_debug_pile("Pile Error: Bad operator passed to comparison().\n"); return NULL; } } } } else if(a == BOOL) { if(b != BOOL && b != INT && b != FLOAT) mismatch = true; else { Bool* C = static_cast<Bool*>(A); if(b == BOOL) { Bool* D = static_cast<Bool*>(B); switch(oper) { case EQUALS: return new Bool(C->getValue() == D->getValue()); case NOT_GREATER: case LESS_EQUAL: return new Bool(C->getValue() <= D->getValue()); case NOT_LESS: case GREATER_EQUAL: return new Bool(C->getValue() >= D->getValue()); case LESS: return new Bool(C->getValue() < D->getValue()); case GREATER: return new Bool(C->getValue() > D->getValue()); case AND: return new Bool(C->getValue() && D->getValue()); case OR: return new Bool(C->getValue() || D->getValue()); case NOT_EQUALS: return new Bool(C->getValue() != D->getValue()); default: UI_debug_pile("Pile Error: Bad operator passed to comparison().\n"); return NULL; } } else if(b == INT) { Int* D = static_cast<Int*>(B); switch(oper) { case EQUALS: return new Bool(C->getValue() == D->getValue()); case NOT_GREATER: case LESS_EQUAL: return new Bool(C->getValue() <= D->getValue()); case NOT_LESS: case GREATER_EQUAL: return new Bool(C->getValue() >= D->getValue()); case LESS: return new Bool(C->getValue() < D->getValue()); case GREATER: return new Bool(C->getValue() > D->getValue()); case AND: return new Bool(C->getValue() && D->getValue()); case OR: return new Bool(C->getValue() || D->getValue()); case NOT_EQUALS: return new Bool(C->getValue() != D->getValue()); default: UI_debug_pile("Pile Error: Bad operator passed to comparison().\n"); return NULL; } } else { Float* D = static_cast<Float*>(B); switch(oper) { case EQUALS: return new Bool(C->getValue() == D->getValue()); case NOT_GREATER: case LESS_EQUAL: return new Bool(C->getValue() <= D->getValue()); case NOT_LESS: case GREATER_EQUAL: return new Bool(C->getValue() >= D->getValue()); case LESS: return new Bool(C->getValue() < D->getValue()); case GREATER: return new Bool(C->getValue() > D->getValue()); case AND: return new Bool(C->getValue() && D->getValue()); case OR: return new Bool(C->getValue() || D->getValue()); case NOT_EQUALS: return new Bool(C->getValue() != D->getValue()); default: UI_debug_pile("Pile Error: Bad operator passed to comparison().\n"); return NULL; } } } } else if(a == MACRO) { if(b != MACRO) mismatch = true; else { Macro* C = static_cast<Macro*>(A); Macro* D = static_cast<Macro*>(B); switch(oper) { case EQUALS: return new Bool(C->getValue() == D->getValue()); case NOT_GREATER: case LESS_EQUAL: return new Bool(C->getValue() <= D->getValue()); case NOT_LESS: case GREATER_EQUAL: return new Bool(C->getValue() >= D->getValue()); case LESS: return new Bool(C->getValue() < D->getValue()); case GREATER: return new Bool(C->getValue() > D->getValue()); case NOT_EQUALS: return new Bool(C->getValue() != D->getValue()); default: UI_debug_pile("Pile Error: Bad operator passed to comparison().\n"); return NULL; } } } else if(a == ARRAY) { if(b != ARRAY) mismatch = true; else { Array* C = static_cast<Array*>(A); Array* D = static_cast<Array*>(B); a = C->getValueType(); b = C->getValueType(); if(a != b) { interpreter.error("Error: Types do not match in assignment: Array<%s> vs Array<%s>\n", C->getValueTypeString().c_str(), D->getValueTypeString().c_str()); return NULL; } switch(oper) { case EQUALS: return new Bool(C->getValue() == D->getValue()); case NOT_GREATER: case LESS_EQUAL: return new Bool(C->getValue() <= D->getValue()); case NOT_LESS: case GREATER_EQUAL: return new Bool(C->getValue() >= D->getValue()); case LESS: return new Bool(C->getValue() < D->getValue()); case GREATER: return new Bool(C->getValue() > D->getValue()); case NOT_EQUALS: return new Bool(C->getValue() != D->getValue()); default: UI_debug_pile("Pile Error: Bad operator passed to comparison().\n"); return NULL; } } } else if(a == LIST) { if(b != LIST) mismatch = true; else { List* C = static_cast<List*>(A); List* D = static_cast<List*>(B); switch(oper) { case EQUALS: return new Bool(C->getValue() == D->getValue()); case NOT_GREATER: case LESS_EQUAL: return new Bool(C->getValue() <= D->getValue()); case NOT_LESS: case GREATER_EQUAL: return new Bool(C->getValue() >= D->getValue()); case LESS: return new Bool(C->getValue() < D->getValue()); case GREATER: return new Bool(C->getValue() > D->getValue()); case NOT_EQUALS: return new Bool(C->getValue() != D->getValue()); default: UI_debug_pile("Pile Error: Bad operator passed to comparison().\n"); return NULL; } } } else if(a == FUNCTION) { if(b != FUNCTION) mismatch = true; else { Function* C = static_cast<Function*>(A); Function* D = static_cast<Function*>(B); switch(oper) { case EQUALS: return new Bool(C->getValue() == D->getValue()); case NOT_GREATER: case LESS_EQUAL: return new Bool(C->getValue() <= D->getValue()); case NOT_LESS: case GREATER_EQUAL: return new Bool(C->getValue() >= D->getValue()); case LESS: return new Bool(C->getValue() < D->getValue()); case GREATER: return new Bool(C->getValue() > D->getValue()); case NOT_EQUALS: return new Bool(C->getValue() != D->getValue()); default: UI_debug_pile("Pile Error: Bad operator passed to comparison().\n"); return NULL; } } } else if(a == PROCEDURE) { if(b != PROCEDURE) mismatch = true; else { Procedure* C = static_cast<Procedure*>(A); Procedure* D = static_cast<Procedure*>(B); switch(oper) { case EQUALS: return new Bool(C->getValue() == D->getValue()); case NOT_GREATER: case LESS_EQUAL: return new Bool(C->getValue() <= D->getValue()); case NOT_LESS: case GREATER_EQUAL: return new Bool(C->getValue() >= D->getValue()); case LESS: return new Bool(C->getValue() < D->getValue()); case GREATER: return new Bool(C->getValue() > D->getValue()); case NOT_EQUALS: return new Bool(C->getValue() != D->getValue()); default: UI_debug_pile("Pile Error: Bad operator passed to comparison().\n"); return NULL; } } } //if(mismatch) { interpreter.error("Error: Types do not match in assignment: %s vs %s\n", A->getTypeString().c_str(), B->getTypeString().c_str()); return NULL; } return NULL; }