diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index e6af150cbf4cebb493e667c134adc13f322240eb..c53d6f5ad168101bf718b47951d8a11705d41e76 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -14,7 +14,7 @@ before_script:
     esac
   - export JOBS=$(grep -c processor /proc/cpuinfo)
   - apk add --no-cache build-base bash libexecinfo-dev
-        cppunit-dev libxml2-dev tclap-dev $EXTRA_PKGS
+        cppunit-dev libxml2-dev tclap-dev readline-dev $EXTRA_PKGS
   - case "$CI_BUILD_NAME" in
       *-clang) ln -s /usr/lib/llvm4/lib/LLVMgold.so /usr/lib/LLVMgold.so;;
       *) ;;
diff --git a/aql2/makefile.conf b/aql2/makefile.conf
index 4556c5f00da4df610b4a4f9f0215e8579c70abe2..29eb6afc9426066de4aa1be41f114f88170db798 100644
--- a/aql2/makefile.conf
+++ b/aql2/makefile.conf
@@ -1,4 +1,4 @@
 EXECUTABLE:=aql2
 LINK_PATHS=../alib2cli/ ../alib2elgo/ ../alib2algo/ ../alib2raw/ ../alib2str/ ../alib2data/ ../alib2common/ ../alib2std/
-LINK_LIBRARIES=alib2cli alib2elgo alib2algo alib2raw alib2str alib2data alib2common alib2std xml2
+LINK_LIBRARIES=alib2cli alib2elgo alib2algo alib2raw alib2str alib2data alib2common alib2std xml2 readline
 INCLUDE_PATHS=\$$(SOURCES_BASE_DIR)/../../alib2cli/src/ \$$(SOURCES_BASE_DIR)/../../alib2data/src/ \$$(SOURCES_BASE_DIR)/../../alib2common/src/ \$$(SOURCES_BASE_DIR)/../../alib2std/src/ /usr/include/libxml2/
diff --git a/aql2/src/aql.cpp b/aql2/src/aql.cpp
index e899dc450664baed063d8e92bd76b0470c467363..cdfe7d1decf90fd18e5f13e3ed6a66d579c92e79 100644
--- a/aql2/src/aql.cpp
+++ b/aql2/src/aql.cpp
@@ -1,11 +1,10 @@
 /*
  * aql.cpp
  *
- *  Created on: 26. 3. 2014
+ *  Created on: 1. 7. 2017
  *	  Author: Jan Travnicek
  */
 
-#include <measure>
 #include <istream>
 #include <iostream>
 
@@ -27,11 +26,13 @@ std::istream& operator>> ( std::istream & in, std::pair < T, U > & value ) {
 	return in;
 }
 
+#include <string>
+
+#include <measure>
 #include <tclap/CmdLine.h>
 #include <global/GlobalData.h>
 
-#include <lexer/Lexer.h>
-#include <parser/Parser.h>
+#include "prompt/Prompt.h"
 
 namespace TCLAP {
 
@@ -50,7 +51,7 @@ int main ( int argc, char * argv[] ) {
 
 		TCLAP::CmdLine cmd ( "Algorithms query language binary", ' ', "0.01" );
 
-		TCLAP::ValueArg < std::string > query ( "q", "query", "Query index", true, "", "query" );
+		TCLAP::ValueArg < std::string > query ( "q", "query", "Query index", false, "", "query" );
 		cmd.add ( query );
 
 		TCLAP::SwitchArg measure ( "m", "measure", "Measure times", false );
@@ -79,15 +80,20 @@ int main ( int argc, char * argv[] ) {
 			environment.set ( param.first, param.second );
 		}
 
-		cli::Parser parser ( cli::Lexer ( query.getValue ( ) ) );
-		parser.execute ( )->translateAndEval ( nullptr, environment );
+		Prompt p ( std::move ( environment ) );
+
+		int result = 0;
+		if ( query.isSet ( ) )
+			result = p.execute_line ( query.getValue ( ) );
+		else
+			result = p.run ( );
 
 		measurements::end ( );
 
 		if ( measure.getValue ( ) )
 			std::cmeasure << measurements::results ( ) << std::endl;
 
-		return 0;
+		return result;
 	} catch ( const exception::CommonException & exception ) {
 		alib::XmlDataFactory::toStdout ( exception );
 		return 1;
diff --git a/aql2/src/prompt/Prompt.cpp b/aql2/src/prompt/Prompt.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..8d98c9c6ae75beca050998d8e0f5c462ee4d8113
--- /dev/null
+++ b/aql2/src/prompt/Prompt.cpp
@@ -0,0 +1,65 @@
+/*
+ * Prompt.cpp
+ *
+ *  Created on: 20. 7. 2017
+ *	  Author: Jan Travnicek
+ */
+
+#include "Prompt.h"
+
+#include <cstdlib>
+#include <cctype>
+#include <cstring>
+
+#include <readline/readline.h>
+#include <readline/history.h>
+
+#include <lexer/Lexer.h>
+#include <parser/Parser.h>
+
+char * Prompt::stripwhite ( char * begin ) {
+	while ( isspace ( * begin ) )
+		++ begin;
+
+	char * end = begin + strlen ( begin ) - 1;
+	while ( end >= begin && isspace ( * end ) )
+		-- end;
+
+	if ( end >= begin )
+		* ++ end = '\0';
+
+	return begin;
+}
+
+Prompt::Prompt ( cli::Environment environment ) : m_prefix ( "> " ), m_active ( true ), m_exec_result ( 0 ), m_environment ( std::move ( environment ) ) {
+}
+
+int Prompt::run ( ) {
+	while ( m_active ) {
+		char * line = readline ( m_prefix.c_str ( ) );
+
+		if ( ! line )
+			continue;
+
+		char * s = stripwhite ( line );
+
+		if ( * s ) {
+			add_history ( s );
+			execute_line ( std::string ( s ) );
+		}
+
+		free ( line );
+	}
+	return m_exec_result;
+}
+
+int Prompt::execute_line ( std::string line ) {
+	if ( line == "quit" ) {
+		m_active = false;
+		m_exec_result = 0;
+	} else {
+		cli::Parser parser = cli::Parser ( cli::Lexer ( line ) );
+		parser.execute ( )->translateAndEval ( nullptr, m_environment );
+	}
+	return m_exec_result;
+}
diff --git a/aql2/src/prompt/Prompt.h b/aql2/src/prompt/Prompt.h
new file mode 100644
index 0000000000000000000000000000000000000000..db0341300c5c7d7e0960ebf960f699119b6d8d5a
--- /dev/null
+++ b/aql2/src/prompt/Prompt.h
@@ -0,0 +1,35 @@
+/*
+ * Prompt.h
+ *
+ *  Created on: 20. 3. 2017
+ *	  Author: Jan Travnicek
+ */
+
+#ifndef _AQL_PROMPT_H_
+#define _AQL_PROMPT_H_
+
+#include <string>
+#include <parser/Parser.h>
+
+class Prompt {
+	Prompt ( const Prompt & ) = delete;
+	Prompt ( Prompt && ) = delete;
+	Prompt & operator = ( const Prompt & ) = delete;
+	Prompt & operator = ( Prompt && ) = delete;
+
+	std::string m_prefix;
+	bool m_active;
+	int m_exec_result;
+
+	cli::Environment m_environment;
+
+	char * stripwhite ( char * begin );
+
+public:
+	Prompt ( cli::Environment environment );
+
+	int run ( );
+	int execute_line ( std::string line );
+};
+
+#endif /* _AQL_PROMPT_H_ */