Add parser
diff --git a/Parser.cpp b/Parser.cpp
new file mode 100644
index 0000000..2d6b992
--- /dev/null
+++ b/Parser.cpp
@@ -0,0 +1,193 @@
+#include "Parser.h"
+
+#include <QDebug>
+
+Parser::Parser(QString input)
+{
+ _input = input;
+}
+
+QChar Parser::peek()
+{
+ if (atEnd())
+ return 0;
+
+ return _input[_pos];
+}
+
+QChar Parser::get()
+{
+ return _input[_pos++];
+}
+
+bool Parser::atEnd()
+{
+ return _pos >= _input.length();
+}
+
+void Parser::skip()
+{
+ while (peek().isSpace())
+ get();
+}
+
+bool Parser::parseSymbol(AstNode *node)
+{
+ skip();
+
+ if (peek().isLetter())
+ {
+ *node = AstNode(get());
+ return true;
+ }
+
+ return false;
+}
+
+bool Parser::parseIdentifier(AstNode *node)
+{
+ skip();
+
+ QString buffer;
+
+ if (peek().isUpper())
+ {
+ while (peek().isLetter() || peek() == '-' || peek() == '_' || peek().isNumber())
+ {
+ buffer += get();
+ }
+
+ *node = AstNode(buffer);
+ return true;
+ }
+
+ return false;
+}
+
+bool Parser::parseNumber(AstNode *node)
+{
+ skip();
+
+ QString buffer;
+
+ if (peek().isDigit())
+ {
+ while (peek().isDigit())
+ buffer += get();
+
+ *node = AstNode(buffer.toInt());
+ return true;
+ }
+
+ return false;
+}
+
+bool Parser::parseVariable(AstNode *node)
+{
+ skip();
+
+ int pos = _pos;
+
+ if (peek() == 's' || peek() == 'e' || peek() == 't')
+ {
+ char type = get().toLatin1();
+
+ if (peek() == '.')
+ {
+ get();
+
+ AstNode identNode;
+
+ if (parseIdentifier(&identNode))
+ {
+ *node = AstNode(type, identNode.name());
+ return true;
+ }
+ }
+ }
+
+ _pos = pos;
+ return false;
+}
+
+bool Parser::parseOne(AstNode *node)
+{
+ return parseFunction(node) ||
+ parseVariable(node) ||
+ parseNumber(node) ||
+ parseIdentifier(node) ||
+ parseSymbol(node) ||
+ parseParens(node);
+}
+
+QList<AstNode> Parser::parseMany()
+{
+ QList<AstNode> nodes;
+ AstNode next;
+
+ while (parseOne(&next))
+ {
+ nodes.append(next);
+ }
+
+ return nodes;
+}
+
+bool Parser::parseParens(AstNode *node)
+{
+ skip();
+
+ int pos = _pos;
+
+ if (peek() != '(')
+ return false;
+
+ get();
+
+ QList<AstNode> many = parseMany();
+ *node = AstNode(many);
+
+ skip();
+ if (peek() != ')')
+ {
+ _pos = pos;
+ return false;
+ }
+
+ get();
+
+ return true;
+}
+
+bool Parser::parseFunction(AstNode *node)
+{
+ skip();
+
+ int pos = _pos;
+
+ if (peek() != '<')
+ return false;
+
+ get();
+
+ AstNode head;
+ if (!parseIdentifier(&head))
+ {
+ _pos = pos;
+ return false;
+ }
+
+ QList<AstNode> body = parseMany();
+ *node = AstNode(head.name(), body);
+
+ skip();
+ if (peek() != '>')
+ {
+ _pos = pos;
+ return false;
+ }
+
+ get();
+
+ return true;
+}