From 996e78ae0ff1c29af4a30724e0a494159c9974a6 Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Thu, 14 Nov 2019 07:46:56 +0100
Subject: [PATCH] eval and interpret commands in aql

---
 alib2cli/src/ast/command/EvalCommand.h      | 31 ++++++++++++++++++
 alib2cli/src/ast/command/InterpretCommand.h | 36 +++++++++++++++++++++
 alib2cli/src/parser/Parser.cpp              | 15 +++++++++
 3 files changed, 82 insertions(+)
 create mode 100644 alib2cli/src/ast/command/EvalCommand.h
 create mode 100644 alib2cli/src/ast/command/InterpretCommand.h

diff --git a/alib2cli/src/ast/command/EvalCommand.h b/alib2cli/src/ast/command/EvalCommand.h
new file mode 100644
index 0000000000..db30797c3d
--- /dev/null
+++ b/alib2cli/src/ast/command/EvalCommand.h
@@ -0,0 +1,31 @@
+#ifndef _CLI_EVAL_COMMAND_H_
+#define _CLI_EVAL_COMMAND_H_
+
+#include <ast/Command.h>
+#include <environment/Environment.h>
+
+#include <readline/StringLineInterface.h>
+#include <iostream>
+
+namespace cli {
+
+class EvalCommand : public Command {
+	std::string m_code;
+
+public:
+	EvalCommand ( std::string code ) : m_code ( std::move ( code ) ) {
+	}
+
+	CommandResult run ( Environment & environment ) const override {
+		CommandResult state = environment.execute ( std::make_shared < cli::StringLineInterface > ( cli::StringLineInterface ( m_code ) ) );
+
+		if ( state != cli::CommandResult::QUIT )
+			state = cli::CommandResult::OK;
+
+		return state;
+	}
+};
+
+} /* namespace cli */
+
+#endif /* _CLI_EVAL_COMMAND_H_ */
diff --git a/alib2cli/src/ast/command/InterpretCommand.h b/alib2cli/src/ast/command/InterpretCommand.h
new file mode 100644
index 0000000000..afd07d79fa
--- /dev/null
+++ b/alib2cli/src/ast/command/InterpretCommand.h
@@ -0,0 +1,36 @@
+#ifndef _CLI_INTERPRET_COMMAND_H_
+#define _CLI_INTERPRET_COMMAND_H_
+
+#include <ast/Command.h>
+#include <environment/Environment.h>
+
+#include <readline/IstreamLineInterface.h>
+#include <fstream>
+
+namespace cli {
+
+class InterpretCommand : public Command {
+	std::string m_fileName;
+
+public:
+	InterpretCommand ( std::string libraryName ) : m_fileName ( std::move ( libraryName ) ) {
+	}
+
+	CommandResult run ( Environment & environment ) const override {
+		std::ifstream ifs ( m_fileName );
+
+		if ( ! ifs.is_open ( ) )
+			throw exception::CommonException ( "File '" + m_fileName + "' not found." );
+
+		CommandResult state = environment.execute ( std::make_shared < cli::IstreamLineInterface < std::ifstream > > ( cli::IstreamLineInterface < std::ifstream > ( std::move ( ifs ) ) ) );
+
+		if ( state != cli::CommandResult::QUIT )
+			state = cli::CommandResult::OK;
+
+		return state;
+	}
+};
+
+} /* namespace cli */
+
+#endif /* _CLI_INTERPRET_COMMAND_H_ */
diff --git a/alib2cli/src/parser/Parser.cpp b/alib2cli/src/parser/Parser.cpp
index dfc425932c..2d62f5eea7 100644
--- a/alib2cli/src/parser/Parser.cpp
+++ b/alib2cli/src/parser/Parser.cpp
@@ -31,6 +31,8 @@
 #include <ast/command/UnloadCommand.h>
 #include <ast/command/CalcCommand.h>
 #include <ast/command/BlockCommand.h>
+#include <ast/command/EvalCommand.h>
+#include <ast/command/InterpretCommand.h>
 
 #include <ast/expression/BinaryExpression.h>
 #include <ast/expression/PrefixExpression.h>
@@ -435,6 +437,19 @@ std::unique_ptr < Command > Parser::command ( ) {
 		return std::make_unique < CalcCommand > ( std::move ( expr ) );
 	} else if ( check_nonreserved_kw ( "begin" ) ) {
 		return std::make_unique < BlockCommand > ( block ( ) );
+	} else if ( check_nonreserved_kw ( "eval" ) ) {
+		match_nonreserved_kw ( "eval" );
+		std::string evalString = getTokenValue ( );
+		match ( cli::Lexer::TokenType::UNSIGNED, cli::Lexer::TokenType::IDENTIFIER, cli::Lexer::TokenType::STRING );
+		return std::make_unique < EvalCommand > ( std::move ( evalString ) );
+	} else if ( check_nonreserved_kw ( "interpret" ) ) {
+		match_nonreserved_kw ( "interpret" );
+
+		setHint ( Lexer::Hint::FILE );
+		std::string fileName = getTokenValue ( );
+		match ( cli::Lexer::TokenType::FILE, cli::Lexer::TokenType::STRING );
+
+		return std::make_unique < InterpretCommand > ( std::move ( fileName ) );
 	} else {
 		throw exception::CommonException ( "Mismatched set " + ext::to_string ( getCheckOptions ( ) ) + " while expanding parse rule. Token is " + ( ( std::string ) m_current ) + "." );
 	}
-- 
GitLab