Skip to content

Commit 9267479

Browse files
author
Joshua Crotts
committed
Added a ton of new tests and hopefully fixed a bit of the egregious error checks.
1 parent 1ec5b18 commit 9267479

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+1835
-58
lines changed

src/main/java/edu/joshuacrotts/littlec/exec/Launcher.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ public static void usage() {
1616
System.out.print("where [optinfile] is a .lc file or standard input (leave blank)\n\n");
1717
System.out.print("where \"flags\" is zero or more of the following:\n");
1818
System.out.print(" -o enables optimizations (in progress)\n");
19+
System.out.print(" -w enables warnings (displayed even if none exist) (in progress)\n");
20+
System.out.print(" -e enables errors (displayed even if none exist) (in progress)\n");
1921
System.out.print(" -d enables comments in assembly code generation (in progress)\n\n");
2022
System.out.print("where \"mode\" is one of the following:\n");
2123
System.out.print(" -lt runs LexerTest\n");

src/main/java/edu/joshuacrotts/littlec/icinterp/ICInterp.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -494,9 +494,9 @@ else if (parts[si + 1].equals("=="))
494494
else if (parts[si + 1].equals("!="))
495495
return new SimValue(4, (val1.iVal != val2.iVal) ? 1 : 0);
496496
else if (parts[si + 1].equals("<>"))
497-
return new SimValue(4, (~(val1.iVal ^ val2.iVal) > 0) ? 1 : 0);
497+
return new SimValue(4, (val1.iVal == val2.iVal) ? 1 : 0);
498498
else if (parts[si + 1].equals("->"))
499-
return new SimValue(4, ((~val1.iVal | val2.iVal) > 0) ? 1 : 0);
499+
return new SimValue(4, (!(val1.iVal !=0) || (val2.iVal!=0)) ? 1 : 0);
500500
else if (parts[si + 1].equals("ldidx4")) {
501501
return new SimValue(4, ptrGetInt(val1.iVal, 4 + 4 * val2.iVal));
502502
} else if (parts[si + 1].equals("ldidx1")) {

src/main/java/edu/joshuacrotts/littlec/main/LCErrorListener.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ public static boolean sawError() {
141141
* @return true if a warning was seen.
142142
*/
143143
public static boolean sawWarning() {
144-
return gotError;
144+
return gotWarning;
145145
}
146146

147147
/**

src/main/java/edu/joshuacrotts/littlec/main/LCListener.java

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,8 @@ public void enterIfStatement(LittleCParser.IfStatementContext ctx) {
145145
*/
146146
@Override
147147
public void exitIfStatement(LittleCParser.IfStatementContext ctx) {
148+
if (LCErrorListener.sawError())
149+
return;
148150
LCSyntaxTree condPortion = this.values.get(ctx.ruleIfStatementCond());
149151
LCSyntaxTree thenPortion = this.syntaxTree.getChildren().remove(this.syntaxTree.getChildren().size() - 1);
150152
LCSyntaxTree elsePortion = this.values.get(ctx.ruleElseStatement());
@@ -189,7 +191,7 @@ public void exitElseStatement(LittleCParser.ElseStatementContext ctx) {
189191
if (this.syntaxTree.getChildren().isEmpty()) {
190192
return;
191193
}
192-
194+
193195
LCSyntaxTree lastChild = this.syntaxTree.getChildren().remove(this.syntaxTree.getChildren().size() - 1);
194196
this.values.put(ctx, lastChild);
195197
}
@@ -218,7 +220,6 @@ public void exitWhileStatement(LittleCParser.WhileStatementContext ctx) {
218220
// we can just remove it from the main tree and add it to the cond tree.
219221
LCSyntaxTree loopBody = this.syntaxTree.getChildren().remove(this.syntaxTree.getChildren().size() - 1);
220222
LCSyntaxTree condPortion = this.values.get(ctx.ruleWhileStatementCond());
221-
222223
this.syntaxTree.addChild(new LCLoopStatementNode(ctx, condPortion, loopBody));
223224

224225
// Turn off the flag for being in a loop.
@@ -592,6 +593,10 @@ public void enterReturnStatement(LittleCParser.ReturnStatementContext ctx) {
592593
*/
593594
@Override
594595
public void exitReturnStatement(LittleCParser.ReturnStatementContext ctx) {
596+
if (LCErrorListener.sawError()) {
597+
return;
598+
}
599+
595600
LCSyntaxTree retExpr = this.values.get(ctx.expr());
596601
String fnRetType = "";
597602

@@ -844,6 +849,7 @@ public void exitExprPreOp(LittleCParser.ExprPreOpContext ctx) {
844849
*/
845850
@Override
846851
public void exitExprPostOp(LittleCParser.ExprPostOpContext ctx) {
852+
if (LCErrorListener.sawError()) return;
847853
// First check if the symbol exists.
848854
String id = ctx.ID().getText();
849855
String idType = this.symbolTable.getSymbolEntry(id).getVarType();
@@ -1033,8 +1039,11 @@ public void exitExprParen(LittleCParser.ExprParenContext ctx) {
10331039
*/
10341040
@Override
10351041
public void exitExprArray(LittleCParser.ExprArrayContext ctx) {
1036-
String id = ctx.ID().getText();
1042+
if (LCErrorListener.sawError()) {
1043+
return;
1044+
}
10371045

1046+
String id = ctx.ID().getText();
10381047
if (!this.symbolTable.hasSymbol(id)) {
10391048
LCErrorListener.syntaxError(ctx, "array object was not previously declared.");
10401049
return;
@@ -1236,6 +1245,10 @@ public void exitStringRefDeclaration(LittleCParser.StringRefDeclarationContext c
12361245
* @return a syntax tree, or null if an error was detected.
12371246
*/
12381247
public LCSyntaxTree getSyntaxTree() {
1248+
if (LCErrorListener.sawWarning()) {
1249+
LCErrorListener.printWarnings();
1250+
}
1251+
12391252
if (LCErrorListener.sawError()) {
12401253
LCErrorListener.printErrors();
12411254
return null;

src/main/java/edu/joshuacrotts/littlec/mipsgen/CodeGeneration.java

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -575,12 +575,20 @@ public static String emitBinaryOp(ProgState progState, ICAddress res, ICAddress
575575
progState.copyVal(op2Reg, op2);
576576

577577
// Perform the binary op (power op uses different code).
578-
if (!op.equals("**"))
579-
sb.append(MIPSInstruction.genBinaryOp(getMIPSBinaryOp(op), "" + resReg, "" + op1Reg, "" + op2Reg));
580-
else {
578+
if (op.equals("**")){
581579
MIPSReg op3Reg = progState.getNextAvailableRegister();
582580
sb.append(MIPSInstruction.genPowerBinaryOp("" + resReg, "" + op1Reg, "" + op2Reg, "" + op3Reg));
583581
progState.invalidate(op3Reg);
582+
} else if (op.equals("<>")) {
583+
MIPSReg op3Reg = progState.getNextAvailableRegister();
584+
sb.append(MIPSInstruction.genBiconditionalBinaryOp("" + resReg, "" + op1Reg, "" + op2Reg, "" + op3Reg));
585+
progState.invalidate(op3Reg);
586+
} else if (op.equals("->")) {
587+
MIPSReg op3Reg = progState.getNextAvailableRegister();
588+
sb.append(MIPSInstruction.genImplicationBinaryOp("" + resReg, "" + op1Reg, "" + op2Reg, "" + op3Reg));
589+
progState.invalidate(op3Reg);
590+
} else {
591+
sb.append(MIPSInstruction.genBinaryOp(getMIPSBinaryOp(op), "" + resReg, "" + op1Reg, "" + op2Reg));
584592
}
585593

586594
// Store the result if we loaded in a new temporary for the destination.
@@ -859,6 +867,10 @@ private static String getMIPSBinaryOp(String op) {
859867
return "sll";
860868
case ">>":
861869
return "sra";
870+
case "<<<":
871+
return "rol";
872+
case ">>>":
873+
return "ror";
862874
case "^":
863875
return "xor";
864876
default:
@@ -881,6 +893,8 @@ private static String getMIPSUnaryOp(String op) {
881893
return "move";
882894
case "~":
883895
return "not";
896+
case "@":
897+
return "abs";
884898
case "-":
885899
case "!":
886900
return "negu";

src/main/java/edu/joshuacrotts/littlec/mipsgen/MIPSInstruction.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,38 @@ protected static String genPowerBinaryOp(String dest, String op1, String op2, St
186186
sb.append(cl2 + ":\n");
187187
return sb.toString();
188188
}
189+
190+
/**
191+
*
192+
* @param dest
193+
* @param op1
194+
* @param op2
195+
* @param tmpOp3
196+
* @return
197+
*/
198+
protected static String genImplicationBinaryOp(String dest, String op1, String op2, String tmpOp3) {
199+
StringBuilder sb = new StringBuilder();
200+
sb.append(MIPSInstruction.genUnaryOp("not", tmpOp3, op1));
201+
sb.append(MIPSInstruction.genBinaryOp("addi", tmpOp3, tmpOp3, "2"));
202+
sb.append(MIPSInstruction.genBinaryOp("or", dest, tmpOp3, op2));
203+
return sb.toString();
204+
}
205+
206+
/**
207+
*
208+
* @param dest
209+
* @param op1
210+
* @param op2
211+
* @param tmpOp3
212+
* @return
213+
*/
214+
protected static String genBiconditionalBinaryOp(String dest, String op1, String op2, String tmpOp3) {
215+
StringBuilder sb = new StringBuilder();
216+
sb.append(MIPSInstruction.genBinaryOp("xor", tmpOp3, op1, op2));
217+
sb.append(MIPSInstruction.genUnaryOp("not", dest, tmpOp3));
218+
sb.append(MIPSInstruction.genBinaryOp("addi", dest, dest, "2"));
219+
return sb.toString();
220+
}
189221

190222
/**
191223
* Generates a binary operator in MIPS.

src/main/java/edu/joshuacrotts/littlec/syntaxtree/LCBinaryOperatorNode.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@
1010

1111
public class LCBinaryOperatorNode extends LCSyntaxTree {
1212

13-
/** Binary operator that we're using. */
13+
/**
14+
* Binary operator that we're using.
15+
*/
1416
private String op;
1517

1618
/**

src/main/java/edu/joshuacrotts/littlec/syntaxtree/LCFunctionArgsListNode.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77

88
public class LCFunctionArgsListNode extends LCSyntaxTree {
99

10-
/** List of LCSyntaxTree arguments. */
10+
/**
11+
* List of LCSyntaxTree arguments.
12+
*/
1113
private List<LCSyntaxTree> args;
1214

1315
/**

src/main/java/edu/joshuacrotts/littlec/syntaxtree/LCFunctionCallNode.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@
1212

1313
public class LCFunctionCallNode extends LCSyntaxTree {
1414

15-
/* Identifier of function. */
15+
/**
16+
* Identifier of function.
17+
*/
1618
private String id;
1719

1820
/**

src/main/java/edu/joshuacrotts/littlec/syntaxtree/LCIfStatementNode.java

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import edu.joshuacrotts.littlec.icode.ActivationRecord;
66
import edu.joshuacrotts.littlec.icode.ICInhAttr;
77
import edu.joshuacrotts.littlec.icode.ICode;
8+
import edu.joshuacrotts.littlec.main.LCErrorListener;
89

910
public class LCIfStatementNode extends LCSyntaxTree {
1011

@@ -28,14 +29,15 @@ public class LCIfStatementNode extends LCSyntaxTree {
2829
public LCIfStatementNode(ParserRuleContext ctx, LCSyntaxTree ifPart, LCSyntaxTree thenPart, LCSyntaxTree elsePart) {
2930
super("IF", "void");// No third parameter.
3031

31-
/* Two or three children. */
32-
/* Child 1 is the conditions. */
32+
// Child 1 is the conditions.
3333
super.addChild(ifPart);
3434

35-
/* Child 2 is the "then" portion of the condition. */
35+
this.testConditional(ctx, ifPart);
36+
37+
// Child 2 is the "then" portion of the condition.
3638
super.addChild(thenPart);
3739

38-
/* Child 3 is the "else" part. */
40+
// Child 3 is the "else" part.
3941
if (elsePart != null) {
4042
super.addChild(elsePart);
4143
}
@@ -80,7 +82,18 @@ public void genCode(ICInhAttr s) {
8082
this.getChildren().get(2).genCode(s2);
8183
}
8284
ICode.quad.addLabel(b.NEXT + ":");
83-
85+
}
86+
87+
/**
88+
* Since using terms, literals, or array indexing may not evaluate correctly (to be honest,
89+
* it DOESN'T evalutate correctly, we can display a warning if the user attempts to.
90+
*/
91+
private void testConditional(ParserRuleContext ctx, LCSyntaxTree cond) {
92+
if (cond instanceof LCVariableIdentifierNode || cond instanceof LCConstantLiteralNode
93+
|| cond instanceof LCArrayIndexNode) {
94+
LCErrorListener.syntaxWarning(ctx,
95+
"using only an identifier or literal in the condition may not evaluate correctly.");
96+
}
8497
}
8598

8699
@Override

src/main/java/edu/joshuacrotts/littlec/syntaxtree/LCLoopStatementNode.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ public void genCode(ICInhAttr s) {
5757

5858
// ...then the conditional.
5959
this.getChildren().get(0).genCode(b);
60+
6061
// The label to go to if it's true.
6162
ICode.quad.addLabel(b.TRUE + ":");
6263
this.getChildren().get(1).genCode(s);

src/main/java/edu/joshuacrotts/littlec/syntaxtree/LCPrePostOperatorNode.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public LCPrePostOperatorNode(ParserRuleContext ctx, SymbolTable symbolTable, Str
2727
LCSyntaxTree lvar) {
2828
super(type, lvarType);
2929

30-
/* One child for the lvalue being incremented or decremented. */
30+
// One child for the lvalue being incremented or decremented.
3131
super.addChild(lvar);
3232
}
3333

src/main/java/edu/joshuacrotts/littlec/syntaxtree/LCReturnStatementNode.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,12 @@ public void genCode(ICInhAttr info) {
4141
String returnStr = "return";
4242

4343
// If there is a return expression, then we have to append a data width to it.
44-
// Otherwise,
4544
if (!this.getChildren().isEmpty()) {
4645
this.getChildren().get(0).genCode(info);
4746
int retWidth = LCUtilities.getDataWidth(this.getChildren().get(0).getType());
4847
returnStr += retWidth;
4948
}
5049

51-
// addLine(resAddr, op1, op2, op), "return" is the op, return val is op1.
5250
ICode.quad.addLine("", (!this.getChildren().isEmpty() ? info.ADDR : ""), "", returnStr);
5351
}
5452

src/main/java/edu/joshuacrotts/littlec/syntaxtree/LCVariableDeclarationNode.java

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,19 @@
1111

1212
public class LCVariableDeclarationNode extends LCSyntaxTree {
1313

14-
/** Name of the variable for later reference. */
14+
/**
15+
* Name of the variable for later reference.
16+
*/
1517
private String id;
1618

17-
/** Type of variable that we're declaring. */
19+
/**
20+
* Type of variable that we're declaring.
21+
*/
1822
private String varType;
1923

20-
/** The literal value that we're assigning. Null if no lit. */
24+
/**
25+
* The literal value that we're assigning. Null if no lit.
26+
*/
2127
private Object literalValue;
2228

2329
/**
@@ -38,7 +44,6 @@ public LCVariableDeclarationNode(ParserRuleContext ctx, SymbolTable symbolTable,
3844
this.id = id;
3945
this.varType = varType;
4046
this.literalValue = literalValue;
41-
4247
// If we don't have the symbol in the current environment table (which defines
4348
// the current scope, then we're good to add it (we can shadow it).
4449
if (!symbolTable.hasSymbolInCurrentEnvironment(this.id)) {
@@ -111,7 +116,7 @@ public void genCode(ICInhAttr info) {
111116
info.ADDR = lLabel;
112117
}
113118
}
114-
/* Otherwise, we insert the value as normal. */
119+
// Otherwise, we insert the value as normal.
115120
else {
116121
int dataWidth = LCUtilities.getDataWidth(this.varType);
117122
String lit = this.literalValue == null ? "0" : this.literalValue.toString();

0 commit comments

Comments
 (0)