Commit 490a0fc3 authored by Maxime Perrotin's avatar Maxime Perrotin
Browse files

Work on LLVM backend (ExprAppend issue)

parent c320d306
......@@ -671,7 +671,7 @@ def _proc_call(proc_call, ctx):
if name == 'write' or name == 'writeln':
def flatten_append(arg):
''' transform "write(a//b)" to "write(a,b)" '''
''' Transform "write(a//b//...)" to "write(a, b, ...)" '''
if isinstance(arg, ogAST.ExprAppend):
res = flatten_append(arg.left)
res.extend(flatten_append(arg.right))
......@@ -1223,61 +1223,78 @@ def _expr_not(expr, ctx):
@expression.register(ogAST.ExprAppend)
def _expr_append(expr, ctx):
''' Generate the IR for a append expression '''
basic_asn1ty = ctx.basic_asn1type_of(expr.exprType)
if basic_asn1ty.kind in ('SequenceOfType', 'OctetStringType'):
res_llty = ctx.lltype_of(expr.exprType)
elem_llty = res_llty.elements[1].element
elem_size_val = lc.Constant.sizeof(elem_llty)
res_ptr = ctx.builder.alloca(res_llty)
res_len_ptr = ctx.builder.gep(res_ptr, [ctx.zero, ctx.zero])
res_arr_ptr = ctx.builder.gep(res_ptr, [ctx.zero, ctx.one])
left_ptr = expression(expr.left, ctx)
if isinstance(left_ptr, SDLSubstringValue):
left_arr_ptr = left_ptr.arr_ptr
left_count_val = left_ptr.count_val
else:
left_len_ptr = ctx.builder.gep(left_ptr, [ctx.zero, ctx.zero])
left_arr_ptr = ctx.builder.gep(left_ptr, [ctx.zero, ctx.one])
left_count_val = ctx.builder.load(left_len_ptr)
right_ptr = expression(expr.right, ctx)
if isinstance(right_ptr, SDLSubstringValue):
right_arr_ptr = right_ptr.arr_ptr
right_count_val = right_ptr.count_val
else:
right_len_ptr = ctx.builder.gep(right_ptr, [ctx.zero, ctx.zero])
right_arr_ptr = ctx.builder.gep(right_ptr, [ctx.zero, ctx.one])
right_count_val = ctx.builder.load(right_len_ptr)
res_len_val = ctx.builder.add(left_count_val, right_count_val)
ctx.builder.store(res_len_val, res_len_ptr)
sdl_call('memcpy', [
ctx.builder.bitcast(res_arr_ptr, ctx.i8_ptr),
ctx.builder.bitcast(left_arr_ptr, ctx.i8_ptr),
ctx.builder.mul(elem_size_val, ctx.builder.zext(left_count_val, ctx.i64)),
lc.Constant.int(ctx.i32, 0),
lc.Constant.int(ctx.i1, 0)
], ctx)
res_arr_ptr = ctx.builder.gep(res_ptr, [ctx.zero, ctx.one, left_count_val])
sdl_call('memcpy', [
ctx.builder.bitcast(res_arr_ptr, ctx.i8_ptr),
ctx.builder.bitcast(right_arr_ptr, ctx.i8_ptr),
ctx.builder.mul(elem_size_val, ctx.builder.zext(right_count_val, ctx.i64)),
lc.Constant.int(ctx.i32, 0),
lc.Constant.int(ctx.i1, 0)
], ctx)
return res_ptr
raise CompileError('Type "%s" not supported in append expressions'
% basic_asn1ty.kind)
''' Generate the IR for an append reference '''
apnd = SDLAppendValue()
# Append expressions can be recursive -> Flatten them
if isinstance(expr.left, ogAST.ExprAppend):
# Get an SDLAppendValue for recursive Append constructs
inner_left = expression(expr.left)
apnd.apnd_list.extend(inner_left.apnd_list)
else:
apnd.apnd_list.append(expr.left)
if isinstance(expr.left, ogAST.ExprAppend):
inner_right = expression(expr.right)
apnd.apnd_list.extend(inner_right.apnd_list)
else:
apnd.apnd_list.append(expr.right)
return apnd
#@expression.register(ogAST.ExprAppend)
#def _expr_append(expr, ctx):
# ''' Generate the IR for a append expression '''
# basic_asn1ty = ctx.basic_asn1type_of(expr.exprType)
#
# if basic_asn1ty.kind in ('SequenceOfType', 'OctetStringType'):
# res_llty = ctx.lltype_of(expr.exprType)
# elem_llty = res_llty.elements[1].element
# elem_size_val = lc.Constant.sizeof(elem_llty)
#
# res_ptr = ctx.builder.alloca(res_llty)
# res_len_ptr = ctx.builder.gep(res_ptr, [ctx.zero, ctx.zero])
# res_arr_ptr = ctx.builder.gep(res_ptr, [ctx.zero, ctx.one])
#
# left_ptr = expression(expr.left, ctx)
# if isinstance(left_ptr, SDLSubstringValue):
# left_arr_ptr = left_ptr.arr_ptr
# left_count_val = left_ptr.count_val
# else:
# left_len_ptr = ctx.builder.gep(left_ptr, [ctx.zero, ctx.zero])
# left_arr_ptr = ctx.builder.gep(left_ptr, [ctx.zero, ctx.one])
# left_count_val = ctx.builder.load(left_len_ptr)
#
# right_ptr = expression(expr.right, ctx)
# if isinstance(right_ptr, SDLSubstringValue):
# right_arr_ptr = right_ptr.arr_ptr
# right_count_val = right_ptr.count_val
# else:
# right_len_ptr = ctx.builder.gep(right_ptr, [ctx.zero, ctx.zero])
# right_arr_ptr = ctx.builder.gep(right_ptr, [ctx.zero, ctx.one])
# right_count_val = ctx.builder.load(right_len_ptr)
#
# res_len_val = ctx.builder.add(left_count_val, right_count_val)
# ctx.builder.store(res_len_val, res_len_ptr)
#
# sdl_call('memcpy', [
# ctx.builder.bitcast(res_arr_ptr, ctx.i8_ptr),
# ctx.builder.bitcast(left_arr_ptr, ctx.i8_ptr),
# ctx.builder.mul(elem_size_val, ctx.builder.zext(left_count_val, ctx.i64)),
# lc.Constant.int(ctx.i32, 0),
# lc.Constant.int(ctx.i1, 0)
# ], ctx)
#
# res_arr_ptr = ctx.builder.gep(res_ptr, [ctx.zero, ctx.one, left_count_val])
#
# sdl_call('memcpy', [
# ctx.builder.bitcast(res_arr_ptr, ctx.i8_ptr),
# ctx.builder.bitcast(right_arr_ptr, ctx.i8_ptr),
# ctx.builder.mul(elem_size_val, ctx.builder.zext(right_count_val, ctx.i64)),
# lc.Constant.int(ctx.i32, 0),
# lc.Constant.int(ctx.i1, 0)
# ], ctx)
#
# return res_ptr
#
# raise CompileError('Type "%s" not supported in append expressions'
# % basic_asn1ty.kind)
@expression.register(ogAST.ExprIn)
......@@ -1828,7 +1845,7 @@ def is_array_ptr(val):
val.type.pointee.kind == lc.TYPE_ARRAY
################################################################################
###############################################################################
# Values
......@@ -1838,8 +1855,12 @@ class SDLSubstringValue():
self.count_val = count_val
self.asn1ty = asn1ty
class SDLAppendValue():
''' Store an array concatenation value (e.g. "a//b") '''
def __init__(self):
self.apnd_list = []
################################################################################
###############################################################################
# Operators
......@@ -1875,6 +1896,9 @@ def sdl_assign(a_ptr, b_val, ctx):
if basic_asn1ty.Min != basic_asn1ty.Max:
ctx.builder.store(b_val.count_val, a_count_ptr)
elif isinstance(b_val, SDLAppendValue):
print 'Assign Append', b_val
elif is_struct_ptr(a_ptr) or is_array_ptr(a_ptr):
size = lc.Constant.sizeof(a_ptr.type.pointee)
align = lc.Constant.int(ctx.i32, 0)
......
include ../shared.mk
all: test-ada test-llvm
edit:
$(OPENGEODE) orchestrator.pr system_structure.pr
test-parse:
$(OPENGEODE) orchestrator.pr system_structure.pr --check
test-ada: orchestrator.ali dataview-uniq.o | test_ada.o
$(GNATBIND) -n orchestrator.ali
$(GNATLINK) -o test_ada test_ada.o orchestrator.ali -lgnat
./test_ada
test-llvm: orchestrator.o dataview-uniq.o | test_llvm.o
$(CC) orchestrator.o dataview-uniq.o test_llvm.o -o test_llvm -lm
./test_llvm
coverage:
coverage run -p $(OPENGEODE) orchestrator.pr system_structure.pr --toAda
.PHONY: all edit test-parse test-ada test-llvm coverage
TASTE-BasicTypes DEFINITIONS ::=
BEGIN
TASTE-Peek-id ::= INTEGER (0..4294967295)
TASTE-Peek-id-list ::= SEQUENCE (SIZE (1..10)) OF TASTE-Peek-id
VariableString ::= OCTET STRING (SIZE (1..10))
FixedString ::= OCTET STRING (SIZE (5))
SeqBool ::= SEQUENCE (SIZE(1..5)) OF BOOLEAN
SeqBoolFix ::= SEQUENCE (SIZE(2)) OF BOOLEAN
SeqEnum ::= SEQUENCE (SIZE(1..5)) OF ENUMERATED { hello, world }
SeqEnumFix ::= SEQUENCE (SIZE(2)) OF ENUMERATED { hello, world }
Enum ::= ENUMERATED {a, b, c, d, eE}
Choice ::= CHOICE {c1 BOOLEAN, cDe2 BOOLEAN}
END
/* CIF PROCESS (295, 56), (150, 75) */
PROCESS orchestrator
/* CIF COMMENT (405, 192), (71, 35) */
COMMENT 'Hello';
/* CIF TEXT (39, 94), (293, 263) */
dcl fixed FixedString := 'Hello';
/* CIF ENDTEXT */
/* CIF START (456, 110), (70, 35) */
START;
/* CIF PROCEDURECALL (352, 160), (277, 35) */
CALL writeln(fixed(0,2)//fixed(2,4)//' world')
/* CIF COMMENT (649, 160), (173, 53) */
COMMENT 'FIXME: string world
cannot be longer than
6 chars !?';
/* CIF TASK (410, 210), (159, 35) */
TASK fixed := 'Hel' // 'lp';
/* CIF PROCEDURECALL (428, 260), (124, 35) */
CALL writeln(fixed);
/* CIF NEXTSTATE (455, 310), (70, 35) */
NEXTSTATE wait;
/* CIF STATE (440, 359), (70, 35) */
STATE wait;
ENDSTATE;
ENDPROCESS orchestrator;
\ No newline at end of file
/* CIF Keep Specific Geode ASNFilename 'dataview-uniq.asn' */
USE Datamodel;
SYSTEM orchestrator;
SIGNAL pulse;
SIGNAL telemetry;
CHANNEL c
FROM ENV TO orchestrator WITH pulse;
FROM orchestrator TO ENV WITH telemetry;
ENDCHANNEL;
BLOCK orchestrator;
SIGNALROUTE r
FROM ENV TO orchestrator WITH pulse;
FROM orchestrator TO ENV WITH telemetry;
CONNECT c and r;
PROCESS orchestrator REFERENCED;
ENDBLOCK;
ENDSYSTEM;
#include <math.h>
#include <stdio.h>
#include "dataview-uniq.h"
extern void adainit();
void orchestrator_RI_telemetry(void *_){}
void orchestrator_RI_S_SET_GNC_LV_SIM_CONTEXT_FOR_NEXT_MAJOR_CYCLE(void *_){}
void orchestrator_RI_Scheduler(void *_){}
void orchestrator_RI_VESAT_Simulation_Step(void *_){}
void orchestrator_RI_plot(void *_) {}
void orchestrator_RI_S_JUMP_TO_NEXT_MAJOR_CYCLE() {}
void orchestrator_RI_S_GET_GNC_LV_SIM_INPUTS_FOR_NEXT_MAJOR_CYCLE(void *_){}
int main()
{
printf("[C Code] Running test\n");
adainit();
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include "dataview-uniq.h"
extern void orchestrator_startup();
void orchestrator_RI_telemetry(void *_){}
void orchestrator_RI_S_SET_GNC_LV_SIM_CONTEXT_FOR_NEXT_MAJOR_CYCLE(void *_){}
void orchestrator_RI_Scheduler(void *_){}
void orchestrator_RI_VESAT_Simulation_Step(void *_){}
void orchestrator_RI_plot(void *_) {}
void orchestrator_RI_S_JUMP_TO_NEXT_MAJOR_CYCLE() {}
void orchestrator_RI_S_GET_GNC_LV_SIM_INPUTS_FOR_NEXT_MAJOR_CYCLE(void *_){}
int main() {
orchestrator_startup();
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