File: If.cpp

package info (click to toggle)
storm-lang 0.7.4-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • 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 (87 lines) | stat: -rw-r--r-- 1,921 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
#include "stdafx.h"
#include "If.h"
#include "Cast.h"
#include "Named.h"
#include "Compiler/Engine.h"
#include "Compiler/Exception.h"
#include "Compiler/Lib/Maybe.h"

namespace storm {
	namespace bs {

		If::If(Block *parent, Condition *cond) : Block(cond->pos(), parent), condition(cond) {
			successBlock = new (this) CondSuccess(pos, this, condition);
		}

		If::If(Block *parent, Expr *expr) : Block(expr->pos, parent) {
			condition = new (this) BoolCondition(expr);
			successBlock = new (this) CondSuccess(pos, this, condition);
		}

		void If::success(Expr *expr) {
			successBlock->set(expr);
		}

		void If::fail(Expr *expr) {
			failStmt = expr;
		}

		ExprResult If::result() {
			if (failStmt) {
				return common(successBlock, failStmt, scope);
			} else {
				return ExprResult();
			}
		}

		void If::blockCode(CodeGen *state, CodeResult *r) {
			using namespace code;

			Value condType(StormInfo<Bool>::type(engine()));
			CodeResult *condResult = new (this) CodeResult(condType, state->block);
			condition->code(state, condResult);

			Label lblElse = state->l->label();
			Label lblDone = state->l->label();

			code::Var c = condResult->location(state);
			*state->l << cmp(c, byteConst(0));
			*state->l << jmp(lblElse, ifEqual);

			Value rType = result().type();

			// True branch:
			{
				Expr *t = expectCastTo(successBlock, rType, scope);
				t->code(state, r->split(state));
			}

			if (failStmt) {
				*state->l << jmp(lblDone);
			}

			*state->l << lblElse;

			if (failStmt) {
				// False branch:
				Expr *f = expectCastTo(failStmt, rType, scope);
				f->code(state, r->split(state));

				*state->l << lblDone;
			}

			// Notify that all branches have created the value.
			r->created(state);
		}

		void If::toS(StrBuf *to) const {
			*to << S("if (") << condition << S(") ");
			*to << successBlock;
			if (failStmt) {
				*to << S(" else ");
				*to << failStmt;
			}
		}

	}
}