Commit 8d058a8b authored by Maxime Perrotin's avatar Maxime Perrotin
Browse files

Merge branch 'master' of https://github.com/maxime-esa/opengeode

parents f98201dc 61bf8b40
#!/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.
There is a single function called "generate", decorated with the
singledispatch mechanism, that needs to be called to generate the code
of any AST element.
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
LOG = logging.getLogger(__name__)
__all__ = ['generate']
@singledispatch
def generate(ast):
''' Generate the code for an item of the AST '''
raise TypeError('[Backend] Unsupported AST construct')
# Processing of the AST
@generate.register(ogAST.Process)
def _process(process):
''' Generate the code for a complete process (AST Top level) '''
pass
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
@generate.register(ogAST.PrimVariable)
def _primary_variable(prim):
''' Single variable reference '''
pass
@generate.register(ogAST.PrimPath)
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
@generate.register(ogAST.ExprPlus)
@generate.register(ogAST.ExprMul)
@generate.register(ogAST.ExprMinus)
@generate.register(ogAST.ExprEq)
@generate.register(ogAST.ExprNeq)
@generate.register(ogAST.ExprGt)
@generate.register(ogAST.ExprGe)
@generate.register(ogAST.ExprLt)
@generate.register(ogAST.ExprLe)
@generate.register(ogAST.ExprDiv)
@generate.register(ogAST.ExprMod)
@generate.register(ogAST.ExprRem)
@generate.register(ogAST.ExprAssign)
def _basic_operators(expr):
''' Expressions with two sides '''
pass
@generate.register(ogAST.ExprOr)
@generate.register(ogAST.ExprAnd)
@generate.register(ogAST.ExprXor)
def _bitwise_operators(expr):
''' Logical operators '''
pass
@generate.register(ogAST.ExprAppend)
def _append(expr):
''' Generate code for the APPEND construct: a // b '''
pass
@generate.register(ogAST.ExprIn)
def _expr_in(expr):
''' IN expressions: check if item is in a SEQUENCE OF '''
pass
@generate.register(ogAST.PrimEnumeratedValue)
def _enumerated_value(primary):
''' Generate code for an enumerated value '''
pass
@generate.register(ogAST.PrimChoiceDeterminant)
def _choice_determinant(primary):
''' Generate code for a choice determinant (enumerated) '''
pass
@generate.register(ogAST.PrimInteger)
@generate.register(ogAST.PrimReal)
@generate.register(ogAST.PrimBoolean)
def _integer(primary):
''' Generate code for a raw integer/real/boolean value '''
pass
@generate.register(ogAST.PrimEmptyString)
def _empty_string(primary):
''' Generate code for an empty SEQUENCE OF: {} '''
pass
@generate.register(ogAST.PrimStringLiteral)
def _string_literal(primary):
''' Generate code for a string (Octet String) '''
pass
@generate.register(ogAST.PrimConstant)
def _constant(primary):
''' Generate code for a reference to an ASN.1 constant '''
pass
@generate.register(ogAST.PrimMantissaBaseExp)
def _mantissa_base_exp(primary):
''' Generate code for a Real with Mantissa-base-Exponent representation '''
pass
@generate.register(ogAST.PrimIfThenElse)
def _if_then_else(ifThenElse):
''' Return string and statements for ternary operator '''
pass
@generate.register(ogAST.PrimSequence)
def _sequence(seq):
''' Return Ada string for an ASN.1 SEQUENCE '''
pass
@generate.register(ogAST.PrimSequenceOf)
def _sequence_of(seqof):
''' Return Ada string for an ASN.1 SEQUENCE OF '''
pass
@generate.register(ogAST.PrimChoiceItem)
def _choiceitem(choice):
''' Return the Ada code for a CHOICE expression '''
pass
@generate.register(ogAST.Decision)
def _decision(dec):
''' generate the code for a decision '''
pass
@generate.register(ogAST.Label)
def _label(tr):
''' Transition following labels are generated in a separate section
for visibility reasons (see Ada scope)
'''
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 (Ada label + transition) '''
pass
@generate.register(ogAST.Procedure)
def _inner_procedure(proc):
''' Generate the code for a procedure '''
pass
......@@ -693,8 +693,8 @@ actual_parameters
task
: cif?
hyperlink?
TASK task_body end
-> ^(TASK cif? hyperlink? end? task_body);
TASK task_body? end
-> ^(TASK cif? hyperlink? end? task_body?);
task_body
......
#!/usr/bin/env python
# ASN.1 Data model
asn1Files = []
asn1Modules = []
exportedTypes = {}
exportedVariables = {}
importedModules = {}
types = {}
asn1Files.append("./dataview-uniq.asn")
asn1Modules.append("TASTE-Dataview")
exportedTypes["TASTE-Dataview"] = ["Some-Thing", "MyInteger", "My-OctStr", "SeqOf"]
exportedVariables["TASTE-Dataview"] = ["default-seqof", "default-str"]
importedModules["TASTE-Dataview"] = []
types["Some-Thing"] = type("Some-Thing", (object,), {
"Line": 6, "CharPositionInLine": 0, "type": type("Some-Thing_type", (object,), {
"Line": 6, "CharPositionInLine": 15, "kind": "ReferenceType", "ReferencedTypeName": "MyInteger", "Min": "0", "Max": "255"
})
})
types["MyInteger"] = type("MyInteger", (object,), {
"Line": 8, "CharPositionInLine": 0, "type": type("MyInteger_type", (object,), {
"Line": 8, "CharPositionInLine": 16, "kind": "IntegerType", "Min": "0", "Max": "255"
})
})
types["My-OctStr"] = type("My-OctStr", (object,), {
"Line": 10, "CharPositionInLine": 0, "type": type("My-OctStr_type", (object,), {
"Line": 10, "CharPositionInLine": 17, "kind": "OctetStringType", "Min": "0", "Max": "20"
})
})
types["SeqOf"] = type("SeqOf", (object,), {
"Line": 12, "CharPositionInLine": 0, "type": type("SeqOf_type", (object,), {
"Line": 12, "CharPositionInLine": 10, "kind": "SequenceOfType", "Min": "0", "Max": "100", "type": type("SeqOf_type", (object,), {
"Line": 12, "CharPositionInLine": 37, "kind": "ReferenceType", "ReferencedTypeName": "MyInteger", "Min": "0", "Max": "255"
})
})
})
all: compile
generate-code:
../../../opengeode.py --toAda og.pr system_structure.pr
compile: generate-code
asn1.exe -Ada dataview-uniq.asn -typePrefix asn1Scc -equal
gnatmake -c *.adb
gcc -c test.c
gcc -o test test.o og.o taste_dataview.o -lgnat
./test > result
diff result expected && echo 'All OK!'
parse:
../../../opengeode.py og.pr system_structure.pr --check
coverage:
coverage run -p ../../../opengeode.py og.pr system_structure.pr --toAda
clean:
rm -rf result *.adb *.ads *.pyc runSpark.sh spark.idx *.o *.ali gnat.cfg examiner bin *.wrn *.gpr
TASTE-Dataview DEFINITIONS ::=
BEGIN
Some-Thing ::= MyInteger
MyInteger ::= INTEGER (0..255)
My-OctStr ::= OCTET STRING (SIZE (0..20))
SeqOf ::= SEQUENCE (SIZE(0..100)) OF MyInteger
default-seqof SeqOf ::= {4,7,9}
default-str My-OctStr ::= 'DEADBEEF'H
END
[C Code] Running test
1
2
3
4
5
6
end of test
PROCESS og;
/* CIF TEXT (0, 0), (229, 98) */
-- Testing decisions
dcl test myInteger := 3;
/* CIF ENDTEXT */
/* CIF START (482, 35), (70, 35) */
START;
/* CIF LABEL (474, 85), (85, 35) */
again:
/* CIF DECISION (482, 135), (70, 50) */
DECISION test;
/* CIF ANSWER (85, 205), (70, 23) */
(3):
/* CIF PROCEDURECALL (67, 243), (106, 35) */
CALL writeln('1');
/* CIF TASK (77, 293), (87, 35) */
TASK test := 5;
/* CIF JOIN (103, 343), (35, 35) */
JOIN again;
/* CIF ANSWER (582, 205), (70, 23) */
(>5):
/* CIF PROCEDURECALL (561, 243), (113, 35) */
CALL writeln('4');
/* CIF TASK (574, 293), (87, 35) */
TASK test := 7;
/* CIF LABEL (568, 343), (98, 35) */
and_again:
/* CIF DECISION (582, 393), (70, 50) */
DECISION test;
/* CIF ANSWER (681, 463), (70, 23) */
(<=5):
/* CIF DECISION (681, 501), (70, 50) */
DECISION test;
/* CIF ANSWER (576, 571), (70, 23) */
(>=5):
/* CIF PROCEDURECALL (545, 609), (132, 35) */
CALL writeln('6');
/* CIF ANSWER (746, 571), (70, 23) */
else:
/* CIF PROCEDURECALL (707, 609), (148, 35) */
CALL writeln('[ERROR]');
ENDDECISION;
/* CIF ANSWER (444, 463), (70, 23) */
(/=5):
/* CIF PROCEDURECALL (422, 501), (113, 35) */
CALL writeln('5');
/* CIF TASK (435, 551), (87, 35) */
TASK test := 5;
/* CIF JOIN (461, 601), (35, 35) */
JOIN and_again;
ENDDECISION;
/* CIF ANSWER (321, 205), (70, 23) */
(<5):
/* CIF PROCEDURECALL (299, 243), (113, 35) */
CALL writeln('3');
/* CIF TASK (309, 293), (94, 35) */
TASK test := 6;
/* CIF JOIN (338, 343), (35, 35) */
JOIN again;
/* CIF ANSWER (201, 205), (70, 23) */
(=5):
/* CIF PROCEDURECALL (183, 243), (106, 35) */
CALL writeln('2');
/* CIF TASK (189, 293), (94, 35) */
TASK test := 4;
/* CIF JOIN (219, 343), (35, 35) */
JOIN again;
/* CIF ANSWER (904, 205), (70, 23) */
else:
/* CIF PROCEDURECALL (865, 243), (148, 35) */
CALL writeln('[ERROR]');
ENDDECISION;
/* CIF PROCEDURECALL (433, 689), (167, 35) */
CALL writeln('end of test');
/* CIF NEXTSTATE (472, 739), (90, 35) */
NEXTSTATE all_done;
/* CIF STATE (1078, 167), (90, 35) */
STATE all_done;
ENDSTATE;
ENDPROCESS og;
\ No newline at end of file
/* CIF Keep Specific Geode ASNFilename 'dataview-uniq.asn' */
USE Datamodel;
SYSTEM og;
/* CIF Keep Specific Geode PARAMNAMES ze_param */
SIGNAL go (My_OctStr);
/* CIF Keep Specific Geode PARAMNAMES ze_rezult */
SIGNAL rezult (My_OctStr);
CHANNEL c
FROM ENV TO og WITH go;
FROM og TO ENV WITH rezult;
ENDCHANNEL;
BLOCK og;
SIGNALROUTE r
FROM ENV TO og WITH go;
FROM og TO ENV WITH rezult;
CONNECT c and r;
PROCESS og REFERENCED;
ENDBLOCK;
ENDSYSTEM;
\ No newline at end of file
#include <math.h>
#include <stdio.h>
/* Ada code external interface */
extern void og_start();
int main()
{
printf("[C Code] Running test\n");
og_start();
return 0;
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment