Commit 5bb148ab authored by dbarbera's avatar dbarbera
Browse files

Add support for ASN.1 constants

parent b0421901
......@@ -39,6 +39,7 @@ class Context():
self.module = lc.Module.new(self.name)
self.target_data = le.TargetData.new(self.module.data_layout)
self.dataview = process.dataview
self.procedures = process.procedures
self.scope = Scope(self)
......@@ -350,10 +351,10 @@ class Scope:
self.parent = parent
def define(self, name, var):
self.vars[name.lower()] = var
self.vars[name.lower().replace('-', '_')] = var
def resolve(self, name):
var = self.vars.get(name.lower())
var = self.vars.get(name.lower().replace('-', '_'))
if var:
return var
if self.parent:
......@@ -411,6 +412,12 @@ def _process(process, ctx=None):
state_cons.initializer = lc.Constant.int(ctx.i32, -1)
ctx.scope.define('.state', state_cons)
# Generate ASN.1 constants
for name, t in process.dv.variables.viewitems():
var_llty = ctx.lltype_of(t.type)
global_var = ctx.module.add_global_variable(var_llty, str(name))
ctx.scope.define(str(name).lower(), global_var)
# Generare process-level vars
for name, (asn1ty, expr) in process.variables.viewitems():
var_llty = ctx.lltype_of(asn1ty)
......@@ -1460,7 +1467,8 @@ def _prim_string_literal(prim, ctx):
@expression.register(ogAST.PrimConstant)
def _prim_constant(prim, ctx):
''' Generate the IR for a reference to an ASN.1 constant '''
raise NotImplementedError
var_ptr = ctx.global_scope.resolve(prim.value[0])
return var_ptr if is_struct_ptr(var_ptr) else ctx.builder.load(var_ptr)
@expression.register(ogAST.PrimMantissaBaseExp)
......
......@@ -400,21 +400,6 @@ def find_basic_type(a_type):
return basic_type
def is_constant(var):
''' Check in ASN.1 modules if var (Primary) is declared as a constant '''
if var is None:
return False
if isinstance(var, ogAST.PrimConstant):
return True
if DV and isinstance(var, ogAST.PrimVariable):
for mod in DV.asn1Modules:
for constant in DV.exportedVariables[mod]:
if(constant.lower() == var.value[0].lower().replace('_', '-')):
LOG.debug('Constant ' + var.inputString + ' found')
return True
return False
def signature(name, context):
''' Return the signature of a procecure/output/operator '''
name = name.lower()
......@@ -605,9 +590,7 @@ def check_type_compatibility(primary, type_ref, context):
assert type_ref is not None
if type_ref is UNKNOWN_TYPE:
raise TypeError('Type reference is unknown')
if isinstance(primary, ogAST.PrimConstant):
# ASN.1 constants type is unknown (Asn1 backend to be completed)
return
basic_type = find_basic_type(type_ref)
LOG.debug("[check_type_compatibility] "
"checking if {value} is of type {typeref}"
......@@ -817,12 +800,14 @@ def compare_types(type_a, type_b):
))
def find_variable(var, context):
def find_variable_type(var, context):
''' Look for a variable name in the context and return its type '''
LOG.debug('[find_variable] checking if ' + str(var) + ' is defined')
# all DCL-variables
all_visible_variables = dict(context.global_variables)
all_visible_variables.update(context.variables)
# First check locally, i.e. in FPAR
try:
for variable in context.fpar:
......@@ -844,6 +829,12 @@ def find_variable(var, context):
LOG.debug(str(var) + ' is defined')
return TIMER
# check if is a ASN.1 constant
for varname, vartype in DV.variables.viewitems():
if var.lower() == varname.lower().replace('-', '_'):
LOG.debug(str(var) + ' is defined')
return vartype.type
LOG.debug('[find_variable] result: not found, raising exception')
raise AttributeError('Variable {var} not defined'.format(var=var))
......@@ -887,13 +878,6 @@ def fix_expression_types(expr, context):
# except (UnboundLocalError, AttributeError, TypeError):
# pass
# If a side type remains unknown, check if it is an ASN.1 constant
for side in permutations(('left', 'right')):
value = getattr(expr, side[0])
if value.exprType == UNKNOWN_TYPE and is_constant(value):
setattr(expr, side[0], ogAST.PrimConstant(primary=value))
getattr(expr, side[0]).exprType = getattr(expr, side[1]).exprType
for side in (expr.right, expr.left):
if side.is_raw:
raw_expr = side
......@@ -1010,30 +994,46 @@ def expression_list(root, context):
def primary_variable(root, context):
''' Primary Variable analysis '''
lexeme = root.children[0].text
name = root.children[0].text
errors, warnings = [], []
# Differentiate DCL and FPAR variables
Prim = ogAST.PrimVariable
if isinstance(context, ogAST.Procedure):
for each in context.fpar:
if each['name'].lower() == lexeme.lower():
Prim = ogAST.PrimFPAR
break
if is_asn1constant(name):
prim = ogAST.PrimConstant()
elif is_fpar(name, context):
prim = ogAST.PrimFPAR()
else:
prim = ogAST.PrimVariable()
prim, errors, warnings = Prim(), [], []
prim.value = [root.children[0].text]
prim.value = [name]
prim.exprType = UNKNOWN_TYPE
prim.inputString = get_input_string(root)
prim.tmpVar = tmp()
try:
prim.exprType = find_variable(lexeme, context)
prim.exprType = find_variable_type(name, context)
except AttributeError:
pass
return prim, errors, warnings
def is_fpar(name, context):
name = name.lower()
if isinstance(context, ogAST.Procedure):
for each in context.fpar:
if each['name'].lower() == name:
return True
return False
def is_asn1constant(name):
name = name.lower().replace('-', '_')
for varname, vartype in DV.variables.viewitems():
if varname.lower().replace('-', '_') == name:
return True
return False
def binary_expression(root, context):
''' Binary expression analysis '''
errors, warnings = [], []
......@@ -1716,7 +1716,8 @@ def variables(root, ta_ast, context):
else:
def_value.exprType = asn1_sort
if not def_value.is_raw and not is_constant(def_value):
if not def_value.is_raw and \
not isinstance(def_value, ogAST.PrimConstant):
errors.append('In variable declaration {}: default'
' value is not a valid ground expression'.
format(var[-1]))
......@@ -2562,7 +2563,7 @@ def input_part(root, parent, context):
len(inputparams[0]) == 1:
user_param, = inputparams[0]
try:
user_param_type = find_variable(user_param.text, context)
user_param_type = find_variable_type(user_param.text, context)
try:
compare_types(sig_param_type, user_param_type)
except TypeError as err:
......@@ -3817,6 +3818,7 @@ def pr_file(root):
ast.processes.append(process)
process.dataview = types()
process.asn1Modules = ast.asn1Modules
process.dv = DV
errors.extend(err)
warnings.extend(warn)
LOG.debug('all files: ' + str(ast.pr_files))
......
......@@ -17,4 +17,6 @@ Choice ::= CHOICE {
f Real
}
pi Real ::= 3.14159265359
END
......@@ -25,7 +25,7 @@ DCL c Choice := i:2;
/* CIF PROCEDURECALL (-22, 324), (293, 35) */
CALL assert(ceil(f + 0.5) = 3.0, 'ceil(f + 0.5) = 3.0');
/* CIF PROCEDURECALL (-90, 374), (429, 35) */
CALL assert(round(cos(3.141632)) = -1.0, 'round(cos(3.141632)) = -1.0');
CALL assert(round(cos(pi)) = -1.0, 'round(cos(pi)) = -1.0');
/* CIF PROCEDURECALL (12, 424), (224, 35) */
CALL assert(fix(f) = i, 'fix(f) = i');
/* CIF PROCEDURECALL (-1, 474), (251, 35) */
......@@ -41,7 +41,7 @@ DCL c Choice := i:2;
/* CIF PROCEDURECALL (-14, 724), (276, 35) */
CALL assert(power(i, 3) = 8, 'power(i, 3) = 8');
/* CIF PROCEDURECALL (-90, 774), (429, 35) */
CALL assert(round(sin(3.141632)) = 0.0, 'round(sin(3.141632)) = 0.0');
CALL assert(round(sin(pi)) = 0.0, 'round(sin(pi)) = 0.0');
/* CIF PROCEDURECALL (-15, 824), (278, 35) */
CALL assert(sqrt(16.0) = 4.0, 'sqrt(16.0) = 4.0');
/* CIF PROCEDURECALL (-26, 874), (301, 35) */
......
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