...
This commit is contained in:
@@ -423,7 +423,7 @@ public sealed class Parser
|
||||
case Symbol.Pipe:
|
||||
binaryExpressionOperator = BinaryOperatorSyntax.BitwiseOr;
|
||||
return true;
|
||||
case Symbol.Caret:
|
||||
case Symbol.XOr:
|
||||
binaryExpressionOperator = BinaryOperatorSyntax.BitwiseXor;
|
||||
return true;
|
||||
default:
|
||||
@@ -445,6 +445,7 @@ public sealed class Parser
|
||||
IdentifierToken identifier => ParseIdentifier(startIndex, identifier),
|
||||
SymbolToken symbolToken => symbolToken.Symbol switch
|
||||
{
|
||||
Symbol.Ampersand => new AddressOfSyntax(GetTokens(startIndex), ParsePrimaryExpression()),
|
||||
Symbol.OpenParen => ParseParenthesizedExpression(),
|
||||
Symbol.Minus => new UnaryExpressionSyntax(GetTokens(startIndex), UnaryOperatorSyntax.Negate, ParsePrimaryExpression()),
|
||||
Symbol.Bang => new UnaryExpressionSyntax(GetTokens(startIndex), UnaryOperatorSyntax.Invert, ParsePrimaryExpression()),
|
||||
@@ -517,12 +518,6 @@ public sealed class Parser
|
||||
var startIndex = _tokenIndex;
|
||||
while (HasToken)
|
||||
{
|
||||
if (TryExpectSymbol(Symbol.Ampersand))
|
||||
{
|
||||
expr = new AddressOfSyntax(GetTokens(startIndex), expr);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (TryExpectSymbol(Symbol.Caret))
|
||||
{
|
||||
expr = new DereferenceSyntax(GetTokens(startIndex), expr);
|
||||
|
||||
@@ -14,14 +14,29 @@ public record IdentifierToken(SourceSpan Span, string Value) : Token(Span)
|
||||
|
||||
public record IntLiteralToken(SourceSpan Span, string Value, int Base) : Token(Span)
|
||||
{
|
||||
public ulong AsU64 => Convert.ToUInt64(Value, Base);
|
||||
public long AsI64 => Convert.ToInt64(Value, Base);
|
||||
public uint AsU32 => Convert.ToUInt32(Value, Base);
|
||||
public int AsI32 => Convert.ToInt32(Value, Base);
|
||||
public ushort AsU16 => Convert.ToUInt16(Value, Base);
|
||||
public short AsI16 => Convert.ToInt16(Value, Base);
|
||||
public byte AsU8 => Convert.ToByte(Value, Base);
|
||||
public sbyte AsI8 => Convert.ToSByte(Value, Base);
|
||||
private string GetNumericValue()
|
||||
{
|
||||
// Strip base prefixes: 0b, 0o, 0x
|
||||
return Base switch
|
||||
{
|
||||
2 when Value.StartsWith("0b", StringComparison.OrdinalIgnoreCase)
|
||||
=> Value.Substring(2),
|
||||
8 when Value.StartsWith("0o", StringComparison.OrdinalIgnoreCase)
|
||||
=> Value.Substring(2),
|
||||
16 when Value.StartsWith("0x", StringComparison.OrdinalIgnoreCase)
|
||||
=> Value.Substring(2),
|
||||
_ => Value
|
||||
};
|
||||
}
|
||||
|
||||
public ulong AsU64 => Convert.ToUInt64(GetNumericValue(), Base);
|
||||
public long AsI64 => Convert.ToInt64(GetNumericValue(), Base);
|
||||
public uint AsU32 => Convert.ToUInt32(GetNumericValue(), Base);
|
||||
public int AsI32 => Convert.ToInt32(GetNumericValue(), Base);
|
||||
public ushort AsU16 => Convert.ToUInt16(GetNumericValue(), Base);
|
||||
public short AsI16 => Convert.ToInt16(GetNumericValue(), Base);
|
||||
public byte AsU8 => Convert.ToByte(GetNumericValue(), Base);
|
||||
public sbyte AsI8 => Convert.ToSByte(GetNumericValue(), Base);
|
||||
|
||||
public float AsF32 => Convert.ToSingle(AsI32);
|
||||
public double AsF64 => Convert.ToDouble(AsI64);
|
||||
@@ -119,6 +134,7 @@ public enum Symbol
|
||||
Pipe,
|
||||
And,
|
||||
Or,
|
||||
XOr,
|
||||
At,
|
||||
QuestionMark,
|
||||
}
|
||||
|
||||
@@ -68,19 +68,17 @@ public sealed class Tokenizer
|
||||
|
||||
private Token ParseToken(char current, int lineStart, int columnStart)
|
||||
{
|
||||
// Numbers
|
||||
if (char.IsDigit(current))
|
||||
{
|
||||
return ParseNumber(lineStart, columnStart);
|
||||
}
|
||||
|
||||
// String literals
|
||||
if (current == '"')
|
||||
{
|
||||
return ParseString(lineStart, columnStart);
|
||||
}
|
||||
|
||||
// Try keywords and symbols by length (longest first)
|
||||
// note(nub31): Look for keywords (longest first in case a keyword fits partially in a larger keyword)
|
||||
for (var i = 8; i >= 1; i--)
|
||||
{
|
||||
if (TryMatchSymbol(i, lineStart, columnStart, out var token))
|
||||
@@ -89,7 +87,6 @@ public sealed class Tokenizer
|
||||
}
|
||||
}
|
||||
|
||||
// Identifiers
|
||||
if (char.IsLetter(current) || current == '_')
|
||||
{
|
||||
return ParseIdentifier(lineStart, columnStart);
|
||||
@@ -103,7 +100,7 @@ public sealed class Tokenizer
|
||||
var start = _index;
|
||||
var current = _content[_index];
|
||||
|
||||
// Hex literal
|
||||
// note(nub31): 0xFFFFFF
|
||||
if (current == '0' && _index + 1 < _content.Length && _content[_index + 1] == 'x')
|
||||
{
|
||||
Next(2);
|
||||
@@ -128,7 +125,7 @@ public sealed class Tokenizer
|
||||
16);
|
||||
}
|
||||
|
||||
// Binary literal
|
||||
// note(nub31): 0b11001100
|
||||
if (current == '0' && _index + 1 < _content.Length && _content[_index + 1] == 'b')
|
||||
{
|
||||
Next(2);
|
||||
@@ -153,7 +150,7 @@ public sealed class Tokenizer
|
||||
2);
|
||||
}
|
||||
|
||||
// Decimal or float
|
||||
// note(nub31): 23/23.5
|
||||
var isFloat = false;
|
||||
while (_index < _content.Length)
|
||||
{
|
||||
@@ -191,7 +188,7 @@ public sealed class Tokenizer
|
||||
|
||||
private StringLiteralToken ParseString(int lineStart, int columnStart)
|
||||
{
|
||||
Next(); // Skip opening quote
|
||||
Next();
|
||||
var start = _index;
|
||||
|
||||
while (true)
|
||||
@@ -236,6 +233,20 @@ public sealed class Tokenizer
|
||||
|
||||
var span = _content.AsSpan(_index, length);
|
||||
|
||||
if (span is "true")
|
||||
{
|
||||
Next(4);
|
||||
token = new BoolLiteralToken(CreateSpan(lineStart, columnStart), true);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (span is "false")
|
||||
{
|
||||
Next(5);
|
||||
token = new BoolLiteralToken(CreateSpan(lineStart, columnStart), false);
|
||||
return true;
|
||||
}
|
||||
|
||||
var symbol = length switch
|
||||
{
|
||||
8 => span switch
|
||||
@@ -287,6 +298,7 @@ public sealed class Tokenizer
|
||||
"&&" => Symbol.And,
|
||||
"||" => Symbol.Or,
|
||||
"::" => Symbol.DoubleColon,
|
||||
"x|" => Symbol.XOr,
|
||||
_ => Symbol.None
|
||||
},
|
||||
1 => span[0] switch
|
||||
@@ -361,9 +373,7 @@ public sealed class Tokenizer
|
||||
}
|
||||
}
|
||||
|
||||
return new IdentifierToken(
|
||||
CreateSpan(lineStart, columnStart),
|
||||
_content.Substring(start, _index - start));
|
||||
return new IdentifierToken(CreateSpan(lineStart, columnStart), _content.Substring(start, _index - start));
|
||||
}
|
||||
|
||||
private SourceSpan CreateSpan(int lineStart, int columnStart)
|
||||
|
||||
Reference in New Issue
Block a user