diff --git a/alib2cli/src/ast/command/VarDeclareCommand.h b/alib2cli/src/ast/command/VarDeclareCommand.h new file mode 100644 index 0000000000000000000000000000000000000000..22e949a97b415f13006fff36b0317fb0a6d2ec7f --- /dev/null +++ b/alib2cli/src/ast/command/VarDeclareCommand.h @@ -0,0 +1,28 @@ +#ifndef _CLI_VAR_DECLARE_COMMAND_H_ +#define _CLI_VAR_DECLARE_COMMAND_H_ + +#include <ast/Command.h> +#include <environment/Environment.h> + +namespace cli { + +class VarDeclareCommand : public Command { + std::unique_ptr < cli::Arg > m_name; + abstraction::ParamQualifiers::ParamQualifierSet m_paramQualifierSet; + std::unique_ptr < Expression > m_expr; + +public: + VarDeclareCommand ( std::unique_ptr < cli::Arg > name, abstraction::ParamQualifiers::ParamQualifierSet paramQualifierSet, std::unique_ptr < Expression > expr ) : m_name ( std::move ( name ) ), m_paramQualifierSet ( paramQualifierSet ), m_expr ( std::move ( expr ) ) { + } + + CommandResult run ( Environment & environment ) const override { + std::shared_ptr < abstraction::Value > value = m_expr->translateAndEval ( environment ); + std::shared_ptr < abstraction::Value > res = value->clone ( m_paramQualifierSet, false ); + environment.setVariable ( m_name->eval ( environment ), res ); + return CommandResult::OK; + } +}; + +} /* namespace cli */ + +#endif /* _CLI_VAR_DECLARE_COMMAND_H_ */ diff --git a/alib2cli/src/parser/Parser.cpp b/alib2cli/src/parser/Parser.cpp index 43098ba3bb5f6900eed9fb5cba25ffe808b51470..e5fc822b7bf5d0c03102592cee317959348df2f6 100644 --- a/alib2cli/src/parser/Parser.cpp +++ b/alib2cli/src/parser/Parser.cpp @@ -38,6 +38,7 @@ #include <ast/command/BreakCommand.h> #include <ast/command/ContinueCommand.h> #include <ast/command/ReturnCommand.h> +#include <ast/command/VarDeclareCommand.h> #include <ast/expression/BatchExpression.h> #include <ast/expression/BinaryExpression.h> @@ -535,6 +536,34 @@ std::unique_ptr < Command > Parser::command ( ) { throw exception::CommonException ( "Statement not available in global scope." ); match_nonreserved_kw ( "continue" ); return std::make_unique < ContinueCommand > ( ); + } else if ( check_nonreserved_kw ( "declare" ) ) { + match_nonreserved_kw ( "declare" ); + + abstraction::ParamQualifiers::ParamQualifierSet paramQualifierSet = abstraction::ParamQualifiers::ParamQualifierSet::NONE; + + if ( check_nonreserved_kw ( "const" ) ) { + match_nonreserved_kw ( "const" ); + paramQualifierSet = paramQualifierSet | abstraction::ParamQualifiers::ParamQualifierSet::CONST; + } + + match_nonreserved_kw ( "auto" ); + + if ( check ( cli::Lexer::TokenType::AND_OPERATOR ) ) { + match ( cli::Lexer::TokenType::AND_OPERATOR ); + paramQualifierSet = paramQualifierSet | abstraction::ParamQualifiers::ParamQualifierSet::RREF; + } else if ( check ( cli::Lexer::TokenType::AMPERSAND_SIGN ) ) { + match ( cli::Lexer::TokenType::AMPERSAND_SIGN ); + paramQualifierSet = paramQualifierSet | abstraction::ParamQualifiers::ParamQualifierSet::LREF; + } + + match ( cli::Lexer::TokenType::DOLAR_SIGN ); + std::unique_ptr < Arg > name = arg ( ); + + match ( cli::Lexer::TokenType::ASSIGN_OPERATOR ); + + std::unique_ptr < Expression > expr = expression ( ); + + return std::make_unique < VarDeclareCommand > ( std::move ( name ), paramQualifierSet, std::move ( expr ) ); } else { throw exception::CommonException ( "Mismatched set " + ext::to_string ( getCheckOptions ( ) ) + " while expanding parse rule. Token is " + ( ( std::string ) m_current ) + "." ); }