- Updated `ParserException` to have a sub-error type `ParserErrorType`
- Updated `SyntaxError` to overwrite the exception's `msg` field
- Added literal encoding for integer support to parser

Typechecker

- Removed exception check which is now redundant seeing as literal overflows would be checked within the parser (way before typechecking begins)
- Added conversion support (type transfers) for the `LiteralValue` instruction codegen
- Removed uneeded sub-error type in `TypeCheckerException`'s `TypecheckError` (rempved `TypecheckError.LITERAL_OVERFLOW`)
compiler_object
parent f7a4091620
commit 18b784f861

@ -1,7 +1,7 @@
module compiler.parsing.core;
import gogga;
import std.conv : to;
import std.conv : to, ConvException;
import std.string : isNumeric, cmp;
import compiler.symbols.check;
import compiler.symbols.data;
@ -1142,7 +1142,37 @@ public final class Parser
// TODO: Issue #94, we should be checking the range here
// ... along with any explicit encoders and setting it
// ... for now default to SIGNED_INTEGER.
numberLiteral = new IntegerLiteral(getCurrentToken().getToken(), IntegerLiteralEncoding.SIGNED_INTEGER);
// TODO (X-platform): Use `size_t` here
// TODO (Redundant-later): Since we check here, remove the conv check in the typechecker!
// TODO: Add a check for the `U`, `UL` stuff here
try
{
ulong literalValue = to!(ulong)(numberLiteralStr);
IntegerLiteralEncoding chosenEncoding;
// Signed integer range [0, 2_147_483_647]
if(literalValue >= 0 && literalValue <= 2_147_483_647)
{
chosenEncoding = IntegerLiteralEncoding.SIGNED_INTEGER;
}
// Signed long range [2_147_483_648, 9_223_372_036_854_775_807]
else if(literalValue >= 2_147_483_648 && literalValue <= 9_223_372_036_854_775_807)
{
chosenEncoding = IntegerLiteralEncoding.SIGNED_LONG;
}
// Unsigned long range [9_223_372_036_854_775_808, 18_446_744_073_709_551_615]
else
{
chosenEncoding = IntegerLiteralEncoding.UNSIGNED_LONG;
}
numberLiteral = new IntegerLiteral(getCurrentToken().getToken(), chosenEncoding);
}
catch(ConvException e)
{
throw new ParserException(this, ParserException.ParserErrorType.LITERAL_OVERFLOW, "Literal '"~numberLiteralStr~"' would overflow");
}
}
/* Add expression to stack */

@ -11,9 +11,15 @@ public class ParserException : TError
{
private Parser parser;
this(Parser parser, string message)
public enum ParserErrorType
{
super(message);
GENERAL_ERROR,
LITERAL_OVERFLOW
}
this(Parser parser, ParserErrorType errType = ParserErrorType.GENERAL_ERROR, string message = "")
{
super("ParserException("~to!(string)(errType)~"): "~message);
this.parser = parser;
}
}
@ -30,6 +36,8 @@ public final class SyntaxError : ParserException
this.provided = getSymbolType(providedToken);
this.providedToken = providedToken;
super(parser, "Syntax error: Expected "~to!(string)(expected)~" but got "~to!(string)(provided)~", see "~providedToken.toString());
super(parser);
msg = "Syntax error: Expected "~to!(string)(expected)~" but got "~to!(string)(provided)~", see "~providedToken.toString();
}
}

@ -364,66 +364,60 @@ public final class TypeChecker
LiteralValue integerLiteral = cast(LiteralValue)literalInstr;
string literal = integerLiteral.getLiteralValue();
try
{
ulong literalValue = to!(ulong)(literal); // TODO: Catch conversion exception when the literal is too big for `ulong`
// NOTE (X-platform): For cross-platform sake we should change the `ulong` to `size_t`
ulong literalValue = to!(ulong)(literal);
if(isSameType(toType, getType(null, "ubyte")))
if(isSameType(toType, getType(null, "ubyte")))
{
if(literalValue >= 0 && literalValue <= 255)
{
if(literalValue >= 0 && literalValue <= 255)
{
// Valid coercion
return true;
}
else
{
// Invalid coercion
return false;
}
// Valid coercion
return true;
}
else if(isSameType(toType, getType(null, "ushort")))
else
{
if(literalValue >= 0 && literalValue <= 65_535)
{
// Valid coercion
return true;
}
else
{
// Invalid coercion
return false;
}
// Invalid coercion
return false;
}
else if(isSameType(toType, getType(null, "uint")))
}
else if(isSameType(toType, getType(null, "ushort")))
{
if(literalValue >= 0 && literalValue <= 65_535)
{
if(literalValue >= 0 && literalValue <= 4_294_967_295)
{
// Valid coercion
return true;
}
else
{
// Invalid coercion
return false;
}
// Valid coercion
return true;
}
else if(isSameType(toType, getType(null, "ulong")))
else
{
if(literalValue >= 0 && literalValue <= 18446744073709551615)
{
// Valid coercion
return true;
}
else
{
// Invalid coercion
return false;
}
// Invalid coercion
return false;
}
}
else if(isSameType(toType, getType(null, "uint")))
{
if(literalValue >= 0 && literalValue <= 4_294_967_295)
{
// Valid coercion
return true;
}
else
{
// Invalid coercion
return false;
}
}
catch(ConvException e)
else if(isSameType(toType, getType(null, "ulong")))
{
throw new TypeCheckerException(this, TypeCheckerException.TypecheckError.LITERAL_OVERFLOW, "Overflow when processing literal '"~literal~"'");
if(literalValue >= 0 && literalValue <= 18446744073709551615)
{
// Valid coercion
return true;
}
else
{
// Invalid coercion
return false;
}
}
}
// LiteralValue (integer literal instructions)
@ -588,6 +582,18 @@ public final class TypeChecker
{
literalEncodingType = getType(modulle, "int");
}
else if(integerLitreal.getEncoding() == IntegerLiteralEncoding.UNSIGNED_INTEGER)
{
literalEncodingType = getType(modulle, "uint");
}
else if(integerLitreal.getEncoding() == IntegerLiteralEncoding.SIGNED_LONG)
{
literalEncodingType = getType(modulle, "long");
}
else if(integerLitreal.getEncoding() == IntegerLiteralEncoding.UNSIGNED_LONG)
{
literalEncodingType = getType(modulle, "ulong");
}
assert(literalEncodingType);
// TODO: Insert getEncoding stuff here

@ -16,8 +16,7 @@ public class TypeCheckerException : TError
// ... in sub-classes of this
public enum TypecheckError
{
GENERAL_ERROR,
LITERAL_OVERFLOW
GENERAL_ERROR
}
this(TypeChecker typeChecker, TypecheckError errType, string msg = "")

Loading…
Cancel
Save