lcc/Compiler/Generator/Generator.cs
2020-08-21 00:18:21 +02:00

74 lines
No EOL
2.7 KiB
C#

using System;
using System.Linq;
using Compiler.Parser;
using Compiler.Parser.Nodes;
namespace Compiler.Generator
{
public class Generator
{
public string Generate(Node rootNode)
{
string s = "";
switch (rootNode.NodeType)
{
case NodeType.ProgramNode:
foreach (Node rootNodeChild in rootNode.Children)
{
s += Generate(rootNodeChild);
}
break;
case NodeType.FunctionNode:
string identifier = ((FunctionNode) rootNode).Name;
string functionBody = "";
foreach (Node rootNodeChild in rootNode.Children)
{
functionBody += Generate(rootNodeChild);
}
s = $".globl {identifier}\n" +
$"{identifier}:\n" +
$"{functionBody}";
break;
case NodeType.ReturnStatementNode:
s = $"{Generate(rootNode.Children[0])}" +
"ret\n";
break;
case NodeType.ExpressionNode:
s = Generate(rootNode.Children[0]);
break;
case NodeType.ConstantNode:
s = $"movl ${((ConstantNode) rootNode).value.ToString()}, %eax\n";
break;
case NodeType.UnaryOperatorNode:
switch (((UnaryOperatorNode) rootNode).OperatorType)
{
case OperatorType.Negation:
s = $"{Generate(rootNode.Children[0])}" +
"neg %eax\n";
break;
case OperatorType.BitwiseComplement:
s = $"{Generate(rootNode.Children[0])}" +
"not %eax\n";
break;
case OperatorType.LogicalNegation:
s = $"{Generate(rootNode.Children[0])}" +
"cmpl $0, %eax\n" +
"movl $0, %eax\n" + //xorl %eax, %eax should also work, but doesn't
"sete %al\n";
break;
default:
throw new NotSpecifiedException(NodeType.UnaryOperatorNode,
((UnaryOperatorNode) rootNode).OperatorType);
}
break;
default:
throw new NotSpecifiedException(rootNode.NodeType);
}
return s;
}
}
}