/**
* 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.Register;
import de.codesourcery.jasm16.ast.AST;
import de.codesourcery.jasm16.ast.ASTUtils;
import de.codesourcery.jasm16.ast.InstructionNode;
import de.codesourcery.jasm16.ast.NumberNode;
import de.codesourcery.jasm16.ast.OperandNode;
import de.codesourcery.jasm16.ast.OperatorNode;
import de.codesourcery.jasm16.ast.RegisterReferenceNode;
import de.codesourcery.jasm16.ast.StatementNode;
import de.codesourcery.jasm16.compiler.io.IResource;
import de.codesourcery.jasm16.compiler.phases.FoldExpressionsPhase;
import de.codesourcery.jasm16.parser.Parser;
import de.codesourcery.jasm16.parser.TestHelper;
import de.codesourcery.jasm16.utils.TextRegion;
public class FoldExpressionsPhaseTest extends TestHelper
{
public void testFoldSimpleExpression() throws IOException
{
final String source ="SET I, 4+5*3";
ICompilationUnit unit = CompilationUnit.createInstance("dummy",source);
Compiler comp = new Compiler();
comp.removeCompilerPhase( ICompilerPhase.PHASE_GENERATE_CODE );
comp.setObjectCodeWriterFactory( NOP_WRITER );
comp.compile( Collections.singletonList( unit ) , new CompilationListener() );
assertFalse( unit.getAST().hasErrors() );
ASTUtils.printAST( unit.getAST(), source );
assertFalse( unit.hasErrors() );
assertNotNull( unit.getAST() );
new FoldExpressionsPhase().execute( Collections.singletonList( unit ) , debugInfo,
symbolTable , NOP_WRITER , new CompilationListener(), RESOURCE_RESOLVER, OPTIONS, new MyResolver(unit) );
System.out.println("----------------------------");
ASTUtils.printAST( unit.getAST() , source );
}
public void testFoldSimpleRegisterExpressionWithWhitespace2() throws IOException
{
final String source =" SET I, [ 4 + 5 * 3+A ] ";
final ICompilationUnit unit = CompilationUnit.createInstance("dummy",source);
ICompilationContext compContext = createCompilationContext( unit );
AST ast = new Parser(this).parse( compContext );
unit.setAST( ast );
assertFalse( unit.getAST().hasErrors() );
assertFalse( unit.hasErrors() );
assertNotNull( unit.getAST() );
new FoldExpressionsPhase().execute( Collections.singletonList( unit ) , debugInfo,symbolTable , NOP_WRITER , new CompilationListener(), RESOURCE_RESOLVER, OPTIONS, new MyResolver(unit) );
ASTUtils.printAST( ast , source );
assertEquals(StatementNode.class , ast.child(0).getClass() );
assertEquals(InstructionNode.class , ast.child(0).child(0).getClass() );
assertEquals(OperandNode.class , ast.child(0).child(0).child(0).getClass() );
assertEquals(RegisterReferenceNode.class , ast.child(0).child(0).child(0).child(0).getClass() );
assertEquals(OperandNode.class , ast.child(0).child(0).child(1).getClass() );
OperandNode op = (OperandNode) ast.child(0).child(0).child(1);
assertTextRegion( new TextRegion(8,15), op.getTextRegion() , source );
assertEquals(OperatorNode.class , ast.child(0).child(0).child(1).child(0).getClass() );
OperatorNode expr = (OperatorNode) ast.child(0).child(0).child(1).child(0);
assertTextRegion( new TextRegion(9,13) , expr.getTextRegion() , source );
assertEquals(NumberNode.class , ast.child(0).child(0).child(1).child(0).child(0).getClass() );
final NumberNode numberNode = (NumberNode) ast.child(0).child(0).child(1).child(0).child(0);
assertEquals( 19L , numberNode.getValue() );
}
public void testFoldSimpleRegisterExpressionWithWhitespace() throws IOException
{
final String source =" SET I, [ A + 4 + 5 * 3 ] ";
final ICompilationUnit unit = CompilationUnit.createInstance("dummy",source);
ICompilationContext compContext = createCompilationContext( unit );
AST ast = new Parser(this).parse( compContext );
unit.setAST( ast );
assertFalse( unit.getAST().hasErrors() );
assertFalse( unit.hasErrors() );
assertNotNull( unit.getAST() );
ASTUtils.printAST( ast , source );
new FoldExpressionsPhase().execute( Collections.singletonList( unit ) , debugInfo,symbolTable , NOP_WRITER , new CompilationListener(), RESOURCE_RESOLVER, OPTIONS, new MyResolver(unit) );
assertEquals(StatementNode.class , ast.child(0).getClass() );
assertEquals(InstructionNode.class , ast.child(0).child(0).getClass() );
assertEquals(OperandNode.class , ast.child(0).child(0).child(0).getClass() );
assertEquals(RegisterReferenceNode.class , ast.child(0).child(0).child(0).child(0).getClass() );
assertEquals(OperandNode.class , ast.child(0).child(0).child(1).getClass() );
OperandNode op = (OperandNode) ast.child(0).child(0).child(1);
assertTextRegion( new TextRegion(8,17), op.getTextRegion() , source );
assertEquals(OperatorNode.class , ast.child(0).child(0).child(1).child(0).getClass() );
OperatorNode expr = (OperatorNode) ast.child(0).child(0).child(1).child(0);
assertTextRegion( new TextRegion(9,15) , expr.getTextRegion() , source );
assertEquals(NumberNode.class , ast.child(0).child(0).child(1).child(0).child(0).getClass() );
final NumberNode numberNode = (NumberNode) ast.child(0).child(0).child(1).child(0).child(0);
assertEquals( 19L , numberNode.getValue() );
}
public void testFoldSimpleRegisterExpression2() throws IOException
{
final String source ="SET I, [4+5*3+A]";
ICompilationUnit unit = CompilationUnit.createInstance("dummy",source);
ICompilationContext compContext = createCompilationContext( unit ); //
AST ast = new Parser(this).parse( compContext );
unit.setAST( ast );
assertFalse( unit.getAST().hasErrors() );
assertFalse( unit.hasErrors() );
assertNotNull( unit.getAST() );
new FoldExpressionsPhase().execute( Collections.singletonList( unit ) , debugInfo,symbolTable , NOP_WRITER , new CompilationListener(), RESOURCE_RESOLVER, OPTIONS, new MyResolver(unit) );
ASTUtils.printAST( ast );
assertEquals(StatementNode.class , ast.child(0).getClass() );
assertEquals(InstructionNode.class , ast.child(0).child(0).getClass() );
assertEquals(OperandNode.class , ast.child(0).child(0).child(0).getClass() );
assertEquals(RegisterReferenceNode.class , ast.child(0).child(0).child(0).child(0).getClass() );
assertEquals(OperandNode.class , ast.child(0).child(0).child(1).getClass() );
assertEquals(OperatorNode.class , ast.child(0).child(0).child(1).child(0).getClass() );
assertEquals(NumberNode.class , ast.child(0).child(0).child(1).child(0).child(0).getClass() );
assertEquals( 19L , ((NumberNode) ast.child(0).child(0).child(1).child(0).child(0)).getValue() );
assertEquals(RegisterReferenceNode.class , ast.child(0).child(0).child(1).child(0).child(1).getClass() );
assertEquals( Register.A , ((RegisterReferenceNode) ast.child(0).child(0).child(1).child(0).child(1) ).getRegister() );
}
public void testFoldSimpleRegisterExpression3() throws IOException
{
final String source ="SET I, [4+5*3+A+19]";
// 4 + 15 + a + 19 = 4+15+19+A = 19+19+a = 38
ICompilationUnit unit = CompilationUnit.createInstance("dummy",source);
ICompilationContext compContext = createCompilationContext( unit );
AST ast = new Parser(this).parse( compContext );
unit.setAST( ast );
assertFalse( unit.getAST().hasErrors() );
assertFalse( unit.hasErrors() );
assertNotNull( unit.getAST() );
new FoldExpressionsPhase().execute( Collections.singletonList( unit ) , debugInfo,symbolTable , NOP_WRITER , new CompilationListener(), RESOURCE_RESOLVER, OPTIONS, new MyResolver(unit) );
ASTUtils.printAST( ast );
assertEquals(StatementNode.class , ast.child(0).getClass() );
assertEquals(InstructionNode.class , ast.child(0).child(0).getClass() );
assertEquals(OperandNode.class , ast.child(0).child(0).child(0).getClass() );
assertEquals(RegisterReferenceNode.class , ast.child(0).child(0).child(0).child(0).getClass() );
assertEquals(OperandNode.class , ast.child(0).child(0).child(1).getClass() );
assertEquals(OperatorNode.class , ast.child(0).child(0).child(1).child(0).getClass() );
assertEquals(NumberNode.class , ast.child(0).child(0).child(1).child(0).child(0).getClass() );
assertEquals( 38L , ((NumberNode) ast.child(0).child(0).child(1).child(0).child(0)).getValue() );
assertEquals(RegisterReferenceNode.class , ast.child(0).child(0).child(1).child(0).child(1).getClass() );
assertEquals(Register.A ,((RegisterReferenceNode)ast.child(0).child(0).child(1).child(0).child(1) ).getRegister() );
}
}