...
This commit is contained in:
@@ -1,12 +1,14 @@
|
|||||||
import "c";
|
import "c";
|
||||||
|
|
||||||
global func main() {
|
struct Human {
|
||||||
let x = true;
|
age: int64;
|
||||||
while x {
|
name: string;
|
||||||
if (true) {
|
}
|
||||||
puts("level 1");
|
|
||||||
}
|
global func main() {
|
||||||
puts("level 2");
|
printName();
|
||||||
break;
|
}
|
||||||
}
|
|
||||||
|
func printName(human: Human) {
|
||||||
|
puts(human.name);
|
||||||
}
|
}
|
||||||
@@ -8,7 +8,7 @@ public class Generator
|
|||||||
private readonly List<DefinitionNode> _definitions;
|
private readonly List<DefinitionNode> _definitions;
|
||||||
private readonly StringBuilder _builder = new();
|
private readonly StringBuilder _builder = new();
|
||||||
private readonly Dictionary<string, int> _prefixIndexes = new();
|
private readonly Dictionary<string, int> _prefixIndexes = new();
|
||||||
private readonly Dictionary<string, string> _variables = new();
|
private readonly Dictionary<string, Variable> _variables = new();
|
||||||
private readonly List<string> _strings = [];
|
private readonly List<string> _strings = [];
|
||||||
private readonly Stack<string> _breakLabels = new();
|
private readonly Stack<string> _breakLabels = new();
|
||||||
private readonly Stack<string> _continueLabels = new();
|
private readonly Stack<string> _continueLabels = new();
|
||||||
@@ -21,9 +21,16 @@ public class Generator
|
|||||||
|
|
||||||
public string Generate()
|
public string Generate()
|
||||||
{
|
{
|
||||||
|
foreach (var structDefinition in _definitions.OfType<StructDefinitionNode>())
|
||||||
|
{
|
||||||
|
GenerateStructDefinition(structDefinition);
|
||||||
|
_builder.AppendLine();
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var funcDefinition in _definitions.OfType<LocalFuncDefinitionNode>())
|
foreach (var funcDefinition in _definitions.OfType<LocalFuncDefinitionNode>())
|
||||||
{
|
{
|
||||||
GenerateFuncDefinition(funcDefinition);
|
GenerateFuncDefinition(funcDefinition);
|
||||||
|
_builder.AppendLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var i = 0; i < _strings.Count; i++)
|
for (var i = 0; i < _strings.Count; i++)
|
||||||
@@ -47,13 +54,22 @@ public class Generator
|
|||||||
return "w";
|
return "w";
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new Exception($"Invalid qbe type {type}");
|
return $":{type.Name}";
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GenerateFuncDefinition(LocalFuncDefinitionNode node)
|
private void GenerateFuncDefinition(LocalFuncDefinitionNode node)
|
||||||
{
|
{
|
||||||
_variables.Clear();
|
_variables.Clear();
|
||||||
var parameters = node.Parameters.Select(p => $"{QbeTypeName(p.Type)} %{p.Name}");
|
|
||||||
|
foreach (var parameter in node.Parameters)
|
||||||
|
{
|
||||||
|
_variables.Add(parameter.Name, new Variable
|
||||||
|
{
|
||||||
|
Identifier = $"%{parameter.Name}",
|
||||||
|
Type = parameter.Type
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (node.Global)
|
if (node.Global)
|
||||||
{
|
{
|
||||||
_builder.Append("export ");
|
_builder.Append("export ");
|
||||||
@@ -68,7 +84,7 @@ public class Generator
|
|||||||
_builder.Append('$');
|
_builder.Append('$');
|
||||||
_builder.Append(node.Name);
|
_builder.Append(node.Name);
|
||||||
|
|
||||||
_builder.AppendLine($"({string.Join(", ", parameters)}) {{");
|
_builder.AppendLine($"({string.Join(", ", node.Parameters.Select(p => $"{QbeTypeName(p.Type)} %{p.Name}"))}) {{");
|
||||||
_builder.AppendLine("@start");
|
_builder.AppendLine("@start");
|
||||||
GenerateBlock(node.Body);
|
GenerateBlock(node.Body);
|
||||||
if (!node.ReturnType.HasValue)
|
if (!node.ReturnType.HasValue)
|
||||||
@@ -79,6 +95,12 @@ public class Generator
|
|||||||
_builder.AppendLine("}");
|
_builder.AppendLine("}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void GenerateStructDefinition(StructDefinitionNode structDefinition)
|
||||||
|
{
|
||||||
|
var fields = structDefinition.Fields.Select(f => QbeTypeName(f.Type));
|
||||||
|
_builder.AppendLine($"type :{structDefinition.Name} = {{ {string.Join(", ", fields)} }}");
|
||||||
|
}
|
||||||
|
|
||||||
private void GenerateBlock(BlockNode block)
|
private void GenerateBlock(BlockNode block)
|
||||||
{
|
{
|
||||||
foreach (var statement in block.Statements.Where(_ => _codeIsReachable))
|
foreach (var statement in block.Statements.Where(_ => _codeIsReachable))
|
||||||
@@ -167,6 +189,7 @@ public class Generator
|
|||||||
GenerateBlock
|
GenerateBlock
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
_builder.AppendLine($"@{endLabel}");
|
_builder.AppendLine($"@{endLabel}");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -185,12 +208,22 @@ public class Generator
|
|||||||
|
|
||||||
private void GenerateVariableAssignment(VariableAssignmentNode variableAssignment)
|
private void GenerateVariableAssignment(VariableAssignmentNode variableAssignment)
|
||||||
{
|
{
|
||||||
_variables[variableAssignment.Name] = GenerateExpression(variableAssignment.Value);
|
var result = GenerateExpression(variableAssignment.Value);
|
||||||
|
_variables[variableAssignment.Name] = new Variable
|
||||||
|
{
|
||||||
|
Identifier = result,
|
||||||
|
Type = variableAssignment.Value.Type
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GenerateVariableReassignment(VariableReassignmentNode variableReassignment)
|
private void GenerateVariableReassignment(VariableReassignmentNode variableReassignment)
|
||||||
{
|
{
|
||||||
_variables[variableReassignment.Name] = GenerateExpression(variableReassignment.Value);
|
var result = GenerateExpression(variableReassignment.Value);
|
||||||
|
_variables[variableReassignment.Name] = new Variable
|
||||||
|
{
|
||||||
|
Identifier = result,
|
||||||
|
Type = variableReassignment.Value.Type
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GenerateWhile(WhileNode whileStatement)
|
private void GenerateWhile(WhileNode whileStatement)
|
||||||
@@ -237,7 +270,16 @@ public class Generator
|
|||||||
|
|
||||||
private string GenerateStructMemberAccessor(StructMemberAccessorNode structMemberAccessor)
|
private string GenerateStructMemberAccessor(StructMemberAccessorNode structMemberAccessor)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
var type = _variables.First(x => x.Key == structMemberAccessor.Fields[0]).Value.Type;
|
||||||
|
var def = _definitions.OfType<StructDefinitionNode>().FirstOrDefault(s => s.Name == type.Name);
|
||||||
|
if (def == null)
|
||||||
|
{
|
||||||
|
throw new Exception("def is null");
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new NotImplementedException("Not finished yet");
|
||||||
|
|
||||||
|
return $"load{QbeTypeName(structMemberAccessor.Type)} ";
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GenerateBinaryExpression(BinaryExpressionNode binaryExpression)
|
private string GenerateBinaryExpression(BinaryExpressionNode binaryExpression)
|
||||||
@@ -247,7 +289,7 @@ public class Generator
|
|||||||
|
|
||||||
private string GenerateIdentifier(IdentifierNode identifier)
|
private string GenerateIdentifier(IdentifierNode identifier)
|
||||||
{
|
{
|
||||||
return _variables[identifier.Identifier];
|
return _variables[identifier.Identifier].Identifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GenerateLiteral(LiteralNode literal)
|
private string GenerateLiteral(LiteralNode literal)
|
||||||
@@ -300,4 +342,11 @@ public class Generator
|
|||||||
_prefixIndexes[prefix] = index + 1;
|
_prefixIndexes[prefix] = index + 1;
|
||||||
return $"{prefix}_{index}";
|
return $"{prefix}_{index}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class Variable
|
||||||
|
{
|
||||||
|
public required string Identifier { get; init; }
|
||||||
|
public required NubType Type { get; init; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
namespace Nub.Lang.Frontend.Parsing;
|
namespace Nub.Lang.Frontend.Parsing;
|
||||||
|
|
||||||
public class StructDefinitionNode(string name, List<StructField> members) : DefinitionNode
|
public class StructDefinitionNode(string name, List<StructField> fields) : DefinitionNode
|
||||||
{
|
{
|
||||||
public string Name { get; } = name;
|
public string Name { get; } = name;
|
||||||
public List<StructField> Members { get; } = members;
|
public List<StructField> Fields { get; } = fields;
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
namespace Nub.Lang.Frontend.Parsing;
|
namespace Nub.Lang.Frontend.Parsing;
|
||||||
|
|
||||||
public class StructMemberAccessorNode(List<string> members) : ExpressionNode
|
public class StructMemberAccessorNode(List<string> fields) : ExpressionNode
|
||||||
{
|
{
|
||||||
public List<string> Members { get; } = members;
|
public List<string> Fields { get; } = fields;
|
||||||
}
|
}
|
||||||
@@ -43,7 +43,7 @@ public class ExpressionTyper
|
|||||||
|
|
||||||
foreach (var @class in _structDefinitions)
|
foreach (var @class in _structDefinitions)
|
||||||
{
|
{
|
||||||
foreach (var variable in @class.Members)
|
foreach (var variable in @class.Fields)
|
||||||
{
|
{
|
||||||
if (variable.Value.HasValue)
|
if (variable.Value.HasValue)
|
||||||
{
|
{
|
||||||
@@ -265,37 +265,37 @@ public class ExpressionTyper
|
|||||||
// TODO: Fix this ugly ass code
|
// TODO: Fix this ugly ass code
|
||||||
private void GenerateStructMemberAccessorNode(StructMemberAccessorNode structMemberAccessor)
|
private void GenerateStructMemberAccessorNode(StructMemberAccessorNode structMemberAccessor)
|
||||||
{
|
{
|
||||||
var variable = _variables.FirstOrDefault(v => v.Name == structMemberAccessor.Members[0]);
|
var variable = _variables.FirstOrDefault(v => v.Name == structMemberAccessor.Fields[0]);
|
||||||
if (variable == null)
|
if (variable == null)
|
||||||
{
|
{
|
||||||
throw new Exception($"Variable {structMemberAccessor.Members[0]} is not defined");
|
throw new Exception($"Variable {structMemberAccessor.Fields[0]} is not defined");
|
||||||
}
|
}
|
||||||
|
|
||||||
var definition = _structDefinitions.FirstOrDefault(sd => sd.Name == variable.Type.Name);
|
var definition = _structDefinitions.FirstOrDefault(sd => sd.Name == variable.Type.Name);
|
||||||
if (definition == null)
|
if (definition == null)
|
||||||
{
|
{
|
||||||
throw new Exception($"Struct {structMemberAccessor.Members[0]} is not defined");
|
throw new Exception($"Struct {structMemberAccessor.Fields[0]} is not defined");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var i = 1; i < structMemberAccessor.Members.Count - 1; i++)
|
for (var i = 1; i < structMemberAccessor.Fields.Count - 1; i++)
|
||||||
{
|
{
|
||||||
var member = definition.Members.FirstOrDefault(m => m.Name == structMemberAccessor.Members[i]);
|
var member = definition.Fields.FirstOrDefault(m => m.Name == structMemberAccessor.Fields[i]);
|
||||||
if (member == null)
|
if (member == null)
|
||||||
{
|
{
|
||||||
throw new Exception($"Member {structMemberAccessor.Members[i]} does not exist on struct {definition.Name}");
|
throw new Exception($"Member {structMemberAccessor.Fields[i]} does not exist on struct {definition.Name}");
|
||||||
}
|
}
|
||||||
|
|
||||||
definition = _structDefinitions.FirstOrDefault(sd => sd.Name == member.Type.Name);
|
definition = _structDefinitions.FirstOrDefault(sd => sd.Name == member.Type.Name);
|
||||||
if (definition == null)
|
if (definition == null)
|
||||||
{
|
{
|
||||||
throw new Exception($"Struct {structMemberAccessor.Members[i]} is not defined");
|
throw new Exception($"Struct {structMemberAccessor.Fields[i]} is not defined");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var tmp = definition.Members.FirstOrDefault(m => m.Name == structMemberAccessor.Members.Last());
|
var tmp = definition.Fields.FirstOrDefault(m => m.Name == structMemberAccessor.Fields.Last());
|
||||||
if (tmp == null)
|
if (tmp == null)
|
||||||
{
|
{
|
||||||
throw new Exception($"Member {structMemberAccessor.Members.Last()} does not exist on struct {definition.Name}");
|
throw new Exception($"Member {structMemberAccessor.Fields.Last()} does not exist on struct {definition.Name}");
|
||||||
}
|
}
|
||||||
|
|
||||||
structMemberAccessor.Type = tmp.Type;
|
structMemberAccessor.Type = tmp.Type;
|
||||||
|
|||||||
Reference in New Issue
Block a user