– Typee Documentation –

3 – Typee Language Description

3.14 – Embedding code

We explain here what are the few constraints imposed by Typee when writing targeted code that is embedded into Typee code.

3.14.1 embed statement reminder

A semi-formal EBNF specification of its syntax is:

<embed statement>      ::= 'embed' <languages>
                               ( <dotted name> ';' | <embedded native code> )
                               ['exit']

<language>             ::= 'android' | 'java' | 'cpp' | 
                            'cs' | 'csharp' | 'py' | 'python'

<languages>            ::= <language> ( ',' <language> )*

<embedded native code> ::= '{{' ( <any code chars but '}}' > )* '}}'

This is not a truly formal LL(1) EBNF specification, but trust us, it can very easily be transformed in a legal one. The advantage of its formulation this way is that it is far easier to understand.

Keyword exit can be added at the end of the statements block of an embed clause. The use of this is that, when translating a Typee portion of code that contains embedded native code, once this native code has been put as-is in the created translation file nothing after this exit will be inserted in the created file until the end of the currently translated portion of Typee code.
See example of use in Typee built-in library Thread, for instance. You will find this extensively used in module base_thread.ty for instance.

You will have noticed that android is an allowed language. Well, Android is not a programming language but it is still defined as being one just to distinguish Java and Java for Android. You will find examples of its use in Typee built-in libraries – see module time.ty in library Time, for instance.

Let’s provide a few examples.

const uint32 NB = 16;
array<int32>[NB] my_data;

embed cpp {{
for( int *ptr=my_data; ptr < my_data+NB; )
    *ptr++ = 0;
}}

embed java, android {{
for( int i=0; i < NB; i++ )
    my_data[i] = 0;
}}

embed python {{
my_data = [0]*NB
}}

my_data[1] = 1;
print( my_data );  // prints 0 1 0 ... 0
const int32 NB = 16;
array<int32>[NB] my_data;

embed cpp     zero_set.cpp;        // (all of these  native  code
embed java    zero_set.java;       //  source files being present
embed python  zero_set.py;         //  in the 'current' directory)

my_data [1] = 1;
print( my_data );  // prints 0 1 0 ... 0

3.14.2 External code accessibility

At translation time, any embedded code will be put as-is in the created module that contains it. This is the reason why any entity declared or defined outside and before an embed statements block will be known of the embedded code after translation, and either at compilation or interpretation time.

See exemples at end of this sub-section.

3.14.3 Internal code accessibility

Meanwhile, any entity declared or defined within some embedded statements block will be visible from every other embedded statements block of same or lower visibility level since the whole code of all those embedded statements blocks will be inserted as-is in the finally created modules of the same targeted programming language.

But, any entity declared or defined within an embedded statements block will not be visible from Typee code outside this embedded statements block. Indeed, embedded code is not parsed by Typee translators (this would need to get parsers for every targeted languages). So, embedded declarations or definitions are not be visible in Typee code outside of embedded code a translation-time.

It is nevertheless easy to workaround this issue: entities to be declared within embedded targeted code can always be declared outside embedded statements blocks, within Typee code. This way, type checking will still be possible also in Typee code.

See exemples at end of this sub-section.

3.14.4 No internal type checking

Since embedded targeted code is not parsed, no type checking is taking place into embedded targeted code. Programmers should then be very cautious with this, type checking being not possible before compilation- or interpretation- time.

3.14.5 Python internal indentation

Embedded targeted code being inserted in created modules, at translation-time, Python programmers are strongly recommended to be very cautious about their embedded code indentation. For instance:

  • when embedding code at module level, no indentation should appear in Python embedded code;
  • when embedding code within a function or method definition, one level of indentation should be added to the function and method indentation level;
  • the same indentation level adding is true also for compound statements such as if, while, for, try, case clauses and the like.

See exemples at end of this sub-section.

3.14.5 Examples

Next are few examples, proposed for illustration of the embed concept.

// some Typee code
// ...

embed cpp, java, android {{
long val = 15;
}}

// some other Typee code
// ... no access to val would be valid here!
int32 val2 = 16;

embed cpp, java, android {{
val2 += val1;  // legal!
}}

print( val2 );  // prints: 31
none my_print( ... args ){
    for( int32 index, ? arg in indexed args ) {
    
      embed python{{
        # mind the 2x4 spaces indentation here!
        print( arg, end=', ' if index < len(args)-1 else '\n' )
      }}
    
    }
}

my_print( 1, 2, 3, "sun" );
// prints:  1, 2, 3, sun  -- well, when translated into Python

3.14.6 Examples of translated code

This is only for illustration purpose. We show here the created files and modules for different targeted programming languages, for the built-in function time() of the built-in library Time.

Here is the Typee code of this function:

/***
Copyright (c) 2018-2019 Philippe Schmouker, schmouk (at) typee.ovh

Permission is hereby granted,  free of charge,  to any person obtaining a copy
of this software and associated documentation files (the "Software"),  to deal
in the Software without restriction, including  without  limitation the rights
to use,  copy,  modify,  merge,  publish,  distribute, sublicense, and/or sell
copies of the Software,  and  to  permit  persons  to  whom  the  Software  is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS",  WITHOUT WARRANTY OF ANY  KIND,  EXPRESS  OR
IMPLIED,  INCLUDING  BUT  NOT  LIMITED  TO  THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT  SHALL  THE
AUTHORS  OR  COPYRIGHT  HOLDERS  BE  LIABLE  FOR  ANY CLAIM,  DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  TORT OR OTHERWISE, ARISING FROM,
OUT  OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
***/

//=============================================================================
// These are the available functions in this module:
fwd float32  time();  // System elapsed time


//=============================================================================
// Targeted languages specificities
embed python {{
import time as py_time
}}

embed cpp {{
#include <chrono>
}}

embed java {{
import System;
}}

embed cs {{
}}


//=============================================================================
float32 time() {
    /**
    Returns  current  time  in seconds since January 1, 1970, 00:00:00 (UTC),
    as a 32-bits floating point in fractional seconds.
    
    Starting date as 1970-01-01 is common to most platforms and  systems  but 
    may  differ  on  a few of them.  Windows and Linux programmers should not
    experience big surprises with this.
    It may be also that some systems provide time with 1 second as precision.
    */
  embed python {{
    return py_time.time()
  }}

  embed cpp {{
    using namespace std::chrono;
    chrono::duration_cast sys_time = chrono::system_clock::now().time_since_epoch();
    return (float)sys_ticks.count() * system_clock::period::num / system_clock::period::den;
  }}

  embed java, android {{
    return (float)System.currentTimeMillis() * 1.0e-3;
  }}

  embed cs {{
    return (float)( DateTime.FromUnixTimeMilliseconds( DateTime.now ).ticks * 1.0e-7 );
  }}
}
3.14.6.1 Python translation

When translating the above Typee module, the Python translator creates the next translated module in package Libs.Time with name time.py:

#!/usr/bin/env python 
# -*- coding: utf-8 -*-
"""
Copyright (c) 2018-2019 Philippe Schmouker, schmouk (at) typee.ovh

Permission is hereby granted,  free of charge,  to any person obtaining a copy
of this software and associated documentation files (the "Software"),  to deal
in the Software without restriction, including  without  limitation the rights
to use,  copy,  modify,  merge,  publish,  distribute, sublicense, and/or sell
copies of the Software,  and  to  permit  persons  to  whom  the  Software  is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS",  WITHOUT WARRANTY OF ANY  KIND,  EXPRESS  OR
IMPLIED,  INCLUDING  BUT  NOT  LIMITED  TO  THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT  SHALL  THE
AUTHORS  OR  COPYRIGHT  HOLDERS  BE  LIABLE  FOR  ANY CLAIM,  DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  TORT OR OTHERWISE, ARISING FROM,
OUT  OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
"""

#=============================================================================
# These are the available functions in this module:
# def time() -> float  // System elapsed time

#=============================================================================
# Targeted languages specificities
import time as py_time

#=============================================================================
def time() -> float:
    """
    Returns  current  time  in seconds since January 1, 1970, 00:00:00 (UTC),
    as a 32-bits floating point in fractional seconds.
    
    Starting date as 1970-01-01 is common to most platforms and  systems  but 
    may  differ  on  a few of them.  Windows and Linux programmers should not
    experience big surprises with this.
    It may be also that some systems provide time with 1 second as precision.
    """
    return py_time.time()
3.14.6.2 C++ translation

When translating the above Typee module, the cpp translator creates the two next translated modules in directory Libs.Time with name time.h for the header and time.cpp for the source code:

time.h:

/**
Copyright (c) 2018-2019 Philippe Schmouker, schmouk (at) typee.ovh

Permission is hereby granted,  free of charge,  to any person obtaining a copy
of this software and associated documentation files (the "Software"),  to deal
in the Software without restriction, including  without  limitation the rights
to use,  copy,  modify,  merge,  publish,  distribute, sublicense, and/or sell
copies of the Software,  and  to  permit  persons  to  whom  the  Software  is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS",  WITHOUT WARRANTY OF ANY  KIND,  EXPRESS  OR
IMPLIED,  INCLUDING  BUT  NOT  LIMITED  TO  THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT  SHALL  THE
AUTHORS  OR  COPYRIGHT  HOLDERS  BE  LIABLE  FOR  ANY CLAIM,  DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  TORT OR OTHERWISE, ARISING FROM,
OUT  OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/

//=============================================================================
// These are the available functions in this module:
// float time()  // System elapsed time

//=============================================================================
// Targeted languages specificities
#include <chrono>

//=============================================================================
float time();
    /**
    Returns  current  time  in seconds since January 1, 1970, 00:00:00 (UTC),
    as a 32-bits floating point in fractional seconds.
    
    Starting date as 1970-01-01 is common to most platforms and  systems  but 
    may  differ  on  a few of them.  Windows and Linux programmers should not
    experience big surprises with this.
    It may be also that some systems provide time with 1 second as precision.
    */

time.cpp:

/**
Copyright (c) 2018-2019 Philippe Schmouker, schmouk (at) typee.ovh

Permission is hereby granted,  free of charge,  to any person obtaining a copy
of this software and associated documentation files (the "Software"),  to deal
in the Software without restriction, including  without  limitation the rights
to use,  copy,  modify,  merge,  publish,  distribute, sublicense, and/or sell
copies of the Software,  and  to  permit  persons  to  whom  the  Software  is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS",  WITHOUT WARRANTY OF ANY  KIND,  EXPRESS  OR
IMPLIED,  INCLUDING  BUT  NOT  LIMITED  TO  THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT  SHALL  THE
AUTHORS  OR  COPYRIGHT  HOLDERS  BE  LIABLE  FOR  ANY CLAIM,  DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  TORT OR OTHERWISE, ARISING FROM,
OUT  OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/

//=============================================================================
// These are the available functions in this module:
// float time()  // System elapsed time

//=============================================================================
// Targeted languages specificities
#include "time.h"

//=============================================================================
float time() {
    /**
    Returns  current  time  in seconds since January 1, 1970, 00:00:00 (UTC),
    as a 32-bits floating point in fractional seconds.
    
    Starting date as 1970-01-01 is common to most platforms and  systems  but 
    may  differ  on  a few of them.  Windows and Linux programmers should not
    experience big surprises with this.
    It may be also that some systems provide time with 1 second as precision.
    */
    using namespace std::chrono;
    chrono::duration_cast sys_time = chrono::system_clock::now().time_since_epoch();
    return (float)sys_ticks.count() * system_clock::period::num / system_clock::period::den;
}
3.14.6.3 Java translation

When translating the above Typee module, the Java translator creates the next translated module in package Libs.Time with name time.java:

/***
Copyright (c) 2018-2019 Philippe Schmouker, schmouk (at) typee.ovh

Permission is hereby granted,  free of charge,  to any person obtaining a copy
of this software and associated documentation files (the "Software"),  to deal
in the Software without restriction, including  without  limitation the rights
to use,  copy,  modify,  merge,  publish,  distribute, sublicense, and/or sell
copies of the Software,  and  to  permit  persons  to  whom  the  Software  is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS",  WITHOUT WARRANTY OF ANY  KIND,  EXPRESS  OR
IMPLIED,  INCLUDING  BUT  NOT  LIMITED  TO  THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT  SHALL  THE
AUTHORS  OR  COPYRIGHT  HOLDERS  BE  LIABLE  FOR  ANY CLAIM,  DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  TORT OR OTHERWISE, ARISING FROM,
OUT  OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
***/

//=============================================================================
// These are the available functions in this module:
// float  time();  // System elapsed time


//=============================================================================
// Targeted languages specificities
import System;


//=============================================================================
float time() {
    /**
    Returns  current  time  in seconds since January 1, 1970, 00:00:00 (UTC),
    as a 32-bits floating point in fractional seconds.
    
    Starting date as 1970-01-01 is common to most platforms and  systems  but 
    may  differ  on  a few of them.  Windows and Linux programmers should not
    experience big surprises with this.
    It may be also that some systems provide time with 1 second as precision.
    */
    return (float)System.currentTimeMillis() * 1.0e-3;
}
3.14.6.4 C# translation

When translating the above Typee module, the C# translator creates the next translated module in package Libs.Time with name time.cs:

/***
Copyright (c) 2018-2019 Philippe Schmouker, schmouk (at) typee.ovh

Permission is hereby granted,  free of charge,  to any person obtaining a copy
of this software and associated documentation files (the "Software"),  to deal
in the Software without restriction, including  without  limitation the rights
to use,  copy,  modify,  merge,  publish,  distribute, sublicense, and/or sell
copies of the Software,  and  to  permit  persons  to  whom  the  Software  is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS",  WITHOUT WARRANTY OF ANY  KIND,  EXPRESS  OR
IMPLIED,  INCLUDING  BUT  NOT  LIMITED  TO  THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT  SHALL  THE
AUTHORS  OR  COPYRIGHT  HOLDERS  BE  LIABLE  FOR  ANY CLAIM,  DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  TORT OR OTHERWISE, ARISING FROM,
OUT  OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
***/

//=============================================================================
// These are the available functions in this module:
// float32  time();  // System elapsed time


//=============================================================================
// Targeted languages specificities


//=============================================================================
float time() {
    /**
    Returns  current  time  in seconds since January 1, 1970, 00:00:00 (UTC),
    as a 32-bits floating point in fractional seconds.
    
    Starting date as 1970-01-01 is common to most platforms and  systems  but 
    may  differ  on  a few of them.  Windows and Linux programmers should not
    experience big surprises with this.
    It may be also that some systems provide time with 1 second as precision.
    */
    return (float)( DateTime.FromUnixTimeMilliseconds( DateTime.now ).ticks * 1.0e-7 );
}

3.14.7 Conclusion

This completes the documentation on embedded code.

 
Next section formerly explains the Typee built-in containers.

< previous (3.13 exceptions) | (3.15 typee strings) next >