Refactoring Rendering backend

This commit is contained in:
2025-10-05 16:26:37 +09:00
parent a39f377533
commit 01a850ff94
99 changed files with 5056 additions and 5136 deletions

148
Ghost.Shader/Lexer.cs Normal file
View File

@@ -0,0 +1,148 @@
namespace Ghost.Shader;
public class Lexer
{
private readonly string _source;
private int _pos = 0;
private int _line = 0;
private int _column = 0;
public Lexer(string source) => _source = source;
public IEnumerable<Token> Tokenize()
{
while (_pos < _source.Length)
{
var c = _source[_pos];
// Skip whitespace
if (char.IsWhiteSpace(c))
{
if (c == '\n')
{
_line++;
_column = 0;
}
else
{
_column++;
}
_pos++;
continue;
}
// Punctuation
switch (c)
{
case '=':
yield return MakeToken(TokenType.Equals, "=");
break;
case ';':
yield return MakeToken(TokenType.Semicolon, ";");
break;
case ',':
yield return MakeToken(TokenType.Comma, ",");
break;
case '{':
yield return MakeToken(TokenType.LBrace, "{");
break;
case '}':
yield return MakeToken(TokenType.RBrace, "}");
break;
case '(':
yield return MakeToken(TokenType.LParen, "(");
break;
case ')':
yield return MakeToken(TokenType.RParen, ")");
break;
case '"':
yield return ReadString();
break;
default:
if (char.IsLetter(c) || c == '_')
{
yield return ReadIdentifierOrKeyword();
}
else if (char.IsDigit(c) || c == '.')
{
yield return ReadNumber();
}
else
{
_pos++; // skip unknown
}
break;
}
}
yield return new Token(TokenType.EndOfFile, "", _line, _column);
}
private Token MakeToken(TokenType type, string lexeme)
{
var token = new Token(type, lexeme, _line, _column);
_pos++;
_column++;
return token;
}
private Token ReadString()
{
var startCol = _column;
_pos++;
_column++; // skip "
var start = _pos;
while (_pos < _source.Length && _source[_pos] != '"')
{
_pos++;
_column++;
}
var text = _source.Substring(start, _pos - start);
_pos++;
_column++; // skip closing "
return new Token(TokenType.StringLiteral, text, _line, startCol);
}
private Token ReadIdentifierOrKeyword()
{
var startCol = _column;
var start = _pos;
while (_pos < _source.Length && (char.IsLetterOrDigit(_source[_pos]) || _source[_pos] == '_'))
{
_pos++;
_column++;
}
var text = _source.Substring(start, _pos - start);
// Optional: detect keywords
if (TokenLexicon.IsKeyword(text))
{
return new Token(TokenType.Keyword, text, _line, startCol);
}
return new Token(TokenType.Identifier, text, _line, startCol);
}
private Token ReadNumber()
{
var startCol = _column;
var start = _pos;
while (_pos < _source.Length && (char.IsDigit(_source[_pos]) || _source[_pos] == '.'))
{
_pos++;
_column++;
}
var num = _source.Substring(start, _pos - start);
return new Token(TokenType.Number, num, _line, startCol);
}
}