diff --git a/Compiler/.idea/.idea.Compiler/.idea/contentModel.xml b/Compiler/.idea/.idea.Compiler/.idea/contentModel.xml
index ecd131e..fe83073 100644
--- a/Compiler/.idea/.idea.Compiler/.idea/contentModel.xml
+++ b/Compiler/.idea/.idea.Compiler/.idea/contentModel.xml
@@ -7,8 +7,10 @@
+
+
diff --git a/Compiler/.idea/.idea.Compiler/.idea/workspace.xml b/Compiler/.idea/.idea.Compiler/.idea/workspace.xml
index 578830b..252fb4d 100644
--- a/Compiler/.idea/.idea.Compiler/.idea/workspace.xml
+++ b/Compiler/.idea/.idea.Compiler/.idea/workspace.xml
@@ -20,12 +20,13 @@
+
+
+
+
-
-
-
-
+
@@ -95,7 +96,6 @@
-
@@ -106,6 +106,10 @@
+
+
+
+
@@ -169,7 +173,7 @@
-
+
@@ -227,22 +231,22 @@
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
@@ -311,10 +315,10 @@
-
+
-
+
@@ -331,14 +335,14 @@
-
+
-
-
+
+
-
+
@@ -348,23 +352,4 @@
-
-
-
-
- file://$PROJECT_DIR$/Compiler.cs
- 138
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Compiler/Compiler.cs b/Compiler/Compiler.cs
index 1d66f96..0b2a1f9 100644
--- a/Compiler/Compiler.cs
+++ b/Compiler/Compiler.cs
@@ -25,30 +25,7 @@ namespace Compiler
}
else
{
- DevMode();
- }
- }
- }
-
- static void DevMode()
- {
- for (int i = 1; i <= 2; i++)
- {
- Console.WriteLine($"---------------------valid, stage {i}-------------------------------");
- foreach (string file in Directory.GetFiles($"/home/clemens/repositorys/lcc/stage_{i}/valid"))
- {
- Console.WriteLine("-------------");
- List tokens = TestLexer(file, 0);
- TestParser(tokens, file, 1);
- }
-
-
- Console.WriteLine($"---------------------invalid, stage {i}-------------------------------");
- foreach (string file in Directory.GetFiles($"/home/clemens/repositorys/lcc/stage_{i}/invalid"))
- {
- Console.WriteLine("-------------");
- List tokens = TestLexer(file, 0);
- TestParser(tokens, file, 1);
+ DevFunctions.DevMode();
}
}
}
@@ -57,7 +34,7 @@ namespace Compiler
{
bool debug = false;
string inputFileName = args[0].Split("/").Last();
- string outputPath = args[0].Substring(0, args[0].LastIndexOf("/"));
+ string outputPath = args[0].Substring(0, args[0].LastIndexOf("/", StringComparison.Ordinal));
if (args.Length == 2)
{
@@ -134,91 +111,5 @@ namespace Compiler
Console.WriteLine(e.Message);
}
}
-
- static void PrettyPrint(Node root, string indent)
- {
- switch (root.NodeType)
- {
- case NodeType.FunctionNode:
- Console.WriteLine(indent + root.NodeType + ":" + ((FunctionNode) root).Name);
- break;
- case NodeType.ConstantNode:
- Console.WriteLine(indent + root.NodeType + ":" + ((ConstantNode) root).value);
- break;
- case NodeType.UnaryOperatorNode:
- Console.WriteLine(indent + root.NodeType + ":" + ((UnaryOperatorNode) root).OperatorType);
- break;
-
- default:
- Console.WriteLine(indent + root.NodeType);
- break;
- }
-
- foreach (Node child in root.Children)
- {
- PrettyPrint(child, indent + " ");
- }
- }
-
- static void TestGenerator(Node root, string destinationPath, int debugLevel)
- {
- if (root != null)
- {
- Generator.Generator gen = new Generator.Generator();
- string asm = gen.Generate(root);
-
- if (debugLevel > 0)
- {
- Console.Write(asm);
- }
- }
- }
-
- static List TestLexer(string path, int debugLevel)
- {
- Lexer.Lexer lexer = new Lexer.Lexer();
-
-
- StreamReader file = new StreamReader(path);
- string contents = file.ReadToEnd();
-
- List tokens = lexer.Lex(contents);
- Console.WriteLine("Lexed \"" + path.Split("/").Last() + "\"");
-
- if (debugLevel > 0)
- {
- foreach (Token token in tokens)
- {
- Console.WriteLine(token.ToString());
- }
- }
-
-
- return tokens;
- }
-
- static Node TestParser(List tokenList, string path, int debugLevel)
- {
- Parser.Parser p = new Parser.Parser(tokenList);
-
- try
- {
- Node programNode = p.Parse(NodeType.ProgramNode);
- Console.WriteLine("Parsed \"" + path.Split("/").Last() + "\"");
- if (debugLevel > 0)
- {
- PrettyPrint(programNode, "");
- }
-
- return programNode;
- }
- catch (Exception e)
- {
- Console.WriteLine("Error in file \"" + path.Split("/").Last() + "\"");
- Console.WriteLine(e.Message);
- }
-
- return null;
- }
}
}
\ No newline at end of file
diff --git a/Compiler/DevFunctions.cs b/Compiler/DevFunctions.cs
new file mode 100644
index 0000000..86280b2
--- /dev/null
+++ b/Compiler/DevFunctions.cs
@@ -0,0 +1,124 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using Compiler.Lexer;
+using Compiler.Parser.Nodes;
+
+namespace Compiler
+{
+ public static class DevFunctions
+ {
+ static void PrettyPrint(Node root, string indent)
+ {
+ switch (root.NodeType)
+ {
+ case NodeType.FunctionNode:
+ Console.WriteLine(indent + root.NodeType + ":" + ((FunctionNode) root).Name);
+ break;
+ case NodeType.ConstantNode:
+ Console.WriteLine(indent + root.NodeType + ":" + ((ConstantNode) root).value);
+ break;
+ case NodeType.UnaryOperatorNode:
+ Console.WriteLine(indent + root.NodeType + ":" + ((UnaryOperatorNode) root).OperatorType);
+ break;
+
+ default:
+ Console.WriteLine(indent + root.NodeType);
+ break;
+ }
+
+ foreach (Node child in root.Children)
+ {
+ PrettyPrint(child, indent + " ");
+ }
+ }
+
+ static void TestGenerator(Node root, int debugLevel)
+ {
+ if (root != null)
+ {
+ Generator.Generator gen = new Generator.Generator();
+ string asm = gen.Generate(root);
+
+ if (debugLevel > 0)
+ {
+ Console.Write(asm);
+ }
+ }
+ }
+
+ static List TestLexer(string path, int debugLevel)
+ {
+ Lexer.Lexer lexer = new Lexer.Lexer();
+
+
+ StreamReader file = new StreamReader(path);
+ string contents = file.ReadToEnd();
+
+ List tokens = lexer.Lex(contents);
+ Console.WriteLine("Lexed \"" + path.Split("/").Last() + "\"");
+
+ if (debugLevel > 0)
+ {
+ foreach (Token token in tokens)
+ {
+ Console.WriteLine(token.ToString());
+ }
+ }
+
+
+ return tokens;
+ }
+
+ static Node TestParser(List tokenList, string path, int debugLevel)
+ {
+ Parser.Parser p = new Parser.Parser(tokenList);
+
+ try
+ {
+ Node programNode = p.Parse(NodeType.ProgramNode);
+ Console.WriteLine("Parsed \"" + path.Split("/").Last() + "\"");
+ if (debugLevel > 0)
+ {
+ PrettyPrint(programNode, "");
+ }
+
+ return programNode;
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("Error in file \"" + path.Split("/").Last() + "\"");
+ Console.WriteLine(e.Message);
+ }
+
+ return null;
+ }
+
+ public static void DevMode()
+ {
+ for (int i = 1; i <= 2; i++)
+ {
+ Console.WriteLine($"---------------------valid, stage {i}-------------------------------");
+ foreach (string file in Directory.GetFiles($"/home/clemens/repositorys/lcc/stage_{i}/valid"))
+ {
+ Console.WriteLine("-------------");
+ List tokens = TestLexer(file, 0);
+ Node programNode = TestParser(tokens, file, 1);
+ TestGenerator(programNode, 1);
+ }
+
+ /*
+ Console.WriteLine($"---------------------invalid, stage {i}-------------------------------");
+ foreach (string file in Directory.GetFiles($"/home/clemens/repositorys/lcc/stage_{i}/invalid"))
+ {
+ Console.WriteLine("-------------");
+ List tokens = TestLexer(file, 0);
+ Node programNode = TestParser(tokens, file, 0);
+ TestGenerator(programNode, 1);
+ }
+ */
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Compiler/Generator/Generator.cs b/Compiler/Generator/Generator.cs
index c3337b0..84c2c4e 100644
--- a/Compiler/Generator/Generator.cs
+++ b/Compiler/Generator/Generator.cs
@@ -32,14 +32,40 @@ namespace Compiler.Generator
$"{functionBody}";
break;
case NodeType.ReturnStatementNode:
- s = $"movl ${Generate(rootNode.Children[0])}, %eax \n" +
+ s = $"{Generate(rootNode.Children[0])}" +
"ret\n";
break;
case NodeType.ExpressionNode:
- s = ((ConstantNode) rootNode).value.ToString();
+ 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 ArgumentOutOfRangeException();
+ throw new NotSpecifiedException(rootNode.NodeType);
}
return s;
diff --git a/Compiler/Generator/NotSpecifiedException.cs b/Compiler/Generator/NotSpecifiedException.cs
new file mode 100644
index 0000000..e9e5990
--- /dev/null
+++ b/Compiler/Generator/NotSpecifiedException.cs
@@ -0,0 +1,21 @@
+using System;
+using Compiler.Lexer;
+using Compiler.Parser.Nodes;
+
+namespace Compiler.Generator
+{
+ public class NotSpecifiedException : Exception
+ {
+ public override string Message { get; }
+
+ public NotSpecifiedException(NodeType nodeType)
+ {
+ Message = $"No code generation for {nodeType} specified.";
+ }
+
+ public NotSpecifiedException(NodeType nodeType, OperatorType operatorType)
+ {
+ Message = $"No code generation for {nodeType}:{operatorType} specified.";
+ }
+ }
+}
\ No newline at end of file
diff --git a/test b/test
new file mode 100755
index 0000000..e69de29