Variable* array_access(Variable* A, Variable* B) { if(A == NULL || B == NULL) { interpreter.error("Error: Void variable in array_access operation.\n"); return NULL; } TypeEnum a = A->getType(); TypeEnum b = B->getType(); if(a != ARRAY || b != INT) { interpreter.error("Error: Array access not defined for types '%s' and '%s'\n", getTypeString(a).c_str(), getTypeString(b).c_str()); return NULL; } Array* C = static_cast<Array*>(A); Int* D = static_cast<Int*>(B); vector<Variable*>& v = C->getValue(); Variable* result = NULL; int index = D->getValue(); if(index >= 0 && (unsigned int)index < v.size()) result = v[index]; if(result == NULL) interpreter.error("Error: Array index out of bounds.\n"); return result; }
Variable* negate(Variable* A) { if(A == NULL) { interpreter.error("Error: Void variable in negation.\n"); return NULL; } TypeEnum a = A->getType(); if(a == STRING || a == BOOL || a == MACRO || a == ARRAY || a == LIST || a == FUNCTION || a == PROCEDURE) { interpreter.error("Error: Negation not defined for type '%s'\n", getTypeString(a).c_str()); return NULL; } if(a == INT) { Int* C = static_cast<Int*>(A); Int* R = new Int; R->setValue(-C->getValue()); return R; } else if(a == FLOAT) { Float* C = static_cast<Float*>(A); Float* R = new Float; R->setValue(-C->getValue()); return R; } return A; }
Variable* exponentiate(Variable* A, Variable* B) { if(A == NULL || B == NULL) { interpreter.error("Error: Void variable in exponentiation.\n"); return NULL; } TypeEnum a = A->getType(); TypeEnum b = B->getType(); if(a == STRING || a == BOOL || a == MACRO || a == ARRAY || a == LIST || a == FUNCTION || a == PROCEDURE || b == STRING || b == BOOL || b == MACRO || b == ARRAY || b == LIST || b == FUNCTION || b == PROCEDURE) { interpreter.error("Error: Exponentiation not defined for types '%s' and '%s'\n", getTypeString(a).c_str(), getTypeString(b).c_str()); return NULL; } if(a == INT) { Int* C = static_cast<Int*>(A); if(b == INT) { Int* D = static_cast<Int*>(B); Int* R = new Int; R->setValue(pow(float(C->getValue()), D->getValue())); return R; } else if(b == FLOAT) { Float* D = static_cast<Float*>(B); Float* R = new Float; R->setValue(pow(C->getValue(), D->getValue())); return R; } } else if(a == FLOAT) { Float* C = static_cast<Float*>(A); if(b == INT) { Int* D = static_cast<Int*>(B); Float* R = new Float; R->setValue(pow(C->getValue(), D->getValue())); return R; } else if(b == FLOAT) { Float* D = static_cast<Float*>(B); Float* R = new Float; R->setValue(pow(C->getValue(), D->getValue())); return R; } } return A; }
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* dot(Variable* A, Variable* B) { if(A == NULL || B == NULL) { interpreter.error("Error: Void variable in dot operation.\n"); return NULL; } TypeEnum a = A->getType(); TypeEnum b = B->getType(); if(B->literal) { interpreter.error("Error: Literal variable used in 'dot' operation\n"); return NULL; } if(a == CLASS_OBJECT) { ClassObject* C = static_cast<ClassObject*>(A); Variable* result = C->getVariable(B->text); if(result == NULL) interpreter.error("Error: %s is not a member of %s.\n", B->text.c_str(), C->className.c_str()); return result; } else if(a == ARRAY) { Array* C = static_cast<Array*>(A); Variable* result = NULL; if(B->text == "size") { interpreter.array_size->parentObject = A; result = interpreter.array_size; } if(result == NULL) interpreter.error("Error: %s is not a member of %s.\n", B->text.c_str(), C->text.c_str()); return result; } interpreter.error("Error: 'Dot' not defined for types '%s' and '%s'\n", getTypeString(a).c_str(), getTypeString(b).c_str()); return NULL; }
Variable* add(Variable* A, Variable* B) { if(A == NULL || B == NULL) { interpreter.error("Error: Void variable in addition.\n"); return NULL; } TypeEnum a = A->getType(); TypeEnum b = B->getType(); if(a != b && !(a == FLOAT && b == INT) && !(b == FLOAT && a == INT)) { interpreter.error("Error: Types do not match in addition: %s vs %s\n", A->getTypeString().c_str(), B->getTypeString().c_str()); return NULL; } if(a == STRING) { String* C = static_cast<String*>(A); String* D = static_cast<String*>(B); String* R = new String("<temp>"); R->setValue(C->getValue() + D->getValue()); return R; } else if(a == INT) { Int* C = static_cast<Int*>(A); if(b == INT) { Int* D = static_cast<Int*>(B); Int* R = new Int; R->setValue(C->getValue() + D->getValue()); return R; } else { Float* D = static_cast<Float*>(B); Float* R = new Float; R->setValue(C->getValue() + D->getValue()); return R; } } else if(a == FLOAT) { Float* C = static_cast<Float*>(A); Float* R = new Float; if(b == INT) { Int* D = static_cast<Int*>(B); R->setValue(C->getValue() + D->getValue()); } else { Float* D = static_cast<Float*>(B); R->setValue(C->getValue() + D->getValue()); } return R; } else if(a == BOOL) { interpreter.error("Error: Addition operation not defined for type 'bool'.\n"); return NULL; } else if(a == MACRO) { Macro* C = static_cast<Macro*>(A); Macro* D = static_cast<Macro*>(B); Macro* R = new Macro; R->setValue(C->getValue() + D->getValue()); return R; } else if(a == ARRAY) { 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 addition: Array<%s> vs Array<%s>\n", C->getValueTypeString().c_str(), D->getValueTypeString().c_str()); return NULL; } vector<Variable*> va = C->getValue(); vector<Variable*>& vb = D->getValue(); for(vector<Variable*>::iterator e = vb.begin(); e != vb.end(); e++) { va.push_back(*e); } Array* arr = new Array("<temp>", va, a); return arr; } else if(a == LIST) { List* C = static_cast<List*>(A); List* D = static_cast<List*>(B); list<Variable*> va = C->getValue(); list<Variable*>& vb = D->getValue(); for(list<Variable*>::iterator e = vb.begin(); e != vb.end(); e++) { va.push_back(*e); } List* lst = new List("<temp>", va); return lst; } else if(a == FUNCTION) { Function* C = static_cast<Function*>(A); Function* D = static_cast<Function*>(B); Function* R = new Function("<temp>", FN_NONE); R->setValue(C->getValue() + D->getValue()); return R; } else if(a == PROCEDURE) { Procedure* C = static_cast<Procedure*>(A); Procedure* D = static_cast<Procedure*>(B); Procedure* R = new Procedure("<temp>"); R->setValue(C->getValue() + D->getValue()); return R; } return A; }
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; }
Variable* subtract(Variable* A, Variable* B) { if(A == NULL || B == NULL) { interpreter.error("Error: Void variable in subtraction.\n"); return NULL; } TypeEnum a = A->getType(); TypeEnum b = B->getType(); if(a != b && !(a == FLOAT && b == INT) && !(b == FLOAT && a == INT)) { interpreter.error("Error: Types do not match in subtraction: %s vs %s\n", A->getTypeString().c_str(), B->getTypeString().c_str()); return NULL; } if(a == STRING) { interpreter.error("Error: Subtraction operation not defined for type 'string'.\n"); return NULL; } else if(a == INT) { Int* C = static_cast<Int*>(A); if(b == INT) { Int* D = static_cast<Int*>(B); Int* R = new Int; R->setValue(C->getValue() - D->getValue()); return R; } else { Float* D = static_cast<Float*>(B); Float* R = new Float; R->setValue(C->getValue() - D->getValue()); return R; } } else if(a == FLOAT) { Float* C = static_cast<Float*>(A); Float* R = new Float; if(b == INT) { Int* D = static_cast<Int*>(B); R->setValue(C->getValue() - D->getValue()); } else { Float* D = static_cast<Float*>(B); R->setValue(C->getValue() - D->getValue()); } return R; } else if(a == BOOL) { interpreter.error("Error: Subtraction operation not defined for type 'bool'.\n"); return NULL; } else if(a == MACRO) { interpreter.error("Error: Subtraction operation not defined for type 'macro'.\n"); return NULL; } else if(a == ARRAY) { interpreter.error("Error: Subtraction operation not defined for type 'array'.\n"); return NULL; } else if(a == LIST) { interpreter.error("Error: Subtraction operation not defined for type 'list'.\n"); return NULL; } else if(a == FUNCTION) { interpreter.error("Error: Subtraction operation not defined for type 'function'.\n"); return NULL; } else if(a == PROCEDURE) { interpreter.error("Error: Subtraction operation not defined for type 'procedure'.\n"); return NULL; } return A; }
EvalState Interpreter::getArrayLiteral(list<Token>& tokens, list<Token>::iterator& e) { Array* arr = NULL; TypeEnum type = NOT_A_TYPE; for(; e != tokens.end(); e++) { if(e->type == Token::SEPARATOR) { if(e->sep == OPEN_SQUARE_BRACKET) // FIXME: This should allow nesting later... continue; if(e->sep == CLOSE_SQUARE_BRACKET) // FIXME: This should allow nesting later... break; } // Get the thing between [ and , or ] list<Token> tok2; while(e != tokens.end()) { if(e->type == Token::SEPARATOR && (e->sep == COMMA || e->sep == CLOSE_SQUARE_BRACKET)) break; tok2.push_back(*e); e++; } EvalState t = evalTokens(tok2, EvalState(EvalState::SUBEXPRESSION)); if(t.state & EvalState::ERROR) return t; if(t.token.type == Token::OPERATOR) { interpreter.error("Error: Unexpected operator when reading an array literal.\n"); continue; } if(t.token.type == Token::SEPARATOR) { interpreter.error("Error: Unexpected separator when reading an array literal.\n"); continue; } if(t.token.var == NULL) { interpreter.error("Error: NULL var in token...\n"); continue; } if(type == NOT_A_TYPE) { type = t.token.var->getType(); if(type == NOT_A_TYPE || type == VOID) { type = NOT_A_TYPE; interpreter.error("Error: Invalid type in array literal.\n"); continue; } arr = new Array("<temp>", type); } if(t.token.var->getType() != type) { interpreter.error("Error: Inconsistent type in array literal.\n"); continue; } arr->push_back(t.token.var); if(e->type == Token::SEPARATOR && e->sep == CLOSE_SQUARE_BRACKET) break; } // Skip the closing bracket //if(e != tokens.end()) // e++; if(arr != NULL) { UI_debug_pile(" Returning an array: Size = %d\n", arr->getValue().size()); for(unsigned int i = 0; i < arr->getValue().size(); i++) { UI_debug_pile(" Element: %s\n", arr->getValue()[i]->getValueString().c_str()); } } return EvalState(Token(arr, "<temp>")); }