File: Resolve.h

package info (click to toggle)
storm-lang 0.7.5-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 52,028 kB
  • sloc: ansic: 261,471; cpp: 140,432; 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 (129 lines) | stat: -rw-r--r-- 4,808 bytes parent folder | download | duplicates (2)
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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#pragma once
#include "Expr.h"
#include "Block.h"
#include "Actuals.h"

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

		/**
		 * Custom name part used to traverse the named hierarchy and find elements that possibly
		 * need a 'this' pointer.
		 *
		 * To perform all name resolution in a single traversal of the name tree, the logic
		 * implemented here is as follows:
		 *
		 * 1. See if the raw name (i.e. without params) matches a type. If that is the case, match
		 *    the type if there is a suitable constructor there (so that we can later match a constructor call).
		 * 2. See if the name with parameters matches an entity. In that case, use that name.
		 * 3. See if the name with a this pointer matches an enity. If so, use that.
		 *
		 * In the implementation, we lump the two first together as a single pass.
		 *
		 * Note: We dont show the implicit this parameter, since some lookups will look at the first
		 * parameter to search in different parts of the name tree.
		 */
		class BSResolvePart : public BSNamePart {
			STORM_CLASS;
		public:
			// Create.
			STORM_CTOR BSResolvePart(Str *name, SrcPos pos, Actuals *params, MAYBE(Expr *) thisExpr);

			// Check if an item matches in the first step. We modify the lookup a bit here to check
			// for type constructors as well.
			virtual Int STORM_FN matches(Named *candidate, Scope source) const;

			// Provide the next part if we need it.
			virtual MAYBE(SimplePart *) STORM_FN nextOption() const;

		private:
			// Part used for the second option.
			MAYBE(SimplePart *) secondPass;

			// Lookup used to match constructors (cache object so we don't need memory allocations).
			mutable BSNamePart *ctorMatcher;
		};


		/**
		 * Custom named element that can be returned in name lookup to allow emitting custom expressions.
		 *
		 * By default, Basic Storm only knows about a pre-defined number of standard entities in the
		 * name tree. Returning this entity allows extending Basic Storm with new concepts, as the
		 * lookup mechanism in Basic Storm will ask the object to create an expression for itself.
		 */
		class CustomNamed : public Named {
			STORM_ABSTRACT_CLASS;
		public:
			// Create.
			STORM_CTOR CustomNamed(Str *name);
			STORM_CTOR CustomNamed(Str *name, Array<Value> *params);

			// Try to create an expression given a set of actual parameters.
			// If 'firstImplicit' is true, then the first parameter was added implicitly.
			virtual MAYBE(Expr *) STORM_FN create(Actuals *params, Bool firstImplicit) ABSTRACT;
		};


		/**
		 * Unresolved named expression returned from 'namedExpr' in case a name is not found. This
		 * is useful since parts of the system (such as the assignment operator when using setters)
		 * need to inspect and modify a possibly incorrect name.
		 *
		 * Accessing any of the member functions that would require a valid name will throw an
		 * appropriate exception. This basically means that the error 'namedExpr' would throw is
		 * delayed until another class tries to access the result rather than being thrown immediately.
		 */
		class UnresolvedName : public Expr {
			STORM_CLASS;
		public:
			// Create. Takes the same parameters as the internal 'findTarget' function so that the
			// same query can be repeated later on.
			UnresolvedName(Block *block, SimpleName *name, SrcPos pos, Actuals *params, Bool useThis);

			// Block.
			Block *block;

			// Name.
			SimpleName *name;

			// Actual parameters.
			Actuals *params;

			// Use the 'this' parameter?
			Bool useThis;

			// Retry with different parameters.
			Expr *retry(Actuals *params) const;

			// Result type.
			virtual ExprResult STORM_FN result();

			// Generate code.
			virtual void STORM_FN code(CodeGen *s, CodeResult *to);

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

		private:
			// Throw the error.
			void error() const;
		};


		// Find out what the named expression means, and create proper object.
		Expr *STORM_FN namedExpr(Block *block, syntax::SStr *name, Actuals *params);
		Expr *STORM_FN namedExpr(Block *block, SrcPos pos, Str *name, Actuals *params);
		Expr *STORM_FN namedExpr(Block *block, SrcName *name, Actuals *params);
		Expr *STORM_FN namedExpr(Block *block, SrcPos pos, Name *name, Actuals *params);

		// Special case of above, used when we find an expression like a.b(...). 'first' is inserted
		// into the beginning of 'params' and used. This method inhibits automatic insertion of 'this'.
		Expr *STORM_FN namedExpr(Block *block, syntax::SStr *name, Expr *first, Actuals *params);
		Expr *STORM_FN namedExpr(Block *block, syntax::SStr *name, Expr *first);
		Expr *STORM_FN namedExpr(Block *block, SrcPos pos, Str *name, Expr *first, Actuals *params);
		Expr *STORM_FN namedExpr(Block *block, SrcPos pos, Str *name, Expr *first);

	}
}