Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
TASTE
buildsupport
Commits
5826a3f0
Commit
5826a3f0
authored
Aug 11, 2017
by
Damien George
Browse files
Initial support for MicroPython
parent
e32aae96
Changes
13
Hide whitespace changes
Inline
Side-by-side
ada/buildsupport.adb
View file @
5826a3f0
...
...
@@ -215,6 +215,8 @@ procedure BuildSupport is
C_Set_Language_To_BlackBox_Device
;
when
Language_QGenAda
=>
C_Set_Language_To_QGenAda
;
when
Language_QGenC
=>
C_Set_Language_To_QGenC
;
when
Language_MicroPython
=>
C_Set_Language_To_MicroPython
;
when
others
=>
Exit_On_Error
(
True
,
"Language is currently not supported: "
&
Source_Language
'
Img
);
...
...
ada/imported_routines.ads
View file @
5826a3f0
...
...
@@ -162,6 +162,7 @@ package Imported_Routines is
procedure
C_Set_Language_To_GUI
;
procedure
C_Set_Language_To_VHDL
;
procedure
C_Set_Language_To_System_C
;
procedure
C_Set_Language_To_MicroPython
;
procedure
C_Set_Native_Encoding
;
procedure
C_Set_UPER_Encoding
;
procedure
C_Set_ACN_Encoding
;
...
...
@@ -249,6 +250,8 @@ private
pragma
Import
(
C
,
C_Set_Language_To_GUI
,
"Set_Language_To_GUI"
);
pragma
Import
(
C
,
C_Set_Language_To_VHDL
,
"Set_Language_To_VHDL"
);
pragma
Import
(
C
,
C_Set_Language_To_System_C
,
"Set_Language_To_System_C"
);
pragma
Import
(
C
,
C_Set_Language_To_MicroPython
,
"Set_Language_To_MicroPython"
);
pragma
Import
(
C
,
C_Set_UPER_Encoding
,
"Set_UPER_Encoding"
);
pragma
Import
(
C
,
C_Set_ACN_Encoding
,
"Set_ACN_Encoding"
);
pragma
Import
(
C
,
C_Set_Native_Encoding
,
"Set_Native_Encoding"
);
...
...
c/build_c_glue.c
View file @
5826a3f0
...
...
@@ -62,6 +62,9 @@ void c_preamble(FV * fv)
else
if
(
rtds
==
fv
->
language
)
{
fprintf
(
vm_if
,
"#include
\"
glue_%s.h
\"\n\n
"
,
fv
->
name
);
}
else
if
(
micropython
==
fv
->
language
)
{
fprintf
(
vm_if
,
"#include
\"
%s_mpy_bindings.h
\"\n\n
"
,
fv
->
name
);
}
if
(
hasparam
)
{
fprintf
(
vm_if
,
"#include
\"
C_ASN1_Types.h
\"\n\n
"
);
...
...
@@ -714,7 +717,8 @@ void GLUE_C_Backend(FV * fv)
if
(
c
==
fv
->
language
||
gui
==
fv
->
language
||
ada
==
fv
->
language
||
vdm
==
fv
->
language
||
qgenada
==
fv
->
language
||
qgenc
==
fv
->
language
||
rtds
==
fv
->
language
||
cpp
==
fv
->
language
||
opengeode
==
fv
->
language
)
{
||
rtds
==
fv
->
language
||
cpp
==
fv
->
language
||
opengeode
==
fv
->
language
||
micropython
==
fv
->
language
)
{
Init_C_Glue_Backend
(
fv
);
FOREACH
(
i
,
Interface
,
fv
->
interfaces
,
{
GLUE_C_ProvidedInterface
(
i
);
...
...
c/build_micropython_glue.c
0 → 100644
View file @
5826a3f0
/* Buildsupport is (c) 2008-2015 European Space Agency
* contact: maxime.perrotin@esa.int
* License is LGPL, check LICENSE file */
/* build_sdl_glue.c
this program generates the code to interface an objectgeode generated application with the assert virtual machine
It creates X_mpy_bindings.h and X_mpy_bindings.c.
*/
#define ID "$Id: build_sdl_glue.c 414 2009-12-04 16:21:52Z maxime1008 $"
#include
<stdio.h>
#include
<string.h>
#include
<stdlib.h>
#include
<sys/stat.h>
#include
"my_types.h"
#include
"practical_functions.h"
static
FILE
*
mpy_bind_h
,
*
mpy_bind_c
;
static
bool
gen_this_ri
(
Interface
*
i
)
{
/*
* There can be duplicate RI name but one sync, the other async
* In that case, discard the async one (generated by VT to allow
* a mix of sync and async PI in one block
*/
if
(
asynch
==
i
->
synchronism
)
{
FOREACH
(
interface
,
Interface
,
i
->
parent_fv
->
interfaces
,
{
if
(
RI
==
interface
->
direction
&&
!
strcmp
(
interface
->
name
,
i
->
name
)
&&
synch
==
interface
->
synchronism
)
{
return
false
;
}
});
}
return
true
;
}
void
micropython_mpy_bind_preamble
(
FV
*
fv
)
{
if
(
NULL
==
mpy_bind_h
||
NULL
==
mpy_bind_c
)
return
;
int
hasparam
=
0
;
/* Check if any interface needs ASN.1 types */
FOREACH
(
i
,
Interface
,
fv
->
interfaces
,
{
CheckForAsn1Params
(
i
,
&
hasparam
);}
);
fprintf
(
mpy_bind_h
,
"/* This file was generated automatically by build_micropython_glue.c: DO NOT MODIFY IT ! */
\n\n
"
);
fprintf
(
mpy_bind_h
,
"/* Declaration of the functions that have to be provided by the user */
\n\n
"
);
fprintf
(
mpy_bind_h
,
"#ifndef __USER_CODE_H_%s__
\n
#define __USER_CODE_H_%s__
\n\n
"
,
fv
->
name
,
fv
->
name
);
fprintf
(
mpy_bind_h
,
"#include <stdint.h>
\n\n
"
);
if
(
hasparam
)
{
fprintf
(
mpy_bind_h
,
"#include
\"
C_ASN1_Types.h
\"\n\n
"
);
}
fprintf
(
mpy_bind_h
,
"#ifdef __cplusplus
\n
"
"extern
\"
C
\"
{
\n
"
"#endif
\n\n
"
);
fprintf
(
mpy_bind_h
,
"void %s_startup();
\n\n
"
,
fv
->
name
);
fprintf
(
mpy_bind_c
,
"#include
\"
py/runtime.h
\"\n
"
);
fprintf
(
mpy_bind_c
,
"#include
\"
py/gc.h
\"\n
"
);
fprintf
(
mpy_bind_c
,
"#include
\"
py/stackctrl.h
\"\n
"
);
fprintf
(
mpy_bind_c
,
"#include
\"
py/pystack.h
\"\n
"
);
fprintf
(
mpy_bind_c
,
"#include
\"
mputil.h
\"\n
"
);
fprintf
(
mpy_bind_c
,
"#include
\"
%s_mpy_bindings.h
\"\n
"
,
fv
->
name
);
fprintf
(
mpy_bind_c
,
"#include
\"
%s.mpy.h
\"\n\n
"
,
fv
->
name
);
if
(
has_context_param
(
fv
))
{
char
*
fv_no_underscore
=
underscore_to_dash
(
fv
->
name
,
strlen
(
fv
->
name
));
fprintf
(
mpy_bind_c
,
"/* Function static data is declared in this file : */
\n
"
);
fprintf
(
mpy_bind_c
,
"#include
\"
Context-%s.h
\"\n\n
"
,
fv_no_underscore
);
free
(
fv_no_underscore
);
}
fprintf
(
mpy_bind_c
,
"mp_state_ctx_t *mp_current_ctx;
\n
"
);
// TODO there should only be one of these per executable
fprintf
(
mpy_bind_c
,
"static mp_state_ctx_t mp_ctx;
\n
"
);
fprintf
(
mpy_bind_c
,
"static uint64_t mp_heap[4096];
\n
"
);
fprintf
(
mpy_bind_c
,
"static mp_obj_t mp_pystack[4096];
\n\n
"
);
FOREACH
(
i
,
Interface
,
fv
->
interfaces
,
{
if
(
i
->
direction
==
PI
)
{
fprintf
(
mpy_bind_c
,
"static mp_obj_t mp_global_%s_PI_%s;
\n\n
"
,
i
->
parent_fv
->
name
,
i
->
name
);
}
});
fprintf
(
mpy_bind_c
,
"void %s_startup()
\n
{
\n
"
,
fv
->
name
);
fprintf
(
mpy_bind_c
,
" /* MicroPython VM initialisation */
\n
"
" mp_current_ctx = &mp_ctx;
\n
"
" mp_stack_ctrl_init();
\n
"
" mp_stack_set_limit(8192);
\n
"
" gc_init(mp_heap, (uint8_t*)mp_heap + sizeof(mp_heap));
\n
"
" mp_pystack_init(mp_pystack, (uint8_t*)mp_pystack + sizeof(mp_pystack));
\n
"
" mp_init();
\n
"
" mp_exec_mpy(mpy_script_data, mpy_script_len);
\n
"
);
fprintf
(
mpy_bind_c
,
" mp_obj_t global_startup = mp_load_global(MP_QSTR_%s_startup);
\n
"
,
fv
->
name
);
FOREACH
(
i
,
Interface
,
fv
->
interfaces
,
{
if
(
i
->
direction
==
PI
)
{
fprintf
(
mpy_bind_c
,
" mp_global_%s_PI_%s = mp_load_global(MP_QSTR_%s_PI_%s);
\n
"
,
i
->
parent_fv
->
name
,
i
->
name
,
i
->
parent_fv
->
name
,
i
->
name
);
}
});
fprintf
(
mpy_bind_c
,
" mp_call_function_0(global_startup);
\n
"
);
fprintf
(
mpy_bind_c
,
"}
\n\n
"
);
}
void
micropython_add_PI_to_glue
(
Interface
*
i
)
{
if
(
NULL
==
mpy_bind_h
)
return
;
char
*
signature
=
make_string
(
"void %s_PI_%s("
,
i
->
parent_fv
->
name
,
i
->
name
);
char
*
signature_py
=
make_string
(
"def %s_PI_%s("
,
i
->
parent_fv
->
name
,
i
->
name
);
size_t
sig_len
=
strlen
(
signature
);
char
*
sep
=
make_string
(
",
\n
%*s"
,
sig_len
,
""
);
char
*
sep_py
=
make_string
(
",
\n
%*s"
,
strlen
(
signature_py
),
""
);
size_t
n_args
=
0
;
fprintf
(
mpy_bind_h
,
"%s"
,
signature
);
fprintf
(
mpy_bind_c
,
"%s"
,
signature
);
FOREACH
(
p
,
Parameter
,
i
->
in
,
{
char
*
sort
=
make_string
(
"%sconst asn1Scc%s *"
,
n_args
?
sep
:
""
,
p
->
type
);
fprintf
(
mpy_bind_h
,
"%s"
,
sort
);
fprintf
(
mpy_bind_c
,
"%sIN_%s"
,
sort
,
p
->
name
);
free
(
sort
);
n_args
+=
1
;
});
FOREACH
(
p
,
Parameter
,
i
->
out
,
{
char
*
sort
=
make_string
(
"%sasn1Scc%s *"
,
n_args
?
sep
:
""
,
p
->
type
);
fprintf
(
mpy_bind_h
,
"%s"
,
sort
);
fprintf
(
mpy_bind_c
,
"%sOUT_%s"
,
sort
,
p
->
name
);
free
(
sort
);
n_args
+=
1
;
});
fprintf
(
mpy_bind_h
,
");
\n\n
"
);
fprintf
(
mpy_bind_c
,
")
\n
{
\n
"
);
fprintf
(
mpy_bind_c
,
" mp_current_ctx = &mp_ctx;
\n
"
);
fprintf
(
mpy_bind_c
,
" mp_obj_t args[%u];
\n
"
,
n_args
);
fprintf
(
mpy_bind_c
,
" mp_stack_ctrl_init();
\n
"
" mp_stack_set_limit(2048);
\n
"
" nlr_buf_t nlr;
\n
"
" if (nlr_push(&nlr) == 0) {
\n
"
);
n_args
=
0
;
FOREACH
(
p
,
Parameter
,
i
->
in
,
{
fprintf
(
mpy_bind_c
,
" args[%u] = mp_obj_new_int(*IN_%s);
\n
"
,
n_args
,
p
->
name
);
n_args
+=
1
;
});
fprintf
(
mpy_bind_c
,
" mp_call_function_n_kw(mp_global_%s_PI_%s, %u, 0, args);
\n
"
" nlr_pop();
\n
"
" } else {
\n
"
" mp_obj_print_exception(&mp_plat_print, MP_OBJ_FROM_PTR(nlr.ret_val));
\n
"
" }
\n
"
"}
\n
"
"
\n
"
,
i
->
parent_fv
->
name
,
i
->
name
,
n_args
);
free
(
signature
);
free
(
signature_py
);
free
(
sep
);
free
(
sep_py
);
}
void
micropython_add_RI_to_glue
(
Interface
*
i
)
{
if
(
NULL
==
mpy_bind_h
)
return
;
char
*
signature
=
make_string
(
"extern void %s_RI_%s("
,
i
->
parent_fv
->
name
,
i
->
name
);
size_t
sig_len
=
strlen
(
signature
);
char
*
sep
=
make_string
(
",
\n
%*s"
,
sig_len
,
""
);
size_t
n_args
=
0
;
fprintf
(
mpy_bind_c
,
"%s"
,
signature
);
FOREACH
(
p
,
Parameter
,
i
->
in
,
{
fprintf
(
mpy_bind_c
,
"%sconst asn1Scc%s *"
,
n_args
?
sep
:
""
,
p
->
type
);
n_args
+=
1
;
});
FOREACH
(
p
,
Parameter
,
i
->
out
,
{
fprintf
(
mpy_bind_c
,
"%sasn1Scc%s *"
,
n_args
?
sep
:
""
,
p
->
type
);
n_args
+=
1
;
});
fprintf
(
mpy_bind_c
,
");
\n\n
"
);
free
(
signature
);
free
(
sep
);
fprintf
(
mpy_bind_c
,
"STATIC mp_obj_t %s_RI_%s_wrap(size_t n_args, const mp_obj_t *args)
\n
"
"{
\n
"
,
i
->
parent_fv
->
name
,
i
->
name
);
n_args
=
0
;
FOREACH
(
p
,
Parameter
,
i
->
in
,
{
fprintf
(
mpy_bind_c
,
" asn1Scc%s asn_IN_%s = mp_obj_get_int(args[%u]);
\n
"
,
p
->
type
,
p
->
name
,
n_args
);
n_args
+=
1
;
});
n_args
=
0
;
FOREACH
(
p
,
Parameter
,
i
->
out
,
{
fprintf
(
mpy_bind_c
,
" asn1Scc%s asn_OUT_%s;
\n
"
,
p
->
type
,
p
->
name
);
n_args
+=
1
;
});
fprintf
(
mpy_bind_c
,
" %s_RI_%s("
,
i
->
parent_fv
->
name
,
i
->
name
);
n_args
=
0
;
FOREACH
(
p
,
Parameter
,
i
->
in
,
{
fprintf
(
mpy_bind_c
,
"%s&asn_IN_%s"
,
n_args
?
", "
:
""
,
p
->
name
);
n_args
+=
1
;
});
FOREACH
(
p
,
Parameter
,
i
->
out
,
{
fprintf
(
mpy_bind_c
,
"%s&asn_OUT_%s"
,
n_args
?
", "
:
""
,
p
->
name
);
n_args
+=
1
;
});
fprintf
(
mpy_bind_c
,
");
\n
"
);
fprintf
(
mpy_bind_c
,
" return mp_const_none;
\n
"
"}
\n
"
"STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(%s_RI_%s_obj, %u, %u, %s_RI_%s_wrap);
\n
"
"
\n
"
,
i
->
parent_fv
->
name
,
i
->
name
,
n_args
,
n_args
,
i
->
parent_fv
->
name
,
i
->
name
);
}
int
Init_MicroPython_Glue_Backend
(
FV
*
fv
)
{
char
*
path
=
NULL
,
*
filename
=
NULL
;
if
(
NULL
!=
fv
->
system_ast
->
context
->
output
)
build_string
(
&
path
,
fv
->
system_ast
->
context
->
output
,
strlen
(
fv
->
system_ast
->
context
->
output
));
build_string
(
&
path
,
fv
->
name
,
strlen
(
fv
->
name
));
build_string
(
&
filename
,
fv
->
name
,
strlen
(
fv
->
name
));
build_string
(
&
filename
,
"_mpy_bindings.c"
,
strlen
(
"_mpy_bindings.c"
));
create_file
(
path
,
filename
,
&
mpy_bind_c
);
filename
[
strlen
(
filename
)
-
1
]
=
'h'
;
create_file
(
path
,
filename
,
&
mpy_bind_h
);
free
(
path
);
free
(
filename
);
if
(
NULL
==
mpy_bind_c
||
NULL
==
mpy_bind_h
)
return
-
1
;
micropython_mpy_bind_preamble
(
fv
);
return
0
;
}
void
End_MicroPython_Glue_Backend
(
FV
*
fv
)
{
// Generate the taste module
fprintf
(
mpy_bind_c
,
"STATIC const mp_rom_map_elem_t taste_module_globals_table[] = {
\n
"
" { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_taste) },
\n
"
);
FOREACH
(
i
,
Interface
,
fv
->
interfaces
,
{
if
(
i
->
direction
==
RI
&&
gen_this_ri
(
i
))
{
fprintf
(
mpy_bind_c
,
" { MP_ROM_QSTR(MP_QSTR_%s_RI_%s), MP_ROM_PTR(&%s_RI_%s_obj) },
\n
"
,
i
->
parent_fv
->
name
,
i
->
name
,
i
->
parent_fv
->
name
,
i
->
name
);
}
});
fprintf
(
mpy_bind_c
,
"};
\n
"
"
\n
"
"STATIC MP_DEFINE_CONST_DICT(taste_module_globals, taste_module_globals_table);
\n
"
"
\n
"
"const mp_obj_module_t mp_module_taste = {
\n
"
" .base = { &mp_type_module },
\n
"
" .globals = (mp_obj_dict_t*)&taste_module_globals,
\n
"
"};
\n
"
);
if
(
NULL
!=
mpy_bind_h
)
{
fprintf
(
mpy_bind_h
,
"#ifdef __cplusplus
\n
"
"}
\n
"
"#endif
\n\n
"
);
fprintf
(
mpy_bind_h
,
"
\n
#endif
\n
"
);
close_file
(
&
mpy_bind_h
);
}
close_file
(
&
mpy_bind_c
);
}
/* Function to process one interface of the FV */
void
GLUE_MicroPython_Interface
(
Interface
*
i
)
{
switch
(
i
->
direction
)
{
case
PI
:
micropython_add_PI_to_glue
(
i
);
break
;
case
RI
:
if
(
gen_this_ri
(
i
))
{
micropython_add_RI_to_glue
(
i
);
}
break
;
default:
break
;
}
}
// External interface (the one and unique)
void
GLUE_MicroPython_Backend
(
FV
*
fv
)
{
if
(
fv
->
system_ast
->
context
->
onlycv
)
return
;
if
(
micropython
==
fv
->
language
)
{
Init_MicroPython_Glue_Backend
(
fv
);
FOREACH
(
i
,
Interface
,
fv
->
interfaces
,
{
GLUE_MicroPython_Interface
(
i
);
})
End_MicroPython_Glue_Backend
(
fv
);
}
}
c/build_micropython_skeletons.c
0 → 100644
View file @
5826a3f0
/* Buildsupport is (c) 2008-2016 European Space Agency
* contact: maxime.perrotin@esa.int
* License is LGPL, check LICENSE file */
/* build_c_skeletons.c
this program generates empty C functions respecting the interfaces defined
in the interface view. it provides functions to invoke RI.
updated 10/06/2016: properly align params and use FOREACH
updated 20/04/2009 to disable in case "-onlycv" flag is set
updated 8/10/2009 to rename the user_code.h/c to FV_name.h/c like in the Ada backend
*/
#include
<stdio.h>
#include
<string.h>
#include
<stdlib.h>
#include
<sys/stat.h>
#include
<stdbool.h>
#include
<assert.h>
#include
"my_types.h"
#include
"practical_functions.h"
static
FILE
*
user_code_py
=
NULL
;
static
bool
gen_this_ri
(
Interface
*
i
)
{
/*
* There can be duplicate RI name but one sync, the other async
* In that case, discard the async one (generated by VT to allow
* a mix of sync and async PI in one block
*/
if
(
asynch
==
i
->
synchronism
)
{
FOREACH
(
interface
,
Interface
,
i
->
parent_fv
->
interfaces
,
{
if
(
RI
==
interface
->
direction
&&
!
strcmp
(
interface
->
name
,
i
->
name
)
&&
synch
==
interface
->
synchronism
)
{
return
false
;
}
});
}
return
true
;
}
/* Import the RI into the module-level namespace of the Python script */
void
import_RI_to_MicroPython_skel
(
Interface
*
i
)
{
if
(
NULL
==
user_code_py
)
return
;
bool
comma
=
false
;
fprintf
(
user_code_py
,
"# %s_RI_%s("
,
i
->
parent_fv
->
name
,
i
->
name
);
FOREACH
(
p
,
Parameter
,
i
->
in
,
{
fprintf
(
user_code_py
,
"%sIN_%s: asn1Scc%s"
,
comma
?
","
:
""
,
p
->
name
,
p
->
type
);
comma
=
true
;
});
FOREACH
(
p
,
Parameter
,
i
->
out
,
{
fprintf
(
user_code_py
,
"%sOUT_%s: asn1Scc%s"
,
comma
?
","
:
""
,
p
->
name
,
p
->
type
);
comma
=
true
;
});
fprintf
(
user_code_py
,
")
\n
"
);
fprintf
(
user_code_py
,
"from taste import %s_RI_%s
\n
"
,
i
->
parent_fv
->
name
,
i
->
name
);
}
/* Generate the preamble of the skeleton script */
void
micropython_skel_preamble
(
FV
*
fv
)
{
int
hasparam
=
0
;
/* Check if any interface needs ASN.1 types */
FOREACH
(
i
,
Interface
,
fv
->
interfaces
,
{
CheckForAsn1Params
(
i
,
&
hasparam
);}
);
/* c. user_code.py preamble (if applicable) */
if
(
NULL
!=
user_code_py
)
{
fprintf
(
user_code_py
,
"# User code: This file will not be overwritten by TASTE.
\n\n
"
);
fprintf
(
user_code_py
,
"import micropython
\n\n
"
);
FOREACH
(
i
,
Interface
,
fv
->
interfaces
,
{
if
(
i
->
direction
==
RI
&&
gen_this_ri
(
i
))
{
import_RI_to_MicroPython_skel
(
i
);
}
});
fprintf
(
user_code_py
,
"
\n
"
);
// TODO need to generate dummy variables for the types
if
(
has_context_param
(
fv
))
{
char
*
fv_no_underscore
=
underscore_to_dash
(
fv
->
name
,
strlen
(
fv
->
name
));
fprintf
(
user_code_py
,
"/* Function static data is declared in this file : */
\n
"
);
fprintf
(
user_code_py
,
"#include
\"
Context-%s.h
\"\n\n
"
,
fv_no_underscore
);
free
(
fv_no_underscore
);
}
fprintf
(
user_code_py
,
"def %s_startup():
\n
"
,
fv
->
name
);
fprintf
(
user_code_py
,
" # Write your initialization code here,
\n
"
" # but do not make any call to a required interface.
\n
"
" pass
\n
"
"
\n\n
"
);
}
}
/* Creates user_code.h, and if necessary user_code.c (if it did not exist) */
int
Init_MicroPython_GW_Backend
(
FV
*
fv
)
{
char
*
path
=
NULL
;
char
*
filename
=
NULL
;
if
(
NULL
!=
fv
->
system_ast
->
context
->
output
)
{
build_string
(
&
path
,
fv
->
system_ast
->
context
->
output
,
strlen
(
fv
->
system_ast
->
context
->
output
));
}
build_string
(
&
path
,
fv
->
name
,
strlen
(
fv
->
name
));
build_string
(
&
filename
,
fv
->
name
,
strlen
(
fv
->
name
));
build_string
(
&
filename
,
".h"
,
strlen
(
".h"
));
filename
[
strlen
(
filename
)
-
1
]
=
'p'
;
/* change from .c to .p */
build_string
(
&
filename
,
"y"
,
1
);
/* change from .p to .py */
if
(
!
file_exists
(
path
,
filename
))
{
printf
(
"MicroPython: creating fresh skeleton %s/%s
\n
"
,
path
,
filename
);
create_file
(
path
,
filename
,
&
user_code_py
);
}
free
(
path
);
micropython_skel_preamble
(
fv
);
return
0
;
}
void
close_micropython_skel_files
()
{
close_file
(
&
user_code_py
);
}
/* Add a Provided interface. Can contain in and out parameters
* Write in user_code.h the declaration of the user functions
* and if user_code.c is new, copy these declarations there too.
*/
void
add_PI_to_MicroPython_skel
(
Interface
*
i
)
{
if
(
NULL
==
user_code_py
)
return
;
char
*
signature_py
=
make_string
(
"def %s_PI_%s("
,
i
->
parent_fv
->
name
,
i
->
name
);
char
*
sep_py
=
make_string
(
",
\n
%*s"
,
strlen
(
signature_py
),
""
);
bool
comma
=
false
;
fprintf
(
user_code_py
,
"%s"
,
signature_py
);
#if 0
// This code generates type hints for the parameters, but need to have the identifiers defined as globals first...
FOREACH (p, Parameter, i->in, {
fprintf(user_code_py, "%sIN_%s : asn1Scc%s",
comma ? sep_py : "", p->name, p->type);
comma = true;
});
FOREACH (p, Parameter, i->out, {
fprintf(user_code_py, "%sOUT_%s : asn1Scc%s",
comma ? sep_py : "", p->name, p->type);