1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-06-03 07:29:37 +00:00
kickc/src/main/java/dk/camelot64/kickc/passes/Pass1UnwindStructVariables.java
2023-04-06 22:46:28 +02:00

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;
}
}