WIP: dev #1

Draft
nub31 wants to merge 103 commits from dev into master
4 changed files with 63 additions and 1 deletions
Showing only changes of commit 38f55d8e7c - Show all commits

View File

@@ -71,6 +71,9 @@ public sealed class Generator(List<NodeDefinition> nodes)
case NodeStatementAssignment statement:
EmitStatementAssignment(statement);
break;
case NodeStatementIf statement:
EmitStatementIf(statement);
break;
default:
throw new ArgumentOutOfRangeException(nameof(node), node, null);
}
@@ -114,6 +117,36 @@ public sealed class Generator(List<NodeDefinition> nodes)
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)
{
return node switch

View File

@@ -80,6 +80,18 @@ public sealed class Parser(List<Token> tokens)
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();
if (TryExpectSymbol(Symbol.OpenParen))
@@ -308,7 +320,7 @@ public sealed class Parser(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);
@@ -358,6 +370,13 @@ internal class NodeStatementAssignment(List<Token> tokens, NodeExpression target
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 sealed class NodeExpressionIntLiteral(List<Token> tokens, TokenIntLiteral value) : NodeExpression(tokens)

View File

@@ -4,6 +4,14 @@ const string contents = """
func main(): i32 {
let x: i32 = 23
x = 24
if true {
x = 49
}
else {
x = 3
}
do_something("test")
return x
}

View File

@@ -279,6 +279,7 @@ public sealed class Tokenizer(string contents)
"func" => new TokenKeyword(line, startColumn, column - startColumn, Keyword.Func),
"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),
"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),
@@ -398,6 +399,7 @@ public enum Keyword
Func,
Let,
If,
Else,
Return,
}