package de.fuberlin.projecta.analysis.ast;
import de.fuberlin.commons.lexer.TokenType;
import de.fuberlin.commons.parser.ISyntaxTree;
import de.fuberlin.projecta.analysis.EntryType;
import de.fuberlin.projecta.analysis.SymbolTableHelper;
import de.fuberlin.projecta.codegen.LLVM;
/**
* This class represents one function call.
*
* It has one or two children. The first is id, which represents the functions
* name, the second is a node of type Args (if existing) and contains all
* arguments.
*/
public class FuncCall extends Expression {
public Id getId() {
return (Id) getChild(0);
}
/**
* For this to work properly all parameters MUST be loaded before (except
* records!)!
*/
@Override
public String genCode() {
String ret = "";
EntryType func = null;
if (getChildrenCount() > 1) {
// List<EntryType> parameters = new ArrayList<EntryType>();
// I simply can't reach the type node of the parameters !!! So
// there's no equal entryType !!!
// TODO: this is currently not working if multiple instances with
// this id exist in the symbolTable!!!
func = SymbolTableHelper.lookup(getId().getValue(), this);
} else {
func = SymbolTableHelper.lookup(getId().getValue(), this);
}
if (func != null) {
// at first, load all params!
if (getChildrenCount() > 1)
ret += LLVM.loadParams((Args) getChild(1));
ret += "call " + func.getType().genCode();
ret += " @" + func.getId() + "(";
boolean tmp = false;
if (getChildrenCount() > 1)
for (ISyntaxTree child : getChild(1).getChildren()) {
tmp = true;
Expression node = (Expression) child;
if (!(node.fromTypeStringToLLVMType().equals(""))) {
ret += node.fromTypeStringToLLVMType() + " %"
+ LLVM.getMem(node) + ", ";
} else if (node instanceof Id
&& SymbolTableHelper.lookup(((Id) node).getValue(),
node).getType() instanceof Record) {
ret += ((Id) node).getType().genCode() + "* %"
+ ((Id) node).getValue() + ", ";
} else if (node instanceof Id
&& SymbolTableHelper.lookup(((Id) node).getValue(),
node).getType() instanceof Array) {
ret += ((Id) node).getType().genCode() + "* %"
+ ((Id) node).getValue() + ", ";
}
}
if (tmp)
ret = ret.substring(0, ret.length() - 2);
ret += ")";
// implicit var incrementation
if (!searchUpAssign()
&& !func.getType().toTypeString().equals("void")) {
getHighestBlock().getNewVar();
}
}
return ret;
}
public boolean searchUpAssign() {
BinaryOp bOp = null;
if (getParent() instanceof Return)
return true;
if (getParent() != null) {
ISyntaxTree parent = getParent();
while (parent != null) {
if (parent instanceof BinaryOp) {
bOp = (BinaryOp) parent;
if (bOp.getOp() == TokenType.OP_ASSIGN)
return true;
} else if (parent instanceof Return) {
return true;
}
parent = parent.getParent();
}
}
return false;
}
@Override
public String toTypeString() {
return SymbolTableHelper.lookup(getId().getValue(), this).getType()
.toTypeString();
}
}