diff --git a/src/main/java/dk/camelot64/kickc/model/symbols/EnumDefinition.java b/src/main/java/dk/camelot64/kickc/model/symbols/EnumDefinition.java index f454b972d..78742232e 100644 --- a/src/main/java/dk/camelot64/kickc/model/symbols/EnumDefinition.java +++ b/src/main/java/dk/camelot64/kickc/model/symbols/EnumDefinition.java @@ -13,7 +13,7 @@ public class EnumDefinition extends Scope { @Override public SymbolType getType() { - return new SymbolTypeEnum(this); + return new SymbolTypeEnum(this, false, false); } @Override diff --git a/src/main/java/dk/camelot64/kickc/model/symbols/StructDefinition.java b/src/main/java/dk/camelot64/kickc/model/symbols/StructDefinition.java index 3e5f29fa0..c09c9b14f 100644 --- a/src/main/java/dk/camelot64/kickc/model/symbols/StructDefinition.java +++ b/src/main/java/dk/camelot64/kickc/model/symbols/StructDefinition.java @@ -15,7 +15,7 @@ public class StructDefinition extends Scope { @Override public SymbolType getType() { - return new SymbolTypeStruct(this); + return new SymbolTypeStruct(this, false, false); } /** 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 669e02f63..cabdd4966 100644 --- a/src/main/java/dk/camelot64/kickc/model/types/SymbolType.java +++ b/src/main/java/dk/camelot64/kickc/model/types/SymbolType.java @@ -5,18 +5,24 @@ import java.io.Serializable; /** Symbol Types */ public interface SymbolType extends Serializable { + /** Specifies that the value of the variable may change at any time, so the optimizer must not make assumptions. The variable must always live in memory to be available for any multi-threaded access (eg. in interrupts). (volatile keyword) */ + boolean isVolatile(); + + /** Specifies that the variable is not allowed to be modified (const keyword). The compiler should try to detect modifications and generate compile-time errors if they occur.*/ + boolean isNomodify(); + /** Unsigned byte (8 bits)). */ - SymbolTypeIntegerFixed BYTE = new SymbolTypeIntegerFixed("byte", 0, 255, false, 8); + SymbolTypeIntegerFixed BYTE = new SymbolTypeIntegerFixed("byte", 0, 255, false, 8, false, false); /** Signed byte (8 bits). */ - SymbolTypeIntegerFixed SBYTE = new SymbolTypeIntegerFixed("signed byte", -128, 127, true, 8); + SymbolTypeIntegerFixed SBYTE = new SymbolTypeIntegerFixed("signed byte", -128, 127, true, 8, false, false); /** Unsigned word (2 bytes, 16 bits). */ - SymbolTypeIntegerFixed WORD = new SymbolTypeIntegerFixed("word", 0, 65_535, false, 16); + SymbolTypeIntegerFixed WORD = new SymbolTypeIntegerFixed("word", 0, 65_535, false, 16, false, false); /** Signed word (2 bytes, 16 bits). */ - SymbolTypeIntegerFixed SWORD = new SymbolTypeIntegerFixed("signed word", -32_768, 32_767, true, 16); + SymbolTypeIntegerFixed SWORD = new SymbolTypeIntegerFixed("signed word", -32_768, 32_767, true, 16, false, false); /** Unsigned double word (4 bytes, 32 bits). */ - SymbolTypeIntegerFixed DWORD = new SymbolTypeIntegerFixed("dword", 0, 4_294_967_296L, false, 32); + SymbolTypeIntegerFixed DWORD = new SymbolTypeIntegerFixed("dword", 0, 4_294_967_296L, false, 32, false, false); /** Signed double word (4 bytes, 32 bits). */ - SymbolTypeIntegerFixed SDWORD = new SymbolTypeIntegerFixed("signed dword", -2_147_483_648, 2_147_483_647, true, 32); + SymbolTypeIntegerFixed SDWORD = new SymbolTypeIntegerFixed("signed dword", -2_147_483_648, 2_147_483_647, true, 32, false, false); /** Integer with unknown size and unknown signedness (used for constant expressions). */ SymbolTypeIntegerAuto NUMBER = new SymbolTypeIntegerAuto("number"); /** Unsigned integer with unknown size (used for constant expressions). */ @@ -24,15 +30,15 @@ public interface SymbolType extends Serializable { /** Signed integer with unknown size (used for constant expressions). */ SymbolTypeIntegerAuto SNUMBER = new SymbolTypeIntegerAuto("snumber"); /** Boolean value. */ - SymbolTypeNamed BOOLEAN = new SymbolTypeNamed("bool", 1); + SymbolTypeNamed BOOLEAN = new SymbolTypeNamed("bool", 1, false, false); /** Numeric floating point value. */ - SymbolTypeNamed DOUBLE = new SymbolTypeNamed("double", 1); + SymbolTypeNamed DOUBLE = new SymbolTypeNamed("double", 1, false, false); /** A label. Name of functions of jump-targets. */ - SymbolTypeNamed LABEL = new SymbolTypeNamed("label", 1); + SymbolTypeNamed LABEL = new SymbolTypeNamed("label", 1, false, false); /** Void type representing no value. */ - SymbolTypeNamed VOID = new SymbolTypeNamed("void", 0); + SymbolTypeNamed VOID = new SymbolTypeNamed("void", 0, false, false); /** An unresolved type. Will be infered later. */ - SymbolTypeNamed VAR = new SymbolTypeNamed("var", -1); + SymbolTypeNamed VAR = new SymbolTypeNamed("var", -1, false, false); /** * Get a simple symbol type from the type name. @@ -43,45 +49,30 @@ public interface SymbolType extends Serializable { static SymbolType get(String name) { switch(name) { case "byte": - return BYTE; case "unsigned byte": - return BYTE; - case "signed byte": - return SBYTE; case "char": - return BYTE; case "unsigned char": return BYTE; + case "signed byte": case "signed char": return SBYTE; case "word": - return WORD; case "unsigned word": - return WORD; - case "signed word": - return SWORD; - case "short": - return SWORD; case "unsigned short": - return WORD; - case "signed short": - return SWORD; - case "int": - return SWORD; case "unsigned int": return WORD; + case "signed word": + case "short": + case "signed short": + case "int": case "signed int": return SWORD; case "dword": - return DWORD; case "unsigned dword": - return DWORD; - case "signed dword": - return SDWORD; - case "long": - return SDWORD; case "unsigned long": return DWORD; + case "signed dword": + case "long": case "signed long": return SDWORD; case "bool": @@ -94,7 +85,6 @@ public interface SymbolType extends Serializable { return null; } - /** * Get the name of the type * diff --git a/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeBlockScope.java b/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeBlockScope.java index 4fc97f3cb..476b28041 100644 --- a/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeBlockScope.java +++ b/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeBlockScope.java @@ -12,6 +12,16 @@ public class SymbolTypeBlockScope implements SymbolType { return "BLOCK"; } + @Override + public boolean isVolatile() { + return false; + } + + @Override + public boolean isNomodify() { + return false; + } + @Override public int getSizeBytes() { return -1; diff --git a/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeEnum.java b/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeEnum.java index 3cec3e46e..f321bc604 100644 --- a/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeEnum.java +++ b/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeEnum.java @@ -13,9 +13,24 @@ public class SymbolTypeEnum implements SymbolType { /** The enum definition. */ private EnumDefinition definition; - public SymbolTypeEnum(EnumDefinition definition) { + private final boolean isVolatile; + private final boolean isNomodify; + + public SymbolTypeEnum(EnumDefinition definition, boolean isVolatile, boolean isNomodify) { this.definition = definition; this.name = definition.getLocalName(); + this.isVolatile = isVolatile; + this.isNomodify = isNomodify; + } + + @Override + public boolean isVolatile() { + return isVolatile; + } + + @Override + public boolean isNomodify() { + return isNomodify; } @Override diff --git a/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeIntegerAuto.java b/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeIntegerAuto.java index 6e643aad8..99cc35d95 100644 --- a/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeIntegerAuto.java +++ b/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeIntegerAuto.java @@ -11,6 +11,16 @@ public class SymbolTypeIntegerAuto implements SymbolTypeInteger { this.typeName = typeName; } + @Override + public boolean isVolatile() { + return false; + } + + @Override + public boolean isNomodify() { + return false; + } + @Override public String getTypeName() { return typeName; @@ -26,7 +36,6 @@ public class SymbolTypeIntegerAuto implements SymbolTypeInteger { return getTypeName(); } - @Override public boolean equals(Object o) { if(this == o) return true; diff --git a/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeIntegerFixed.java b/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeIntegerFixed.java index 506d0e7d9..0088f6010 100644 --- a/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeIntegerFixed.java +++ b/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeIntegerFixed.java @@ -12,13 +12,17 @@ public class SymbolTypeIntegerFixed implements SymbolTypeInteger { private final long maxValue; private final boolean signed; private final int bits; + private final boolean isVolatile; + private final boolean isNomodify; - SymbolTypeIntegerFixed(String typeName, long minValue, long maxValue, boolean signed, int bits) { + SymbolTypeIntegerFixed(String typeName, long minValue, long maxValue, boolean signed, int bits, boolean isVolatile, boolean isNomodify) { this.typeName = typeName; this.minValue = minValue; this.maxValue = maxValue; this.signed = signed; this.bits = bits; + this.isVolatile = isVolatile; + this.isNomodify = isNomodify; } /** @@ -62,6 +66,15 @@ public class SymbolTypeIntegerFixed implements SymbolTypeInteger { return null; } + @Override + public boolean isVolatile() { + return isVolatile; + } + + @Override + public boolean isNomodify() { + return isNomodify; + } /** * Determines if a value can be represented by the type without loss of information diff --git a/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeNamed.java b/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeNamed.java index 5578a24bf..e04caff74 100644 --- a/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeNamed.java +++ b/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeNamed.java @@ -4,12 +4,25 @@ package dk.camelot64.kickc.model.types; public class SymbolTypeNamed implements SymbolType { private String typeName; - private int sizeBytes; + private final boolean isVolatile; + private final boolean isNomodify; - SymbolTypeNamed(String typeName, int sizeBytes) { + SymbolTypeNamed(String typeName, int sizeBytes, boolean isVolatile, boolean isNomodify) { this.typeName = typeName; this.sizeBytes = sizeBytes; + this.isVolatile = isVolatile; + this.isNomodify = isNomodify; + } + + @Override + public boolean isVolatile() { + return isVolatile; + } + + @Override + public boolean isNomodify() { + return isNomodify; } public String getTypeName() { diff --git a/src/main/java/dk/camelot64/kickc/model/types/SymbolTypePointer.java b/src/main/java/dk/camelot64/kickc/model/types/SymbolTypePointer.java index 7c8bcadca..bdb916c87 100644 --- a/src/main/java/dk/camelot64/kickc/model/types/SymbolTypePointer.java +++ b/src/main/java/dk/camelot64/kickc/model/types/SymbolTypePointer.java @@ -15,13 +15,29 @@ public class SymbolTypePointer implements SymbolType { /** If non-null the pointer is an array. */ private ArraySpec arraySpec; - public SymbolTypePointer(SymbolType elementType, ArraySpec arraySpec) { + private final boolean isVolatile; + private final boolean isNomodify; + + + public SymbolTypePointer(SymbolType elementType, ArraySpec arraySpec, boolean isVolatile, boolean isNomodify) { this.elementType = elementType; this.arraySpec = arraySpec; + this.isVolatile = isVolatile; + this.isNomodify = isNomodify; } public SymbolTypePointer(SymbolType elementType) { - this(elementType, null); + this(elementType, null, false, false); + } + + @Override + public boolean isVolatile() { + return false; + } + + @Override + public boolean isNomodify() { + return false; } public SymbolType getElementType() { diff --git a/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeProcedure.java b/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeProcedure.java index f38c140db..552bedda8 100644 --- a/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeProcedure.java +++ b/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeProcedure.java @@ -11,6 +11,16 @@ public class SymbolTypeProcedure implements SymbolType { this.returnType = returnType; } + @Override + public boolean isVolatile() { + return false; + } + + @Override + public boolean isNomodify() { + return false; + } + @Override public int getSizeBytes() { return -1; diff --git a/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeProgram.java b/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeProgram.java index 186ba98b5..2b362b20c 100644 --- a/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeProgram.java +++ b/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeProgram.java @@ -7,6 +7,16 @@ public class SymbolTypeProgram implements SymbolType { } + @Override + public boolean isVolatile() { + return false; + } + + @Override + public boolean isNomodify() { + return false; + } + @Override public String getTypeName() { return "PROGRAM"; diff --git a/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeStruct.java b/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeStruct.java index 6af936c60..0cf8548b8 100644 --- a/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeStruct.java +++ b/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeStruct.java @@ -18,9 +18,24 @@ public class SymbolTypeStruct implements SymbolType { /** Size of the struct in bytes. */ private int sizeBytes; - public SymbolTypeStruct(StructDefinition structDefinition) { + private final boolean isVolatile; + private final boolean isNomodify; + + public SymbolTypeStruct(StructDefinition structDefinition, boolean isVolatile, boolean isNomodify) { this.name = structDefinition.getLocalName(); this.sizeBytes = calculateSizeBytes(structDefinition, null); + this.isVolatile = isVolatile; + this.isNomodify = isNomodify; + } + + @Override + public boolean isVolatile() { + return isVolatile; + } + + @Override + public boolean isNomodify() { + return isNomodify; } @Override diff --git a/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeTypeDefScope.java b/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeTypeDefScope.java index 7f38cfe17..25356a172 100644 --- a/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeTypeDefScope.java +++ b/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeTypeDefScope.java @@ -7,6 +7,16 @@ public class SymbolTypeTypeDefScope implements SymbolType { } + @Override + public boolean isVolatile() { + return false; + } + + @Override + public boolean isNomodify() { + return false; + } + @Override public String getTypeName() { return "TYPEDEF"; diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass0GenerateStatementSequence.java b/src/main/java/dk/camelot64/kickc/passes/Pass0GenerateStatementSequence.java index c2d5dbde7..e1d23a067 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass0GenerateStatementSequence.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass0GenerateStatementSequence.java @@ -980,7 +980,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor