int NMethodCall::checkParams(Node* funcParams) { int isValid = 1; node_children_t thisParams = children[0]->getChildren(); int thisSize = thisParams.size(); int expectedSize = funcParams->getChildrenSize(); /* Do we have the same number of expected and given arguments? */ if(thisSize != expectedSize) { printErrorHeader("method call"); error_num_args(name, expectedSize, thisSize); isValid = 0; } /* Compare the arguments and ensure they are of the same type. */ int i = 0; int j = 0; int expectedType, givenType; string varName; while( i < expectedSize && j < thisSize) { expectedType = funcParams->getChild(i)->getType(); givenType = thisParams[j]->getType(); if(!compareTypes(expectedType, givenType)) { varName = thisParams[j]->getID(); printErrorHeader("method call"); error_type_mismatch(varName, givenType, expectedType); isValid = 0; } ++i; ++j; } return isValid; }
void typeARGUMENT(ARGUMENT* arg, EXP* expr) { if((arg == NULL) != (expr == NULL)) /* one is null, so wrong number of arguments */ { typeErrors++; if(arg == NULL) printf("%d: Type Error: Wrong number of arguments for function call.\n", expr->lineno); else printf("%d: Type Error: Wrong number of arguments for function call.\n", arg->lineno); return; } if(arg == NULL && expr == NULL) return; typeARGUMENT(arg->next, expr->next); typeEXP(expr); if(!compareTypes(arg->type, expr->type)) { typeErrors++; printf("%d: Type Error: Wrong type of argument for function call.\n", expr->lineno); } }
void typeSTM(STM* s, TYPE* t) { if(s == NULL) return; if(s->next != NULL) typeSTM(s->next, t); switch(s->kind) { case semicolonK: break; case showK: typeDOCUMENT(s->val.showE.doc); typeRECEIVE(s->val.showE.rec); break; case exitK: typeDOCUMENT(s->val.doc); break; case returnK: if(t == NULL) { typeErrors++; printf("%d: Type Error: Sessions may not return.\n", s->lineno); return; } if(!compareTypes(voidType, t)) { typeErrors++; printf("%d: Type Error: Function must return correct type.\n", s->lineno); return; } break; case returnexprK: if(t == NULL) { typeErrors++; printf("%d: Type Error: Sessions may not return.\n", s->lineno); return; } typeEXP(s->val.expr); if(s->val.expr->type == NULL) return; if(!compareTypes(s->val.expr->type, t)) { typeErrors++; printf("%d: Type Error: Function must return correct type.\n", s->lineno); return; } break; case ifK: typeEXP(s->val.ifE.expr); typeSTM(s->val.ifE.stm, t); break; case ifelseK: typeEXP(s->val.ifelseE.expr); typeSTM(s->val.ifelseE.stm1, t); typeSTM(s->val.ifelseE.stm2, t); break; case whileK: typeEXP(s->val.whileE.expr); typeSTM(s->val.whileE.stm, t); break; case compoundK: typeCOMPOUNDSTM(s->val.compoundstm, t); break; case exprK: typeEXP(s->val.expr); break; } }
void typeEXP(EXP* e) { int counter; if(e == NULL) return; if(e->next != NULL) typeEXP(e->next); switch(e->kind) { case lvalueK: typeLVALUE(e->val.lvalueE); e->type = e->val.lvalueE->type; break; case assignK: typeLVALUE(e->val.assignE.lvalue); typeEXP(e->val.assignE.expr); if(compareTypes(e->val.assignE.lvalue->type, e->val.assignE.expr->type)) { e->type = e->val.assignE.lvalue->type; } else { printf("%d: Type Error: Assignment of incompatible types.\n", e->lineno); typeErrors++; } break; case equalsK: typeEXP(e->val.equalsE.left); typeEXP(e->val.equalsE.right); if(compareTypes(e->val.equalsE.left->type, e->val.equalsE.right->type)) { e->type = makeBool(); } else { printf("%d: Type Error: Comparing incompatible types.\n", e->lineno); typeErrors++; } break; case notequalsK: typeEXP(e->val.notequalsE.left); typeEXP(e->val.notequalsE.right); if(compareTypes(e->val.notequalsE.left->type, e->val.notequalsE.right->type)) { e->type = makeBool(); } else { printf("%d: Type Error: Comparing incompatible types.\n", e->lineno); typeErrors++; } break; case ltK: typeEXP(e->val.ltE.left); typeEXP(e->val.ltE.right); if(compareTypes(e->val.ltE.left->type, e->val.ltE.right->type)) { e->type = makeBool(); } else { printf("%d: Type Error: Comparing incompatible types.\n", e->lineno); typeErrors++; } if(!compareTypes(stringType, e->val.ltE.left->type) && !compareTypes(intType, e->val.ltE.left->type)) { printf("%d: Type Error: Comparisons can only be between ints or strings.\n", e->lineno); typeErrors++; } break; case gtK: typeEXP(e->val.gtE.left); typeEXP(e->val.gtE.right); if(compareTypes(e->val.gtE.left->type, e->val.gtE.right->type)) { e->type = makeBool(); } else { printf("%d: Type Error: Comparing incompatible types.\n", e->lineno); typeErrors++; } if(!compareTypes(stringType, e->val.gtE.left->type) && !compareTypes(intType, e->val.gtE.left->type)) { printf("%d: Type Error: Comparisons can only be between ints or strings.\n", e->lineno); typeErrors++; } break; case lteK: typeEXP(e->val.lteE.left); typeEXP(e->val.lteE.right); if(compareTypes(e->val.lteE.left->type, e->val.lteE.right->type)) { e->type = makeBool(); } else { printf("%d: Type Error: Comparing incompatible types.\n", e->lineno); typeErrors++; } if(!compareTypes(stringType, e->val.lteE.left->type) && !compareTypes(intType, e->val.lteE.left->type)) { printf("%d: Type Error: Comparisons can only be between ints or strings.\n", e->lineno); typeErrors++; } break; case gteK: typeEXP(e->val.gteE.left); typeEXP(e->val.gteE.right); if(compareTypes(e->val.gteE.left->type, e->val.gteE.right->type)) { e->type = makeBool(); } else { printf("%d: Type Error: Comparing incompatible types.\n", e->lineno); typeErrors++; } if(!compareTypes(stringType, e->val.gteE.left->type) && !compareTypes(intType, e->val.gteE.left->type)) { printf("%d: Type Error: Comparisons can only be between ints or strings.\n", e->lineno); typeErrors++; } break; case notK: typeEXP(e->val.exprE); if(compareTypes(boolType, e->val.exprE->type)) e->type = makeBool(); else { printf("%d: Type Error: bool type expected.\n", e->lineno); typeErrors++; } break; case plusK: typeEXP(e->val.plusE.left); typeEXP(e->val.plusE.right); counter = 0; if(compareTypes(stringType, e->val.plusE.left->type)) counter++; else if(!compareTypes(intType, e->val.plusE.left->type)) { printf("%d: Type Error: incorrect types for operator '+'.\n", e->lineno); typeErrors++; } if(compareTypes(stringType, e->val.plusE.right->type)) counter++; else if(!compareTypes(intType, e->val.plusE.right->type)) { printf("%d: Type Error: incorrect types for operator '+'.\n", e->lineno); typeErrors++; } if(counter > 0) e->type = makeString(); else e->type = makeInt(); break; case minusK: typeEXP(e->val.minusE.left); typeEXP(e->val.minusE.right); if(compareTypes(e->val.minusE.left->type, e->val.minusE.right->type) && compareTypes(intType, e->val.minusE.left->type)) { e->type = makeInt(); } else { printf("%d: Type Error: Expected type int for subtraction.\n", e->lineno); typeErrors++; } break; case multK: typeEXP(e->val.multE.left); typeEXP(e->val.multE.right); if(compareTypes(e->val.multE.left->type, e->val.multE.right->type) && compareTypes(intType, e->val.multE.left->type)) { e->type = makeInt(); } else { printf("%d: Type Error: Expected type int for multiplication.\n", e->lineno); typeErrors++; } break; case divK: typeEXP(e->val.divE.left); typeEXP(e->val.divE.right); if(compareTypes(e->val.divE.left->type, e->val.divE.right->type) && compareTypes(intType, e->val.divE.left->type)) { e->type = makeInt(); } else { printf("%d: Type Error: Expected type int for division.\n", e->lineno); typeErrors++; } break; case modK: typeEXP(e->val.modE.left); typeEXP(e->val.modE.right); if(compareTypes(e->val.modE.left->type, e->val.modE.right->type) && compareTypes(intType, e->val.modE.left->type)) { e->type = makeInt(); } else { printf("%d: Type Error: Expected type int for mod.\n", e->lineno); typeErrors++; } break; case andK: typeEXP(e->val.andE.left); typeEXP(e->val.andE.right); if(compareTypes(e->val.andE.left->type, e->val.andE.right->type) && compareTypes(boolType, e->val.andE.left->type)) { e->type = makeBool(); } else { printf("%d: Type Error: Expected type bool for &&.\n", e->lineno); typeErrors++; } break; case orK: typeEXP(e->val.orE.left); typeEXP(e->val.orE.right); if(compareTypes(e->val.orE.left->type, e->val.orE.right->type) && compareTypes(boolType, e->val.orE.left->type)) { e->type = makeBool(); } else { printf("%d: Type Error: Expected type bool for ||.\n", e->lineno); typeErrors++; } break; case joinK: typeEXP(e->val.joinE.left); typeEXP(e->val.joinE.right); if(e->val.joinE.left->type->schema == NULL || e->val.joinE.right->type->schema == NULL) { return; } e->type = NEW(TYPE); e->type->kind = tupleidK; e->type->schema = joinTuples(e->val.joinE.left->type->schema, e->val.joinE.right->type->schema); break; case keepK: typeEXP(e->val.keepE.left); e->type = NEW(TYPE); e->type->kind = tupleidK; e->type->schema = keepIDs(e->val.keepE.left->type->schema, e->val.keepE.right); if(e->type->schema == NULL) { printf("%d: Type Error: Identifiers are not a subset of schema fields.\n", e->lineno); typeErrors++; } break; case removeK: typeEXP(e->val.removeE.left); e->type = NEW(TYPE); e->type->kind = tupleidK; e->type->schema = removeIDs(e->val.keepE.left->type->schema, e->val.keepE.right); if(e->type->schema == NULL) { printf("%d: Type Error: Identifiers are not a subset of schema fields.\n", e->lineno); typeErrors++; } break; case callK: typeARGUMENT(e->val.callE.left->symbol->val.functionS->argument, e->val.callE.right); e->type = e->val.callE.left->symbol->val.functionS->type; break; case tupleK: typeFIELDVALUE(e->val.tupleE); e->type = NEW(TYPE); e->type->kind = tupleidK; /* SEGFAULT WARNING TODO HELP */ e->type->schema = NEW(SCHEMA); makeAnonymousTuple(e->type->schema, e->val.tupleE); break; case parenK: typeEXP(e->val.exprE); e->type = e->val.exprE->type; break; case intconstK: e->type = makeInt(); break; case trueK: e->type = makeBool(); break; case falseK: e->type = makeBool(); break; case stringconstK: e->type = makeString(); break; } }