package codeline; import processor.ControlFlow; import processor.Memory; import processor.StackFrame; import processor.Memory.Visibility; import processor.StackFrame.FrameType; /** * a line of code that defines introduces the definition of a new function * @author kolja */ public class FunctionDefinition extends CodeLine { private String[] params; /** * Erstellt eine neue Funktion * @param params Eine Liste mit Namen von Argumenten die automatisch beim Aufruf aus den Globalen Registern in das neue Stackframe geladen werden sollen */ public FunctionDefinition( String[] params ) { this.params = params; } @Override public ControlFlow runForward(Memory m) { if( !m.isDefined( "line_" + lineId + "_inside", Visibility.LOCAL ) ) { // Funktion wurde noch nicht aufgerufen m.addFrame( new StackFrame( FrameType.FUNCTION ) ); // F�ge neues Stackframe hinzu m.declare( "line_" + lineId + "_inside", true, Visibility.LOCAL ); int index = 1; Object[] olds = new Object[ params.length ]; for( String p : params ) { // Lade alle Parameter aus den Globalen Registern olds[ index - 1 ] = m.read( "param" + index, Visibility.GLOBAL ); m.declare( p, olds[ index - 1 ], Visibility.LOCAL ); // Speichere sie im Stack m.undeclare( "param" + index, Visibility.GLOBAL ); index++; } actions.push( (Memory mem) -> { // merkt sich die R�ckw�rtsaktion mem.removeFrame(); int i = 1; for( @SuppressWarnings("unused") String p : params ) { mem.declare( "param" + i, olds[ i - 1], Visibility.GLOBAL ); i++; } } ); return new ControlFlow( ControlFlow.STEP_INTO ); // springe in die Funktion } else { // Funktion ist bereits follst�ndig ausgef�hrt worden StackFrame frame = m.removeFrame(); actions.push( (Memory mem) -> { mem.addFrame( frame ); } ); return new ControlFlow( ControlFlow.STEP_OVER ); // return } } }