- ast: added root and macro nodes and processing of them scripting

Tue, 03 Feb 2015 15:26:07 +0200

author
Teemu Piippo <crimsondusk64@gmail.com>
date
Tue, 03 Feb 2015 15:26:07 +0200
branch
scripting
changeset 924
d1ac217c9165
parent 923
e15a577a0bfe
child 925
2f316b57b508

- ast: added root and macro nodes and processing of them

CMakeLists.txt file | annotate | diff | comparison | revisions
src/script/ast.cpp file | annotate | diff | comparison | revisions
src/script/ast.h file | annotate | diff | comparison | revisions
src/script/parser.cpp file | annotate | diff | comparison | revisions
src/script/parser.h file | annotate | diff | comparison | revisions
--- a/CMakeLists.txt	Tue Feb 03 04:03:19 2015 +0200
+++ b/CMakeLists.txt	Tue Feb 03 15:26:07 2015 +0200
@@ -73,6 +73,7 @@
 	src/editmodes/selectMode.cc
 	src/script/parser.cpp
 	src/script/objtype.cpp
+	src/script/ast.cpp
 )
 
 set (LDFORGE_HEADERS
@@ -109,6 +110,9 @@
 	src/editmodes/magicWandMode.h
 	src/editmodes/rectangleMode.h
 	src/editmodes/selectMode.h
+	src/script/parser.h
+	src/script/objtype.h
+	src/script/ast.h
 )
 
 set (LDFORGE_FORMS
--- a/src/script/ast.cpp	Tue Feb 03 04:03:19 2015 +0200
+++ b/src/script/ast.cpp	Tue Feb 03 15:26:07 2015 +0200
@@ -1,7 +1,40 @@
 #include "ast.h"
 
-Script::AstNode::AstNode (QSharedPointer<AstNode> parent) :
-	m_parent (parent)
+Script::Ast::BaseNode::BaseNode (NodePointer parent, NodeType type) :
+	m_parent (parent),
+	m_type (type)
+{
+}
+
+Script::Ast::BaseNode::~BaseNode() {}
+
+void Script::Ast::BaseNode::dump()
 {
+	static QString tabs;
 
+	if (children().isEmpty())
+	{
+		print (tabs + describe() + "\n");
+	}
+	else
+	{
+		print (tabs + describe() + ":\n");
+
+		for (NodePointer child : children())
+		{
+			tabs += '\t';
+			child->dump();
+			tabs.chop(1);
+		}
+	}
 }
+
+QString Script::Ast::RootNode::describe() const
+{
+	return "root";
+}
+
+QString Script::Ast::MacroNode::describe() const
+{
+	return format ("macro (%1)", m_macroName);
+}
\ No newline at end of file
--- a/src/script/ast.h	Tue Feb 03 04:03:19 2015 +0200
+++ b/src/script/ast.h	Tue Feb 03 15:26:07 2015 +0200
@@ -1,23 +1,75 @@
 #pragma once
 #include <QVector>
 #include <QSharedPointer>
+#include "../main.h"
 
 namespace Script
 {
-	using AstPointer = QSharedPointer<class AstNode>;
-
-	enum AstNodeType
-	{
-
-	};
-
-	class AstNode
+	namespace Ast
 	{
-	public:
-		AstNode (AstPointer parent);
+		using NodePointer = QSharedPointer<class BaseNode>;
+		using RootPointer = QSharedPointer<class RootNode>;
+		using MacroPointer = QSharedPointer<class MacroNode>;
+
+		enum NodeType
+		{
+			ROOT,
+			MACRO,
+		};
+
+		class BaseNode
+		{
+		public:
+			BaseNode (NodePointer parent, NodeType type);
+			virtual ~BaseNode() = 0;
+
+			NodeType type() const { return m_type; }
+			NodePointer parent() const { return m_parent; }
+			QVector<NodePointer> children() const { return m_children; }
+			void addChild (NodePointer child) { m_children.append (child); }
+			void dump();
+			virtual QString describe() const = 0;
+
+		private:
+			QVector<NodePointer> m_children;
+			NodePointer m_parent;
+			NodeType m_type;
+		};
 
-	private:
-		QVector<AstPointer> m_children;
-		AstPointer m_parent;
-	};
+		class RootNode : public BaseNode
+		{
+		public:
+			RootNode() : BaseNode (NodePointer(), ROOT) {}
+			QString describe() const override;
+		};
+
+		class MacroNode : public BaseNode
+		{
+		public:
+			MacroNode (NodePointer parent, QString macroName) :
+				BaseNode (parent, MACRO),
+				m_macroName (macroName) {}
+
+			QString macroName() const { return m_macroName; }
+			QString describe() const override;
+
+		private:
+			QString m_macroName;
+		};
+
+		template<typename T, typename... Args>
+		QSharedPointer<T> spawn (NodePointer parent, Args&&... args)
+		{
+			static_assert (std::is_base_of<BaseNode, T>::value,
+				"Script::Ast::spawn can only be used for AST types.");
+			QSharedPointer<T> ast (new T (parent, args...));
+			parent->addChild (ast);
+			return ast;
+		}
+
+		inline RootPointer spawnRoot()
+		{
+			return RootPointer (new RootNode());
+		}
+	}
 }
--- a/src/script/parser.cpp	Tue Feb 03 04:03:19 2015 +0200
+++ b/src/script/parser.cpp	Tue Feb 03 15:26:07 2015 +0200
@@ -89,11 +89,25 @@
 {
 	preprocess();
 	m_state.reset();
+	m_astRoot = Ast::spawnRoot();
 
-	while (next (TOK_Any))
+	while (next())
 	{
-		print ("token: %1 (%2)\n", state().token.text, TokenNames[state().token.type]);
+		if (m_state.token.type == TOK_Semicolon)
+			continue;
+
+		tokenMustBe (TOK_Macro);
+		mustGetNext (TOK_Symbol);
+		Ast::MacroPointer macroAst = Ast::spawn<Ast::MacroNode> (m_astRoot, state().token.text);
+		mustGetNext (TOK_Semicolon);
+
+		do
+		{
+			mustGetNext();
+		} while (m_state.token.type != TOK_EndMacro);
 	}
+
+	m_astRoot->dump();
 }
 
 //
@@ -571,4 +585,17 @@
 
 	unread();
 	return identifier;
-}
\ No newline at end of file
+}
+
+//
+// -------------------------------------------------------------------------------------------------
+//
+void Script::Parser::tokenMustBe (TokenType desiredType)
+{
+	if (m_state.token.type != desiredType)
+	{
+		scriptError ("expected %1, got %2",
+			TokenNames[desiredType],
+			TokenNames[m_state.token.type]);
+	}
+}
--- a/src/script/parser.h	Tue Feb 03 04:03:19 2015 +0200
+++ b/src/script/parser.h	Tue Feb 03 15:26:07 2015 +0200
@@ -141,6 +141,7 @@
 		void skipSpace();
 		bool isAtEnd() const { return m_state.position >= m_data.length(); }
 		bool tryMatch (const char* text, bool caseSensitive);
+		void tokenMustBe (TokenType desiredType);
 
 		template<typename... Args>
 		void scriptError (QString text, Args... args)
@@ -153,7 +154,7 @@
 		QByteArray m_data;
 		QVector<int> m_lineEndings;
 		SavedState m_state;
-		AstNode* m_astRoot;
+		Ast::RootPointer m_astRoot;
 		Token m_rejectedToken;
 
 		void parseString();

mercurial