diff --git a/compiler/Compiler/Generator.cs b/compiler/Compiler/Generator.cs index 6fe4cf3..d869002 100644 --- a/compiler/Compiler/Generator.cs +++ b/compiler/Compiler/Generator.cs @@ -14,6 +14,12 @@ public sealed class Generator(List nodes) private string Emit() { writer.WriteLine(""" + #include + #include + #include + #include + #include + struct string { const char *data; int length; @@ -59,6 +65,8 @@ public sealed class Generator(List nodes) case NodeStatementReturn statement: EmitStatementReturn(statement); break; + default: + throw new ArgumentOutOfRangeException(nameof(node), node, null); } } @@ -91,155 +99,88 @@ public sealed class Generator(List nodes) { return node switch { - NodeExpressionBoolLiteral expression => EmitExpressionBoolLiteral(expression), - NodeExpressionIntLiteral expression => EmitExpressionIntLiteral(expression), - NodeExpressionStringLiteral expression => EmitExpressionStringLiteral(expression), - NodeExpressionIdent expression => EmitExpressionIdent(expression), + NodeExpressionBoolLiteral expression => expression.Value.Value ? "true" : "false", + NodeExpressionIntLiteral expression => expression.Value.Value.ToString(), + NodeExpressionStringLiteral expression => $"(struct string){{ \"{expression.Value.Value}\", {expression.Value.Value.Length} }}", + NodeExpressionIdent expression => expression.Value.Ident, + _ => throw new ArgumentOutOfRangeException(nameof(node), node, null) }; } - private string EmitExpressionBoolLiteral(NodeExpressionBoolLiteral expression) + private static string CType(NodeType node, string? varName = null) { - return expression.Value.Value ? "1" : "0"; - } - - private string EmitExpressionIntLiteral(NodeExpressionIntLiteral expression) - { - return expression.Value.Value.ToString(); - } - - private string EmitExpressionStringLiteral(NodeExpressionStringLiteral expression) - { - return $"(struct string){{ \"{expression.Value.Value}\", {expression.Value.Value.Length} }}"; - } - - private string EmitExpressionIdent(NodeExpressionIdent expression) - { - return expression.Value.Ident; - } - - private static string CType(NodeType type, string? variableName = null) - { - return type switch + return node switch { - NodeTypeVoid => "void" + (variableName != null ? $" {variableName}" : ""), - NodeTypeBool => "bool" + (variableName != null ? $" {variableName}" : ""), - NodeTypeSInt intType => CTypeSInt(intType, variableName), - NodeTypeUInt intType => CTypeUInt(intType, variableName), - NodeTypePointer ptr => CType(ptr.To) + "*" + (variableName != null ? $" {variableName}" : ""), - NodeTypeString => "struct string" + (variableName != null ? $" {variableName}" : ""), - NodeTypeFunc fn => CTypeFunc(fn, variableName), + NodeTypeVoid => "void" + (varName != null ? $" {varName}" : ""), + NodeTypeBool => "bool" + (varName != null ? $" {varName}" : ""), + NodeTypeCustom type => $"struct {type}" + (varName != null ? $" {varName}" : ""), + NodeTypeSInt type => $"int{type.Width}_t" + (varName != null ? $" {varName}" : ""), + NodeTypeUInt type => $"uint{type.Width}_t" + (varName != null ? $" {varName}" : ""), + NodeTypePointer type => CType(type.To) + (varName != null ? $" *{varName}" : "*"), + NodeTypeString => "struct string" + (varName != null ? $" {varName}" : ""), + NodeTypeFunc type => $"{CType(type.ReturnType)} (*{varName})({string.Join(", ", type.Parameters.Select(p => CType(p)))})", + _ => throw new ArgumentOutOfRangeException(nameof(node), node, null) }; } - - private static string CTypeSInt(NodeTypeSInt intType, string? varName) - { - var cType = intType.Width switch - { - 8 => "char", - 16 => "short", - 32 => "int", - 64 => "long long", - }; - - return cType + (varName != null ? $" {varName}" : ""); - } - - private static string CTypeUInt(NodeTypeUInt intType, string? varName) - { - var cType = intType.Width switch - { - 8 => "unsigned char", - 16 => "unsigned short", - 32 => "unsigned int", - 64 => "unsigned long long", - }; - - return cType + (varName != null ? $" {varName}" : ""); - } - - private static string CTypeFunc(NodeTypeFunc fn, string? varName) - { - var returnType = CType(fn.ReturnType); - var parameters = string.Join(", ", fn.Parameters.Select(p => CType(p))); - - if (string.IsNullOrEmpty(parameters)) - { - parameters = "void"; - } - - if (varName != null) - { - return $"{returnType} (*{varName})({parameters})"; - } - - return $"{returnType} (*)({parameters})"; - } } internal class IndentedTextWriter { - private readonly StringBuilder _builder = new(); - private int _indentLevel; + private readonly StringBuilder builder = new(); + private int indentLevel; public IDisposable Indent() { - _indentLevel++; + indentLevel++; return new IndentScope(this); } public void WriteLine(string text) { WriteIndent(); - _builder.AppendLine(text); + builder.AppendLine(text); } public void Write(string text) { WriteIndent(); - _builder.Append(text); + builder.Append(text); } public void WriteLine() { - _builder.AppendLine(); + builder.AppendLine(); } public override string ToString() { - return _builder.ToString(); + return builder.ToString(); } private void WriteIndent() { - if (_builder.Length > 0) + if (builder.Length > 0) { - var lastChar = _builder[^1]; + var lastChar = builder[^1]; if (lastChar != '\n' && lastChar != '\r') return; } - for (var i = 0; i < _indentLevel; i++) + for (var i = 0; i < indentLevel; i++) { - _builder.Append(" "); + builder.Append(" "); } } - private class IndentScope : IDisposable + private class IndentScope(IndentedTextWriter writer) : IDisposable { - private readonly IndentedTextWriter _writer; - private bool _disposed; - - public IndentScope(IndentedTextWriter writer) - { - _writer = writer; - } + private bool disposed; public void Dispose() { - if (_disposed) return; - _writer._indentLevel--; - _disposed = true; + if (disposed) return; + writer.indentLevel--; + disposed = true; } } } \ No newline at end of file diff --git a/compiler/Compiler/Program.cs b/compiler/Compiler/Program.cs index 8c9cd6f..26bfc8d 100644 --- a/compiler/Compiler/Program.cs +++ b/compiler/Compiler/Program.cs @@ -6,7 +6,7 @@ const string contents = """ return 69 } - func do_something(text: string): func(i32 u32): void { + func do_something(text: string): void { } """;