Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
TASTE
OpenGEODE
Commits
418479ad
Commit
418479ad
authored
Feb 06, 2018
by
Maxime Perrotin
Browse files
Fix operator ranges, and more signed/unsigned
parent
07c5971b
Changes
2
Hide whitespace changes
Inline
Side-by-side
opengeode/AdaGenerator.py
View file @
418479ad
...
...
@@ -1750,7 +1750,8 @@ def _basic_operators(expr):
right_stmts
,
right_str
,
right_local
=
expression
(
expr
.
right
)
##
#print expr.inputString, " ==> ", left_str, ' and ', right_str,
if
isinstance
(
expr
,
ogAST
.
ExprMod
):
bt
=
find_basic_type
(
expr
.
exprType
)
right_is_numeric
,
left_is_numeric
=
True
,
True
try
:
...
...
@@ -1878,7 +1879,16 @@ def _assign_expression(expr):
# Make sure that integers are cast to 64 bits
# No, casting to int64 isn't right if the type is unsigned (asn1scc v4)
# strings.append(u"{} := AsN1Int({});".format(left_str, right_str))
strings
.
append
(
u
"{} := {};"
.
format
(
left_str
,
right_str
))
# It is possible that left and right are of different types
# (signed vs unsigned). The parser should have ensured that the
# ranges are compatible. So we can safely cast to the left type
# when right side is of different type.
basic_right
=
find_basic_type
(
expr
.
right
.
exprType
)
if
float
(
basic_right
.
Min
)
>=
0
and
float
(
basic_left
.
Min
)
<
0
:
res
=
"Asn1Int({})"
.
format
(
right_str
)
else
:
res
=
right_str
strings
.
append
(
u
"{} := {};"
.
format
(
left_str
,
res
))
else
:
strings
.
append
(
u
"{} := {};"
.
format
(
left_str
,
right_str
))
code
.
extend
(
left_stmts
)
...
...
opengeode/ogParser.py
View file @
418479ad
...
...
@@ -29,6 +29,7 @@ __author__ = 'Maxime Perrotin'
import
sys
import
os
import
math
import
operator
import
logging
import
traceback
import
binascii
...
...
@@ -1318,12 +1319,23 @@ def logic_expression(root, context):
def
arithmetic_expression
(
root
,
context
):
''' Arithmetic expression analysis '''
def
find_bounds
(
operator
,
minL
,
maxL
,
minR
,
maxR
):
candidates
=
[
operator
(
float
(
l
),
float
(
r
))
for
l
in
[
minL
,
maxL
]
for
r
in
[
minR
,
maxR
]]
return
{
'Min'
:
str
(
min
(
candidates
)),
'Max'
:
str
(
max
(
candidates
))}
expr
,
errors
,
warnings
=
binary_expression
(
root
,
context
)
# Expressions returning a numerical type must have their range defined
# accordingly with the kind of opration used between operand:
# accordingly with the kind of op
e
ration used between operand
s
:
left
=
find_basic_type
(
expr
.
left
.
exprType
)
right
=
find_basic_type
(
expr
.
right
.
exprType
)
minL
=
float
(
left
.
Min
)
maxL
=
float
(
left
.
Max
)
minR
=
float
(
right
.
Min
)
maxR
=
float
(
right
.
Max
)
# Type of the resulting expression depends on whether there are raw numbers
# on one side of the expression (PrInt). By default when they are parsed,
# they are set to 64 bits integers ; but if they are in an expression where
...
...
@@ -1332,23 +1344,22 @@ def arithmetic_expression(root, context):
basic
=
right
if
left
.
__name__
==
'PrInt'
else
left
try
:
if
isinstance
(
expr
,
ogAST
.
ExprPlus
):
attrs
=
{
'Min'
:
str
(
float
(
left
.
M
in
)
+
float
(
right
.
M
in
)
),
'Max'
:
str
(
float
(
left
.
M
ax
)
+
float
(
right
.
M
ax
)
)}
attrs
=
{
'Min'
:
str
(
m
in
L
+
m
in
R
),
'Max'
:
str
(
m
ax
L
+
m
ax
R
)}
expr
.
exprType
=
type
(
'Plus'
,
(
basic
,),
attrs
)
elif
isinstance
(
expr
,
ogAST
.
ExprMul
):
attrs
=
{
'Min'
:
str
(
float
(
left
.
Min
)
*
float
(
right
.
Min
)),
'Max'
:
str
(
float
(
left
.
Max
)
*
float
(
right
.
Max
))}
attrs
=
find_bounds
(
operator
.
mul
,
minL
,
maxL
,
minR
,
maxR
)
expr
.
exprType
=
type
(
'Mul'
,
(
basic
,),
attrs
)
elif
isinstance
(
expr
,
ogAST
.
ExprMinus
):
attrs
=
{
'Min'
:
str
(
float
(
left
.
M
in
)
-
float
(
right
.
M
ax
)
),
'Max'
:
str
(
float
(
left
.
M
ax
)
-
float
(
right
.
M
in
)
)}
attrs
=
{
'Min'
:
str
(
m
in
L
-
m
ax
R
),
'Max'
:
str
(
m
ax
L
-
m
in
R
)}
expr
.
exprType
=
type
(
'Minus'
,
(
basic
,),
attrs
)
elif
isinstance
(
expr
,
ogAST
.
ExprDiv
):
attrs
=
{
'Min'
:
str
(
float
(
left
.
Min
)
/
(
float
(
right
.
Max
)
or
1
))
,
'Max'
:
str
(
float
(
left
.
Max
)
/
(
float
(
right
.
Min
)
or
1
)
)}
attrs
=
find_bounds
(
operator
.
truediv
,
minL
,
maxL
,
minR
or
1
,
maxR
or
1
)
expr
.
exprType
=
type
(
'Div'
,
(
basic
,),
attrs
)
elif
isinstance
(
expr
,
(
ogAST
.
ExprMod
,
ogAST
.
ExprRem
)):
attrs
=
{
'Min'
:
right
.
Min
,
'Max'
:
right
.
Max
}
attrs
=
{
'Min'
:
'0'
,
'Max'
:
right
.
Max
}
expr
.
exprType
=
type
(
'Mod'
,
(
basic
,),
attrs
)
except
(
ValueError
,
AttributeError
):
msg
=
'Check that all your numerical data types '
\
...
...
@@ -4150,6 +4161,7 @@ def assign(root, context):
if
not
errors
:
if
expr
.
right
.
exprType
==
UNKNOWN_TYPE
or
not
\
isinstance
(
expr
.
right
,
(
ogAST
.
ExprAppend
,
ogAST
.
ExprMod
,
ogAST
.
PrimSequenceOf
,
ogAST
.
PrimStringLiteral
)):
expr
.
right
.
exprType
=
expr
.
left
.
exprType
...
...
@@ -4164,7 +4176,6 @@ def assign(root, context):
# Set the expected type on the right, this is needed to know
# if the expected size is variable or fixed in backends
expr
.
right
.
expected_type
=
expr
.
left
.
exprType
return
expr
,
errors
,
warnings
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment