This commit is contained in:
2026-02-08 16:18:41 +01:00
parent 38f55d8e7c
commit 423ec4c798
4 changed files with 35 additions and 2 deletions

View File

@@ -74,6 +74,9 @@ public sealed class Generator(List<NodeDefinition> nodes)
case NodeStatementIf statement:
EmitStatementIf(statement);
break;
case NodeStatementWhile statement:
EmitStatementWhile(statement);
break;
default:
throw new ArgumentOutOfRangeException(nameof(node), node, null);
}
@@ -147,6 +150,18 @@ public sealed class Generator(List<NodeDefinition> nodes)
}
}
private void EmitStatementWhile(NodeStatementWhile statement)
{
var condition = EmitExpression(statement.Condition);
writer.WriteLine($"while ({condition})");
writer.WriteLine("{");
using (writer.Indent())
{
EmitStatement(statement.Block);
}
writer.WriteLine("}");
}
private string EmitExpression(NodeExpression node)
{
return node switch

View File

@@ -92,6 +92,13 @@ public sealed class Parser(List<Token> tokens)
return new NodeStatementIf(TokensFrom(startIndex), condition, thenBlock, elseBlock);
}
if (TryExpectKeyword(Keyword.While))
{
var condition = ParseExpression();
var thenBlock = ParseStatement();
return new NodeStatementWhile(TokensFrom(startIndex), condition, thenBlock);
}
var target = ParseExpression();
if (TryExpectSymbol(Symbol.OpenParen))
@@ -377,6 +384,12 @@ internal class NodeStatementIf(List<Token> tokens, NodeExpression condition, Nod
public readonly NodeStatement? ElseBlock = elseBlock;
}
internal class NodeStatementWhile(List<Token> tokens, NodeExpression condition, NodeStatement block) : NodeStatement(tokens)
{
public readonly NodeExpression Condition = condition;
public readonly NodeStatement Block = block;
}
public abstract class NodeExpression(List<Token> tokens) : Node(tokens);
public sealed class NodeExpressionIntLiteral(List<Token> tokens, TokenIntLiteral value) : NodeExpression(tokens)

View File

@@ -7,11 +7,14 @@ const string contents = """
if true {
x = 49
}
else {
} else {
x = 3
}
while false {
x = 6
}
do_something("test")
return x
}

View File

@@ -280,6 +280,7 @@ public sealed class Tokenizer(string contents)
"let" => new TokenKeyword(line, startColumn, column - startColumn, Keyword.Let),
"if" => new TokenKeyword(line, startColumn, column - startColumn, Keyword.If),
"else" => new TokenKeyword(line, startColumn, column - startColumn, Keyword.Else),
"while" => new TokenKeyword(line, startColumn, column - startColumn, Keyword.While),
"return" => new TokenKeyword(line, startColumn, column - startColumn, Keyword.Return),
"true" => new TokenBoolLiteral(line, startColumn, column - startColumn, true),
"false" => new TokenBoolLiteral(line, startColumn, column - startColumn, false),
@@ -400,6 +401,7 @@ public enum Keyword
Let,
If,
Else,
While,
Return,
}