Commit e82dcd8a authored by dbarbera's avatar dbarbera
Browse files

Added variable size SequenceOf generation

parent 0336f49e
......@@ -523,8 +523,7 @@ def generate_for_range(loop):
def generate_for_iterable(loop):
''' Generate the code for a for x in iterable loop'''
seqof_asn1ty = find_basic_type(loop['list'].exprType)
if seqof_asn1ty.Min != seqof_asn1ty.Min:
raise NotImplementedError
is_variable_size = seqof_asn1ty.Min != seqof_asn1ty.Max
func = g.builder.basic_block.function
......@@ -542,9 +541,20 @@ def generate_for_iterable(loop):
idx_ptr = g.builder.alloca(g.i32)
g.builder.store(core.Constant.int(g.i32, 0), idx_ptr)
seqof_struct_ptr = expression(loop['list'])
array_ptr = g.builder.gep(seqof_struct_ptr, [g.zero, g.zero])
if is_variable_size:
# In variable size SequenceOfs the array values are in the second field
array_ptr = g.builder.gep(seqof_struct_ptr, [g.zero, g.one])
else:
array_ptr = g.builder.gep(seqof_struct_ptr, [g.zero, g.zero])
element_typ = array_ptr.type.pointee.element
array_len_val = core.Constant.int(g.i32, array_ptr.type.pointee.count)
if is_variable_size:
# load the current number of elements that is on the first field
end_idx = g.builder.load(g.builder.gep(seqof_struct_ptr, [g.zero, g.zero]))
else:
end_idx = core.Constant.int(g.i32, array_ptr.type.pointee.count)
var_ptr = g.builder.alloca(element_typ, None, str(loop['var']))
g.scope.define(str(loop['var']), var_ptr)
......@@ -569,7 +579,7 @@ def generate_for_iterable(loop):
g.builder.position_at_end(cond_block)
tmp_val = g.builder.add(idx_var, g.one)
g.builder.store(tmp_val, idx_ptr)
cond_val = g.builder.icmp(core.ICMP_SLT, tmp_val, array_len_val)
cond_val = g.builder.icmp(core.ICMP_SLT, tmp_val, end_idx)
g.builder.cbranch(cond_val, load_block, end_block)
g.builder.position_at_end(end_block)
......@@ -602,7 +612,14 @@ def _prim_path_reference(prim):
if type(elem) == dict:
if 'index' in elem:
idx_val = expression(elem['index'][0])
var_ptr = g.builder.gep(var_ptr, [g.zero, g.zero, idx_val])
array_ptr = g.builder.gep(var_ptr, [g.zero, g.zero])
# TODO: Refactor this
if array_ptr.type.pointee.kind != core.TYPE_VECTOR:
# If is not a vector this is a pointer to a variable size SeqOf
# The array is in the second field of the struct
var_ptr = g.builder.gep(var_ptr, [g.zero, g.one, idx_val])
else:
var_ptr = g.builder.gep(var_ptr, [g.zero, g.zero, idx_val])
else:
raise NotImplementedError
else:
......@@ -843,25 +860,34 @@ def _expr_in(expr):
end_block = func.append_basic_block('in:end')
seq_asn1_ty = find_basic_type(expr.left.exprType)
if seq_asn1_ty.Min != seq_asn1_ty.Max:
# variable size sequence
raise NotImplementedError
is_variable_size = seq_asn1_ty.Min != seq_asn1_ty.Max
idx_ptr = g.builder.alloca(g.i32)
g.builder.store(core.Constant.int(g.i32, 0), idx_ptr)
# TODO: Should be 'left' in 'right'?
value_val = expression(expr.right)
array_ptr = expression(expr.left)
struct_ptr = expression(expr.left)
array_ty = array_ptr.type.pointee.elements[0]
array_size = core.Constant.int(g.i32, array_ty.count)
if is_variable_size:
# load the current number of elements from the first field
end_idx = g.builder.load(g.builder.gep(struct_ptr, [g.zero, g.zero]))
else:
array_ty = struct_ptr.type.pointee.elements[0]
end_idx = core.Constant.int(g.i32, array_ty.count)
g.builder.branch(check_block)
g.builder.position_at_end(check_block)
idx_val = g.builder.load(idx_ptr)
elem_val = g.builder.load(g.builder.gep(array_ptr, [g.zero, g.zero, idx_val]))
if is_variable_size:
# The array values are in the second field in variable size arrays
elem_val = g.builder.load(g.builder.gep(struct_ptr, [g.zero, g.one, idx_val]))
else:
elem_val = g.builder.load(g.builder.gep(struct_ptr, [g.zero, g.zero, idx_val]))
if value_val.type.kind == core.TYPE_INTEGER:
cond_val = g.builder.icmp(core.ICMP_EQ, value_val, elem_val)
elif value_val.type.kind == core.TYPE_DOUBLE:
......@@ -871,9 +897,9 @@ def _expr_in(expr):
g.builder.cbranch(cond_val, end_block, next_block)
g.builder.position_at_end(next_block)
idx_tmp_val = g.builder.add(idx_val, core.Constant.int(g.i32, 1))
idx_tmp_val = g.builder.add(idx_val, g.one)
g.builder.store(idx_tmp_val, idx_ptr)
end_cond_val = g.builder.icmp(core.ICMP_SGE, idx_tmp_val, array_size)
end_cond_val = g.builder.icmp(core.ICMP_SGE, idx_tmp_val, end_idx)
g.builder.cbranch(end_cond_val, end_block, check_block)
g.builder.position_at_end(end_block)
......@@ -988,9 +1014,18 @@ def _sequence(seq):
@expression.register(ogAST.PrimSequenceOf)
def _sequence_of(seqof):
''' Generate the code for an ASN.1 SEQUENCE OF '''
basic_ty = find_basic_type(seqof.exprType)
ty = generate_type(seqof.exprType)
struct_ptr = g.builder.alloca(ty)
array_ptr = g.builder.gep(struct_ptr, [g.zero, g.zero])
is_variable_size = basic_ty.Min != basic_ty.Max
if is_variable_size:
size_val = core.Constant.int(g.i32, len(seqof.value))
g.builder.store(size_val, g.builder.gep(struct_ptr, [g.zero, g.zero]))
array_ptr = g.builder.gep(struct_ptr, [g.zero, g.one])
else:
array_ptr = g.builder.gep(struct_ptr, [g.zero, g.zero])
for idx, expr in enumerate(seqof.value):
idx_cons = core.Constant.int(g.i32, idx)
......@@ -1237,23 +1272,20 @@ def generate_type(ty):
def generate_sequenceof_type(name, sequenceof_ty):
''' Generate the equivalent LLVM type of a SequenceOf type '''
if name and name in g.structs:
return g.structs[name].ty
min_size = int(sequenceof_ty.Max)
max_size = int(sequenceof_ty.Min)
if min_size != max_size:
raise NotImplementedError
min_size = int(sequenceof_ty.Min)
max_size = int(sequenceof_ty.Max)
is_variable_size = min_size != max_size
elem_ty = generate_type(sequenceof_ty.type)
array_ty = core.Type.array(elem_ty, max_size)
if name:
struct = decl_struct(['arr'], [array_ty], name)
if is_variable_size:
struct = decl_struct(['nCount', 'arr'], [g.i32, array_ty], name)
else:
# anonymous sequence used in expressions like a in {b, c, d}
struct = decl_struct(['arr'], [array_ty])
struct = decl_struct(['arr'], [array_ty], name)
return struct.ty
......
/* CIF PROCESS (152, 148), (150, 75) */
/* CIF PROCESS (153, 148), (150, 75) */
PROCESS controlflow;
/* CIF TEXT (373, 97), (303, 168) */
-- Declare your variables
......@@ -9,6 +9,7 @@ DCL n Int32;
DCL b Bool;
DCL l1 IntList;
DCL l2 PointList;
DCL varlist VarIntList;
/* CIF ENDTEXT */
/* CIF START (0, 0), (70, 35) */
START;
......@@ -18,16 +19,10 @@ DCL l2 PointList;
TASK l1 := {1, 2};
/* CIF TASK (-55, 150), (181, 35) */
TASK l2 := {{x 1, y 2}, {x 3, y 4}};
/* CIF NEXTSTATE (0, 200), (70, 35) */
/* CIF TASK (-146, 200), (362, 35) */
TASK varlist := {1, 2, 3, 4, 5, 6, 7};
/* CIF NEXTSTATE (0, 250), (70, 35) */
NEXTSTATE Wait;
/* CIF LABEL (470, 571), (78, 35) */
CONNECTION label1:
/* CIF PROCEDURECALL (438, 621), (141, 35) */
CALL writeln('label1');
/* CIF JOIN (491, 671), (35, 35) */
JOIN label2;
/* CIF End Label */
ENDCONNECTION;
/* CIF LABEL (490, 793), (75, 35) */
CONNECTION label2:
/* CIF PROCEDURECALL (459, 843), (136, 35) */
......@@ -40,76 +35,102 @@ DCL l2 PointList;
NEXTSTATE wait;
/* CIF End Label */
ENDCONNECTION;
/* CIF STATE (0, 200), (70, 35) */
/* CIF LABEL (470, 571), (78, 35) */
CONNECTION label1:
/* CIF PROCEDURECALL (438, 621), (141, 35) */
CALL writeln('label1');
/* CIF JOIN (491, 671), (35, 35) */
JOIN label2;
/* CIF End Label */
ENDCONNECTION;
/* CIF STATE (0, 250), (70, 35) */
STATE Wait;
/* CIF INPUT (0, 255), (70, 35) */
/* CIF INPUT (0, 305), (70, 35) */
INPUT run;
/* CIF DECISION (0, 305), (70, 50) */
/* CIF DECISION (0, 355), (70, 50) */
DECISION b;
/* CIF ANSWER (-73, 375), (73, 24) */
/* CIF ANSWER (-73, 425), (73, 24) */
(true):
/* CIF PROCEDURECALL (-107, 414), (142, 35) */
/* CIF PROCEDURECALL (-107, 464), (142, 35) */
CALL writeln('ERROR');
/* CIF ANSWER (77, 375), (78, 24) */
/* CIF ANSWER (77, 425), (78, 24) */
(false):
/* CIF PROCEDURECALL (44, 414), (142, 35) */
/* CIF PROCEDURECALL (45, 464), (142, 35) */
CALL writeln('OK');
ENDDECISION;
/* CIF DECISION (0, 464), (70, 50) */
/* CIF DECISION (0, 514), (70, 50) */
DECISION n;
/* CIF ANSWER (-11, 464), (70, 24) */
/* CIF ANSWER (-11, 459), (70, 24) */
(2):
/* CIF PROCEDURECALL (-47, 503), (142, 35) */
/* CIF PROCEDURECALL (-47, 498), (142, 35) */
CALL writeln('ERROR');
/* CIF ANSWER (-163, 465), (70, 24) */
/* CIF ANSWER (-163, 460), (70, 24) */
(1):
/* CIF PROCEDURECALL (-199, 504), (142, 35) */
/* CIF PROCEDURECALL (-199, 499), (142, 35) */
CALL writeln('ERROR');
/* CIF ANSWER (132, 464), (70, 24) */
/* CIF ANSWER (132, 459), (70, 24) */
else:
/* CIF PROCEDURECALL (105, 503), (124, 35) */
/* CIF PROCEDURECALL (105, 498), (124, 35) */
CALL writeln('OK');
ENDDECISION;
/* CIF TASK (0, 554), (70, 35) */
/* CIF TASK (0, 549), (70, 35) */
TASK n := 7;
/* CIF DECISION (0, 604), (70, 50) */
/* CIF DECISION (0, 599), (70, 50) */
DECISION n;
/* CIF ANSWER (-159, 659), (70, 24) */
/* CIF ANSWER (-159, 599), (70, 24) */
(2):
/* CIF PROCEDURECALL (-197, 698), (147, 35) */
/* CIF PROCEDURECALL (-197, 638), (147, 35) */
CALL writeln('ERROR');
/* CIF ANSWER (-14, 659), (70, 24) */
/* CIF ANSWER (-14, 599), (70, 24) */
(<10):
/* CIF PROCEDURECALL (-40, 698), (123, 35) */
/* CIF PROCEDURECALL (-40, 638), (123, 35) */
CALL writeln('OK');
/* CIF ANSWER (128, 669), (70, 24) */
/* CIF ANSWER (128, 609), (70, 24) */
else:
/* CIF PROCEDURECALL (91, 708), (142, 35) */
/* CIF PROCEDURECALL (91, 648), (142, 35) */
CALL writeln('ERROR');
ENDDECISION;
/* CIF TASK (-48, 758), (167, 56) */
/* CIF TASK (-48, 698), (167, 56) */
TASK for x in range(3):
call writeln(x);
endfor;
/* CIF TASK (0, 829), (70, 35) */
/* CIF TASK (0, 769), (70, 35) */
TASK n := 0;
/* CIF TASK (-55, 879), (181, 56) */
/* CIF TASK (-55, 819), (181, 56) */
TASK for x in range(2, 10, 2):
n := (n + x) mod 255
endfor;
/* CIF PROCEDURECALL (-15, 950), (100, 34) */
/* CIF PROCEDURECALL (-15, 890), (100, 34) */
CALL writeln(n)
/* CIF COMMENT (105, 894), (70, 35) */
/* CIF COMMENT (105, 779), (70, 35) */
COMMENT '20';
/* CIF TASK (-36, 999), (142, 56) */
/* CIF TASK (-36, 939), (142, 56) */
TASK for x in l1:
call writeln(x);
endfor;
/* CIF TASK (-38, 1070), (146, 56) */
/* CIF TASK (-38, 1010), (146, 56) */
TASK for p in l2:
call writeln(p!x);
endfor;
/* CIF JOIN (17, 1141), (35, 35) */
/* CIF TASK (-36, 1081), (142, 56) */
TASK for x in varlist:
call writeln(x);
endfor;
/* CIF TASK (-26, 1152), (123, 35) */
TASK varlist := {7, 8};
/* CIF TASK (-36, 1202), (142, 56) */
TASK for x in varlist:
call writeln(x);
endfor;
/* CIF PROCEDURECALL (-38, 1273), (146, 35) */
CALL writeln(varlist(0));
/* CIF PROCEDURECALL (-38, 1323), (146, 35) */
CALL writeln(varlist(1));
/* CIF PROCEDURECALL (-46, 1373), (162, 35) */
CALL writeln(99 in varlist);
/* CIF PROCEDURECALL (-42, 1423), (154, 35) */
CALL writeln(8 in varlist);
/* CIF JOIN (17, 1473), (35, 35) */
JOIN label1;
ENDSTATE;
ENDPROCESS controlflow;
\ No newline at end of file
......@@ -12,6 +12,8 @@ Point ::= SEQUENCE {
IntList ::= SEQUENCE (SIZE (2)) OF Int32
VarIntList ::= SEQUENCE (SIZE (1..32)) OF Int32
PointList ::= SEQUENCE (SIZE(2)) OF Point
END
......@@ -9,6 +9,19 @@ OK
2
1
3
1
2
3
4
5
6
7
7
8
7
8
FALSE
TRUE
label1
label2
label3
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