mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-06-03 07:29:37 +00:00
67 lines
3.1 KiB
Java
67 lines
3.1 KiB
Java
package dk.camelot64.kickc.passes;
|
|
|
|
import dk.camelot64.kickc.model.Program;
|
|
import dk.camelot64.kickc.model.StructVariableMemberUnwinding;
|
|
import dk.camelot64.kickc.model.symbols.Procedure;
|
|
import dk.camelot64.kickc.model.symbols.Scope;
|
|
import dk.camelot64.kickc.model.symbols.StructDefinition;
|
|
import dk.camelot64.kickc.model.symbols.Variable;
|
|
import dk.camelot64.kickc.model.types.SymbolTypeStruct;
|
|
|
|
/**
|
|
* Create unwindings for all unwinding struct variables. The unwinding is a conversion to one variable per member.
|
|
* The unwindings are stored in {@link Program#getStructVariableMemberUnwinding()}
|
|
*/
|
|
public class Pass1UnwindStructVariables extends Pass1Base {
|
|
|
|
public Pass1UnwindStructVariables(Program program) {
|
|
super(program);
|
|
}
|
|
|
|
@Override
|
|
public boolean step() {
|
|
if(getProgram().getStructVariableMemberUnwinding() == null) {
|
|
getProgram().setStructVariableMemberUnwinding(new StructVariableMemberUnwinding());
|
|
}
|
|
// Iterate through all scopes generating member-variables for each struct
|
|
return unwindStructVariables();
|
|
}
|
|
|
|
/**
|
|
* Iterate through all scopes generating member-variables for each struct variable
|
|
*
|
|
* @return Information about all unwound struct variables
|
|
*/
|
|
private boolean unwindStructVariables() {
|
|
boolean modified = false;
|
|
// Iterate through all scopes generating member-variables for each struct
|
|
for(Variable variable : getProgramScope().getAllVariables(true)) {
|
|
if(variable.isStructUnwind()) {
|
|
StructVariableMemberUnwinding structVariableMemberUnwinding = getProgram().getStructVariableMemberUnwinding();
|
|
if(structVariableMemberUnwinding.getVariableUnwinding(variable.getRef()) == null) {
|
|
// A non-volatile struct variable
|
|
Scope scope = variable.getScope();
|
|
if(!(scope instanceof StructDefinition)) {
|
|
// Not inside another struct
|
|
StructDefinition structDefinition = ((SymbolTypeStruct) variable.getType()).getStructDefinition(getProgram().getScope());
|
|
StructVariableMemberUnwinding.VariableUnwinding variableUnwinding = structVariableMemberUnwinding.createVariableUnwinding(variable.getRef());
|
|
for(Variable member : structDefinition.getAllVars(false)) {
|
|
boolean isParameter = scope instanceof Procedure && ((Procedure) scope).getParameters().contains(variable);
|
|
Variable memberVariable = Variable.createStructMemberUnwound(variable, member, isParameter);
|
|
scope.add(memberVariable);
|
|
variableUnwinding.setMemberUnwinding(member.getLocalName(), memberVariable.getRef());
|
|
if(getLog().isVerboseStructUnwind())
|
|
getLog().append("Created struct value member variable " + memberVariable.toString(getProgram()));
|
|
}
|
|
if(getLog().isVerboseStructUnwind())
|
|
getLog().append("Converted struct value to member variables " + variable.toString(getProgram()));
|
|
modified = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return modified;
|
|
}
|
|
|
|
}
|