binary expressions
This commit is contained in:
1
debug.sh
1
debug.sh
@@ -1,4 +1,5 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
set -e
|
||||||
./clean.sh
|
./clean.sh
|
||||||
./build.sh
|
./build.sh
|
||||||
gdb -tui ./out/program
|
gdb -tui ./out/program
|
||||||
|
|||||||
@@ -1,22 +1,7 @@
|
|||||||
import "c";
|
import "c";
|
||||||
|
|
||||||
struct Human {
|
|
||||||
age: int64 = 0;
|
|
||||||
name: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
global func main() {
|
global func main() {
|
||||||
while true {
|
if 3 / 3 == 1 {
|
||||||
let dad = new Human
|
puts("uwu");
|
||||||
{
|
|
||||||
name = "John";
|
|
||||||
};
|
|
||||||
|
|
||||||
printName(dad);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func printName(human: Human) {
|
|
||||||
puts(human.name);
|
|
||||||
}
|
}
|
||||||
1
run.sh
1
run.sh
@@ -1,4 +1,5 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
set -e
|
||||||
./clean.sh
|
./clean.sh
|
||||||
./build.sh
|
./build.sh
|
||||||
./out/program
|
./out/program
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ public class Generator
|
|||||||
Type = parameter.Type
|
Type = parameter.Type
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node.Global)
|
if (node.Global)
|
||||||
{
|
{
|
||||||
_builder.Append("export ");
|
_builder.Append("export ");
|
||||||
@@ -284,9 +284,9 @@ public class Generator
|
|||||||
{
|
{
|
||||||
throw new Exception($"Struct {structType.Name} is not defined");
|
throw new Exception($"Struct {structType.Name} is not defined");
|
||||||
}
|
}
|
||||||
|
|
||||||
var @struct = GenerateExpression(structFieldAccessor.Struct);
|
var @struct = GenerateExpression(structFieldAccessor.Struct);
|
||||||
|
|
||||||
var fieldIndex = -1;
|
var fieldIndex = -1;
|
||||||
for (var i = 0; i < structDefinition.Fields.Count; i++)
|
for (var i = 0; i < structDefinition.Fields.Count; i++)
|
||||||
{
|
{
|
||||||
@@ -296,24 +296,235 @@ public class Generator
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fieldIndex == -1)
|
if (fieldIndex == -1)
|
||||||
{
|
{
|
||||||
throw new Exception($"Field {structFieldAccessor.Field} is not defined in struct {structType.Name}");
|
throw new Exception($"Field {structFieldAccessor.Field} is not defined in struct {structType.Name}");
|
||||||
}
|
}
|
||||||
|
|
||||||
var offsetLabel = GenName("offset");
|
var offsetLabel = GenName("offset");
|
||||||
_builder.AppendLine($" %{offsetLabel} ={QbeTypeName(structFieldAccessor.Type)} add {@struct}, {fieldIndex * QbeTypeSize(structFieldAccessor.Type)}");
|
_builder.AppendLine($" %{offsetLabel} ={QbeTypeName(structFieldAccessor.Type)} add {@struct}, {fieldIndex * QbeTypeSize(structFieldAccessor.Type)}");
|
||||||
|
|
||||||
var outputLabel = GenName("field");
|
var outputLabel = GenName("field");
|
||||||
_builder.AppendLine($" %{outputLabel} ={QbeTypeName(structFieldAccessor.Type)} load{QbeTypeName(structFieldAccessor.Type)} %{offsetLabel}");
|
_builder.AppendLine($" %{outputLabel} ={QbeTypeName(structFieldAccessor.Type)} load{QbeTypeName(structFieldAccessor.Type)} %{offsetLabel}");
|
||||||
|
|
||||||
return $"%{outputLabel}";
|
return $"%{outputLabel}";
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GenerateBinaryExpression(BinaryExpressionNode binaryExpression)
|
private string GenerateBinaryExpression(BinaryExpressionNode binaryExpression)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
var left = GenerateExpression(binaryExpression.Left);
|
||||||
|
var right = GenerateExpression(binaryExpression.Right);
|
||||||
|
var outputLabel = GenName();
|
||||||
|
|
||||||
|
switch (binaryExpression.Operator)
|
||||||
|
{
|
||||||
|
case BinaryExpressionOperator.Equal:
|
||||||
|
{
|
||||||
|
if (binaryExpression.Left.Type.Equals(NubType.Int64) && binaryExpression.Right.Type.Equals(NubType.Int64))
|
||||||
|
{
|
||||||
|
_builder.AppendLine($" %{outputLabel} =w ceql {left}, {right}");
|
||||||
|
return $"%{outputLabel}";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (binaryExpression.Left.Type.Equals(NubType.Int32) && binaryExpression.Right.Type.Equals(NubType.Int32))
|
||||||
|
{
|
||||||
|
_builder.AppendLine($" %{outputLabel} =w ceqw {left}, {right}");
|
||||||
|
return $"%{outputLabel}";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (binaryExpression.Left.Type.Equals(NubType.String) && binaryExpression.Right.Type.Equals(NubType.String))
|
||||||
|
{
|
||||||
|
_builder.AppendLine($" %{outputLabel} =w call $nub_strcmp(l {left}, l {right})");
|
||||||
|
return $"%{outputLabel}";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (binaryExpression.Left.Type.Equals(NubType.Bool) && binaryExpression.Right.Type.Equals(NubType.Bool))
|
||||||
|
{
|
||||||
|
_builder.AppendLine($" %{outputLabel} =w ceqw {left}, {right}");
|
||||||
|
return $"%{outputLabel}";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BinaryExpressionOperator.NotEqual:
|
||||||
|
{
|
||||||
|
if (binaryExpression.Left.Type.Equals(NubType.Int64) && binaryExpression.Right.Type.Equals(NubType.Int64))
|
||||||
|
{
|
||||||
|
_builder.AppendLine($" %{outputLabel} =w cnel {left}, {right}");
|
||||||
|
return $"%{outputLabel}";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (binaryExpression.Left.Type.Equals(NubType.Int32) && binaryExpression.Right.Type.Equals(NubType.Int32))
|
||||||
|
{
|
||||||
|
_builder.AppendLine($" %{outputLabel} =w cnew {left}, {right}");
|
||||||
|
return $"%{outputLabel}";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (binaryExpression.Left.Type.Equals(NubType.String) && binaryExpression.Right.Type.Equals(NubType.String))
|
||||||
|
{
|
||||||
|
_builder.AppendLine($" %{outputLabel} =w call $nub_strcmp(l {left}, l {right})");
|
||||||
|
_builder.AppendLine($" %{outputLabel} =w xor %{outputLabel}, 1");
|
||||||
|
return $"%{outputLabel}";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (binaryExpression.Left.Type.Equals(NubType.Bool) && binaryExpression.Right.Type.Equals(NubType.Bool))
|
||||||
|
{
|
||||||
|
_builder.AppendLine($" %{outputLabel} =w cnew {left}, {right}");
|
||||||
|
return $"%{outputLabel}";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BinaryExpressionOperator.GreaterThan:
|
||||||
|
{
|
||||||
|
if (binaryExpression.Left.Type.Equals(NubType.Int64) && binaryExpression.Right.Type.Equals(NubType.Int64))
|
||||||
|
{
|
||||||
|
_builder.AppendLine($" %{outputLabel} =w csgtl {left}, {right}");
|
||||||
|
return $"%{outputLabel}";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (binaryExpression.Left.Type.Equals(NubType.Int32) && binaryExpression.Right.Type.Equals(NubType.Int32))
|
||||||
|
{
|
||||||
|
_builder.AppendLine($" %{outputLabel} =w csgtw {left}, {right}");
|
||||||
|
return $"%{outputLabel}";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (binaryExpression.Left.Type.Equals(NubType.Bool) && binaryExpression.Right.Type.Equals(NubType.Bool))
|
||||||
|
{
|
||||||
|
_builder.AppendLine($" %{outputLabel} =w csgtw {left}, {right}");
|
||||||
|
return $"%{outputLabel}";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BinaryExpressionOperator.GreaterThanOrEqual:
|
||||||
|
{
|
||||||
|
if (binaryExpression.Left.Type.Equals(NubType.Int64) && binaryExpression.Right.Type.Equals(NubType.Int64))
|
||||||
|
{
|
||||||
|
_builder.AppendLine($" %{outputLabel} =w csgel {left}, {right}");
|
||||||
|
return $"%{outputLabel}";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (binaryExpression.Left.Type.Equals(NubType.Int32) && binaryExpression.Right.Type.Equals(NubType.Int32))
|
||||||
|
{
|
||||||
|
_builder.AppendLine($" %{outputLabel} =w csgew {left}, {right}");
|
||||||
|
return $"%{outputLabel}";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (binaryExpression.Left.Type.Equals(NubType.Bool) && binaryExpression.Right.Type.Equals(NubType.Bool))
|
||||||
|
{
|
||||||
|
_builder.AppendLine($" %{outputLabel} =w csgew {left}, {right}");
|
||||||
|
return $"%{outputLabel}";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BinaryExpressionOperator.LessThan:
|
||||||
|
{
|
||||||
|
if (binaryExpression.Left.Type.Equals(NubType.Int64) && binaryExpression.Right.Type.Equals(NubType.Int64))
|
||||||
|
{
|
||||||
|
_builder.AppendLine($" %{outputLabel} =w csltl {left}, {right}");
|
||||||
|
return $"%{outputLabel}";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (binaryExpression.Left.Type.Equals(NubType.Int32) && binaryExpression.Right.Type.Equals(NubType.Int32))
|
||||||
|
{
|
||||||
|
_builder.AppendLine($" %{outputLabel} =w csltw {left}, {right}");
|
||||||
|
return $"%{outputLabel}";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (binaryExpression.Left.Type.Equals(NubType.Bool) && binaryExpression.Right.Type.Equals(NubType.Bool))
|
||||||
|
{
|
||||||
|
_builder.AppendLine($" %{outputLabel} =w csltw {left}, {right}");
|
||||||
|
return $"%{outputLabel}";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BinaryExpressionOperator.LessThanOrEqual:
|
||||||
|
{
|
||||||
|
if (binaryExpression.Left.Type.Equals(NubType.Int64) && binaryExpression.Right.Type.Equals(NubType.Int64))
|
||||||
|
{
|
||||||
|
_builder.AppendLine($" %{outputLabel} =w cslel {left}, {right}");
|
||||||
|
return $"%{outputLabel}";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (binaryExpression.Left.Type.Equals(NubType.Int32) && binaryExpression.Right.Type.Equals(NubType.Int32))
|
||||||
|
{
|
||||||
|
_builder.AppendLine($" %{outputLabel} =w cslew {left}, {right}");
|
||||||
|
return $"%{outputLabel}";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (binaryExpression.Left.Type.Equals(NubType.Bool) && binaryExpression.Right.Type.Equals(NubType.Bool))
|
||||||
|
{
|
||||||
|
_builder.AppendLine($" %{outputLabel} =w cslew {left}, {right}");
|
||||||
|
return $"%{outputLabel}";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BinaryExpressionOperator.Plus:
|
||||||
|
{
|
||||||
|
if (binaryExpression.Left.Type.Equals(NubType.Int64) && binaryExpression.Right.Type.Equals(NubType.Int64))
|
||||||
|
{
|
||||||
|
_builder.AppendLine($" %{outputLabel} =l add {left}, {right}");
|
||||||
|
return $"%{outputLabel}";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (binaryExpression.Left.Type.Equals(NubType.Int32) && binaryExpression.Right.Type.Equals(NubType.Int32))
|
||||||
|
{
|
||||||
|
_builder.AppendLine($" %{outputLabel} =w add {left}, {right}");
|
||||||
|
return $"%{outputLabel}";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BinaryExpressionOperator.Minus:
|
||||||
|
{
|
||||||
|
if (binaryExpression.Left.Type.Equals(NubType.Int64) && binaryExpression.Right.Type.Equals(NubType.Int64))
|
||||||
|
{
|
||||||
|
_builder.AppendLine($" %{outputLabel} =l sub {left}, {right}");
|
||||||
|
return $"%{outputLabel}";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (binaryExpression.Left.Type.Equals(NubType.Int32) && binaryExpression.Right.Type.Equals(NubType.Int32))
|
||||||
|
{
|
||||||
|
_builder.AppendLine($" %{outputLabel} =w sub {left}, {right}");
|
||||||
|
return $"%{outputLabel}";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BinaryExpressionOperator.Multiply:
|
||||||
|
{
|
||||||
|
if (binaryExpression.Left.Type.Equals(NubType.Int64) && binaryExpression.Right.Type.Equals(NubType.Int64))
|
||||||
|
{
|
||||||
|
_builder.AppendLine($" %{outputLabel} =l mul {left}, {right}");
|
||||||
|
return $"%{outputLabel}";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (binaryExpression.Left.Type.Equals(NubType.Int32) && binaryExpression.Right.Type.Equals(NubType.Int32))
|
||||||
|
{
|
||||||
|
_builder.AppendLine($" %{outputLabel} =w mul {left}, {right}");
|
||||||
|
return $"%{outputLabel}";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BinaryExpressionOperator.Divide:
|
||||||
|
{
|
||||||
|
if (binaryExpression.Left.Type.Equals(NubType.Int64) && binaryExpression.Right.Type.Equals(NubType.Int64))
|
||||||
|
{
|
||||||
|
_builder.AppendLine($" %{outputLabel} =l div {left}, {right}");
|
||||||
|
return $"%{outputLabel}";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (binaryExpression.Left.Type.Equals(NubType.Int32) && binaryExpression.Right.Type.Equals(NubType.Int32))
|
||||||
|
{
|
||||||
|
_builder.AppendLine($" %{outputLabel} =w div {left}, {right}");
|
||||||
|
return $"%{outputLabel}";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
throw new ArgumentOutOfRangeException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new NotSupportedException($"Binary operator {binaryExpression.Operator} for types left: {binaryExpression.Left.Type}, right: {binaryExpression.Right.Type} not supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GenerateIdentifier(IdentifierNode identifier)
|
private string GenerateIdentifier(IdentifierNode identifier)
|
||||||
@@ -362,7 +573,7 @@ public class Generator
|
|||||||
for (var i = 0; i < structDefinition.Fields.Count; i++)
|
for (var i = 0; i < structDefinition.Fields.Count; i++)
|
||||||
{
|
{
|
||||||
var field = structDefinition.Fields[i];
|
var field = structDefinition.Fields[i];
|
||||||
|
|
||||||
if (structInitializer.Initializers.TryGetValue(field.Name, out var fieldValue))
|
if (structInitializer.Initializers.TryGetValue(field.Name, out var fieldValue))
|
||||||
{
|
{
|
||||||
var var = GenerateExpression(fieldValue);
|
var var = GenerateExpression(fieldValue);
|
||||||
@@ -396,23 +607,22 @@ public class Generator
|
|||||||
|
|
||||||
var parameters = results.Select(p => $"{QbeTypeName(p.Item2)} {p.Item1}");
|
var parameters = results.Select(p => $"{QbeTypeName(p.Item2)} {p.Item1}");
|
||||||
|
|
||||||
var output = GenName("var");
|
var output = GenName();
|
||||||
_builder.AppendLine($" %{output} ={QbeTypeName(funcCall.Type)} call ${funcCall.FuncCall.Name}({string.Join(", ", parameters)})");
|
_builder.AppendLine($" %{output} ={QbeTypeName(funcCall.Type)} call ${funcCall.FuncCall.Name}({string.Join(", ", parameters)})");
|
||||||
|
|
||||||
return $"%{output}";
|
return $"%{output}";
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GenName(string prefix)
|
private string GenName(string prefix = "var")
|
||||||
{
|
{
|
||||||
var index = _prefixIndexes.GetValueOrDefault(prefix, 0);
|
var index = _prefixIndexes.GetValueOrDefault(prefix, 0);
|
||||||
_prefixIndexes[prefix] = index + 1;
|
_prefixIndexes[prefix] = index + 1;
|
||||||
return $"{prefix}_{index}";
|
return $"{prefix}_{index}";
|
||||||
}
|
}
|
||||||
|
|
||||||
private class Variable
|
private class Variable
|
||||||
{
|
{
|
||||||
public required string Identifier { get; init; }
|
public required string Identifier { get; init; }
|
||||||
public required NubType Type { get; init; }
|
public required NubType Type { get; init; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user