package de.fuberlin.projecta.analysis.ast;
import de.fuberlin.commons.parser.ISyntaxTree;
import de.fuberlin.projecta.analysis.SemanticException;
import de.fuberlin.projecta.analysis.SymbolTableHelper;
/**
* first child num
* second child Type
*
*/
public class ArrayCall extends Type {
public Id getArrayId(){
ISyntaxTree child = getChild(1);
while (child instanceof ArrayCall) {
child = child.getChild(1);
}
return (Id) child;
}
@Override
public void checkSemantics() {
ISyntaxTree child = this;
do {
child = child.getChild(1);
} while (!(child instanceof Id));
Id id = (Id) child;
Type type = SymbolTableHelper.lookup(id.getValue(), this).getType();
// we now have a the type node and the call node
// we have to look if there both have the same depth
// if so, the array call is complete
// if not, the array call is obviously incomplete and therefore the
// array call is semantically wrong!
ISyntaxTree self = this;
ISyntaxTree def = type;
do{
self = self.getChild(1);
def = def.getChild(1);
} while(!(self instanceof Id || !(def instanceof Array)));
// if both have the same depth self will be an instance of Id and def
// won't be an instance of array. Otherwise there must be something
// wrong woth the call
if (!(self instanceof Id)) {
if(!(def instanceof Array)){
throw new SemanticException("More dimensions in array call, than in definition!", this);
}
} else {
if (def instanceof Array){
throw new SemanticException("Only full array calls are allowed!", this);
}
}
}
@Override
public String toTypeString(){
ISyntaxTree child = this;
do{
child = child.getChild(1);
} while(!(child instanceof Id));
Id id = (Id) child;
Type type = SymbolTableHelper.lookup(id.getValue(), this).getType();
// we already know that the array call is calling a non array type
// because of semantic check
do{
type = (Type) type.getChild(1);
} while(!(type instanceof BasicType));
return type.toTypeString();
}
public Id getVarId() {
// collect all array references
ArrayCall tmp = this;
while(tmp.getChild(1) instanceof ArrayCall)
tmp = (ArrayCall)tmp.getChild(1);
return (Id)tmp.getChild(1);
}
@Override
public String genCode(){
//in LLVM class
return "";
}
}