Commit b3878576 authored by Maxime Perrotin's avatar Maxime Perrotin
Browse files

Added support for bitwise operations

parent c2762c46
......@@ -638,13 +638,14 @@ def _task_forloop(task):
@generate.register(ogAST.PrimVariable)
def _primary_variable(prim):
''' Single variable reference '''
return [], 'l_{}'.format(prim.value[0]), []
sep = 'l_' if find_var(prim.value[0]) else ''
return [], '{sep}{name}'.format(sep=sep, name=prim.value[0]), []
@generate.register(ogAST.PrimPath)
def _prim_path(primaryId):
'''
Return the Ada string of a PrimaryId element list (path)
Return the Ada 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)
......@@ -718,7 +719,7 @@ def _prim_path(primaryId):
if unicode.isnumeric(idx_string):
idx_string = int(idx_string) + 1
else:
idx_string = '1+({idx})'.format(idx=idx_string)
idx_string = '1+Integer({idx})'.format(idx=idx_string)
ada_string += '.Data({idx})'.format(idx=idx_string)
stmts.extend(idx_stmts)
local_decl.extend(local_var)
......@@ -796,9 +797,6 @@ def _prim_path(primaryId):
@generate.register(ogAST.ExprPlus)
@generate.register(ogAST.ExprMul)
@generate.register(ogAST.ExprMinus)
@generate.register(ogAST.ExprOr)
@generate.register(ogAST.ExprAnd)
@generate.register(ogAST.ExprXor)
@generate.register(ogAST.ExprEq)
@generate.register(ogAST.ExprNeq)
@generate.register(ogAST.ExprGt)
......@@ -810,6 +808,7 @@ def _prim_path(primaryId):
@generate.register(ogAST.ExprRem)
@generate.register(ogAST.ExprAssign)
def _basic_operators(expr):
''' Expressions with two sides '''
code, local_decl = [], []
left_stmts, left_str, left_local = generate(expr.left)
right_stmts, right_str, right_local = generate(expr.right)
......@@ -821,6 +820,41 @@ def _basic_operators(expr):
local_decl.extend(right_local)
return code, ada_string, local_decl
@generate.register(ogAST.ExprOr)
@generate.register(ogAST.ExprAnd)
@generate.register(ogAST.ExprXor)
def _bitwise_operators(expr):
''' Logical operators '''
code, local_decl = [], []
left_stmts, left_str, left_local = generate(expr.left)
right_stmts, right_str, right_local = generate(expr.right)
basic_type = find_basic_type(expr.exprType)
if basic_type.kind != 'BooleanType':
# Sequence of boolean or bit string
if expr.right.is_raw:
# Declare a temporary variable to store the raw value
tmp_string = 'tmp{}'.format(expr.right.tmpVar)
local_decl.append('{tmp} : aliased asn1Scc{eType};'.format(
tmp=tmp_string,
eType=expr.right.exprType.ReferencedTypeName
.replace('-', '_')))
code.append('{tmp} := {right};'.format(tmp=tmp_string,
right=right_str))
right_str = tmp_string
ada_string = '(Data => ({left}.Data {op} {right}.Data)'.format(
left=left_str, op=expr.operand, right=right_str)
if basic_type.Min != basic_type.Max:
ada_string += ", Length => {left}.Length".format(left=left_str)
ada_string += ')'
else:
ada_string = '({left} {op} {right})'.format(
left=left_str, op=expr.operand, right=right_str)
code.extend(left_stmts)
code.extend(right_stmts)
local_decl.extend(left_local)
local_decl.extend(right_local)
return code, ada_string, local_decl
@generate.register(ogAST.ExprAppend)
def _append(expr):
......
......@@ -1001,16 +1001,12 @@ def expression(root, context):
expr.right.inputString + ', type= ' +
type_name(expr.right.exprType) + ') ' + str(err))
if root.type in (lexer.AND,
lexer.EQ,
if root.type in (lexer.EQ,
lexer.NEQ,
lexer.GT,
lexer.GE,
lexer.LT,
lexer.LE,
lexer.OR,
lexer.XOR,
lexer.AND,
lexer.IN):
expr.exprType = BOOLEAN
# elif root.type == lexer.PLUS:
......@@ -1021,6 +1017,16 @@ def expression(root, context):
# (find_basic_type(expr.left.exprType),), {})
# expr.exprType.Max = str(int(find_basic_type(expr.left.exprType).Max) +
# int(find_basic_type(expr.right.exprType).Max))
elif root.type in (lexer.OR, lexer.AND, lexer.XOR):
# in the case of bitwise operators, if both sides are arrays,
# then the result is an array too
basic_left = find_basic_type(expr.left.exprType)
basic_right = find_basic_type(expr.right.exprType)
if basic_left.kind == basic_right.kind == 'BooleanType':
expr.exprType = BOOLEAN
else:
expr.exprType = expr.left.exprType
elif root.type in (lexer.PLUS,
lexer.ASTERISK,
lexer.DASH,
......@@ -1839,23 +1845,21 @@ def outputbody(root, context):
elif child.type == lexer.PARAMS:
body['params'], err, warn = expression_list(
child, context)
# here we must check/set the type of each param
try:
check_and_fix_op_params(
body.get('outputName') or '',
body['params'],
context)
except (AttributeError, TypeError) as op_err:
errors.append('[output] ' + str(op_err)
+ ' - ' + get_input_string(root))
LOG.debug('[outputbody] call check_and_fix_op_params : '
+ get_input_string(root) + str(op_err))
LOG.debug(str(traceback.format_exc()))
errors.extend(err)
warnings.extend(warn)
else:
warnings.append('Unsupported output body type:' +
str(child.type))
# Check/set the type of each param
try:
check_and_fix_op_params(body.get('outputName', ''),
body.get('params', []),
context)
except (AttributeError, TypeError) as op_err:
errors.append(str(op_err) + ' - ' + get_input_string(root))
LOG.debug('[outputbody] call check_and_fix_op_params : '
+ get_input_string(root) + str(op_err))
LOG.debug(str(traceback.format_exc()))
if body.get('params'):
body['tmpVars'] = []
global TMPVAR
......@@ -2286,7 +2290,6 @@ def fix_expression_types(expr, context):
fix_expression_types(check_expr, context)
expr.right.value[det] = check_expr.right
elif isinstance(expr.right, ogAST.PrimSequenceOf):
# tired, check this XXX
asn_type = find_basic_type(expr.left.exprType).type
for idx, elem in enumerate(expr.right.value):
check_expr = ogAST.ExprAssign()
......@@ -2295,7 +2298,21 @@ def fix_expression_types(expr, context):
check_expr.right = elem
fix_expression_types(check_expr, context)
expr.right.value[idx] = check_expr.right
# the type of the raw PrimSequenceOf can be set now
expr.right.exprType.type = asn_type
if isinstance(expr, (ogAST.ExprAnd, ogAST.ExprOr, ogAST.ExprXor)):
# Bitwise operators: check that both sides are booleans
for side in expr.left, expr.right:
basic_type = find_basic_type(side.exprType)
if basic_type.kind in ('BooleanType', 'BitStringType'):
continue
elif basic_type.kind == 'SequenceOfType':
if find_basic_type(side.exprType).type.kind == 'BooleanType':
continue
else:
raise TypeError('Bitwise operators only work with '
'booleans and arrays of booleans')
if expr.right.is_raw != expr.left.is_raw:
check_type_compatibility(raw_expr, ref_type, context)
raw_expr.exprType = ref_type
......
......@@ -243,7 +243,7 @@ class Sdl_toolbar(QtGui.QToolBar, object):
selection, = selection
for action in self.actions.viewkeys():
self.actions[action].setEnabled(False)
for action in selection.allowed_followers:
for action in getattr(selection, 'allowed_followers', []):
try:
self.actions[action].setEnabled(True)
except KeyError:
......
EXAMPLES=test1 test2 test3 test4 test5 test6 test7 test8
EXAMPLES=test1 test2 test3 test4 test5 test6 test7 test8 test9
all:
for v in $(EXAMPLES) ; do make -C $$v clean all || exit 1 ; done
......
#!/usr/bin/env python
# ASN.1 Data model
# EXPERIMENTAL VERSION
asn1Files = []
asn1Modules = []
exportedTypes = {}
exportedVariables = {}
importedModules = {}
types = {}
asn1Files.append("dataview-uniq.asn")
asn1Modules.append("TASTE-BasicTypes")
exportedTypes["TASTE-BasicTypes"] = ["T-Int32", "T-UInt32", "T-Int8", "T-UInt8", "T-Boolean", "BitString", "OctString", "SeqBit", "SeqBit2"]
exportedVariables["TASTE-BasicTypes"] = []
importedModules["TASTE-BasicTypes"] = []
types["T-Int32"] = type("T-Int32", (object,), {
"Line": 6, "CharPositionInLine": 0, "type": type("T-Int32_type", (object,), {
"Line": 6, "CharPositionInLine": 13, "kind": "IntegerType", "Min": "-2147483648", "Max": "2147483647"
})
})
types["T-UInt32"] = type("T-UInt32", (object,), {
"Line": 8, "CharPositionInLine": 0, "type": type("T-UInt32_type", (object,), {
"Line": 8, "CharPositionInLine": 13, "kind": "IntegerType", "Min": "0", "Max": "4294967295"
})
})
types["T-Int8"] = type("T-Int8", (object,), {
"Line": 10, "CharPositionInLine": 0, "type": type("T-Int8_type", (object,), {
"Line": 10, "CharPositionInLine": 11, "kind": "IntegerType", "Min": "-128", "Max": "127"
})
})
types["T-UInt8"] = type("T-UInt8", (object,), {
"Line": 12, "CharPositionInLine": 0, "type": type("T-UInt8_type", (object,), {
"Line": 12, "CharPositionInLine": 12, "kind": "IntegerType", "Min": "0", "Max": "255"
})
})
types["T-Boolean"] = type("T-Boolean", (object,), {
"Line": 14, "CharPositionInLine": 0, "type": type("T-Boolean_type", (object,), {
"Line": 14, "CharPositionInLine": 14, "kind": "BooleanType"
})
})
types["BitString"] = type("BitString", (object,), {
"Line": 16, "CharPositionInLine": 0, "type": type("BitString_type", (object,), {
"Line": 16, "CharPositionInLine": 14, "kind": "BitStringType", "Min": "32", "Max": "32"
})
})
types["OctString"] = type("OctString", (object,), {
"Line": 17, "CharPositionInLine": 0, "type": type("OctString_type", (object,), {
"Line": 17, "CharPositionInLine": 14, "kind": "OctetStringType", "Min": "4", "Max": "4"
})
})
types["SeqBit"] = type("SeqBit", (object,), {
"Line": 18, "CharPositionInLine": 0, "type": type("SeqBit_type", (object,), {
"Line": 18, "CharPositionInLine": 11, "kind": "SequenceOfType", "Min": "32", "Max": "32", "type": type("SeqOf_type", (object,), {
"Line": 18, "CharPositionInLine": 34, "kind": "BooleanType"
})
})
})
types["SeqBit2"] = type("SeqBit2", (object,), {
"Line": 19, "CharPositionInLine": 0, "type": type("SeqBit2_type", (object,), {
"Line": 19, "CharPositionInLine": 12, "kind": "SequenceOfType", "Min": "1", "Max": "32", "type": type("SeqOf_type", (object,), {
"Line": 19, "CharPositionInLine": 38, "kind": "BooleanType"
})
})
})
asn1Modules.append("TASTE-Dataview")
exportedTypes["TASTE-Dataview"] = ["CountTab", "T-Int32", "T-UInt32", "T-Int8", "T-UInt8", "T-Boolean"]
exportedVariables["TASTE-Dataview"] = ["challenge", "bound", "nb-bit", "val-max", "count-max", "exceed-nb"]
importedModules["TASTE-Dataview"] = [{"TASTE-BasicTypes":{"ImportedTypes": ["T-Int32","T-UInt32","T-Int8","T-UInt8","T-Boolean"], "ImportedVariables": []}}]
types["CountTab"] = type("CountTab", (object,), {
"Line": 36, "CharPositionInLine": 0, "type": type("CountTab_type", (object,), {
"Line": 36, "CharPositionInLine": 13, "kind": "SequenceOfType", "Min": "20", "Max": "20", "type": type("SeqOf_type", (object,), {
"Line": 36, "CharPositionInLine": 40, "kind": "ReferenceType", "ReferencedTypeName": "T-UInt32", "Min": "0", "Max": "4294967295", "ReferencedModName": "TASTE-BasicTypes"
})
})
})
all: compile
generate-code:
../../../opengeode.py --toAda challenge.pr system_structure.pr
compile: generate-code
asn1.exe -Ada dataview-uniq.asn -typePrefix asn1Scc -equal
gnatgcc -c challenge.adb && echo 'All OK!'
parse:
../../../opengeode.py challenge.pr system_structure.pr --check
coverage:
coverage run -p ../../../opengeode.py challenge.pr system_structure.pr --toAda
clean:
rm -rf *.adb *.ads *.pyc runSpark.sh spark.idx *.o *.ali gnat.cfg examiner bin *.wrn *.gpr
PROCESS challenge;
/* CIF TEXT (243, 91), (298, 113) */
dcl count, actual_count CountTab;
dcl pow_value T_UInt32 := 0;
dcl check T_UInt8;
dcl bitwise SeqBit;
dcl bitwise2 SeqBit2;
dcl boolwise t_Boolean;
/* CIF ENDTEXT */
/* CIF START (94, 14), (68, 37) */
START;
/* CIF TASK (37, 66), (182, 68) */
TASK for x in count:
count(x) := count_max
actual_count(x) := 0
endfor;
/* CIF NEXTSTATE (93, 149), (70, 35) */
NEXTSTATE Wait;
/* CIF STATE (290, 11), (65, 35) */
STATE Wait;
ENDSTATE;
/* CIF STATE (93, 149), (70, 35) */
STATE Wait;
/* CIF INPUT (93, 204), (70, 35) */
INPUT run;
/* CIF PROCEDURECALL (45, 254), (166, 35) */
CALL writeln('Computing');
/* CIF TASK (-76, 304), (409, 188) */
TASK for x in range(exceed_nb):
for n in range(nb_bit):
call pow(2, n, pow_value);
check := if val_max - x>0 and pow_value>0 then 1 else 0 fi
bitwise := bitwise and bitwise
bitwise2 := bitwise2 and {true, false}
bitwise2 := bitwise2 and bitwise2
boolwise := boolwise and boolwise
check := if (check=0) and pow_value>1 then 1 else 0 fi
count(n) := count(n) - check
endfor
endfor;
/* CIF NEXTSTATE (93, 507), (70, 35) */
NEXTSTATE wait;
ENDSTATE;
ENDPROCESS challenge;
\ No newline at end of file
TASTE-BasicTypes DEFINITIONS ::=
BEGIN
-- Set of TASTE predefined basic types
T-Int32 ::= INTEGER (-2147483648 .. 2147483647)
T-UInt32 ::= INTEGER (0 .. 4294967295)
T-Int8 ::= INTEGER (-128 .. 127)
T-UInt8 ::= INTEGER (0 .. 255)
T-Boolean ::= BOOLEAN
BitString ::= BIT STRING (SIZE(32))
OctString ::= OCTET STRING (SIZE(4))
SeqBit ::= SEQUENCE (SIZE(32)) OF BOOLEAN
SeqBit2 ::= SEQUENCE (SIZE(1..32)) OF BOOLEAN
END
TASTE-Dataview DEFINITIONS ::=
BEGIN
IMPORTS T-Int32, T-UInt32, T-Int8, T-UInt8, T-Boolean FROM TASTE-BasicTypes;
-- A few simple types to start with ASN.1
challenge T-UInt32 ::= 18
bound T-UInt32 ::= 1000000
nb-bit T-UInt32 ::= 20
val-max T-UInt32 ::= 1048575
count-max T-UInt32 ::= 524288
exceed-nb T-UInt32 ::= 48575
CountTab ::= SEQUENCE (SIZE(nb-bit)) OF T-UInt32
END
/* CIF Keep Specific Geode ASNFilename 'dataview-uniq.asn' */
USE Datamodel;
SYSTEM challenge;
PROCEDURE pow COMMENT '#c_predef';
FPAR
IN a T_UInt32,
IN b T_UInt32,
IN/OUT res T_UInt32;
EXTERNAL;
SIGNAL run;
CHANNEL c
FROM ENV TO challenge WITH run;
ENDCHANNEL;
BLOCK challenge;
SIGNALROUTE r
FROM ENV TO challenge WITH run;
CONNECT c and r;
PROCESS challenge REFERENCED;
ENDBLOCK;
ENDSYSTEM;
\ No newline at end of file
Markdown is supported
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