1 |
3
|
krennw
|
/**
|
2 |
|
|
*
|
3 |
|
|
* OOAS Compiler (Deprecated)
|
4 |
|
|
*
|
5 |
|
|
* Copyright 2015, Institute for Software Technology, Graz University of
|
6 |
|
|
* Technology. Portions are copyright 2015 by the AIT Austrian Institute
|
7 |
|
|
* of Technology. All rights reserved.
|
8 |
|
|
*
|
9 |
|
|
* SEE THE "LICENSE" FILE FOR THE TERMS UNDER WHICH THIS FILE IS PROVIDED.
|
10 |
|
|
*
|
11 |
|
|
* Please notice that this version of the OOAS compiler is considered de-
|
12 |
|
|
* precated. Only the Java version is maintained.
|
13 |
|
|
*
|
14 |
|
|
* Contributors:
|
15 |
|
|
* Willibald Krenn (TU Graz/AIT)
|
16 |
|
|
* Stefan Tiran (TU Graz/AIT)
|
17 |
|
|
*/
|
18 |
|
|
|
19 |
|
|
using System;
|
20 |
|
|
using Antlr.Runtime;
|
21 |
|
|
using System.Text;
|
22 |
|
|
using System.Collections.Generic;
|
23 |
|
|
using System.Text.RegularExpressions;
|
24 |
|
|
|
25 |
|
|
namespace TUG.Mogentes
|
26 |
|
|
{
|
27 |
|
|
|
28 |
|
|
public class CompilerMessage
|
29 |
|
|
{
|
30 |
|
|
private string m_file;
|
31 |
|
|
private int m_line;
|
32 |
|
|
private int m_column;
|
33 |
|
|
private string m_message;
|
34 |
|
|
|
35 |
|
|
public CompilerMessage(string aFile, int aLine, int aColumn, string aMessage)
|
36 |
|
|
{
|
37 |
|
|
m_file = aFile;
|
38 |
|
|
m_line = aLine;
|
39 |
|
|
m_column = aColumn;
|
40 |
|
|
m_message = aMessage;
|
41 |
|
|
}
|
42 |
|
|
|
43 |
|
|
public CompilerMessage(string aFile, IToken aSymbol, string aMessage)
|
44 |
|
|
{
|
45 |
|
|
m_file = aFile;
|
46 |
|
|
m_line = aSymbol.Line;
|
47 |
|
|
m_column = aSymbol.CharPositionInLine;
|
48 |
|
|
m_message = aMessage;
|
49 |
|
|
}
|
50 |
|
|
|
51 |
|
|
public string file { get { return m_file; } }
|
52 |
|
|
public int line { get { return m_line; } }
|
53 |
|
|
public int column { get { return m_column; } }
|
54 |
|
|
public string message { get { return m_message; } }
|
55 |
|
|
|
56 |
|
|
}
|
57 |
|
|
|
58 |
|
|
|
59 |
|
|
public class ParserError : CompilerMessage
|
60 |
|
|
{
|
61 |
|
|
public ParserError(string aFile, int aLine, int aColumn, string aMessage)
|
62 |
|
|
: base(aFile, aLine, aColumn, aMessage)
|
63 |
|
|
{ }
|
64 |
|
|
|
65 |
|
|
public ParserError(string aFile, IToken aSymbol, string aMessage)
|
66 |
|
|
: base(aFile, aSymbol, aMessage)
|
67 |
|
|
{ }
|
68 |
|
|
}
|
69 |
|
|
|
70 |
|
|
|
71 |
|
|
public class ParserWarning : CompilerMessage
|
72 |
|
|
{
|
73 |
|
|
public ParserWarning(string aFile, int aLine, int aColumn, string aMessage)
|
74 |
|
|
: base(aFile, aLine, aColumn, aMessage)
|
75 |
|
|
{ }
|
76 |
|
|
|
77 |
|
|
public ParserWarning(string aFile, IToken aSymbol, string aMessage)
|
78 |
|
|
: base(aFile, aSymbol, aMessage)
|
79 |
|
|
{ }
|
80 |
|
|
}
|
81 |
|
|
|
82 |
|
|
public class ParserMessage : CompilerMessage
|
83 |
|
|
{
|
84 |
|
|
public ParserMessage(string aFile, int aLine, int aColumn, string aMessage)
|
85 |
|
|
: base(aFile, aLine, aColumn, aMessage)
|
86 |
|
|
{ }
|
87 |
|
|
|
88 |
|
|
public ParserMessage(string aFile, IToken aSymbol, string aMessage)
|
89 |
|
|
: base(aFile, aSymbol, aMessage)
|
90 |
|
|
{ }
|
91 |
|
|
}
|
92 |
|
|
|
93 |
|
|
|
94 |
|
|
public class ParserState
|
95 |
|
|
{
|
96 |
|
|
public ooaParser parser;
|
97 |
|
|
public ooaLexer lexer;
|
98 |
|
|
public string filename;
|
99 |
|
|
public string namesTypePrefix = String.Empty;
|
100 |
|
|
public bool parsingAttributes;
|
101 |
|
|
|
102 |
|
|
|
103 |
|
|
public MainModule ooaSystem;
|
104 |
|
|
|
105 |
|
|
public IScope currentScope;
|
106 |
|
|
public List<ParserError> listOfParserErrors;
|
107 |
|
|
public List<ParserWarning> listOfParserWarnings;
|
108 |
|
|
public List<ParserMessage> listOfParserMessages;
|
109 |
|
|
public List<OpaqueType> typesToFixUp;
|
110 |
|
|
|
111 |
|
|
public ParserState(Program.Options options)
|
112 |
|
|
{
|
113 |
|
|
listOfParserErrors = new List<ParserError>();
|
114 |
|
|
listOfParserWarnings = new List<ParserWarning>();
|
115 |
|
|
listOfParserMessages = new List<ParserMessage>();
|
116 |
|
|
typesToFixUp = new List<OpaqueType>();
|
117 |
|
|
this.filename = options.fileToParse;
|
118 |
|
|
this.namesTypePrefix = options.namedTypePrefix;
|
119 |
|
|
ICharStream input = new ANTLRFileStream(filename, Encoding.ASCII);
|
120 |
|
|
lexer = new ooaLexer(input);
|
121 |
|
|
CommonTokenStream tokens = new CommonTokenStream(lexer);
|
122 |
|
|
parser = new ooaParser(tokens);
|
123 |
|
|
parser.pState = this;
|
124 |
|
|
}
|
125 |
|
|
|
126 |
|
|
public void AddErrorMessage(ParserError parserError)
|
127 |
|
|
{
|
128 |
|
|
listOfParserErrors.Add(parserError);
|
129 |
|
|
}
|
130 |
|
|
public void AddWarningMessage(ParserWarning parserWarning)
|
131 |
|
|
{
|
132 |
|
|
listOfParserWarnings.Add(parserWarning);
|
133 |
|
|
}
|
134 |
|
|
public void AddMessage(ParserMessage aMessage)
|
135 |
|
|
{
|
136 |
|
|
listOfParserMessages.Add(aMessage);
|
137 |
|
|
}
|
138 |
|
|
|
139 |
|
|
public Identifier Lookup(string symbolName, IScope resolveStack)
|
140 |
|
|
{
|
141 |
|
|
string lkupname = symbolName;
|
142 |
|
|
do
|
143 |
|
|
{
|
144 |
|
|
Identifier result = resolveStack.ResolveIdentifier(lkupname);
|
145 |
|
|
if (result != null)
|
146 |
|
|
return result;
|
147 |
|
|
resolveStack = resolveStack.GetParentScope();
|
148 |
|
|
} while (resolveStack != null);
|
149 |
|
|
|
150 |
|
|
return null;
|
151 |
|
|
}
|
152 |
|
|
public Identifier Lookup(string symbolName)
|
153 |
|
|
{
|
154 |
|
|
return Lookup(symbolName, currentScope);
|
155 |
|
|
}
|
156 |
|
|
public Identifier Lookup(IToken symbolName)
|
157 |
|
|
{
|
158 |
|
|
if (symbolName != null)
|
159 |
|
|
return Lookup(symbolName.Text);
|
160 |
|
|
else
|
161 |
|
|
return null;
|
162 |
|
|
}
|
163 |
|
|
|
164 |
|
|
public void PushResolveStack(IScope newScope)
|
165 |
|
|
{
|
166 |
|
|
// some sanity check.
|
167 |
|
|
if (newScope is MethodIdentifier)
|
168 |
|
|
System.Diagnostics.Debug.Assert(currentScope is OoActionSystemType);
|
169 |
|
|
|
170 |
|
|
newScope.SetParentScope(currentScope);
|
171 |
|
|
currentScope = newScope;
|
172 |
|
|
}
|
173 |
|
|
public void PopResolveStack()
|
174 |
|
|
{
|
175 |
|
|
currentScope = currentScope.GetParentScope();
|
176 |
|
|
}
|
177 |
|
|
}
|
178 |
|
|
|
179 |
|
|
|
180 |
|
|
public partial class ooaParser : Parser
|
181 |
|
|
{
|
182 |
|
|
public ParserState pState { get; set; }
|
183 |
|
|
|
184 |
|
|
|
185 |
|
|
|
186 |
|
|
|
187 |
|
|
public bool IsRightToLeft(ExpressionKind type)
|
188 |
|
|
{
|
189 |
|
|
return type == ExpressionKind.implies; // implication has right grouping
|
190 |
|
|
}
|
191 |
|
|
|
192 |
|
|
public int GetOperatorPrecedence(ExpressionKind type)
|
193 |
|
|
{
|
194 |
|
|
switch (type)
|
195 |
|
|
{
|
196 |
|
|
/*Family of Evaluators*/
|
197 |
|
|
|
198 |
|
|
case ExpressionKind.abs: // T_ABS:
|
199 |
|
|
case ExpressionKind.card: // T_CARD:
|
200 |
|
|
case ExpressionKind.dom: // T_DOM:
|
201 |
|
|
case ExpressionKind.range: // T_RNG:
|
202 |
|
|
case ExpressionKind.merge: // T_MERGE:
|
203 |
|
|
case ExpressionKind.len: // T_LEN:
|
204 |
|
|
case ExpressionKind.elems: // T_ELEMS:
|
205 |
|
|
case ExpressionKind.head: // T_HEAD:
|
206 |
|
|
case ExpressionKind.tail: // T_TAIL:
|
207 |
|
|
case ExpressionKind.conc: // T_CONC:
|
208 |
|
|
case ExpressionKind.inds: // T_INDS:
|
209 |
|
|
case ExpressionKind.dinter: // T_DINTER:
|
210 |
|
|
case ExpressionKind.dunion: // T_DUNION:
|
211 |
|
|
return 1;
|
212 |
|
|
|
213 |
|
|
case ExpressionKind.domresby: // T_DOMRESBY:
|
214 |
|
|
case ExpressionKind.domresto: // T_DOMRESTO:
|
215 |
|
|
case ExpressionKind.rngresby: // T_RNGRESBY:
|
216 |
|
|
case ExpressionKind.rngresto: // T_RNGRESTO:
|
217 |
|
|
return 2;
|
218 |
|
|
|
219 |
|
|
case ExpressionKind.div: // T_DIV:
|
220 |
|
|
case ExpressionKind.idiv: // T_IDIV:
|
221 |
|
|
case ExpressionKind.mod: // T_MOD:
|
222 |
|
|
case ExpressionKind.prod: // T_PROD:
|
223 |
|
|
case ExpressionKind.inter: // T_INTER:
|
224 |
|
|
return 3;
|
225 |
|
|
|
226 |
|
|
case ExpressionKind.sum: // T_SUM:
|
227 |
|
|
case ExpressionKind.minus: // T_MINUS:
|
228 |
|
|
case ExpressionKind.union: // T_UNION:
|
229 |
|
|
case ExpressionKind.diff: // T_DIFF:
|
230 |
|
|
case ExpressionKind.munion: // T_MUNION:
|
231 |
|
|
case ExpressionKind.seqmod_mapoverride: // T_SEQMOD_MAPOVERRIDE:
|
232 |
|
|
return 4;
|
233 |
|
|
|
234 |
|
|
/*Family of Relations*/
|
235 |
|
|
|
236 |
|
|
case ExpressionKind.less:
|
237 |
|
|
case ExpressionKind.lessequal:
|
238 |
|
|
case ExpressionKind.greater:
|
239 |
|
|
case ExpressionKind.greaterequal:
|
240 |
|
|
case ExpressionKind.equal:
|
241 |
|
|
case ExpressionKind.notequal:
|
242 |
|
|
case ExpressionKind.subset:
|
243 |
|
|
case ExpressionKind.elemin:
|
244 |
|
|
case ExpressionKind.notelemin:
|
245 |
|
|
return 5;
|
246 |
|
|
|
247 |
|
|
/*Family of Connectives*/
|
248 |
|
|
|
249 |
|
|
case ExpressionKind.and: // T_AND:
|
250 |
|
|
return 6;
|
251 |
|
|
|
252 |
|
|
case ExpressionKind.or: // T_OR:
|
253 |
|
|
return 7;
|
254 |
|
|
|
255 |
|
|
case ExpressionKind.implies: // T_IMPLIES:
|
256 |
|
|
return 8;
|
257 |
|
|
|
258 |
|
|
case ExpressionKind.biimplies: // T_BIIMPLIES:
|
259 |
|
|
return 9;
|
260 |
|
|
|
261 |
|
|
default:
|
262 |
|
|
throw new NotImplementedException("operator not supported: " + type.ToString());
|
263 |
|
|
// return 0;
|
264 |
|
|
}
|
265 |
|
|
}
|
266 |
|
|
|
267 |
|
|
/*taken from antlr homepage:
|
268 |
|
|
http://www.antlr.org/wiki/display/ANTLR3/Operator+precedence+parser
|
269 |
|
|
*/
|
270 |
|
|
int findPivot(List<BinaryOperator> operators, int startIndex, int stopIndex)
|
271 |
|
|
{
|
272 |
|
|
int pivot = startIndex;
|
273 |
|
|
int pivotRank = GetOperatorPrecedence(operators[pivot].kind);
|
274 |
|
|
for (int i = startIndex + 1; i <= stopIndex; i++)
|
275 |
|
|
{
|
276 |
|
|
ExpressionKind type = operators[i].kind;
|
277 |
|
|
int current = GetOperatorPrecedence(type);
|
278 |
|
|
bool rtl = IsRightToLeft(type);
|
279 |
|
|
if (current > pivotRank || (current == pivotRank && rtl))
|
280 |
|
|
{
|
281 |
|
|
pivot = i;
|
282 |
|
|
pivotRank = current;
|
283 |
|
|
}
|
284 |
|
|
}
|
285 |
|
|
return pivot;
|
286 |
|
|
}
|
287 |
|
|
|
288 |
|
|
internal Expression createPrecedenceTree(
|
289 |
|
|
List<Expression> expressions,
|
290 |
|
|
List<BinaryOperator> operators,
|
291 |
|
|
int startIndex,
|
292 |
|
|
int stopIndex)
|
293 |
|
|
{
|
294 |
|
|
if (stopIndex == startIndex)
|
295 |
|
|
return expressions[startIndex];
|
296 |
|
|
|
297 |
|
|
int pivot = findPivot(operators, startIndex, stopIndex - 1);
|
298 |
|
|
|
299 |
|
|
BinaryOperator result = operators[pivot];
|
300 |
|
|
result.SetLeftChild(createPrecedenceTree(expressions, operators, startIndex, pivot));
|
301 |
|
|
result.SetRightChild(createPrecedenceTree(expressions, operators, pivot + 1, stopIndex));
|
302 |
|
|
|
303 |
|
|
return result;
|
304 |
|
|
}
|
305 |
|
|
|
306 |
|
|
internal Expression createPrecedenceTree(List<Expression> expressions, List<BinaryOperator> operators)
|
307 |
|
|
{
|
308 |
|
|
return createPrecedenceTree(expressions, operators, 0, expressions.Count - 1);
|
309 |
|
|
}
|
310 |
|
|
|
311 |
|
|
|
312 |
|
|
/* add error message to state. */
|
313 |
|
|
private void doError(IToken aToken, string aMessage)
|
314 |
|
|
{
|
315 |
|
|
pState.AddErrorMessage(
|
316 |
|
|
new ParserError(pState.filename, aToken, aMessage));
|
317 |
|
|
}
|
318 |
|
|
|
319 |
|
|
/* add warning message to state */
|
320 |
|
|
private void doWarning(IToken id1, string p)
|
321 |
|
|
{
|
322 |
|
|
pState.AddWarningMessage(new ParserWarning(pState.filename, id1, p));
|
323 |
|
|
}
|
324 |
|
|
|
325 |
|
|
private void doError(string aMessage)
|
326 |
|
|
{
|
327 |
|
|
pState.AddErrorMessage(
|
328 |
|
|
new ParserError(pState.filename, 0, 0, aMessage));
|
329 |
|
|
}
|
330 |
|
|
|
331 |
|
|
/* init global state */
|
332 |
|
|
internal void initializeTopLevelParserState()
|
333 |
|
|
{
|
334 |
|
|
pState.ooaSystem = new MainModule();
|
335 |
|
|
pState.PushResolveStack(pState.ooaSystem);
|
336 |
|
|
}
|
337 |
|
|
|
338 |
|
|
|
339 |
|
|
private IScope GetScope()
|
340 |
|
|
{
|
341 |
|
|
return pState.currentScope;
|
342 |
|
|
}
|
343 |
|
|
|
344 |
|
|
|
345 |
|
|
/*create a named constant*/
|
346 |
|
|
internal void addNamedConst(IToken aName, Expression anExpr)
|
347 |
|
|
{
|
348 |
|
|
if (pState.currentScope.ResolveIdentifier(aName.Text) == null)
|
349 |
|
|
{
|
350 |
|
|
/* needs to be a constant... */
|
351 |
|
|
ConstantIdentifier aConst = new ConstantIdentifier(aName, anExpr, GetScope());
|
352 |
|
|
|
353 |
|
|
OoaResolveExpressionsVisitor resolver = new OoaResolveExpressionsVisitor(pState);
|
354 |
|
|
aConst.Accept(resolver);
|
355 |
|
|
|
356 |
|
|
if (aConst.Value == null || aConst.Value.type == null || aConst.Value.kind != ExpressionKind.Value)
|
357 |
|
|
{
|
358 |
|
|
doError(aName, String.Format("{0} not a constant!", aName.Text));
|
359 |
|
|
}
|
360 |
|
|
else
|
361 |
|
|
{
|
362 |
|
|
aConst.SetType(aConst.Value.type);
|
363 |
|
|
pState.currentScope.AddIdentifier(aConst, null);
|
364 |
|
|
}
|
365 |
|
|
}
|
366 |
|
|
else
|
367 |
|
|
doError(aName, String.Format("{0} already defined!", aName.Text));
|
368 |
|
|
}
|
369 |
|
|
|
370 |
|
|
|
371 |
|
|
|
372 |
|
|
/* create a named type; we're on top-level here */
|
373 |
|
|
internal void createNamedType(IToken aName, UlyssesType aType)
|
374 |
|
|
{
|
375 |
|
|
// precond..
|
376 |
|
|
System.Diagnostics.Debug.Assert(aName != null);
|
377 |
|
|
|
378 |
|
|
if (aType == null)
|
379 |
|
|
{
|
380 |
|
|
doError(aName, String.Format("{0} lacks a type! (Type not added)", aName.Text));
|
381 |
|
|
return;
|
382 |
|
|
}
|
383 |
|
|
|
384 |
|
|
|
385 |
|
|
if (pState.currentScope.ResolveIdentifier(aName.Text) == null)
|
386 |
|
|
{
|
387 |
|
|
TypeIdentifier newid = new TypeIdentifier(aName, aType, GetScope());
|
388 |
|
|
aType.SetTypeIdentifier(newid);
|
389 |
|
|
pState.currentScope.AddIdentifier(newid, null);
|
390 |
|
|
}
|
391 |
|
|
else
|
392 |
|
|
doError(aName, String.Format("{0} already defined!", aName.Text));
|
393 |
|
|
|
394 |
|
|
}
|
395 |
|
|
|
396 |
|
|
/* create basic structure for an ooa-system descr. resolve stack TOS is now ooa-system symbols */
|
397 |
|
|
internal OoActionSystemType createOoaType(IToken refinesSystemName, bool autoCons)
|
398 |
|
|
{
|
399 |
|
|
Identifier refinedSystem = pState.Lookup(refinesSystemName);
|
400 |
|
|
OoActionSystemType refinedSystemType = null;
|
401 |
|
|
if ((refinedSystem != null) && (refinedSystem.type != null))
|
402 |
|
|
{
|
403 |
|
|
if (refinedSystem.type.kind != TypeKind.OoActionSystemType)
|
404 |
|
|
doError(refinesSystemName,
|
405 |
|
|
String.Format("{0} not an object oriented action system", refinesSystemName.Text));
|
406 |
|
|
else
|
407 |
|
|
refinedSystemType = (OoActionSystemType)refinedSystem.type;
|
408 |
|
|
}
|
409 |
|
|
else if (refinesSystemName != null)
|
410 |
|
|
{
|
411 |
|
|
pState.AddErrorMessage(
|
412 |
|
|
new ParserError(pState.filename, refinesSystemName,
|
413 |
|
|
String.Format("Type that's being refined ({0}) not found!", refinesSystemName.Text)));
|
414 |
|
|
}
|
415 |
|
|
|
416 |
|
|
OoActionSystemType result = new OoActionSystemType(autoCons, refinedSystemType, null);
|
417 |
|
|
|
418 |
|
|
|
419 |
|
|
// add 'self' to the symbols.. (self is a keyword, so it can't be defined)
|
420 |
|
|
result.AddIdentifier(new SelfTypeIdentifier("self", result, GetScope()), null);
|
421 |
|
|
|
422 |
|
|
|
423 |
|
|
|
424 |
|
|
pState.PushResolveStack(result);
|
425 |
|
|
return result;
|
426 |
|
|
}
|
427 |
|
|
|
428 |
|
|
/* remove ooa-system symbols from resolve stack TOS */
|
429 |
|
|
internal void fixupOoaType(OoActionSystemType aTypeSymbol)
|
430 |
|
|
{
|
431 |
|
|
if (aTypeSymbol == null)
|
432 |
|
|
return;
|
433 |
|
|
|
434 |
|
|
aTypeSymbol.SetupAnonymousName();
|
435 |
|
|
if (aTypeSymbol != null)
|
436 |
|
|
pState.PopResolveStack();
|
437 |
|
|
}
|
438 |
|
|
|
439 |
|
|
internal Expression addCastExpression(Expression e, IToken cid)
|
440 |
|
|
{
|
441 |
|
|
System.Diagnostics.Debug.Assert(e != null);
|
442 |
|
|
|
443 |
|
|
Expression result = new UnaryOperator(ExpressionKind.Cast, e, cid.Line, cid.CharPositionInLine);
|
444 |
|
|
result.SetType(new OpaqueType(new TypeIdentifier(cid, null, GetScope())));
|
445 |
|
|
pState.typesToFixUp.Add((OpaqueType)result.type);
|
446 |
|
|
return result;
|
447 |
|
|
}
|
448 |
|
|
|
449 |
|
|
|
450 |
|
|
/* add a new ooa to the list describing the composition of action systems */
|
451 |
|
|
internal void addToIdentifierList(IdentifierList top, IToken aName)
|
452 |
|
|
{
|
453 |
|
|
System.Diagnostics.Debug.Assert(top != null);
|
454 |
|
|
|
455 |
|
|
Identifier aSym = pState.Lookup(aName);
|
456 |
|
|
if (aSym == null)
|
457 |
|
|
{
|
458 |
|
|
doError(aName, String.Format("Could not find ooa-system {0}!", aName.Text));
|
459 |
|
|
}
|
460 |
|
|
else if ((aSym.type == null) || !(aSym.type.kind == TypeKind.OoActionSystemType))
|
461 |
|
|
{
|
462 |
|
|
doError(aName, String.Format("Referenced type ({0}) does not have correct type!", aName.Text));
|
463 |
|
|
}
|
464 |
|
|
else
|
465 |
|
|
{
|
466 |
|
|
OoActionSystemType aType = (OoActionSystemType)aSym.type;
|
467 |
|
|
if (aType.isInSystemDescription)
|
468 |
|
|
doError(aName, String.Format("Referenced type ({0}) already used in composition!", aName.Text));
|
469 |
|
|
else
|
470 |
|
|
aType.SetIsInSystemDescription(true);
|
471 |
|
|
top.AddElement(aSym);
|
472 |
|
|
}
|
473 |
|
|
}
|
474 |
|
|
|
475 |
|
|
/* does a fixup run after parsing */
|
476 |
|
|
internal void fixUpRun(IdentifierList sysDescr)
|
477 |
|
|
{
|
478 |
|
|
// set system descr.
|
479 |
|
|
pState.ooaSystem.SetSystemDescription(sysDescr);
|
480 |
|
|
|
481 |
|
|
// fixup named types
|
482 |
|
|
FixupNamedTypes();
|
483 |
|
|
}
|
484 |
|
|
|
485 |
|
|
private void FixupNamedTypes()
|
486 |
|
|
{
|
487 |
|
|
/*named type refs that could not be resolved in the first run, have to
|
488 |
|
|
be resolved now. */
|
489 |
|
|
foreach (var ntype in pState.typesToFixUp)
|
490 |
|
|
{
|
491 |
|
|
if (ntype.resolvedType == null)
|
492 |
|
|
{
|
493 |
|
|
//ntype.identifier
|
494 |
|
|
Identifier asym = pState.Lookup(ntype.identifier.tokenText, ntype.identifier.definingScope);
|
495 |
|
|
if ((asym == null) || (asym.kind != IdentifierKind.TypeIdentifier))
|
496 |
|
|
{
|
497 |
|
|
ParserError error = new ParserError(pState.filename, ntype.identifier.line, ntype.identifier.column,
|
498 |
|
|
String.Format("Can not resolve {0} to a named type", ntype.identifier.tokenText));
|
499 |
|
|
pState.AddErrorMessage(error);
|
500 |
|
|
}
|
501 |
|
|
else
|
502 |
|
|
ntype.SetResolvedType(asym.type);
|
503 |
|
|
}
|
504 |
|
|
}
|
505 |
|
|
pState.typesToFixUp.Clear();
|
506 |
|
|
}
|
507 |
|
|
|
508 |
|
|
|
509 |
|
|
private bool TosIsActionSystem()
|
510 |
|
|
{
|
511 |
|
|
return pState.currentScope is OoActionSystemType;
|
512 |
|
|
}
|
513 |
|
|
|
514 |
|
|
|
515 |
|
|
private int currentLine
|
516 |
|
|
{
|
517 |
|
|
get
|
518 |
|
|
{
|
519 |
|
|
IToken token = input.LT(-1);
|
520 |
|
|
return token == null ? 0 : token.Line;
|
521 |
|
|
}
|
522 |
|
|
}
|
523 |
|
|
|
524 |
|
|
private int currentPos
|
525 |
|
|
{
|
526 |
|
|
get
|
527 |
|
|
{
|
528 |
|
|
IToken token = input.LT(-1);
|
529 |
|
|
return token == null ? 0 : token.CharPositionInLine;
|
530 |
|
|
}
|
531 |
|
|
}
|
532 |
|
|
|
533 |
|
|
/* add var symbol to the current action system */
|
534 |
|
|
internal void createAttribute(IToken varname, bool isStatic, bool isObs, bool isCtr, UlyssesType aType, Expression anExpr)
|
535 |
|
|
{
|
536 |
|
|
if (!TosIsActionSystem())
|
537 |
|
|
return;
|
538 |
|
|
|
539 |
|
|
if (aType == null)
|
540 |
|
|
{
|
541 |
|
|
doError(varname, String.Format("{0} lacks type!", varname.Text));
|
542 |
|
|
}
|
543 |
|
|
if (anExpr == null)
|
544 |
|
|
{
|
545 |
|
|
doError(varname, String.Format("{0} lacks initializer!", varname.Text));
|
546 |
|
|
}
|
547 |
|
|
if (isObs == true || isCtr == true)
|
548 |
|
|
if (aType.kind != TypeKind.QrType)
|
549 |
|
|
doError(varname, "'obs' or 'ctr' on attributes only allowed for qualitative types");
|
550 |
|
|
|
551 |
|
|
|
552 |
|
|
AttributeIdentifier var = new AttributeIdentifier(varname, aType, GetScope(), anExpr, isStatic, isObs, isCtr);
|
553 |
|
|
if (pState.currentScope.ResolveIdentifier(varname.Text) == null)
|
554 |
|
|
pState.currentScope.AddIdentifier(var, null);
|
555 |
|
|
else
|
556 |
|
|
doError(varname, String.Format("Can not add {0}: Symbol already defined!", varname.Text));
|
557 |
|
|
}
|
558 |
|
|
|
559 |
|
|
|
560 |
|
|
/* create a bool type */
|
561 |
|
|
internal BoolType createBoolType()
|
562 |
|
|
{
|
563 |
|
|
return new BoolType(null);
|
564 |
|
|
}
|
565 |
|
|
|
566 |
|
|
/* create a char type */
|
567 |
|
|
internal CharType createCharType()
|
568 |
|
|
{
|
569 |
|
|
return new CharType(null);
|
570 |
|
|
}
|
571 |
|
|
|
572 |
|
|
/* create an int type */
|
573 |
|
|
internal UlyssesType createIntType(IToken rangeLow, IToken rangeHigh)
|
574 |
|
|
{
|
575 |
|
|
int low = 0;
|
576 |
|
|
int high = 0;
|
577 |
|
|
|
578 |
|
|
if (rangeLow.Type == ooaLexer.T_INFTY)
|
579 |
|
|
doError(rangeLow, "Infinity not supported.");
|
580 |
|
|
if (rangeLow.Type == ooaLexer.T_INFTY)
|
581 |
|
|
doError(rangeHigh, "Infinity not supported.");
|
582 |
|
|
|
583 |
|
|
if (rangeLow.Type == ooaLexer.T_IDENTIFIER)
|
584 |
|
|
{
|
585 |
|
|
// see whether we can find the constant
|
586 |
|
|
Identifier aconst = pState.currentScope.ResolveIdentifier(rangeLow.Text);
|
587 |
|
|
if (aconst == null || aconst.kind != IdentifierKind.Constant)
|
588 |
|
|
doError(rangeLow, String.Format("Constant {0} not found", rangeLow.Text));
|
589 |
|
|
else if (aconst.type.kind != TypeKind.IntType)
|
590 |
|
|
doError(rangeLow, "Constant must be integer");
|
591 |
|
|
else
|
592 |
|
|
low = ((ValueExpression<int>)((ConstantIdentifier)aconst).Value).value;
|
593 |
|
|
}
|
594 |
|
|
else
|
595 |
|
|
if (!Int32.TryParse(rangeLow.Text, out low))
|
596 |
|
|
doError(rangeLow, "Can not convert to integer");
|
597 |
|
|
|
598 |
|
|
if (rangeHigh.Type == ooaLexer.T_IDENTIFIER)
|
599 |
|
|
{
|
600 |
|
|
// see whether we can find the constant
|
601 |
|
|
Identifier aconst = pState.currentScope.ResolveIdentifier(rangeHigh.Text);
|
602 |
|
|
if (aconst == null || aconst.kind != IdentifierKind.Constant)
|
603 |
|
|
doError(rangeHigh, String.Format("Constant {0} not found", rangeHigh.Text));
|
604 |
|
|
else if (aconst.type.kind != TypeKind.IntType)
|
605 |
|
|
doError(rangeHigh, "Constant must be integer");
|
606 |
|
|
else
|
607 |
|
|
high = ((ValueExpression<int>)((ConstantIdentifier)aconst).Value).value;
|
608 |
|
|
}
|
609 |
|
|
else
|
610 |
|
|
if (!Int32.TryParse(rangeHigh.Text, out high))
|
611 |
|
|
doError(rangeHigh, "Can not convert to interger");
|
612 |
|
|
|
613 |
|
|
if (high < low)
|
614 |
|
|
doError(rangeHigh, "Lower bound greater than upper bound");
|
615 |
|
|
|
616 |
|
|
return new IntType(low, high, null);
|
617 |
|
|
}
|
618 |
|
|
|
619 |
|
|
/* create a float type */
|
620 |
|
|
internal UlyssesType createFloatType(IToken rangeLow, IToken rangeHigh)
|
621 |
|
|
{
|
622 |
|
|
float low = 0;
|
623 |
|
|
float high = 0;
|
624 |
|
|
|
625 |
|
|
if (rangeLow.Type == ooaLexer.T_INFTY)
|
626 |
|
|
doError(rangeLow, "Infinity not supported.");
|
627 |
|
|
if (rangeLow.Type == ooaLexer.T_INFTY)
|
628 |
|
|
doError(rangeHigh, "Infinity not supported.");
|
629 |
|
|
|
630 |
|
|
if (rangeLow.Type == ooaLexer.T_IDENTIFIER)
|
631 |
|
|
{
|
632 |
|
|
// see whether we can find the constant
|
633 |
|
|
Identifier aconst = pState.currentScope.ResolveIdentifier(rangeLow.Text);
|
634 |
|
|
if (aconst == null || aconst.kind != IdentifierKind.Constant)
|
635 |
|
|
doError(rangeLow, String.Format("Constant {0} not found", rangeLow.Text));
|
636 |
|
|
else if (aconst.type.kind != TypeKind.FloatType)
|
637 |
|
|
doError(rangeLow, "Constant must be float");
|
638 |
|
|
else
|
639 |
|
|
low = ((ValueExpression<int>)((ConstantIdentifier)aconst).Value).value;
|
640 |
|
|
}
|
641 |
|
|
else if (!float.TryParse(rangeLow.Text, out low))
|
642 |
|
|
doError(rangeLow, "Can not convert to float (single)");
|
643 |
|
|
|
644 |
|
|
if (rangeHigh.Type == ooaLexer.T_IDENTIFIER)
|
645 |
|
|
{
|
646 |
|
|
// see whether we can find the constant
|
647 |
|
|
Identifier aconst = pState.currentScope.ResolveIdentifier(rangeHigh.Text);
|
648 |
|
|
if (aconst == null || aconst.kind != IdentifierKind.Constant)
|
649 |
|
|
doError(rangeHigh, String.Format("Constant {0} not found", rangeHigh.Text));
|
650 |
|
|
else if (aconst.type.kind != TypeKind.FloatType)
|
651 |
|
|
doError(rangeHigh, "Constant must be integer");
|
652 |
|
|
else
|
653 |
|
|
high = ((ValueExpression<int>)((ConstantIdentifier)aconst).Value).value;
|
654 |
|
|
}
|
655 |
|
|
else if (!float.TryParse(rangeHigh.Text, out high))
|
656 |
|
|
doError(rangeHigh, "Can not convert to float (single)");
|
657 |
|
|
|
658 |
|
|
if (high < low)
|
659 |
|
|
doError(rangeHigh, "Lower bound greater than upper bound");
|
660 |
|
|
|
661 |
|
|
/* precision */
|
662 |
|
|
float afterc_low = low - (float)Convert.ToInt32(low);
|
663 |
|
|
float afterc_high = high - (float)Convert.ToInt32(high);
|
664 |
|
|
float precision = afterc_low < afterc_high ? afterc_low : afterc_high;
|
665 |
|
|
|
666 |
|
|
return new FloatType(low, high, precision, null);
|
667 |
|
|
}
|
668 |
|
|
|
669 |
|
|
/* create a list of an enumerated type */
|
670 |
|
|
internal UlyssesType createListEnumType(IToken alistelem)
|
671 |
|
|
{
|
672 |
|
|
EnumType hiddenEnumType = new EnumType(null);
|
673 |
|
|
|
674 |
|
|
ListType result = new ListType(hiddenEnumType, 500, null);
|
675 |
|
|
addToListEnumType(result, alistelem);
|
676 |
|
|
return result;
|
677 |
|
|
}
|
678 |
|
|
|
679 |
|
|
/* add a new enum symbol to a list with an anonymous enumerated type */
|
680 |
|
|
internal void addToListEnumType(UlyssesType aTypeSymbol, IToken otherlistelem)
|
681 |
|
|
{
|
682 |
|
|
EnumType enumtype = (EnumType)((ListType)aTypeSymbol).innerType;
|
683 |
|
|
addToEnumType(enumtype, otherlistelem, null);
|
684 |
|
|
}
|
685 |
|
|
|
686 |
|
|
/* create a new enumerated type */
|
687 |
|
|
internal UlyssesType createEnumType(IToken aRangeValue, IToken anIntegerValue)
|
688 |
|
|
{
|
689 |
|
|
EnumType result;
|
690 |
|
|
|
691 |
|
|
if (anIntegerValue == null)
|
692 |
|
|
result = new EnumType(null);
|
693 |
|
|
else
|
694 |
|
|
result = new ValuedEnumType(null);
|
695 |
|
|
|
696 |
|
|
addToEnumType(result, aRangeValue, anIntegerValue);
|
697 |
|
|
return result;
|
698 |
|
|
}
|
699 |
|
|
|
700 |
|
|
/* add a new enum symbol to the enumerated type */
|
701 |
|
|
internal void addToEnumType(UlyssesType aTypeSymbol, IToken otherRangeValue, IToken anIntegerValue)
|
702 |
|
|
{
|
703 |
|
|
EnumType anEnum = (EnumType)aTypeSymbol;
|
704 |
|
|
if (anEnum.symbolTable.Defined(otherRangeValue.Text))
|
705 |
|
|
{
|
706 |
|
|
doError(otherRangeValue, String.Format("Element '{0}' already defined!", otherRangeValue.Text));
|
707 |
|
|
return;
|
708 |
|
|
}
|
709 |
|
|
|
710 |
|
|
/* for now we allow the usage of enum-ids without specifying the actual enum type,
|
711 |
|
|
* e.g., x = some_enum_id, hence all enum identifier must be globally unique.
|
712 |
|
|
* This decision could be reverted at later time...
|
713 |
|
|
*/
|
714 |
|
|
Identifier sym = pState.Lookup(otherRangeValue);
|
715 |
|
|
if (sym != null)
|
716 |
|
|
{
|
717 |
|
|
doError(otherRangeValue, String.Format("Element '{0}' already defined!", otherRangeValue.Text));
|
718 |
|
|
return;
|
719 |
|
|
}
|
720 |
|
|
|
721 |
|
|
EnumIdentifier enumval;
|
722 |
|
|
if (anIntegerValue == null)
|
723 |
|
|
{
|
724 |
|
|
if (aTypeSymbol is ValuedEnumType)
|
725 |
|
|
{
|
726 |
|
|
doError(otherRangeValue, String.Format("Element '{0}' needs integer value!", otherRangeValue.Text));
|
727 |
|
|
return;
|
728 |
|
|
}
|
729 |
|
|
|
730 |
|
|
enumval = new EnumIdentifier(otherRangeValue, (EnumType)aTypeSymbol, GetScope());
|
731 |
|
|
}
|
732 |
|
|
else
|
733 |
|
|
{
|
734 |
|
|
if (!(aTypeSymbol is ValuedEnumType))
|
735 |
|
|
{
|
736 |
|
|
doError(otherRangeValue, String.Format("Element '{0}' must not have integer value!", otherRangeValue.Text));
|
737 |
|
|
return;
|
738 |
|
|
}
|
739 |
|
|
enumval = new EnumIdentifier(otherRangeValue, Int32.Parse(anIntegerValue.Text), (EnumType)aTypeSymbol, GetScope());
|
740 |
|
|
}
|
741 |
|
|
|
742 |
|
|
((EnumType)aTypeSymbol).AddEnumSymbol(enumval);
|
743 |
|
|
|
744 |
|
|
/* add the enum id to 'global' state */
|
745 |
|
|
pState.currentScope.AddIdentifier(enumval, null);
|
746 |
|
|
}
|
747 |
|
|
|
748 |
|
|
/* get a named type */
|
749 |
|
|
internal UlyssesType getNamedType(IToken aType)
|
750 |
|
|
{
|
751 |
|
|
UlyssesType result = null;
|
752 |
|
|
Identifier sym = pState.Lookup(aType);
|
753 |
|
|
if (sym == null)
|
754 |
|
|
{
|
755 |
|
|
/* we might not have seen this type yet - so do a fixup run later */
|
756 |
|
|
result = new OpaqueType(new TypeIdentifier(aType, null, GetScope()));
|
757 |
|
|
pState.typesToFixUp.Add((OpaqueType)result);
|
758 |
|
|
}
|
759 |
|
|
else if (sym.kind == IdentifierKind.TypeIdentifier)
|
760 |
|
|
result = ((TypeIdentifier)sym).type;
|
761 |
|
|
else
|
762 |
|
|
doError(aType, "Not a named type symbol!");
|
763 |
|
|
|
764 |
|
|
return result;
|
765 |
|
|
}
|
766 |
|
|
|
767 |
|
|
/* create a list type */
|
768 |
|
|
internal UlyssesType createListType(IToken numOfElements, UlyssesType innertype)
|
769 |
|
|
{
|
770 |
|
|
if (innertype == null)
|
771 |
|
|
doError(numOfElements, "List type lacks proper element type (null)");
|
772 |
|
|
|
773 |
|
|
int numElems = 0;
|
774 |
|
|
|
775 |
|
|
if (numOfElements.Type == ooaLexer.T_IDENTIFIER)
|
776 |
|
|
{
|
777 |
|
|
// see whether we can find the constant
|
778 |
|
|
Identifier aconst = pState.currentScope.ResolveIdentifier(numOfElements.Text);
|
779 |
|
|
if (aconst == null || aconst.kind != IdentifierKind.Constant)
|
780 |
|
|
doError(numOfElements, String.Format("Constant {0} not found", numOfElements.Text));
|
781 |
|
|
else if (aconst.type.kind != TypeKind.IntType)
|
782 |
|
|
doError(numOfElements, "Constant must be integer");
|
783 |
|
|
else
|
784 |
|
|
numElems = ((ValueExpression<int>)((ConstantIdentifier)aconst).Value).value;
|
785 |
|
|
}
|
786 |
|
|
else
|
787 |
|
|
{
|
788 |
|
|
if (!Int32.TryParse(numOfElements.Text, out numElems))
|
789 |
|
|
doError(numOfElements, "Not an integer");
|
790 |
|
|
if (numElems <= 0)
|
791 |
|
|
doError(numOfElements, "Number of elements in a list must be >= 1");
|
792 |
|
|
}
|
793 |
|
|
|
794 |
|
|
ListType result = new ListType(innertype, numElems, null);
|
795 |
|
|
return result;
|
796 |
|
|
}
|
797 |
|
|
|
798 |
|
|
/* create a map type */
|
799 |
|
|
internal UlyssesType createMapType(IToken numOfElements, UlyssesType mapfromtype, UlyssesType maptotype)
|
800 |
|
|
{
|
801 |
|
|
if (mapfromtype == null)
|
802 |
|
|
doError(numOfElements, "Map: From-type not set (null)");
|
803 |
|
|
if (maptotype == null)
|
804 |
|
|
doError(numOfElements, "Map: To-type not set (null)");
|
805 |
|
|
|
806 |
|
|
int max = 0;
|
807 |
|
|
|
808 |
|
|
if (numOfElements.Type == ooaLexer.T_IDENTIFIER)
|
809 |
|
|
{
|
810 |
|
|
// see whether we can find the constant
|
811 |
|
|
Identifier aconst = pState.currentScope.ResolveIdentifier(numOfElements.Text);
|
812 |
|
|
if (aconst == null || aconst.kind != IdentifierKind.Constant)
|
813 |
|
|
doError(numOfElements, String.Format("Constant {0} not found", numOfElements.Text));
|
814 |
|
|
else if (aconst.type.kind != TypeKind.IntType)
|
815 |
|
|
doError(numOfElements, "Constant must be integer");
|
816 |
|
|
else
|
817 |
|
|
max = ((ValueExpression<int>)((ConstantIdentifier)aconst).Value).value;
|
818 |
|
|
}
|
819 |
|
|
else
|
820 |
|
|
if (!Int32.TryParse(numOfElements.Text, out max))
|
821 |
|
|
doError(numOfElements, "Not an integer");
|
822 |
|
|
|
823 |
|
|
MapType result = new MapType(mapfromtype, maptotype, max, null);
|
824 |
|
|
return result;
|
825 |
|
|
}
|
826 |
|
|
|
827 |
|
|
/* create a tuple type */
|
828 |
|
|
internal UlyssesType createTupleType(UlyssesType aType)
|
829 |
|
|
{
|
830 |
|
|
TupleType result = new TupleType(null);
|
831 |
|
|
if (aType == null)
|
832 |
|
|
doError("Unknown inner type.");
|
833 |
|
|
else
|
834 |
|
|
addToTupleType(result, aType);
|
835 |
|
|
return result;
|
836 |
|
|
}
|
837 |
|
|
|
838 |
|
|
/* add inner type to tuple */
|
839 |
|
|
internal void addToTupleType(UlyssesType aTypeSymbol, UlyssesType anotherType)
|
840 |
|
|
{
|
841 |
|
|
if (anotherType == null)
|
842 |
|
|
doError("Unknown inner type.");
|
843 |
|
|
else
|
844 |
|
|
{
|
845 |
|
|
TupleType tuple = (TupleType)aTypeSymbol;
|
846 |
|
|
tuple.AddType(anotherType);
|
847 |
|
|
}
|
848 |
|
|
}
|
849 |
|
|
|
850 |
|
|
/* create a QR type */
|
851 |
|
|
internal UlyssesType createQrType(IToken alandmark)
|
852 |
|
|
{
|
853 |
|
|
QrType result = new QrType(null);
|
854 |
|
|
addToQrType(result, alandmark);
|
855 |
|
|
return result;
|
856 |
|
|
}
|
857 |
|
|
|
858 |
|
|
/* add another landmark to QR type */
|
859 |
|
|
private void addToQrType(UlyssesType aTypeSymbol, IToken otherlandmark)
|
860 |
|
|
{
|
861 |
|
|
Identifier sym = pState.Lookup(otherlandmark);
|
862 |
|
|
if (sym != null)
|
863 |
|
|
{
|
864 |
|
|
doError(otherlandmark, String.Format("Redifinition of {0}", otherlandmark.Text));
|
865 |
|
|
return;
|
866 |
|
|
}
|
867 |
|
|
|
868 |
|
|
LandmarkIdentifier lndmrk = new LandmarkIdentifier(otherlandmark, (QrType)aTypeSymbol, GetScope());
|
869 |
|
|
((QrType)aTypeSymbol).AddLandmark(lndmrk);
|
870 |
|
|
}
|
871 |
|
|
|
872 |
|
|
/* gets called after a simple type has been constructed. used to define an internal name*/
|
873 |
|
|
internal void fixupSimpleType(UlyssesType aTypeSymbol)
|
874 |
|
|
{
|
875 |
|
|
if (aTypeSymbol != null)
|
876 |
|
|
aTypeSymbol.SetupAnonymousName();
|
877 |
|
|
}
|
878 |
|
|
|
879 |
|
|
/* gets called after a simple or complex type has been constructed. used to define an internal name */
|
880 |
|
|
internal void fixupComplexType(UlyssesType aTypeSymbol)
|
881 |
|
|
{
|
882 |
|
|
if (aTypeSymbol != null)
|
883 |
|
|
aTypeSymbol.SetupAnonymousName();
|
884 |
|
|
}
|
885 |
|
|
|
886 |
|
|
|
887 |
|
|
/* create a method symbol */
|
888 |
|
|
internal FunctionIdentifier createMethodSymbol(IToken mname)
|
889 |
|
|
{
|
890 |
|
|
Identifier sym = pState.Lookup(mname);
|
891 |
|
|
if (sym != null)
|
892 |
|
|
{
|
893 |
|
|
doError(mname, String.Format("Redefinition of {0}", mname.Text));
|
894 |
|
|
return null;
|
895 |
|
|
}
|
896 |
|
|
|
897 |
|
|
FunctionType funtype = new FunctionType(FunctionTypeEnum.Method, new LinkedList<UlyssesType>(), null);
|
898 |
|
|
MethodIdentifier msym = new MethodIdentifier(mname, funtype, GetScope());
|
899 |
|
|
funtype.SetTypeIdentifier(msym);
|
900 |
|
|
|
901 |
|
|
pState.currentScope.AddIdentifier(msym, null);
|
902 |
|
|
|
903 |
|
|
pState.PushResolveStack(msym);
|
904 |
|
|
return msym;
|
905 |
|
|
}
|
906 |
|
|
|
907 |
|
|
/* remove local method symbols from resolution stack again */
|
908 |
|
|
private void popResolveStack(FunctionIdentifier newMethod)
|
909 |
|
|
{
|
910 |
|
|
if (newMethod != null)
|
911 |
|
|
pState.PopResolveStack();
|
912 |
|
|
}
|
913 |
|
|
|
914 |
|
|
|
915 |
|
|
/* add a return type to a method */
|
916 |
|
|
internal void setMethodReturnType(FunctionIdentifier newMethod, UlyssesType rt)
|
917 |
|
|
{
|
918 |
|
|
if (newMethod == null)
|
919 |
|
|
return;
|
920 |
|
|
|
921 |
|
|
if (rt == null)
|
922 |
|
|
doError(String.Format("Method {0} has no return type (null)", newMethod.tokenText));
|
923 |
|
|
|
924 |
|
|
/* set return type */
|
925 |
|
|
((FunctionType)newMethod.type).SetReturnType(rt);
|
926 |
|
|
|
927 |
|
|
|
928 |
|
|
/* add hidden return parameter */
|
929 |
|
|
if (newMethod.symbolTable.Defined("result"))
|
930 |
|
|
{
|
931 |
|
|
doError(String.Format("Method {0} defines 'result'", newMethod.tokenText));
|
932 |
|
|
return;
|
933 |
|
|
}
|
934 |
|
|
|
935 |
|
|
ParameterIdentifier returnval = new ParameterIdentifier("result", rt, GetScope());
|
936 |
|
|
newMethod.symbolTable.AddIdentifier(returnval);
|
937 |
|
|
}
|
938 |
|
|
|
939 |
|
|
/* add a parameter to a method */
|
940 |
|
|
internal void addMethodParameter(FunctionIdentifier newMethod, IToken paramName, UlyssesType atype)
|
941 |
|
|
{
|
942 |
|
|
if (newMethod == null)
|
943 |
|
|
return;
|
944 |
|
|
|
945 |
|
|
if (atype == null)
|
946 |
|
|
doError(paramName, "Parameter has no type (null)");
|
947 |
|
|
|
948 |
|
|
|
949 |
|
|
if (newMethod.symbolTable.Defined(paramName.Text) == true)
|
950 |
|
|
{
|
951 |
|
|
doError(paramName, String.Format("Parameter {0} already defined", paramName.Text));
|
952 |
|
|
return;
|
953 |
|
|
}
|
954 |
|
|
|
955 |
|
|
// add parameter to scope
|
956 |
|
|
ParameterIdentifier param = new ParameterIdentifier(paramName, atype, GetScope());
|
957 |
|
|
newMethod.AddParameter(param);
|
958 |
|
|
|
959 |
|
|
// add type of param to signature
|
960 |
|
|
FunctionType ftype = (FunctionType)newMethod.type;
|
961 |
|
|
ftype.AddParameterType(atype);
|
962 |
|
|
}
|
963 |
|
|
|
964 |
|
|
/* set method body of a method */
|
965 |
|
|
internal void addMethodBody(FunctionIdentifier newMethod, Block statements)
|
966 |
|
|
{
|
967 |
|
|
if (newMethod == null)
|
968 |
|
|
return;
|
969 |
|
|
|
970 |
|
|
if (statements == null)
|
971 |
|
|
doError(String.Format("{0} has empty body (null)",
|
972 |
|
|
((FunctionType)newMethod.type).functionType == FunctionTypeEnum.Method ? "Method" : "Action"));
|
973 |
|
|
|
974 |
|
|
newMethod.SetBody(statements);
|
975 |
|
|
}
|
976 |
|
|
|
977 |
|
|
/* create a continuous action */
|
978 |
|
|
internal FunctionIdentifier createNamedContinuousAction(IToken cactionname, FunctionTypeEnum actionTypeEnum)
|
979 |
|
|
{
|
980 |
|
|
return createNamedAction(cactionname, actionTypeEnum);
|
981 |
|
|
}
|
982 |
|
|
|
983 |
|
|
/* create a named action */
|
984 |
|
|
internal FunctionIdentifier createNamedAction(IToken actionname, FunctionTypeEnum actionType)
|
985 |
|
|
{
|
986 |
|
|
Identifier sym = pState.Lookup(actionname);
|
987 |
|
|
if (sym != null)
|
988 |
|
|
{
|
989 |
|
|
doError(actionname, "Symbol already defined.");
|
990 |
|
|
return null;
|
991 |
|
|
}
|
992 |
|
|
|
993 |
|
|
FunctionType atype = new FunctionType(actionType, new LinkedList<UlyssesType>(), null);
|
994 |
|
|
NamedActionIdentifier action = new NamedActionIdentifier(actionname, atype, GetScope());
|
995 |
|
|
atype.SetTypeIdentifier(action);
|
996 |
|
|
|
997 |
|
|
pState.currentScope.AddIdentifier(action, null);
|
998 |
|
|
pState.PushResolveStack(action);
|
999 |
|
|
return action;
|
1000 |
|
|
}
|
1001 |
|
|
|
1002 |
|
|
/* add body of action */
|
1003 |
|
|
internal void addActionBody(FunctionIdentifier newAction, GuardedCommand body)
|
1004 |
|
|
{
|
1005 |
|
|
// we need a wrapper around the guarded command..
|
1006 |
|
|
Block bdy = new SeqBlock(currentLine, currentPos);
|
1007 |
|
|
bdy.AddStatement(body);
|
1008 |
|
|
addMethodBody(newAction, bdy);
|
1009 |
|
|
}
|
1010 |
|
|
|
1011 |
|
|
/* add constraints of cont. action */
|
1012 |
|
|
internal void addContinuousActionBody(FunctionIdentifier newAction, GuardedCommand constraints)
|
1013 |
|
|
{
|
1014 |
|
|
Block bdy = new SeqBlock(currentLine, currentPos);
|
1015 |
|
|
bdy.AddStatement(constraints);
|
1016 |
|
|
addMethodBody(newAction, bdy);
|
1017 |
|
|
}
|
1018 |
|
|
|
1019 |
|
|
/* create a guarded command */
|
1020 |
|
|
internal GuardedCommand createGuardedCommandStatement(Expression expr, Block bdy)
|
1021 |
|
|
{
|
1022 |
|
|
if (bdy == null)
|
1023 |
|
|
doError("Guarded command without body (null)!");
|
1024 |
|
|
|
1025 |
|
|
if (expr == null)
|
1026 |
|
|
doError("Guarded command without guard (null)!");
|
1027 |
|
|
|
1028 |
|
|
GuardedCommand result = new GuardedCommand(expr, bdy, currentLine, currentPos);
|
1029 |
|
|
return result;
|
1030 |
|
|
}
|
1031 |
|
|
internal GuardedCommand createGuardedCommandStatement(Expression expr, Block bdy, bool isQualitative)
|
1032 |
|
|
{
|
1033 |
|
|
GuardedCommand result = createGuardedCommandStatement(expr, bdy);
|
1034 |
|
|
result.SetIsQualitative(isQualitative);
|
1035 |
|
|
return result;
|
1036 |
|
|
}
|
1037 |
|
|
|
1038 |
|
|
/* add statements to list */
|
1039 |
|
|
internal void addToStatementList(Block top, Statement stmt)
|
1040 |
|
|
{
|
1041 |
|
|
if (stmt == null)
|
1042 |
|
|
doError("Can not add statement: null!");
|
1043 |
|
|
|
1044 |
|
|
top.AddStatement(stmt);
|
1045 |
|
|
}
|
1046 |
|
|
|
1047 |
|
|
/* create a Kill statement */
|
1048 |
|
|
internal Statement createKillStatement(IToken aname)
|
1049 |
|
|
{
|
1050 |
|
|
Identifier sym = pState.Lookup(aname);
|
1051 |
|
|
if (sym == null)
|
1052 |
|
|
doError(aname, "Not defined");
|
1053 |
|
|
|
1054 |
|
|
KillStatement result = new KillStatement(sym, aname.Line, aname.CharPositionInLine);
|
1055 |
|
|
return result;
|
1056 |
|
|
}
|
1057 |
|
|
|
1058 |
|
|
/* create a Skip statement */
|
1059 |
|
|
internal Statement createSkipStatement()
|
1060 |
|
|
{
|
1061 |
|
|
return new SkipStatement(currentLine, currentPos);
|
1062 |
|
|
}
|
1063 |
|
|
|
1064 |
|
|
/* create an Abort statement */
|
1065 |
|
|
internal Statement createAbortStatement()
|
1066 |
|
|
{
|
1067 |
|
|
return new AbortStatement(currentLine, currentPos);
|
1068 |
|
|
}
|
1069 |
|
|
|
1070 |
|
|
/* creates a prioritized composition block */
|
1071 |
|
|
internal Block createPrioBlock(Block top)
|
1072 |
|
|
{
|
1073 |
|
|
return new PrioBlock(top, currentLine, currentPos);
|
1074 |
|
|
}
|
1075 |
|
|
|
1076 |
|
|
/* creates a nondeterministically composed block */
|
1077 |
|
|
internal Block createNondetBlock(Block top)
|
1078 |
|
|
{
|
1079 |
|
|
return new NondetBlock(top, currentLine, currentPos);
|
1080 |
|
|
}
|
1081 |
|
|
|
1082 |
|
|
/* creates a sequentially composed block */
|
1083 |
|
|
internal Block createSeqBlock(Block top)
|
1084 |
|
|
{
|
1085 |
|
|
return new SeqBlock(top, currentLine, currentPos);
|
1086 |
|
|
}
|
1087 |
|
|
|
1088 |
|
|
|
1089 |
|
|
/* adds a filter expression to seq block */
|
1090 |
|
|
private void addSeqBlockExpression(Block seqList, Expression sexpr)
|
1091 |
|
|
{
|
1092 |
|
|
seqList.SetFilter(sexpr); /*gets transformed to guarded command in resolvevisitor!*/
|
1093 |
|
|
}
|
1094 |
|
|
|
1095 |
|
|
|
1096 |
|
|
/* create a self identifier */
|
1097 |
|
|
internal IdentifierExpression createSelfIdentifierExpression(IToken self)
|
1098 |
|
|
{
|
1099 |
|
|
Identifier id = pState.Lookup("self");
|
1100 |
|
|
if (id == null)
|
1101 |
|
|
{
|
1102 |
|
|
doError(self, "Can not resolve 'self'");
|
1103 |
|
|
return null;
|
1104 |
|
|
}
|
1105 |
|
|
|
1106 |
|
|
IdentifierExpression result = new IdentifierExpression(id, self.Line, self.CharPositionInLine);
|
1107 |
|
|
result.setIsSelf(true);
|
1108 |
|
|
return result;
|
1109 |
|
|
}
|
1110 |
|
|
|
1111 |
|
|
/* build up identifier tree... */
|
1112 |
|
|
internal Expression createIdentifierAccessExpression(IdentifierExpression aself, IToken token)
|
1113 |
|
|
{
|
1114 |
|
|
Identifier someid = pState.Lookup(token.Text, GetScope());
|
1115 |
|
|
Identifier self = pState.Lookup("self");
|
1116 |
|
|
|
1117 |
|
|
if (someid != null)
|
1118 |
|
|
{
|
1119 |
|
|
switch (someid.kind)
|
1120 |
|
|
{
|
1121 |
|
|
/* all method and attribute accesses are prefixed by self */
|
1122 |
|
|
case IdentifierKind.AttributeIdentifier:
|
1123 |
|
|
case IdentifierKind.MethodIdentifier:
|
1124 |
|
|
if (self == null)
|
1125 |
|
|
doError(token, "Self access of method: Can not find 'self' symbol! (internal error)");
|
1126 |
|
|
aself = new IdentifierExpression(self, token.Line, token.CharPositionInLine);
|
1127 |
|
|
aself.setIsSelf(true);
|
1128 |
|
|
break;
|
1129 |
|
|
default:
|
1130 |
|
|
break;
|
1131 |
|
|
}
|
1132 |
|
|
}
|
1133 |
|
|
|
1134 |
|
|
IdentifierExpression ident = new UnresolvedIdentifierExpression(token, GetScope());
|
1135 |
|
|
if (aself != null)
|
1136 |
|
|
return new AccessExpression(aself, ident, token.Line, token.CharPositionInLine);
|
1137 |
|
|
else
|
1138 |
|
|
return ident;
|
1139 |
|
|
}
|
1140 |
|
|
|
1141 |
|
|
internal AccessExpression addIdentifierAccessExpression(Expression parent, IToken token)
|
1142 |
|
|
{
|
1143 |
|
|
IdentifierExpression ident = new UnresolvedIdentifierExpression(token, GetScope());
|
1144 |
|
|
return new AccessExpression(parent, ident, token.Line, token.CharPositionInLine);
|
1145 |
|
|
}
|
1146 |
|
|
|
1147 |
|
|
/* we have a primed id; prime the complete subtree.. */
|
1148 |
|
|
internal void setIdentifierExpressionPrimed(ref Expression result, IToken token)
|
1149 |
|
|
{
|
1150 |
|
|
Expression priming = new UnaryOperator(ExpressionKind.Primed, result, token.Line, token.CharPositionInLine);
|
1151 |
|
|
result = priming;
|
1152 |
|
|
}
|
1153 |
|
|
|
1154 |
|
|
/* create a fold operation */
|
1155 |
|
|
internal Expression createFoldExpression(Expression result, IToken afold, Expression initval, Expression anexpr)
|
1156 |
|
|
{
|
1157 |
|
|
ExpressionKind akind = ExpressionKind.foldLR;
|
1158 |
|
|
if (afold.Type == ooaLexer.T_FOLDLR)
|
1159 |
|
|
akind = ExpressionKind.foldLR;
|
1160 |
|
|
else if (afold.Type == ooaLexer.T_FOLDRL)
|
1161 |
|
|
akind = ExpressionKind.foldRL;
|
1162 |
|
|
else
|
1163 |
|
|
System.Diagnostics.Debug.Assert(false);
|
1164 |
|
|
|
1165 |
|
|
TernaryOperator op = new TernaryOperator(akind, result, initval, anexpr, currentLine, currentPos, GetScope());
|
1166 |
|
|
return op;
|
1167 |
|
|
}
|
1168 |
|
|
|
1169 |
|
|
|
1170 |
|
|
/* create a method access */
|
1171 |
|
|
internal CallExpression createMethodAccessExpression(Expression subexpr, List<Expression> m_params, IToken token)
|
1172 |
|
|
{
|
1173 |
|
|
System.Diagnostics.Debug.Assert(subexpr != null);
|
1174 |
|
|
|
1175 |
|
|
return new CallExpression(subexpr, m_params, token.Line, token.CharPositionInLine, GetScope());
|
1176 |
|
|
}
|
1177 |
|
|
|
1178 |
|
|
/* create a tuple or map access */
|
1179 |
|
|
internal TupleMapAccessExpression createTupleMapAccessExpression(Expression subexpr, Expression ac, IToken token)
|
1180 |
|
|
{
|
1181 |
|
|
System.Diagnostics.Debug.Assert(subexpr != null);
|
1182 |
|
|
|
1183 |
|
|
return new TupleMapAccessExpression(subexpr, ac, token.Line, token.CharPositionInLine);
|
1184 |
|
|
}
|
1185 |
|
|
|
1186 |
|
|
/* create a method call statement; has to be resolved in a second run */
|
1187 |
|
|
internal Statement createCallStatement(Expression aqname)
|
1188 |
|
|
{
|
1189 |
|
|
return new Call(aqname, currentLine, currentPos);
|
1190 |
|
|
}
|
1191 |
|
|
|
1192 |
|
|
/* create a single assignment statement */
|
1193 |
|
|
internal Statement createSingleAssignmentStatement(Expression aqname, Expression aexp)
|
1194 |
|
|
{
|
1195 |
|
|
Assignment result = new Assignment(aqname, aexp, null, currentLine, currentPos);
|
1196 |
|
|
return result;
|
1197 |
|
|
}
|
1198 |
|
|
|
1199 |
|
|
/* create a multi-assignment statement; has to be resolved in a second run */
|
1200 |
|
|
internal Statement createMultipleAssignmentStatementLHS(Expression aqname)
|
1201 |
|
|
{
|
1202 |
|
|
return new Assignment(aqname, null, null, currentLine, currentPos);
|
1203 |
|
|
}
|
1204 |
|
|
|
1205 |
|
|
/* adds an expression to the multi-assign */
|
1206 |
|
|
internal void addMutlipleAssignmentStatementRHS(Statement result, Expression mexp)
|
1207 |
|
|
{
|
1208 |
|
|
((Assignment)result).AddValue(mexp);
|
1209 |
|
|
}
|
1210 |
|
|
|
1211 |
|
|
/* adds a LHS-var to the multi assign */
|
1212 |
|
|
internal void addMultipleAssignmentStatementLHS(Statement result, Expression malhs)
|
1213 |
|
|
{
|
1214 |
|
|
((Assignment)result).AddPlace(malhs);
|
1215 |
|
|
}
|
1216 |
|
|
|
1217 |
|
|
/* pop an assignment statement from the resolve stack */
|
1218 |
|
|
internal void popAssignmentOffResolveStack(Statement result)
|
1219 |
|
|
{
|
1220 |
|
|
System.Diagnostics.Debug.Assert(ReferenceEquals(result, pState.currentScope));
|
1221 |
|
|
pState.PopResolveStack();
|
1222 |
|
|
}
|
1223 |
|
|
|
1224 |
|
|
/* pushes the assignment statement onto resolve stack. */
|
1225 |
|
|
internal void pushAssignmentOnResolveStack(Statement result)
|
1226 |
|
|
{
|
1227 |
|
|
System.Diagnostics.Debug.Assert(result is Assignment);
|
1228 |
|
|
pState.PushResolveStack((Assignment)result);
|
1229 |
|
|
}
|
1230 |
|
|
|
1231 |
|
|
|
1232 |
|
|
/* adds a nondet-assignment constraint */
|
1233 |
|
|
internal void addConstraintToAssignment(Statement result, Expression ndexp)
|
1234 |
|
|
{
|
1235 |
|
|
((Assignment)result).SetNondetExpression(ndexp);
|
1236 |
|
|
}
|
1237 |
|
|
|
1238 |
|
|
/* add a named action call to do-od block */
|
1239 |
|
|
internal void addNamedActionCallToBlockList(Block top, IToken aname, List<Expression> m_params, IToken maptoken, Expression amapexpression)
|
1240 |
|
|
{
|
1241 |
|
|
Identifier id = pState.Lookup(aname);
|
1242 |
|
|
if (id == null)
|
1243 |
|
|
{
|
1244 |
|
|
doError(aname, "Could not find named action");
|
1245 |
|
|
return;
|
1246 |
|
|
}
|
1247 |
|
|
Expression callexpr;
|
1248 |
|
|
if (id.kind == IdentifierKind.MethodIdentifier)
|
1249 |
|
|
{
|
1250 |
|
|
doError(aname, "Method access in do-od block not allowed.");
|
1251 |
|
|
return;
|
1252 |
|
|
// access via self
|
1253 |
|
|
/*
|
1254 |
|
|
Identifier self = pState.Lookup("self");
|
1255 |
|
|
if (self == null)
|
1256 |
|
|
doError(aname, "Self access of method: Can not find 'self' symbol! (internal error)");
|
1257 |
|
|
IdentifierExpression aself = new IdentifierExpression(self, aname.Line, aname.CharPositionInLine);
|
1258 |
|
|
aself.setIsSelf(true);
|
1259 |
|
|
callexpr = new CallExpression(
|
1260 |
|
|
new AccessExpression(aself,
|
1261 |
|
|
new IdentifierExpression(id, aname.Line, aname.CharPositionInLine), aname.Line, aname.CharPositionInLine),
|
1262 |
|
|
m_params, aname.Line, aname.CharPositionInLine, GetScope());
|
1263 |
|
|
*/
|
1264 |
|
|
}
|
1265 |
|
|
else
|
1266 |
|
|
callexpr = new CallExpression(
|
1267 |
|
|
new IdentifierExpression(id, aname.Line, aname.CharPositionInLine),
|
1268 |
|
|
m_params, aname.Line, aname.CharPositionInLine, GetScope());
|
1269 |
|
|
|
1270 |
|
|
if (amapexpression != null)
|
1271 |
|
|
{
|
1272 |
|
|
ExpressionKind akind = ExpressionKind.foldLR;
|
1273 |
|
|
if (maptoken.Type == ooaLexer.T_FOLDLR)
|
1274 |
|
|
akind = ExpressionKind.foldLR;
|
1275 |
|
|
else if (maptoken.Type == ooaLexer.T_FOLDRL)
|
1276 |
|
|
akind = ExpressionKind.foldRL;
|
1277 |
|
|
else
|
1278 |
|
|
System.Diagnostics.Debug.Assert(false);
|
1279 |
|
|
|
1280 |
|
|
callexpr = new TernaryOperator(akind, callexpr, null, amapexpression,
|
1281 |
|
|
currentLine, currentPos, GetScope());
|
1282 |
|
|
}
|
1283 |
|
|
Call statement = new Call(callexpr, currentLine, currentPos);
|
1284 |
|
|
top.AddStatement(statement);
|
1285 |
|
|
}
|
1286 |
|
|
|
1287 |
|
|
/*adds skip statement instead of call to do-od block*/
|
1288 |
|
|
internal void addSkipStatementToBlockList(Block top)
|
1289 |
|
|
{
|
1290 |
|
|
top.AddStatement(new SkipStatement(currentLine, currentPos));
|
1291 |
|
|
}
|
1292 |
|
|
|
1293 |
|
|
|
1294 |
|
|
/* add anonymous action to do-od block */
|
1295 |
|
|
internal void addToBlockList(Block top, Statement gcmd)
|
1296 |
|
|
{
|
1297 |
|
|
if (gcmd != null)
|
1298 |
|
|
top.AddStatement(gcmd);
|
1299 |
|
|
}
|
1300 |
|
|
|
1301 |
|
|
/* add the do-od block to the action system type */
|
1302 |
|
|
internal void addActionBlock(OoActionSystemType aTypeSymbol, Block bl)
|
1303 |
|
|
{
|
1304 |
|
|
aTypeSymbol.SetDoOdBlock(bl);
|
1305 |
|
|
}
|
1306 |
|
|
|
1307 |
|
|
/* push block */
|
1308 |
|
|
internal void pushBlockToResolveStack(Block toPush)
|
1309 |
|
|
{
|
1310 |
|
|
pState.PushResolveStack(toPush);
|
1311 |
|
|
}
|
1312 |
|
|
|
1313 |
|
|
/* pop block */
|
1314 |
|
|
internal void popBlockFromResolveStack(Block toPop)
|
1315 |
|
|
{
|
1316 |
|
|
if (toPop != null)
|
1317 |
|
|
{
|
1318 |
|
|
object anobject = pState.currentScope as Block;
|
1319 |
|
|
System.Diagnostics.Debug.Assert(Object.ReferenceEquals(anobject, toPop));
|
1320 |
|
|
|
1321 |
|
|
pState.PopResolveStack();
|
1322 |
|
|
}
|
1323 |
|
|
}
|
1324 |
|
|
|
1325 |
|
|
/* add block var */
|
1326 |
|
|
internal void addBlockVariable(Block seqList, IToken varname, UlyssesType aType)
|
1327 |
|
|
{
|
1328 |
|
|
if (aType == null)
|
1329 |
|
|
{
|
1330 |
|
|
doError(varname, String.Format("{0} lacks type!", varname.Text));
|
1331 |
|
|
}
|
1332 |
|
|
try
|
1333 |
|
|
{
|
1334 |
|
|
seqList.AddIdentifier(new LocalVariableIdentifier(varname, aType, GetScope()));
|
1335 |
|
|
}
|
1336 |
|
|
catch (ArgumentException)
|
1337 |
|
|
{
|
1338 |
|
|
doError(varname, String.Format("{0} redefined!", varname.Text));
|
1339 |
|
|
}
|
1340 |
|
|
}
|
1341 |
|
|
|
1342 |
|
|
|
1343 |
|
|
internal QualitativeConstraintStatement createTwoVarConstraintStatement(IToken id1, IToken id2, QualitativeConstraintOperation op)
|
1344 |
|
|
{
|
1345 |
|
|
Identifier var1 = pState.Lookup(id1);
|
1346 |
|
|
if (var1 == null)
|
1347 |
|
|
{
|
1348 |
|
|
var1 = new ExpressionVariableIdentifier(id1.Text, id1.Line, id1.CharPositionInLine);
|
1349 |
|
|
var1.SetType(new AnyType((ExpressionVariableIdentifier)var1));
|
1350 |
|
|
|
1351 |
|
|
GetScope().AddIdentifier(var1, null);
|
1352 |
|
|
|
1353 |
|
|
doWarning(id1, String.Format("Free variable in qualitative constraint: '{0}'.", id1.Text));
|
1354 |
|
|
}
|
1355 |
|
|
|
1356 |
|
|
Identifier var2 = pState.Lookup(id2);
|
1357 |
|
|
if (var2 == null)
|
1358 |
|
|
{
|
1359 |
|
|
var2 = new ExpressionVariableIdentifier(id2.Text, id2.Line, id2.CharPositionInLine);
|
1360 |
|
|
var2.SetType(new AnyType((ExpressionVariableIdentifier)var2));
|
1361 |
|
|
|
1362 |
|
|
GetScope().AddIdentifier(var2, null);
|
1363 |
|
|
|
1364 |
|
|
doWarning(id1, String.Format("Free variable in qualitative constraint: '{0}'.", id2.Text));
|
1365 |
|
|
}
|
1366 |
|
|
|
1367 |
|
|
QualitativeConstraintStatement result = new QualitativeConstraintStatement(var1, var2, op, id1.Line, id1.CharPositionInLine);
|
1368 |
|
|
return result;
|
1369 |
|
|
}
|
1370 |
|
|
|
1371 |
|
|
|
1372 |
|
|
internal QualitativeConstraintStatement createQualEqualConstraintStatement(IToken id1, IToken id2)
|
1373 |
|
|
{
|
1374 |
|
|
return createTwoVarConstraintStatement(id1, id2, QualitativeConstraintOperation.Equal);
|
1375 |
|
|
}
|
1376 |
|
|
|
1377 |
|
|
internal QualitativeConstraintStatement createQualArithConstraintStatement(IToken id1, IToken id2, IToken id3, IToken op)
|
1378 |
|
|
{
|
1379 |
|
|
Identifier var1 = pState.Lookup(id1);
|
1380 |
|
|
if (var1 == null)
|
1381 |
|
|
{
|
1382 |
|
|
var1 = new ExpressionVariableIdentifier(id1.Text, id1.Line, id1.CharPositionInLine);
|
1383 |
|
|
var1.SetType(new AnyType((ExpressionVariableIdentifier)var1));
|
1384 |
|
|
|
1385 |
|
|
GetScope().AddIdentifier(var1, null);
|
1386 |
|
|
|
1387 |
|
|
doWarning(id1, String.Format("Free variable in qualitative constraint: '{0}'.", id1.Text));
|
1388 |
|
|
}
|
1389 |
|
|
|
1390 |
|
|
Identifier var2 = pState.Lookup(id2);
|
1391 |
|
|
if (var2 == null)
|
1392 |
|
|
{
|
1393 |
|
|
var2 = new ExpressionVariableIdentifier(id2.Text, id2.Line, id2.CharPositionInLine);
|
1394 |
|
|
var2.SetType(new AnyType((ExpressionVariableIdentifier)var2));
|
1395 |
|
|
|
1396 |
|
|
GetScope().AddIdentifier(var2, null);
|
1397 |
|
|
|
1398 |
|
|
doWarning(id1, String.Format("Free variable in qualitative constraint: '{0}'.", id2.Text));
|
1399 |
|
|
}
|
1400 |
|
|
|
1401 |
|
|
Identifier var3 = pState.Lookup(id3);
|
1402 |
|
|
if (var3 == null)
|
1403 |
|
|
{
|
1404 |
|
|
var3 = new ExpressionVariableIdentifier(id3.Text, id3.Line, id3.CharPositionInLine);
|
1405 |
|
|
var3.SetType(new AnyType((ExpressionVariableIdentifier)var3));
|
1406 |
|
|
|
1407 |
|
|
GetScope().AddIdentifier(var3, null);
|
1408 |
|
|
|
1409 |
|
|
doWarning(id1, String.Format("Free variable in qualitative constraint: '{0}'.", id3.Text));
|
1410 |
|
|
}
|
1411 |
|
|
QualitativeConstraintOperation operation;
|
1412 |
|
|
switch (op.Type)
|
1413 |
|
|
{
|
1414 |
|
|
case ooaParser.T_SUM:
|
1415 |
|
|
operation = QualitativeConstraintOperation.Sum;
|
1416 |
|
|
break;
|
1417 |
|
|
case ooaParser.T_DIFF:
|
1418 |
|
|
operation = QualitativeConstraintOperation.Diff;
|
1419 |
|
|
break;
|
1420 |
|
|
case ooaParser.T_PROD:
|
1421 |
|
|
operation = QualitativeConstraintOperation.Prod;
|
1422 |
|
|
break;
|
1423 |
|
|
default:
|
1424 |
|
|
doError(op, String.Format("'{0}' unknown operation", op.Text));
|
1425 |
|
|
return null;
|
1426 |
|
|
}
|
1427 |
|
|
|
1428 |
|
|
QualitativeConstraintStatement result = new QualitativeConstraintStatement(var1, var2, var3, operation, id1.Line, id1.CharPositionInLine);
|
1429 |
|
|
return result;
|
1430 |
|
|
}
|
1431 |
|
|
|
1432 |
|
|
internal QualitativeConstraintStatement createQualDerivConstraintStatement(IToken id1, IToken derivid)
|
1433 |
|
|
{
|
1434 |
|
|
return createTwoVarConstraintStatement(id1, derivid, QualitativeConstraintOperation.Deriv);
|
1435 |
|
|
}
|
1436 |
|
|
|
1437 |
|
|
|
1438 |
|
|
|
1439 |
|
|
/* creates a general binary operator without any children */
|
1440 |
|
|
internal BinaryOperator createBinaryOperator(ExpressionKind akind)
|
1441 |
|
|
{
|
1442 |
|
|
IToken token = input.LT(-1);
|
1443 |
|
|
return new BinaryOperator(akind, null, null, token.Line, token.CharPositionInLine);
|
1444 |
|
|
}
|
1445 |
|
|
|
1446 |
|
|
|
1447 |
|
|
/* creates a general unary operator without child */
|
1448 |
|
|
internal UnaryOperator createUnaryOperator(ExpressionKind unaryOperatorType)
|
1449 |
|
|
{
|
1450 |
|
|
IToken token = input.LT(-1);
|
1451 |
|
|
return new UnaryOperator(unaryOperatorType, null, token.Line, token.CharPositionInLine);
|
1452 |
|
|
}
|
1453 |
|
|
|
1454 |
|
|
/* create a conditional expression */
|
1455 |
|
|
internal Expression createConditionalExpression(Expression ce, Expression te, Expression ee, IToken ef)
|
1456 |
|
|
{
|
1457 |
|
|
return new TernaryOperator(ExpressionKind.conditional, ce, te, ee, ef.Line, ef.CharPositionInLine, GetScope());
|
1458 |
|
|
}
|
1459 |
|
|
|
1460 |
|
|
/* create a quantifier expression */
|
1461 |
|
|
internal Quantifier createQuantifierExpression(IToken t)
|
1462 |
|
|
{
|
1463 |
|
|
Quantifier result = null;
|
1464 |
|
|
if (t.Type == T_FORALL)
|
1465 |
|
|
result = new ForallQuantifier(null, t.Line, t.CharPositionInLine);
|
1466 |
|
|
else
|
1467 |
|
|
result = new ExistsQuantifier(null, t.Line, t.CharPositionInLine);
|
1468 |
|
|
|
1469 |
|
|
|
1470 |
|
|
pState.PushResolveStack(result);
|
1471 |
|
|
return result;
|
1472 |
|
|
}
|
1473 |
|
|
|
1474 |
|
|
/* add a bound variable to the quantifier */
|
1475 |
|
|
internal void addBoundVarToQuantifierExpression(Quantifier result, IToken id, UlyssesType id_type)
|
1476 |
|
|
{
|
1477 |
|
|
/*note: this might be a bit harsh, but for now it's easier to demand uniquely named vars,
|
1478 |
|
|
without any hiding. Could be fixed in searching only the first resolve level for
|
1479 |
|
|
dupes..
|
1480 |
|
|
*/
|
1481 |
|
|
Identifier sym = pState.Lookup(id);
|
1482 |
|
|
if (sym != null)
|
1483 |
|
|
doError(id, String.Format("{0} already defined!", id.Text));
|
1484 |
|
|
else
|
1485 |
|
|
{
|
1486 |
|
|
if (id_type == null)
|
1487 |
|
|
doError(id, String.Format("{0} lacks type (null).", id.Text));
|
1488 |
|
|
Identifier newvar = new ExpressionVariableIdentifier(id, id_type, GetScope());
|
1489 |
|
|
result.AddIdentifier(newvar, null);
|
1490 |
|
|
}
|
1491 |
|
|
}
|
1492 |
|
|
|
1493 |
|
|
/* add the expression to the quantifier */
|
1494 |
|
|
internal void addExpressionToQuantifier(Quantifier result, Expression e)
|
1495 |
|
|
{
|
1496 |
|
|
result.SetChild(e);
|
1497 |
|
|
}
|
1498 |
|
|
|
1499 |
|
|
/* remove local variables from resolve stack */
|
1500 |
|
|
internal void removeBoundVarsFromResolveStack(Quantifier result)
|
1501 |
|
|
{
|
1502 |
|
|
if (result != null)
|
1503 |
|
|
pState.PopResolveStack();
|
1504 |
|
|
}
|
1505 |
|
|
|
1506 |
|
|
|
1507 |
|
|
/* create a bool constant */
|
1508 |
|
|
internal LeafExpression createBoolConstant(bool p)
|
1509 |
|
|
{
|
1510 |
|
|
IToken token = input.LT(-1);
|
1511 |
|
|
return new ValueExpression<bool>(p, token.Line, token.CharPositionInLine);
|
1512 |
|
|
}
|
1513 |
|
|
|
1514 |
|
|
/* create a nil */
|
1515 |
|
|
internal LeafExpression createNullPointerConstant()
|
1516 |
|
|
{
|
1517 |
|
|
IToken token = input.LT(-1);
|
1518 |
|
|
return new ValueExpression<object>(null, token.Line, token.CharPositionInLine);
|
1519 |
|
|
}
|
1520 |
|
|
|
1521 |
|
|
/* create a 'self' identifier */
|
1522 |
|
|
internal LeafExpression createSelfPointer()
|
1523 |
|
|
{
|
1524 |
|
|
IToken token = input.LT(-1);
|
1525 |
|
|
Identifier self = pState.Lookup("self");
|
1526 |
|
|
if (self == null)
|
1527 |
|
|
{
|
1528 |
|
|
doError(token, "Could not resolve 'self'");
|
1529 |
|
|
return new UnresolvedIdentifierExpression(token, GetScope());
|
1530 |
|
|
}
|
1531 |
|
|
|
1532 |
|
|
IdentifierExpression result = new IdentifierExpression(self, token.Line, token.CharPositionInLine);
|
1533 |
|
|
result.setIsSelf(true);
|
1534 |
|
|
|
1535 |
|
|
return result;
|
1536 |
|
|
}
|
1537 |
|
|
|
1538 |
|
|
/* create a float const */
|
1539 |
|
|
internal LeafExpression createFloatConstant(IToken t_fl)
|
1540 |
|
|
{
|
1541 |
|
|
return new ValueExpression<double>(double.Parse(t_fl.Text, System.Globalization.CultureInfo.InvariantCulture), t_fl.Line, t_fl.CharPositionInLine);
|
1542 |
|
|
}
|
1543 |
|
|
|
1544 |
|
|
/* create int const */
|
1545 |
|
|
internal LeafExpression createIntConstant(IToken t_in)
|
1546 |
|
|
{
|
1547 |
|
|
return new ValueExpression<int>(int.Parse(t_in.Text), t_in.Line, t_in.CharPositionInLine);
|
1548 |
|
|
}
|
1549 |
|
|
|
1550 |
|
|
/* set children of binary operator*/
|
1551 |
|
|
internal Expression addBinaryExpression(BinaryOperator binexpr, Expression expr, Expression e2)
|
1552 |
|
|
{
|
1553 |
|
|
binexpr.SetLeftChild(expr);
|
1554 |
|
|
binexpr.SetRightChild(e2);
|
1555 |
|
|
return binexpr;
|
1556 |
|
|
}
|
1557 |
|
|
|
1558 |
|
|
/* set child of unary expr */
|
1559 |
|
|
internal Expression addUnaryExpression(UnaryOperator unexpr, Expression e)
|
1560 |
|
|
{
|
1561 |
|
|
if (unexpr != null)
|
1562 |
|
|
{
|
1563 |
|
|
unexpr.SetChild(e);
|
1564 |
|
|
return unexpr;
|
1565 |
|
|
}
|
1566 |
|
|
else
|
1567 |
|
|
return e;
|
1568 |
|
|
}
|
1569 |
|
|
|
1570 |
|
|
|
1571 |
|
|
|
1572 |
|
|
/* create a list */
|
1573 |
|
|
internal ListConstructor createInitializedList()
|
1574 |
|
|
{
|
1575 |
|
|
IToken nexttoken = input.LT(1);
|
1576 |
|
|
return new ListConstructor(nexttoken.Line, nexttoken.CharPositionInLine);
|
1577 |
|
|
}
|
1578 |
|
|
|
1579 |
|
|
/* add an element to the list */
|
1580 |
|
|
internal void addListElement(ListConstructor result, Expression e)
|
1581 |
|
|
{
|
1582 |
|
|
result.AddElement(e);
|
1583 |
|
|
}
|
1584 |
|
|
|
1585 |
|
|
/* push list comprehension vars on resolve stack */
|
1586 |
|
|
internal void pushListVarsOnResolveStack(ListConstructor result)
|
1587 |
|
|
{
|
1588 |
|
|
pState.PushResolveStack(result);
|
1589 |
|
|
}
|
1590 |
|
|
|
1591 |
|
|
/* pop list comprehension vars from resolve stack */
|
1592 |
|
|
internal void popListVarsFromResolveStack(ListConstructor result)
|
1593 |
|
|
{
|
1594 |
|
|
if (result != null)
|
1595 |
|
|
pState.PopResolveStack();
|
1596 |
|
|
}
|
1597 |
|
|
|
1598 |
|
|
/* set list comprehension expression */
|
1599 |
|
|
internal void addListComprExpr(ListConstructor result, Expression e)
|
1600 |
|
|
{
|
1601 |
|
|
result.SetComprehension(e);
|
1602 |
|
|
}
|
1603 |
|
|
|
1604 |
|
|
/* add list comprehension variable */
|
1605 |
|
|
internal void addListComprVar(ListConstructor result, IToken id, UlyssesType t1)
|
1606 |
|
|
{
|
1607 |
|
|
Identifier sym = pState.Lookup(id);
|
1608 |
|
|
if (sym != null)
|
1609 |
|
|
{
|
1610 |
|
|
/* see notes in quantifier*/
|
1611 |
|
|
doError(id, String.Format("{0} already defined.", id.Text));
|
1612 |
|
|
}
|
1613 |
|
|
else
|
1614 |
|
|
{
|
1615 |
|
|
ExpressionVariableIdentifier newvar = new ExpressionVariableIdentifier(id, t1, GetScope());
|
1616 |
|
|
result.AddIdentifier(newvar, null);
|
1617 |
|
|
}
|
1618 |
|
|
}
|
1619 |
|
|
|
1620 |
|
|
/* converts a string into a list of char */
|
1621 |
|
|
internal ListConstructor createStringConstant(IToken t_l)
|
1622 |
|
|
{
|
1623 |
|
|
ListConstructor result = new ListConstructor(t_l.Line, t_l.CharPositionInLine);
|
1624 |
|
|
foreach (char c in t_l.Text.Substring(1, t_l.Text.Length - 2))
|
1625 |
|
|
result.AddElement(new ValueExpression<char>(c, t_l.Line, t_l.CharPositionInLine));
|
1626 |
|
|
return result;
|
1627 |
|
|
}
|
1628 |
|
|
|
1629 |
|
|
/* creates an empty map */
|
1630 |
|
|
internal Expression createEmptyMap()
|
1631 |
|
|
{
|
1632 |
|
|
IToken token = input.LT(-1);
|
1633 |
|
|
return new MapConstructor(token.Line, token.CharPositionInLine);
|
1634 |
|
|
}
|
1635 |
|
|
|
1636 |
|
|
/* create a map and populate it with two items.. */
|
1637 |
|
|
internal Expression createMap(Expression e1, Expression e2, IToken am)
|
1638 |
|
|
{
|
1639 |
|
|
MapConstructor result = new MapConstructor(am.Line, am.CharPositionInLine);
|
1640 |
|
|
result.AddItem(e1, e2);
|
1641 |
|
|
return result;
|
1642 |
|
|
}
|
1643 |
|
|
|
1644 |
|
|
/* add a key/value pair to a map */
|
1645 |
|
|
internal void addToMap(Expression map, Expression e3, Expression e4)
|
1646 |
|
|
{
|
1647 |
|
|
((MapConstructor)map).AddItem(e3, e4);
|
1648 |
|
|
}
|
1649 |
|
|
|
1650 |
|
|
/* create a set */
|
1651 |
|
|
internal SetConstructor createSet()
|
1652 |
|
|
{
|
1653 |
|
|
IToken nexttoken = input.LT(1);
|
1654 |
|
|
SetConstructor result = new SetConstructor(nexttoken.Line, nexttoken.CharPositionInLine);
|
1655 |
|
|
return result;
|
1656 |
|
|
}
|
1657 |
|
|
|
1658 |
|
|
/* add item to set */
|
1659 |
|
|
internal void addToSet(Expression result, Expression e2)
|
1660 |
|
|
{
|
1661 |
|
|
((SetConstructor)result).AddItem(e2);
|
1662 |
|
|
}
|
1663 |
|
|
|
1664 |
|
|
/* remove set comprehension variables from resolution stack */
|
1665 |
|
|
internal void popSetVarsFromResolveStack(SetConstructor _set)
|
1666 |
|
|
{
|
1667 |
|
|
if (_set != null)
|
1668 |
|
|
pState.PopResolveStack();
|
1669 |
|
|
}
|
1670 |
|
|
|
1671 |
|
|
/* add set comprehension variables to resolution stack */
|
1672 |
|
|
internal void pushSetVarsOnResolveStack(SetConstructor _set)
|
1673 |
|
|
{
|
1674 |
|
|
pState.PushResolveStack(_set);
|
1675 |
|
|
}
|
1676 |
|
|
|
1677 |
|
|
/* set comprehension expression fro set */
|
1678 |
|
|
internal void addSetComprExpr(SetConstructor _set, Expression epx)
|
1679 |
|
|
{
|
1680 |
|
|
_set.SetComprehension(epx);
|
1681 |
|
|
}
|
1682 |
|
|
|
1683 |
|
|
/* add local set compr. variable */
|
1684 |
|
|
internal void addSetComprVar(SetConstructor _set, IToken id1, UlyssesType t1)
|
1685 |
|
|
{
|
1686 |
|
|
Identifier sym = pState.Lookup(id1);
|
1687 |
|
|
if (sym != null)
|
1688 |
|
|
doError(id1, String.Format("{0} already defined!", id1.Text));
|
1689 |
|
|
else
|
1690 |
|
|
{
|
1691 |
|
|
ExpressionVariableIdentifier newvar = new ExpressionVariableIdentifier(id1, t1, GetScope());
|
1692 |
|
|
_set.AddIdentifier(newvar, null);
|
1693 |
|
|
}
|
1694 |
|
|
}
|
1695 |
|
|
|
1696 |
|
|
/* check whether identifier p is a tuple type */
|
1697 |
|
|
internal bool isTuple(string p)
|
1698 |
|
|
{
|
1699 |
|
|
Identifier sym = pState.Lookup(p);
|
1700 |
|
|
return (sym != null)
|
1701 |
|
|
&& (sym.kind == IdentifierKind.TypeIdentifier)
|
1702 |
|
|
&& (sym.type.kind == TypeKind.TupleType);
|
1703 |
|
|
}
|
1704 |
|
|
|
1705 |
|
|
/* create an initialized tuple */
|
1706 |
|
|
internal Expression createInitializedTuple(IToken aName, System.Collections.Generic.List<Expression> m_params)
|
1707 |
|
|
{
|
1708 |
|
|
Identifier sym = pState.Lookup(aName);
|
1709 |
|
|
if ((sym == null) || !(sym.type is TupleType))
|
1710 |
|
|
{
|
1711 |
|
|
doError(aName, "Not a tuple type!");
|
1712 |
|
|
return null;
|
1713 |
|
|
}
|
1714 |
|
|
|
1715 |
|
|
TupleType atuple = (TupleType)sym.type;
|
1716 |
|
|
if (atuple.innerTypes.Count != m_params.Count)
|
1717 |
|
|
{
|
1718 |
|
|
doError(aName, "Number of parameters does not match type definition!");
|
1719 |
|
|
return null;
|
1720 |
|
|
}
|
1721 |
|
|
|
1722 |
|
|
return new TupleConstructor(sym, m_params, aName.Line, aName.CharPositionInLine);
|
1723 |
|
|
}
|
1724 |
|
|
|
1725 |
|
|
|
1726 |
|
|
/* create an reference expression: (<expression>).xyz */
|
1727 |
|
|
internal Expression createExpressionReference(Expression e, Expression aref, IToken atoken)
|
1728 |
|
|
{
|
1729 |
|
|
AccessExpression result = new AccessExpression(e, aref, atoken.Line, atoken.CharPositionInLine);
|
1730 |
|
|
return result;
|
1731 |
|
|
}
|
1732 |
|
|
|
1733 |
|
|
|
1734 |
|
|
/* gets called when we are parsing attributes */
|
1735 |
|
|
internal void BeginParsingAttributes()
|
1736 |
|
|
{
|
1737 |
|
|
pState.parsingAttributes = true;
|
1738 |
|
|
}
|
1739 |
|
|
|
1740 |
|
|
/* gets called when we stop parsing attributes */
|
1741 |
|
|
internal void EndParsingAttributes()
|
1742 |
|
|
{
|
1743 |
|
|
pState.parsingAttributes = false;
|
1744 |
|
|
}
|
1745 |
|
|
|
1746 |
|
|
/*dummy*/
|
1747 |
|
|
internal bool notIsAttributeInitialization()
|
1748 |
|
|
{
|
1749 |
|
|
return !pState.parsingAttributes;
|
1750 |
|
|
}
|
1751 |
|
|
|
1752 |
|
|
/* create a new(anid) constructor */
|
1753 |
|
|
private Expression createObject(IToken anid)
|
1754 |
|
|
{
|
1755 |
|
|
if (!pState.parsingAttributes)
|
1756 |
|
|
{
|
1757 |
|
|
doError(anid, "Object creation with 'new' only allowed in variable initializers.");
|
1758 |
|
|
return null;
|
1759 |
|
|
}
|
1760 |
|
|
|
1761 |
|
|
|
1762 |
|
|
OpaqueType atype = new OpaqueType(new TypeIdentifier(anid, null, GetScope()));
|
1763 |
|
|
pState.typesToFixUp.Add(atype);
|
1764 |
|
|
return new ObjectConstructor(atype, anid.Line, anid.CharPositionInLine);
|
1765 |
|
|
}
|
1766 |
|
|
|
1767 |
|
|
|
1768 |
|
|
private Expression createNamedObject(IToken anid, IToken aname)
|
1769 |
|
|
{
|
1770 |
|
|
if (!pState.parsingAttributes)
|
1771 |
|
|
{
|
1772 |
|
|
doError(anid, "Object creation with 'new' only allowed in variable initializers.");
|
1773 |
|
|
return null;
|
1774 |
|
|
}
|
1775 |
|
|
|
1776 |
|
|
Regex validid = new Regex("\"[_]*[a-zA-Z][a-zA-Z0-9_]*\"");
|
1777 |
|
|
if (!validid.IsMatch(aname.Text))
|
1778 |
|
|
{
|
1779 |
|
|
doError(aname, "Not a valid identifier");
|
1780 |
|
|
return null;
|
1781 |
|
|
}
|
1782 |
|
|
|
1783 |
|
|
OpaqueType atype = new OpaqueType(new TypeIdentifier(anid, null, GetScope()));
|
1784 |
|
|
pState.typesToFixUp.Add(atype);
|
1785 |
|
|
return new ObjectConstructor(atype, aname.Text, anid.Line, anid.CharPositionInLine);
|
1786 |
|
|
}
|
1787 |
|
|
|
1788 |
|
|
|
1789 |
|
|
internal void setQualitativeDerivDec(QValConstructor result)
|
1790 |
|
|
{
|
1791 |
|
|
result.SetDerivation(QValDeriv.Dec);
|
1792 |
|
|
}
|
1793 |
|
|
|
1794 |
|
|
internal void setQualitativeDerivInc(QValConstructor result)
|
1795 |
|
|
{
|
1796 |
|
|
result.SetDerivation(QValDeriv.Inc);
|
1797 |
|
|
}
|
1798 |
|
|
|
1799 |
|
|
internal void setQualitativeDerivSteady(QValConstructor result)
|
1800 |
|
|
{
|
1801 |
|
|
result.SetDerivation(QValDeriv.Steady);
|
1802 |
|
|
}
|
1803 |
|
|
|
1804 |
|
|
internal void setQualitativeDerivDontCare(QValConstructor result)
|
1805 |
|
|
{
|
1806 |
|
|
result.SetDerivation(QValDeriv.DonTCare);
|
1807 |
|
|
}
|
1808 |
|
|
|
1809 |
|
|
internal void setQualitativeValueRangeInfinity(QValConstructor result, bool p)
|
1810 |
|
|
{
|
1811 |
|
|
throw new NotImplementedException();
|
1812 |
|
|
}
|
1813 |
|
|
|
1814 |
|
|
internal void setQualitativeValueRange(QValConstructor result, Expression expr2)
|
1815 |
|
|
{
|
1816 |
|
|
result.AddRange(expr2);
|
1817 |
|
|
}
|
1818 |
|
|
|
1819 |
|
|
internal void setQualitativeValueInfinity(QValConstructor result, bool minus)
|
1820 |
|
|
{
|
1821 |
|
|
throw new NotImplementedException();
|
1822 |
|
|
}
|
1823 |
|
|
|
1824 |
|
|
internal void setQualitativeValueLandmark(QValConstructor result, Expression expr)
|
1825 |
|
|
{
|
1826 |
|
|
result.SetValue(expr);
|
1827 |
|
|
}
|
1828 |
|
|
|
1829 |
|
|
internal void setQualitativeValueDontCare(QValConstructor result)
|
1830 |
|
|
{
|
1831 |
|
|
throw new NotImplementedException();
|
1832 |
|
|
}
|
1833 |
|
|
|
1834 |
|
|
internal QValConstructor createQualitativeValue(IToken aval)
|
1835 |
|
|
{
|
1836 |
|
|
return new QValConstructor(aval.Line, aval.CharPositionInLine);
|
1837 |
|
|
}
|
1838 |
|
|
|
1839 |
|
|
/* add a local variable to a named action */
|
1840 |
|
|
internal void addLocalVariableToNamedAction(FunctionIdentifier newMethod, IToken id1, UlyssesType t1)
|
1841 |
|
|
{
|
1842 |
|
|
if (t1 == null)
|
1843 |
|
|
{
|
1844 |
|
|
doError(id1, "Variable lacks type");
|
1845 |
|
|
return;
|
1846 |
|
|
}
|
1847 |
|
|
|
1848 |
|
|
LocalVariableIdentifier lvar = new LocalVariableIdentifier(id1, t1, GetScope());
|
1849 |
|
|
newMethod.AddIdentifier(lvar, null);
|
1850 |
|
|
}
|
1851 |
|
|
|
1852 |
|
|
/* ====== */
|
1853 |
|
|
/* ====== */
|
1854 |
|
|
|
1855 |
|
|
public Dictionary<string, string> readableTokens = new Dictionary<string, string>();
|
1856 |
|
|
|
1857 |
|
|
|
1858 |
|
|
private void SetUpTokenDictionary()
|
1859 |
|
|
{
|
1860 |
|
|
if (readableTokens.Count > 0)
|
1861 |
|
|
return;
|
1862 |
|
|
readableTokens.Add("<invalid>", "<invalid>");
|
1863 |
|
|
readableTokens.Add("<EOR>", "<EOR>");
|
1864 |
|
|
readableTokens.Add("<DOWN>", "<DOWN>");
|
1865 |
|
|
readableTokens.Add("<UP>", "<UP>");
|
1866 |
|
|
readableTokens.Add("T_TYPES", "'types'");
|
1867 |
|
|
readableTokens.Add("T_SYSTEM", "'system'");
|
1868 |
|
|
readableTokens.Add("T_SEMICOLON", "';'");
|
1869 |
|
|
readableTokens.Add("T_IDENTIFIER", "<identifier>");
|
1870 |
|
|
readableTokens.Add("T_EQUAL", "'='");
|
1871 |
|
|
readableTokens.Add("T_PRIO", "'//'");
|
1872 |
|
|
readableTokens.Add("T_NONDET", "'[]'");
|
1873 |
|
|
readableTokens.Add("T_LPAREN", "'('");
|
1874 |
|
|
readableTokens.Add("T_RPAREN", "')'");
|
1875 |
|
|
readableTokens.Add("T_LIST", "'list'");
|
1876 |
|
|
readableTokens.Add("T_LSQPAREN", "'['");
|
1877 |
|
|
readableTokens.Add("T_INTNUMBER", "<integer>");
|
1878 |
|
|
readableTokens.Add("T_RSQPAREN", "']'");
|
1879 |
|
|
readableTokens.Add("T_OF", "'of'");
|
1880 |
|
|
readableTokens.Add("T_COMMA", "','");
|
1881 |
|
|
readableTokens.Add("T_MAP", "'map'");
|
1882 |
|
|
readableTokens.Add("T_TO", "'to'");
|
1883 |
|
|
readableTokens.Add("T_QUANTITY", "'quantity'");
|
1884 |
|
|
readableTokens.Add("T_INFTY", "'inf'");
|
1885 |
|
|
readableTokens.Add("T_BOOL", "'bool'");
|
1886 |
|
|
readableTokens.Add("T_INT", "'int'");
|
1887 |
|
|
readableTokens.Add("T_RANGETO", "'..'");
|
1888 |
|
|
readableTokens.Add("T_FLOAT", "'float'");
|
1889 |
|
|
readableTokens.Add("T_FLOATNUMBER", "<floating point number>");
|
1890 |
|
|
readableTokens.Add("T_CHAR", "'char'");
|
1891 |
|
|
readableTokens.Add("T_CBRL", "'{'");
|
1892 |
|
|
readableTokens.Add("T_CBRR", "'}'");
|
1893 |
|
|
readableTokens.Add("T_AUTOCONS", "'autocons'");
|
1894 |
|
|
readableTokens.Add("T_VAR", "'var'");
|
1895 |
|
|
readableTokens.Add("T_METHODS", "'methods'");
|
1896 |
|
|
readableTokens.Add("T_ACTIONS", "'actions'");
|
1897 |
|
|
readableTokens.Add("T_DO", "'do'");
|
1898 |
|
|
readableTokens.Add("T_OD", "'od'");
|
1899 |
|
|
readableTokens.Add("T_STATIC", "'static'");
|
1900 |
|
|
readableTokens.Add("T_COLON", "':'");
|
1901 |
|
|
readableTokens.Add("T_END", "'end'");
|
1902 |
|
|
readableTokens.Add("T_CONT", "'cont'");
|
1903 |
|
|
readableTokens.Add("T_CTRL", "'ctr'");
|
1904 |
|
|
readableTokens.Add("T_OBS", "'obs'");
|
1905 |
|
|
readableTokens.Add("T_REQUIRES", "'requires'");
|
1906 |
|
|
readableTokens.Add("T_AND", "'and'");
|
1907 |
|
|
readableTokens.Add("T_ABORT", "'abort'");
|
1908 |
|
|
readableTokens.Add("T_SKIP", "'skip'");
|
1909 |
|
|
readableTokens.Add("T_KILL", "'kill'");
|
1910 |
|
|
readableTokens.Add("T_SELF", "'self'");
|
1911 |
|
|
readableTokens.Add("T_ASSIGNMENT", "':='");
|
1912 |
|
|
readableTokens.Add("T_WITH", "'with'");
|
1913 |
|
|
readableTokens.Add("T_IF", "'if'");
|
1914 |
|
|
readableTokens.Add("T_THEN", "'then'");
|
1915 |
|
|
readableTokens.Add("T_ELSE", "'else'");
|
1916 |
|
|
readableTokens.Add("T_FORALL", "'forall'");
|
1917 |
|
|
readableTokens.Add("T_EXISTS", "'exists'");
|
1918 |
|
|
readableTokens.Add("T_TRUE", "'true'");
|
1919 |
|
|
readableTokens.Add("T_FALSE", "'false'");
|
1920 |
|
|
readableTokens.Add("T_NIL", "'nil'");
|
1921 |
|
|
readableTokens.Add("T_STRINGLITERAL", "'\"<string>\"'");
|
1922 |
|
|
readableTokens.Add("T_NEW", "'new'");
|
1923 |
|
|
readableTokens.Add("T_BAR", "'|'");
|
1924 |
|
|
readableTokens.Add("T_MAPS", "'->'");
|
1925 |
|
|
readableTokens.Add("T_PRIMED", "'''");
|
1926 |
|
|
readableTokens.Add("T_POINT", "'.'");
|
1927 |
|
|
readableTokens.Add("T_NOTEQUAL", "'<>'");
|
1928 |
|
|
readableTokens.Add("T_SEQMOD_MAPOVERRIDE", "'++'");
|
1929 |
|
|
readableTokens.Add("T_BIIMPLIES", "'<=>'");
|
1930 |
|
|
readableTokens.Add("T_IMPLIES", "'=>'");
|
1931 |
|
|
readableTokens.Add("T_OR", "'or'");
|
1932 |
|
|
readableTokens.Add("T_ABS", "'abs'");
|
1933 |
|
|
readableTokens.Add("T_DIV", "'/'");
|
1934 |
|
|
readableTokens.Add("T_GREATER", "'>'");
|
1935 |
|
|
readableTokens.Add("T_GREATEREQUAL", "'>='");
|
1936 |
|
|
readableTokens.Add("T_IDIV", "'div'");
|
1937 |
|
|
readableTokens.Add("T_LESS", "'<'");
|
1938 |
|
|
readableTokens.Add("T_LESSEQUAL", "'<='");
|
1939 |
|
|
readableTokens.Add("T_MINUS", "'-'");
|
1940 |
|
|
readableTokens.Add("T_MOD", "'mod'");
|
1941 |
|
|
readableTokens.Add("T_POW", "'**'");
|
1942 |
|
|
readableTokens.Add("T_PROD", "'*'");
|
1943 |
|
|
readableTokens.Add("T_SUM", "'+'");
|
1944 |
|
|
readableTokens.Add("T_CONC", "'^'");
|
1945 |
|
|
readableTokens.Add("T_DIFF", "'\\'");
|
1946 |
|
|
readableTokens.Add("T_INTER", "'inter'");
|
1947 |
|
|
readableTokens.Add("T_IN", "'in'");
|
1948 |
|
|
readableTokens.Add("T_SET", "'set'");
|
1949 |
|
|
readableTokens.Add("T_NOT", "'not'");
|
1950 |
|
|
readableTokens.Add("T_SUBSET", "'subset'");
|
1951 |
|
|
readableTokens.Add("T_UNION", "'union'");
|
1952 |
|
|
readableTokens.Add("T_DOMRESBY", "'<-:'");
|
1953 |
|
|
readableTokens.Add("T_DOMRESTO", "'<:'");
|
1954 |
|
|
readableTokens.Add("T_RNGRESBY", "':->'");
|
1955 |
|
|
readableTokens.Add("T_RNGRESTO", "':>'");
|
1956 |
|
|
readableTokens.Add("T_MUNION", "'munion'");
|
1957 |
|
|
readableTokens.Add("T_CARD", "'card'");
|
1958 |
|
|
readableTokens.Add("T_DCONC", "'conc'");
|
1959 |
|
|
readableTokens.Add("T_DINTER", "'dinter'");
|
1960 |
|
|
readableTokens.Add("T_DUNION", "'dunion'");
|
1961 |
|
|
readableTokens.Add("T_ELEMS", "'elems'");
|
1962 |
|
|
readableTokens.Add("T_HEAD", "'hd'");
|
1963 |
|
|
readableTokens.Add("T_INDS", "'inds'");
|
1964 |
|
|
readableTokens.Add("T_LEN", "'len'");
|
1965 |
|
|
readableTokens.Add("T_TAIL", "'tl'");
|
1966 |
|
|
readableTokens.Add("T_DOM", "'dom'");
|
1967 |
|
|
readableTokens.Add("T_RNG", "'rng'");
|
1968 |
|
|
readableTokens.Add("T_MERGE", "'merge'");
|
1969 |
|
|
readableTokens.Add("T_WS", "<space>");
|
1970 |
|
|
readableTokens.Add("T_COMMENT", "'/*<comment>*/'");
|
1971 |
|
|
readableTokens.Add("LINE_COMMENT", "'#<line comment>'");
|
1972 |
|
|
readableTokens.Add("T_DIGIT", "<0..9>");
|
1973 |
|
|
readableTokens.Add("FLOAT_OR_INT_OR_RANGE", "<float_int_range>");
|
1974 |
|
|
readableTokens.Add("T_LETTER", "<a..z,A..Z>");
|
1975 |
|
|
readableTokens.Add("'|['", "'|['");
|
1976 |
|
|
readableTokens.Add("']|'", "']|'");
|
1977 |
|
|
readableTokens.Add("'add'", "'add'");
|
1978 |
|
|
readableTokens.Add("'mult'", "'mult'");
|
1979 |
|
|
readableTokens.Add("'deriv'", "'deriv'");
|
1980 |
|
|
readableTokens.Add("'mon+'", "'mon+'");
|
1981 |
|
|
readableTokens.Add("'mon-'", "'mon-'");
|
1982 |
|
|
readableTokens.Add("'id'", "'id'");
|
1983 |
|
|
readableTokens.Add("'qval'", "'qval'");
|
1984 |
|
|
readableTokens.Add("'\"'", "'\"'");
|
1985 |
|
|
readableTokens.Add("as", "as");
|
1986 |
|
|
}
|
1987 |
|
|
|
1988 |
|
|
/* override routine that displays recongition errors.. */
|
1989 |
|
|
public override void DisplayRecognitionError(String[] tokenNames, RecognitionException e)
|
1990 |
|
|
{
|
1991 |
|
|
int i;
|
1992 |
|
|
System.Text.StringBuilder result = new System.Text.StringBuilder();
|
1993 |
|
|
SetUpTokenDictionary();
|
1994 |
|
|
|
1995 |
|
|
|
1996 |
|
|
if (e is MismatchedTokenException)
|
1997 |
|
|
{
|
1998 |
|
|
result.Append("Found '");
|
1999 |
|
|
result.Append(e.Token.Text);
|
2000 |
|
|
result.Append("'");
|
2001 |
|
|
i = ((MismatchedTokenException)e).Expecting;
|
2002 |
|
|
result.Append(" Expected: ");
|
2003 |
|
|
result.Append(readableTokens[tokenNames[i]]);
|
2004 |
|
|
result.Append(" ("); result.Append(tokenNames[i]); result.Append(") ");
|
2005 |
|
|
|
2006 |
|
|
}
|
2007 |
|
|
else
|
2008 |
|
|
{
|
2009 |
|
|
/*if (e is NoViableAltException)
|
2010 |
|
|
{
|
2011 |
|
|
result.Append("Unexpected '");
|
2012 |
|
|
result.Append(e.Token.Text);
|
2013 |
|
|
result.Append("' (");
|
2014 |
|
|
i = ((NoViableAltException)e).UnexpectedType;
|
2015 |
|
|
result.Append(tokenNames[i]);
|
2016 |
|
|
result.Append(")");
|
2017 |
|
|
}
|
2018 |
|
|
else*/
|
2019 |
|
|
if (e is RecognitionException)
|
2020 |
|
|
{
|
2021 |
|
|
result.Append("Unexpected '");
|
2022 |
|
|
result.Append(e.Token.Text);
|
2023 |
|
|
result.Append("' (");
|
2024 |
|
|
i = ((RecognitionException)e).UnexpectedType;
|
2025 |
|
|
result.Append(tokenNames[i]);
|
2026 |
|
|
result.Append(") ");
|
2027 |
|
|
}
|
2028 |
|
|
else
|
2029 |
|
|
result.Append(e.Message);
|
2030 |
|
|
}
|
2031 |
|
|
|
2032 |
|
|
pState.AddErrorMessage(new ParserError(pState.filename, e.Line, e.CharPositionInLine, result.ToString()));
|
2033 |
|
|
}
|
2034 |
|
|
|
2035 |
|
|
|
2036 |
|
|
/* just run over once */
|
2037 |
|
|
public static int FirstPass(ParserState pState)
|
2038 |
|
|
{
|
2039 |
|
|
pState.parser.ooActionSystems();
|
2040 |
|
|
|
2041 |
|
|
return pState.listOfParserErrors.Count; // + pState.lexer.NumberOfSyntaxErrors;
|
2042 |
|
|
}
|
2043 |
|
|
|
2044 |
|
|
|
2045 |
|
|
|
2046 |
|
|
/* print syntax tree */
|
2047 |
|
|
public static string PrintSyntaxTree(ParserState pState)
|
2048 |
|
|
{
|
2049 |
|
|
if ((pState != null) && (pState.ooaSystem != null))
|
2050 |
|
|
{
|
2051 |
|
|
return pState.ooaSystem.ToString();
|
2052 |
|
|
}
|
2053 |
|
|
else
|
2054 |
|
|
return String.Empty;
|
2055 |
|
|
}
|
2056 |
|
|
}
|
2057 |
|
|
} |