/** * Copyright 2012 Tobias Gierke <tobias.gierke@code-sourcery.de> * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.codesourcery.jasm16.compiler; import java.io.IOException; import java.util.Collections; import de.codesourcery.jasm16.ast.ASTNode; import de.codesourcery.jasm16.ast.InstructionNode; import de.codesourcery.jasm16.ast.TermNode; import de.codesourcery.jasm16.compiler.ICompiler.CompilerOption; import de.codesourcery.jasm16.parser.Identifier; import de.codesourcery.jasm16.parser.TestHelper; import de.codesourcery.jasm16.utils.Misc; public class LabelExpressionsInliningTest extends TestHelper { public void testSimpleInlining() throws Exception { final String source="label: JSR label+1"; final Compiler compiler = new Compiler(); compiler.setCompilerOption( CompilerOption.DEBUG_MODE , true ); compiler.setObjectCodeWriterFactory( NOP_WRITER ); final ICompilationUnit unit = CompilationUnit.createInstance("string input" , source ); final ISymbolTable[] symbolTable = new ISymbolTable[1]; compiler.insertCompilerPhaseAfter( new CompilerPhase("pry-on-symbol-table") { @Override protected void run(ICompilationUnit unit,ICompilationContext context) throws IOException { symbolTable[0] = context.getSymbolTable(); } },ICompilerPhase.PHASE_GENERATE_CODE ); compiler.compile( Collections.singletonList( unit ) , new CompilationListener() ); Misc.printCompilationErrors( unit , source , true ); assertSourceCode( source , unit.getAST() ); assertFalse( unit.hasErrors() ); assertNotNull( symbolTable[0] ); final InstructionNode instruction = (InstructionNode) unit.getAST().child(0).child(1); final ASTNode valueNode = instruction.getOperand( 0 ).child( 0 ); assertTrue( valueNode.getClass().getName() , valueNode instanceof TermNode ); Long value = ((TermNode) valueNode).calculate( symbolTable[0] ); assertEquals( "0001" , Misc.toHexString( value.intValue() ) ); } public void testInliningWithForwardReference1() throws Exception { final String source=" JSR label+1 ; 0000\n" + " SET a,1 ; 0001\n" + " SET a,1 ; 0002\n" + " SET a,1 ; 0003\n" + " SET a,1 ; 0004\n" + " SET a,1 ; 0005\n" + " SET a,1 ; 0006\n" + " SET a,1 ; 0007\n" + " SET a,1 ; 0008\n" + " SET a,1 ; 0009\n" + " SET a,1 ; 000a\n" + " SET a,1 ; 000b\n" + " SET a,1 ; 000c\n" + " SET a,1 ; 000d\n" + " SET a,1 ; 000e\n" + " SET a,1 ; 000f\n" + " SET a,1 ; 0010\n" + " SET a,1 ; 0011\n" + " SET a,1 ; 0012\n" + " SET a,1 ; 0013\n" + " SET a,1 ; 0014\n" + " SET a,1 ; 0015\n" + " SET a,1 ; 0016\n" + " SET a,1 ; 0017\n" + " SET a,1 ; 0018\n" + " SET a,1 ; 0019\n" + " SET a,1 ; 001a\n" + " SET a,1 ; 001b\n" + " SET a,1 ; 001c\n" + " SET a,1 ; 001d\n" + " SET a,1 ; 001e\n" + "label: SET b,1 ; 001f"; final Compiler compiler = new Compiler(); compiler.setCompilerOption( CompilerOption.DEBUG_MODE , true ); compiler.setObjectCodeWriterFactory( NOP_WRITER ); final ICompilationUnit unit = CompilationUnit.createInstance("string input" , source ); final ISymbolTable[] symbolTable = new ISymbolTable[1]; compiler.insertCompilerPhaseAfter( new CompilerPhase("pry-on-symbol-table") { @Override protected void run(ICompilationUnit unit,ICompilationContext context) throws IOException { symbolTable[0] = context.getSymbolTable(); } },ICompilerPhase.PHASE_GENERATE_CODE ); compiler.compile( Collections.singletonList( unit ) , new CompilationListener() ); Misc.printCompilationErrors( unit , source , true ); assertSourceCode( source , unit.getAST() ); assertFalse( unit.hasErrors() ); assertNotNull( symbolTable[0] ); final InstructionNode instruction = (InstructionNode) unit.getAST().child(0).child(0); final ASTNode valueNode = instruction.getOperand( 0 ).child( 0 ); assertTrue( valueNode.getClass().getName() , valueNode instanceof TermNode ); Long value = ((TermNode) valueNode).calculate( symbolTable[0] ); final Label label = (Label) symbolTable[0].getSymbol(new Identifier("label") , null ); assertEquals( label.getAddress().getValue()+1 , value.intValue() ); } public void testInliningWithForwardReference2() throws Exception { final String source=" JSR label+1 ; 0000\n" + " SET a,1 ; 0001\n" + " SET a,1 ; 0002\n" + " SET a,1 ; 0003\n" + " SET a,1 ; 0004\n" + " SET a,1 ; 0005\n" + " SET a,1 ; 0006\n" + " SET a,1 ; 0007\n" + " SET a,1 ; 0008\n" + " SET a,1 ; 0009\n" + " SET a,1 ; 000a\n" + " SET a,1 ; 000b\n" + " SET a,1 ; 000c\n" + " SET a,1 ; 000d\n" + " SET a,1 ; 000e\n" + " SET a,1 ; 000f\n" + " SET a,1 ; 0010\n" + " SET a,1 ; 0011\n" + " SET a,1 ; 0012\n" + " SET a,1 ; 0013\n" + " SET a,1 ; 0014\n" + " SET a,1 ; 0015\n" + " SET a,1 ; 0016\n" + " SET a,1 ; 0017\n" + " SET a,1 ; 0018\n" + " SET a,1 ; 0019\n" + " SET a,1 ; 001a\n" + " SET a,1 ; 001b\n" + " SET a,1 ; 001c\n" + " SET a,1 ; 001d\n" + "label: SET b,1 ; 001e"; final Compiler compiler = new Compiler(); compiler.setCompilerOption( CompilerOption.DEBUG_MODE , true ); compiler.setObjectCodeWriterFactory( NOP_WRITER ); final ICompilationUnit unit = CompilationUnit.createInstance("string input" , source ); final ISymbolTable[] symbolTable = new ISymbolTable[1]; compiler.insertCompilerPhaseAfter( new CompilerPhase("pry-on-symbol-table") { @Override protected void run(ICompilationUnit unit,ICompilationContext context) throws IOException { symbolTable[0] = context.getSymbolTable(); } },ICompilerPhase.PHASE_GENERATE_CODE ); compiler.compile( Collections.singletonList( unit ) , new CompilationListener() ); Misc.printCompilationErrors( unit , source , true ); assertSourceCode( source , unit.getAST() ); assertFalse( unit.hasErrors() ); assertNotNull( symbolTable[0] ); final InstructionNode instruction = (InstructionNode) unit.getAST().child(0).child(0); final ASTNode valueNode = instruction.getOperand( 0 ).child( 0 ); assertTrue( valueNode.getClass().getName() , valueNode instanceof TermNode ); Long value = ((TermNode) valueNode).calculate( symbolTable[0] ); final Label label = (Label) symbolTable[0].getSymbol(new Identifier("label") , null ); assertEquals( label.getAddress().getValue()+1 , value.intValue() ); } }