Browse Source

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
constants
Tristan B. V. Kildaire 6 months ago
parent
commit
7e49cf1d0a
  1. 16
      source/tlang/compiler/codegen/instruction.d
  2. 64
      source/tlang/compiler/lexer.d
  3. 33
      source/tlang/compiler/typecheck/core.d
  4. 4
      source/tlang/testing/typecheck/simple_float_constant_bad.t

16
source/tlang/compiler/codegen/instruction.d

@ -95,6 +95,7 @@ public final class FetchValueVar : Value
}
}
/* Used for integers */
public final class LiteralValue : Value
{
/* 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 */
/**
* TODO: This should take in:

64
source/tlang/compiler/lexer.d

@ -52,6 +52,7 @@ public final class Lexer
private ulong position; /* Current character position */
private char currentChar; /* Current character */
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 */
private Token[] tokens;
@ -108,7 +109,38 @@ public final class Lexer
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 */
if(currentToken.length != 0)
@ -128,8 +160,23 @@ public final class Lexer
gprintln("Build up: "~currentToken);
gprintln("Current char: "~currentChar);
/* FIXME: Add floating point support here */
/* 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 */
public Token[] getTokens()

33
source/tlang/compiler/typecheck/core.d

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

4
source/tlang/testing/typecheck/simple_float_constant_bad.t

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