Project

General

Profile

root / trunk / compiler / ooasCompiler / src / org / momut / ooas / ast / AstBuilder.java @ 9

1
/**
2
  *
3
  *                      OOAS Compiler
4
  *
5
  *       Copyright 2015, AIT Austrian Institute of Technology.
6
  * This code is based on the C# Version of the OOAS Compiler, which is
7
  * copyright 2015 by the Institute of Software Technology, Graz University
8
  * of Technology with portions copyright by the AIT Austrian Institute of
9
  * Technology. All rights reserved.
10
  *
11
  * SEE THE "LICENSE" FILE FOR THE TERMS UNDER WHICH THIS FILE IS PROVIDED.
12
  *
13
  * If you modify the file please update the list of contributors below to in-
14
  * clude your name. Please also stick to the coding convention of using TABs
15
  * to do the basic (block-level) indentation and spaces for anything after
16
  * that. (Enable the display of special chars and it should be pretty obvious
17
  * what this means.) Also, remove all trailing whitespace.
18
  *
19
  * Contributors:
20
  *               Stefan Tiran (AIT)
21
  *               Willibald Krenn (AIT)
22
  *
23
  */
24

    
25

    
26
package org.momut.ooas.ast;
27

    
28

    
29
import java.util.LinkedList;
30
import java.util.List;
31

    
32
import org.momut.ooas.ast.expressions.AccessExpression;
33
import org.momut.ooas.ast.expressions.CallExpression;
34
import org.momut.ooas.ast.expressions.Expression;
35
import org.momut.ooas.ast.expressions.IdentifierExpression;
36
import org.momut.ooas.ast.expressions.LeafExpression;
37
import org.momut.ooas.ast.expressions.ListConstructor;
38
import org.momut.ooas.ast.expressions.ObjectConstructor;
39
import org.momut.ooas.ast.expressions.UnresolvedIdentifierExpression;
40
import org.momut.ooas.ast.expressions.ValueExpression;
41
import org.momut.ooas.ast.identifiers.AttributeIdentifier;
42
import org.momut.ooas.ast.identifiers.EnumIdentifier;
43
import org.momut.ooas.ast.identifiers.Identifier;
44
import org.momut.ooas.ast.identifiers.IdentifierKind;
45
import org.momut.ooas.ast.identifiers.IdentifierList;
46
import org.momut.ooas.ast.identifiers.MainModule;
47
import org.momut.ooas.ast.identifiers.MethodIdentifier;
48
import org.momut.ooas.ast.identifiers.NamedActionIdentifier;
49
import org.momut.ooas.ast.identifiers.NondetIdentifierList;
50
import org.momut.ooas.ast.identifiers.ParameterIdentifier;
51
import org.momut.ooas.ast.identifiers.PrioIdentifierList;
52
import org.momut.ooas.ast.identifiers.SelfTypeIdentifier;
53
import org.momut.ooas.ast.identifiers.TypeIdentifier;
54
import org.momut.ooas.ast.statements.Assignment;
55
import org.momut.ooas.ast.statements.Block;
56
import org.momut.ooas.ast.statements.Call;
57
import org.momut.ooas.ast.statements.NondetBlock;
58
import org.momut.ooas.ast.statements.SeqBlock;
59
import org.momut.ooas.ast.statements.SkipStatement;
60
import org.momut.ooas.ast.statements.Statement;
61
import org.momut.ooas.ast.types.BoolType;
62
import org.momut.ooas.ast.types.EnumType;
63
import org.momut.ooas.ast.types.FunctionType;
64
import org.momut.ooas.ast.types.FunctionType.FunctionTypeEnum;
65
import org.momut.ooas.ast.types.IntType;
66
import org.momut.ooas.ast.types.ListType;
67
import org.momut.ooas.ast.types.OoActionSystemType;
68
import org.momut.ooas.ast.types.OpaqueType;
69
import org.momut.ooas.ast.types.Type;
70
import org.momut.ooas.parser.ParserError;
71
import org.momut.ooas.parser.ParserState;
72

    
73

    
74
public class AstBuilder {
75

    
76
        public static void setSystemDescription(MainModule mainModule, Identifier systemDescription) {
77
                final IdentifierList aDescr = new NondetIdentifierList();
78
                aDescr.AddElement(systemDescription);
79
                mainModule.SetSystemDescription(aDescr);
80
        }
81

    
82
        public static Identifier createPrioritizedSAB(LinkedList<Identifier> systems){
83
                final IdentifierList systemDescription = new PrioIdentifierList();
84
                for (final Identifier system : systems){
85
                        systemDescription.AddElement(system);
86
                }
87
                return systemDescription;
88
        }
89

    
90
        public static Identifier createNonDetChoiceSAB(LinkedList<Identifier> systems){
91
                final IdentifierList systemDescription = new NondetIdentifierList();
92
                for (final Identifier system : systems){
93
                        systemDescription.AddElement(system);
94
                }
95
                return systemDescription;
96
        }
97

    
98
        public static TypeIdentifier createActionSystem(boolean autocons, String name, IScope scope){
99
                final OoActionSystemType type = new OoActionSystemType(autocons, null, null);
100
                final SelfTypeIdentifier self = new SelfTypeIdentifier("self", type, scope);
101
                type.AddIdentifier(self, null);
102
                type.SetupAnonymousName(); // need to be called before setting the type identifier
103
                final TypeIdentifier ident = new TypeIdentifier(name, type, scope);
104

    
105
                type.SetTypeIdentifier(ident);
106
                scope.AddIdentifier(ident, null);
107

    
108
                return ident;
109
        }
110

    
111

    
112
        public static AttributeIdentifier createObjectAttribute(String varName, Identifier aClass, boolean doInstantiate, Identifier root){
113
                final Type aType = aClass.type();
114
                aType.SetupAnonymousName(); //not sure if necessary
115
                Expression anExpr;
116
                if (doInstantiate){
117
                        anExpr = new ObjectConstructor(aType, varName, 0, 0);
118
                } else {
119
                        anExpr = new ValueExpression<Object>(null, 0, 0, Object.class);
120
                }
121

    
122
                final AttributeIdentifier attributeIdentifier = new AttributeIdentifier(varName, aType, ((IScope)(root).type()), anExpr, false, false, false );
123
                ((IScope)(root).type()).AddIdentifier(attributeIdentifier, null);
124

    
125
                return attributeIdentifier;
126
        }
127

    
128

    
129
        public static Expression boolConstant(boolean b){
130
                return new ValueExpression<Boolean>(b, 0, 0, Boolean.class);
131
        }
132

    
133
        public static ListType createListType(Type elemType, int max, TypeIdentifier anIdentifier){
134
                final ListType result = new ListType(elemType, max, null);
135
                result.SetupAnonymousName();
136
                result.SetTypeIdentifier(anIdentifier);
137
                return result;
138
        }
139

    
140
        public static EnumType createEnumType(String name, List<String> ranges, IScope scope){
141
                final EnumType type = new EnumType(null);
142

    
143
                EnumIdentifier enumval;
144
                for (final String range : ranges){
145
                        enumval = new EnumIdentifier(range, type, scope);
146
                        type.AddEnumSymbol(enumval);
147
                        scope.AddIdentifier(enumval, null);
148
                }
149
                type.SetupAnonymousName();
150
                final TypeIdentifier ident = new TypeIdentifier(name, type, scope);
151

    
152
                type.SetTypeIdentifier(ident);
153
                scope.AddIdentifier(ident, null);
154
                return type;
155
        }
156

    
157

    
158
        public static Type createIntType(int low, int high){
159
                return new IntType(low, high, null);
160
        }
161

    
162
        public static AttributeIdentifier createListAttribute(String varname, ListType type, Identifier root){
163
                final Expression anExpr = new ListConstructor(0, 0);
164
                final AttributeIdentifier attributeIdentifier = new AttributeIdentifier(varname, type, ((IScope)(root).type()), anExpr, false, false, false );
165
                ((IScope)(root).type()).AddIdentifier(attributeIdentifier, null);
166

    
167
                return attributeIdentifier;
168
        }
169

    
170
        public static AttributeIdentifier createEnumAttribute(String varname, EnumType type, String init, Identifier root){
171
                final Identifier initIdent = root.definingScope().ResolveIdentifier(init);
172
                final Expression anExpr = new IdentifierExpression(initIdent, 0, 0);
173
                final AttributeIdentifier attributeIdentifier = new AttributeIdentifier(varname, type, ((IScope)(root).type()), anExpr, false, false, false );
174
                ((IScope)(root).type()).AddIdentifier(attributeIdentifier, null);
175

    
176
                return attributeIdentifier;
177
        }
178

    
179

    
180
        public static AttributeIdentifier createBoolAttribute(String varname, boolean isStatic, boolean init, Identifier root){
181
                final Expression anExpr = new ValueExpression<Boolean>(init, 0, 0, Boolean.class);
182
                final Type aType = new BoolType(null);
183
                aType.SetupAnonymousName();
184
                final AttributeIdentifier attributeIdentifier = new AttributeIdentifier(varname, aType, ((IScope)(root).type()), anExpr, isStatic, false, false );
185
                ((IScope)(root).type()).AddIdentifier(attributeIdentifier, null);
186

    
187
                return attributeIdentifier;
188
        }
189

    
190
        public static AttributeIdentifier createAttribute(String varname, boolean isStatic, Type aType, Expression anExpr, IScope scope){
191
                final AttributeIdentifier attributeIdentifier = new AttributeIdentifier(varname, aType, scope, anExpr, isStatic, false, false );
192
                scope.AddIdentifier(attributeIdentifier, null);
193

    
194
                return attributeIdentifier;
195
        }
196

    
197
        public static MethodIdentifier createMethod(
198
                        String name,
199
                        LinkedList<ParameterIdentifier> params,
200
                        Type returnType,
201
                        Identifier as,
202
                        Statement body
203
                        ) {
204
                final LinkedList<Type> parameterTypes = new LinkedList<Type>();
205
                for (final ParameterIdentifier param : params) {
206
                        parameterTypes.add(param.type());
207
                }
208

    
209
                final FunctionType methodType = new FunctionType(FunctionType.FunctionTypeEnum.Method, parameterTypes, returnType);
210

    
211
                final MethodIdentifier ident = new MethodIdentifier(name, methodType, (IScope)as.type());
212
                ((IScope)(as.type())).AddIdentifier(ident, null);
213
                ident.SetParentScope((IScope)as.type());
214
                ident.SetBody(body);
215

    
216
                for (final ParameterIdentifier p : params) {
217
                        ident.AddParameter(p);
218
                }
219
                methodType.SetupAnonymousName();
220

    
221
                return ident;
222
        }
223

    
224
        public static NamedActionIdentifier createActionWithoutBody(
225
                        FunctionType.FunctionTypeEnum functionType,
226
                        String name,
227
                        LinkedList<Type> parameters,
228
                        Identifier as)
229
        {
230
                final FunctionType actionType = new FunctionType(functionType, parameters, null);
231
                actionType.SetupAnonymousName();
232
                final NamedActionIdentifier ident = new NamedActionIdentifier(name, actionType, (IScope)as.type());
233
                ((IScope)(as.type())).AddIdentifier(ident, null);
234
                return ident;
235
        }
236

    
237
        public static Identifier createAction(
238
                        FunctionType.FunctionTypeEnum functionType,
239
                        String name,
240
                        LinkedList<Type> parameters,
241
                        Identifier as,
242
                        Statement body)
243
        {
244
                final FunctionType actionType = new FunctionType(functionType, parameters, null);
245
                actionType.SetupAnonymousName();
246
                final NamedActionIdentifier ident = new NamedActionIdentifier(name, actionType, (IScope)as.type());
247
                ((IScope)(as.type())).AddIdentifier(ident, null);
248
                ident.SetBody(body);
249
                return ident;
250
        }
251

    
252
        public static Block createNonDetBlock(LinkedList<Identifier> actions){
253
                final Block block = new NondetBlock(0, 0);
254

    
255
                for (final Identifier action : actions) {
256
                        final Block block2 = new SeqBlock(0, 0);
257
                        final CallExpression ce = new CallExpression(
258
                                        new IdentifierExpression(action,0,0),
259
                                        null,
260
                                        0,
261
                                        0,
262
                                        block
263
                                        );
264
                        block2.AddStatement(new Call(ce, 0, 0));
265
                        block.AddStatement(block2);
266
                }
267

    
268
                return block;
269
        }
270

    
271

    
272
        public static MainModule buildHelloWorld(){
273
                // == (1) define the main module, i.e. main scope ==
274
                final MainModule mainModule = new MainModule();
275

    
276
                // == (2) let's define the single action system type that is contained/defined in this main module ==
277
                final OoActionSystemType greeterType = new OoActionSystemType(
278
                                true,      // let's suppose this is auto-constructing
279
                                null,      // refines no other action system
280
                                null       // type identifier is set below
281
                );
282
                greeterType.AddIdentifier(new SelfTypeIdentifier("self", greeterType, greeterType), null);
283
                greeterType.SetupAnonymousName(); // need to be called before setting the type identifier
284

    
285
                // -- instantiate the type identifier for our action system type --
286
                final TypeIdentifier greeterTypeIdentifier = new TypeIdentifier(
287
                                "greeter",  // name
288
                                greeterType,// bind it to the type
289
                                mainModule  // scope where this is defined
290
                );
291
                // -- wire up the type identifier with the type (doubly linked therefore this more cumbersome two-call approach)
292
                greeterType.SetTypeIdentifier(greeterTypeIdentifier);
293
                mainModule.AddIdentifier(greeterTypeIdentifier, null);
294

    
295

    
296
                // == (3) define the sole observable action of the type ==
297
                // -- define the (implicitly declared type of the action) --lBlock
298
                final FunctionType helloWorldActionType = new FunctionType(  // this type is anonymous and doesn't have a name!
299
                                FunctionTypeEnum.Observable,   // This is observable, hence an action
300
                                new LinkedList<Type>(), // no parameters
301
                                null                           // void return
302
                );
303
                helloWorldActionType.SetupAnonymousName(); // need to be called before setting the type identifier
304
                // -- define the actual identifier incl. impl. --
305
                final NamedActionIdentifier helloWorldActionIdentifier = new NamedActionIdentifier(
306
                                "HelloWorld",           // name of the action
307
                                helloWorldActionType,   // type of the action
308
                                greeterType             // defining scope
309
                );
310
                // -- register the new identifier with the current scope
311
                greeterType.AddIdentifier(helloWorldActionIdentifier, null);
312
                // -- add implementation of the action
313
                //helloWorldActionIdentifier.SetBody(new SkipStatement(0, 0));
314
                helloWorldActionIdentifier.SetBody(new SkipStatement(0, 0));
315

    
316

    
317
                // == (4) define the do-od block of the action system type
318
                final Block greeterDoOdBlock = new SeqBlock(0, 0);
319
                greeterType.SetDoOdBlock(greeterDoOdBlock);
320
                // -- add a call statement to the dood block --
321
                final CallExpression callHelloWorldExpression = new CallExpression(
322
                                new IdentifierExpression(helloWorldActionIdentifier, 0, 0),  // what to call
323
                                null,             // arguments
324
                                0,                // line
325
                                0,                // col
326
                                greeterDoOdBlock  // scope
327
                );
328
                greeterDoOdBlock.AddStatement(new Call(callHelloWorldExpression, 0, 0));
329

    
330

    
331
                // == (5) add scheduling information (SAB block) ==
332
                final IdentifierList systemDescription = new NondetIdentifierList();
333
                systemDescription.AddElement(greeterTypeIdentifier);
334
                mainModule.SetSystemDescription(systemDescription);
335

    
336
                return mainModule;
337
        }
338

    
339

    
340
        public static LeafExpression createIntConstant(Integer i)
341
        {
342
                return new ValueExpression<Integer>(i, 0, 0, Integer.class);
343
        }
344

    
345
        public static Expression createIdentifierAccessExpressionWithoutResolve(String name, IScope scope){
346
                final IdentifierExpression uIdent = new UnresolvedIdentifierExpression(name, scope);
347
                final IdentifierExpression aself = new IdentifierExpression(scope.ResolveIdentifier("self"), 0, 0);
348
                aself.setIsSelf(true);
349
                final AccessExpression exp = new AccessExpression(aself, uIdent, 0, 0);
350
                return exp;
351
        }
352

    
353
        public static Expression createIdentifierAccessExpression(Identifier attr){
354
                final IdentifierExpression uIdent = new IdentifierExpression(attr, 0, 0);
355

    
356
                final IdentifierExpression aself = new IdentifierExpression(attr.definingScope().ResolveIdentifier("self"), 0, 0);
357
                aself.setIsSelf(true);
358
                final AccessExpression exp = new AccessExpression(aself, uIdent, 0, 0);
359
                return exp;
360
        }
361

    
362
        public static CallExpression createMethodAccessExpression(Expression subexpr, List<Expression> m_params, IScope scope){
363
                return new CallExpression(subexpr, m_params, 0, 0, scope);
364
        }
365

    
366
        public static Statement createAssignment(AttributeIdentifier attr, ListConstructor lc) {
367
                return new Assignment(createIdentifierAccessExpression(attr), lc, null, 0, 0);
368
        }
369

    
370
        public static Statement createAssignment(Expression exp1, Expression exp2) {
371
                return new Assignment(exp1, exp2, null, 0, 0);
372
        }
373

    
374
        public static Statement createAssignment(AttributeIdentifier attr, boolean b) {
375
                return new Assignment(createIdentifierAccessExpression(attr), new ValueExpression<Boolean>(b, 0, 0, Boolean.class),null,0,0);
376
        }
377

    
378
        public static Statement createAssignment2(
379
                        AttributeIdentifier attr, Identifier instance) {
380
                //FIXXME here be dragons
381
                return new Assignment(createIdentifierAccessExpression(attr), new IdentifierExpression(instance, 0, 0), null, 0, 0);
382
        }
383

    
384
        public static Statement createAssignmentWithoutResolve(String leftName, IScope leftScope, Expression right){
385
                return new Assignment(new UnresolvedIdentifierExpression(leftName, leftScope), right , null, 0, 0);
386
        }
387

    
388
        public static Statement createAssignmentWithoutResolve(String leftName, IScope leftScope, String rightName, IScope rightScope){
389
                return new Assignment(new UnresolvedIdentifierExpression(leftName, leftScope), new UnresolvedIdentifierExpression(rightName, rightScope), null, 0, 0);
390
        }
391

    
392
        public static Statement createAssignment(
393
                        AttributeIdentifier attr, Identifier instance) {
394
                return new Assignment(createIdentifierAccessExpression(attr), createIdentifierAccessExpression(instance), null, 0, 0);
395
        }
396

    
397
        public static Expression createMethodAccessExpressionWithLocalVar(String objectName,
398
                        String methodName, List<Expression> m_params, IScope scope) {
399
                final Expression subexpr = new AccessExpression(
400
                                new UnresolvedIdentifierExpression(objectName, scope),
401
                                new UnresolvedIdentifierExpression(methodName, scope),
402
                                0,0);
403
                return new CallExpression(subexpr, m_params, 0, 0, scope);
404
        }
405

    
406

    
407
        public static Expression createMethodAccessExpressionWithoutResolveAtAll(String objectName,
408
                        String methodName, List<Expression> m_params, IScope scope) {
409
                final UnresolvedIdentifierExpression modelSelf = new UnresolvedIdentifierExpression("self", scope);
410
                modelSelf.setIsSelf(true);
411

    
412
                final Expression subexpr = new AccessExpression(
413
                                new AccessExpression(
414
                                                modelSelf,
415
                                                new UnresolvedIdentifierExpression(objectName, scope),
416
                                                0, 0),
417
                                new UnresolvedIdentifierExpression(methodName, scope),
418
                                0,0);
419
                return new CallExpression(subexpr, m_params, 0, 0, scope);
420
        }
421

    
422

    
423
        public static Statement createAssignment(Identifier attr,
424
                        Identifier instance) {
425
                return new Assignment(createIdentifierAccessExpression(attr), createIdentifierAccessExpression(instance), null, 0, 0);
426
        }
427

    
428
        public static Statement createAssignment(Identifier attr,
429
                        Expression exp) {
430
                return new Assignment(createIdentifierAccessExpression(attr), exp, null, 0, 0);
431
        }
432

    
433
        public static LeafExpression createNullPointerConstant()
434
        {
435
                return new ValueExpression<Object>(null, 0, 0, Object.class);
436
        }
437

    
438
        public static Expression intConstant(int i) {
439
                return new ValueExpression<Integer>(i, 0, 0, Integer.class);
440
        }
441

    
442
        public static void FixupNamedTypes(ParserState pState)
443
        {
444
                /*named type refs that could not be resolved in the first run, have to
445
                  be resolved now. */
446
                for (final OpaqueType ntype: pState.typesToFixUp)
447
                {
448
                        if (ntype.resolvedType() == null)
449
                        {
450
                                //ntype.identifier
451
                                final Identifier asym = pState.Lookup(ntype.identifier().tokenText(), ntype.identifier().definingScope());
452
                                if ((asym == null) || (asym.kind() != IdentifierKind.TypeIdentifier))
453
                                {
454
                                        final ParserError error = new ParserError(pState.filename, ntype.identifier().line(), ntype.identifier().column(),
455
                                                        String.format("Can not resolve %s to a named type", ntype.identifier().tokenText()));
456
                                        pState.AddErrorMessage(error);
457
                                }
458
                                else
459
                                        ntype.SetResolvedType(asym.type());
460
                        }
461
                }
462
                pState.typesToFixUp.clear();
463
        }
464

    
465

    
466
}