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