Skip to content

Commit f51cf6e

Browse files
author
robertDurst
committed
small improvements to error message display for error handling
1 parent b5e09fe commit f51cf6e

File tree

2 files changed

+79
-65
lines changed

2 files changed

+79
-65
lines changed

src/semantics/TypeChecker.cpp

Lines changed: 78 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,8 @@ isVoid(ast::Primary* node)
354354
// the actual types (inputs) and determines if everything is kosher
355355
void
356356
TypeChecker::compareFunctions(std::vector<std::string> inputs,
357-
std::vector<ast::Primary*> args, std::string name)
357+
std::vector<ast::Primary*> args, std::string name,
358+
int lineNumber)
358359
{
359360
int numArgs = args.size();
360361
if (numArgs == 1 && isVoid(args.at(0)))
@@ -366,11 +367,11 @@ TypeChecker::compareFunctions(std::vector<std::string> inputs,
366367

367368
if (numArgs < numInps)
368369
semanticErrorHandler->handle(new Error(
369-
0, "Not enough args supplied to function: " + name + "."));
370+
lineNumber, "Not enough args supplied to function: " + name + "."));
370371

371372
else if (numArgs > numInps)
372-
semanticErrorHandler->handle(
373-
new Error(0, "Too many args supplied to function: " + name + "."));
373+
semanticErrorHandler->handle(new Error(
374+
lineNumber, "Too many args supplied to function: " + name + "."));
374375

375376
else
376377
{
@@ -387,9 +388,10 @@ TypeChecker::compareFunctions(std::vector<std::string> inputs,
387388
// ok
388389
}
389390
else if (!symbolTable->hasVariable(actual))
390-
semanticErrorHandler->handle(new Error(
391-
0, "Undefined argument: " + actual +
392-
" supplied for function: " + name + "."));
391+
semanticErrorHandler->handle(
392+
new Error(lineNumber,
393+
"Undefined argument: " + actual +
394+
" supplied for function: " + name + "."));
393395

394396
else
395397
{
@@ -417,9 +419,9 @@ TypeChecker::compareFunctions(std::vector<std::string> inputs,
417419

418420
if (actual != inputs[i])
419421
semanticErrorHandler->handle(new Error(
420-
0, "Supplied argument type of: " + actual +
421-
" does not match expected type of: " + inputs[i] +
422-
"."));
422+
lineNumber, "Supplied argument type of: " + actual +
423+
" does not match expected type of: " +
424+
inputs[i] + "."));
423425
}
424426
}
425427
}
@@ -478,16 +480,17 @@ TypeChecker::visit(ast::NewUDTDefinition* node)
478480
if (baseType != "udt")
479481
{
480482
semanticErrorHandler->handle(new Error(
481-
node->getLineNum(),
483+
node->getExpression()->getLineNum(),
482484
"Expected udt type. Instead received: " + baseType + "."));
483485
}
484486

485487
// make sure the type name of the assigned udt matches
486488
else if (udtTypeName != type)
487489
{
488-
semanticErrorHandler->handle(new Error(
489-
node->getLineNum(), "Expected udt of type: " + type +
490-
" and received: " + udtTypeName + "."));
490+
semanticErrorHandler->handle(
491+
new Error(node->getExpression()->getLineNum(),
492+
"Expected udt of type: " + type +
493+
" and received: " + udtTypeName + "."));
491494
}
492495

493496
// ensure all attributes exist
@@ -507,7 +510,7 @@ TypeChecker::visit(ast::NewUDTDefinition* node)
507510
if (count + 1 > st->getCurrentScope())
508511
{
509512
semanticErrorHandler->handle(
510-
new Error(node->getLineNum(),
513+
new Error(node->getExpression()->getLineNum(),
511514
"Too many arguments in udt initialization."));
512515
break;
513516
}
@@ -524,7 +527,7 @@ TypeChecker::visit(ast::NewUDTDefinition* node)
524527
{
525528
// var does not exist in method symbol table
526529
semanticErrorHandler->handle(new Error(
527-
node->getLineNum(),
530+
node->getExpression()->getLineNum(),
528531
"Received unknown attribute name of: " + varName +
529532
" in constructor of udt of type: " + udtTypeName +
530533
"."));
@@ -538,7 +541,7 @@ TypeChecker::visit(ast::NewUDTDefinition* node)
538541
// given var type does not match expected type
539542
// determined by udt definition
540543
semanticErrorHandler->handle(new Error(
541-
node->getLineNum(),
544+
node->getExpression()->getLineNum(),
542545
"Received intiializer variable of type: " + actualType +
543546
" in constructor of udt of type: " + udtTypeName +
544547
" when a variable for type: " + expectedType +
@@ -552,7 +555,7 @@ TypeChecker::visit(ast::NewUDTDefinition* node)
552555
if (ordering != count)
553556
{
554557
semanticErrorHandler->handle(new Error(
555-
node->getLineNum(),
558+
node->getExpression()->getLineNum(),
556559
"In udt inititialization, attributes must be "
557560
"defined in the same ordering as the udt "
558561
"definition. Received: " +
@@ -568,7 +571,7 @@ TypeChecker::visit(ast::NewUDTDefinition* node)
568571

569572
if (count < st->getCurrentScope())
570573
semanticErrorHandler->handle(
571-
new Error(node->getLineNum(),
574+
new Error(node->getExpression()->getLineNum(),
572575
"Too few arguments in udt initialization."));
573576
}
574577

@@ -643,7 +646,7 @@ TypeChecker::visit(ast::FunctionDefinition* node)
643646
udtTable->hasUDT(inp_name)))
644647
{
645648
semanticErrorHandler->handle(
646-
new Error(node->getLineNum(),
649+
new Error(var->getLineNum(),
647650
"Declared function input named: " + inp_name +
648651
" illegally shares its name with a "
649652
"type or a keyword/reserved word."));
@@ -701,7 +704,7 @@ TypeChecker::visit(ast::FunctionDefinition* node)
701704
if (out_type == "void")
702705
{
703706
semanticErrorHandler->handle(
704-
new Error(node->getLineNum(),
707+
new Error(var->getLineNum(),
705708
"Unexpected return in function returning void."));
706709
break;
707710
}
@@ -719,7 +722,7 @@ TypeChecker::visit(ast::FunctionDefinition* node)
719722

720723
if (actualReturnType != out_type)
721724
semanticErrorHandler->handle(new Error(
722-
node->getLineNum(),
725+
subnode->getLineNum(),
723726
"Actual return type of: " + actualReturnType +
724727
" does not match expected return type of: " + out_type +
725728
"."));
@@ -728,7 +731,7 @@ TypeChecker::visit(ast::FunctionDefinition* node)
728731

729732
if (!hasReturn && out_type != "void")
730733
semanticErrorHandler->handle(new Error(
731-
node->getLineNum(), "Function does not have a return statement."));
734+
body->getLineNum(), "Function does not have a return statement."));
732735

733736
// exit scope once we exit the body
734737
symbolTable->exitScope();
@@ -774,7 +777,7 @@ TypeChecker::visit(ast::UserDefinedTypeDefinition* node)
774777
// void, makes no sense here
775778
if ((!isPrimitive(type) && !udtTable->hasUDT(type)) || (type == "void"))
776779
semanticErrorHandler->handle(new Error(
777-
node->getLineNum(),
780+
var->getLineNum(),
778781
"Udt attribute type of: " + type + " for attribute: " + name +
779782
" and for udt: " + udt_name + " does not exist."));
780783

@@ -904,48 +907,55 @@ TypeChecker::visit(ast::BinaryExpression* node)
904907
{
905908
if (lType != "int")
906909
semanticErrorHandler->handle(
907-
new Error(0, "Expected int type on left "
908-
"side of operation. Instead received: " +
909-
lType + "."));
910+
new Error(subnode->getLineNum(),
911+
"Expected int type on left "
912+
"side of operation. Instead received: " +
913+
lType + "."));
910914
else if (rType != "int")
911915
semanticErrorHandler->handle(
912-
new Error(0, "Expected int type on left "
913-
"side of operation. Instead received: " +
914-
rType + "."));
916+
new Error(subnode->getLineNum(),
917+
"Expected int type on left "
918+
"side of operation. Instead received: " +
919+
rType + "."));
915920
}
916921
else if (subnode->onlyAcceptsBool())
917922
{
918923
if (lType != "bool")
919924
semanticErrorHandler->handle(
920-
new Error(0, "Expected boolean type on left side of "
921-
"operation. Instead received: " +
922-
lType + "."));
925+
new Error(subnode->getLineNum(),
926+
"Expected boolean type on left side of "
927+
"operation. Instead received: " +
928+
lType + "."));
923929

924930
else if (rType != "bool")
925931
semanticErrorHandler->handle(
926-
new Error(0, "Expected boolean type on right side of "
927-
"operation. Instead received: " +
928-
rType + "."));
932+
new Error(subnode->getLineNum(),
933+
"Expected boolean type on right side of "
934+
"operation. Instead received: " +
935+
rType + "."));
929936
}
930937
else if (subnode->onlyAcceptsFltOrInt())
931938
{
932939
if (lType != rType)
933940
semanticErrorHandler->handle(
934-
new Error(0, "Expected the same types on each side of "
935-
"operation. Instead received: " +
936-
lType + " and " + rType + "."));
941+
new Error(subnode->getLineNum(),
942+
"Expected the same types on each side of "
943+
"operation. Instead received: " +
944+
lType + " and " + rType + "."));
937945

938946
else if (lType != "int" && lType != "flt")
939-
semanticErrorHandler->handle(new Error(
940-
0, "Expected either float or integer type on left "
941-
"side of operation. Instead received: " +
942-
lType + "."));
947+
semanticErrorHandler->handle(
948+
new Error(subnode->getLineNum(),
949+
"Expected either float or integer type on left "
950+
"side of operation. Instead received: " +
951+
lType + "."));
943952

944953
else if (rType != "int" && rType != "flt")
945-
semanticErrorHandler->handle(new Error(
946-
0, "Expected either float or integer type on left "
947-
"side of operation. Instead received: " +
948-
rType + "."));
954+
semanticErrorHandler->handle(
955+
new Error(subnode->getLineNum(),
956+
"Expected either float or integer type on left "
957+
"side of operation. Instead received: " +
958+
rType + "."));
949959
}
950960
else
951961
{
@@ -956,9 +966,10 @@ TypeChecker::visit(ast::BinaryExpression* node)
956966
else
957967
{
958968
semanticErrorHandler->handle(
959-
new Error(0, "Expected the same types on each side of "
960-
"operation. Instead received: " +
961-
lType + " and " + rType + "."));
969+
new Error(subnode->getLineNum(),
970+
"Expected the same types on each side of "
971+
"operation. Instead received: " +
972+
lType + " and " + rType + "."));
962973
}
963974
}
964975
break;
@@ -986,8 +997,9 @@ TypeChecker::visit(ast::BinaryExpression* node)
986997
break;
987998
}
988999
default:
989-
semanticErrorHandler->handle(new Error(
990-
0, "Illegal left hand expression in assignment."));
1000+
semanticErrorHandler->handle(
1001+
new Error(subnode->getLineNum(),
1002+
"Illegal left hand expression in assignment."));
9911003
}
9921004
break;
9931005
}
@@ -1022,7 +1034,7 @@ TypeChecker::visit(ast::AttributeAccess* node)
10221034
if (!symbolTable->hasVariable(variableName))
10231035
{
10241036
semanticErrorHandler->handle(new Error(
1025-
node->getLineNum(),
1037+
node->getUDT()->getLineNum(),
10261038
"Attribute: " + attributeName +
10271039
" called on undeclared variable: " + variableName + "."));
10281040

@@ -1037,7 +1049,7 @@ TypeChecker::visit(ast::AttributeAccess* node)
10371049
if (!udtTable->hasUDT(variableName))
10381050
{
10391051
semanticErrorHandler->handle(new Error(
1040-
node->getLineNum(),
1052+
node->getUDT()->getLineNum(),
10411053
"Attribute: " + attributeName +
10421054
" called on nonexistent udt type: " + variableName + "."));
10431055

@@ -1049,7 +1061,7 @@ TypeChecker::visit(ast::AttributeAccess* node)
10491061
->hasVariable(attributeName))
10501062
{
10511063
semanticErrorHandler->handle(new Error(
1052-
node->getLineNum(),
1064+
node->getAttribute()->getLineNum(),
10531065
"Attribute: " + attributeName +
10541066
" does not exists for udt type: " + variableName + "."));
10551067

@@ -1073,9 +1085,9 @@ TypeChecker::visit(ast::MethodAccess* node)
10731085
if (!symbolTable->hasVariable(variableUDTname))
10741086
{
10751087
semanticErrorHandler->handle(new Error(
1076-
node->getLineNum(), "Method: " + methodName +
1077-
" called on nonexistent udt type: " +
1078-
variableUDTname + "."));
1088+
node->getUDT()->getLineNum(),
1089+
"Method: " + methodName + " called on nonexistent udt type: " +
1090+
variableUDTname + "."));
10791091

10801092
return;
10811093
}
@@ -1087,7 +1099,7 @@ TypeChecker::visit(ast::MethodAccess* node)
10871099
if (!udtTable->hasUDT(udtname))
10881100
{
10891101
semanticErrorHandler->handle(new Error(
1090-
node->getLineNum(),
1102+
node->getUDT()->getLineNum(),
10911103
"Method: " + methodName +
10921104
" called on nonexistent udt type: " + udtname + "."));
10931105

@@ -1103,7 +1115,7 @@ TypeChecker::visit(ast::MethodAccess* node)
11031115
if (!udtTable->getMethodSymbolTable(udtType)->hasVariable(methodName))
11041116
{
11051117
semanticErrorHandler->handle(
1106-
new Error(node->getLineNum(),
1118+
new Error(node->getName()->getLineNum(),
11071119
"Method: " + methodName +
11081120
" does not exist for udt type: " + udtType + "."));
11091121
// abort
@@ -1119,7 +1131,8 @@ TypeChecker::visit(ast::MethodAccess* node)
11191131
// ensure that each of the arguments is supplied and of the proper type
11201132
std::vector<ast::Primary*> args = node->getFunctionCall()->getArguments();
11211133

1122-
compareFunctions(inputs, args, methodName);
1134+
compareFunctions(inputs, args, methodName,
1135+
node->getFunctionCall()->getLineNum());
11231136

11241137
for (auto const& arg : args)
11251138
visit(arg);
@@ -1132,8 +1145,9 @@ TypeChecker::visit(ast::FunctionCall* node)
11321145

11331146
if (!symbolTable->hasVariable(name))
11341147
{
1135-
semanticErrorHandler->handle(new Error(
1136-
node->getLineNum(), "Function: " + name + " is not defined."));
1148+
semanticErrorHandler->handle(
1149+
new Error(node->getName()->getLineNum(),
1150+
"Function: " + name + " is not defined."));
11371151
return;
11381152
}
11391153

@@ -1146,7 +1160,7 @@ TypeChecker::visit(ast::FunctionCall* node)
11461160
// ensure that each of the arguments is supplied and of the proper type
11471161
std::vector<ast::Primary*> args = node->getArguments();
11481162

1149-
compareFunctions(inputs, args, name);
1163+
compareFunctions(inputs, args, name, node->getLineNum());
11501164

11511165
for (auto const& arg : args)
11521166
visit(arg);

src/semantics/TypeChecker.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class TypeChecker : public Visitor
2828
std::string primaryHelper(ast::Primary*);
2929
std::string expressionHelper(ast::Expression*);
3030
void compareFunctions(std::vector<std::string>, std::vector<ast::Primary*>,
31-
std::string);
31+
std::string, int);
3232
std::string getRightExpressionType(ast::BinaryExpression* node);
3333
bool nameIsLegal(std::string, int);
3434
bool typeExists(std::string, std::string, int);

0 commit comments

Comments
 (0)