From 07b67efb7ce4c7bd5ed24b14f7bc6c3ed8f72a8d Mon Sep 17 00:00:00 2001
From: jespergravgaard <jesper@balmangravgaard.dk>
Date: Sun, 12 May 2019 14:42:41 +0200
Subject: [PATCH] Eliminating SymbolTypeMulti - 274/351

---
 .../camelot64/kickc/fragment/AsmFormat.java   | 20 +++----
 .../kickc/fragment/AsmFragmentInstance.java   |  2 +-
 .../AsmFragmentInstanceSpecFactory.java       | 24 ++++----
 .../kickc/model/operators/OperatorDWord.java  |  6 +-
 .../model/operators/OperatorGetHigh.java      |  8 +--
 .../kickc/model/operators/OperatorGetLow.java |  8 +--
 .../kickc/model/operators/OperatorPlus.java   |  6 +-
 .../model/operators/OperatorSetHigh.java      | 12 ++--
 .../kickc/model/operators/OperatorSetLow.java |  8 +--
 .../kickc/model/operators/OperatorSizeOf.java | 15 ++---
 .../kickc/model/operators/OperatorTypeId.java | 36 +----------
 .../kickc/model/operators/OperatorWord.java   |  3 +-
 .../kickc/model/types/SymbolType.java         | 60 -------------------
 .../model/types/SymbolTypeInference.java      |  4 +-
 .../passes/Pass2FixInlineConstructors.java    |  4 +-
 .../kickc/passes/Pass2NopCastElimination.java | 10 ++--
 .../kickc/passes/Pass4CodeGeneration.java     | 18 +++---
 .../kickc/passes/Pass4RegistersFinalize.java  | 12 ++--
 18 files changed, 79 insertions(+), 177 deletions(-)

diff --git a/src/main/java/dk/camelot64/kickc/fragment/AsmFormat.java b/src/main/java/dk/camelot64/kickc/fragment/AsmFormat.java
index 26db72078..331c51337 100644
--- a/src/main/java/dk/camelot64/kickc/fragment/AsmFormat.java
+++ b/src/main/java/dk/camelot64/kickc/fragment/AsmFormat.java
@@ -10,8 +10,6 @@ import dk.camelot64.kickc.model.symbols.Variable;
 import dk.camelot64.kickc.model.types.*;
 import dk.camelot64.kickc.model.values.*;
 
-import java.util.List;
-
 /** Formatting of numbers, constants, names and more for KickAssembler */
 public class AsmFormat {
 
@@ -165,22 +163,22 @@ public class AsmFormat {
          return getAsmConstant(program, new ConstantBinary(new ConstantInteger((long) 0xffffffffL), Operators.BOOL_AND, operand), outerPrecedence, codeScope);
       } else if(Operators.LOWBYTE.equals(operator)) {
          SymbolType operandType = SymbolTypeInference.inferType(program.getScope(), operand);
-         if(SymbolType.isByte(operandType) || SymbolType.isSByte(operandType)) {
+         if(SymbolType.BYTE.equals(operandType) || SymbolType.SBYTE.equals(operandType)) {
             return getAsmConstant(program, operand, outerPrecedence, codeScope);
-         } else if(SymbolType.isWord(operandType) || SymbolType.isSWord(operandType) || operandType instanceof SymbolTypePointer || SymbolType.STRING.equals(operandType)) {
+         } else if(SymbolType.WORD.equals(operandType) || SymbolType.SWORD.equals(operandType) || operandType instanceof SymbolTypePointer || SymbolType.STRING.equals(operandType)) {
             return "<" + getAsmConstant(program, operand, outerPrecedence, codeScope);
-         } else if(SymbolType.isDWord(operandType) || SymbolType.isSDWord(operandType)) {
+         } else if(SymbolType.DWORD.equals(operandType) || SymbolType.SDWORD.equals(operandType)) {
             return getAsmConstant(program, new ConstantBinary(operand, Operators.BOOL_AND, new ConstantInteger((long) 0xffff)), outerPrecedence, codeScope);
          } else {
             throw new CompileError("Unhandled type " + operand);
          }
       } else if(Operators.HIBYTE.equals(operator)) {
          SymbolType operandType = SymbolTypeInference.inferType(program.getScope(), operand);
-         if(SymbolType.isByte(operandType) || SymbolType.isSByte(operandType)) {
+         if(SymbolType.BYTE.equals(operandType) || SymbolType.SBYTE.equals(operandType)) {
             return getAsmConstant(program, new ConstantInteger(0l), outerPrecedence, codeScope);
-         } else if(SymbolType.isWord(operandType) || SymbolType.isSWord(operandType) || operandType instanceof SymbolTypePointer || SymbolType.STRING.equals(operandType)) {
+         } else if(SymbolType.WORD.equals(operandType) || SymbolType.SWORD.equals(operandType) || operandType instanceof SymbolTypePointer || SymbolType.STRING.equals(operandType)) {
             return ">" + getAsmConstant(program, operand, outerPrecedence, codeScope);
-         } else if(SymbolType.isDWord(operandType) || SymbolType.isSDWord(operandType)) {
+         } else if(SymbolType.DWORD.equals(operandType) || SymbolType.SDWORD.equals(operandType)) {
             return getAsmConstant(program, new ConstantBinary(operand, Operators.SHIFT_RIGHT, new ConstantInteger((long) 16)), outerPrecedence, codeScope);
          } else {
             throw new CompileError("Unhandled type " + operand);
@@ -191,11 +189,11 @@ public class AsmFormat {
          return getAsmConstant(program, new ConstantBinary(operand, Operators.MINUS, new ConstantInteger((long) 1)), outerPrecedence, codeScope);
       } else if(Operators.BOOL_NOT.equals(operator)) {
          SymbolType operandType = SymbolTypeInference.inferType(program.getScope(), operand);
-         if(SymbolType.isByte(operandType) || SymbolType.isSByte(operandType)) {
+         if(SymbolType.BYTE.equals(operandType) || SymbolType.SBYTE.equals(operandType)) {
             return getAsmConstant(program, new ConstantBinary(operand, Operators.BOOL_XOR, new ConstantInteger((long) 0xff)), outerPrecedence, codeScope);
-         } else if(SymbolType.isWord(operandType) || SymbolType.isSWord(operandType) || operandType instanceof SymbolTypePointer || SymbolType.STRING.equals(operandType)) {
+         } else if(SymbolType.WORD.equals(operandType) || SymbolType.SWORD.equals(operandType) || operandType instanceof SymbolTypePointer || SymbolType.STRING.equals(operandType)) {
             return getAsmConstant(program, new ConstantBinary(operand, Operators.BOOL_XOR, new ConstantInteger((long) 0xffff)), outerPrecedence, codeScope);
-         } else if(SymbolType.isDWord(operandType) || SymbolType.isSDWord(operandType)) {
+         } else if(SymbolType.DWORD.equals(operandType) || SymbolType.SDWORD.equals(operandType)) {
             return getAsmConstant(program, new ConstantBinary(operand, Operators.BOOL_XOR, new ConstantInteger((long) 0xffffffff)), outerPrecedence, codeScope);
          } else {
             throw new CompileError("Unhandled type " + operand);
diff --git a/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentInstance.java b/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentInstance.java
index 9a34ffe2a..53793f4c9 100644
--- a/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentInstance.java
+++ b/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentInstance.java
@@ -301,7 +301,7 @@ public class AsmFragmentInstance {
       public AsmParameter visitAsmExprInt(KickCParser.AsmExprIntContext ctx) {
          Number number = NumberParser.parseLiteral(ctx.NUMBER().getText());
          ConstantInteger intVal = new ConstantInteger(number.longValue());
-         boolean isZp = SymbolType.isByte(intVal.getType()) || SymbolType.isSByte(intVal.getType());
+         boolean isZp = SymbolType.BYTE.equals(intVal.getType()) || SymbolType.SBYTE.equals(intVal.getType());
          String param = AsmFormat.getAsmNumber(number);
          return new AsmParameter(param, isZp);
       }
diff --git a/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentInstanceSpecFactory.java b/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentInstanceSpecFactory.java
index 396ec781e..de00e8edf 100644
--- a/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentInstanceSpecFactory.java
+++ b/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentInstanceSpecFactory.java
@@ -288,17 +288,17 @@ public class AsmFragmentInstanceSpecFactory {
     * @return The type name
     */
    static String getTypePrefix(SymbolType type) {
-      if(SymbolType.isByte(type)) {
+      if(SymbolType.BYTE.equals(type)) {
          return "vbu";
-      } else if(SymbolType.isSByte(type)) {
+      } else if(SymbolType.SBYTE.equals(type)) {
          return "vbs";
-      } else if(SymbolType.isWord(type)) {
+      } else if(SymbolType.WORD.equals(type)) {
          return "vwu";
-      } else if(SymbolType.isSWord(type)) {
+      } else if(SymbolType.SWORD.equals(type)) {
          return "vws";
-      } else if(SymbolType.isDWord(type)) {
+      } else if(SymbolType.DWORD.equals(type)) {
          return "vdu";
-      } else if(SymbolType.isSDWord(type)) {
+      } else if(SymbolType.SDWORD.equals(type)) {
          return "vds";
       } else if(SymbolType.STRING.equals(type)) {
          return "pbu";
@@ -306,17 +306,17 @@ public class AsmFragmentInstanceSpecFactory {
          return "vbo";
       } else if(type instanceof SymbolTypePointer) {
          SymbolType elementType = ((SymbolTypePointer) type).getElementType();
-         if(SymbolType.isByte(elementType)) {
+         if(SymbolType.BYTE.equals(elementType)) {
             return "pbu";
-         } else if(SymbolType.isSByte(elementType)) {
+         } else if(SymbolType.SBYTE.equals(elementType)) {
             return "pbs";
-         } else if(SymbolType.isWord(elementType)) {
+         } else if(SymbolType.WORD.equals(elementType)) {
             return "pwu";
-         } else if(SymbolType.isSWord(elementType)) {
+         } else if(SymbolType.SWORD.equals(elementType)) {
             return "pws";
-         } else if(SymbolType.isDWord(elementType)) {
+         } else if(SymbolType.DWORD.equals(elementType)) {
             return "pdu";
-         } else if(SymbolType.isSDWord(elementType)) {
+         } else if(SymbolType.SDWORD.equals(elementType)) {
             return "pds";
          } else if(SymbolType.BOOLEAN.equals(elementType)) {
             return "pbo";
diff --git a/src/main/java/dk/camelot64/kickc/model/operators/OperatorDWord.java b/src/main/java/dk/camelot64/kickc/model/operators/OperatorDWord.java
index c713d3255..b0e06378c 100644
--- a/src/main/java/dk/camelot64/kickc/model/operators/OperatorDWord.java
+++ b/src/main/java/dk/camelot64/kickc/model/operators/OperatorDWord.java
@@ -32,13 +32,13 @@ public class OperatorDWord extends OperatorBinary {
       if(right instanceof SymbolTypePointer) {
          right = SymbolType.WORD;
       }
-      if(SymbolType.isByte(left)) {
+      if(SymbolType.BYTE.equals(left)) {
          left = SymbolType.WORD;
       }
-      if(SymbolType.isByte(right)) {
+      if(SymbolType.BYTE.equals(right)) {
          right = SymbolType.WORD;
       }
-      if(SymbolType.isWord(left) && SymbolType.isWord(right)) {
+      if(SymbolType.WORD.equals(left) && SymbolType.WORD.equals(right)) {
          return SymbolType.DWORD;
       }
       throw new NoMatchingType("DWord constructor cannot use " + left + " " + getOperator() + " " + right);
diff --git a/src/main/java/dk/camelot64/kickc/model/operators/OperatorGetHigh.java b/src/main/java/dk/camelot64/kickc/model/operators/OperatorGetHigh.java
index 81aad2e0e..d28f2f49f 100644
--- a/src/main/java/dk/camelot64/kickc/model/operators/OperatorGetHigh.java
+++ b/src/main/java/dk/camelot64/kickc/model/operators/OperatorGetHigh.java
@@ -22,9 +22,9 @@ public class OperatorGetHigh extends OperatorUnary {
    public ConstantLiteral calculateLiteral(ConstantLiteral operand, ProgramScope scope) {
       if(operand instanceof ConstantInteger) {
          ConstantInteger operandInt = (ConstantInteger) operand;
-         if(SymbolType.isWord(operandInt.getType()) || SymbolType.isSWord(operandInt.getType())) {
+         if(SymbolType.WORD.equals(operandInt.getType()) || SymbolType.SWORD.equals(operandInt.getType())) {
             return new ConstantInteger(operandInt.getInteger()>>8);
-         } else if(SymbolType.isDWord(operandInt.getType()) || SymbolType.isSDWord(operandInt.getType())) {
+         } else if(SymbolType.DWORD.equals(operandInt.getType()) || SymbolType.SDWORD.equals(operandInt.getType())) {
             return new ConstantInteger(operandInt.getInteger()>>16);
          }
       } else if(operand instanceof ConstantPointer) {
@@ -37,9 +37,9 @@ public class OperatorGetHigh extends OperatorUnary {
 
    @Override
    public SymbolType inferType(SymbolTypeSimple operandType) {
-      if(operandType instanceof SymbolTypePointer || SymbolType.isWord(operandType) || SymbolType.isSWord(operandType)) {
+      if(operandType instanceof SymbolTypePointer || SymbolType.WORD.equals(operandType) || SymbolType.SWORD.equals(operandType)) {
          return SymbolType.BYTE;
-      } else if(SymbolType.isDWord(operandType) || SymbolType.isSDWord(operandType)) {
+      } else if(SymbolType.DWORD.equals(operandType) || SymbolType.SDWORD.equals(operandType)) {
          return SymbolType.WORD;
       } else if(SymbolType.STRING.equals(operandType)) {
          return SymbolType.BYTE;
diff --git a/src/main/java/dk/camelot64/kickc/model/operators/OperatorGetLow.java b/src/main/java/dk/camelot64/kickc/model/operators/OperatorGetLow.java
index 81fc490c0..c05e748d4 100644
--- a/src/main/java/dk/camelot64/kickc/model/operators/OperatorGetLow.java
+++ b/src/main/java/dk/camelot64/kickc/model/operators/OperatorGetLow.java
@@ -22,9 +22,9 @@ public class OperatorGetLow extends OperatorUnary {
    public ConstantLiteral calculateLiteral(ConstantLiteral operand, ProgramScope scope) {
       if(operand instanceof ConstantInteger) {
          ConstantInteger operandInt = (ConstantInteger) operand;
-         if(SymbolType.isWord(operandInt.getType()) || SymbolType.isSWord(operandInt.getType())) {
+         if(SymbolType.WORD.equals(operandInt.getType()) || SymbolType.SWORD.equals(operandInt.getType())) {
             return new ConstantInteger(operandInt.getInteger()&0xff);
-         } else if(SymbolType.isDWord(operandInt.getType()) || SymbolType.isSDWord(operandInt.getType())) {
+         } else if(SymbolType.DWORD.equals(operandInt.getType()) || SymbolType.SDWORD.equals(operandInt.getType())) {
             return new ConstantInteger(operandInt.getInteger()&0xffff);
          }
       } else if(operand instanceof ConstantPointer) {
@@ -37,9 +37,9 @@ public class OperatorGetLow extends OperatorUnary {
 
    @Override
    public SymbolType inferType(SymbolTypeSimple operandType) {
-      if(operandType instanceof SymbolTypePointer || SymbolType.isWord(operandType) || SymbolType.isSWord(operandType)) {
+      if(operandType instanceof SymbolTypePointer || SymbolType.WORD.equals(operandType) || SymbolType.SWORD.equals(operandType)) {
          return SymbolType.BYTE;
-      } else if(SymbolType.isDWord(operandType) || SymbolType.isSDWord(operandType)) {
+      } else if(SymbolType.DWORD.equals(operandType) || SymbolType.SDWORD.equals(operandType)) {
          return SymbolType.WORD;
       } else if(SymbolType.STRING.equals(operandType)) {
          return SymbolType.BYTE;
diff --git a/src/main/java/dk/camelot64/kickc/model/operators/OperatorPlus.java b/src/main/java/dk/camelot64/kickc/model/operators/OperatorPlus.java
index 00844a779..0cb8ec7b8 100644
--- a/src/main/java/dk/camelot64/kickc/model/operators/OperatorPlus.java
+++ b/src/main/java/dk/camelot64/kickc/model/operators/OperatorPlus.java
@@ -23,7 +23,7 @@ public class OperatorPlus extends OperatorBinary {
          return new ConstantString(((ConstantString) left).getString() + ((ConstantString) right).getString());
       } else if(left instanceof ConstantString && right instanceof ConstantChar) {
          return new ConstantString(((ConstantString) left).getString() + ((ConstantChar) right).getChar());
-      } else if(left instanceof ConstantString && right instanceof ConstantInteger && SymbolType.isByte(((ConstantInteger) right).getType())) {
+      } else if(left instanceof ConstantString && right instanceof ConstantInteger && SymbolType.BYTE.equals(((ConstantInteger) right).getType())) {
          Character character = (char) ((ConstantInteger) right).getInteger().byteValue();
          return new ConstantString(((ConstantString) left).getString() + character);
       } else if(left instanceof ConstantPointer && right instanceof ConstantInteger) {
@@ -62,9 +62,9 @@ public class OperatorPlus extends OperatorBinary {
    private boolean isStringLike(SymbolTypeSimple type) {
       if(SymbolType.STRING.equals(type)) {
          return true;
-      } else if(SymbolType.isByte(type)) {
+      } else if(SymbolType.BYTE.equals(type)) {
          return true;
-      } else if(type instanceof SymbolTypeArray && SymbolType.isByte(((SymbolTypeArray) type).getElementType())) {
+      } else if(type instanceof SymbolTypeArray && SymbolType.BYTE.equals(((SymbolTypeArray) type).getElementType())) {
          return true;
       }
       return false;
diff --git a/src/main/java/dk/camelot64/kickc/model/operators/OperatorSetHigh.java b/src/main/java/dk/camelot64/kickc/model/operators/OperatorSetHigh.java
index e5218c3bd..19662e139 100644
--- a/src/main/java/dk/camelot64/kickc/model/operators/OperatorSetHigh.java
+++ b/src/main/java/dk/camelot64/kickc/model/operators/OperatorSetHigh.java
@@ -22,17 +22,17 @@ public class OperatorSetHigh extends OperatorBinary {
    public SymbolType inferType(SymbolTypeSimple left, SymbolTypeSimple right) {
       if(left instanceof SymbolTypePointer) {
          return left;
-      } else if(SymbolType.isByte(left)) {
+      } else if(SymbolType.BYTE.equals(left)) {
          return SymbolType.WORD;
-      } else if(SymbolType.isSByte(left)) {
+      } else if(SymbolType.SBYTE.equals(left)) {
          return SymbolType.WORD;
-      } else if(SymbolType.isWord(left)) {
+      } else if(SymbolType.WORD.equals(left)) {
          return SymbolType.WORD;
-      } else if(SymbolType.isSWord(left)) {
+      } else if(SymbolType.SWORD.equals(left)) {
          return SymbolType.SWORD;
-      } else if(SymbolType.isDWord(left)) {
+      } else if(SymbolType.DWORD.equals(left)) {
          return SymbolType.DWORD;
-      } else if(SymbolType.isSDWord(left)) {
+      } else if(SymbolType.SDWORD.equals(left)) {
          return SymbolType.SDWORD;
       }
       throw new RuntimeException("Type inference case not handled " + left + " " + getOperator() + " " + right);
diff --git a/src/main/java/dk/camelot64/kickc/model/operators/OperatorSetLow.java b/src/main/java/dk/camelot64/kickc/model/operators/OperatorSetLow.java
index 12e3d486f..bd4cd763a 100644
--- a/src/main/java/dk/camelot64/kickc/model/operators/OperatorSetLow.java
+++ b/src/main/java/dk/camelot64/kickc/model/operators/OperatorSetLow.java
@@ -23,13 +23,13 @@ public class OperatorSetLow extends OperatorBinary {
       if(left instanceof SymbolTypePointer) {
          return left;
       }
-      if(SymbolType.isWord(left)) {
+      if(SymbolType.WORD.equals(left)) {
          return SymbolType.WORD;
-      } else if(SymbolType.isSWord(left)) {
+      } else if(SymbolType.SWORD.equals(left)) {
          return SymbolType.SWORD;
-      } else if(SymbolType.isDWord(left)) {
+      } else if(SymbolType.DWORD.equals(left)) {
          return SymbolType.DWORD;
-      } else if(SymbolType.isSDWord(left)) {
+      } else if(SymbolType.SDWORD.equals(left)) {
          return SymbolType.SDWORD;
       }
       throw new RuntimeException("Type inference case not handled " + left + " " + getOperator() + " " + right);
diff --git a/src/main/java/dk/camelot64/kickc/model/operators/OperatorSizeOf.java b/src/main/java/dk/camelot64/kickc/model/operators/OperatorSizeOf.java
index 02d3e51e8..6300140e1 100644
--- a/src/main/java/dk/camelot64/kickc/model/operators/OperatorSizeOf.java
+++ b/src/main/java/dk/camelot64/kickc/model/operators/OperatorSizeOf.java
@@ -3,7 +3,6 @@ package dk.camelot64.kickc.model.operators;
 import dk.camelot64.kickc.model.symbols.ConstantVar;
 import dk.camelot64.kickc.model.symbols.ProgramScope;
 import dk.camelot64.kickc.model.types.SymbolType;
-import dk.camelot64.kickc.model.types.SymbolTypeMulti;
 import dk.camelot64.kickc.model.types.SymbolTypePointer;
 import dk.camelot64.kickc.model.types.SymbolTypeSimple;
 import dk.camelot64.kickc.model.values.ConstantInteger;
@@ -20,7 +19,7 @@ public class OperatorSizeOf extends OperatorUnary {
    @Override
    public ConstantLiteral calculateLiteral(ConstantLiteral operand, ProgramScope scope) {
       SymbolType type = operand.getType(scope);
-      return new ConstantInteger((long)type.getSizeBytes());
+      return new ConstantInteger((long) type.getSizeBytes());
    }
 
    @Override
@@ -30,6 +29,7 @@ public class OperatorSizeOf extends OperatorUnary {
 
    /**
     * Get the constant variable containing the size of a specific type
+    *
     * @param programScope The program scope (used for finding/adding the constant).
     * @param type The type to get the variable for
     * @return The constant variable
@@ -37,7 +37,7 @@ public class OperatorSizeOf extends OperatorUnary {
    public static ConstantRef getSizeOfConstantVar(ProgramScope programScope, SymbolType type) {
       String typeConstName = getSizeofConstantName(type);
       ConstantVar typeSizeConstant = programScope.getConstant(typeConstName);
-      if(typeSizeConstant ==null) {
+      if(typeSizeConstant == null) {
          // Constant not found - create it
          long typeSize = type.getSizeBytes();
          typeSizeConstant = new ConstantVar(typeConstName, programScope, SymbolType.BYTE, new ConstantInteger(typeSize));
@@ -48,18 +48,15 @@ public class OperatorSizeOf extends OperatorUnary {
 
    /**
     * Get the name of the constant variable containing the size of a specific type
+    *
     * @param type The type to get the variable for
     * @return The name of the constant
     */
    public static String getSizeofConstantName(SymbolType type) {
-      if(type instanceof SymbolTypeMulti) {
-         // Grab the first sub-type. It will be the smallest
-         SymbolType subType = OperatorTypeId.getSubTypeToUse((SymbolTypeMulti) type);
-         return getSizeofConstantName(subType);
-      } else if(type instanceof SymbolTypePointer) {
+      if(type instanceof SymbolTypePointer) {
          return "SIZEOF_POINTER";
       } else {
-         return "SIZEOF_"+type.getTypeName().toUpperCase().replace(" ", "_");
+         return "SIZEOF_" + type.getTypeName().toUpperCase().replace(" ", "_");
       }
    }
 
diff --git a/src/main/java/dk/camelot64/kickc/model/operators/OperatorTypeId.java b/src/main/java/dk/camelot64/kickc/model/operators/OperatorTypeId.java
index df22fc60d..c5dca47db 100644
--- a/src/main/java/dk/camelot64/kickc/model/operators/OperatorTypeId.java
+++ b/src/main/java/dk/camelot64/kickc/model/operators/OperatorTypeId.java
@@ -36,7 +36,7 @@ public class OperatorTypeId extends OperatorUnary {
     * @return The constant variable
     */
    public static ConstantRef getTypeIdConstantVar(ProgramScope programScope, SymbolType type) {
-      String typeConstName = "TYPEID_"+getTypeIdConstantName(type);
+      String typeConstName = "TYPEID_" + getTypeIdConstantName(type);
       ConstantVar typeIdConstant = programScope.getConstant(typeConstName);
       if(typeIdConstant == null) {
          // Constant not found - create it
@@ -54,15 +54,7 @@ public class OperatorTypeId extends OperatorUnary {
     * @return The name of the constant
     */
    private static String getTypeIdConstantName(SymbolType type) {
-      if(type instanceof SymbolTypeMulti) {
-         // Grab the first sub-type. It will be the smallest
-         SymbolType subType = getSubTypeToUse((SymbolTypeMulti) type);
-         if(subType==null) {
-            return "VOID";
-         } else {
-            return getTypeIdConstantName(subType);
-         }
-      } else if(type instanceof SymbolTypeProcedure) {
+      if(type instanceof SymbolTypeProcedure) {
          return "PROCEDURE";
       } else if(type instanceof SymbolTypePointer) {
          return "POINTER_" + getTypeIdConstantName(((SymbolTypePointer) type).getElementType());
@@ -113,33 +105,9 @@ public class OperatorTypeId extends OperatorUnary {
          return 0x0f;
       } else if(type instanceof SymbolTypePointer) {
          return 0x10 + getTypeId(((SymbolTypePointer) type).getElementType());
-      } else if(type instanceof SymbolTypeMulti) {
-         // Return the smallest type ID
-         SymbolType useType = getSubTypeToUse((SymbolTypeMulti) type);
-         if(useType==null) return 0;
-         return getTypeId(useType);
       } else {
          return 0;
       }
    }
 
-   /**
-    * Find the sub-type to use for typeid()
-    * @param type The multi type
-    * @return The sub-type to use
-    */
-   public static SymbolType getSubTypeToUse(SymbolTypeMulti type) {
-      SymbolType useType = null;
-      Integer useID = null;
-      for(SymbolType subType : type.getTypes()) {
-         int subId = getTypeId(subType);
-         if(useType==null || subId < useID) {
-            useType = subType;
-            useID = subId;
-         }
-      }
-      return useType;
-   }
-
-
 }
diff --git a/src/main/java/dk/camelot64/kickc/model/operators/OperatorWord.java b/src/main/java/dk/camelot64/kickc/model/operators/OperatorWord.java
index 1ddc3a770..c84710823 100644
--- a/src/main/java/dk/camelot64/kickc/model/operators/OperatorWord.java
+++ b/src/main/java/dk/camelot64/kickc/model/operators/OperatorWord.java
@@ -3,7 +3,6 @@ package dk.camelot64.kickc.model.operators;
 import dk.camelot64.kickc.model.CompileError;
 import dk.camelot64.kickc.model.types.NoMatchingType;
 import dk.camelot64.kickc.model.types.SymbolType;
-import dk.camelot64.kickc.model.types.SymbolTypePointer;
 import dk.camelot64.kickc.model.types.SymbolTypeSimple;
 import dk.camelot64.kickc.model.values.ConstantInteger;
 import dk.camelot64.kickc.model.values.ConstantLiteral;
@@ -25,7 +24,7 @@ public class OperatorWord extends OperatorBinary {
 
    @Override
    public SymbolType inferType(SymbolTypeSimple left, SymbolTypeSimple right) {
-      if(SymbolType.isByte(left) && SymbolType.isByte(right)) {
+      if(SymbolType.BYTE.equals(left) && SymbolType.BYTE.equals(right)) {
          return SymbolType.WORD;
       }
       throw new NoMatchingType("Word constructor cannot use " + left + " " + getOperator() + " " + right);
diff --git a/src/main/java/dk/camelot64/kickc/model/types/SymbolType.java b/src/main/java/dk/camelot64/kickc/model/types/SymbolType.java
index 71e41be30..34747ed97 100644
--- a/src/main/java/dk/camelot64/kickc/model/types/SymbolType.java
+++ b/src/main/java/dk/camelot64/kickc/model/types/SymbolType.java
@@ -106,66 +106,6 @@ public interface SymbolType {
     */
    int getSizeBytes();
 
-   /**
-    * Is the type {@link #BYTE} or compatible {@link SymbolTypeMulti}
-    *
-    * @param type The type to examine
-    * @return true if the type is BYTE compatible
-    */
-   static boolean isByte(SymbolType type) {
-      return BYTE.equals(type);
-   }
-
-   /**
-    * Is the type {@link #SBYTE} or compatible {@link SymbolTypeMulti}
-    *
-    * @param type The type to examine
-    * @return true if the type is SBYTE compatible
-    */
-   static boolean isSByte(SymbolType type) {
-      return SBYTE.equals(type);
-   }
-
-   /**
-    * Is the type {@link #WORD} or compatible {@link SymbolTypeMulti}
-    *
-    * @param type The type to examine
-    * @return true if the type is WORD compatible
-    */
-   static boolean isWord(SymbolType type) {
-      return WORD.equals(type);
-   }
-
-   /**
-    * Is the type {@link #SWORD} or compatible {@link SymbolTypeMulti}
-    *
-    * @param type The type to examine
-    * @return true if the type is SWORD compatible
-    */
-   static boolean isSWord(SymbolType type) {
-      return SWORD.equals(type);
-   }
-
-   /**
-    * Is the type {@link #DWORD} or compatible {@link SymbolTypeMulti}
-    *
-    * @param type The type to examine
-    * @return true if the type is DWORD compatible
-    */
-   static boolean isDWord(SymbolType type) {
-      return DWORD.equals(type);
-   }
-
-   /**
-    * Is the type {@link #SDWORD} or compatible {@link SymbolTypeMulti}
-    *
-    * @param type The type to examine
-    * @return true if the type is SDWORD compatible
-    */
-   static boolean isSDWord(SymbolType type) {
-      return SDWORD.equals(type);
-   }
-
    /**
     * Is the type an integer type (including {@link #NUMBER})
     *
diff --git a/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeInference.java b/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeInference.java
index 31bf4b7a9..100244aca 100644
--- a/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeInference.java
+++ b/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeInference.java
@@ -148,13 +148,13 @@ public class SymbolTypeInference {
          }
       }
       if(elmType != null) {
-         if((list.getList().size() == 2 && SymbolType.isByte(elmType) || SymbolType.isSByte(elmType))) {
+         if((list.getList().size() == 2 && SymbolType.BYTE.equals(elmType) || SymbolType.SBYTE.equals(elmType))) {
             // Potentially a word constructor - return a composite type
             ArrayList<SymbolType> types = new ArrayList<>();
             types.add(new SymbolTypeArray(elmType));
             types.add(SymbolType.WORD);
             return new SymbolTypeMulti(types);
-         } else if((list.getList().size() == 2 && SymbolType.isWord(elmType))) {
+         } else if((list.getList().size() == 2 && SymbolType.WORD.equals(elmType))) {
             // Potentially a dword constructor - return a composite type
             ArrayList<SymbolType> types = new ArrayList<>();
             types.add(new SymbolTypeArray(elmType));
diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass2FixInlineConstructors.java b/src/main/java/dk/camelot64/kickc/passes/Pass2FixInlineConstructors.java
index 49b6afce4..e13b30941 100644
--- a/src/main/java/dk/camelot64/kickc/passes/Pass2FixInlineConstructors.java
+++ b/src/main/java/dk/camelot64/kickc/passes/Pass2FixInlineConstructors.java
@@ -49,7 +49,7 @@ public class Pass2FixInlineConstructors extends Pass2SsaOptimization {
 
       @Override
       protected boolean isSubType(SymbolType elmType) {
-         return SymbolType.isByte(elmType);
+         return SymbolType.BYTE.equals(elmType);
       }
    }
 
@@ -62,7 +62,7 @@ public class Pass2FixInlineConstructors extends Pass2SsaOptimization {
 
       @Override
       protected boolean isSubType(SymbolType elmType) {
-         return SymbolType.isWord(elmType);
+         return SymbolType.WORD.equals(elmType);
       }
    }
 
diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass2NopCastElimination.java b/src/main/java/dk/camelot64/kickc/passes/Pass2NopCastElimination.java
index a298ad251..b66de4df4 100644
--- a/src/main/java/dk/camelot64/kickc/passes/Pass2NopCastElimination.java
+++ b/src/main/java/dk/camelot64/kickc/passes/Pass2NopCastElimination.java
@@ -40,19 +40,19 @@ public class Pass2NopCastElimination extends Pass2SsaOptimization {
                   SymbolType rValType = SymbolTypeInference.inferType(getScope(), assignment.getrValue2());
                   boolean isNopCast = false;
                   SymbolType toType = null;
-                  if(SymbolType.isByte(rValType) && Operators.CAST_SBYTE.equals(assignment.getOperator())) {
+                  if(SymbolType.BYTE.equals(rValType) && Operators.CAST_SBYTE.equals(assignment.getOperator())) {
                      isNopCast = true;
                      toType = SymbolType.SBYTE;
-                  } else if(SymbolType.isSByte(rValType) && Operators.CAST_BYTE.equals(assignment.getOperator())) {
+                  } else if(SymbolType.SBYTE.equals(rValType) && Operators.CAST_BYTE.equals(assignment.getOperator())) {
                      isNopCast = true;
                      toType = SymbolType.BYTE;
-                  } else if(SymbolType.isWord(rValType) && Operators.CAST_SWORD.equals(assignment.getOperator())) {
+                  } else if(SymbolType.WORD.equals(rValType) && Operators.CAST_SWORD.equals(assignment.getOperator())) {
                      isNopCast = true;
                      toType = SymbolType.SWORD;
-                  } else if(SymbolType.isSWord(rValType) && Operators.CAST_WORD.equals(assignment.getOperator())) {
+                  } else if(SymbolType.SWORD.equals(rValType) && Operators.CAST_WORD.equals(assignment.getOperator())) {
                      isNopCast = true;
                      toType = SymbolType.WORD;
-                  } else if(SymbolType.isWord(rValType) && assignment.getOperator() instanceof OperatorCastPtr) {
+                  } else if(SymbolType.WORD.equals(rValType) && assignment.getOperator() instanceof OperatorCastPtr) {
                      isNopCast = true;
                      OperatorCastPtr castOperator = (OperatorCastPtr) (assignment.getOperator());
                      toType = new SymbolTypePointer(castOperator.getElementType());
diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass4CodeGeneration.java b/src/main/java/dk/camelot64/kickc/passes/Pass4CodeGeneration.java
index 630581697..e758eb361 100644
--- a/src/main/java/dk/camelot64/kickc/passes/Pass4CodeGeneration.java
+++ b/src/main/java/dk/camelot64/kickc/passes/Pass4CodeGeneration.java
@@ -387,13 +387,13 @@ public class Pass4CodeGeneration {
                   String asmElement = AsmFormat.getAsmConstant(program, element, 99, scopeRef);
                   asmElements.add(asmElement);
                }
-               if(SymbolType.isByte(elementType) || SymbolType.isSByte(elementType)) {
+               if(SymbolType.BYTE.equals(elementType) || SymbolType.SBYTE.equals(elementType)) {
                   asm.addDataNumeric(asmName.replace("#", "_").replace("$", "_"), AsmDataNumeric.Type.BYTE, asmElements);
                   added.add(asmName);
-               } else if(SymbolType.isWord(elementType) || SymbolType.isSWord(elementType)) {
+               } else if(SymbolType.WORD.equals(elementType) || SymbolType.SWORD.equals(elementType)) {
                   asm.addDataNumeric(asmName.replace("#", "_").replace("$", "_"), AsmDataNumeric.Type.WORD, asmElements);
                   added.add(asmName);
-               } else if(SymbolType.isDWord(elementType) || SymbolType.isSDWord(elementType)) {
+               } else if(SymbolType.DWORD.equals(elementType) || SymbolType.SDWORD.equals(elementType)) {
                   asm.addDataNumeric(asmName.replace("#", "_").replace("$", "_"), AsmDataNumeric.Type.DWORD, asmElements);
                   added.add(asmName);
                } else if(elementType instanceof SymbolTypePointer) {
@@ -410,27 +410,27 @@ public class Pass4CodeGeneration {
                   throw new Pass2SsaAssertion.AssertionFailed("Error! Array size is not constant integer " + constantVar.toString(program));
                }
                int size = ((ConstantInteger) arraySizeConst).getInteger().intValue();
-               if(SymbolType.isByte(constantArrayFilled.getElementType())) {
+               if(SymbolType.BYTE.equals(constantArrayFilled.getElementType())) {
                   String asmSize = AsmFormat.getAsmConstant(program, arraySize, 99, scopeRef);
                   asm.addDataFilled(asmName.replace("#", "_").replace("$", "_"), AsmDataNumeric.Type.BYTE, asmSize, size, "0");
                   added.add(asmName);
-               } else if(SymbolType.isSByte(constantArrayFilled.getElementType())) {
+               } else if(SymbolType.SBYTE.equals(constantArrayFilled.getElementType())) {
                   String asmSize = AsmFormat.getAsmConstant(program, arraySize, 99, scopeRef);
                   asm.addDataFilled(asmName.replace("#", "_").replace("$", "_"), AsmDataNumeric.Type.BYTE, asmSize, size, "0");
                   added.add(asmName);
-               } else if(SymbolType.isWord(constantArrayFilled.getElementType())) {
+               } else if(SymbolType.WORD.equals(constantArrayFilled.getElementType())) {
                   String asmSize = AsmFormat.getAsmConstant(program, new ConstantBinary(new ConstantInteger(2L), Operators.MULTIPLY, arraySize), 99, scopeRef);
                   asm.addDataFilled(asmName.replace("#", "_").replace("$", "_"), AsmDataNumeric.Type.WORD, asmSize, size, "0");
                   added.add(asmName);
-               } else if(SymbolType.isSWord(constantArrayFilled.getElementType())) {
+               } else if(SymbolType.SWORD.equals(constantArrayFilled.getElementType())) {
                   String asmSize = AsmFormat.getAsmConstant(program, new ConstantBinary(new ConstantInteger(2L), Operators.MULTIPLY, arraySize), 99, scopeRef);
                   asm.addDataFilled(asmName.replace("#", "_").replace("$", "_"), AsmDataNumeric.Type.WORD, asmSize, size, "0");
                   added.add(asmName);
-               } else if(SymbolType.isDWord(constantArrayFilled.getElementType())) {
+               } else if(SymbolType.DWORD.equals(constantArrayFilled.getElementType())) {
                   String asmSize = AsmFormat.getAsmConstant(program, new ConstantBinary(new ConstantInteger(4L), Operators.MULTIPLY, arraySize), 99, scopeRef);
                   asm.addDataFilled(asmName.replace("#", "_").replace("$", "_"), AsmDataNumeric.Type.DWORD, asmSize, size, "0");
                   added.add(asmName);
-               } else if(SymbolType.isSDWord(constantArrayFilled.getElementType())) {
+               } else if(SymbolType.SDWORD.equals(constantArrayFilled.getElementType())) {
                   String asmSize = AsmFormat.getAsmConstant(program, new ConstantBinary(new ConstantInteger(4L), Operators.MULTIPLY, arraySize), 99, scopeRef);
                   asm.addDataFilled(asmName.replace("#", "_").replace("$", "_"), AsmDataNumeric.Type.DWORD, asmSize, size, "0");
                   added.add(asmName);
diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass4RegistersFinalize.java b/src/main/java/dk/camelot64/kickc/passes/Pass4RegistersFinalize.java
index 157b04ca7..e36e1348a 100644
--- a/src/main/java/dk/camelot64/kickc/passes/Pass4RegistersFinalize.java
+++ b/src/main/java/dk/camelot64/kickc/passes/Pass4RegistersFinalize.java
@@ -195,23 +195,23 @@ public class Pass4RegistersFinalize extends Pass2Base {
     */
    private Registers.Register allocateNewRegisterZp(Variable variable) {
       SymbolType varType = variable.getType();
-      if(SymbolType.isByte(varType)) {
+      if(SymbolType.BYTE.equals(varType)) {
          return new Registers.RegisterZpByte(allocateZp((1)));
-      } else if(SymbolType.isSByte(varType)) {
+      } else if(SymbolType.SBYTE.equals(varType)) {
          return new Registers.RegisterZpByte(allocateZp(1));
-      } else if(SymbolType.isWord(varType)) {
+      } else if(SymbolType.WORD.equals(varType)) {
          Registers.RegisterZpWord registerZpWord =
                new Registers.RegisterZpWord(allocateZp(2));
          return registerZpWord;
-      } else if(SymbolType.isSWord(varType)) {
+      } else if(SymbolType.SWORD.equals(varType)) {
          Registers.RegisterZpWord registerZpWord =
                new Registers.RegisterZpWord(allocateZp(2));
          return registerZpWord;
-      } else if(SymbolType.isDWord(varType)) {
+      } else if(SymbolType.DWORD.equals(varType)) {
          Registers.RegisterZpDWord registerZpDWord =
                new Registers.RegisterZpDWord(allocateZp(4));
          return registerZpDWord;
-      } else if(SymbolType.isSDWord(varType)) {
+      } else if(SymbolType.SDWORD.equals(varType)) {
          Registers.RegisterZpDWord registerZpDWord =
                new Registers.RegisterZpDWord(allocateZp(4));
          return registerZpDWord;