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

Commit

Permalink
Group 6 - help needed once again :D (#72)
Browse files Browse the repository at this point in the history
Co-authored-by: Simon Hajek <[email protected]>
Co-authored-by: Nick Möhrmann <[email protected]>
Co-authored-by: nils bohland <[email protected]>
Co-authored-by: Marc Auberer <[email protected]>
  • Loading branch information
5 people authored Jun 14, 2024
1 parent 838adbf commit 6f533f4
Show file tree
Hide file tree
Showing 16 changed files with 314 additions and 22 deletions.
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(){
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);
}

@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) {
// 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

0 comments on commit 6f533f4

Please sign in to comment.