...
This commit is contained in:
@@ -71,6 +71,9 @@ public sealed class Generator(List<NodeDefinition> nodes)
|
|||||||
case NodeStatementAssignment statement:
|
case NodeStatementAssignment statement:
|
||||||
EmitStatementAssignment(statement);
|
EmitStatementAssignment(statement);
|
||||||
break;
|
break;
|
||||||
|
case NodeStatementIf statement:
|
||||||
|
EmitStatementIf(statement);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
throw new ArgumentOutOfRangeException(nameof(node), node, null);
|
throw new ArgumentOutOfRangeException(nameof(node), node, null);
|
||||||
}
|
}
|
||||||
@@ -114,6 +117,36 @@ public sealed class Generator(List<NodeDefinition> nodes)
|
|||||||
writer.WriteLine($"{target} = {value};");
|
writer.WriteLine($"{target} = {value};");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void EmitStatementIf(NodeStatementIf statement)
|
||||||
|
{
|
||||||
|
var condition = EmitExpression(statement.Condition);
|
||||||
|
writer.WriteLine($"if ({condition})");
|
||||||
|
writer.WriteLine("{");
|
||||||
|
using (writer.Indent())
|
||||||
|
{
|
||||||
|
EmitStatement(statement.ThenBlock);
|
||||||
|
}
|
||||||
|
|
||||||
|
writer.WriteLine("}");
|
||||||
|
|
||||||
|
if (statement.ElseBlock != null)
|
||||||
|
{
|
||||||
|
writer.Write("else");
|
||||||
|
if (statement.ElseBlock is NodeStatementIf)
|
||||||
|
writer.Write(" ");
|
||||||
|
else
|
||||||
|
writer.WriteLine();
|
||||||
|
|
||||||
|
writer.WriteLine("{");
|
||||||
|
using (writer.Indent())
|
||||||
|
{
|
||||||
|
EmitStatement(statement.ElseBlock);
|
||||||
|
}
|
||||||
|
|
||||||
|
writer.WriteLine("}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private string EmitExpression(NodeExpression node)
|
private string EmitExpression(NodeExpression node)
|
||||||
{
|
{
|
||||||
return node switch
|
return node switch
|
||||||
|
|||||||
@@ -80,6 +80,18 @@ public sealed class Parser(List<Token> tokens)
|
|||||||
return new NodeStatementVariableDeclaration(TokensFrom(startIndex), name, type, value);
|
return new NodeStatementVariableDeclaration(TokensFrom(startIndex), name, type, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (TryExpectKeyword(Keyword.If))
|
||||||
|
{
|
||||||
|
var condition = ParseExpression();
|
||||||
|
var thenBlock = ParseStatement();
|
||||||
|
NodeStatement? elseBlock = null;
|
||||||
|
|
||||||
|
if (TryExpectKeyword(Keyword.Else))
|
||||||
|
elseBlock = ParseStatement();
|
||||||
|
|
||||||
|
return new NodeStatementIf(TokensFrom(startIndex), condition, thenBlock, elseBlock);
|
||||||
|
}
|
||||||
|
|
||||||
var target = ParseExpression();
|
var target = ParseExpression();
|
||||||
|
|
||||||
if (TryExpectSymbol(Symbol.OpenParen))
|
if (TryExpectSymbol(Symbol.OpenParen))
|
||||||
@@ -308,7 +320,7 @@ public sealed class Parser(List<Token> tokens)
|
|||||||
|
|
||||||
public abstract class Node(List<Token> tokens)
|
public abstract class Node(List<Token> tokens)
|
||||||
{
|
{
|
||||||
public List<Token> Tokens = tokens;
|
public readonly List<Token> Tokens = tokens;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract class NodeDefinition(List<Token> tokens) : Node(tokens);
|
public abstract class NodeDefinition(List<Token> tokens) : Node(tokens);
|
||||||
@@ -358,6 +370,13 @@ internal class NodeStatementAssignment(List<Token> tokens, NodeExpression target
|
|||||||
public readonly NodeExpression Value = value;
|
public readonly NodeExpression Value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal class NodeStatementIf(List<Token> tokens, NodeExpression condition, NodeStatement thenBlock, NodeStatement? elseBlock) : NodeStatement(tokens)
|
||||||
|
{
|
||||||
|
public readonly NodeExpression Condition = condition;
|
||||||
|
public readonly NodeStatement ThenBlock = thenBlock;
|
||||||
|
public readonly NodeStatement? ElseBlock = elseBlock;
|
||||||
|
}
|
||||||
|
|
||||||
public abstract class NodeExpression(List<Token> tokens) : Node(tokens);
|
public abstract class NodeExpression(List<Token> tokens) : Node(tokens);
|
||||||
|
|
||||||
public sealed class NodeExpressionIntLiteral(List<Token> tokens, TokenIntLiteral value) : NodeExpression(tokens)
|
public sealed class NodeExpressionIntLiteral(List<Token> tokens, TokenIntLiteral value) : NodeExpression(tokens)
|
||||||
|
|||||||
@@ -4,6 +4,14 @@ const string contents = """
|
|||||||
func main(): i32 {
|
func main(): i32 {
|
||||||
let x: i32 = 23
|
let x: i32 = 23
|
||||||
x = 24
|
x = 24
|
||||||
|
|
||||||
|
if true {
|
||||||
|
x = 49
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
x = 3
|
||||||
|
}
|
||||||
|
|
||||||
do_something("test")
|
do_something("test")
|
||||||
return x
|
return x
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -279,6 +279,7 @@ public sealed class Tokenizer(string contents)
|
|||||||
"func" => new TokenKeyword(line, startColumn, column - startColumn, Keyword.Func),
|
"func" => new TokenKeyword(line, startColumn, column - startColumn, Keyword.Func),
|
||||||
"let" => new TokenKeyword(line, startColumn, column - startColumn, Keyword.Let),
|
"let" => new TokenKeyword(line, startColumn, column - startColumn, Keyword.Let),
|
||||||
"if" => new TokenKeyword(line, startColumn, column - startColumn, Keyword.If),
|
"if" => new TokenKeyword(line, startColumn, column - startColumn, Keyword.If),
|
||||||
|
"else" => new TokenKeyword(line, startColumn, column - startColumn, Keyword.Else),
|
||||||
"return" => new TokenKeyword(line, startColumn, column - startColumn, Keyword.Return),
|
"return" => new TokenKeyword(line, startColumn, column - startColumn, Keyword.Return),
|
||||||
"true" => new TokenBoolLiteral(line, startColumn, column - startColumn, true),
|
"true" => new TokenBoolLiteral(line, startColumn, column - startColumn, true),
|
||||||
"false" => new TokenBoolLiteral(line, startColumn, column - startColumn, false),
|
"false" => new TokenBoolLiteral(line, startColumn, column - startColumn, false),
|
||||||
@@ -398,6 +399,7 @@ public enum Keyword
|
|||||||
Func,
|
Func,
|
||||||
Let,
|
Let,
|
||||||
If,
|
If,
|
||||||
|
Else,
|
||||||
Return,
|
Return,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user