Some cleanup
This commit is contained in:
@@ -1,29 +0,0 @@
|
|||||||
using System.Diagnostics;
|
|
||||||
|
|
||||||
namespace NubLang.CLI;
|
|
||||||
|
|
||||||
public static class Archive
|
|
||||||
{
|
|
||||||
public static async Task<bool> Invoke(string fileName, params IEnumerable<string> objectFiles)
|
|
||||||
{
|
|
||||||
using var process = new Process();
|
|
||||||
process.StartInfo = new ProcessStartInfo("ar", ["rcs", fileName, ..objectFiles])
|
|
||||||
{
|
|
||||||
UseShellExecute = false,
|
|
||||||
RedirectStandardOutput = true,
|
|
||||||
RedirectStandardError = true,
|
|
||||||
CreateNoWindow = true
|
|
||||||
};
|
|
||||||
|
|
||||||
process.Start();
|
|
||||||
await process.WaitForExitAsync();
|
|
||||||
|
|
||||||
var errors = await process.StandardError.ReadToEndAsync();
|
|
||||||
if (!string.IsNullOrWhiteSpace(errors))
|
|
||||||
{
|
|
||||||
await Console.Error.WriteLineAsync(errors);
|
|
||||||
}
|
|
||||||
|
|
||||||
return process.ExitCode == 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
using System.Diagnostics;
|
|
||||||
|
|
||||||
namespace NubLang.CLI;
|
|
||||||
|
|
||||||
public static class GCC
|
|
||||||
{
|
|
||||||
public static async Task<bool> Assemble(string asmPath, string outPath)
|
|
||||||
{
|
|
||||||
using var process = new Process();
|
|
||||||
process.StartInfo = new ProcessStartInfo("x86_64-elf-as", ["-nostartfiles", "-o", outPath, asmPath])
|
|
||||||
{
|
|
||||||
UseShellExecute = false,
|
|
||||||
RedirectStandardOutput = true,
|
|
||||||
RedirectStandardError = true,
|
|
||||||
CreateNoWindow = true
|
|
||||||
};
|
|
||||||
|
|
||||||
process.Start();
|
|
||||||
|
|
||||||
await process.WaitForExitAsync();
|
|
||||||
|
|
||||||
var errors = await process.StandardError.ReadToEndAsync();
|
|
||||||
if (!string.IsNullOrWhiteSpace(errors))
|
|
||||||
{
|
|
||||||
await Console.Error.WriteLineAsync(errors);
|
|
||||||
}
|
|
||||||
|
|
||||||
return process.ExitCode == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static async Task<bool> Compile(string cPath, string outPath)
|
|
||||||
{
|
|
||||||
using var process = new Process();
|
|
||||||
process.StartInfo = new ProcessStartInfo("gcc", ["-ffreestanding", "-nostartfiles", "-c", "-o", outPath, cPath])
|
|
||||||
{
|
|
||||||
UseShellExecute = false,
|
|
||||||
RedirectStandardOutput = true,
|
|
||||||
RedirectStandardError = true,
|
|
||||||
CreateNoWindow = true
|
|
||||||
};
|
|
||||||
|
|
||||||
process.Start();
|
|
||||||
|
|
||||||
await process.WaitForExitAsync();
|
|
||||||
|
|
||||||
var errors = await process.StandardError.ReadToEndAsync();
|
|
||||||
if (!string.IsNullOrWhiteSpace(errors))
|
|
||||||
{
|
|
||||||
await Console.Error.WriteLineAsync(errors);
|
|
||||||
}
|
|
||||||
|
|
||||||
return process.ExitCode == 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -6,8 +6,6 @@ using NubLang.Generation;
|
|||||||
using NubLang.Modules;
|
using NubLang.Modules;
|
||||||
using NubLang.Syntax;
|
using NubLang.Syntax;
|
||||||
|
|
||||||
var sw = Stopwatch.StartNew();
|
|
||||||
|
|
||||||
var options = new Options();
|
var options = new Options();
|
||||||
|
|
||||||
for (var i = 0; i < args.Length; i++)
|
for (var i = 0; i < args.Length; i++)
|
||||||
@@ -34,9 +32,6 @@ for (var i = 0; i < args.Length; i++)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.WriteLine($"Parse cli args: {sw.ElapsedMilliseconds}ms");
|
|
||||||
sw.Restart();
|
|
||||||
|
|
||||||
foreach (var file in options.Files)
|
foreach (var file in options.Files)
|
||||||
{
|
{
|
||||||
if (!File.Exists(file))
|
if (!File.Exists(file))
|
||||||
@@ -46,9 +41,6 @@ foreach (var file in options.Files)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.WriteLine($"Check file exists: {sw.ElapsedMilliseconds}ms");
|
|
||||||
sw.Restart();
|
|
||||||
|
|
||||||
var diagnostics = new List<Diagnostic>();
|
var diagnostics = new List<Diagnostic>();
|
||||||
|
|
||||||
var syntaxTrees = new List<SyntaxTree>();
|
var syntaxTrees = new List<SyntaxTree>();
|
||||||
@@ -58,26 +50,15 @@ foreach (var file in options.Files)
|
|||||||
tokenizer.Tokenize();
|
tokenizer.Tokenize();
|
||||||
diagnostics.AddRange(tokenizer.Diagnostics);
|
diagnostics.AddRange(tokenizer.Diagnostics);
|
||||||
|
|
||||||
Console.WriteLine($" Tokenize: {Path.GetFileName(file)}: {sw.ElapsedMilliseconds}ms");
|
|
||||||
sw.Restart();
|
|
||||||
|
|
||||||
var parser = new Parser();
|
var parser = new Parser();
|
||||||
var syntaxTree = parser.Parse(tokenizer.Tokens);
|
var syntaxTree = parser.Parse(tokenizer.Tokens);
|
||||||
diagnostics.AddRange(parser.Diagnostics);
|
diagnostics.AddRange(parser.Diagnostics);
|
||||||
|
|
||||||
Console.WriteLine($" Parse: {Path.GetFileName(file)}: {sw.ElapsedMilliseconds}ms");
|
|
||||||
sw.Restart();
|
|
||||||
|
|
||||||
syntaxTrees.Add(syntaxTree);
|
syntaxTrees.Add(syntaxTree);
|
||||||
}
|
}
|
||||||
|
|
||||||
sw.Restart();
|
|
||||||
|
|
||||||
var moduleRepository = new ModuleRepository(syntaxTrees);
|
var moduleRepository = new ModuleRepository(syntaxTrees);
|
||||||
|
|
||||||
Console.WriteLine($"Create module repository: {sw.ElapsedMilliseconds}ms");
|
|
||||||
sw.Restart();
|
|
||||||
|
|
||||||
var definitions = new List<DefinitionNode>();
|
var definitions = new List<DefinitionNode>();
|
||||||
|
|
||||||
var referencedStructTypes = new HashSet<NubStructType>();
|
var referencedStructTypes = new HashSet<NubStructType>();
|
||||||
@@ -87,9 +68,6 @@ foreach (var syntaxTree in syntaxTrees)
|
|||||||
var typeChecker = new TypeChecker(syntaxTree, moduleRepository);
|
var typeChecker = new TypeChecker(syntaxTree, moduleRepository);
|
||||||
typeChecker.Check();
|
typeChecker.Check();
|
||||||
|
|
||||||
Console.WriteLine($" Type check {syntaxTree.Metadata.ModuleName}: {sw.ElapsedMilliseconds}ms");
|
|
||||||
sw.Restart();
|
|
||||||
|
|
||||||
definitions.AddRange(typeChecker.Definitions);
|
definitions.AddRange(typeChecker.Definitions);
|
||||||
diagnostics.AddRange(typeChecker.Diagnostics);
|
diagnostics.AddRange(typeChecker.Diagnostics);
|
||||||
|
|
||||||
@@ -99,16 +77,11 @@ foreach (var syntaxTree in syntaxTrees)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sw.Restart();
|
|
||||||
|
|
||||||
foreach (var diagnostic in diagnostics)
|
foreach (var diagnostic in diagnostics)
|
||||||
{
|
{
|
||||||
Console.Error.WriteLine(diagnostic.FormatANSI());
|
Console.Error.WriteLine(diagnostic.FormatANSI());
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.WriteLine($"Print diagnostics: {sw.ElapsedMilliseconds}ms");
|
|
||||||
sw.Restart();
|
|
||||||
|
|
||||||
if (diagnostics.Any(diagnostic => diagnostic.Severity == DiagnosticSeverity.Error))
|
if (diagnostics.Any(diagnostic => diagnostic.Severity == DiagnosticSeverity.Error))
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
@@ -116,38 +89,20 @@ if (diagnostics.Any(diagnostic => diagnostic.Severity == DiagnosticSeverity.Erro
|
|||||||
|
|
||||||
Directory.CreateDirectory(".build");
|
Directory.CreateDirectory(".build");
|
||||||
|
|
||||||
var generator = new CGenerator(definitions, referencedStructTypes);
|
var generator = new Generator(definitions, referencedStructTypes);
|
||||||
var c = generator.Emit();
|
var c = generator.Emit();
|
||||||
var cFilePath = Path.Combine(".build", "out.c");
|
var cFilePath = Path.Combine(".build", "out.c");
|
||||||
|
|
||||||
File.WriteAllText(cFilePath, c);
|
File.WriteAllText(cFilePath, c);
|
||||||
|
|
||||||
var objFilePath = Path.Combine(".build", "out.o");
|
using var process = Process.Start("gcc", ["-ffreestanding", "-nostartfiles", "-c", "-o", Path.Combine(".build", "out.o"), cFilePath]);
|
||||||
var asmSuccess = await GCC.Compile(cFilePath, objFilePath);
|
|
||||||
if (!asmSuccess) return 1;
|
|
||||||
|
|
||||||
// sw.Restart();
|
process.WaitForExit();
|
||||||
//
|
|
||||||
// var generator = new QBEGenerator(definitions, referencedStructTypes);
|
if (process.ExitCode != 0)
|
||||||
// var ssa = generator.Emit();
|
{
|
||||||
// var ssaFilePath = Path.Combine(".build", "out.ssa");
|
Console.Error.WriteLine($"gcc failed with exit code {process.ExitCode}");
|
||||||
// File.WriteAllText(ssaFilePath, ssa);
|
return 1;
|
||||||
//
|
}
|
||||||
// Console.WriteLine($"Emit ssa: {sw.ElapsedMilliseconds}ms");
|
|
||||||
// sw.Restart();
|
|
||||||
//
|
|
||||||
// var asmFilePath = Path.Combine(".build", "out.asm");
|
|
||||||
// var qbeSuccess = await QBE.Invoke(ssaFilePath, asmFilePath);
|
|
||||||
// if (!qbeSuccess) return 1;
|
|
||||||
//
|
|
||||||
// Console.WriteLine($"Emit asm: {sw.ElapsedMilliseconds}ms");
|
|
||||||
// sw.Restart();
|
|
||||||
//
|
|
||||||
// var objFilePath = Path.Combine(".build", "out.o");
|
|
||||||
// var asmSuccess = await GCC.Assemble(asmFilePath, objFilePath);
|
|
||||||
// if (!asmSuccess) return 1;
|
|
||||||
//
|
|
||||||
// Console.WriteLine($"Assemble: {sw.ElapsedMilliseconds}ms");
|
|
||||||
sw.Restart();
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
using System.Diagnostics;
|
|
||||||
|
|
||||||
namespace NubLang.CLI;
|
|
||||||
|
|
||||||
public static class QBE
|
|
||||||
{
|
|
||||||
public static async Task<bool> Invoke(string ssaPath, string outPath)
|
|
||||||
{
|
|
||||||
using var process = new Process();
|
|
||||||
process.StartInfo = new ProcessStartInfo("qbe", ["-o", outPath, ssaPath])
|
|
||||||
{
|
|
||||||
UseShellExecute = false,
|
|
||||||
RedirectStandardOutput = true,
|
|
||||||
RedirectStandardError = true,
|
|
||||||
CreateNoWindow = true
|
|
||||||
};
|
|
||||||
|
|
||||||
process.Start();
|
|
||||||
|
|
||||||
await process.WaitForExitAsync();
|
|
||||||
|
|
||||||
var errors = await process.StandardError.ReadToEndAsync();
|
|
||||||
if (!string.IsNullOrWhiteSpace(errors))
|
|
||||||
{
|
|
||||||
await Console.Error.WriteLineAsync(errors);
|
|
||||||
}
|
|
||||||
|
|
||||||
return process.ExitCode == 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -126,7 +126,7 @@ public record StructFieldAccessNode(NubType Type, ExpressionNode Target, string
|
|||||||
|
|
||||||
public record StructInitializerNode(NubStructType StructType, Dictionary<string, ExpressionNode> Initializers) : RValueExpressionNode(StructType);
|
public record StructInitializerNode(NubStructType StructType, Dictionary<string, ExpressionNode> Initializers) : RValueExpressionNode(StructType);
|
||||||
|
|
||||||
public record DereferenceNode(NubType Type, ExpressionNode Expression) : LValueExpressionNode(Type);
|
public record DereferenceNode(NubType Type, ExpressionNode Target) : LValueExpressionNode(Type);
|
||||||
|
|
||||||
public record ConvertIntNode(NubType Type, ExpressionNode Value, NubIntType ValueType, NubIntType TargetType) : RValueExpressionNode(Type);
|
public record ConvertIntNode(NubType Type, ExpressionNode Value, NubIntType ValueType, NubIntType TargetType) : RValueExpressionNode(Type);
|
||||||
|
|
||||||
|
|||||||
@@ -2,17 +2,17 @@ using NubLang.Ast;
|
|||||||
|
|
||||||
namespace NubLang.Generation;
|
namespace NubLang.Generation;
|
||||||
|
|
||||||
public class CGenerator
|
public class Generator
|
||||||
{
|
{
|
||||||
private readonly List<DefinitionNode> _definitions;
|
private readonly List<DefinitionNode> _definitions;
|
||||||
private readonly HashSet<NubStructType> _structTypes;
|
private readonly HashSet<NubStructType> _structTypes;
|
||||||
private readonly CWriter _writer;
|
private readonly IndentedTextWriter _writer;
|
||||||
|
|
||||||
public CGenerator(List<DefinitionNode> definitions, HashSet<NubStructType> structTypes)
|
public Generator(List<DefinitionNode> definitions, HashSet<NubStructType> structTypes)
|
||||||
{
|
{
|
||||||
_definitions = definitions;
|
_definitions = definitions;
|
||||||
_structTypes = structTypes;
|
_structTypes = structTypes;
|
||||||
_writer = new CWriter();
|
_writer = new IndentedTextWriter();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string MapType(NubType nubType)
|
private static string MapType(NubType nubType)
|
||||||
@@ -114,7 +114,6 @@ public class CGenerator
|
|||||||
""");
|
""");
|
||||||
_writer.WriteLine();
|
_writer.WriteLine();
|
||||||
|
|
||||||
_writer.WriteLine("// Struct definitions");
|
|
||||||
foreach (var structType in _structTypes)
|
foreach (var structType in _structTypes)
|
||||||
{
|
{
|
||||||
_writer.WriteLine("typedef struct");
|
_writer.WriteLine("typedef struct");
|
||||||
@@ -131,9 +130,11 @@ public class CGenerator
|
|||||||
_writer.WriteLine();
|
_writer.WriteLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
_writer.WriteLine("// Function declarations");
|
var appendNewLine = false;
|
||||||
|
|
||||||
foreach (var funcNode in _definitions.OfType<FuncNode>())
|
foreach (var funcNode in _definitions.OfType<FuncNode>())
|
||||||
{
|
{
|
||||||
|
appendNewLine = true;
|
||||||
var parameters = funcNode.Signature.Parameters.Count != 0
|
var parameters = funcNode.Signature.Parameters.Count != 0
|
||||||
? string.Join(", ", funcNode.Signature.Parameters.Select(x => $"{MapType(x.Type)} {x.Name}"))
|
? string.Join(", ", funcNode.Signature.Parameters.Select(x => $"{MapType(x.Type)} {x.Name}"))
|
||||||
: "void";
|
: "void";
|
||||||
@@ -142,12 +143,13 @@ public class CGenerator
|
|||||||
_writer.WriteLine($"{MapType(funcNode.Signature.ReturnType)} {name}({parameters});");
|
_writer.WriteLine($"{MapType(funcNode.Signature.ReturnType)} {name}({parameters});");
|
||||||
}
|
}
|
||||||
|
|
||||||
_writer.WriteLine();
|
if (appendNewLine)
|
||||||
|
{
|
||||||
|
_writer.WriteLine();
|
||||||
|
}
|
||||||
|
|
||||||
_writer.WriteLine("// Struct function implementations");
|
|
||||||
foreach (var structNode in _definitions.OfType<StructNode>())
|
foreach (var structNode in _definitions.OfType<StructNode>())
|
||||||
{
|
{
|
||||||
_writer.WriteLine($"// {structNode.Module}::{structNode.Name}");
|
|
||||||
foreach (var structFuncNode in structNode.Functions)
|
foreach (var structFuncNode in structNode.Functions)
|
||||||
{
|
{
|
||||||
var parameters = structFuncNode.Signature.Parameters.Count != 0
|
var parameters = structFuncNode.Signature.Parameters.Count != 0
|
||||||
@@ -157,12 +159,10 @@ public class CGenerator
|
|||||||
var name = StructFuncName(structNode.Module, structNode.Name, structFuncNode.Name);
|
var name = StructFuncName(structNode.Module, structNode.Name, structFuncNode.Name);
|
||||||
_writer.WriteLine($"{MapType(structFuncNode.Signature.ReturnType)} {name}({parameters})");
|
_writer.WriteLine($"{MapType(structFuncNode.Signature.ReturnType)} {name}({parameters})");
|
||||||
EmitBlock(structFuncNode.Body);
|
EmitBlock(structFuncNode.Body);
|
||||||
|
_writer.WriteLine();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_writer.WriteLine();
|
|
||||||
|
|
||||||
_writer.WriteLine("// Function implementations");
|
|
||||||
foreach (var funcNode in _definitions.OfType<FuncNode>())
|
foreach (var funcNode in _definitions.OfType<FuncNode>())
|
||||||
{
|
{
|
||||||
if (funcNode.Body == null) continue;
|
if (funcNode.Body == null) continue;
|
||||||
@@ -229,7 +229,9 @@ public class CGenerator
|
|||||||
|
|
||||||
private void EmitAssignment(AssignmentNode assignmentNode)
|
private void EmitAssignment(AssignmentNode assignmentNode)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
var target = EmitExpression(assignmentNode.Target);
|
||||||
|
var value = EmitExpression(assignmentNode.Value);
|
||||||
|
_writer.WriteLine($"{target} = {value};");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void EmitBreak(BreakNode breakNode)
|
private void EmitBreak(BreakNode breakNode)
|
||||||
@@ -314,7 +316,7 @@ public class CGenerator
|
|||||||
|
|
||||||
private string EmitExpression(ExpressionNode expressionNode)
|
private string EmitExpression(ExpressionNode expressionNode)
|
||||||
{
|
{
|
||||||
return expressionNode switch
|
var expr = expressionNode switch
|
||||||
{
|
{
|
||||||
ArrayIndexAccessNode arrayIndexAccessNode => EmitArrayIndexAccess(arrayIndexAccessNode),
|
ArrayIndexAccessNode arrayIndexAccessNode => EmitArrayIndexAccess(arrayIndexAccessNode),
|
||||||
ArrayInitializerNode arrayInitializerNode => EmitArrayInitializer(arrayInitializerNode),
|
ArrayInitializerNode arrayInitializerNode => EmitArrayInitializer(arrayInitializerNode),
|
||||||
@@ -342,21 +344,53 @@ public class CGenerator
|
|||||||
UnaryExpressionNode unaryExpressionNode => EmitUnaryExpression(unaryExpressionNode),
|
UnaryExpressionNode unaryExpressionNode => EmitUnaryExpression(unaryExpressionNode),
|
||||||
_ => throw new ArgumentOutOfRangeException(nameof(expressionNode))
|
_ => throw new ArgumentOutOfRangeException(nameof(expressionNode))
|
||||||
};
|
};
|
||||||
|
|
||||||
|
return $"({expr})";
|
||||||
}
|
}
|
||||||
|
|
||||||
private string EmitArrayIndexAccess(ArrayIndexAccessNode arrayIndexAccessNode)
|
private string EmitArrayIndexAccess(ArrayIndexAccessNode arrayIndexAccessNode)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
var array = EmitExpression(arrayIndexAccessNode.Target);
|
||||||
|
var index = EmitExpression(arrayIndexAccessNode.Index);
|
||||||
|
return $"(({MapType(arrayIndexAccessNode.Type)}*){array})[{index}]";
|
||||||
}
|
}
|
||||||
|
|
||||||
private string EmitArrayInitializer(ArrayInitializerNode arrayInitializerNode)
|
private string EmitArrayInitializer(ArrayInitializerNode arrayInitializerNode)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
var capacity = EmitExpression(arrayInitializerNode.Capacity);
|
||||||
|
var elementType = MapType(arrayInitializerNode.ElementType);
|
||||||
|
return $"({elementType}[{capacity}]){{0}}";
|
||||||
}
|
}
|
||||||
|
|
||||||
private string EmitBinaryExpression(BinaryExpressionNode binaryExpressionNode)
|
private string EmitBinaryExpression(BinaryExpressionNode binaryExpressionNode)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
var left = EmitExpression(binaryExpressionNode.Left);
|
||||||
|
var right = EmitExpression(binaryExpressionNode.Right);
|
||||||
|
|
||||||
|
var op = binaryExpressionNode.Operator switch
|
||||||
|
{
|
||||||
|
BinaryOperator.Plus => "+",
|
||||||
|
BinaryOperator.Minus => "-",
|
||||||
|
BinaryOperator.Multiply => "*",
|
||||||
|
BinaryOperator.Divide => "/",
|
||||||
|
BinaryOperator.Modulo => "%",
|
||||||
|
BinaryOperator.Equal => "==",
|
||||||
|
BinaryOperator.NotEqual => "!=",
|
||||||
|
BinaryOperator.LessThan => "<",
|
||||||
|
BinaryOperator.LessThanOrEqual => "<=",
|
||||||
|
BinaryOperator.GreaterThan => ">",
|
||||||
|
BinaryOperator.GreaterThanOrEqual => ">=",
|
||||||
|
BinaryOperator.LogicalAnd => "&&",
|
||||||
|
BinaryOperator.LogicalOr => "||",
|
||||||
|
BinaryOperator.BitwiseAnd => "&",
|
||||||
|
BinaryOperator.BitwiseOr => "|",
|
||||||
|
BinaryOperator.BitwiseXor => "^",
|
||||||
|
BinaryOperator.LeftShift => "<<",
|
||||||
|
BinaryOperator.RightShift => ">>",
|
||||||
|
_ => throw new ArgumentOutOfRangeException()
|
||||||
|
};
|
||||||
|
|
||||||
|
return $"{left} {op} {right}";
|
||||||
}
|
}
|
||||||
|
|
||||||
private string EmitBoolLiteral(BoolLiteralNode boolLiteralNode)
|
private string EmitBoolLiteral(BoolLiteralNode boolLiteralNode)
|
||||||
@@ -366,12 +400,14 @@ public class CGenerator
|
|||||||
|
|
||||||
private string EmitConvertFloat(ConvertFloatNode convertFloatNode)
|
private string EmitConvertFloat(ConvertFloatNode convertFloatNode)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
var value = EmitExpression(convertFloatNode.Value);
|
||||||
|
return $"({MapType(convertFloatNode.Type)}){value}";
|
||||||
}
|
}
|
||||||
|
|
||||||
private string EmitConvertInt(ConvertIntNode convertIntNode)
|
private string EmitConvertInt(ConvertIntNode convertIntNode)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
var value = EmitExpression(convertIntNode.Value);
|
||||||
|
return $"({MapType(convertIntNode.Type)}){value}";
|
||||||
}
|
}
|
||||||
|
|
||||||
private string EmitCStringLiteral(CStringLiteralNode cStringLiteralNode)
|
private string EmitCStringLiteral(CStringLiteralNode cStringLiteralNode)
|
||||||
@@ -381,22 +417,36 @@ public class CGenerator
|
|||||||
|
|
||||||
private string EmitDereference(DereferenceNode dereferenceNode)
|
private string EmitDereference(DereferenceNode dereferenceNode)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
var pointer = EmitExpression(dereferenceNode.Target);
|
||||||
|
return $"*({MapType(dereferenceNode.Type)}*){pointer}";
|
||||||
}
|
}
|
||||||
|
|
||||||
private string EmitFloat32Literal(Float32LiteralNode float32LiteralNode)
|
private string EmitFloat32Literal(Float32LiteralNode float32LiteralNode)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
var str = float32LiteralNode.Value.ToString("G9", System.Globalization.CultureInfo.InvariantCulture);
|
||||||
|
if (!str.Contains('.') && !str.Contains('e') && !str.Contains('E'))
|
||||||
|
{
|
||||||
|
str += ".0";
|
||||||
|
}
|
||||||
|
|
||||||
|
return str + "f";
|
||||||
}
|
}
|
||||||
|
|
||||||
private string EmitFloat64Literal(Float64LiteralNode float64LiteralNode)
|
private string EmitFloat64Literal(Float64LiteralNode float64LiteralNode)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
var str = float64LiteralNode.Value.ToString("G17", System.Globalization.CultureInfo.InvariantCulture);
|
||||||
|
if (!str.Contains('.') && !str.Contains('e') && !str.Contains('E'))
|
||||||
|
{
|
||||||
|
str += ".0";
|
||||||
|
}
|
||||||
|
|
||||||
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
private string EmitFloatToIntBuiltin(FloatToIntBuiltinNode floatToIntBuiltinNode)
|
private string EmitFloatToIntBuiltin(FloatToIntBuiltinNode floatToIntBuiltinNode)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
var value = EmitExpression(floatToIntBuiltinNode.Value);
|
||||||
|
return $"({MapType(floatToIntBuiltinNode.Type)}){value}";
|
||||||
}
|
}
|
||||||
|
|
||||||
private string EmitFuncCall(FuncCallNode funcCallNode)
|
private string EmitFuncCall(FuncCallNode funcCallNode)
|
||||||
@@ -426,22 +476,23 @@ public class CGenerator
|
|||||||
|
|
||||||
private string EmitAddressOf(AddressOfNode addressOfNode)
|
private string EmitAddressOf(AddressOfNode addressOfNode)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
var value = EmitExpression(addressOfNode.LValue);
|
||||||
|
return $"(uintptr_t)&{value}";
|
||||||
}
|
}
|
||||||
|
|
||||||
private string EmitLValueIdentifier(LValueIdentifierNode lValueIdentifierNode)
|
private string EmitLValueIdentifier(LValueIdentifierNode lValueIdentifierNode)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
return lValueIdentifierNode.Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
private string EmitRValueIdentifier(RValueIdentifierNode rValueIdentifierNode)
|
private string EmitRValueIdentifier(RValueIdentifierNode rValueIdentifierNode)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
return rValueIdentifierNode.Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
private string EmitSizeBuiltin(SizeBuiltinNode sizeBuiltinNode)
|
private string EmitSizeBuiltin(SizeBuiltinNode sizeBuiltinNode)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
return $"sizeof({MapType(sizeBuiltinNode.TargetType)})";
|
||||||
}
|
}
|
||||||
|
|
||||||
private string EmitStringLiteral(StringLiteralNode stringLiteralNode)
|
private string EmitStringLiteral(StringLiteralNode stringLiteralNode)
|
||||||
@@ -451,7 +502,8 @@ public class CGenerator
|
|||||||
|
|
||||||
private string EmitStructFieldAccess(StructFieldAccessNode structFieldAccessNode)
|
private string EmitStructFieldAccess(StructFieldAccessNode structFieldAccessNode)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
var structExpr = EmitExpression(structFieldAccessNode.Target);
|
||||||
|
return $"{structExpr}.{structFieldAccessNode.Field}";
|
||||||
}
|
}
|
||||||
|
|
||||||
private string EmitStructFuncCall(StructFuncCallNode structFuncCallNode)
|
private string EmitStructFuncCall(StructFuncCallNode structFuncCallNode)
|
||||||
@@ -474,7 +526,7 @@ public class CGenerator
|
|||||||
? "0"
|
? "0"
|
||||||
: string.Join(", ", initValues);
|
: string.Join(", ", initValues);
|
||||||
|
|
||||||
return $"({MapType(structInitializerNode.Type)}){{ {initString} }}";
|
return $"({MapType(structInitializerNode.Type)}){{{initString}}}";
|
||||||
}
|
}
|
||||||
|
|
||||||
private string EmitUIntLiteral(UIntLiteralNode uIntLiteralNode)
|
private string EmitUIntLiteral(UIntLiteralNode uIntLiteralNode)
|
||||||
@@ -2,7 +2,7 @@ using System.Text;
|
|||||||
|
|
||||||
namespace NubLang.Generation;
|
namespace NubLang.Generation;
|
||||||
|
|
||||||
internal class CWriter
|
internal class IndentedTextWriter
|
||||||
{
|
{
|
||||||
private readonly StringBuilder _builder = new();
|
private readonly StringBuilder _builder = new();
|
||||||
private int _indentLevel;
|
private int _indentLevel;
|
||||||
@@ -52,10 +52,10 @@ internal class CWriter
|
|||||||
|
|
||||||
private class IndentScope : IDisposable
|
private class IndentScope : IDisposable
|
||||||
{
|
{
|
||||||
private readonly CWriter _writer;
|
private readonly IndentedTextWriter _writer;
|
||||||
private bool _disposed;
|
private bool _disposed;
|
||||||
|
|
||||||
public IndentScope(CWriter writer)
|
public IndentScope(IndentedTextWriter writer)
|
||||||
{
|
{
|
||||||
_writer = writer;
|
_writer = writer;
|
||||||
}
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,39 +0,0 @@
|
|||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace NubLang.Generation;
|
|
||||||
|
|
||||||
internal class QBEWriter
|
|
||||||
{
|
|
||||||
private readonly StringBuilder _builder = new();
|
|
||||||
|
|
||||||
public void Indented(string value)
|
|
||||||
{
|
|
||||||
_builder.Append('\t');
|
|
||||||
_builder.AppendLine(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Comment(string comment)
|
|
||||||
{
|
|
||||||
_builder.AppendLine("# " + comment);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void WriteLine(string text)
|
|
||||||
{
|
|
||||||
_builder.AppendLine(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Write(string text)
|
|
||||||
{
|
|
||||||
_builder.Append(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void NewLine()
|
|
||||||
{
|
|
||||||
_builder.AppendLine();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string ToString()
|
|
||||||
{
|
|
||||||
return _builder.ToString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
NUBC = ../../compiler/NubLang.CLI/bin/Debug/net9.0/nubc
|
NUBC = ../../compiler/NubLang.CLI/bin/Debug/net9.0/nubc
|
||||||
|
|
||||||
out: .build/out.o
|
out: .build/out.o
|
||||||
gcc -nostartfiles -lm -o out x86_64.s .build/out.o raylib-5.5_linux_amd64/lib/libraylib.a
|
clang -nostartfiles -lm -O3 -o out x86_64.s .build/out.o raylib-5.5_linux_amd64/lib/libraylib.a
|
||||||
|
|
||||||
.build/out.o: $(NUBC) main.nub raylib.nub
|
.build/out.o: $(NUBC) main.nub raylib.nub
|
||||||
$(NUBC) main.nub raylib.nub
|
$(NUBC) main.nub raylib.nub
|
||||||
|
|||||||
Reference in New Issue
Block a user