GenericBackend.py 6.65 KB
Newer Older
Maxime Perrotin's avatar
Maxime Perrotin committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
    OpenGEODE - A tiny SDL Editor for TASTE

    This module is a template for backends such as code generators

    Entry point:
    The AST of the model that is parsed is described in ogAST.py

    A Visitor Pattern using Python's "singledispatch" mechanism is used
    to go through the AST and generate code for each SDL construct.

Maxime Perrotin's avatar
Maxime Perrotin committed
15
    At top-level there is a function called "generate", decorated with the
Maxime Perrotin's avatar
Maxime Perrotin committed
16
    singledispatch mechanism, that needs to be called to generate the code
Maxime Perrotin's avatar
Maxime Perrotin committed
17
18
19
20
21
22
    of an AST construct.

    Expressions have to be generated from the "expression" function.

    Optionnaly use the Helper module functions to flatten the model,
    rename symbols, etc. (see AdaGenerator.py).
Maxime Perrotin's avatar
Maxime Perrotin committed
23
24
25
26
27
28
29
30
31
32
33
34
35

    Copyright (c) 2012-2014 European Space Agency

    Designed and implemented by Maxime Perrotin

    Contact: maxime.perrotin@esa.int
"""


import logging
from singledispatch import singledispatch

import ogAST
Maxime Perrotin's avatar
Maxime Perrotin committed
36
import Helper
Maxime Perrotin's avatar
Maxime Perrotin committed
37
38
39
40
41
42
43
44

LOG = logging.getLogger(__name__)

__all__ = ['generate']


@singledispatch
def generate(ast):
Maxime Perrotin's avatar
Maxime Perrotin committed
45
46
47
48
49
    ''' Generate the code for an item of the AST
        Should typically return:
            - a list of statements
            - a list of needed local variables
    '''
Maxime Perrotin's avatar
Maxime Perrotin committed
50
    raise TypeError('[Backend] Unsupported AST construct')
Maxime Perrotin's avatar
Maxime Perrotin committed
51
52
53
54
55
56
57
58
59
60
61
62
63
    # return [], []


@singledispatch
def expression(expr):
    ''' Generate the code for Expression-classes, returning 3 things:
            - list of statements
            - useable string corresponding to the evaluation of the expression,
            - list of local declarations
    '''
    _ = expr
    raise TypeError('Unsupported expression: ' + str(expr))
    # return [], '', []
Maxime Perrotin's avatar
Maxime Perrotin committed
64
65
66
67
68
69

# Processing of the AST

@generate.register(ogAST.Process)
def _process(process):
    ''' Generate the code for a complete process (AST Top level) '''
Maxime Perrotin's avatar
Maxime Perrotin committed
70
71
72
73
74
75
    # In case model has nested states, flatten everything
    Helper.flatten(process)

    # Make an maping {input: {state: transition...}} in order to easily
    # generate the lookup tables for the state machine runtime
    mapping = Helper.map_input_state(process)
Maxime Perrotin's avatar
Maxime Perrotin committed
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108

def write_statement(param, newline):
    ''' Generate the code for the special "write" operator '''
    pass

@generate.register(ogAST.Output)
@generate.register(ogAST.ProcedureCall)
def _call_external_function(output):
    ''' Generate the code of a set of output or procedure call statement '''
    pass


@generate.register(ogAST.TaskAssign)
def _task_assign(task):
    ''' A list of assignments in a task symbol '''
    pass


@generate.register(ogAST.TaskInformalText)
def _task_informal_text(task):
    ''' Generate comments for informal text '''
    pass


@generate.register(ogAST.TaskForLoop)
def _task_forloop(task):
    '''
        Return the code corresponding to a for loop. Two forms are possible:
        for x in range ([start], stop [, step])
        for x in iterable (a SEQUENCE OF)
    '''
    pass

Maxime Perrotin's avatar
Maxime Perrotin committed
109
110
111
112
113
@generate.register(ogAST.Decision)
def _decision(dec):
    ''' generate the code for a decision '''
    pass

Maxime Perrotin's avatar
Maxime Perrotin committed
114

Maxime Perrotin's avatar
Maxime Perrotin committed
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
@generate.register(ogAST.Label)
def _label(tr):
    ''' Transition following labels should be generated in a separate section
        for visibility reasons
    '''
    pass


@generate.register(ogAST.Transition)
def _transition(tr):
    ''' generate the code for a transition '''
    pass


@generate.register(ogAST.Floating_label)
def _floating_label(label):
    ''' Generate the code for a floating label (label + transition) '''
    pass


@generate.register(ogAST.Procedure)
def _inner_procedure(proc):
    ''' Generate the code for a procedure '''
    pass
@expression.register(ogAST.PrimVariable)
Maxime Perrotin's avatar
Maxime Perrotin committed
140
141
142
143
144
def _primary_variable(prim):
    ''' Single variable reference '''
    pass


Maxime Perrotin's avatar
Maxime Perrotin committed
145
146
147
# Expressions

@expression.register(ogAST.PrimPath)
Maxime Perrotin's avatar
Maxime Perrotin committed
148
149
150
151
152
153
154
155
156
157
158
159
160
def _prim_path(primaryId):
    '''
        Return the string of an element list (path)
        cases: a => 'l_a' (reference to a variable)
        a_timer => 'a_timer'  (reference to a timer)
        a!b => a.b (field of a structure)
        a!b if a is a CHOICE => TypeOfa_b_get(a)
        a(Expression) => a(ExpressionSolver) (array index)
        Expression can be complex (if-then-else-fi..)
    '''
    pass


Maxime Perrotin's avatar
Maxime Perrotin committed
161
162
163
164
165
166
167
168
169
170
171
172
173
@expression.register(ogAST.ExprPlus)
@expression.register(ogAST.ExprMul)
@expression.register(ogAST.ExprMinus)
@expression.register(ogAST.ExprEq)
@expression.register(ogAST.ExprNeq)
@expression.register(ogAST.ExprGt)
@expression.register(ogAST.ExprGe)
@expression.register(ogAST.ExprLt)
@expression.register(ogAST.ExprLe)
@expression.register(ogAST.ExprDiv)
@expression.register(ogAST.ExprMod)
@expression.register(ogAST.ExprRem)
@expression.register(ogAST.ExprAssign)
Maxime Perrotin's avatar
Maxime Perrotin committed
174
175
176
177
178
def _basic_operators(expr):
    ''' Expressions with two sides '''
    pass


Maxime Perrotin's avatar
Maxime Perrotin committed
179
180
181
@expression.register(ogAST.ExprOr)
@expression.register(ogAST.ExprAnd)
@expression.register(ogAST.ExprXor)
Maxime Perrotin's avatar
Maxime Perrotin committed
182
183
184
185
186
def _bitwise_operators(expr):
    ''' Logical operators '''
    pass


Maxime Perrotin's avatar
Maxime Perrotin committed
187
@expression.register(ogAST.ExprAppend)
Maxime Perrotin's avatar
Maxime Perrotin committed
188
189
190
191
192
def _append(expr):
    ''' Generate code for the APPEND construct: a // b '''
    pass


Maxime Perrotin's avatar
Maxime Perrotin committed
193
@expression.register(ogAST.ExprIn)
Maxime Perrotin's avatar
Maxime Perrotin committed
194
195
196
197
198
def _expr_in(expr):
    ''' IN expressions: check if item is in a SEQUENCE OF '''
    pass


Maxime Perrotin's avatar
Maxime Perrotin committed
199
@expression.register(ogAST.PrimEnumeratedValue)
Maxime Perrotin's avatar
Maxime Perrotin committed
200
201
202
203
204
def _enumerated_value(primary):
    ''' Generate code for an enumerated value '''
    pass


Maxime Perrotin's avatar
Maxime Perrotin committed
205
@expression.register(ogAST.PrimChoiceDeterminant)
Maxime Perrotin's avatar
Maxime Perrotin committed
206
207
208
209
210
def _choice_determinant(primary):
    ''' Generate code for a choice determinant (enumerated) '''
    pass


Maxime Perrotin's avatar
Maxime Perrotin committed
211
212
213
@expression.register(ogAST.PrimInteger)
@expression.register(ogAST.PrimReal)
@expression.register(ogAST.PrimBoolean)
Maxime Perrotin's avatar
Maxime Perrotin committed
214
215
216
217
218
def _integer(primary):
    ''' Generate code for a raw integer/real/boolean value  '''
    pass


Maxime Perrotin's avatar
Maxime Perrotin committed
219
@expression.register(ogAST.PrimEmptyString)
Maxime Perrotin's avatar
Maxime Perrotin committed
220
221
222
223
224
def _empty_string(primary):
    ''' Generate code for an empty SEQUENCE OF: {} '''
    pass


Maxime Perrotin's avatar
Maxime Perrotin committed
225
@expression.register(ogAST.PrimStringLiteral)
Maxime Perrotin's avatar
Maxime Perrotin committed
226
227
228
229
230
def _string_literal(primary):
    ''' Generate code for a string (Octet String) '''
    pass


Maxime Perrotin's avatar
Maxime Perrotin committed
231
@expression.register(ogAST.PrimConstant)
Maxime Perrotin's avatar
Maxime Perrotin committed
232
233
234
235
236
def _constant(primary):
    ''' Generate code for a reference to an ASN.1 constant '''
    pass


Maxime Perrotin's avatar
Maxime Perrotin committed
237
@expression.register(ogAST.PrimMantissaBaseExp)
Maxime Perrotin's avatar
Maxime Perrotin committed
238
239
240
241
242
def _mantissa_base_exp(primary):
    ''' Generate code for a Real with Mantissa-base-Exponent representation '''
    pass


Maxime Perrotin's avatar
Maxime Perrotin committed
243
@expression.register(ogAST.PrimIfThenElse)
Maxime Perrotin's avatar
Maxime Perrotin committed
244
245
246
247
248
def _if_then_else(ifThenElse):
    ''' Return string and statements for ternary operator '''
    pass


Maxime Perrotin's avatar
Maxime Perrotin committed
249
@expression.register(ogAST.PrimSequence)
Maxime Perrotin's avatar
Maxime Perrotin committed
250
def _sequence(seq):
Maxime Perrotin's avatar
Maxime Perrotin committed
251
    ''' Return string for an ASN.1 SEQUENCE '''
Maxime Perrotin's avatar
Maxime Perrotin committed
252
253
254
    pass


Maxime Perrotin's avatar
Maxime Perrotin committed
255
@expression.register(ogAST.PrimSequenceOf)
Maxime Perrotin's avatar
Maxime Perrotin committed
256
def _sequence_of(seqof):
Maxime Perrotin's avatar
Maxime Perrotin committed
257
    ''' Return string for an ASN.1 SEQUENCE OF '''
Maxime Perrotin's avatar
Maxime Perrotin committed
258
259
260
    pass


Maxime Perrotin's avatar
Maxime Perrotin committed
261
@expression.register(ogAST.PrimChoiceItem)
Maxime Perrotin's avatar
Maxime Perrotin committed
262
def _choiceitem(choice):
Maxime Perrotin's avatar
Maxime Perrotin committed
263
    ''' Return the code for a CHOICE expression '''
Maxime Perrotin's avatar
Maxime Perrotin committed
264
265
266
    pass