Files
sbox-public/engine/Sandbox.System/UI/Calc/Calc.Tokenize.cs
s&box team 71f266059a Open source release
This commit imports the C# engine code and game files, excluding C++ source code.

[Source-Commit: ceb3d758046e50faa6258bc3b658a30c97743268]
2025-11-24 09:05:18 +00:00

80 lines
1.6 KiB
C#

namespace Sandbox.UI;
partial class Calc
{
private enum TokenType
{
Literal,
Add, // +
Subtract, // -
Multiply, // *
Divide, // /
};
private struct Token
{
public TokenType Type;
public Length? Value;
public static Token Literal( Length? value ) => new Token { Type = TokenType.Literal, Value = value };
}
private static List<Token> Tokenize( string expression )
{
var tokens = new List<Token>();
expression = expression.Trim();
var p = new Parse( expression );
while ( !p.IsEnd )
{
//
// Skip bullshit
//
p.SkipWhitespaceAndNewlines();
if ( p.TrySkip( "(" ) ) continue;
if ( p.TrySkip( "calc(", ignorecase: true ) ) continue;
if ( p.TrySkip( ")" ) ) continue;
p.SkipWhitespaceAndNewlines();
if ( p.IsEnd ) break;
//
// Read
//
if ( p.TryReadLength( out var length ) )
{
tokens.Add( new Token()
{
Type = TokenType.Literal,
Value = length
} );
continue;
}
else
{
var token = new Token();
var word = p.ReadUntilWhitespaceOrNewlineOrEnd().Trim();
word = word.ToLower();
if ( word == "+" ) token.Type = TokenType.Add;
else if ( word == "-" ) token.Type = TokenType.Subtract;
else if ( word == "*" ) token.Type = TokenType.Multiply;
else if ( word == "/" ) token.Type = TokenType.Divide;
else if ( word == "pi" ) token = Token.Literal( float.Pi );
else if ( word == "e" ) token = Token.Literal( float.E );
else if ( word == "(" || word == ")" ) continue; // Skip parentheses
else throw new( $"Invalid token '{word}'" );
tokens.Add( token );
}
}
return tokens;
}
}