Skip to content
This repository has been archived by the owner on Jul 10, 2024. It is now read-only.

Group 6 - help needed once again :D #72

Merged
merged 11 commits into from
Jun 14, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import java.util.Set;

public class ASTLogicNode extends ASTNode {

@Override
public <T> T accept(ASTVisitor<T> visitor) {
return visitor.visitLogic(this);
Expand All @@ -14,7 +15,17 @@ public static Set<TokenType> getSelectionSet() {
return ASTStmtLstNode.getSelectionSet();
}

public ASTLogicalExprNode logicalExpr() {
public ASTLogicalExprNode getReturnNode() {
if(getChildren(ASTLogicalExprNode.class).isEmpty()){
return null;
}
return getChild(ASTLogicalExprNode.class, 0);
}

public boolean hasReturn(){
return getReturnNode() != null;
}
public ASTStmtLstNode getBody() {
return getChild(ASTStmtLstNode.class, 0);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@
import com.auberer.compilerdesignlectureproject.sema.SuperType;
import com.auberer.compilerdesignlectureproject.sema.Type;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Data
@Getter
@Setter
public abstract class ASTNode implements IVisitable {

public void addChild(ASTNode child) {
Expand All @@ -34,6 +37,10 @@ public Type setEvaluatedSymbolType(Type type) {
return type;
}

public String toString(){
marcauberer marked this conversation as resolved.
Show resolved Hide resolved
return "";
}

ASTNode parent;
List<ASTNode> children = new ArrayList<>();
CodeLoc codeLoc;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
package com.auberer.compilerdesignlectureproject.ast;

import com.auberer.compilerdesignlectureproject.lexer.TokenType;
import com.auberer.compilerdesignlectureproject.sema.SymbolTableEntry;
import lombok.Getter;
import lombok.Setter;

import java.util.Set;

@Getter
@Setter
public class ASTParamNode extends ASTNode{

@Getter
@Setter

private String name;
private SymbolTableEntry symbol;

public static Set<TokenType> getSelectionSet() {
return ASTTypeNode.getSelectionSet();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public boolean equals(FunctionDef def) {
return def.getName().equals(getName()) && isSameParams(def.getParams());
}

public boolean isSameParams(List<SuperType> otherParams) {
private boolean isSameParams(List<SuperType> otherParams) {
if (params.size() != otherParams.size()) {
return false;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
package com.auberer.compilerdesignlectureproject.codegen;

import com.auberer.compilerdesignlectureproject.sema.Type;
import lombok.Getter;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

@Getter
public class Function implements IDumpable {

private final String name;
private BasicBlock entryBlock;
private final List<Parameter> parameters;

public Function(String name) {
public Function(String name, List<Parameter> parameters) {
this.name = name;
this.parameters = parameters;
}

public void setEntryBlock(BasicBlock entryBlock) {
Expand All @@ -22,9 +27,26 @@ public void setEntryBlock(BasicBlock entryBlock) {

@Override
public void dumpIR(StringBuilder sb) {
sb.append("function ").append(name).append(": {\n");
sb.append("function ").append(name).
append("(");
String params = parameters.stream().map(parameter -> parameter.getType() + " " + parameter.getName()).collect(Collectors.joining(","));

sb.append(params);
sb.append(")");
sb.append(": {\n");
List<BasicBlock> dumpedBlocks = new ArrayList<>();
entryBlock.dumpIR(sb, dumpedBlocks);
sb.append("}\n\n");
}

@Getter
public static class Parameter{
private final String name;
private final Type type;

public Parameter(String name, Type type) {
this.name = name;
this.type = type;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
public class IRGenerator extends ASTVisitor<IRExprResult> {

// IR module, which represents the whole program

private final Module module;

@Getter
Expand All @@ -23,6 +24,7 @@ public IRGenerator(String moduleName) {
module = new Module(moduleName);
}


@Override
public IRExprResult visitForLoop(ASTForNode node) {
BasicBlock loopHeadBlock = new BasicBlock("loopHead");
Expand Down Expand Up @@ -270,7 +272,7 @@ private void switchToBlock(BasicBlock targetBlock) {
*/
private void finalizeFunction() {
assert currentBlock != null;
assert isBlockTerminated(currentBlock);
assert !isBlockTerminated(currentBlock);
currentBlock = null;
}

Expand Down Expand Up @@ -298,4 +300,59 @@ private boolean isBlockTerminated(BasicBlock block) {
return !block.getInstructions().isEmpty() && block.getInstructions().getLast().isTerminator();
}

@Override
public IRExprResult visitFctCall(ASTFctCallNode node) {
CallInstruction callInstruction = new CallInstruction(node, module.getFunction(node.getName(), node.getCallParams().getParamsAsLogicNodes().stream().map(ASTNode::getType).toList()), node.getCallParams());
pushToCurrentBlock(callInstruction);
return new IRExprResult(node.getValue(), node, null);
}

@Override
public IRExprResult visitFctDef(ASTFctDefNode node) {
BasicBlock fctDef = new BasicBlock("fctDef");

switchToBlock(fctDef);
if(node.hasParams()){
visitParamLst(node.getParams());
}


List<Function.Parameter> params = node.hasParams()?
node.getParams().getParamNodes().stream().map((paramNode) -> new Function.Parameter(paramNode.getName(), paramNode.getType())).toList()
:new ArrayList<>();

Function function = new Function(node.getName(), params);
function.setEntryBlock(fctDef);
module.addFunction(function);

visitLogic(node.getBody());

currentBlock = null;
return new IRExprResult(node.getValue(), node, null);
marcauberer marked this conversation as resolved.
Show resolved Hide resolved
}

Umbranecis marked this conversation as resolved.
Show resolved Hide resolved
@Override
public IRExprResult visitParamLst(ASTParamLstNode node){
for (ASTParamNode paramNode: node.getParamNodes()){
visitParam(paramNode);
}
return new IRExprResult(null, node, null);
}

@Override
public IRExprResult visitParam(ASTParamNode node){
AllocaInstruction allocaInstruction = new AllocaInstruction(node, node.getSymbol());
pushToCurrentBlock(allocaInstruction);
StoreInstruction storeParam = new StoreInstruction(node, node.getSymbol());
pushToCurrentBlock(storeParam);
return new IRExprResult(null, node, null);
}

@Override
public IRExprResult visitLogic(ASTLogicNode node) {
visitStmtLst(node.getBody());
ReturnInstruction returnInstruction = new ReturnInstruction(node);
pushToCurrentBlock(returnInstruction);
return new IRExprResult(null, node, null);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.auberer.compilerdesignlectureproject.codegen;

import com.auberer.compilerdesignlectureproject.sema.Type;
import lombok.Getter;

import java.util.ArrayList;
Expand All @@ -23,9 +24,9 @@ public void addFunction(Function function) {
functions.add(function);
}

public Function getFunction(String name) {
public Function getFunction(String name, List<Type> parameters) {
for (Function function : functions)
if (function.getName().equals(name))
if (function.getName().equals(name) && function.getParameters().stream().map(Function.Parameter::getType).toList().equals(parameters))
return function;
return null;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.auberer.compilerdesignlectureproject.codegen.instructions;

import com.auberer.compilerdesignlectureproject.ast.ASTCallParamsNode;
import com.auberer.compilerdesignlectureproject.ast.ASTNode;
import com.auberer.compilerdesignlectureproject.codegen.Function;
import com.auberer.compilerdesignlectureproject.interpreter.InterpreterEnvironment;
import lombok.Getter;

import java.util.ListIterator;
import java.util.stream.Collectors;

@Getter
public class CallInstruction extends Instruction {
private final Function function;
private final ASTCallParamsNode callParamsNode;

public CallInstruction(ASTNode node, Function function, ASTCallParamsNode callParamsNode) {
super(node);
this.function = function;
this.callParamsNode = callParamsNode;
}

@Override
public void run(InterpreterEnvironment env) {
// Save the current instruction iterator
ListIterator<Instruction> returnIterator = env.getInstructionIterator();
// Handle the function call in the interpreter environment
env.callFunction(returnIterator, function);
}

@Override
public void dumpIR(StringBuilder sb) {
// call <functionName>(<params>)
sb.append("call ").append(function.getName()).append("(");
String params = callParamsNode.getParamsAsLogicNodes().stream().map(astLogicalExprNode -> astLogicalExprNode.getValue().getName()).collect(Collectors.joining(","));
sb.append(params).append(")");
}

@Override
public void trace(StringBuilder sb) {
sb.append(node.getCodeLoc().toString()).append(": call ");
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,20 @@ public class ReturnInstruction extends Instruction {

public ReturnInstruction(ASTLogicNode logicNode) {
super(logicNode);
returnExpr = logicNode.logicalExpr();
returnExpr = logicNode.getReturnNode();
}

@Override
public void run(InterpreterEnvironment env) {
// ToDo(Team 6): Implement
// Return from the current function and set the instruction iterator to the instruction after the call
env.returnFromFunction();
}

@Override
public void dumpIR(StringBuilder sb) {
sb.append("return ");
sb.append("return");
if (returnExpr != null)
sb.append(returnExpr.getValue().getName());
sb.append(" ").append(returnExpr.getValue().getName());
}

@Override
Expand All @@ -34,4 +35,4 @@ public void trace(StringBuilder sb) {
public boolean isTerminator() {
return true;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,19 @@
import com.auberer.compilerdesignlectureproject.codegen.Function;
import com.auberer.compilerdesignlectureproject.codegen.Module;
import com.auberer.compilerdesignlectureproject.codegen.instructions.Instruction;
import lombok.Getter;
import lombok.Setter;

import java.util.ArrayList;
import java.util.ListIterator;
import java.util.Stack;

public class InterpreterEnvironment {

private final Module irModule;
private final boolean doTracing;
@Setter
@Getter
private ListIterator<Instruction> instructionIterator;

public InterpreterEnvironment(Module irModule, boolean doTracing) {
Expand All @@ -21,7 +25,7 @@ public InterpreterEnvironment(Module irModule, boolean doTracing) {

public void interpret() {
// Search for main function
Function mainFunction = irModule.getFunction("main");
Function mainFunction = irModule.getFunction("main", new ArrayList<>());
if (mainFunction == null)
throw new RuntimeException("No main function found in module " + irModule.getName());

Expand All @@ -36,4 +40,23 @@ public void interpret() {
}
}

}
private final Stack<ListIterator<Instruction>> callStack = new Stack<>();

public void callFunction(ListIterator<Instruction> returnIterator, Function function) {
Umbranecis marked this conversation as resolved.
Show resolved Hide resolved
// Push the current instruction iterator to the call stack
callStack.push(returnIterator);
// Set the instruction iterator to the first instruction of the called function
instructionIterator = function.getEntryBlock().getInstructions().listIterator();
}

public void returnFromFunction() {
// Check if there is a corresponding call for the return instruction
if (callStack.isEmpty()) {
throw new RuntimeException("Return instruction without corresponding call");
}
// Pop the call stack and set the instruction iterator to the instruction after the call
// This logic allows for nested function calls
instructionIterator = callStack.pop();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ public Void visitParam(ASTParamNode node) {
throw new SemaError(node, "Parameter name already in use");
} else {
currentScopes.peek().insertSymbol(node.getName(), node);
node.setSymbol(new SymbolTableEntry(currentScopes.peek(), node.getName(), node));
}
return null;
}
Expand Down
Loading
Loading