summaryrefslogtreecommitdiff
path: root/src/ast/nodes/FuncdefNode.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/ast/nodes/FuncdefNode.java')
-rw-r--r--src/ast/nodes/FuncdefNode.java37
1 files changed, 27 insertions, 10 deletions
diff --git a/src/ast/nodes/FuncdefNode.java b/src/ast/nodes/FuncdefNode.java
index 91231cc..c2671b2 100644
--- a/src/ast/nodes/FuncdefNode.java
+++ b/src/ast/nodes/FuncdefNode.java
@@ -8,6 +8,7 @@ import semanticanalysis.SemanticError;
import semanticanalysis.SymbolTable;
import ast.types.*;
import org.antlr.v4.runtime.tree.TerminalNode;
+import codegen.Label;
/**
* Node for the `funcdef` statement of the grammar.
@@ -17,38 +18,45 @@ public class FuncdefNode implements Node {
private final TerminalNode name;
private final Node paramlist;
private final Node block;
+ private final String funLabel;
public FuncdefNode(TerminalNode name, Node paramlist, Node block) {
this.name = name;
this.paramlist = paramlist;
this.block = block;
+ this.funLabel = Label.newFun("FUN");
}
@Override
- public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting) {
+ public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting, FunctionType ft) {
ArrayList<SemanticError> errors = new ArrayList<>();
- int paramNumber = ((ParamlistNode) paramlist).getParamNumber();
+ int paramNumber = 0;
+ if (paramlist != null) {
+ paramNumber = ((ParamlistNode) paramlist).getParamNumber();
+ }
Type returnType = this.block.typeCheck();
- FunctionType ft = new FunctionType(paramNumber, returnType);
+ FunctionType newFt = new FunctionType(paramNumber, returnType, funLabel);
- ST.insert(this.name.toString(), ft, _nesting, "");
+ String funName = this.name.toString();
+ ST.insert(funName, newFt, _nesting, "");
HashMap<String, STentry> HM = new HashMap<>();
ST.add(HM);
- ST.insert(this.name.toString(), ft, _nesting + 1, "");
+ ST.insert(funName, newFt, _nesting + 1, "");
+ ST.decreaseOffset();
if (paramlist != null) {
- errors.addAll(paramlist.checkSemantics(ST, _nesting + 1));
+ errors.addAll(paramlist.checkSemantics(ST, _nesting + 1, newFt));
}
- // TODO: think to the fucking offset
// Offset is increased for the possible return value
- ST.increaseoffset();
+ ST.increaseOffset();
- errors.addAll(block.checkSemantics(ST, _nesting + 1));
+ errors.addAll(block.checkSemantics(ST, _nesting + 1, newFt));
+ // return to the outer block
ST.remove();
return errors;
@@ -60,9 +68,18 @@ public class FuncdefNode implements Node {
return new VoidType();
}
- // TODO: code generation for funcdef
+ /**
+ * Taken from slide 56 of CodeGeneration.pdf
+ */
@Override
public String codeGeneration() {
+ String blockS = block.codeGeneration();
+ // The "return" which fix the RA is inside the block
+ String funS = funLabel + ":\n" +
+ "pushr RA\n" +
+ blockS;
+
+ Label.addFunDef(funS);
return "";
}