#pragma once
#include "Expr.h"
#include "Condition.h"

namespace storm {
	namespace bs {
		STORM_PKG(lang.bs);

		/**
		 * Implements the unless (<cast>) return X; ... syntax.
		 *
		 * Note: Will "leak" the created variable into the parent block (much like variable
		 * definitions). This is so that we can structure the grammar more easily and avoid
		 * ambiguities.
		 */
		class Unless : public Expr {
			STORM_CLASS;
		public:
			// Create. Note: requiring 'expr' here means that it is natural to create 'fail' before
			// calling the constructor. This reduces the possibility of accidentally referencing
			// the new variables before they are created.
			STORM_CTOR Unless(Block *block, Condition *cond, Expr *fail);

			// Condition.
			Condition *cond;

			// Statement to be executed if the cast fails. Needs to be set to something that never
			// returns (e.g. 'return', 'break').
			Expr *fail;

			// Result (always void - it is invalid to use 'unless' as an expression in the grammar).
			virtual ExprResult STORM_FN result();

			// Generate code.
			virtual void STORM_FN code(CodeGen *state, CodeResult *r);

			// Output.
			virtual void STORM_FN toS(StrBuf *to) const;
		};


	}
}
