literal fix
This commit is contained in:
@@ -69,17 +69,17 @@ public static class ConsoleColors
|
|||||||
case IdentifierToken:
|
case IdentifierToken:
|
||||||
return White;
|
return White;
|
||||||
case LiteralToken literal:
|
case LiteralToken literal:
|
||||||
if (literal.Type.Equals(NubPrimitiveType.String))
|
if (literal.Kind.Equals(NubPrimitiveType.String))
|
||||||
{
|
{
|
||||||
return Green;
|
return Green;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (literal.Type.Equals(NubPrimitiveType.I64) || literal.Type.Equals(NubPrimitiveType.F64))
|
if (literal.Kind.Equals(NubPrimitiveType.I64) || literal.Kind.Equals(NubPrimitiveType.F64))
|
||||||
{
|
{
|
||||||
return BrightBlue;
|
return BrightBlue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (literal.Type.Equals(NubPrimitiveType.Bool))
|
if (literal.Kind.Equals(NubPrimitiveType.Bool))
|
||||||
{
|
{
|
||||||
return Blue;
|
return Blue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using Nub.Lang.Frontend.Lexing;
|
||||||
using Nub.Lang.Frontend.Parsing;
|
using Nub.Lang.Frontend.Parsing;
|
||||||
using Nub.Lang.Frontend.Parsing.Definitions;
|
using Nub.Lang.Frontend.Parsing.Definitions;
|
||||||
using Nub.Lang.Frontend.Parsing.Expressions;
|
using Nub.Lang.Frontend.Parsing.Expressions;
|
||||||
@@ -15,7 +16,7 @@ public class Generator
|
|||||||
|
|
||||||
private List<SourceFile> _sourceFiles = [];
|
private List<SourceFile> _sourceFiles = [];
|
||||||
private StringBuilder _builder = new();
|
private StringBuilder _builder = new();
|
||||||
private Dictionary<string, Variable> _variables = [];
|
private Dictionary<string, string> _variables = [];
|
||||||
private List<string> _strings = [];
|
private List<string> _strings = [];
|
||||||
private Stack<string> _breakLabels = [];
|
private Stack<string> _breakLabels = [];
|
||||||
private Stack<string> _continueLabels = [];
|
private Stack<string> _continueLabels = [];
|
||||||
@@ -28,7 +29,7 @@ public class Generator
|
|||||||
{
|
{
|
||||||
_sourceFiles = sourceFiles;
|
_sourceFiles = sourceFiles;
|
||||||
_builder = new StringBuilder();
|
_builder = new StringBuilder();
|
||||||
_variables = new Dictionary<string, Variable>();
|
_variables = new Dictionary<string, string>();
|
||||||
_strings = [];
|
_strings = [];
|
||||||
_funcNames = [];
|
_funcNames = [];
|
||||||
_breakLabels = [];
|
_breakLabels = [];
|
||||||
@@ -355,11 +356,7 @@ public class Generator
|
|||||||
_builder.AppendLine($" {pointerName} {QBEAssign(parameter.Type)} alloc8 {SizeOf(parameter.Type)}");
|
_builder.AppendLine($" {pointerName} {QBEAssign(parameter.Type)} alloc8 {SizeOf(parameter.Type)}");
|
||||||
_builder.AppendLine($" storel %{parameterName}, {pointerName}");
|
_builder.AppendLine($" storel %{parameterName}, {pointerName}");
|
||||||
|
|
||||||
_variables[parameter.Name] = new Variable
|
_variables[parameter.Name] = pointerName;
|
||||||
{
|
|
||||||
Pointer = pointerName,
|
|
||||||
Type = parameter.Type
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_builder.AppendLine();
|
_builder.AppendLine();
|
||||||
@@ -627,7 +624,7 @@ public class Generator
|
|||||||
private void GenerateVariableAssignment(VariableAssignmentNode variableAssignment)
|
private void GenerateVariableAssignment(VariableAssignmentNode variableAssignment)
|
||||||
{
|
{
|
||||||
var result = GenerateExpression(variableAssignment.Value);
|
var result = GenerateExpression(variableAssignment.Value);
|
||||||
_builder.AppendLine($" storel {result}, {_variables[variableAssignment.Identifier.Identifier].Pointer}");
|
_builder.AppendLine($" storel {result}, {_variables[variableAssignment.Identifier.Identifier]}");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GenerateVariableDeclaration(VariableDeclarationNode variableDeclaration)
|
private void GenerateVariableDeclaration(VariableDeclarationNode variableDeclaration)
|
||||||
@@ -664,11 +661,7 @@ public class Generator
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_variables[variableDeclaration.Name] = new Variable
|
_variables[variableDeclaration.Name] = pointerName;
|
||||||
{
|
|
||||||
Pointer = pointerName,
|
|
||||||
Type = type
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GenerateWhile(WhileNode whileStatement)
|
private void GenerateWhile(WhileNode whileStatement)
|
||||||
@@ -1522,42 +1515,34 @@ public class Generator
|
|||||||
var variable = _variables[identifier.Identifier];
|
var variable = _variables[identifier.Identifier];
|
||||||
if (IsLargeType(identifier.Type))
|
if (IsLargeType(identifier.Type))
|
||||||
{
|
{
|
||||||
return variable.Pointer;
|
return variable;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var outputName = GenVarName();
|
var outputName = GenVarName();
|
||||||
_builder.AppendLine($" {outputName} {QBEAssign(identifier.Type)} {QBELoad(identifier.Type)} {variable.Pointer}");
|
_builder.AppendLine($" {outputName} {QBEAssign(identifier.Type)} {QBELoad(identifier.Type)} {variable}");
|
||||||
return outputName;
|
return outputName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GenerateLiteral(LiteralNode literal)
|
private string GenerateLiteral(LiteralNode literal)
|
||||||
{
|
{
|
||||||
if (literal.LiteralType.Equals(NubPrimitiveType.String))
|
switch (literal.Kind)
|
||||||
{
|
{
|
||||||
_strings.Add(literal.Literal);
|
case LiteralKind.Integer:
|
||||||
return $"$str{_strings.Count}";
|
return literal.Literal;
|
||||||
|
case LiteralKind.Float:
|
||||||
|
var value = double.Parse(literal.Literal, CultureInfo.InvariantCulture);
|
||||||
|
var bits = BitConverter.DoubleToInt64Bits(value);
|
||||||
|
return bits.ToString();
|
||||||
|
case LiteralKind.String:
|
||||||
|
_strings.Add(literal.Literal);
|
||||||
|
return $"$str{_strings.Count}";
|
||||||
|
case LiteralKind.Bool:
|
||||||
|
return bool.Parse(literal.Literal) ? "1" : "0";
|
||||||
|
default:
|
||||||
|
throw new ArgumentOutOfRangeException();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (literal.LiteralType.Equals(NubPrimitiveType.I64))
|
|
||||||
{
|
|
||||||
return literal.Literal;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (literal.LiteralType.Equals(NubPrimitiveType.F64))
|
|
||||||
{
|
|
||||||
var value = double.Parse(literal.Literal, CultureInfo.InvariantCulture);
|
|
||||||
var bits = BitConverter.DoubleToInt64Bits(value);
|
|
||||||
return bits.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (literal.LiteralType.Equals(NubPrimitiveType.Bool))
|
|
||||||
{
|
|
||||||
return bool.Parse(literal.Literal) ? "1" : "0";
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new NotSupportedException($"Literal {literal.LiteralType} is not supported");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GenerateStructInitializer(StructInitializerNode structInitializer)
|
private string GenerateStructInitializer(StructInitializerNode structInitializer)
|
||||||
@@ -1787,10 +1772,4 @@ public class Generator
|
|||||||
{
|
{
|
||||||
return structDefinition.Fields.TakeWhile(f => f.Name != member).Sum(f => SizeOf(f.Type));
|
return structDefinition.Fields.TakeWhile(f => f.Name != member).Sum(f => SizeOf(f.Type));
|
||||||
}
|
}
|
||||||
|
|
||||||
private class Variable
|
|
||||||
{
|
|
||||||
public required string Pointer { get; init; }
|
|
||||||
public required NubType Type { get; init; }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
using Nub.Lang.Diagnostics;
|
using Nub.Lang.Diagnostics;
|
||||||
using Nub.Lang.Frontend.Typing;
|
|
||||||
|
|
||||||
namespace Nub.Lang.Frontend.Lexing;
|
namespace Nub.Lang.Frontend.Lexing;
|
||||||
|
|
||||||
@@ -143,7 +142,7 @@ public class Lexer
|
|||||||
|
|
||||||
if (buffer is "true" or "false")
|
if (buffer is "true" or "false")
|
||||||
{
|
{
|
||||||
return new LiteralToken(CreateSpan(startIndex), NubPrimitiveType.Bool, buffer);
|
return new LiteralToken(CreateSpan(startIndex), LiteralKind.Bool, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new IdentifierToken(CreateSpan(startIndex), buffer);
|
return new IdentifierToken(CreateSpan(startIndex), buffer);
|
||||||
@@ -184,7 +183,7 @@ public class Lexer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new LiteralToken(CreateSpan(startIndex), isFloat ? NubPrimitiveType.F64 : NubPrimitiveType.I64, buffer);
|
return new LiteralToken(CreateSpan(startIndex), isFloat ? LiteralKind.Float : LiteralKind.Integer, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Revisit this
|
// TODO: Revisit this
|
||||||
@@ -237,7 +236,7 @@ public class Lexer
|
|||||||
Next();
|
Next();
|
||||||
}
|
}
|
||||||
|
|
||||||
return new LiteralToken(CreateSpan(startIndex), NubPrimitiveType.String, buffer);
|
return new LiteralToken(CreateSpan(startIndex), LiteralKind.String, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new Exception($"Unknown character {current}");
|
throw new Exception($"Unknown character {current}");
|
||||||
|
|||||||
@@ -1,9 +1,15 @@
|
|||||||
using Nub.Lang.Frontend.Typing;
|
namespace Nub.Lang.Frontend.Lexing;
|
||||||
|
|
||||||
namespace Nub.Lang.Frontend.Lexing;
|
public class LiteralToken(SourceSpan span, LiteralKind kind, string value) : Token(span)
|
||||||
|
|
||||||
public class LiteralToken(SourceSpan span, NubType type, string value) : Token(span)
|
|
||||||
{
|
{
|
||||||
public NubType Type { get; } = type;
|
public LiteralKind Kind { get; } = kind;
|
||||||
public string Value { get; } = value;
|
public string Value { get; } = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum LiteralKind
|
||||||
|
{
|
||||||
|
Integer,
|
||||||
|
Float,
|
||||||
|
String,
|
||||||
|
Bool
|
||||||
|
}
|
||||||
@@ -3,8 +3,8 @@ using Nub.Lang.Frontend.Typing;
|
|||||||
|
|
||||||
namespace Nub.Lang.Frontend.Parsing.Expressions;
|
namespace Nub.Lang.Frontend.Parsing.Expressions;
|
||||||
|
|
||||||
public class LiteralNode(IReadOnlyList<Token> tokens, string literal, NubType literalType) : ExpressionNode(tokens)
|
public class LiteralNode(IReadOnlyList<Token> tokens, string literal, LiteralKind kind) : ExpressionNode(tokens)
|
||||||
{
|
{
|
||||||
public string Literal { get; } = literal;
|
public string Literal { get; } = literal;
|
||||||
public NubType LiteralType { get; } = literalType;
|
public LiteralKind Kind { get; } = kind;
|
||||||
}
|
}
|
||||||
@@ -429,7 +429,7 @@ public class Parser
|
|||||||
{
|
{
|
||||||
case LiteralToken literal:
|
case LiteralToken literal:
|
||||||
{
|
{
|
||||||
expr = new LiteralNode(GetTokensForNode(startIndex), literal.Value, literal.Type);
|
expr = new LiteralNode(GetTokensForNode(startIndex), literal.Value, literal.Kind);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IdentifierToken identifier:
|
case IdentifierToken identifier:
|
||||||
@@ -529,7 +529,7 @@ public class Parser
|
|||||||
}
|
}
|
||||||
case Symbol.OpenBracket:
|
case Symbol.OpenBracket:
|
||||||
{
|
{
|
||||||
if (Peek().TryGetValue(out var capacityToken) && capacityToken is LiteralToken { Type: NubPrimitiveType { Kind: PrimitiveTypeKind.I64 } } literalToken)
|
if (Peek().TryGetValue(out var capacityToken) && capacityToken is LiteralToken { Kind: LiteralKind.Integer } literalToken)
|
||||||
{
|
{
|
||||||
var capacity = int.Parse(literalToken.Value);
|
var capacity = int.Parse(literalToken.Value);
|
||||||
Next();
|
Next();
|
||||||
@@ -689,7 +689,7 @@ public class Parser
|
|||||||
|
|
||||||
if (TryExpectSymbol(Symbol.OpenBracket))
|
if (TryExpectSymbol(Symbol.OpenBracket))
|
||||||
{
|
{
|
||||||
if (Peek().TryGetValue(out var token) && token is LiteralToken { Type: NubPrimitiveType { Kind: PrimitiveTypeKind.I64 }, Value: var sizeValue })
|
if (Peek().TryGetValue(out var token) && token is LiteralToken { Kind: LiteralKind.Integer, Value: var sizeValue })
|
||||||
{
|
{
|
||||||
Next();
|
Next();
|
||||||
ExpectSymbol(Symbol.CloseBracket);
|
ExpectSymbol(Symbol.CloseBracket);
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using Nub.Lang.Diagnostics;
|
using Nub.Lang.Diagnostics;
|
||||||
|
using Nub.Lang.Frontend.Lexing;
|
||||||
using Nub.Lang.Frontend.Parsing;
|
using Nub.Lang.Frontend.Parsing;
|
||||||
using Nub.Lang.Frontend.Parsing.Definitions;
|
using Nub.Lang.Frontend.Parsing.Definitions;
|
||||||
using Nub.Lang.Frontend.Parsing.Expressions;
|
using Nub.Lang.Frontend.Parsing.Expressions;
|
||||||
@@ -376,7 +377,7 @@ public class TypeChecker
|
|||||||
AddressOfNode addressOf => TypeCheckAddressOf(addressOf),
|
AddressOfNode addressOf => TypeCheckAddressOf(addressOf),
|
||||||
ArrayIndexAccessNode arrayIndex => TypeCheckArrayIndex(arrayIndex),
|
ArrayIndexAccessNode arrayIndex => TypeCheckArrayIndex(arrayIndex),
|
||||||
ArrayInitializerNode arrayInitializer => TypeCheckArrayInitializer(arrayInitializer),
|
ArrayInitializerNode arrayInitializer => TypeCheckArrayInitializer(arrayInitializer),
|
||||||
LiteralNode literal => literal.LiteralType,
|
LiteralNode literal => TypeCheckLiteral(literal),
|
||||||
IdentifierNode identifier => TypeCheckIdentifier(identifier),
|
IdentifierNode identifier => TypeCheckIdentifier(identifier),
|
||||||
BinaryExpressionNode binaryExpr => TypeCheckBinaryExpression(binaryExpr),
|
BinaryExpressionNode binaryExpr => TypeCheckBinaryExpression(binaryExpr),
|
||||||
CastNode cast => TypeCheckCast(cast),
|
CastNode cast => TypeCheckCast(cast),
|
||||||
@@ -397,6 +398,18 @@ public class TypeChecker
|
|||||||
return resultType;
|
return resultType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private NubType TypeCheckLiteral(LiteralNode literal)
|
||||||
|
{
|
||||||
|
return literal.Kind switch
|
||||||
|
{
|
||||||
|
LiteralKind.Integer => NubPrimitiveType.I64,
|
||||||
|
LiteralKind.Float => NubPrimitiveType.F64,
|
||||||
|
LiteralKind.String => NubPrimitiveType.String,
|
||||||
|
LiteralKind.Bool => NubPrimitiveType.Bool,
|
||||||
|
_ => throw new UnreachableException()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
private NubType? TypeCheckArrayIndex(ArrayIndexAccessNode arrayIndexAccess)
|
private NubType? TypeCheckArrayIndex(ArrayIndexAccessNode arrayIndexAccess)
|
||||||
{
|
{
|
||||||
var expressionType = TypeCheckExpression(arrayIndexAccess.Array);
|
var expressionType = TypeCheckExpression(arrayIndexAccess.Array);
|
||||||
|
|||||||
Reference in New Issue
Block a user