Commit b798cdd8 authored by xx1219's avatar xx1219
Browse files

xx1219: merge with develop

parents 71debc50 570699bd
......@@ -358,7 +358,9 @@ public class ARMInstructionGenerator implements NodeVisitor<Void> {
stackOffset = 0;
/* 2 call function with B instruction */
instructions.add(new BL(FUNC_HEADER + node.getFunction().getFunctionName()));
String overloadName = node.getFunction().getOverloadName();
String actualFuncName = (overloadName != null) ? overloadName : node.getFunction().getFunctionName();
instructions.add(new BL(FUNC_HEADER + actualFuncName));
/* 3 add back stack pointer */
if (paramSize > 0) {
......@@ -773,7 +775,9 @@ public class ARMInstructionGenerator implements NodeVisitor<Void> {
/* 1 add function label,
* PUSH {lr}
*/
instructions.add(new Label(FUNC_HEADER + node.getFunctionName()));
String overloadName = node.getOverloadName();
String actualFuncName = (overloadName != null) ? overloadName : node.getFunctionName();
instructions.add(new Label(FUNC_HEADER + actualFuncName));
instructions.add(new Push(Collections.singletonList(LR)));
/* 2 decrease stack, leave space for variable in function body
......
......@@ -37,8 +37,8 @@ import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.ParserRuleContext;
import utils.NodeVisitor;
import utils.frontend.ParserErrorHandler;
import utils.frontend.symbolTable.Symbol;
import utils.frontend.symbolTable.SymbolTable;
......@@ -91,6 +91,10 @@ public class SemanticChecker extends WACCParserBaseVisitor<Node> {
/* record all files that have been imported */
private Set<String> allImportCollection = new HashSet<>();
/* for function overload */
private Set<String> overloadFuncNames = new HashSet<>();
/* constructor of SemanticChecker */
public SemanticChecker(Set<String> libraryCollection) {
currSymbolTable = null;
......@@ -163,10 +167,25 @@ public class SemanticChecker extends WACCParserBaseVisitor<Node> {
globalStructTable.replace(s.IDENT().getText(), node);
}
/* check function overload */
Set<String> tempStore = new HashSet<>();
for (FuncContext f : ctx.func()) {
String funcName = f.IDENT().getText();
if (tempStore.contains(funcName)) {
overloadFuncNames.add(funcName);
}
tempStore.add(funcName);
}
/* add the identifiers and parameter list of functions in the globalFuncTable first */
for (FuncContext f : ctx.func()) {
String funcName = f.IDENT().getText();
/* if the func name is overloading, append the types of all param */
if (overloadFuncNames.contains(funcName)) {
funcName = findOverloadFuncName(f);
}
/* check if the function is defined already */
if (globalFuncTable.containsKey(funcName)) {
symbolRedeclared(ctx, funcName);
......@@ -186,12 +205,23 @@ public class SemanticChecker extends WACCParserBaseVisitor<Node> {
}
}
globalFuncTable.put(funcName, new FuncNode(funcName, returnType, param_list));
/* store the text func name because ASTPrinter need to use it */
FuncNode node = new FuncNode(f.IDENT().getText(), returnType, param_list);
/* store the overload func name as well if necessary */
if (!funcName.equals(f.IDENT().getText())) {
node.setOverloadName(funcName);
}
globalFuncTable.put(funcName, node);
}
/* then iterate through a list of function declarations to visit the function body */
for (FuncContext f : ctx.func()) {
String funcName = f.IDENT().getText();
if (overloadFuncNames.contains(funcName)) {
funcName = findOverloadFuncName(f);
}
StatNode functionBody = visitFunc(f).asStatNode();
......@@ -319,8 +349,11 @@ public class SemanticChecker extends WACCParserBaseVisitor<Node> {
@Override
public Node visitFunc(FuncContext ctx) {
FuncNode funcNode = globalFuncTable.get(ctx.IDENT().getText());
String funcName = ctx.IDENT().getText();
if (overloadFuncNames.contains(funcName)) {
funcName = findOverloadFuncName(ctx);
}
FuncNode funcNode = globalFuncTable.get(funcName);
/* visit the function body */
expectedFunctionReturn = funcNode.getReturnType();
......@@ -949,10 +982,23 @@ public class SemanticChecker extends WACCParserBaseVisitor<Node> {
@Override
public Node visitFunctionCall(FunctionCallContext ctx) {
String funcName = ctx.IDENT().getText();
if (overloadFuncNames.contains(funcName)) {
if (ctx.arg_list() != null) {
for (ExprContext e : ctx.arg_list().expr()) {
funcName += (overloadSeparator + visit(e).asExprNode().getType().toString());
}
}
funcName = formatFuncName(funcName);
}
FuncNode function = globalFuncTable.get(funcName);
if (function == null) {
if (function == null && (funcName.contains("null")) || funcName.contains("empty")) {
overloadUnclearTypeError(ctx);
} else if (function == null) {
symbolNotFound(ctx, funcName);
}
List<ExprNode> params = new ArrayList<>();
/* check whether function has same number of parameter */
......
......@@ -22,12 +22,15 @@ public class FuncNode implements Node {
private final Type returnType;
private final List<IdentNode> parameters;
private StatNode functionBody;
/* for function overload */
private String overloadName;
public FuncNode(String functionName, Type returnType, List<IdentNode> params) {
this.returnType = returnType;
this.functionBody = null;
this.parameters = params;
this.functionName = functionName;
this.overloadName = null;
}
public StatNode getFunctionBody() {
......@@ -58,6 +61,14 @@ public class FuncNode implements Node {
return functionName;
}
public void setOverloadName(String overloadName) {
this.overloadName = overloadName;
}
public String getOverloadName() {
return overloadName;
}
@Override
public <T> T accept(NodeVisitor<T> visitor) {
return visitor.visitFuncNode(this);
......
......@@ -36,10 +36,10 @@ public class BinopNode extends ExprNode {
case MOD:
case BITOR:
case BITAND:
type = new BasicType(BasicTypeEnum.INTEGER);
type = new BasicType(BasicTypeEnum.INT);
break;
default:
type = new BasicType(BasicTypeEnum.BOOLEAN);
type = new BasicType(BasicTypeEnum.BOOL);
}
weight = expr1.getWeight() + expr2.getWeight() + 2;
}
......
......@@ -15,7 +15,7 @@ public class BoolNode extends ExprNode {
public BoolNode(boolean val) {
this.val = val;
this.type = new BasicType(BasicTypeEnum.BOOLEAN);
this.type = new BasicType(BasicTypeEnum.BOOL);
this.weight = 1;
}
......
......@@ -15,7 +15,7 @@ public class IntegerNode extends ExprNode {
public IntegerNode(int val) {
this.val = val;
this.type = new BasicType(BasicTypeEnum.INTEGER);
this.type = new BasicType(BasicTypeEnum.INT);
this.weight = 1;
}
......
......@@ -23,13 +23,13 @@ public class UnopNode extends ExprNode {
this.operator = operator;
switch (operator) {
case NOT:
type = new BasicType(BasicTypeEnum.BOOLEAN);
type = new BasicType(BasicTypeEnum.BOOL);
break;
case LEN:
case MINUS:
case ORD:
case COMPLEMENT:
type = new BasicType(BasicTypeEnum.INTEGER);
type = new BasicType(BasicTypeEnum.INT);
break;
case CHR:
type = new BasicType(BasicTypeEnum.CHAR);
......
......@@ -49,7 +49,7 @@ public class ArrayType implements Type {
@Override
public String toString() {
return "Array<" + contentType + ">";
return contentType + "[]";
}
@Override
......
......@@ -30,7 +30,7 @@ public class BasicType implements Type {
@Override
public String toString() {
return basicTypeEnum.toString();
return basicTypeEnum.toString().toLowerCase();
}
@Override
......@@ -42,9 +42,9 @@ public class BasicType implements Type {
public int getSize() {
switch (basicTypeEnum) {
case CHAR:
case BOOLEAN:
case BOOL:
return BYTE_SIZE;
case INTEGER:
case INT:
return WORD_SIZE;
case STRING:
return POINTER_SIZE;
......
package frontend.type;
public enum BasicTypeEnum {
INTEGER,
BOOLEAN,
INT,
BOOL,
CHAR,
STRING
}
package frontend.type;
import frontend.node.expr.ExprNode;
import static utils.Utils.*;
import java.util.Objects;
import static utils.Utils.POINTER_SIZE;
public class PairType implements Type {
......@@ -64,7 +60,12 @@ public class PairType implements Type {
@Override
public String toString() {
return "Pair<" + fstType + ", " + sndType + ">";
if (fstType == null || sndType == null) {
return "null";
}
String fst = (fstType instanceof PairType) ? "pair" : fstType.toString();
String snd = (sndType instanceof PairType) ? "pair" : sndType.toString();
return "pair(" + fst + ", " + snd + ")";
}
@Override
......
......@@ -47,6 +47,6 @@ public class StructType implements Type {
@Override
public String toString() {
return "struct " + ((name != null) ? name : "\"name\"");
return (name != null) ? name : "empty";
}
}
# Output:
# #semantic error#
# Program:
begin
int foo(int i) is return 1 end
char foo(int c) is return 'a' end
skip
end
\ No newline at end of file
# Output:
# #semantic error#
# Program:
begin
struct a is {int i}
struct b is {int i}
int foo(a x) is return 1 end
int foo(b y) is return 1 end
int a = call foo(empty)
end
\ No newline at end of file
# Output:
# #semantic error#
# Program:
begin
int foo(pair(bool, bool) b) is return 1 end
int foo(pair(int, int) a) is return 1 end
int x = call foo(null)
end
\ No newline at end of file
# Output:
# 1
# 1
# Program:
begin
int foo(int[] a) is return a[0] end
int foo(int[][] a) is return a[0][0] end
int[] a = [1];
int[][] b = [a];
int x = call foo(a);
int y = call foo(b);
println x;
println y
end
\ No newline at end of file
# Output:
# 1
# Program:
begin
struct a is {int i}
struct b is {int i}
int foo(a x) is return 1 end
int foo(b y) is return 1 end
a x = empty;
int a = call foo(x);
println a
end
\ No newline at end of file
# Output:
# 1
# Program:
begin
int foo(pair(bool, bool) b) is return 1 end
int foo(pair(int, int) a) is return 1 end
pair(int, int) x = null;
int y = call foo(x);
println y
end
\ No newline at end of file
# Output:
# 1
# 1
# Program:
begin
int foo(pair(int, int) a) is int x = fst a; return x end
int foo(pair(pair, pair) a) is pair(int,int) p = fst a; int x = fst p; return x end
pair(int, int) p1 = newpair(1,2);
pair(pair, pair) p2 = newpair(p1, null);
int x = call foo(p1);
int y = call foo(p2);
println x;
println y
end
\ No newline at end of file
# Output:
# 10
# 1
# Program:
begin
int foo() is return 10 end
int foo(int n) is return n end
int a = call foo();
println a;
int b = call foo(1);
println b
end
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment