mirror of
https://gitlab.com/camelot/kickc.git
synced 2025-04-08 14:37:40 +00:00
Moved expression operators to separate package
This commit is contained in:
parent
73afb3d1be
commit
fd0b667b19
@ -1,6 +1,8 @@
|
||||
package dk.camelot64.kickc.fragment;
|
||||
|
||||
import dk.camelot64.kickc.model.*;
|
||||
import dk.camelot64.kickc.model.operators.Operator;
|
||||
import dk.camelot64.kickc.model.operators.Operators;
|
||||
|
||||
/** Formatting of numbers, constants, names and more for KickAssembler */
|
||||
public class AsmFormat {
|
||||
@ -60,56 +62,56 @@ public class AsmFormat {
|
||||
* @return The ASM string representing the constant value
|
||||
*/
|
||||
private static String getAsmConstantUnary(Program program, ScopeRef codeScope, Operator operator, ConstantValue operand, int outerPrecedence) {
|
||||
if(Operator.CAST_BYTE.equals(operator) || Operator.CAST_SBYTE.equals(operator)) {
|
||||
if(Operators.CAST_BYTE.equals(operator) || Operators.CAST_SBYTE.equals(operator)) {
|
||||
SymbolType operandType = SymbolTypeInference.inferType(program.getScope(), operand);
|
||||
if(SymbolType.isByte(operandType) || SymbolType.isSByte(operandType)) {
|
||||
// No cast needed
|
||||
return getAsmConstant(program, operand, outerPrecedence, codeScope);
|
||||
} else {
|
||||
return getAsmConstant(program, new ConstantBinary(new ConstantInteger((long)0xff), Operator.BOOL_AND, operand), outerPrecedence, codeScope);
|
||||
return getAsmConstant(program, new ConstantBinary(new ConstantInteger((long)0xff), Operators.BOOL_AND, operand), outerPrecedence, codeScope);
|
||||
}
|
||||
} else if(Operator.CAST_WORD.equals(operator) || Operator.CAST_SWORD.equals(operator) || Operator.CAST_PTRBY.equals(operator)) {
|
||||
} else if(Operators.CAST_WORD.equals(operator) || Operators.CAST_SWORD.equals(operator) || Operators.CAST_PTRBY.equals(operator)) {
|
||||
SymbolType operandType = SymbolTypeInference.inferType(program.getScope(), operand);
|
||||
if(SymbolType.isWord(operandType) || SymbolType.isSWord(operandType)) {
|
||||
// No cast needed
|
||||
return getAsmConstant(program, operand, outerPrecedence, codeScope);
|
||||
} else {
|
||||
return getAsmConstant(program, new ConstantBinary(new ConstantInteger((long)0xffff), Operator.BOOL_AND, operand), outerPrecedence, codeScope);
|
||||
return getAsmConstant(program, new ConstantBinary(new ConstantInteger((long)0xffff), Operators.BOOL_AND, operand), outerPrecedence, codeScope);
|
||||
}
|
||||
} else if(Operator.CAST_DWORD.equals(operator) || Operator.CAST_SDWORD.equals(operator)) {
|
||||
} else if(Operators.CAST_DWORD.equals(operator) || Operators.CAST_SDWORD.equals(operator)) {
|
||||
SymbolType operandType = SymbolTypeInference.inferType(program.getScope(), operand);
|
||||
if(SymbolType.isDWord(operandType) || SymbolType.isSDWord(operandType)) {
|
||||
// No cast needed
|
||||
return getAsmConstant(program, operand, outerPrecedence, codeScope);
|
||||
} else {
|
||||
return getAsmConstant(program, new ConstantBinary(new ConstantInteger((long)0xffffffff), Operator.BOOL_AND, operand), outerPrecedence, codeScope);
|
||||
return getAsmConstant(program, new ConstantBinary(new ConstantInteger((long)0xffffffff), Operators.BOOL_AND, operand), outerPrecedence, codeScope);
|
||||
}
|
||||
} else if(Operator.LOWBYTE.equals(operator)) {
|
||||
} else if(Operators.LOWBYTE.equals(operator)) {
|
||||
SymbolType operandType = SymbolTypeInference.inferType(program.getScope(), operand);
|
||||
if(SymbolType.isByte(operandType) || SymbolType.isSByte(operandType)) {
|
||||
return getAsmConstant(program, operand, outerPrecedence, codeScope);
|
||||
} else if(SymbolType.isWord(operandType) || SymbolType.isSWord(operandType) || operandType instanceof SymbolTypePointer) {
|
||||
return "<" + getAsmConstant(program, operand, outerPrecedence, codeScope);
|
||||
} else if(SymbolType.isDWord(operandType) || SymbolType.isSDWord(operandType)) {
|
||||
return getAsmConstant(program, new ConstantBinary(operand, Operator.BOOL_AND, new ConstantInteger((long)0xffff)), outerPrecedence, codeScope);
|
||||
return getAsmConstant(program, new ConstantBinary(operand, Operators.BOOL_AND, new ConstantInteger((long)0xffff)), outerPrecedence, codeScope);
|
||||
} else {
|
||||
throw new CompileError("Unhandled type "+operand);
|
||||
}
|
||||
} else if(Operator.HIBYTE.equals(operator)) {
|
||||
} else if(Operators.HIBYTE.equals(operator)) {
|
||||
SymbolType operandType = SymbolTypeInference.inferType(program.getScope(), operand);
|
||||
if(SymbolType.isByte(operandType) || SymbolType.isSByte(operandType)) {
|
||||
return getAsmConstant(program, operand, outerPrecedence, codeScope);
|
||||
} else if(SymbolType.isWord(operandType) || SymbolType.isSWord(operandType) || operandType instanceof SymbolTypePointer) {
|
||||
return ">" + getAsmConstant(program, operand, outerPrecedence, codeScope);
|
||||
} else if(SymbolType.isDWord(operandType) || SymbolType.isSDWord(operandType)) {
|
||||
return getAsmConstant(program, new ConstantBinary(operand, Operator.SHIFT_RIGHT, new ConstantInteger((long)16)), outerPrecedence, codeScope);
|
||||
return getAsmConstant(program, new ConstantBinary(operand, Operators.SHIFT_RIGHT, new ConstantInteger((long)16)), outerPrecedence, codeScope);
|
||||
} else {
|
||||
throw new CompileError("Unhandled type "+operand);
|
||||
}
|
||||
} else if(Operator.INCREMENT.equals(operator)) {
|
||||
return getAsmConstant(program, new ConstantBinary(operand, Operator.PLUS, new ConstantInteger((long)1)), outerPrecedence, codeScope);
|
||||
} else if(Operator.DECREMENT.equals(operator)) {
|
||||
return getAsmConstant(program, new ConstantBinary(operand, Operator.MINUS, new ConstantInteger((long)1)), outerPrecedence, codeScope);
|
||||
} else if(Operators.INCREMENT.equals(operator)) {
|
||||
return getAsmConstant(program, new ConstantBinary(operand, Operators.PLUS, new ConstantInteger((long)1)), outerPrecedence, codeScope);
|
||||
} else if(Operators.DECREMENT.equals(operator)) {
|
||||
return getAsmConstant(program, new ConstantBinary(operand, Operators.MINUS, new ConstantInteger((long)1)), outerPrecedence, codeScope);
|
||||
} else {
|
||||
return operator.getOperator() +
|
||||
getAsmConstant(program, operand, operator.getPrecedence(), codeScope);
|
||||
|
@ -1,6 +1,7 @@
|
||||
package dk.camelot64.kickc.fragment;
|
||||
|
||||
import dk.camelot64.kickc.model.*;
|
||||
import dk.camelot64.kickc.model.operators.Operator;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
@ -1,5 +1,7 @@
|
||||
package dk.camelot64.kickc.model;
|
||||
|
||||
import dk.camelot64.kickc.model.operators.Operator;
|
||||
|
||||
/** A constant defined by a binary operator applied to two constants */
|
||||
public class ConstantBinary implements ConstantValue {
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
package dk.camelot64.kickc.model;
|
||||
|
||||
import dk.camelot64.kickc.model.operators.Operator;
|
||||
|
||||
/** A constant defined by a unary operator appied to another constant */
|
||||
public class ConstantUnary implements ConstantValue {
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
package dk.camelot64.kickc.model;
|
||||
|
||||
import dk.camelot64.kickc.model.operators.Operator;
|
||||
import dk.camelot64.kickc.model.operators.Operators;
|
||||
|
||||
/** Can calculate the exact value for constants (used for type inference). */
|
||||
public class ConstantValueCalculator {
|
||||
|
||||
@ -34,17 +37,17 @@ public class ConstantValueCalculator {
|
||||
|
||||
|
||||
public static ConstantValue calcValue(ProgramScope programScope, Operator operator, ConstantValue value) {
|
||||
if(operator.equals(Operator.NEG)) {
|
||||
if(operator.equals(Operators.NEG)) {
|
||||
return neg(calcValue(programScope, value));
|
||||
} else if(operator.equals(Operator.POS)) {
|
||||
} else if(operator.equals(Operators.POS)) {
|
||||
return pos(calcValue(programScope, value));
|
||||
} else if(operator.equals(Operator.CAST_WORD)) {
|
||||
} else if(operator.equals(Operators.CAST_WORD)) {
|
||||
return castWord(calcValue(programScope, value));
|
||||
} else if(operator.equals(Operator.CAST_SWORD)) {
|
||||
} else if(operator.equals(Operators.CAST_SWORD)) {
|
||||
return castSWord(calcValue(programScope, value));
|
||||
} else if(operator.equals(Operator.CAST_BYTE)) {
|
||||
} else if(operator.equals(Operators.CAST_BYTE)) {
|
||||
return castByte(calcValue(programScope, value));
|
||||
} else if(operator.equals(Operator.CAST_SBYTE)) {
|
||||
} else if(operator.equals(Operators.CAST_SBYTE)) {
|
||||
return castSByte(calcValue(programScope, value));
|
||||
}
|
||||
return null;
|
||||
@ -84,13 +87,13 @@ public class ConstantValueCalculator {
|
||||
|
||||
|
||||
public static ConstantValue calcValue(ProgramScope programScope, ConstantValue value1, Operator operator, ConstantValue value2) {
|
||||
if(operator.equals(Operator.MULTIPLY)) {
|
||||
if(operator.equals(Operators.MULTIPLY)) {
|
||||
return multiply(calcValue(programScope, value1), calcValue(programScope, value2));
|
||||
} else if(operator.equals(Operator.PLUS)) {
|
||||
} else if(operator.equals(Operators.PLUS)) {
|
||||
return plus(calcValue(programScope, value1), calcValue(programScope, value2));
|
||||
} else if(operator.equals(Operator.MINUS)) {
|
||||
} else if(operator.equals(Operators.MINUS)) {
|
||||
return minus(calcValue(programScope, value1), calcValue(programScope, value2));
|
||||
} else if(operator.equals(Operator.DIVIDE)) {
|
||||
} else if(operator.equals(Operators.DIVIDE)) {
|
||||
return div(calcValue(programScope, value1), calcValue(programScope, value2));
|
||||
}
|
||||
return null;
|
||||
|
@ -1,5 +1,7 @@
|
||||
package dk.camelot64.kickc.model;
|
||||
|
||||
import dk.camelot64.kickc.model.operators.Operator;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
package dk.camelot64.kickc.model;
|
||||
|
||||
import dk.camelot64.kickc.model.operators.Operator;
|
||||
|
||||
/**
|
||||
* Single Static Assignment Form Statement.
|
||||
* Intermediate form used for compiler optimization.
|
||||
|
@ -1,5 +1,7 @@
|
||||
package dk.camelot64.kickc.model;
|
||||
|
||||
import dk.camelot64.kickc.model.operators.Operator;
|
||||
|
||||
/**
|
||||
* Intermediate Compiler Form Statement with a conditional jump.
|
||||
* Intermediate form used for compiler optimization.
|
||||
|
@ -1,5 +1,8 @@
|
||||
package dk.camelot64.kickc.model;
|
||||
|
||||
import dk.camelot64.kickc.model.operators.Operator;
|
||||
import dk.camelot64.kickc.model.operators.Operators;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
@ -22,21 +25,21 @@ public class SymbolTypeInference {
|
||||
if(operator == null) {
|
||||
return inferType(programScope, rValue);
|
||||
}
|
||||
if(operator.equals(Operator.CAST_BYTE)) {
|
||||
if(operator.equals(Operators.CAST_BYTE)) {
|
||||
return SymbolType.BYTE;
|
||||
} else if(operator.equals(Operator.CAST_SBYTE)) {
|
||||
} else if(operator.equals(Operators.CAST_SBYTE)) {
|
||||
return SymbolType.SBYTE;
|
||||
} else if(operator.equals(Operator.CAST_WORD)) {
|
||||
} else if(operator.equals(Operators.CAST_WORD)) {
|
||||
return SymbolType.WORD;
|
||||
} else if(operator.equals(Operator.CAST_SWORD)) {
|
||||
} else if(operator.equals(Operators.CAST_SWORD)) {
|
||||
return SymbolType.SWORD;
|
||||
} else if(operator.equals(Operator.CAST_DWORD)) {
|
||||
} else if(operator.equals(Operators.CAST_DWORD)) {
|
||||
return SymbolType.DWORD;
|
||||
} else if(operator.equals(Operator.CAST_SDWORD)) {
|
||||
} else if(operator.equals(Operators.CAST_SDWORD)) {
|
||||
return SymbolType.SDWORD;
|
||||
} else if(operator.equals(Operator.CAST_PTRBY)) {
|
||||
} else if(operator.equals(Operators.CAST_PTRBY)) {
|
||||
return new SymbolTypePointer(SymbolType.BYTE);
|
||||
} else if(operator.equals(Operator.ADDRESS_OF)) {
|
||||
} else if(operator.equals(Operators.ADDRESS_OF)) {
|
||||
SymbolType valueType = inferType(programScope, rValue);
|
||||
return new SymbolTypePointer(valueType);
|
||||
}
|
||||
@ -71,31 +74,31 @@ public class SymbolTypeInference {
|
||||
if(operator == null) {
|
||||
return subType;
|
||||
}
|
||||
if(Operator.DEREF.equals(operator)) {
|
||||
if(Operators.DEREF.equals(operator)) {
|
||||
if(subType instanceof SymbolTypePointer) {
|
||||
return ((SymbolTypePointer) subType).getElementType();
|
||||
} else {
|
||||
throw new RuntimeException("Type error: Dereferencing a non-pointer " + subType);
|
||||
}
|
||||
} else if(Operator.LOWBYTE.equals(operator)) {
|
||||
} else if(Operators.LOWBYTE.equals(operator)) {
|
||||
if(subType instanceof SymbolTypePointer || SymbolType.isWord(subType) || SymbolType.isSWord(subType)) {
|
||||
return SymbolType.BYTE;
|
||||
} else if(SymbolType.isDWord(subType) || SymbolType.isSDWord(subType)) {
|
||||
return SymbolType.WORD;
|
||||
}
|
||||
} else if(Operator.HIBYTE.equals(operator)) {
|
||||
} else if(Operators.HIBYTE.equals(operator)) {
|
||||
if(subType instanceof SymbolTypePointer || SymbolType.isWord(subType) || SymbolType.isSWord(subType)) {
|
||||
return SymbolType.BYTE;
|
||||
} else if(SymbolType.isDWord(subType) || SymbolType.isSDWord(subType)) {
|
||||
return SymbolType.WORD;
|
||||
}
|
||||
} else if(Operator.CAST_BYTE.equals(operator)) {
|
||||
} else if(Operators.CAST_BYTE.equals(operator)) {
|
||||
return SymbolType.BYTE;
|
||||
} else if(Operator.CAST_SBYTE.equals(operator)) {
|
||||
} else if(Operators.CAST_SBYTE.equals(operator)) {
|
||||
return SymbolType.SBYTE;
|
||||
} else if(Operator.CAST_WORD.equals(operator)) {
|
||||
} else if(Operators.CAST_WORD.equals(operator)) {
|
||||
return SymbolType.WORD;
|
||||
} else if(Operator.CAST_SWORD.equals(operator)) {
|
||||
} else if(Operators.CAST_SWORD.equals(operator)) {
|
||||
return SymbolType.SWORD;
|
||||
} else {
|
||||
return subType;
|
||||
@ -105,19 +108,19 @@ public class SymbolTypeInference {
|
||||
|
||||
public static SymbolType inferType(SymbolType type1, Operator operator, SymbolType type2) {
|
||||
|
||||
if(Operator.PLUS.equals(operator)) {
|
||||
if(Operators.PLUS.equals(operator)) {
|
||||
return inferPlus(type1, type2);
|
||||
} else if(Operator.MINUS.equals(operator)) {
|
||||
} else if(Operators.MINUS.equals(operator)) {
|
||||
return inferMinus(type1, type2);
|
||||
} else if(Operator.BOOL_AND.equals(operator)) {
|
||||
} else if(Operators.BOOL_AND.equals(operator)) {
|
||||
return inferBoolAnd(type1, type2);
|
||||
} else if(Operator.SET_HIBYTE.equals(operator)) {
|
||||
} else if(Operators.SET_HIBYTE.equals(operator)) {
|
||||
return type1;
|
||||
} else if(Operator.SET_LOWBYTE.equals(operator)) {
|
||||
} else if(Operators.SET_LOWBYTE.equals(operator)) {
|
||||
return type1;
|
||||
} else if(Operator.WORD.equals(operator)) {
|
||||
} else if(Operators.WORD.equals(operator)) {
|
||||
return SymbolType.WORD;
|
||||
} else if(Operator.DWORD.equals(operator)) {
|
||||
} else if(Operators.DWORD.equals(operator)) {
|
||||
return SymbolType.DWORD;
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,71 @@
|
||||
package dk.camelot64.kickc.model.operators;
|
||||
|
||||
/**
|
||||
* An Operator. The operation performed on the rvalues in a Statement.
|
||||
*/
|
||||
public class Operator {
|
||||
|
||||
private String operator;
|
||||
private int precedence;
|
||||
private Type type;
|
||||
private String asmOperator;
|
||||
|
||||
public Operator(String operator, String asmOperator, Type type, int precedence) {
|
||||
this.operator = operator;
|
||||
this.precedence = precedence;
|
||||
this.type = type;
|
||||
this.asmOperator = asmOperator;
|
||||
}
|
||||
|
||||
// Constant Evaluation / Calculation (ParseTreeConstantEvaluator / Pass2ConstantIdentification / ConstantValueCalculator)
|
||||
|
||||
// Type Inference (SymbolTypeInference)
|
||||
|
||||
// Constant ASM formatting (AsmFormat)
|
||||
|
||||
|
||||
|
||||
public String getOperator() {
|
||||
return operator;
|
||||
}
|
||||
|
||||
public int getPrecedence() {
|
||||
return precedence;
|
||||
}
|
||||
|
||||
public enum Type {
|
||||
UNARY, BINARY
|
||||
}
|
||||
|
||||
public Type getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public String getAsmOperator() {
|
||||
return asmOperator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return operator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if(this == o) return true;
|
||||
if(o == null || getClass() != o.getClass()) return false;
|
||||
Operator operator1 = (Operator) o;
|
||||
if(precedence != operator1.precedence) return false;
|
||||
if(!operator.equals(operator1.operator)) return false;
|
||||
return type == operator1.type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = operator.hashCode();
|
||||
result = 31 * result + precedence;
|
||||
result = 31 * result + type.hashCode();
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
@ -1,7 +1,5 @@
|
||||
package dk.camelot64.kickc.model.operators;
|
||||
|
||||
import dk.camelot64.kickc.model.OperatorUnary;
|
||||
|
||||
/** Unary Address-of Operator (&p) */
|
||||
public class OperatorAddressOf extends OperatorUnary {
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
package dk.camelot64.kickc.model;
|
||||
package dk.camelot64.kickc.model.operators;
|
||||
|
||||
/** A binary expression operator */
|
||||
public class OperatorBinary extends Operator {
|
@ -1,7 +1,5 @@
|
||||
package dk.camelot64.kickc.model.operators;
|
||||
|
||||
import dk.camelot64.kickc.model.OperatorBinary;
|
||||
|
||||
/** Binary boolean and Operator ( x & y ) */
|
||||
public class OperatorBoolAnd extends OperatorBinary {
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
package dk.camelot64.kickc.model.operators;
|
||||
|
||||
import dk.camelot64.kickc.model.OperatorUnary;
|
||||
|
||||
/** Unary Boolean Not operator (~b) */
|
||||
public class OperatorBoolNot extends OperatorUnary {
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
package dk.camelot64.kickc.model.operators;
|
||||
|
||||
import dk.camelot64.kickc.model.OperatorBinary;
|
||||
|
||||
/** Binary boolean or Operator ( x | y ) */
|
||||
public class OperatorBoolOr extends OperatorBinary {
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
package dk.camelot64.kickc.model.operators;
|
||||
|
||||
import dk.camelot64.kickc.model.OperatorBinary;
|
||||
|
||||
/** Binary boolean exclusive or Operator ( x ^ y ) */
|
||||
public class OperatorBoolXor extends OperatorBinary {
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
package dk.camelot64.kickc.model.operators;
|
||||
|
||||
import dk.camelot64.kickc.model.OperatorUnary;
|
||||
|
||||
/** Unary Cast to byte operator ( (byte) x ) */
|
||||
public class OperatorCastByte extends OperatorUnary {
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
package dk.camelot64.kickc.model.operators;
|
||||
|
||||
import dk.camelot64.kickc.model.OperatorUnary;
|
||||
|
||||
/** Unary Cast to double word operator ( (dword) x ) */
|
||||
public class OperatorCastDWord extends OperatorUnary {
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
package dk.camelot64.kickc.model.operators;
|
||||
|
||||
import dk.camelot64.kickc.model.OperatorUnary;
|
||||
|
||||
/** Unary Cast to byte pointer operator ( (byte*) x ) */
|
||||
public class OperatorCastPtrByte extends OperatorUnary {
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
package dk.camelot64.kickc.model.operators;
|
||||
|
||||
import dk.camelot64.kickc.model.OperatorUnary;
|
||||
|
||||
/** Unary Cast to signed byte operator ( (signed byte) x ) */
|
||||
public class OperatorCastSByte extends OperatorUnary {
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
package dk.camelot64.kickc.model.operators;
|
||||
|
||||
import dk.camelot64.kickc.model.OperatorUnary;
|
||||
|
||||
/** Unary Cast to signed double word operator ( (signed dword) x ) */
|
||||
public class OperatorCastSDWord extends OperatorUnary {
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
package dk.camelot64.kickc.model.operators;
|
||||
|
||||
import dk.camelot64.kickc.model.OperatorUnary;
|
||||
|
||||
/** Unary Cast to signed word operator ( (signed word) x ) */
|
||||
public class OperatorCastSWord extends OperatorUnary {
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
package dk.camelot64.kickc.model.operators;
|
||||
|
||||
import dk.camelot64.kickc.model.OperatorUnary;
|
||||
|
||||
/** Unary Cast to word operator ( (word) x ) */
|
||||
public class OperatorCastWord extends OperatorUnary {
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
package dk.camelot64.kickc.model.operators;
|
||||
|
||||
import dk.camelot64.kickc.model.OperatorBinary;
|
||||
|
||||
/** Binary DWord Constructor operator (w dw= w) */
|
||||
public class OperatorDWord extends OperatorBinary {
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
package dk.camelot64.kickc.model.operators;
|
||||
|
||||
import dk.camelot64.kickc.model.OperatorUnary;
|
||||
|
||||
/** Unary Decrement operator (--) */
|
||||
public class OperatorDecrement extends OperatorUnary {
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
package dk.camelot64.kickc.model.operators;
|
||||
|
||||
import dk.camelot64.kickc.model.OperatorUnary;
|
||||
|
||||
/** Unary Pointer Dereference Operator (*p) */
|
||||
public class OperatorDeref extends OperatorUnary {
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
package dk.camelot64.kickc.model.operators;
|
||||
|
||||
import dk.camelot64.kickc.model.OperatorBinary;
|
||||
|
||||
/** Binary Pointer Dereference with an index Operator ( p[i] / *(p+i) ) */
|
||||
public class OperatorDerefIdx extends OperatorBinary {
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
package dk.camelot64.kickc.model.operators;
|
||||
|
||||
import dk.camelot64.kickc.model.OperatorBinary;
|
||||
|
||||
/** Binary division Operator ( x / y ) */
|
||||
public class OperatorDivide extends OperatorBinary {
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
package dk.camelot64.kickc.model.operators;
|
||||
|
||||
import dk.camelot64.kickc.model.OperatorBinary;
|
||||
|
||||
/** Binary equal Operator ( x == y ) */
|
||||
public class OperatorEqual extends OperatorBinary {
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
package dk.camelot64.kickc.model.operators;
|
||||
|
||||
import dk.camelot64.kickc.model.OperatorUnary;
|
||||
|
||||
/** Unary get high operator (>b) */
|
||||
public class OperatorGetHigh extends OperatorUnary {
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
package dk.camelot64.kickc.model.operators;
|
||||
|
||||
import dk.camelot64.kickc.model.OperatorUnary;
|
||||
|
||||
/** Unary get low operator (<b) */
|
||||
public class OperatorGetLow extends OperatorUnary {
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
package dk.camelot64.kickc.model.operators;
|
||||
|
||||
import dk.camelot64.kickc.model.OperatorBinary;
|
||||
|
||||
/** Binary greater-than Operator ( x > y ) */
|
||||
public class OperatorGreaterThan extends OperatorBinary {
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
package dk.camelot64.kickc.model.operators;
|
||||
|
||||
import dk.camelot64.kickc.model.OperatorBinary;
|
||||
|
||||
/** Binary greater-than-equal Operator ( x >= y ) */
|
||||
public class OperatorGreaterThanEqual extends OperatorBinary {
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
package dk.camelot64.kickc.model.operators;
|
||||
|
||||
import dk.camelot64.kickc.model.OperatorUnary;
|
||||
|
||||
/** Unary Increment operator (++) */
|
||||
public class OperatorIncrement extends OperatorUnary {
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
package dk.camelot64.kickc.model.operators;
|
||||
|
||||
import dk.camelot64.kickc.model.OperatorBinary;
|
||||
|
||||
/** Binary less-than Operator ( x < y ) */
|
||||
public class OperatorLessThan extends OperatorBinary {
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
package dk.camelot64.kickc.model.operators;
|
||||
|
||||
import dk.camelot64.kickc.model.OperatorBinary;
|
||||
|
||||
/** Binary less-than-equal Operator ( x <= y ) */
|
||||
public class OperatorLessThanEqual extends OperatorBinary {
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
package dk.camelot64.kickc.model.operators;
|
||||
|
||||
import dk.camelot64.kickc.model.OperatorBinary;
|
||||
|
||||
/** Binary logic and Operator ( x && y ) */
|
||||
public class OperatorLogicAnd extends OperatorBinary {
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
package dk.camelot64.kickc.model.operators;
|
||||
|
||||
import dk.camelot64.kickc.model.OperatorUnary;
|
||||
|
||||
/** Unary Logic Not operator (!b) */
|
||||
public class OperatorLogicNot extends OperatorUnary {
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
package dk.camelot64.kickc.model.operators;
|
||||
|
||||
import dk.camelot64.kickc.model.OperatorBinary;
|
||||
|
||||
/** Binary logic or Operator ( x || y ) */
|
||||
public class OperatorLogicOr extends OperatorBinary {
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
package dk.camelot64.kickc.model.operators;
|
||||
|
||||
import dk.camelot64.kickc.model.OperatorBinary;
|
||||
|
||||
/** Binary minus Operator ( x - y ) */
|
||||
public class OperatorMinus extends OperatorBinary {
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
package dk.camelot64.kickc.model.operators;
|
||||
|
||||
import dk.camelot64.kickc.model.OperatorBinary;
|
||||
|
||||
/** Binary multiply Operator ( x * y ) */
|
||||
public class OperatorMultiply extends OperatorBinary {
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
package dk.camelot64.kickc.model.operators;
|
||||
|
||||
import dk.camelot64.kickc.model.OperatorUnary;
|
||||
|
||||
/** Unary Negative operator (-) */
|
||||
public class OperatorNeg extends OperatorUnary {
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
package dk.camelot64.kickc.model.operators;
|
||||
|
||||
import dk.camelot64.kickc.model.OperatorBinary;
|
||||
|
||||
/** Binary not-equal Operator ( x != y ) */
|
||||
public class OperatorNotEqual extends OperatorBinary {
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
package dk.camelot64.kickc.model.operators;
|
||||
|
||||
import dk.camelot64.kickc.model.OperatorBinary;
|
||||
|
||||
/** Binary plus Operator ( x + y ) */
|
||||
public class OperatorPlus extends OperatorBinary {
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
package dk.camelot64.kickc.model.operators;
|
||||
|
||||
import dk.camelot64.kickc.model.OperatorUnary;
|
||||
|
||||
/** Unary Positive operator (+) */
|
||||
public class OperatorPos extends OperatorUnary {
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
package dk.camelot64.kickc.model.operators;
|
||||
|
||||
import dk.camelot64.kickc.model.OperatorBinary;
|
||||
|
||||
/** Binary SetHighByte Operator ( w hi= b ) */
|
||||
public class OperatorSetHigh extends OperatorBinary {
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
package dk.camelot64.kickc.model.operators;
|
||||
|
||||
import dk.camelot64.kickc.model.OperatorBinary;
|
||||
|
||||
/** Binary SetLowByte Operator ( w lo= b ) */
|
||||
public class OperatorSetLow extends OperatorBinary {
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
package dk.camelot64.kickc.model.operators;
|
||||
|
||||
import dk.camelot64.kickc.model.OperatorBinary;
|
||||
|
||||
/** Binary shift left Operator ( x << n ) */
|
||||
public class OperatorShiftLeft extends OperatorBinary {
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
package dk.camelot64.kickc.model.operators;
|
||||
|
||||
import dk.camelot64.kickc.model.OperatorBinary;
|
||||
|
||||
/** Binary shift right Operator ( x >> n ) */
|
||||
public class OperatorShiftRight extends OperatorBinary {
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
package dk.camelot64.kickc.model;
|
||||
package dk.camelot64.kickc.model.operators;
|
||||
|
||||
/** A unary expression operator */
|
||||
public class OperatorUnary extends Operator {
|
@ -1,7 +1,5 @@
|
||||
package dk.camelot64.kickc.model.operators;
|
||||
|
||||
import dk.camelot64.kickc.model.OperatorBinary;
|
||||
|
||||
/** Binary Word Constructor operator (b w= b) */
|
||||
public class OperatorWord extends OperatorBinary {
|
||||
|
||||
|
@ -1,11 +1,10 @@
|
||||
package dk.camelot64.kickc.model;
|
||||
package dk.camelot64.kickc.model.operators;
|
||||
|
||||
import dk.camelot64.kickc.model.operators.*;
|
||||
import dk.camelot64.kickc.model.SymbolType;
|
||||
import dk.camelot64.kickc.model.SymbolTypePointer;
|
||||
|
||||
/**
|
||||
* An Operator. The operation performed on the rvalues in a Statement.
|
||||
*/
|
||||
public class Operator {
|
||||
/** Constainer for all the expression operators */
|
||||
public class Operators {
|
||||
|
||||
public static final Operator INCREMENT = new OperatorIncrement(1);
|
||||
public static final Operator DECREMENT = new OperatorDecrement(1);
|
||||
@ -47,19 +46,6 @@ public class Operator {
|
||||
public static final Operator LOGIC_AND = new OperatorLogicAnd(12);
|
||||
public static final Operator LOGIC_OR = new OperatorLogicOr(13);
|
||||
|
||||
|
||||
private String operator;
|
||||
private int precedence;
|
||||
private Type type;
|
||||
private String asmOperator;
|
||||
|
||||
public Operator(String operator, String asmOperator, Type type, int precedence) {
|
||||
this.operator = operator;
|
||||
this.precedence = precedence;
|
||||
this.type = type;
|
||||
this.asmOperator = asmOperator;
|
||||
}
|
||||
|
||||
public static Operator getBinary(String op) {
|
||||
switch(op) {
|
||||
case "+":
|
||||
@ -154,48 +140,4 @@ public class Operator {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public String getOperator() {
|
||||
return operator;
|
||||
}
|
||||
|
||||
public int getPrecedence() {
|
||||
return precedence;
|
||||
}
|
||||
|
||||
public Type getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public String getAsmOperator() {
|
||||
return asmOperator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return operator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if(this == o) return true;
|
||||
if(o == null || getClass() != o.getClass()) return false;
|
||||
Operator operator1 = (Operator) o;
|
||||
if(precedence != operator1.precedence) return false;
|
||||
if(!operator.equals(operator1.operator)) return false;
|
||||
return type == operator1.type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = operator.hashCode();
|
||||
result = 31 * result + precedence;
|
||||
result = 31 * result + type.hashCode();
|
||||
return result;
|
||||
}
|
||||
|
||||
public enum Type {
|
||||
UNARY, BINARY
|
||||
}
|
||||
|
||||
}
|
@ -2,6 +2,8 @@ package dk.camelot64.kickc.passes;
|
||||
|
||||
import dk.camelot64.kickc.NumberParser;
|
||||
import dk.camelot64.kickc.model.*;
|
||||
import dk.camelot64.kickc.model.operators.Operator;
|
||||
import dk.camelot64.kickc.model.operators.Operators;
|
||||
import dk.camelot64.kickc.parser.KickCBaseVisitor;
|
||||
import dk.camelot64.kickc.parser.KickCParser;
|
||||
import org.antlr.v4.runtime.tree.TerminalNode;
|
||||
@ -164,7 +166,7 @@ public class ParseTreeConstantEvaluator extends KickCBaseVisitor<ConstantValue>
|
||||
public ConstantValue visitExprUnary(KickCParser.ExprUnaryContext ctx) {
|
||||
ConstantValue sub = visit(ctx.expr());
|
||||
String op = ((TerminalNode) ctx.getChild(0)).getSymbol().getText();
|
||||
Operator operator = Operator.getUnary(op);
|
||||
Operator operator = Operators.getUnary(op);
|
||||
return calculateUnary(operator, sub);
|
||||
}
|
||||
|
||||
@ -173,7 +175,7 @@ public class ParseTreeConstantEvaluator extends KickCBaseVisitor<ConstantValue>
|
||||
ConstantValue left = this.visit(ctx.expr(0));
|
||||
ConstantValue right = this.visit(ctx.expr(1));
|
||||
String op = ((TerminalNode) ctx.getChild(1)).getSymbol().getText();
|
||||
Operator operator = Operator.getBinary(op);
|
||||
Operator operator = Operators.getBinary(op);
|
||||
return calculateBinary(operator, left, right);
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,8 @@ package dk.camelot64.kickc.passes;
|
||||
import dk.camelot64.kickc.Compiler;
|
||||
import dk.camelot64.kickc.NumberParser;
|
||||
import dk.camelot64.kickc.model.*;
|
||||
import dk.camelot64.kickc.model.operators.Operator;
|
||||
import dk.camelot64.kickc.model.operators.Operators;
|
||||
import dk.camelot64.kickc.parser.KickCBaseVisitor;
|
||||
import dk.camelot64.kickc.parser.KickCParser;
|
||||
import org.antlr.v4.runtime.ParserRuleContext;
|
||||
@ -243,7 +245,7 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
|
||||
PrePostModifierHandler.addPreModifiers(this, ctx.expr());
|
||||
RValue rValue = (RValue) this.visit(ctx.expr());
|
||||
VariableRef notExprVar = getCurrentSymbols().addVariableIntermediate().getRef();
|
||||
sequence.addStatement(new StatementAssignment(notExprVar, null, Operator.LOGIC_NOT, rValue));
|
||||
sequence.addStatement(new StatementAssignment(notExprVar, null, Operators.LOGIC_NOT, rValue));
|
||||
PrePostModifierHandler.addPostModifiers(this, ctx.expr());
|
||||
|
||||
Label elseJumpLabel = getCurrentSymbols().addLabelIntermediate();
|
||||
@ -404,7 +406,7 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
|
||||
// Add increment
|
||||
ConstantInteger beyondLastVal;
|
||||
if(rangeFirst.getNumber() > rangeLast.getNumber()) {
|
||||
Statement stmtInc = new StatementAssignment(lValue.getRef(), Operator.DECREMENT, lValue.getRef());
|
||||
Statement stmtInc = new StatementAssignment(lValue.getRef(), Operators.DECREMENT, lValue.getRef());
|
||||
sequence.addStatement(stmtInc);
|
||||
if(rangeLast.getNumber() == 0) {
|
||||
beyondLastVal = new ConstantInteger(255L);
|
||||
@ -412,7 +414,7 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
|
||||
beyondLastVal = new ConstantInteger(rangeLast.getNumber() - 1);
|
||||
}
|
||||
} else {
|
||||
Statement stmtInc = new StatementAssignment(lValue.getRef(), Operator.INCREMENT, lValue.getRef());
|
||||
Statement stmtInc = new StatementAssignment(lValue.getRef(), Operators.INCREMENT, lValue.getRef());
|
||||
sequence.addStatement(stmtInc);
|
||||
if(rangeLast.getNumber() == 255) {
|
||||
beyondLastVal = new ConstantInteger(0L);
|
||||
@ -424,7 +426,7 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
|
||||
// Add condition i<last+1 or i<last-1
|
||||
VariableIntermediate tmpVar = getCurrentSymbols().addVariableIntermediate();
|
||||
VariableRef tmpVarRef = tmpVar.getRef();
|
||||
Statement stmtTmpVar = new StatementAssignment(tmpVarRef, lValue.getRef(), Operator.NEQ, beyondLastVal);
|
||||
Statement stmtTmpVar = new StatementAssignment(tmpVarRef, lValue.getRef(), Operators.NEQ, beyondLastVal);
|
||||
sequence.addStatement(stmtTmpVar);
|
||||
// Add jump if condition was met
|
||||
Statement doJmpStmt = new StatementConditionalJump(tmpVarRef, repeatLabel.getRef());
|
||||
@ -527,7 +529,7 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
|
||||
public RValue visitExprCast(KickCParser.ExprCastContext ctx) {
|
||||
RValue child = (RValue) this.visit(ctx.expr());
|
||||
SymbolType castType = (SymbolType) this.visit(ctx.typeDecl());
|
||||
Operator operator = Operator.getCastUnary(castType);
|
||||
Operator operator = Operators.getCastUnary(castType);
|
||||
VariableIntermediate tmpVar = getCurrentSymbols().addVariableIntermediate();
|
||||
VariableRef tmpVarRef = tmpVar.getRef();
|
||||
Statement stmt = new StatementAssignment(tmpVarRef, operator, child);
|
||||
@ -599,7 +601,7 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
|
||||
RValue left = (RValue) this.visit(ctx.expr(0));
|
||||
RValue right = (RValue) this.visit(ctx.expr(1));
|
||||
String op = ((TerminalNode) ctx.getChild(1)).getSymbol().getText();
|
||||
Operator operator = Operator.getBinary(op);
|
||||
Operator operator = Operators.getBinary(op);
|
||||
VariableIntermediate tmpVar = getCurrentSymbols().addVariableIntermediate();
|
||||
VariableRef tmpVarRef = tmpVar.getRef();
|
||||
Statement stmt = new StatementAssignment(tmpVarRef, left, operator, right);
|
||||
@ -617,7 +619,7 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
|
||||
public RValue visitExprUnary(KickCParser.ExprUnaryContext ctx) {
|
||||
RValue child = (RValue) this.visit(ctx.expr());
|
||||
String op = ((TerminalNode) ctx.getChild(0)).getSymbol().getText();
|
||||
Operator operator = Operator.getUnary(op);
|
||||
Operator operator = Operators.getUnary(op);
|
||||
VariableIntermediate tmpVar = getCurrentSymbols().addVariableIntermediate();
|
||||
VariableRef tmpVarRef = tmpVar.getRef();
|
||||
Statement stmt = new StatementAssignment(tmpVarRef, operator, child);
|
||||
@ -743,7 +745,7 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
|
||||
public Void visitExprPostMod(KickCParser.ExprPostModContext ctx) {
|
||||
RValue child = (RValue) mainParser.visit(ctx.expr());
|
||||
String op = ((TerminalNode) ctx.getChild(1)).getSymbol().getText();
|
||||
Operator operator = Operator.getUnary(op);
|
||||
Operator operator = Operators.getUnary(op);
|
||||
PrePostModifier modifier = new PrePostModifier(child, operator);
|
||||
postMods.add(modifier);
|
||||
return null;
|
||||
@ -753,7 +755,7 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
|
||||
public Void visitExprPreMod(KickCParser.ExprPreModContext ctx) {
|
||||
RValue child = (RValue) mainParser.visit(ctx.expr());
|
||||
String op = ((TerminalNode) ctx.getChild(0)).getSymbol().getText();
|
||||
Operator operator = Operator.getUnary(op);
|
||||
Operator operator = Operators.getUnary(op);
|
||||
PrePostModifier modifier = new PrePostModifier(child, operator);
|
||||
preMods.add(modifier);
|
||||
return null;
|
||||
|
@ -1,6 +1,7 @@
|
||||
package dk.camelot64.kickc.passes;
|
||||
|
||||
import dk.camelot64.kickc.model.*;
|
||||
import dk.camelot64.kickc.model.operators.Operators;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
@ -51,7 +52,7 @@ public class Pass1AddTypePromotions extends Pass1Base {
|
||||
// Promotion possible - add tmp-var and a cast
|
||||
if(assignment.getOperator() == null) {
|
||||
// No operator - add cast directly!
|
||||
assignment.setOperator(Operator.getCastUnary(lValueType));
|
||||
assignment.setOperator(Operators.getCastUnary(lValueType));
|
||||
getProgram().getLog().append("Promoting " + rValueType + " to " + lValueType + " in " + assignment);
|
||||
} else {
|
||||
throw new RuntimeException("Tmp-var promotions not implemented yet " + assignment);
|
||||
|
@ -1,6 +1,8 @@
|
||||
package dk.camelot64.kickc.passes;
|
||||
|
||||
import dk.camelot64.kickc.model.*;
|
||||
import dk.camelot64.kickc.model.operators.Operator;
|
||||
import dk.camelot64.kickc.model.operators.Operators;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
@ -28,12 +30,12 @@ public class Pass1FixLValuesLoHi extends Pass1Base {
|
||||
StatementLValue statementLValue = (StatementLValue) statement;
|
||||
LvalueIntermediate intermediate = (LvalueIntermediate) statementLValue.getlValue();
|
||||
StatementAssignment intermediateAssignment = getProgram().getGraph().getAssignment(intermediate.getVariable());
|
||||
if(Operator.LOWBYTE.equals(intermediateAssignment.getOperator()) && intermediateAssignment.getrValue1() == null) {
|
||||
if(Operators.LOWBYTE.equals(intermediateAssignment.getOperator()) && intermediateAssignment.getrValue1() == null) {
|
||||
// Found assignment to an intermediate low byte lValue <x = ...
|
||||
fixLoHiLValue(programScope, statementsIt, statementLValue, intermediate, intermediateAssignment, Operator.SET_LOWBYTE);
|
||||
} else if(Operator.HIBYTE.equals(intermediateAssignment.getOperator()) && intermediateAssignment.getrValue1() == null) {
|
||||
fixLoHiLValue(programScope, statementsIt, statementLValue, intermediate, intermediateAssignment, Operators.SET_LOWBYTE);
|
||||
} else if(Operators.HIBYTE.equals(intermediateAssignment.getOperator()) && intermediateAssignment.getrValue1() == null) {
|
||||
// Found assignment to an intermediate low byte lValue >x = ...
|
||||
fixLoHiLValue(programScope, statementsIt, statementLValue, intermediate, intermediateAssignment, Operator.SET_HIBYTE);
|
||||
fixLoHiLValue(programScope, statementsIt, statementLValue, intermediate, intermediateAssignment, Operators.SET_HIBYTE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
package dk.camelot64.kickc.passes;
|
||||
|
||||
import dk.camelot64.kickc.model.*;
|
||||
import dk.camelot64.kickc.model.operators.Operator;
|
||||
import dk.camelot64.kickc.model.operators.Operators;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@ -78,7 +80,7 @@ public class Pass2ConstantAdditionElimination extends Pass2SsaOptimization {
|
||||
if(pointerDereferenceIndexed.getPointer() instanceof ConstantValue && pointerDereferenceIndexed.getIndex() instanceof ConstantValue) {
|
||||
ConstantValue ptrConstant = (ConstantValue) pointerDereferenceIndexed.getPointer();
|
||||
ConstantValue idxConstant = (ConstantValue) pointerDereferenceIndexed.getIndex();
|
||||
ConstantValue newPtr = new ConstantBinary(ptrConstant, Operator.PLUS, idxConstant);
|
||||
ConstantValue newPtr = new ConstantBinary(ptrConstant, Operators.PLUS, idxConstant);
|
||||
value.set(new PointerDereferenceSimple(newPtr));
|
||||
getLog().append("Consolidated array index constant in " + value.get().toString());
|
||||
return true;
|
||||
@ -88,7 +90,7 @@ public class Pass2ConstantAdditionElimination extends Pass2SsaOptimization {
|
||||
ConstantValue consolidated = consolidateSubConstants(variable);
|
||||
if(consolidated != null) {
|
||||
ConstantValue ptrConstant = (ConstantValue) pointerDereferenceIndexed.getPointer();
|
||||
ConstantValue newPtr = new ConstantBinary(ptrConstant, Operator.PLUS, consolidated);
|
||||
ConstantValue newPtr = new ConstantBinary(ptrConstant, Operators.PLUS, consolidated);
|
||||
pointerDereferenceIndexed.setPointer(newPtr);
|
||||
getLog().append("Consolidated array index constant in assignment " + value.get().toString());
|
||||
return true;
|
||||
@ -101,9 +103,9 @@ public class Pass2ConstantAdditionElimination extends Pass2SsaOptimization {
|
||||
if(assignment.getrValue1() instanceof ConstantValue && assignment.getrValue2() instanceof ConstantValue) {
|
||||
ConstantValue ptrConstant = (ConstantValue) assignment.getrValue1();
|
||||
ConstantValue idxConstant = (ConstantValue) assignment.getrValue2();
|
||||
ConstantValue newPtr = new ConstantBinary(ptrConstant, Operator.PLUS, idxConstant);
|
||||
ConstantValue newPtr = new ConstantBinary(ptrConstant, Operators.PLUS, idxConstant);
|
||||
assignment.setrValue1(null);
|
||||
assignment.setOperator(Operator.DEREF);
|
||||
assignment.setOperator(Operators.DEREF);
|
||||
assignment.setrValue2(newPtr);
|
||||
getLog().append("Consolidated referenced array index constant in assignment " + assignment.getlValue());
|
||||
return true;
|
||||
@ -113,7 +115,7 @@ public class Pass2ConstantAdditionElimination extends Pass2SsaOptimization {
|
||||
ConstantValue consolidated = consolidateSubConstants(variable);
|
||||
if(consolidated != null) {
|
||||
ConstantValue ptrConstant = (ConstantValue) assignment.getrValue1();
|
||||
ConstantValue newPtr = new ConstantBinary(ptrConstant, Operator.PLUS, consolidated);
|
||||
ConstantValue newPtr = new ConstantBinary(ptrConstant, Operators.PLUS, consolidated);
|
||||
assignment.setrValue1(newPtr);
|
||||
getLog().append("Consolidated referenced array index constant in assignment " + assignment.getlValue());
|
||||
return true;
|
||||
@ -128,7 +130,7 @@ public class Pass2ConstantAdditionElimination extends Pass2SsaOptimization {
|
||||
ConstantValue consolidated = consolidateSubConstants(variable);
|
||||
if(consolidated != null) {
|
||||
ConstantValue const1 = (ConstantValue) assignment.getrValue1();
|
||||
assignment.setrValue1(new ConstantBinary(const1, Operator.PLUS, consolidated));
|
||||
assignment.setrValue1(new ConstantBinary(const1, Operators.PLUS, consolidated));
|
||||
getLog().append("Consolidated constant in assignment " + assignment.getlValue());
|
||||
return true;
|
||||
}
|
||||
@ -137,7 +139,7 @@ public class Pass2ConstantAdditionElimination extends Pass2SsaOptimization {
|
||||
ConstantValue consolidated = consolidateSubConstants(variable);
|
||||
if(consolidated != null) {
|
||||
ConstantValue const2 = (ConstantValue) assignment.getrValue2();
|
||||
ConstantValue newNumber = new ConstantBinary(consolidated, Operator.PLUS, const2);
|
||||
ConstantValue newNumber = new ConstantBinary(consolidated, Operators.PLUS, const2);
|
||||
assignment.setrValue2(newNumber);
|
||||
// Handling of negative consolidated numbers?
|
||||
getLog().append("Consolidated constant in assignment " + assignment.getlValue());
|
||||
@ -184,7 +186,7 @@ public class Pass2ConstantAdditionElimination extends Pass2SsaOptimization {
|
||||
if(const1 != null) {
|
||||
result = const1;
|
||||
if(const2 != null) {
|
||||
result = new ConstantBinary(const1, Operator.PLUS, const2);
|
||||
result = new ConstantBinary(const1, Operators.PLUS, const2);
|
||||
}
|
||||
} else if(const2 != null) {
|
||||
result = const2;
|
||||
@ -202,7 +204,7 @@ public class Pass2ConstantAdditionElimination extends Pass2SsaOptimization {
|
||||
assignment.setrValue2(assignment.getrValue1());
|
||||
assignment.setOperator(null);
|
||||
assignment.setrValue1(null);
|
||||
return new ConstantUnary(Operator.MINUS, constant);
|
||||
return new ConstantUnary(Operators.MINUS, constant);
|
||||
} else {
|
||||
ConstantValue const1 = null;
|
||||
if(assignment.getrValue1() instanceof VariableRef) {
|
||||
@ -216,7 +218,7 @@ public class Pass2ConstantAdditionElimination extends Pass2SsaOptimization {
|
||||
if(const1 != null) {
|
||||
result = const1;
|
||||
if(const2 != null) {
|
||||
result = new ConstantBinary(const1, Operator.MINUS, const2);
|
||||
result = new ConstantBinary(const1, Operators.MINUS, const2);
|
||||
}
|
||||
} else if(const2 != null) {
|
||||
result = const2;
|
||||
|
@ -1,6 +1,8 @@
|
||||
package dk.camelot64.kickc.passes;
|
||||
|
||||
import dk.camelot64.kickc.model.*;
|
||||
import dk.camelot64.kickc.model.operators.Operator;
|
||||
import dk.camelot64.kickc.model.operators.Operators;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@ -140,7 +142,7 @@ public class Pass2ConstantIdentification extends Pass2SsaOptimization {
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if(Operator.ADDRESS_OF.equals(assignment.getOperator()) && assignment.getrValue1()==null) {
|
||||
} else if(Operators.ADDRESS_OF.equals(assignment.getOperator()) && assignment.getrValue1()==null) {
|
||||
if(assignment.getrValue2() instanceof VariableRef) {
|
||||
ConstantVarPointer constantVarPointer = new ConstantVarPointer((VariableRef) assignment.getrValue2());
|
||||
constants.put(variable, constantVarPointer);
|
||||
@ -241,9 +243,9 @@ public class Pass2ConstantIdentification extends Pass2SsaOptimization {
|
||||
case "<=":
|
||||
return new ConstantBinary(c1, operator, c2);
|
||||
case "w=":
|
||||
return new ConstantBinary(new ConstantBinary(c1, Operator.MULTIPLY, new ConstantInteger(256L)), Operator.PLUS, c2);
|
||||
return new ConstantBinary(new ConstantBinary(c1, Operators.MULTIPLY, new ConstantInteger(256L)), Operators.PLUS, c2);
|
||||
case "dw=":
|
||||
return new ConstantBinary(new ConstantBinary(c1, Operator.MULTIPLY, new ConstantInteger(65536L)), Operator.PLUS, c2);
|
||||
return new ConstantBinary(new ConstantBinary(c1, Operators.MULTIPLY, new ConstantInteger(65536L)), Operators.PLUS, c2);
|
||||
case "*idx":
|
||||
// Pointer dereference - not constant
|
||||
return null;
|
||||
@ -263,7 +265,7 @@ public class Pass2ConstantIdentification extends Pass2SsaOptimization {
|
||||
for(Statement statement : block.getStatements()) {
|
||||
if(statement instanceof StatementAssignment) {
|
||||
StatementAssignment assignment = (StatementAssignment) statement;
|
||||
if(Operator.ADDRESS_OF.equals(assignment.getOperator()) && var.equals(assignment.getrValue2())) {
|
||||
if(Operators.ADDRESS_OF.equals(assignment.getOperator()) && var.equals(assignment.getrValue2())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
package dk.camelot64.kickc.passes;
|
||||
|
||||
import dk.camelot64.kickc.model.*;
|
||||
import dk.camelot64.kickc.model.operators.Operator;
|
||||
import dk.camelot64.kickc.model.operators.Operators;
|
||||
|
||||
import java.util.ListIterator;
|
||||
|
||||
@ -27,7 +29,7 @@ public class Pass2FixInlineConstructors extends Pass2SsaOptimization {
|
||||
private class WordConstructor extends InlineConstructor {
|
||||
|
||||
public WordConstructor() {
|
||||
super(SymbolType.WORD, Operator.WORD);
|
||||
super(SymbolType.WORD, Operators.WORD);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -40,7 +42,7 @@ public class Pass2FixInlineConstructors extends Pass2SsaOptimization {
|
||||
private class DWordConstructor extends InlineConstructor {
|
||||
|
||||
public DWordConstructor() {
|
||||
super(SymbolType.DWORD, Operator.DWORD);
|
||||
super(SymbolType.DWORD, Operators.DWORD);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,6 +1,7 @@
|
||||
package dk.camelot64.kickc.passes;
|
||||
|
||||
import dk.camelot64.kickc.model.*;
|
||||
import dk.camelot64.kickc.model.operators.Operators;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.ListIterator;
|
||||
@ -32,22 +33,22 @@ public class Pass2NopCastElimination extends Pass2SsaOptimization {
|
||||
SymbolType rValType = SymbolTypeInference.inferType(getScope(), assignment.getrValue2());
|
||||
boolean isNopCast = false;
|
||||
SymbolType toType = null;
|
||||
if(SymbolType.isByte(rValType) && Operator.CAST_SBYTE.equals(assignment.getOperator())) {
|
||||
if(SymbolType.isByte(rValType) && Operators.CAST_SBYTE.equals(assignment.getOperator())) {
|
||||
isNopCast = true;
|
||||
toType = SymbolType.SBYTE;
|
||||
} else if(SymbolType.isSByte(rValType) && Operator.CAST_BYTE.equals(assignment.getOperator())) {
|
||||
} else if(SymbolType.isSByte(rValType) && Operators.CAST_BYTE.equals(assignment.getOperator())) {
|
||||
isNopCast = true;
|
||||
toType = SymbolType.BYTE;
|
||||
} else if(SymbolType.isWord(rValType) && Operator.CAST_SWORD.equals(assignment.getOperator())) {
|
||||
} else if(SymbolType.isWord(rValType) && Operators.CAST_SWORD.equals(assignment.getOperator())) {
|
||||
isNopCast = true;
|
||||
toType = SymbolType.SWORD;
|
||||
} else if(SymbolType.isSWord(rValType) && Operator.CAST_WORD.equals(assignment.getOperator())) {
|
||||
} else if(SymbolType.isSWord(rValType) && Operators.CAST_WORD.equals(assignment.getOperator())) {
|
||||
isNopCast = true;
|
||||
toType = SymbolType.WORD;
|
||||
} else if(SymbolType.isWord(rValType) && Operator.CAST_PTRBY.equals(assignment.getOperator())) {
|
||||
} else if(SymbolType.isWord(rValType) && Operators.CAST_PTRBY.equals(assignment.getOperator())) {
|
||||
isNopCast = true;
|
||||
toType = new SymbolTypePointer(SymbolType.BYTE);
|
||||
} else if(rValType instanceof SymbolTypePointer && Operator.CAST_WORD.equals(assignment.getOperator())) {
|
||||
} else if(rValType instanceof SymbolTypePointer && Operators.CAST_WORD.equals(assignment.getOperator())) {
|
||||
isNopCast = true;
|
||||
toType = SymbolType.WORD;
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package dk.camelot64.kickc.passes;
|
||||
|
||||
import dk.camelot64.kickc.model.*;
|
||||
import dk.camelot64.kickc.model.operators.Operators;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -96,7 +97,7 @@ public class Pass2UnaryNotSimplification extends Pass2SsaOptimization {
|
||||
*/
|
||||
private void createInverse(String newOperator, StatementAssignment assignment, StatementAssignment tempAssignment) {
|
||||
assignment.setrValue1(tempAssignment.getrValue1());
|
||||
assignment.setOperator(newOperator == null ? null : Operator.getBinary(newOperator));
|
||||
assignment.setOperator(newOperator == null ? null : Operators.getBinary(newOperator));
|
||||
assignment.setrValue2(tempAssignment.getrValue2());
|
||||
getLog().append("Inversing boolean not " + assignment.toString(getProgram(), true) + " from " + tempAssignment.toString(getProgram(), true));
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package dk.camelot64.kickc.passes;
|
||||
|
||||
import dk.camelot64.kickc.model.*;
|
||||
import dk.camelot64.kickc.model.operators.Operators;
|
||||
|
||||
/***
|
||||
* Find equivalence classes that could be assigned to the special ALU register.
|
||||
@ -43,7 +44,7 @@ public class Pass4RegisterUpliftPotentialAluAnalysis extends Pass2Base {
|
||||
// The variable has ALU potential
|
||||
setHasAluPotential(registerPotentials, potentialAluVar);
|
||||
}
|
||||
} else if(assignment.getOperator() != null && (Operator.PLUS.equals(assignment.getOperator()) || Operator.BOOL_OR.equals(assignment.getOperator()) || Operator.WORD.equals(assignment.getOperator()))) {
|
||||
} else if(assignment.getOperator() != null && (Operators.PLUS.equals(assignment.getOperator()) || Operators.BOOL_OR.equals(assignment.getOperator()) || Operators.WORD.equals(assignment.getOperator()))) {
|
||||
// ALU applicable if the variable is one of the two values
|
||||
if(assignment.getrValue2().equals(potentialAluVar) && assignment.getrValue1() != null) {
|
||||
// The variable has ALU potential
|
||||
@ -65,10 +66,10 @@ public class Pass4RegisterUpliftPotentialAluAnalysis extends Pass2Base {
|
||||
if(assignment.getOperator() != null && "*idx".equals(assignment.getOperator().getOperator())) {
|
||||
potentialAluVar = findAluPotential(assignment);
|
||||
}
|
||||
if(assignment.getOperator() != null && Operator.LOWBYTE.equals(assignment.getOperator()) && assignment.getrValue1() == null) {
|
||||
if(assignment.getOperator() != null && Operators.LOWBYTE.equals(assignment.getOperator()) && assignment.getrValue1() == null) {
|
||||
potentialAluVar = findAluPotential(assignment);
|
||||
}
|
||||
if(assignment.getOperator() != null && Operator.HIBYTE.equals(assignment.getOperator()) && assignment.getrValue1() == null) {
|
||||
if(assignment.getOperator() != null && Operators.HIBYTE.equals(assignment.getOperator()) && assignment.getrValue1() == null) {
|
||||
potentialAluVar = findAluPotential(assignment);
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ import dk.camelot64.kickc.CompileLog;
|
||||
import dk.camelot64.kickc.fragment.AsmFragmentTemplate;
|
||||
import dk.camelot64.kickc.fragment.AsmFragmentTemplateSynthesizer;
|
||||
import dk.camelot64.kickc.fragment.AsmFragmentTemplateUsages;
|
||||
import dk.camelot64.kickc.model.Operator;
|
||||
import dk.camelot64.kickc.model.operators.Operators;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
@ -119,21 +119,21 @@ public class TestFragments {
|
||||
|
||||
private Collection<String> unaryBu() {
|
||||
ArrayList<String> unaries = new ArrayList<>();
|
||||
unaries.add(Operator.BOOL_NOT.getAsmOperator());
|
||||
unaries.add(Operator.DECREMENT.getAsmOperator());
|
||||
unaries.add(Operator.INCREMENT.getAsmOperator());
|
||||
unaries.add(Operator.NEG.getAsmOperator());
|
||||
unaries.add(Operator.POS.getAsmOperator());
|
||||
unaries.add(Operators.BOOL_NOT.getAsmOperator());
|
||||
unaries.add(Operators.DECREMENT.getAsmOperator());
|
||||
unaries.add(Operators.INCREMENT.getAsmOperator());
|
||||
unaries.add(Operators.NEG.getAsmOperator());
|
||||
unaries.add(Operators.POS.getAsmOperator());
|
||||
return unaries;
|
||||
}
|
||||
|
||||
private Collection<String> binaryBu() {
|
||||
ArrayList<String> unaries = new ArrayList<>();
|
||||
unaries.add(Operator.BOOL_AND.getAsmOperator());
|
||||
unaries.add(Operator.BOOL_OR.getAsmOperator());
|
||||
unaries.add(Operator.BOOL_XOR.getAsmOperator());
|
||||
unaries.add(Operator.MINUS.getAsmOperator());
|
||||
unaries.add(Operator.PLUS.getAsmOperator());
|
||||
unaries.add(Operators.BOOL_AND.getAsmOperator());
|
||||
unaries.add(Operators.BOOL_OR.getAsmOperator());
|
||||
unaries.add(Operators.BOOL_XOR.getAsmOperator());
|
||||
unaries.add(Operators.MINUS.getAsmOperator());
|
||||
unaries.add(Operators.PLUS.getAsmOperator());
|
||||
return unaries;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user