File: Condition.cpp

package info (click to toggle)
storm-lang 0.7.4-1
  • links: PTS, VCS
  • area: main
  • in suites: forky
  • size: 52,004 kB
  • sloc: ansic: 261,462; cpp: 140,405; sh: 14,891; perl: 9,846; python: 2,525; lisp: 2,504; asm: 860; makefile: 678; pascal: 70; java: 52; xml: 37; awk: 12
file content (114 lines) | stat: -rw-r--r-- 2,377 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#include "stdafx.h"
#include "Condition.h"
#include "WeakCast.h"
#include "Compiler/Exception.h"
#include "Compiler/Lib/Maybe.h"

namespace storm {
	namespace bs {

		/**
		 * Condition.
		 */

		Condition::Condition() {}

		SrcPos Condition::pos() {
			return SrcPos();
		}

		MAYBE(LocalVar *) Condition::result() {
			return null;
		}

		void Condition::trueCode(CodeGen *) {}


		/**
		 * Boolean condition.
		 */

		BoolCondition::BoolCondition(Expr *expr) : expr(expr) {
			if (expr->result().type().asRef(false) != Value(StormInfo<Bool>::type(engine())))
				throw new (this) TypeError(expr->pos, S("The expression must evaluate to Bool."));
		}

		SrcPos BoolCondition::pos() {
			return expr->largePos();
		}

		MAYBE(LocalVar *) BoolCondition::result() {
			// We never create anything!
			return null;
		}

		void BoolCondition::code(CodeGen *state, CodeResult *ok) {
			expr->code(state, ok);
		}

		void BoolCondition::toS(StrBuf *to) const {
			*to << expr;
		}


		// Create suitable conditions.
		Condition *STORM_FN createCondition(Expr *expr) {
			Value result = expr->result().type().asRef(false);

			if (result == Value(StormInfo<Bool>::type(expr->engine()))) {
				return new (expr) BoolCondition(expr);
			} else if (isMaybe(result)) {
				return new (expr) WeakMaybeCast(expr);
			} else {
				Str *msg = TO_S(expr->engine(), S("You can not use the type ")
								<< result << S(" as a condition."));
				throw new (expr) SyntaxError(expr->pos, msg);
			}
		}


		/**
		 * CondSuccess.
		 */

		CondSuccess::CondSuccess(SrcPos pos, Block *parent, Condition *cond) : Block(pos, parent), cond(cond) {
			if (LocalVar *var = cond->result())
				add(var);
		}

		void CondSuccess::set(Expr *e) {
			if (expr)
				throw new (e) UsageError(S("Cannot call CondSuccess::set multiple times!"));
			expr = e;
		}

		ExprResult CondSuccess::result() {
			if (expr)
				return expr->result();
			else
				return ExprResult();
		}

		void CondSuccess::blockCode(CodeGen *state, CodeResult *to) {
			// Initialize new variable if required:
			cond->trueCode(state);

			// Then we can execute the contained expression!
			if (expr)
				expr->code(state, to);
		}

		Int CondSuccess::castPenalty(Value to) {
			if (expr)
				return expr->castPenalty(to);
			else
				return -1;
		}

		void CondSuccess::toS(StrBuf *to) const {
			if (expr)
				*to << expr;
		}

	}
}