Added float support

- Added float constant support to the lexer
- Added float support to the typechecker to build the correct Instruction type

Unit tests

- Added unit test for a bad example of a malformed encoded floating point to test out the lexer
This commit is contained in:
Tristan B. Velloza Kildaire 2022-08-11 10:26:30 +02:00
parent 2dbe14b490
commit 7e49cf1d0a
4 changed files with 111 additions and 6 deletions

View File

@ -95,6 +95,7 @@ public final class FetchValueVar : Value
} }
} }
/* Used for integers */
public final class LiteralValue : Value public final class LiteralValue : Value
{ {
/* Data */ /* Data */
@ -110,6 +111,21 @@ public final class LiteralValue : Value
} }
} }
public final class LiteralValueFloat : Value
{
/* Data */
public double data; /* TODO: Is this best way to store? Consirring floats/doubles */
public byte len;
this(double data, byte len)
{
this.data = data;
this.len = len;
addInfo = "Data: "~to!(string)(data)~", Length: "~to!(string)(len);
}
}
/* FIXME: Implement this */ /* FIXME: Implement this */
/** /**
* TODO: This should take in: * TODO: This should take in:

View File

@ -52,6 +52,7 @@ public final class Lexer
private ulong position; /* Current character position */ private ulong position; /* Current character position */
private char currentChar; /* Current character */ private char currentChar; /* Current character */
private bool stringMode; /* Whether we are in a string "we are here" or not */ private bool stringMode; /* Whether we are in a string "we are here" or not */
private bool floatMode; /* Whether or not we are building a floating point constant */
/* The tokens */ /* The tokens */
private Token[] tokens; private Token[] tokens;
@ -108,7 +109,38 @@ public final class Lexer
currentChar = sourceCode[position]; currentChar = sourceCode[position];
if(currentChar == ' ' && !stringMode) if(floatMode == true)
{
if(isDigit(currentChar))
{
/* tack on and move to next iteration */
currentToken~=currentChar;
position++;
column++;
continue;
}
/* TODO; handle closer case and error case */
else
{
/* TODO: Throw erropr here */
if(isSpliter(currentChar))
{
floatMode = false;
currentTokens ~= new Token(currentToken, line, column);
currentToken = "";
/* We just flush and catch splitter in next round, hence below is commented out */
// column++;
// position++;
}
else
{
gprintln("Floating point '"~currentToken~"' cannot be followed by a '"~currentChar~"'", DebugType.ERROR);
return false;
}
}
}
else if(currentChar == ' ' && !stringMode)
{ {
/* TODO: Check if current token is fulled, then flush */ /* TODO: Check if current token is fulled, then flush */
if(currentToken.length != 0) if(currentToken.length != 0)
@ -128,8 +160,23 @@ public final class Lexer
gprintln("Build up: "~currentToken); gprintln("Build up: "~currentToken);
gprintln("Current char: "~currentChar); gprintln("Current char: "~currentChar);
/* FIXME: Add floating point support here */ /* FIXME: Add floating point support here */
/* TODO: IF buildUp is all numerical and we have dot go into float mode */ /* TODO: IF buildUp is all numerical and we have dot go into float mode */
/* TODO: Error checking will need to be added */
if(isNumericalStr(currentToken) && currentChar == '.')
{
/* Tack on the dot */
currentToken~=".";
/* Enable floating point mode and go to next iteration*/
floatMode = true;
gprintln("Halo");
column++;
position++;
continue;
}
/** /**
@ -536,6 +583,21 @@ public final class Lexer
} }
private static bool isNumericalStr(string input)
{
for(ulong i = 0; i < input.length; i++)
{
char character = input[i];
if(!isDigit(character))
{
return false;
}
}
return true;
}
/* Return the tokens */ /* Return the tokens */
public Token[] getTokens() public Token[] getTokens()

View File

@ -262,16 +262,39 @@ public final class TypeChecker
/** /**
* Typechecking * Typechecking
*
* TODO: Find the type of literal. Integer v.s. floating point
*/ */
gprintln("NUMBER LIT"); NumberLiteral numLit = cast(NumberLiteral)statement;
addType(getType(modulle, "int")); import std.string : indexOf;
bool isFloat = indexOf(numLit.getNumber(), ".") > -1;
gprintln("NUMBER LIT: isFloat: "~to!(string)(isFloat));
addType(getType(modulle, isFloat ? "float" : "int"));
/** /**
* Codegen * Codegen
*
* FIXME: Add support for floats
* TODO: We just assume (for integers) byte size 4?
*/ */
ulong i = to!(ulong)((cast(NumberLiteral)statement).getNumber()); Value valInstr;
LiteralValue litValInstr = new LiteralValue(i, 4);
addInstr(litValInstr); if(!isFloat)
{
ulong i = to!(ulong)((cast(NumberLiteral)statement).getNumber());
LiteralValue litValInstr = new LiteralValue(i, 4);
valInstr = litValInstr;
}
else
{
double i = to!(float)((cast(NumberLiteral)statement).getNumber());
LiteralValueFloat litValInstr = new LiteralValueFloat(i, 4);
valInstr = litValInstr;
}
addInstr(valInstr);
} }
/* String literal */ /* String literal */
else if(cast(StringExpression)statement) else if(cast(StringExpression)statement)

View File

@ -0,0 +1,4 @@
module simple;
float f1 = 1.4d;
double f2 = 1.4f;