--------- COP C-like compiler for NXT lego ROBOT -------

28th of August 2007 – v1.2

 

 

 

New :

-        partial enrichment  of the “programming guide

-        optimized management of library, only functions that are called are generated

-        enrichment of the sound library

-        several bugs are fixed, see : 11 – Fixed bugs

-        all error messages are now translated in English

-        entire translation of the GUI in English

 

Go to the table of contents :

Go to Download section :

 

_________________________________________________________________________________________________________________________________________________________

Introduction :

 

Find in this WEB page, explanations about a C-like COP compiler dedicated to the NXT Lego ROBOT.

I have started this project 6 months ago, and  I have not enough time to work on it, so it is still an ongoing project J

 

To be quite honest, I have not built any robots, and my son ( 5 years old ) looks at the mountain of pieces and asks :“Daddy, when are you building this robot ?”  and I always answer : “When this compiler is finished !”. I guess he doesn’t understand why.

 

Sources of this compiler are free, that is to say that anybody can reuse, and modify this compiler. I don’t know if this compiler can be useful for other people ...

 

To help other developers, this web page intends to give enough information to make this compiler a reusable source.

 

This WEB page and compiler are beta-versions, many remaining issues are to be completed, especially :

-        a complete specification of code patterns

-        lot of bugs to be discovered !!! J

-        automated generation of code to allocate memory for arrays

-        a complete library

-        a library dedicated to mathematic function to be developed

-        and so many other stuffs like that

 

Find below explanations concerning this compiler and files to be downloaded.

 

Do not hesitate to send me an email to reports bugs of the compiler and or any comments on this web page to :

 

__________________________________________________________________________________________________________________________________________________________

 

Below a list of favourite links :

 

Web sites :

 

Lego WEB site :

http://mindstorms.lego.com/Overview/NXT_Software.aspx

Extensions of NXT :

 http://www.philohome.com/nxt.htm

National Instrument tool kit :

http://www.ni.com/academic/mindstorms/

A Web site where you can purchase NXT robots :

http://www.robopolis.com/produit/2474/20/Robots-programmables/MINDSTORMS-NXT-V41.php

NBC compiler, which is the code generated by COP compiler :

http://bricxcc.sourceforge.net/nbc/

An assembly language fot NXT :

http://users.ece.utexas.edu/~valvano/assmbly/syntax.htm

More sensors for NXT :

http://www.mindsensors.com/index.php?module=pagemaster&PAGE_user_op=view_page&PAGE_id=57&MMN_position=24:24

Robots developed for computer science training course, in the RENNES university (IFSIC, I am a former student of IFSIC ;-)) :

http//www.irisa.fr/caps/people/puaut/Mindstorm/TPMindstorm.html#TP4

Bricx Command Center 3.3 :

http://bricxcc.sourceforge.net/nbc/

NBC Debugger :

http://nxtasy.org/2006/11/29/nbc-debugger-for-nxt/

Other tools :

http://www.lysator.liu.se/~nisse/lego-nxt-dev/

Debugger for NXT :

http://www.sorosy.com/lego/nxtdbg/

 

 

Forum :

 

        French Forum : http://www.vieartificielle.com/forum/

        English/American Forum : http://thenxtstep.com/forums.html

        French WEB site dedicated to LEGO  : http://www.freelug.org/

English/American Forum : http://forums.nxtasy.org

Lego Forum : http://messageboards.lego.com/ShowForum.aspx?ForumID=1042

POB-Technology, a company dedicated to robots : http://pob-technology.com/

__________________________________________________________________________________________________________________________________________________________

 

 

1- What is COP compiler ?

2- Installation guide

3- User manual

4- Grammar implemented in COP compiler

5 –Programming guide

        5.1 Task

        5.2 Function

        5.3 Types and structures

        5.4 Expression

5.5 Variable

5.6 Assigment

5.7 If

        5.8 For, continue and break

        5.9 While

        5.10 Switch

5.11 Return

5.12 Arrsize

        5.13 Arrinit

        5.14 Arrsubset

        5.15 Arrbuild

        5.16 Precedes

        5.17 Label and Goto

        5.18 Inline

        5.19 Mutex, acquire & Release

6- How COP compiler works

-        6.1 Principles

-        6.2 Data model

-        6.3 Lexical parsing

-        6.4 Syntax parsing

1.   Principles

2.   Top-Down analysis

3.   Bottom-Up analysis

4.   Comments on the syntax parsing in the COP compiler

1.   Example of the for loop

2.   Dedicated grammar for operators

3.   Mapping between rules and C functions

-        6.5 Code generation

1.   Principles :

2.   Mapping between C structures and code generation functions  :

3.   Code generation patterns :

7 - libraries

8 – Examples of COP sources

9 – Errors 

10 – Download section : sources, files and executable  

11 – Fixed bugs :

12 - Annexes

 

__________________________________________________________________________________________________________________________________________________________

 

1 – What is COP compiler :

 

For X-mas, I got a Lego NXT robot. As I am a lazy guy, I do not want to code NBC instructions. So I decided to write my own C-like compiler which generates NBC codes. For people which are familiar with the C language syntax, I guess they won’t be destabilized by COP compiler.

 

This compiler is fully open, it means that you can enrich it in term of functions or data or enrich its library as well, C sources are downloadable.

 

As I am not a very good programmer, the C code is not commented ( few comments are in French ) but in section 5, I try to give enough information for a better understanding. Moreover, I have fixed a huge number of bugs, but I am quite sure there are still lot of  bugs to be discovered and fixed. Do not hesitate to report bugs.

 

This compiler is compiled with lcc compiler ( http://www.cs.virginia.edu/~lcc-win32/ ) and use an external library (dislin : http://www.mps.mpg.de/dislin/).

 

To complete this introduction, as you can read ( see ) , I am French and English is not my native language, so do not hesitate to report me all  misunderstandings due to my poor English.

 

__________________________________________________________________________________________________________________________________________________________

 

2- Installation guide

 

The installation is quite simple :

 

1) Create a directory named “COP” and copy “cop.exe” in this directory ( see executable file  )

2) Create a sub-directory named “source”

3) Create a sub-directory  of “source” named “lib” and copy all library files in this directory (see 6 - Libraries )

4) If you want to use COP source examples, copy these files in the “source” directory ( see 7 - Example of COP sources )

5) Create you own COP sources in the “source” directory.

 

The directory tree must look as below :

 

COP --+

            + cop.exe

            +  source -- +

        + COP files eg. essai_librairie_def.cop.txt

                                + lib -- +

                                           + display.cop.lib

                                           + file.cop.lib

                                            + motor.cop.lib

                                            + sensor.cop.lib

                                            + sound.cop.lib

        + string.cop.lib

                                           + system.cop.lib 

 

Or download the package : 10 – Download section : sources, files and executable

__________________________________________________________________________________________________________________________________________________________

 

3- User manual

 

The use of COP compiler is quite simple.

The only thing you have to do is to execute cop.exe.

 

Below this window will be displayed :

 

 

The selection of the “exit” menu  will end the program.

The selection of the “help” menu will show you the current version of COP compiler.

The selection of file will offer you a dedicated window to select the cop file you want to compile.

 

The following options are offered :

            - Syntax Parsing traces : if selected, the entire syntax parsing is traced in the text window.

            - Syntax tree, types and variables : if selected, the entire syntax tree which is the result of the parsing step is displayed in the text window.

            - Code generation traces : If selected, traces will be added in the target .nbc file.

            - Automatic generation mutex : If selected, mutexes are automatically declared and invoked to protect accesses to all functions.

 

To compile the only thing you have to do, is to press the “OK” button.

 

 

 _____________________________________

 COP Compiler v.1.2 / 28 th August 2007

 Author : Olivier POURCHER

 _____________________________________

 

 

 

 PASS #1 : pre-processing ( defines lexical parsing of define completed

 Lexical parsing of define completed : D:\DELTA\lcc1\source\essai_sound.cop.txt - 68 lines

 Lexical parsing of define completed : lib\display.cop.lib.txt - 123 lines

 Lexical parsing of define completed : lib\file.cop.lib.txt - 118 lines

 Lexical parsing of define completed : lib\motor.cop.lib.txt - 115 lines

 Lexical parsing of define completed : lib\sensor.cop.lib.txt - 181 lines

 Lexical parsing of define completed : lib\sound.cop.lib.txt - 154 lines

 Lexical parsing of define completed : lib\string.cop.lib.txt - 55 lines

 Lexical parsing of define completed : lib\system.cop.lib.txt - 74 lines

 PASS #1 : Successfully completed / 117 'defines' parsed

 

 

 

 

 PASS #2 : Lexical parsing of libraries and module to be compiled

 Lexical parsing completed : lib\display.cop.lib.txt - 123 lines

 Lexical parsing completed : lib\file.cop.lib.txt - 118 lines

 Lexical parsing completed : lib\motor.cop.lib.txt - 115 lines

 Lexical parsing completed : lib\sensor.cop.lib.txt - 181 lines

 Lexical parsing completed : lib\sound.cop.lib.txt - 154 lines

 Lexical parsing completed : lib\string.cop.lib.txt - 55 lines

 Lexical parsing completed : lib\system.cop.lib.txt - 74 lines

 PASS #2 : Successfully completed

 PASS #2 : Lexical parsing completed : D:\DELTA\lcc1\source\essai_sound.cop.txt  - 68 lines

 

 

 

 PASS #3 : Syntax parsing of libraries and module to be compiled

 End of parsing of global variables

 -------> module lib\file.cop.lib.txt line 31 ::

[Warning Error #SX0675: Types not compatible in expression ] token = )

 -------> module lib\file.cop.lib.txt line 39 ::

[Warning Error #SX0675: Types not compatible in expression ] token = )

 End of parsing of functions and tasks

 compiled line = 68

 # of types =12

 # of variables = 89

 # of functions = 47

 # of tasks = 1

 PASS #3 : Successfully completed

 PASS #3 : Syntax parsing completed D:\DELTA\lcc1\source\essai_sound.cop.txt - total compiled lines = 888

 

 

 

 PASS #4 : Code generation of libraries (only those called) and module to be compiled

 Code generation completed D:\DELTA\lcc1\source\essai_sound.cop.txt

 PASS #4 : Successfully completed

 

 

 Press a key to terminate D:\DELTA\lcc1\source\essai_sound.cop.txt

 

__________________________________________________________________________________________________________________________________________________________

 

4- Grammar implemented in COP compiler

 

Find below a description of the grammar of the COP language.

 

<Program> ->  [ <define declaration> | <struct declaration> | <variable declarations>| <mutex declarations>   | <function> | <task> ]0..n

<define declaration> -> define  <ident>  <text>

 

<struct declaration> -> struct { < field definition >1..n };

<field definition> -> <type> <list of fields>

<list of fields> -> <field> , <list of fields> | <field> ;

<field> -> [*]0|1 <ident> [ [<integer>] ] 0..n

 

<variable declarations> -> <type> <list of variables>

<list of variables> -> <variable> , <list of variables> | <field> ;

<variable> -> [*]0|1 <ident> [ [<integer>] ] 0..n [= <init>]0|1

<init> -> <numeric value> | <string>

<type> -> char | schar | byte | int | sint | long | slong | <ident type>

<list of mutex> -> <mutex> , <list of mutex> | <mutex> ;

< mutex> -> mutex <ident>

 

<ident type> -> <generic ident >

<ident > -> <generic ident >

 

<function> -> <ident> ( <list of parameters> )  < body > |

          < return value > <ident> ( <list of parameters> | void  ) < body >

<list of parameters>  -> <list of parameters> ,<parameter> | <parameter>

<parameter> -> [ mod ] 0|1  <type> [*]0|1 <ident>

<return value> -> void | <type>

<task> -> task  <ident> ( ) < body >

 

<body> -> {  [<variable declarations>] 0|1  [<instruction>]0..n  }

<instruction> -> <assignment> |

                         <for loop> |

                        <do while loop> |

                        <if then else> |

                        <switch> |

                        <goto> |

                        <label> |

                        <continue> |

                        <break> |

                         <exit> |

<return> |

<acquire> |

<release> |

<precedes> |

<arrinit> |

<arrsize> |

<arrbuild> |

<arrsubset> |

<inline> |

< function call> ;

 

<assignment> -> [ [*( <ident> + <expr> ) | <ident assign> ] [=  <expr> ; ] 0|1    |  <ident> ++; | <ident> -- ;

<for loop> -> for ( [ <affectation> ] 0..1   ;  [<expr>] 0..1  ; <affectation> ] 0..1   ) <body instruction>

<do while loop> -> do {  [<instruction>]0..n  } while ( <expr>   ) ;

<if then else> -> if ( <expr> ) <body instruction> [ else <body instruction>  ] 0..1 

<switch> -> switch ( <expr> ) { [< switch body>]0..1  }

<switch body> -> case <expr> :  [<body instruction>] 0..1  [break ; ] 0..1 |

    default  : [<body instruction>] 0..1 

<goto> -> goto  <ident> ;

<label> -> <ident> :

<continue> -> continue ;

<break> -> break ;

 <exit> -> exit ( ) ; 

<return> -> return ( expr ) ;

<acquire> -> acquire ( <ident> ) ;

<release> -> release ( <ident> ) ;

<precedes>-> precedes <list of tasks> ;

<list of tasks> -> <list of tasks> , <ident> | <ident>

<arrinit> -> arrsubset ( <ident>, <expr>, <expr> ) ;

<arrsize> -> arrssize ( <ident>, <ident> ) ;

<arrbuild> -> arrsbuild (  <list of arrays> ) ;

<list of arrays> -> <list of arrays> , <ident> | <ident>

<arrsubset> -> arrsubset ( <ident>, <ident>, <expr>, <expr> ) ;

<inline> -> inline “<text>” ;

 

<body instruction> -> {  [<instruction>]0..n  } |

<instruction>

 

 

<expr>  -> [ <expr rec ou>  ] 0..1  

<expr rec ou>  -> <expr rec et>  | <expr rec et>  || <expr rec ou> 

<expr rec et>  -> <expr rec comp>  | <expr rec comp>  && <expr rec et> 

<expr rec comp>  -> <expr rec arith>  | <expr rec arith> [ ==| != |  >|  <|  <=|  >=  ] <expr rec comp> 

<expr rec arith>  -> <expr rec>  | <expr rec>  [  + | - |  | ] <expr rec arith> 

<expr rec>  -> <expr rec shr shl>  | <expr rec shr shl>  [  & | /  | *  | % ]  <expr rec> 

<expr rec shr shl>  -> <expr rec not>  | <expr rec not >  [  >> | <<  ]   <expr rec shr shl > 

<expr rec not>  -> <expr rec neg>  | ! <expr rec neg >

<expr rec neg>  -> <expr rec atom>  | -  <expr rec atom >

<expr rec atom>  -> <atom> | <var func> | (<expr rec ou>   )

<var func> - > <ident assign>| <function call>

 

<ident assign>-> <ident>  |

                           <ident> ++ ; |

                           <ident>  --  ; |

   <ident> [ . <ident assign> ] 1..n   | 

                          <ident> [ [<expr> ] ] 1..n  

 

<function call> -> <ident> (  [< list of function parameters>]0..1   )

< list of function parameters> -> < list of function parameters> , <expr> | <expr>

 

<atom> -> <numeric value> | <string>

<generic ident > ->  [a..z] | [A..Z] [[a..z] | [A..Z] | [0..9] | _ ] 0..n

<string> -> [all ASCII code] 0..n

<numeric value> -> <binary>  | <hexa>  | <decimal>

<binary> -> 0b [0|1] 1..n

<hexa> -> 0x [ [0|1] | [ [A..F] | [a..f] ] ] 1..n

<decimal>-> [0..9]  [0..9] 1..n

<text> -> [all ASCII code] 0..n

 

__________________________________________________________________________________________________________________________________________________________

 

5- Programming guide

 

5.1 Task

 

Downloadable example

 

A COP program contains at least one task which is called ‘main’. This is the entry point of the program. Several tasks can be defined and launched, see precedes.

These tasks can be executed in parallel.

 

Below an example of program :

 

task tache1()

 {

 }

 

 

task tache2()

 {

 }

 

task main()

 {

            precedes tache1,tache2;

 }

 

5.2 Function

 

downloadable example

 

A COP program can contain several functions. Some of these functions are defined in libraries, eg. COP_wait() and cannot be double defined.

As they are not really  local variables  ( they are emulated by the COP compiler ), mutex can be automatically generated at complie time to have a one and only one call at a given time.

 

A function is composed of 4 parts : < return value > <ident> ( <list of parameters>) < body >

 

            - type of returned value, if exists :

                        - the type can be void if no value are returned

                        - the type can be an atomic ‘type’ or structure

            - identifier of the function

            - parameters

                        - parameters can be passed by value or can be modified  ( mod )

            - body of the function

                        - the body contains a set of instruction and local variables ( see variables )

 

Example1 :

 

void ffff()

 {

 }

 

task main()

 {

            ffff();

 }

 

example 2 :

 

int abcdefgh ()

 {

            return(1);

 }

 

task main()

 {

            int v;

           

            v=abcsdefgh();

 }

 

example 3 :

 

 

struct COORD

 {

            int x;

            int y;    

 };

 

struct LINE

 {

            COORD ext1;

            COORD ext2;

 };

 

int ff(mod int g, int k,mod int x,mod COORD z)

 {

            int a,b,c,d:

 

            g=1;

            x = 0;

            z.x=1;

            z.y=2;

 }

 

task main()

 {

            int a,b,c;

            LINE line1;

            COORD point;

           

            c=ff(a,b,line.ext1.x,point);       

 }

5.3 Types and structures

 

downloadable example :

 

Cop program can define data types and structures.

 

Atoms :

            byte     unsigned 8 bits

            char     unsigned 8 bits

            schar   signed 8 bits

            int        unsigned 16 bits

            sint      signed 16 bits

            long     unsigned 32 bits

            slong   signed 32 bits

 

<type> -> char | schar | byte | int | sint | long | slong | <ident type>

 

Nota : float is not available, this type is not supported by the NXT. I am writing a library dedicated to “float an mathematic functions ( cos, sin, … ).

Nota : bollean type doesn’t exist, but can be replaced by a byte variable, 0 is ‘FALSE’, all other values (>0) are ‘TRUE’.

 

Pointers:

Pointers are used to handle arrays which are passed as ‘reference’ parameters in function.

 

<parameter> -> [ mod ] 0|1  <type> [*]0|1 <ident>

 

Arrays :

Arrays are scalar types. Arrays can be applied to atom or structures. Arrays can be multi-dimensional, COP compiler support up to 10 dimensions.

These dimensions are used to address the exact memory location.

Strings are defined as arrays of  char, eg.  char String[10]. Strings must be terminated by a null  byte.

 

<variable> -> [*]0|1 <ident> [ [<integer>] ] 0..n [= <init>]0|1

 

Nota : If arrays are passed by ‘reference’ in a called, they must be then used as pointer in the called function.

 

Structures :

A structure is set of fields which are gathered into a one and only one structure. A structure can contains, atoms, arrays, structures or arrays of structures.

 

<struct declaration> -> struct { < field definition >1..n };

<field definition> -> <type> <list of fields>

<list of fields> -> <field> , <list of fields> | <field> ;

<field> -> [*]0|1 <ident> [ [<integer>] ] 0..n

 

Example 1 :

 

struct COORD

 {

            int x;

            int y;    

 };

 

struct LINE

 {

            COORD ext1;

            COORD ext2;

 };

 

LINE line[10];

 

 

void assign(mod int d,int s)

 {

            d=s;

 }

 

void init_line(mod LINE *l,int index, int x1, int y1,int x2,int y2)

 {

            LINE v;

 

            assign(v.ext1.x,x1);     

            assign(v.ext1.y,y1);

           

            v.ext2.x=x2;

            v.ext2.y=y2;

 

            *(l+index)=v;  

 }

 

 

task main()

 {

            int x;

            int valeur;

            char buffer[10];

            LINE v;

 

            inline "arrinit globale_line,0 , 10";

           

COP_DrawText(1,1,"INIT");

            COP_Wait(1000);

 

            x=0;

 

            do

              {

                        init_line(line,x,1,x,60,60-x);

                        x++;

              }

            while(x<10);

           

            for(x=0;x<10;x++)

             {

                        v=line[x];

 

                        COP_LineOut(v.ext1.x, v.ext1.y, v.ext2.x, v.ext2.y, 1);

                        COP_Wait(1000);

             }

           

            COP_DrawText(1,1,"FIN");

            COP_Wait(1000);

 

            COP_LineOut(1, 1, 20, 20, 1);

            COP_Wait(5000);

 }

5.4 Expression

 

downloadable example

 

to be completed

5.5 Variable

to be completed

5.6 Assigment

to be completed

5.7 If

 

downloadable example

 

The if instruction follows this pattern: if ( <expr> ) <body instruction> [ else <body instruction>  ] 0..1 

 

example 1 :

 

if (a==b) k=0;

 

example 2 :

 

if (a==b)

{

k=0;

d=1;

            }         

 

example 3 :

 

if (a==b)

{

k=0;

d=1;

            }

else

            {

k=1;

d=0;

            }         

5.8 For, continue and break

 

downloadable example

 

The for  instruction follows this pattern: for ( [ <affectation> ] 0..1   ;  [<expr>] 0..1  ; <affectation> ] 0..1   ) <body instruction>

The for loop is divided into 3 :

-         initial value

-         logical expression which stops the loop if equal to false, eg. if i =5, (i<4) is evaluated as FALSE

-         incrementation, this assignement change values of variable which are part of the logical expression

 

The ‘break’ instruction ‘jumps’ to next instruction which follows the for loop.

The ‘continue’ instruction ‘jumps’ to the beginning of the for loop but executes the incremental instructions.

 

example 1 :

 

task main()

 {

            int a;

            char chaine[10];

            int inv;

           

            for(a=0;a<10;a++)

             {        

                        if(inv==1)

                         {

                                   inv=1-inv;

                                   continue;

                         }

 

                        inv=1-inv;

             }        

 

            /* test 2 */

 

            for(a=0;;a++)

             {                                           

                        if(a>5) break;

             }

 

 

            /* test 3 */

 

            a=0;

            for(;;)

             {        

                                  

                        if(a>5)  break;

 

                        a++;

             }

5.9 While

 

downloadable example

 

The do/while  instruction follows this pattern: <do while loop> -> do {  [<instruction>]0..n  } while ( <expr>   ) ;

The while loop evaluate a logical expression which stops the loop if equal to FALSE, eg. x<10

The ‘break’ instruction ‘jumps’ to next instruction which follows the for do/while loop.

The ‘continue’ instruction ‘jumps’ to the beginning of the do/while loop but executes the incremental instructions.

 

example 1 :

 

task main()

 {

            int x;

            int valeur;

            char buffer[10];

           

            COP_DrawText(1,1,"AFFICHAGE");

        COP_Wait(1000);

 

            x=0;

 

            do

              {

                        COP_NumtoString(x,buffer);

                        COP_DrawText(1,1,buffer);

                        COP_Wait(1000);

                        x++;

              }

            while(x<10);

 

            COP_DrawText(1,1,"FIN");

        COP_Wait(1000);

 }

5.10 Switch

 

downloadable example

 

5.11 Return

 

downloadable example

 

return is use to return value ( amazing ! ). Return can only be used in functions which return values.

return can contain complex expression, but the return type must comply with the declared type of the function.

 

example 1 :

 

int f(int a,int x,int b)

 {

            return(a*x+b);

 }

 

task main()

 {

            int x;

            int valeur;

            char buffer[10];

           

            COP_DrawText(1,1,"AFFICHAGE");

            COP_Wait(1000);

 

            x=0;

 

            do

              {

                        valeur=f(2,x,3);

                        COP_NumtoString(valeur,buffer);

                        COP_DrawText(1,1,buffer);

                        COP_Wait(1000);

                        x++;

              }

            while(x<10);

 

COP_DrawText(1,1,"FIN");

            COP_Wait(1000);

 }

5.12 Arrsize

to be completed

5.13 Arrinit

to be completed

5.14 Arrsubset

to be completed

5.15 Arrbuild

to be completed

5.16 Precedes

downloadable example

to be completed

5.17 Label and Goto

 

downloadable example

 

label and goto are used to jump to a given instruction of the program.

God of programmers never uses the goto instruction, using goto is strictly forbidden ( even in the toilet J).

Obviously , to program a goto, a label must be declared in the code.

 

<goto> -> goto  <ident> ;

<label> -> <ident> :

 

example 1 :

 

/**/

/**/

/**/

/*******************************/

/* this function opens file in */

/* read or write mode          */

/*******************************/

 

byte COP_Fopen(char *name,char *mode)

 {

            inline "dseg segment";

            inline "FO TFileOpen";

            inline "expr_g_byte_tab_COP_Fopen byte[]";

            inline "expr_d_byte_tab_COP_Fopen byte[]";

            inline "expr_g_byte_COP_Fopen byte";

            inline "expr_d_byte_COP_Fopen byte";

            inline "expr_byte_tab_COP_Fopen byte[]";

            inline "inc_COP_Fopen word";

           

            inline "dseg ends";

 

            if(mode=="w")

             {        

                        inline "mov FO.Filename, COP_Fopen_name";

                        inline "mov FO.Length, 100";

                        inline "syscall FileOpenWrite, FO";

                        inline "mov expr_byte_COP_Fopen, FO.FileHandle";

                        goto end_fopen;

             }

            if(mode=="r")

             {

                        inline "mov FO.Filename, COP_Fopen_name";

                        inline "mov FO.Length, 100";

                        inline "syscall FileOpenRead, FO";

                        inline "mov expr_byte_COP_Fopen, FO.FileHandle";

             }

    end_fopen:

 }

 

5.18 Inline

 

downloadable example

 

inline is a very simple and powerful instruction. It can be used to directly low level nbc instructions.

inline’ is also massively used in libraries to make the link between COP functions and nbc libraries.

 

<inline> -> inline “<text>” ;

 

Nota : the text between the two quotes is not parsed.

 

example 1 :

 

/**/

/**/

/**/

/*******************************/

/* this function opens file in */

/* read or write mode          */

/*******************************/

 

byte COP_Fopen(char *name,char *mode)

 {

            inline "dseg segment";

            inline "FO TFileOpen";

            inline "expr_g_byte_tab_COP_Fopen byte[]";

            inline "expr_d_byte_tab_COP_Fopen byte[]";

            inline "expr_g_byte_COP_Fopen byte";

            inline "expr_d_byte_COP_Fopen byte";

            inline "expr_byte_tab_COP_Fopen byte[]";

            inline "inc_COP_Fopen word";

           

            inline "dseg ends";

 

            if(mode=="w")

             {        

                        inline "mov FO.Filename, COP_Fopen_name";

                        inline "mov FO.Length, 100";

                        inline "syscall FileOpenWrite, FO";

                        inline "mov expr_byte_COP_Fopen, FO.FileHandle";

                        goto end_fopen;

             }

            if(mode=="r")

             {

                        inline "mov FO.Filename, COP_Fopen_name";

                        inline "mov FO.Length, 100";

                        inline "syscall FileOpenRead, FO";

                        inline "mov expr_byte_COP_Fopen, FO.FileHandle";

             }

    end_fopen:

 }

5.19 Mutex, acquire & Release

downloadable example

to be completed

 

__________________________________________________________________________________________________________________________________________________________

 

6- How COP compiler works

 

6.1 Principles

C files :

 

The C code is made of 4 C files (see 9 – Download section : sources, files and executable) :

            - cop.c : this is the heart of COP compiler, this module contains the entry point of the program ( main ) and the calls of the four passes.

            - lexical.c : this module focuses on the lexical parsing pass and pre-processing pass

            - syntaxique.c : this module focuses on the syntax parsing pass

            - genere_code.c : this module focuses on the code generation pass

            - delta_encrier.h : this header contains C structures and defines used by COP compiler.

 

4 passes compiler :

 

The COP compiler is a 4 passes compiler :

            - 1) pre-processing pass, which identifies all defines

            - 2) a lexical parsing pass

            - 3) a syntax parsing pass

            - 4) a code generation pass

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


Above, a schema which illustrates flows and main functions of the COP compilers.

 

The first pass, pre-processing, parses all files and stores all defines ( #define <ident> text ).

ð     it generates a table of defines

ð     file : lexical.c

ð     entry point : cop.c :

o       pre-processing : analyse_lexicale_define()

The second pass, lexical parsing, parses all files and identifies a flow of lexem ( +, -, <ident>, for, if, else  … ), if an <ident> is detected and if this <ident> is a ‘define’, it is replaced by its value.

ð     it generates a table of lexems

ð     file : lexical.c

ð     entry point : cop.c : analyse_lexicale()

The third pass, syntax parsing, parses the list of lexems according to the grammar rules specified in the chapter 4- Grammar implemented in COP compiler.

ð     it generates table of structures, table of variables, table of functions, table of tasks, tables of instructions. Those table can be considered as a syntax tree.

ð     file : syntaxique.c

ð     entry point : cop.c : analyse_syntaxique()

The fourth pass, code generation, generates the NBC codes by analysing the syntax tree.

            =>  it generates a NBC target file

ð     file : genere_code.c

ð     entry point : generation_de_code()

 

In the next chapters, main data, and each pass is explained in detailed.

6.2 Data Model

 

Below the data model of the COP compiler.

 

 

 

This table comments the data model :

 

Structure

Array/variable

Index

Semantic

Display/debug function

PROGRAM

PROGRAM program;

 

This variable contains the Variable_globales array.

The principle is that even if we are facing to a local variable of a function or a task, variables are stored in the same table. To find the relevant variable, first, we always try to find it in the function or task and if it is not defined at this level, we assume that it is a global variable.

void analyse_syntaxique(void)

 

printf("\n LISTE DES VARIABLES ");

for(i=0;i<program.nb_vg;i++)

{

printf("\n\n#################################\n VARIABLE %d",i);

affiche_variable(i);

}

TACHE

TACHE tab_tache[MAX_TACHE];

int nb_tache;

This table contains the list of task that are defined in the program.

void analyse_syntaxique(void)

for(i=0;i<nb_tache;i++)

 {

printf("\n\n#################################\n TACHE %d '%s' nb_instruction %d",i,tab_tache[i].ident_tache,tab_tache[i].nb_instruction);

affichage_instruction(tab_tache[i].liste_instruction);

 }

FONCTION

FONCTION tab_fonction[MAX_FONCTION];

int nb_fonction;

This table contains the list of function that are defined in the program

void analyse_syntaxique(void)

printf("\n LISTE DES INSTRUCTIONS ");

 for(i=0;i<nb_fonction;i++)

 {

printf("\n\n#################################\n FONCTION %d '%s' nb_instruction %d ",i,tab_fonction[i].ident_fonction,tab_fonction[i].nb_instruction);

affichage_instruction(tab_fonction[i].liste_instruction);

}

VARIABLE_GLOBALE

See PROGRAM

 

This structure models variable, both global and local variables.

void affiche_variable(int index)

TYPE_VARIABLE

TYPE_VARIABLE tab_type_variable[MAX_TYPE_VARIABLE];

int nb_tab_type_variable;

This structure models types of variables. A type of variable can be :

   - atom ( #define ATOME 1 )

   - array ( #define TABLEAU 2 )

   - array of structure ( #define TABLEAU_STRUCTURE 4 )

   - structure ( #define STRUCTURE 2)

   - field of a structure ( #define CHAMP 5 )

This is a recursive structure.

The void init_type_variable(char *prof_bloc) function defines atom types such as int, char, byte, long, sint, char, sbyte, slong …

void affiche_type(TYPE_VARIABLE *type,int prof)

INSTRUCTION

INSTRUCTION tab_instruction[MAX_INSTRUCTION];

int nb_instruction;

 

This structure models a list of atomic instructions such as an assignment, a for loop …

void affichage_instruction(INSTRUCTION *inst)

INSTRUCTION_ELT

 

 

This union models an atomic instructions such as an assignment, a for loop, an if, …

 

SEXPRESSION

 

 

This structure models binary expression, in other words a node of a binary tree which contains an operator and 2 or 1 argument. Example, < +, sub-exp1,sup-exp2> or <not,sub-exp1,null > or a leaf (feuille in French ).

void affichage_recursif(SEXPRESSION *exp)

FEUILLE

 

 

This union models leaf of tree, which be really a leaf such an integer, a string … but can also be a call of function which contains arguments which are also modelled as expression trees ( eg. f(1+2,3*4 ) ) … but can also be an array variable which contains dimensions which are also modelled as expression trees ( tab[2][f(3-2)][tab1[j*3]] …

See void affichage_recursif(SEXPRESSION *exp)

SATOME

 

 

This structure models a real leaf of an expression tree, it means that it cannot be decomposed. Eg. integer value = 1968

 

SPOINTEUR

 

 

This structure models indirection of a pointer.

 

SVARIABLE

 

 

This structure models variables which can be simple variable such as i or j, or scalar variable such as array ( t[2][i] ) or structures ( a.b.c ).

 

SFONCTION

 

 

This structure models call of function such as  f(1+2,3*4 )

 

SAFFECTATION

 

 

This structure models an assignment of  a variable.

See void affichage_instruction(INSTRUCTION *inst)

SIF

 

 

This structure models the « if » instruction.

void affiche_inst_if(INSTRUCTION *inst)

SFOR

 

 

This structure models the « for » instruction.

void affiche_inst_for(INSTRUCTION *inst)

SBLOC

 

 

 

 

SSWITCH

 

 

This structure models the « switch » instruction.

See void affichage_instruction(INSTRUCTION *inst)

SDO_REPEAT

 

 

This structure models the « do while » instruction.

void affiche_inst_do_while(INSTRUCTION *inst)

SRETURN

 

 

This structure models the « return » instruction.

See void affichage_instruction(INSTRUCTION *inst)

SARRSIZE

 

 

This structure models the « arrsize » instruction.

See void affichage_instruction(INSTRUCTION *inst)

SARRINIT

 

 

This structure models the « arrinit » instruction.

See void affichage_instruction(INSTRUCTION *inst)

SARRSUBSET

 

 

This structure models the « arrsubset » instruction.

See void affichage_instruction(INSTRUCTION *inst)

SARRBUILD

 

 

This structure models the « arrbuild » instruction.

See void affichage_instruction(INSTRUCTION *inst)

SPRECEDE

 

 

This structure models the « precede » instruction.

See void affichage_instruction(INSTRUCTION *inst)

TAB_MUTEX

TAB_MUTEX tab_mutex[MAX_MUTEX];

int nb_mutex;

This structure models mutex ( semaphore ).

void analyse_syntaxique(void)

  for(i=0;i<nb_mutex;i++)

{

printf("\n\n#################################\n MUTEX %d \n ident ='%s' module '%s' ligne '%d' ",

                                                                                              i                tab_mutex[i].ident,

                                                                                              tab_mutex[i].module,

                                                                                              tab_mutex[i].ligne);

}

TAB_DEFINE

TAB_DEFINE tab_define[MAX_DEFINE];

int nb_define;

This structure models defines that are processed during the lexical analysis pre-processing. See Pre-processing pass :

 

ECHANT

ECHANT *Techant;

long nb_echant;

This structure models a lexem, it means an elementary token of the COP language, such as LFOR, LBEGIN (“{“ ), LEND (“=” ), see Lexical parsing :

 

 

6.3 Lexical parsing

 

Pre-processing pass :

 

 

 

 

 

 

 

 

 

 

 

 

 


The entry point is the lexical.c :: analyse_lexicales_define() function.This function calls the lecture_donnees_define() function.

The lecture_donnees_define() function opens the file to be parsed, calls a line after line parsing function named analyse_fichier_ligne_a_ligne_define(), and then closes the file.

The analyse_fichier_ligne_a_ligne_define(), parses line after line the file and store defines in the tab_define[] array ( nb_define is the index ) by invoking the ajout_define() function ( ajout = add in English ).

Lexical parsing :

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


The lexical parsing is far more complex.

Before commenting in detail the C code, below a summary of the lexical parsing principle.

The lexical parsing analyses a flow of ASCII characters and generates a flow of lexems.

 

A lexem is :

-  a keyword  :  for, task , while, define, break … are keywords

- an integer : 123, 0xfffff, 0b0110110 … are integers

- a string : « hello world » … is a string

- an ident : variable_identifier, i, j … are idents

- separators : , ; { } ( ) … are seprators

- operators : + - / * == != .. are operators

All ASCII characters between /* ignored ASCII charecters and */  are ignored. /* */ is used for comments.

All ASCII such as CarriageReturn, Line Feed, Tab … are ignored.

 

In theory, lexems to be recognized can me modelled as a state machine. The principle is to recognize the longer string as possible.

Below a simplified state machine for the COP language :

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


In this state machine, there are states and arrows between states. “Start” is the initial state. LBEGIN, LEND, LENTIER … are “end” states. The current ASCII character is the key used to determine the relevant transition between two states. Actually, in COP compiler, this state machine is hard-coded.

 

The entry point is the lexical.c :: analyse_lexicales() function.This function calls the lecture_donnees() function.

The lecture_donnees() function opens the file to be parsed, calls a line after line parsing function named analyse_fichier_ligne_a_ligne(), and then closes the file.

The analyse_fichier_ligne_a_ligne(), parses line after line the file, skips comments ( /* */ ) and recognized lexems ans stores them in the Techant[] array ( nb_echant is the index ).

 

Example for LBEGIN which is the lexem attached to { :

                                   if(buff[index]=='{')

                                                           {

#ifdef TESTLEX

                                                                       printf(" { [%d] ",nb_echant);

#endif

                                                                       Techant[nb_echant].type_lexeme=LBEGIN;

                                                                       strcpy(Techant[nb_echant].lexeme,"{");

                                                                       Techant[nb_echant].num_ligne=ligne_lu;

                                                                       strcpy(Techant[nb_echant].module,nom_fic);

                                                                       nb_echant++;

                                                               index++;

                                                                       goto fin;

                                                           }

Example for LCOMPEG which is the lexem attached to == :

 

/* LEG         31 /* = */

/* LCOMPEG     20 /* == */

 

 

                                               if(buff[index]=='=')

                                                           {

                                                                       if(buff[index+1]=='=')

                                                                        {

#ifdef TESTLEX

                                                                                  printf(" == [%d] ",nb_echant);

#endif

                                                                                  Techant[nb_echant].type_lexeme=LCOMPEG;

                                                                                  strcpy(Techant[nb_echant].lexeme,"==");

                                                                                  Techant[nb_echant].num_ligne=ligne_lu;

                                                                                  strcpy(Techant[nb_echant].module,nom_fic);

                                                                                  index=index+2;

                                                                                  nb_echant++;

                                                                                  goto fin;

                                                                       }

                                                                       else

                                                                       {

#ifdef TESTLEX

                                                                                  printf(" = [%d] ",nb_echant);

#endif

                                                                                  Techant[nb_echant].type_lexeme=LEG;

                                                                                  strcpy(Techant[nb_echant].lexeme,"=");

                                                                                  Techant[nb_echant].num_ligne=ligne_lu;

                                                                                  strcpy(Techant[nb_echant].module,nom_fic);

                                                                                  index++;

                                                                                  nb_echant++;

                                                                                  goto fin;

                                                                       }

                                                  }

 

Example for LIF which is the lexem attached to if :

 

 

                                               if(         ((buff[index]>='a')&&(buff[index]<='z')) ||

                                                           ((buff[index]>='A')&&(buff[index]<='Z'))

                                                 )

                                                           {

                                                                       char chaine_tempo[1000];

                                                                       int k;

 

                                                                       k=0;

                                                                       for(;(

                                                                            ((buff[index]>='a')&&(buff[index]<='z')) ||

                                                                                   ((buff[index]>='A')&&(buff[index]<='Z')) ||

                                                                            ((buff[index]>='0')&&(buff[index]<='9')) ||

                                                                             (buff[index]=='_'))

                                                                           ;)

                                                                                  {

                                                                                              chaine_tempo[k]=buff[index];

                                                                                              k++;index++;

                                                                                  }

 

                                                                       chaine_tempo[k]='\0';

 

/* LIF         21 /* if */

 

                                                                       if(strcmp("if",chaine_tempo)==0)

                                                                          {

#ifdef TESTLEX

                                                                       printf(" IF %s [%d] ",chaine_tempo,nb_echant);

#endif

                                                                                              Techant[nb_echant].type_lexeme=LIF;

                                                                                              strcpy(Techant[nb_echant].lexeme,chaine_tempo);

                                                                                              Techant[nb_echant].num_ligne=ligne_lu;

                                                                                              strcpy(Techant[nb_echant].module,nom_fic);

                                                                                              nb_echant++;

                                                                                              goto fin;

                                                                                  }/*if*/

 

In this compiler, the following list of lexems are implemented :

 

#define LBEGIN      0 /*{ */

#define LEND        1 /* } */

#define LFOR        2 /* for */

#define LWHILE      3 /* while */

#define LDO         4 /* do */

#define LTASK       5 /* task */

#define LSUBROUTINE 6 /* subroutine */

#define LIDENT      7 /*identifier */

#define LENTIER     8 /* int */

#define LCHAR       24 /* char */

#define OCTET       26 /* byte */

#define LFLOTTANT   25 /* float */

#define CHAINE      9 /* chaine = string*/

#define LPV         10 /* ; */

#define LV          11 /* , */

#define LPLUS       12 /* + */

#define LMOINS      13 /* - */

#define LMUL        14 /* * */

#define LDIV        15 /* / */

#define LEG         31 /* = */

#define LOP         32 /* ( */

#define LCL         33 /* ) */

#define LCOMPINF    16 /* < */

#define LCOMPSUP    17 /* > */

#define LCOMPINFEG  18 /* <= */

#define LCOMPSUPEG  19 /* >= */

#define LCOMPEG     20 /* == */

#define LIF         21 /* if */

#define LELSE                        22 /* else */

#define LRETURN     23 /* return */

#define LCONTINUE   27 /* continue */

#define LBREAK      28 /* break */

#define LSWITCH     29 /* switch */

#define LCASE       30 /* case */

#define LDP         34  /* : */

#define LET         35 /* & */

#define LOU         36 /* | */

#define LCOMPET     37 /* && */

#define LCOMPOU     38 /* || */

#define LNON        39 /* ! */

#define LADDR       40 /* & */

#define LCROP       41 /*[*/

#define LCRCL       42 /* ] */

#define LCHIFFREENT 43 /* 123 */

#define LCHIFFRREEL 44 /*123.52 */

#define LOPCOMM     45 /* /* */

#define LCLCOMM     46 /* */

#define LPOINT      47  /* . */

#define LSTRUCT     48 /* struct */

#define LEXIT       49 /* exit */

#define LVOID       50 /* LVOID */

#define LINC        51 /* ++ */

#define LDEC        52 /* -- */

#define LGOTO       53 /* goto */

#define LCOMPDIFF   54 /* != */

#define LINDIRECT   55 /* -> */

#define LSIZEOF     56 /* sizeof */

#define LDEFAULT    57 /* default */

#define LMODULO     58 /* % */

#define LSCHAR      59 /* schar */

#define LSINT       60 /* sint */

#define LLONG       61 /* long */

#define LSLONG      62 /* slong */

#define LSHL        63 /* << */

#define LSHR        64 /* >> */

#define LPRECEDES  65 /* precedes */

#define LMODIFY                 66 /* mod */

#define LINLINE                    67 /* inline */

#define LNEG             68 /* moins unaire */

#define LMUTEX                   69 /* semaphore mutex */

#define LACQUIRE    70 /* acquire */

#define LRELEASE     71 /* release */

#define LARRSIZE     72 /* arrsize */

#define LARRINIT      73 /* arrinit */

#define LARRSUBSET           74 /* arrsubset */

#define LARRBUILD  75 /* arrbuild */

6.4 Syntax parsing

 

Principles :

 

The syntax  parsing is far far more complex than the two previous steps …

Before commenting in detail the C code, below a summary of the parsing  principles.

 

The syntax parsing  analyses a flow of lexems character and generates a syntax tree.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


In theory, there are different types of languages, some of them can be modelled by using state machine, eg. LALR(2) state machine.

Smart programmers use yacc tool ( yet another compiler compiler ) to generate automatically state machines.

 

 

 

As I am not a smart guy, I have chosen to program my own syntax parser by using a simple “functional” parser. In a nutshell, a functional parser associates a function per “grammar rules”.

The stack which saves contexts is handled by the compiler itself and is managed by the micro-processor during the execution.

 

Below an example of syntax parsing of the “for” instruction : <for loop> -> for ( [ <affectation> ] 0..1   ;  [<expr>] 0..1  ; <affectation> ] 0..1   ) <body instruction>

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


Example :

 

<bloc> -> { <sint> }

<sint> -> <inst> | <inst> <sinit>

<inst> -> <if>  | <assign>  | <func call>

<assign> -> <ident> = <exp>;

<func call> -> <ident> ();

<if> -> if <expr> <bloc>

<exp> -> <comp> | <func call exp>  | 1

<comp> -> <ident> == <ident>

<func call exp> -> <ident> ()

 

Top-down analysis :

 

The top-down approach is based on the fact that the grammar rule to be recognized is chosen first, in other words, before having read all the tokens. That’s why in some cases, backtrack is required if ambiguous choice between several grammar rules occur.

If we consider a top-down approach , this grammar is modelled as follow :

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


Example of parsing :

 

{

            if ( i=j) {g();k=1;}

}

 

Below the stack at each step of the parsing process :

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

;

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

;

 

 

 

1

1

 

 

 

 

 

 

 

 

 

 

 

 

 

 

)

)

 

 

=

=

=

 

 

 

 

 

 

 

 

 

 

 

 

=

(

(

(

 

Ident

“k”

Ident

“k”

Ident

“k”

Ident

“k”

 

 

 

 

 

 

 

 

 

 

 

Ident

“g”

Ident

“g”

Ident

“g”

Ident

“g”

Ident

“g”

inst

inst

inst

inst

inst

 

 

 

 

 

 

ident
”j”

ident
”j”

 

 

{

{

{

{

{

{

{

{

{

{

{

 

 

 

 

 

==

==

==

 

)

)

)

)

)

)

)

)

)

)

)

)

 

 

 

 

ident “i”

ident “i”

ident “i”

ident “i”

exp

exp

exp

exp

exp

exp

exp

exp

exp

exp

exp

exp

exp

 

 

(

(

(

(

(

(

(

(

(

(

(

(

(

(

(

(

(

(

(

 

if

if

if

if

if

if

if

if

if

if

if

if

if

if

if

if

if

if

if

if

{

{

{

{

{

{

{

{

{

{

{

{

{

{

{

{

{

{

{

 

{

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

inst

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

inst

sinst

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

{

{

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

)

)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

exp

exp

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

(

(

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

if

if

inst

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

{

{

{

bloc

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Bottom-up  analysis :

 

The bottom-up  approach is based on the fact that the grammar rule to be recognized is reduced after a complete recognition of the right part of the “grammar rule”, e.g <A> -> <atome> () is reduced only if <atom> and () have been previously recognized. In some cases, there are conflicts between rules to be reduced or reduce/shift (reading ).

 

Example :

 

<bloc> -> { <sint> }

<sinst> -> <inst> | <inst> <sinst>

<inst> -> <if>  | <assign>  | <func call>

<assign> -> <ident> = <exp>;

<func call> -> <ident> ();

<if> -> if <expr> <bloc>

<exp> -> <comp> | <func call exp>

<comp> -> <ident> == <ident>

<func call exp> -> <ident> ()

 

If we consider a bottom-up approach , this grammar is modelled by an LR(0), as follow : ( I’ve processed this state machine by hand, and it is not very easy … )

 

 

table of the LR(0) parser :

 

S : Shift : Read the current token ( lexem )

R : Reduce

 

State

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

<bloc>

 

 

 

R

<bloc>->{<sinst>}

R

<inst>-><assign>

R

<inst>-><if>

R

<inst>-><func call>

 

 

 

 

R

<func call>-><ident>();

S/26

 

 

R

<exp>-<comp>

<exp>-><func call exp>

 

 

 

<comp>-><ident> == <ident>

<func call exp>-> <ident>()

 

R

<sinst>-><inst><sinst>

R

<assign>-><ident>=<expr>;

R

<if>->if<expr><bloc>

<assign>

 

S/5

 

 

S/5

 

 

 

 

 

 

 

 

 

<if>

 

S/6

 

 

S/6

 

 

 

 

 

 

 

 

 

<sinst>

 

S/3

 

 

S/24

 

 

 

 

 

 

 

 

 

<inst>

 

S/9

 

 

S/ 9 (

<sint> -> .<inst> <sint>

)

R/9 (<sint> -> <inst>.)

Conflict

Use ‘}’to make the right choice

 

 

 

 

 

 

 

 

 

<func call>

 

S/7

 

 

S/7

 

 

 

 

 

 

 

 

 

<comp>

 

 

 

 

 

 

 

 

S/16

S/16

 

 

 

 

<func call exp>

 

 

 

 

 

 

 

 

S/17

S/17

 

 

 

 

<expr>

 

 

 

 

 

 

 

 

S/23

S/13

 

 

 

 

<ident>

 

S/8

 

 

S/8

 

 

 

S/18

S/18

 

S/21

 

 

(

 

 

 

S/10

 

 

 

 

 

 

S/20

 

 

 

)

 

 

 

 

 

S/11

 

 

 

 

 

 

S/22

 

{

S/2

 

 

 

 

 

 

S/2

 

 

 

 

 

 

}

 

 

S/4

 

 

 

 

 

 

 

 

 

 

 

;

 

 

 

 

 

 

S/12

 

 

 

 

 

 

S/25

=

 

 

 

S/14

 

 

 

 

 

 

 

 

 

 

==

 

 

 

 

 

 

 

 

 

 

S/19

 

 

 

if

 

S/15

 

 

S/15

 

 

 

 

 

 

 

 

 

 

This type of  state machine engenders conflicts :

-         Shift / Reduce conflicts

-         Reduce/Reduce conflicts

 

To solve conflicts, there is a simple method which consists in determining the next token to be read in order to choose the relevant action to be processed. For example to choose between “shitfing” <inst>  in the rule <sint> -> .<inst> <sint>  or reducing  <sint> -> <inst>., you may say that if the following token is “}” you reduce else you shift. But in some cases this method do not solve the problem, more powerful state machines must then be used.

The Parsing Algorithm

The LR parsing algorithm now works as follows:

1.     The stack is initialized with [0]. The current state will always be the state that is at the top of the stack.

2.     Given the current state and the current terminal on the input stream an action is looked up in the action table. There are four cases:

o       a shift sn:

§       the current terminal is removed from the input stream

§       the state n is pushed onto the stack and becomes the current state

o       a reduce rm:

§       the number m is written to the output stream

§       for every symbol in the right-hand side of rule m a state is removed from the stack

§       given the state that is then on top of the stack and the left-hand side of rule m a new state is looked up in the goto table and made the new current state by pushing it onto the stack

o       an accept: the string is accepted

o       no action: a syntax error is reported

3.     Step 2 is repeated until either the string is accepted or a syntax error is reported.

Below an execution of the algorithm according to the table of action.

 

Example of parsing :

 

{

            if i=j {g();k=f();}

}

 

 Reduction

 

 

 

 

 

<comp> -> <ident> == <ident>

 

 

<exp> -> <comp>

 

 

 

 

 

 

<func call exp> -> <ident> ()

 

 

<inst> -> <func call>

 

 

Token

{

if

Ident

==

Ident

{

{

{

{

{

Ident

(

)

;

;

Ident

Ident

Ident

State

1

2

15

18

19

21

15

16

15

13

2

8

10

11

12

2

7

2

Action

S/2

S/15

S/18

S/19

S/21

R

S/16

R

S/13

S/2

S/8

S/10

S/11

S/12

R

S/7

R

R

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

;12

;12

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

);11

);11

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

(;10

(;10

(;10

 

 

 

 

 

 

 

 

Ident-
j;
19

Ident-
j;
19

 

 

 

 

 

Ident-g;8

Ident-g;8

Ident-g;8

Ident-g;8

<fun call>;12

<fun call>;12

<inst>;7

 

 

 

 

==;18

==;18

==;18

 

 

 

 

{;2

{;2

{;2

{;2

{;2

{;2

{;2

{;2

 

 

 

Ident- I;15

Ident-
I;
15

Ident-
I;
15

Ident-
I;
15

<comp>;15

<comp>;15

<exp>;15

<exp>;13

<exp>;13

<exp>;13

<exp>;13

<exp>;13

<exp>;13

<exp>;13

<exp>;13

<exp>;13

 

 

If;2

If;2

If;2

If;2

If;2

If;2

If;2

If;2

If;2

If;2

If;2

If;2

If;2

If;2

If;2

If;2

If;2

 

{;1

{;1

{;1

{;1

{;1

{;1

{;1

{;1

{;1

{;1

{;1

{;1

{;1

{;1

{;1

{;1

{;1

{;1

 

 

Reduction

 

 

 

 

 

 

<func call exp> -> <ident> ()

 

<exp> -> <func call exp> 

 

 

<assign> -> <ident> = <exp>;

 

<inst> -> <assign> 

<sinst> -> <inst>

 

Token

Ident

Ident

=

Ident

(

)

;

;

;

;

;

}

}

}

}

}

State

2

9

8

14

18

20

22

14

17

14

23

25

9

5

9

9

Action

S/9

S/8

S/14

S/18

S/20

S/22

R

S/17

R

S/23

S25

R

S/5

R

R

S/24

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

);20

);20

 

 

 

 

 

 

 

 

 

 

 

 

 

 

(;18

(;18

(;18

 

 

 

 

;;25

 

 

 

 

 

 

 

 

Ident;14

Ident;14

Ident;14

Ident;14

<Func all exp>;14

<Func all exp>;14

<exp>;14

<exp>;14

<exp>;14

 

 

 

 

 

 

 

=;8

=;8

=;8

=;8

=;8

=;8

=;8

=;8

=;8

=;8

 

 

 

 

 

 

Ident;9

Ident;9

Ident;9

Ident;9

Ident;9

Ident;9

Ident;9

Ident;9

Ident;9

Ident;9

Ident;9

<assign>;9

<assign>;9

<inst>;9

<sinst>;9

 

<inst>;2

<inst>;2

<inst>;2

<inst>;2

<inst>;2

<inst>;2

<inst>;2

<inst>;2

<inst>;2

<inst>;2

<inst>;2

<inst>;2

<inst>;2

<inst>;2

<inst>;2

<inst>;2

 

{;2

{;2

{;2

{;2

{;2

{;2

{;2

{;2

{;2

{;2

{;2

{;2

{;2

{;2

{;2

{;2

 

<exp>;13

<exp>;13

<exp>;13

<exp>;13

<exp>;13

<exp>;13

<exp>;13

<exp>;13

<exp>;13

<exp>;13

<exp>;13

<exp>;13

<exp>;13

<exp>;13

<exp>;13

<exp>;13

 

If;2

If;2

If;2

If;2

If;2

If;2

If;2

If;2

If;2

If;2

If;2

If;2

If;2

If;2

If;2

If;2

 

{;1

{;1

{;1

{;1

{;1

{;1

{;1

{;1

{;1

{;1

{;1

{;1

{;1

{;1

{;1

{;1

 

Reduction

<sinst> -> <inst> <sinst>

 

 

 

<bloc> -> { <sint> }

 

 

<if> -> if <expr> <bloc>

 

 

<inst> -> <if> 

 

<sinst> -> <inst>

 

 

<bloc> -> { <sint> }

 

 

 

Token

}

}

}

}

}

}

}

}

}

}

}

void

 

 

 

 

State

2

2

3

4

13

26

2

2

2

9

2

3

 

 

 

 

Action

R

S/3

S/4

R

S/26

R

S/6

R

S/9

R

S/3

S/4

R

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

};8

 

 

 

 

 

 

 

 

 

 

 

 

 

 

<sinst>;2

<sinst>;2

<sinst>;2

 

 

 

 

 

 

 

 

 

 

 

 

 

 

{;2

{;2

{;2

<bloc>;13

<bloc>;13

 

 

 

 

 

 

 

 

 

 

 

 

<exp>;13

<exp>;13

<exp>;13

<exp>;13

<exp>;13

 

 

 

 

 

 

};4

 

 

 

 

 

If;2

If;2

If;2

If;2

If;2

<i>;2

<if>;2

<inst>;2

<inst>;2

<sinst>;2

<sinst>;2

<sinst>;2

 

 

 

 

 

{;1

{;1

{;1

{;1

{;1

{;1

{;1

{;1

{;1

{;1

{;1

{;1

<bloc>

 

 

 

 

As you can seen, the bottom-up approach is far more complex than the top-down approach, and for my COP compiler I have chosen the simplest solution.

Comments on the syntax parsing in the COP compiler :

 

As seen above, the simplest way to parse simple grammar is to use the top-down approach.

The principle of implementation in the COP compiler is to associate a C function to each grammar rule.

The lire_token() function returns in the token string the value of the token ( eg. for LIDENT, the value of the identifier ), and the type_token the type of the token ( eg. LFOR ).

In case of conflict between 2 or more C functions to call, eg. “assignment” or “function call”, backtrack mechanism is put in place and the retour_arriere() function is used to position the current token to the appropriate lexem to be read.

Example of the for loop :

 

Example for the <for loop> -> for ( [ <affectation> ] 0..1   ;  [<expr>] 0..1  ; <affectation> ] 0..1   ) <body instruction> :

 

In red, error which are detected, eg. message_erreur("Erreur Fatale #S0130 :: ( attendue ") is raised if the parenthesis after “for” is missing.

In orange, calls to analysis of rules :

-         analyse_affectation(bloc_prof,type_pointeur_var); is called to parse the assignment in the rule for(<assignement> )

-         analyse_expression(bloc_prof); is called to parse the rule in the rule “for(<assignement>;<expression>;… )”

 

INSTRUCTION * analyse_for(char *bloc_prof)

  {

              SEXPRESSION *exp1;

              SAFFECTATION *aff1,*aff2;

              INSTRUCTION *inst;

              INSTRUCTION  *inst_r;

              /*SFOR *sfor;*/

 

              monte();

              boucle++;

 

              if(traceaff==1) printf("\n%s : for (token constatee =%s;;)",affiche,token);

 

              /* consommation du ( */

              cr=lire_token();

              if(cr==-1)

                         message_erreur("\n Erreur Fatale #S0129 : fin prématuré du fichier source dans l'instruction for(;;)  ");

 

             if(traceaff==1) printf("\n%s : token lu apres le for =%s",affiche,token);

 

             if(type_token!=LOP)

                         message_erreur("Erreur Fatale #S0130 :: ( attendue ");

 

             /* analyse de l'affectation du for(xxx;;) */

 

             cr=lire_token();

             if(cr==-1)

                         message_erreur("\n Erreur Fatale #S0131 : fin prématuré du fichier source dans l'instruction for(;;)  ");

 

             if(type_token!=LPV)

                         {

                                    int type_pointeur_var;

 

                                     type_pointeur_var=TYP_PTR_VAR_NORMAL;

 

                                     if(type_token==LMUL)

                                               {

                                                           if(traceaff==1) printf("\n X %s * detectee",affiche);

                                                           cr=lire_token();

                                                           if(cr==-1)

                                                                       message_erreur("\n Erreur Fatale #S0132 : fin prématuré du fichier source dans l'expression ");

                                                           type_pointeur_var=TYP_PTR_VAR_POINTEUR;

                                                           if(type_token==LMUL)

                                                                       {

                                                                                  if(traceaff==1) printf("\n Z %s ** detectee",affiche);

                                                                                  cr=lire_token();

                                                                                   if(cr==-1)

                                                                                               message_erreur("\n Erreur Fatale #S0133 : fin prématuré du fichier source dans l'expression ");

                                                                                  type_pointeur_var=TYP_PTR_VAR_POINTEUR_POINTEUR;

                                                                       }

                                               }

                                    aff1=analyse_affectation(bloc_prof,type_pointeur_var);

                         } /* patch 15/04/07 */

             else aff1=NULL;

 

             if(type_token!=LPV)

                         message_erreur("Erreur Fatale #S0134 :: ; attendue ");

 

               /* consommation du ; */

              cr=lire_token();

              if(cr==-1)

                         message_erreur("\n Erreur Fatale #S0135 : fin prématuré du fichier source dans l'instruction for(;;)  ");

 

             /* analyse de l'affectation du for(;xxx;) */

             if(type_token!=LPV)

                        exp1=analyse_expression(bloc_prof); /* l'expression peut être vide  */

     /* patch 15/04/07 */

             else exp1=NULL;

 

             if(type_token!=LPV)

                         message_erreur("Erreur Fatale #S0136 :: ; attendue ");

 

              /* consommation du ; */

              cr=lire_token();

              if(cr==-1)

                         message_erreur("\n Erreur Fatale #S0137 : fin prématuré du fichier source dans l'instruction for(;;)  ");

 

             /* analyse de l'affectation du for(;;xxx) */

 

             if(type_token!=LCL)

                         {

                                    int type_pointeur_var;

 

                                     type_pointeur_var=TYP_PTR_VAR_NORMAL;

 

                                     if(type_token==LMUL)

                                               {

                                                           if(traceaff==1) printf("\n X %s * detectee",affiche);

                                                           cr=lire_token();

                                                           if(cr==-1)

                                                                       message_erreur("\n Erreur Fatale #S0138 : fin prématuré du fichier source dans l'expression ");

                                                           type_pointeur_var=TYP_PTR_VAR_POINTEUR;

                                                           if(type_token==LMUL)

                                                                       {

                                                                                  if(traceaff==1) printf("\n Z %s ** detectee",affiche);

                                                                                  cr=lire_token();

                                                                                   if(cr==-1)

                                                                                               message_erreur("\n Erreur Fatale #S0139 : fin prématuré du fichier source dans l'expression ");

                                                                                  type_pointeur_var=TYP_PTR_VAR_POINTEUR_POINTEUR;

                                                                       }

                                               }

 

                                     aff2=analyse_affectation(bloc_prof,type_pointeur_var);

                         } /* patch 15/04/07 */

             else aff2=NULL;

 

             if(type_token!=LCL)

                         message_erreur("Erreur Fatale #S0140 :: ) attendue ");

 

             cr=lire_token();

              if(cr==-1)

                         message_erreur("\n Erreur Fatale #S0141 : fin prématuré du fichier source dans l'instruction for(;;)  ");

 

             /* analyse du corps du for */

 

             inst=(INSTRUCTION *)analyse_liste_instruction(bloc_prof,1);

 

             /* analyse du corps du for */

 

             descend();

 

             inst_r=(INSTRUCTION *)nouvelle_instruction(bloc_prof,INST_FOR,0,exp1,inst,NULL,aff1,aff2,NULL,0,NULL,NULL,NULL,NULL);

 

            /* affiche_inst_for(inst_r);*/

 

            boucle--;

 

            return(inst_r);

 

  }

 

Dedicated grammar for operators :

 

This grammar below is not really implemented  like described.

 

<expr>  -> <ident> |

                  <ident> [ . <ident assign> ] 1..n   | 

                   <ident> [ [<expr> ] ] 1..n   |

                  <atom> |

                  (<expr> ) |

                   <expr>  [<math op> <expr>] 1..n  |

                   - <math expr> |

                   <expr> [<logical op> <logical expr>] 1..n  |

                    ! <expr>

 

Indeed, the aim is to generate a binary tree which makes easier the code generation step : the set of arithmetic instruction is based on binary argument.

The second reason is that operators have precedence.

 

a+3*c is equal to a + (3*c), the ‘*’ operator is prioritized.  To recognize  a such pattern, the grammar must be written by following a particular way.

 

<Exp> ->  <Sub_Exp>  [+ | -]  <Exp>

<Exp> ->  <Sub_Exp>

<Sub_Exp>  -> <atom> [* | /] <Sub_Exp>

<Sub_Exp>  -> <atom>

<atom> -> <variable> | <integer> | ( <Exp> )

 

example of parsing which illustrates the precedence of the operator ‘*’ :

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


As you can see above, 3*c is parsed as a <sub exp> rule and not as an <exp> rule.

In the COP compiler, such a grammar operator has been implemented.

 

a+3*c+d  is parsed as shown below :

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


Mapping between rules and C functions :

 

Below an array which maps the grammar and the C function which code the parsing :

 

rules

C function

C structures

Semantic and Syntax controls
 ( non exhaustive list )

<Program> ->  [ <define declaration> | <struct declaration> | <variable declarations>| <mutex declarations>   | <function> | <task> ]0..n

void analyse_corps(char *prof_bloc)

 

 

<define declaration> -> define  <ident>  <text>

See pre-processing step

 

Double declaration of define

<struct declaration> -> struct { < field definition >1..n };

void analyse_variable(char *prof_bloc),
case LSTRUCT of the switch()

extern TYPE_VARIABLE tab_type_variable[MAX_TYPE_VARIABLE];

extern int nb_tab_type_variable;

extern PROGRAM program;

Storage of structure and fields :

index_type=ajout_type(prof_bloc, type,STRUCTURE,dimension,

nb_dimension, nom_structure, ident,

nb_champ, type_pointeur);

see more detail on variables and structures

#define MAX_VARIABLE_GLOBALE 1000

#define TYPE_VARIABLE struct type_variable

TYPE_VARIABLE {

                        int  genre_variable; /* ATOME, STRUCTURE, TABLEAU, pointeur */

                        char type[MAX_IDENT]; /* type */

                        char champ_structure[MAX_IDENT]; /* ident du champ */

                        TYPE_VARIABLE *type_variable_ptr[MAX_CHAMP]; /* champs de la structure */

                        int  nb_type_variable; /* nombre de champs de la structure */

                        int  dimension[MAX_DIMENSION]; /* dimension du tabelau, si tableau */

                        int  nb_dimension; /*nombre de dimension du tableau */

                        int  nb_champ; /* nb de champ de la structure */

                        char bloc[PROF_BLOC+1];

                        int  type_pointeur; /* pour les champs */

            };

Syntax errors

Double declaration of  structure

Double declaration of a filed of structure

Too many fields in the structure …

<field definition> -> <type> <list of fields>

<list of fields> -> <field> , <list of fields> | <field> ;

<field> -> [*]0|1 <ident> [ [<integer>] ] 0..n

<variable declarations> -> <type> <list of variables>

void analyse_variable(char *prof_bloc),
case <> of LSTRUCT of the switch()

Storage of arrays :

index_type=ajout_type(prof_bloc,type,TABLEAU,dimension,

nb_dimension,NULL,NULL,0,type_pointeur);

Storage of variables ( initialized or not ) :

if(init_var==0)

 ajout_variable(prof_bloc,index_type,type,ident,NULL,

 init_var,type_pointeur);

else

 jout_variable(prof_bloc,index_type,type,ident,valeur_token,

 init_var,type_pointeur);

see more detail on variables and structures

#define POINTEUR 0

#define PASPOINTEUR 1

#define POINTEURPOINTEUR 2

#define MAX_TYPE_VARIABLE 1000

#define VARIABLE_GLOBALE struct variable_globale

VARIABLE_GLOBALE {

                        TYPE_VARIABLE *type_variable_ptr;

                        char ident[MAX_IDENT];

                        char bloc[PROF_BLOC+1];

                        char valeur[MAX_IDENT]; /* vaut null si pas de valeur initialisée */

                        int  type_pointeur;

                        int  modify;

            };

Syntax errors

Double declaration of variable

Dimension of  an array exceed the maximum value

Initialisation with a constant which is not compatible with the type of the variable …

<list of variables> -> <variable> , <list of variables> | <field> ;

<variable> -> [*]0|1 <ident> [ [<integer>] ] 0..n = [<init>]0|1

<init> -> <numeric value> | <string>

<mutex_declaration> -> mutex <list of mutex>

<list of mutex> -> <mutex> , <list of mutex> | <mutex> ;

< mutex> -> <ident>

void analyse_mutex(void)

extern TAB_MUTEX tab_mutex[MAX_MUTEX];

extern int nb_mutex;

#define MAX_MUTEX 10000

#define TAB_MUTEX struct tab_mutex

TAB_MUTEX {

                char ident[MAX_IDENT]; /* nom du mutex */

                        char module[100];                   /* module       */

                        int  ligne;                                              /* ligne        */

            };

Syntax errors

Double declaration of mutex …

<function> -> <ident> ( <list of parameters> )  < body > |

          < return value > <ident> ( <list of parameters> | void  ) < body >

<list of parameters>  -> <list of parameters> ,<parameter> | <parameter>

<parameter> -> [ mod ] 0|1  <type> [*]0|1 <ident>

<return value> -> void | <type>

void analyse_fonction(void)

extern FONCTION tab_fonction[MAX_FONCTION];

extern int nb_fonction;

#define MAX_FONCTION 1000

#define MAX_VARLOC 100

#define FONCTION struct fonction

FONCTION {

                        TYPE_VARIABLE *type_variable_retournee_ptr; /* pointe sur le type de variable retournee atome ou structure */

                        int type_pointeur; /* type de pointeur retourne PASPOINTEUR,POINTEUR,POINTEURPOINTEUR */

                        char ident_fonction[MAX_IDENT]; /* nom de la fonction */

                        int nb_parametre; /*nb de paramètres */

                        VARIABLE_GLOBALE *parametres; /* liste des parametres */

                        int nb_var_locale; /*nb de variable locale */

                        VARIABLE_GLOBALE *var_locale; /* liste des parametres */

                        INSTRUCTION *liste_instruction; /* listes des instructions */

                        int nb_instruction;

                        int librairie;

};

Syntax errors

Double declaration of  functions

Bad type of the return value …

<task> -> task  <ident> ( ) < body >

void analyse_tache(void)

extern TACHE tab_tache[MAX_TACHE];

extern int nb_tache;

#define MAX_TACHE 1000

#define TACHE struct tache

TACHE {

                char ident_tache[MAX_IDENT]; /* nom de la tache */

                        int nb_var_locale; /*nb de variable locale */

                        VARIABLE_GLOBALE *var_locale; /* liste des parametres */

                        INSTRUCTION *liste_instruction; /* listes des instructions */

                        int nb_instruction;

            };

Syntax errors

Double declaration of  tasks

 

<body> -> {  [<variable declarations>] 0|1  [<instruction>]0..n  }

void analyse_variable(char *prof_bloc)

extern TYPE_VARIABLE tab_type_variable[MAX_TYPE_VARIABLE];

extern int nb_tab_type_variable;

extern PROGRAM program;

Syntax errors

Double declaration of  functions

Bad type of the return value …

<instruction> -> <assignment> |

                                <for loop> |

                               <do while loop> |

                               <if then else> |

                               <switch> |

                               <goto> |

                               <label> |

                               <continue> |

                               <break> |

                                <exit> |

<return> |

<acquire> |

<release> |

<precedes> |

<arrinit> |

<arrsize> |

<arrbuild> |

<arrsubset> |

<inline> |

< function call> ;

INSTRUCTION * analyse_liste_instruction(char *bloc_prof,int tag)

extern INSTRUCTION tab_instruction[MAX_INSTRUCTION];

extern int nb_instruction;

Syntax errors

 

<assignment> -> [ [*( <ident> + <expr> ) | <ident assign> ] [=  <expr> ; ] 0|1    |  <ident> ++; | <ident> -- ;

 

SAFFECTATION * analyse_affectation(char *bloc_prof,int type_pointeur_var)

#define INST_AFFECTATION 9

 

#define AFF_EXP  0

#define AFF_INC  1

#define AFF_DEC  2

#define AFF_PTR  3

 

#define SAFFECTATION struct saffectation

SAFFECTATION {

            SEXPRESSION *variable;

            SEXPRESSION *valeur_affectee;

            int type_affectation;

};

Syntax errors

 

<for loop> -> for ( [ <affectation> ] 0..1   ;  [<expr>] 0..1  ; <affectation> ] 0..1   ) <body instruction>

INSTRUCTION * analyse_for(char *bloc_prof)

#define INST_FOR                  1

#define SFOR struct sfor

SFOR {

            SAFFECTATION *argument_init_ptr;

            SEXPRESSION *expression_ptr;

            SAFFECTATION *argument_increment_ptr;

            INSTRUCTION *corps_for;

};

Syntax errors

 

<do while loop> -> do {  [<instruction>]0..n  } while ( <expr>   ) ;

INSTRUCTION * analyse_do_while(char *bloc_prof)

#define INST_DO_REPEAT  2

#define SDO_REPEAT struct sdorepeat

SDO_REPEAT {

            SEXPRESSION *expression_ptr;

            INSTRUCTION *corps;

};

Syntax errors

 

<if then else> -> if ( <expr> ) <body instruction> [ else <body instruction>  ] 0..1 

INSTRUCTION * analyse_if(char *bloc_prof)

#define INST_IF                      0

#define SIF struct sif

SIF {

            int selse;

            SEXPRESSION *argument;

            INSTRUCTION *corps_if;

            INSTRUCTION *corps_else;

};

Syntax errors

 

<switch> -> switch ( <expr> ) { [< switch body>]0..1  }

<switch body> -> case <expr> :  [<body instruction>] 0..1  [break ; ] 0..1 |

    default  : [<body instruction>] 0..1 

INSTRUCTION * analyse_switch(char *bloc_prof)

#define INST_SWITCH          3

#define TYPE_CASE_CASE 1

#define TYPE_CASE_DEFAULT 2

#define MAX_CASE 100

#define SSWITCH struct sswitch

SSWITCH {

            SEXPRESSION *expression;

            SEXPRESSION *expression_case[MAX_CASE];

            INSTRUCTION *cases[MAX_CASE];

            int nb_case;

            int type_case[MAX_CASE];

            int break_or_not[MAX_CASE];

};

Syntax errors

 

<goto> -> goto  <ident> ;

void analyse_goto(char *bloc_prof)

#define INST_GOTO              4

INSTRUCTION_ELT {

            char                sgoto[MAX_IDENT];

};

Syntax errors

 

<label> -> <ident> :

void analyse_lident(char *bloc_prof)

#define INST_LABEL            15

INSTRUCTION_ELT {

            char                slabel[MAX_IDENT];

};

Syntax errors

 

<continue> -> continue ;

INSTRUCTION *  analyse_continue(char *bloc_prof)

#define INST_CONTINUE    8

 

Syntax errors

 

<break> -> break ;

INSTRUCTION * analyse_break(char *bloc_prof)

#define INST_BREAK           6

 

Syntax errors

 

<exit> -> exit ( ) ; 

INSTRUCTION * analyse_exit(char *bloc_prof)

#define INST_EXIT                17

 

Syntax errors

 

<return> -> return ( expr ) ;

INSTRUCTION * analyse_return(char *bloc_prof)

#define INST_RETURN         5

#define SRETURN struct sreturn

SRETURN {

            SEXPRESSION *expression_ptr;

            int exp;

};

Syntax errors

 

<acquire> -> acquire ( <ident> ) ;

void analyse_acquire(char *bloc_prof)

#define INST_ACQUIRE       19

INSTRUCTION_ELT {

            char                smutex_acquire[MAX_IDENT];

};

Syntax errors

Unknown mutex

<release> -> release ( <ident> ) ;

void analyse_release(char *bloc_prof)

#define INST_RELEASE        20

INSTRUCTION_ELT {

            char                smutex_release[MAX_IDENT];

};

Syntax errors

Unknown mutex

<precedes>-> precedes <list of tasks> ;

<list of tasks> -> <list of tasks> , <ident> | <ident>

INSTRUCTION * analyse_precedes(char *bloc_prof)

#define INST_PRECEDES     16

#define MAX_PRECEDES 20

#define SPRECEDES struct sprecedes

SPRECEDES {

            int  nb_label;

            char label[MAX_PRECEDES][MAX_IDENT];

};

Syntax errors

Unknown task

<arrinit> -> arrinit ( <ident>, <expr>, <expr> ) ;

void analyse_arrinit(char *bloc_prof)

#define INST_ARRINIT         22

#define SARRINIT struct sarrinit

SARRINIT {

            char  label[MAX_IDENT];

            SEXPRESSION *expression_value_ptr;

            SEXPRESSION *expression_size_ptr;

};

Syntax errors

Unknown array

Bad init type

<arrsize> -> arrssize ( <ident>, <ident> ) ;

void analyse_arrsize(char *bloc_prof)

#define INST_ARRSIZE         21

#define SARRSIZE struct sarrsize

SARRSIZE {

            char  label[MAX_IDENT];

            char  size[MAX_IDENT];

};

Syntax errors

Unknown array

Bad type of the “size” parameter

<arrbuild> -> arrsbuild (  <list of arrays> ) ;

<list of arrays> -> <list of arrays> , <ident> | <ident>

void analyse_arrbuild(char *bloc_prof)

#define INST_ARRBUILD     24

#define SARRBUILD struct sarrbuild

SARRBUILD {

            int        nb_tab;

            char    *label[10];

};

Syntax errors

Unknown arrays

 

<arrsubset> -> arrsubset ( <ident>, <ident>, <expr>, <expr> ) ;

void analyse_arrsubset(char *bloc_prof)

#define INST_ARRSUBSET  23

#define SARRSUBSET struct sarrsubset

SARRSUBSET {

            char  label_src[MAX_IDENT];

            char  label_dst[MAX_IDENT];

            SEXPRESSION *expression_index_ptr;

            SEXPRESSION *expression_length_ptr;

};

Syntax errors

Unknown arrays

 

<inline> -> inline “<text>” ;

void analyse_inline(char *bloc_prof)

#define INST_INLINE           18

INSTRUCTION_ELT {

            char                            sinline[MAX_INLINE];

};

 

Syntax errors

<body instruction> -> {  [<instruction>]0..n  } |

<instruction>

INSTRUCTION * analyse_liste_instruction(char *bloc_prof,int tag)

extern INSTRUCTION tab_instruction[MAX_INSTRUCTION];

extern int nb_instruction;

 

 

#define INSTRUCTION_ELT union instruction_elt

INSTRUCTION_ELT {

            SAFFECTATION      *saffectation;

            SEXPRESSION         *sfonction;

            SIF                              sif;

            SFOR                         sfor;

            SBLOC                                  sbloc;

            SSWITCH                  sswitch;

            SDO_REPEAT                       sdo_repeat;

            SRETURN                  sreturn;

            SARRSIZE                 sarrsize;

            SARRINIT                  sarrinit;

            SARRSUBSET                       sarrsubset;

            SARRBUILD              sarrbuild;

            char                 slabel[MAX_IDENT];

            char                 sgoto[MAX_IDENT];

            SPRECEDES              sprecedes;

            char                             sinline[MAX_INLINE];

            char                             smutex_acquire[MAX_IDENT];

            char                             smutex_release[MAX_IDENT];

};

 

#define INST_ATOME           14

#define INST_VARIABLE     13

#define INST_IF                      0

#define INST_FOR                  1

#define INST_DO_REPEAT  2

#define INST_SWITCH          3

#define INST_GOTO              4

#define INST_RETURN         5

#define INST_BREAK           6

#define INST_CASE              7

#define INST_CONTINUE    8

#define INST_AFFECTATION 9

#define INST_EXPRESSION  10

#define INST_FONCTION    11

#define INST_BLOC              12

#define INST_LABEL            15

#define INST_PRECEDES     16

#define INST_EXIT                17

#define INST_INLINE           18

#define INST_ACQUIRE       19

#define INST_RELEASE        20

#define INST_ARRSIZE         21

#define INST_ARRINIT         22

#define INST_ARRSUBSET  23

#define INST_ARRBUILD     24

#define MAX_INSTRUCTION 100000

#define INSTRUCTION struct instruction

INSTRUCTION {

            int type_instruction; /* type de l'instruction */

            INSTRUCTION_ELT instruction; /* pointeur sur 
                                         l'instruction ou la liste d'instruction */

            char bloc[PROF_BLOC+1];

            int  index;

};

Syntax errors

 

<expr>  -> [ <expr rec ou>  ] 0..1  

SEXPRESSION * analyse_expression(char *bloc_prof)

#define SATOME struct satome

SATOME {

            char valeur[MAX_IDENT];

            int type;

};

 

#define SVARIABLE_VARIABLE      1 (type_svariable )

#define SVARIABLE_TABLEAU_SEUL  2 (type_svariable )

#define SVARIABLE_CHAMP_SEUL    3 (type_svariable )

#define SVARIABLE_CHAMP_TABLEAU 4 (type_svariable )

 

#define SVARIABLE struct svariable

SVARIABLE {

            int ligne;

            int type_svariable;

            char ident_variable[MAX_IDENT];

            VARIABLE_GLOBALE *variable_ptr;

            char ident_champ[MAX_IDENT];

            TYPE_VARIABLE *type;

            SVARIABLE *suivant;

            int indirection;

            SEXPRESSION *dimension[MAX_DIMENSION];

            int nb_dimension;

};

 

#define MAX_PARAMETRE 100

 

#define SFONCTION struct sfonction

SFONCTION {

            char fonction[MAX_IDENT];

            int nb_argument;

            SEXPRESSION *argument_ptr[MAX_PARAMETRE];

};

 

#define SPOINTEUR struct spointeur

SPOINTEUR {

            int ligne;

            char ident_variable[MAX_IDENT];

            VARIABLE_GLOBALE *variable_ptr;

            TYPE_VARIABLE *type;

            SEXPRESSION *index;

};

 

#define FEUILLE union feuille

FEUILLE {

            SFONCTION sfonction;

            SVARIABLE svariable;

            SATOME          satome;

            SPOINTEUR spointeur;

};

 

#define EXP_OPERATEUR 1

#define EXP_ATOME     2

#define EXP_VARIABLE  3

#define EXP_FONCTION  4

#define EXP_POINTEUR  5

 

#define SEXPRESSION struct sexpression

SEXPRESSION {

            int operateur; /* + - / % */ /* penser à ajouter modulo */

            SEXPRESSION *gauche;

            SEXPRESSION *droit;

            int type;

            FEUILLE feuille;

            int type_resultant;

};

Syntax errors

 

<expr rec ou>  -> <expr rec et>  | <expr rec et>  || <expr rec ou> 

SEXPRESSION * analyse_recursive_expression_logique_ou(char *bloc_prof)

Syntax errors

 

<expr rec et>  -> <expr rec comp>  | <expr rec comp>  && <expr rec et> 

SEXPRESSION * analyse_recursive_expression_logique_et(char *bloc_prof)

Syntax errors

 

<expr rec comp>  -> <expr rec arith>  | <expr rec arith> [ ==| != |  >|  <|  <=|  >=  ] <expr rec comp> 

SEXPRESSION * analyse_recursive_expression_comparaison(char *bloc_prof)

Syntax errors

 

<expr rec arith>  -> <expr rec>  | <expr rec>  [  + | - |  | ] <expr rec arith> 

SEXPRESSION * analyse_recursive_expression_arithmetique(char *bloc_prof)

Syntax errors

 

<expr rec>  -> <expr rec shr shl>  | <expr rec shr shl>  [  & | /  | *  | % ]  <expr rec> 

SEXPRESSION * analyse_recursive(char *bloc_prof)

Syntax errors

 

<expr rec shr shl>  -> <expr rec not>  | <expr rec not >  [  >> | <<  ]   <expr rec shr shl > 

SEXPRESSION * analyse_recursive_shr_shl(char *bloc_prof)

Syntax errors

 

<expr rec not>  -> <expr rec neg>  | ! <expr rec neg >

SEXPRESSION * analyse_atome_non(char *bloc_prof)

Syntax errors

 

<expr rec neg>  -> <expr rec atom>  | -  <expr rec atom >

SEXPRESSION * analyse_atome_neg(char *bloc_prof)

Syntax errors

 

<expr rec atom>  -> <atom> | <var func> | (<expr rec ou>   )

SEXPRESSION * analyse_atome(char * bloc_prof)

Syntax errors

 

<var func> - > <ident assign>| <function call>

SEXPRESSION * analyse_fonction_ou_variable(char * bloc_prof,int type_pointeur_var)

Syntax errors

Unknown function

<ident assign>-> <ident>  |

                                  <ident> ++ ; |

                                  <ident>  --  ; |

   <ident> [ . <ident assign> ] 1..n   | 

                          <ident> [ [<expr> ] ] 1..n  

SEXPRESSION * analyse_synt_variable(char *bloc_prof,int type_pointeur_var)

Syntax errors

Unknown variable

<function call> -> <ident> (  [< list of function parameters>]0..1   )

< list of function parameters> -> < list of function parameters> , <expr> | <expr>

SEXPRESSION * analyse_synt_fonction(char *bloc_prof)

Syntax errors

 

<atom> -> <numeric value> | <string>

See lexical step

 

 

<generic ident > ->  [a..z] | [A..Z] [[a..z] | [A..Z] | [0..9] | _ ] 0..n

See lexical step

 

 

<string> -> [all ASCII code] 0..n

See lexical step

 

 

<numeric value> -> <binary>  | <hexa>  | <decimal>

See lexical step

 

 

<binary> -> 0b [0|1] 1..n

See lexical step

 

 

<hexa> -> 0x [ [0|1] | [ [A..F] | [a..f] ] ] 1..n

See lexical step

 

 

<decimal>-> [0..9]  [0..9] 1..n

See lexical step

 

 

<text> -> [all ASCII code] 0..n

See lexical step

 

 

<ident type> -> <generic ident >

See lexical step

 

 

<ident > -> <generic ident >

See lexical step

 

 

<type> -> char | schar | byte | sbyte | int | sint | long | slong | <ident type>

See lexical step

 

 

 

 

6.5 Code generation

 

6.5.1 Principles :

 

The code generation step is the last step of the COP compiler.  In a nutshell, it consists in generating codes to declare variables and data structures and in generating NBC instructions by going thru the syntax tree.

 

 

 


Code generation pass

 

Expliciter le princpe de la générationde code instruction / instercutopn

5.5 Examples of code

 

 

 

 

 

 

 

 

 

 

 

 

 

6.4.2 Mapping between C structures and code generation functions  :

 

The module “genere_code.c” contains the code generation functions.

The entry point is the function void generation_de_code(char *nom), this function opens in write mode the target nbc file and calls the void genere_code(void) function.

 

This function is described below :

 

void genere_code(void)

 {

            int i;

 

            fprintf(file_code,"#include \"NXTDefs.h\""); Generate the include command for the NXTDefs.h file.

            fprintf(file_code,"\ndseg segment");

 

            genere_types(); Generate structures ( if some are defined )

            genere_variables("0",0,0); Generate global variables

            genere_mutex(); Generate Mutex

 

            for(i=0;i<nb_tache;i++)

                         {

                                     genere_variables(tab_tache[i].ident_tache,0,0); Generate local variables of tasks.

                         }

 

            for(i=0;i<nb_fonction;i++)

                         {

                                     genere_variables(tab_fonction[i].ident_fonction,tab_fonction[i].librairie,i); Generates local variables of functions and parameters as well.

                         }

 

            fprintf(file_code,"\ndseg ends");

 

            genere_taches(); Generate codes of tasks

            genere_fonctions(); Generate codes of functions

 

            fprintf(file_code,"\n// End of program");

 }

 

 

Below this table summarizes code patterns that are used to generate NBC codes.

 

Structure

Array/variable

Pattern

C function which generates the NMC code

PROGRAM

PROGRAM program;

 

 

TACHE

TACHE tab_tache[MAX_TACHE];

See pattern

void genere_taches(void)

FONCTION

FONCTION tab_fonction[MAX_FONCTION];

See pattern

void genere_fonctions(void)

VARIABLE_GLOBALE

See PROGRAM

See pattern

for global variables  => genere_variables("0",0,0)

for local variable of task  => genere_variables(tab_tache[i].ident_tache,0,0);

for local variables of functions and parameters => genere_variables(tab_fonction[i].ident_fonction,tab_fonction[i].librairie,i);

TYPE_VARIABLE

TYPE_VARIABLE tab_type_variable[MAX_TYPE_VARIABLE];

See pattern

 

INSTRUCTION

INSTRUCTION tab_instruction[MAX_INSTRUCTION];

 

void genere_instruction(INSTRUCTION *inst,char *bloc) ;

This function contains a switch which associates to each type of instruction a dedicated code generation pattern. Some cases have a dedicated C function and some others are coded in the bodies of the cases.

Below the skeleton of this function ( find links to the detailed C code ) :

void genere_instruction(INSTRUCTION *inst,char *bloc)

  {

      if(inst==NULL)

            {

                        end of recursivity

            }

else

            {

               switch(inst->type_instruction)

                  {

                        case INST_INLINE: case_INST_INLINE

                        case INST_IF : case_INST_IF

                        case INST_FOR : case_INST_FOR

                        case INST_DO_REPEAT : case_INST_DO_REPEAT

                        case INST_SWITCH : case_INST_DO_REPEAT

                        case INST_LABEL : case_INST_LABEL

                        case INST_GOTO : case_INST_GOTO

                        case INST_ACQUIRE : case_INST_ACQUIRE

                        case INST_RELEASE : case_INST_RELEASE

                        case INST_ARRSIZE: case_INST_ARRSIZE

                        case INST_ARRINIT: case_INST_ARRINIT

                        case INST_ARRSUBSET: case_INST_ARRSUBSET

                        case INST_ARRBUILD: case_INST_ARRBUILD

                        case INST_RETURN : case_INST_RETURN

                        case INST_EXIT: case_INST_EXIT

                        case INST_PRECEDES: case_INST_PRECEDES

                        case INST_BREAK    : case_INST_BREAK

                        case INST_CONTINUE : case_INST_CONTINUE

                        case INST_AFFECTATION : case_INST_AFFECTATION

                        case INST_FONCTION : case_INST_FONCTION

                        case INST_BLOC : recursivity genere_instruction() case_INST_BLOC

               }

  }

 

INSTRUCTION_ELT

See #instruction_elt

 

 

SEXPRESSION

See expression

 

 

FEUILLE

See expression

 

 

SATOME

See expression

 

 

SPOINTEUR

See expression

 

 

SVARIABLE

See expression

 

 

SFONCTION

See expression

See Pattern

See case_INST_FONCTION

SAFFECTATION

See affectation

See Pattern

See case_INST_AFFECTATION

SIF

See if

See Pattern

See case_INST_IF

SFOR

See for

See Pattern

See case_INST_FOR

void genere_inst_for(INSTRUCTION *inst,char *bloc)

SBLOC

 

 

 

SSWITCH

See switch

See Pattern

See case_INST_SWITCH

SDO_REPEAT

See do_repeat

See Pattern

See case_INST_DO_REPEAT

SRETURN

See return

See Pattern

See case_INST_RETURN

SARRSIZE

See arrsize

See Pattern

See case_INST_ARRSIZE

SARRINIT

See arrinit

See Pattern

See case_INST_ARRINIT

SARRSUBSET

See arrsubset

See Pattern

See case_INST_ARRSUBSET

SARRBUILD

See arrbuild

See Pattern

See case_INST_ARRBUILD

SPRECEDE

See precedes

See Pattern

See case_INST_PRECEDES

SLABEL

See label

See Pattern

See case_INST_LABEL

SGOTO

See goto

See Pattern

See case_INST_GOTO

SINLINE

See inline

See Pattern

See case_INST_INLINE

ACQUIRE

See acquire

See Pattern

See case_INST_ACQUIRE

RELEASE

See release

See Pattern

See case_INST_RELEASE

Mutex

#define MAX_MUTEX 10000

#define TAB_MUTEX struct tab_mutex

TAB_MUTEX {

   char ident[MAX_IDENT]; /* nom du mutex */

   char module[100];                /* module       */

    int  ligne;                              /* ligne        */

};

 

TAB_MUTEX tab_mutex[MAX_MUTEX];

int nb_mutex;

See pattern

void genere_mutex(void)

 

6.4.3 Code generation patterns :

 

Pattern of variables

 

To be completed

 

Pattern of mutex

 

To be completed

Pattern of tasks

 

To be completed

Pattern of functions

 

To be completed

Pattern of expression

 

The pattern of expression requires some clear explanations.

Indeed, the NXT virtual machine doesn’t offer a stack, in other words you cannot save a context by using POP or PUSH instruction.

Due to this limitation, the generation of codes for complex expressions requires an explicit ‘management’ of stack.

 

The algorithm  is described hereafter :

 

If there is a right sub-tree :

            Generate recursively the code of this right sub-tree=> rtyped=genere_recursif(exp->droit,0,bloc,NULL);

 

If there is a left sub-tree ( not an unary operator such as DEC, INC, NOT, NEG )

            If the right sub-tree is not an atom then PUSH the context to save the right value

            Generate recursively the code of this left sub-tree => rtypeg=genere_recursif(exp->gauche,0,bloc,NULL);

            If the right sub-tree is not an atom then POP the context to retrieve the right value on top if the stack

 

Apply the operator, + , - ….

 

Example of code :

 

task main()

 {

            int a,b,c;

 

            c=3*a+4*b;

           

 }

 

A simple pattern based on the following example shows that if stack is not managed, it cannot work .

 

 

The relevant solution relies on the use of a stack, see below the use of this stack :

 

            arrinit expr_pile_byte_main,   0, 100

            arrinit expr_pile_sbyte_main,  0, 100

            arrinit expr_pile_word_main,   0, 100

            arrinit expr_pile_sword_main,  0, 100

            arrinit expr_pile_dword_main,  0, 100

            arrinit expr_pile_sdword_main, 0, 100

            set expr_ptr_pile_byte_main, 0

            set expr_ptr_pile_sbyte_main, 0

            set expr_ptr_pile_word_main, 0

            set expr_ptr_pile_sword_main, 0

            set expr_ptr_pile_dword_main, 0

            set expr_ptr_pile_sdword_main, 0

            mov expr_word_main, main_b // aff 1

            mov expr_d_word_main, expr_word_main

            replace  expr_pile_word_main, expr_pile_word_main, expr_ptr_pile_word_main, expr_d_word_main -> PUSH(1) save the value on the top of the stack ‘b’

            set inc_main, 1

            add expr_ptr_pile_word_main, expr_ptr_pile_word_main, inc_main -> increment the stack pointer

            set expr_byte_main, 4

            set inc_main, 1

            sub expr_ptr_pile_word_main, expr_ptr_pile_word_main, inc_main -> decrement the stack pointer

            index expr_d_word_main, expr_pile_word_main, expr_ptr_pile_word_main  -> POP(2) retreive the value on the top of the stack -> expr_d_word_main = ‘b’

            mov expr_g_byte_main, expr_byte_main -> expr_g_byte_main = 4

            mul expr_word_main, expr_g_byte_main, expr_d_word_main ->  expr_word_main = expr_g_byte_main * expr_d_word_main = ‘4*b’

            mov expr_d_word_main, expr_word_main

            replace  expr_pile_word_main, expr_pile_word_main, expr_ptr_pile_word_main, expr_d_word_main -> PUSH(3) save the value on the top of the stack ‘4*b’

            set inc_main, 1

            add expr_ptr_pile_word_main, expr_ptr_pile_word_main, inc_main -> increment the stack pointer

            mov expr_word_main, main_a // aff 1

            mov expr_d_word_main, expr_word_main

            replace  expr_pile_word_main, expr_pile_word_main, expr_ptr_pile_word_main, expr_d_word_main -> PUSH(4) save the value on the top of the stack ‘a’

            set inc_main, 1

            add expr_ptr_pile_word_main, expr_ptr_pile_word_main, inc_main -> increment the stack pointer

            set expr_byte_main, 3

            set inc_main, 1

            sub expr_ptr_pile_word_main, expr_ptr_pile_word_main, inc_main

            index expr_d_word_main, expr_pile_word_main, expr_ptr_pile_word_main  -> POP(5) retreive the value on the top of the stack -> expr_d_word_main = ‘a’

            mov expr_g_byte_main, expr_byte_main -> expr_g_byte_main = 3

            mul expr_word_main, expr_g_byte_main, expr_d_word_main ->  expr_word_main = expr_g_byte_main * expr_d_word_main= ‘3*a’

            set inc_main, 1

            sub expr_ptr_pile_word_main, expr_ptr_pile_word_main, inc_main

            index expr_d_word_main, expr_pile_word_main, expr_ptr_pile_word_main  -> POP(6) retreive the value on the top of the stack -> expr_d_word_main = ‘4*b’

            mov expr_g_word_main, expr_word_main

            add expr_word_main, expr_g_word_main, expr_d_word_main -> expr_word_main = ‘3*a’ + ‘4*b’

            mov expr_aff_word_main, expr_word_main // affectation 3 

            mov main_c, expr_aff_word_main // aff 3- > c = ‘3*a’ + ‘4*b’

 

SP is Stack Pointer

 

 

Below a table which maps operators versus instructions :

 

Nota : types of left and right expressions are controlled, eg. we cannot add a string and an integer. In some some cases the types are ‘forced’ as well.

 

operator

token

Generated codes

'<<'

LSHL

fprintf(file_code,"\n\tshl expr_%s_%s, expr_g_%s_%s, expr_d_%s_%s",rtype,bloc,rtypeg,bloc,rtyped,bloc);

'>>'

LSHR

fprintf(file_code,"\n\tshr expr_%s_%s, expr_g_%s_%s, expr_d_%s_%s",rtype,bloc,rtypeg,bloc,rtyped,bloc);

'*'

LMUL

fprintf(file_code,"\n\tmul expr_%s_%s, expr_g_%s_%s, expr_d_%s_%s",rtype,bloc,rtypeg,bloc,rtyped,bloc);

'/'

LDIV

fprintf(file_code,"\n\tdiv expr_%s_%s, expr_g_%s_%s, expr_d_%s_%s",rtype,bloc,rtypeg,bloc,rtyped,bloc);

'%'

LMODULO

fprintf(file_code,"\n\tmod expr_%s_%s, expr_g_%s_%s, expr_d_%s_%s",rtype,bloc,rtypeg,bloc,rtyped,bloc);

'+'

LPLUS

fprintf(file_code,"\n\tadd expr_%s_%s, expr_g_%s_%s, expr_d_%s_%s",rtype,bloc,rtypeg,bloc,rtyped,bloc);

'-'

LMOINS

fprintf(file_code,"\n\tsub expr_%s_%s, expr_g_%s_%s, expr_d_%s_%s",rtype,bloc,rtypeg,bloc,rtyped,bloc);

'&&'

LCOMPET

fprintf(file_code,"\n\tbrtst EQ, false_et_%d, expr_g_%s_%s",ind_et,rtypeg,bloc);

fprintf(file_code,"\n\tbrtst EQ, false_et_%d, expr_d_%s_%s",ind_et, rtyped,bloc);

fprintf(file_code,"\n\tset expr_byte_%s, 1",bloc);

fprintf(file_code,"\n\tjmp fin_test_et_%d",ind_et);

fprintf(file_code,"\nfalse_et_%d:",ind_et);

fprintf(file_code,"\n\tset expr_byte_%s, 0",bloc);

fprintf(file_code,"\nfin_test_et_%d:",ind_et);

'||'

LCOMPOU

 

fprintf(file_code,"\n\tbrtst GT, true_ou_%d, expr_g_%s_%s",ind_ou,rtypeg,bloc);

fprintf(file_code,"\n\tbrtst GT, true_ou_%d, expr_d_%s_%s",ind_ou,rtyped,bloc);

fprintf(file_code,"\n\tset expr_byte_%s, 0",bloc);

fprintf(file_code,"\n\tjmp fin_test_ou_%d",ind_ou);

fprintf(file_code,"\ntrue_ou_%d:",ind_ou);

fprintf(file_code,"\n\tset expr_byte_%s, 1",bloc);

fprintf(file_code,"\nfin_test_ou_%d:",ind_ou);

'<'

LCOMPINF

fprintf(file_code,"\n\tcmp LT, expr_%s_%s, expr_g_%s_%s, expr_d_%s_%s","byte",bloc,rtypeg,bloc,rtyped,bloc);

'>'

LCOMPSUP

fprintf(file_code,"\n\tcmp GT, expr_%s_%s, expr_g_%s_%s, expr_d_%s_%s","byte",bloc,rtypeg,bloc,rtyped,bloc);

'<='

LCOMPINFEG

fprintf(file_code,"\n\tcmp LTEQ, expr_%s_%s, expr_g_%s_%s, expr_d_%s_%s","byte",bloc,rtypeg,bloc,rtyped,bloc);

'>='

LCOMPSUPEG

fprintf(file_code,"\n\tcmp GTEQ, expr_%s_%s, expr_g_%s_%s, expr_d_%s_%s","byte",bloc,rtypeg,bloc,rtyped,bloc);

'=='

LCOMPEG

fprintf(file_code,"\n\tcmp EQ, expr_%s_%s, expr_g_%s_%s, expr_d_%s_%s","byte",bloc,rtypeg,bloc,rtyped,bloc);

'!=’

LCOMPDIFF

fprintf(file_code,"\n\tcmp NEQ, expr_%s_%s, expr_g_%s_%s, expr_d_%s_%s","byte",bloc,rtypeg,bloc,rtyped,bloc);

'|'

LOU

fprintf(file_code,"\n\tor expr_%s_%s, expr_g_%s_%s, expr_d_%s_%s",rtype,bloc,rtypeg,bloc,rtyped,bloc);

'&'

LET

fprintf(file_code,"\n\tand expr_%s_%s, expr_g_%s_%s, expr_d_%s_%s",rtype,bloc,rtypeg,bloc,rtyped,bloc);

'!'

LNON

fprintf(file_code,"\n\tnot expr_%s_%s, expr_%s_%s",rtype,bloc,rtypeg,bloc);

'- unaire'

LNEG

fprintf(file_code,"\n\tneg expr_%s_%s, expr_%s_%s",rtype,bloc,rtypeg,bloc);

'++'

LINC

rtype=genere_recursif(exp->gauche,2,bloc,NULL);

'--'

LDEC

rtype=genere_recursif(exp->gauche,3,bloc,NULL);

Pattern of function call

 

To be completed

 

Pattern of  assignment (SAFFECTATION)

 

To be completed

 

Pattern of ‘if’

 

The ‘if’ condition  follows the following pattern :

 

Expression condition

brcmp EQ, else_main_if_2, expr_byte_main, 0

bloc if

jmp end_main_if_2

else_main_if_2:

bloc else

end_main_if_2:

 

Obviously the “else” bloc is not generated if no ‘else’ is parsed.

 

Sample of code :

 

task main()

 {

            int i;

 

            if(i==1)

                        {

                        }

            else {

                        }

           

 }

 

Sample of generated code :

 

//_________________________________________________

// task main()

// {

thread main

// ALLOCATION DU TABLEAU D'INDEX

            arrinit index_tab_main, 0, 100

// BODY

            arrinit expr_pile_byte_main,   0, 100

            arrinit expr_pile_sbyte_main,  0, 100

            arrinit expr_pile_word_main,   0, 100

            arrinit expr_pile_sword_main,  0, 100

            arrinit expr_pile_dword_main,  0, 100

            arrinit expr_pile_sdword_main, 0, 100

            set expr_ptr_pile_byte_main, 0

            set expr_ptr_pile_sbyte_main, 0

            set expr_ptr_pile_word_main, 0

            set expr_ptr_pile_sword_main, 0

            set expr_ptr_pile_dword_main, 0

            set expr_ptr_pile_sdword_main, 0

//

//

// Index instruction =3 main

// INSTRUCTION BLOC

//-- LISTE INSTRUCTION BLOC nb_inst 1

//-- SOUS INSTRUCTION BLOC 0

//

//

//---- Index instruction =2 main

//---- INSTRUCTION IF

//------ INSTRUCTION IF

// TYPE = byte

            set expr_byte_main, 1

//---------- ATOME 1 OP = 0 TYPE = 43/ENTIER

// TYPED = byte

            mov expr_d_byte_main, expr_byte_main

//PUSH context expr_pile_byte_main

            replace  expr_pile_byte_main, expr_pile_byte_main, expr_ptr_pile_byte_main, expr_d_byte_main

            set inc_main, 1

            add expr_ptr_pile_byte_main, expr_ptr_pile_byte_main, inc_main

// TYPE VARIABLE=int NOM = 'main_i' DIM = 0

            mov expr_word_main, main_i // aff 1

//---------- VARIABLE 'i' type ptr ='normal'

//---------- ident 'i' bloc 'main' valeur '' / type 'int'  'PASPOINTEUR'

//---------- TYPE VARIABLE 'word'

//POP context expr_pile_byte_main

            set inc_main, 1

            sub expr_ptr_pile_byte_main, expr_ptr_pile_byte_main, inc_main

            index expr_d_byte_main, expr_pile_byte_main, expr_ptr_pile_byte_main

// TYPE = word

            mov expr_g_word_main, expr_word_main

//-------- TYPE VARIABLE d='byte' g='word'

// TYPE_RESULTANT word

//-------- OPERATEUR 20/ '=='

            mov expr_d_word_main, expr_d_byte_main

            cmp EQ, expr_byte_main, expr_g_word_main, expr_d_word_main

            brcmp EQ, else_main_if_2, expr_byte_main, 0

//------ THEN

//

//

//-------- Index instruction =0 main

//-------- INSTRUCTION BLOC

//---------- BLOC VIDE

            jmp end_main_if_2

else_main_if_2:

//------ ELSE

//

//

//-------- Index instruction =1 main

//-------- INSTRUCTION BLOC

//---------- BLOC VIDE

end_main_if_2:

endt

 // }

// End of task main()

// End of program

Pattern of ‘for’

 

The ‘for’ loop follows the following pattern :

 

for(init;cond;inc_dec) body

 

pattern :

 

init code

jmp eval_cond_main_for_2

main_for_2:

body code

continue_main_for_2:

inc_dec code

eval_cond_main_for_2:

cond code

brcmp GT, main_for_2, expr_byte_main, 0

break_main_for_2:

 

Sample of code :

 

task main()

 {

            int i;

 

            i=1000;

            for(i=1000;i>0;i--)

             {

             }

 }

 

Sample of generated code :

 

//_________________________________________________

// task main()

// {

thread main

// ALLOCATION DU TABLEAU D'INDEX

            arrinit index_tab_main, 0, 100

// BODY

//

//

// Index instruction =3 main

// INSTRUCTION BLOC

//-- LISTE INSTRUCTION BLOC nb_inst 2

//-- SOUS INSTRUCTION BLOC 0

//

//

//---- Index instruction =0 main

//------ = AFF VARIABLE SIMPLE

// TYPE = word

            set expr_word_main, 1000

//-------- ATOME 1000 OP = 0 TYPE = 43/ENTIER

            mov expr_aff_word_main, expr_word_main // affectation 3

// TYPE VARIABLE=int NOM = 'main_i' DIM = 0

            mov main_i, expr_aff_word_main // aff 3

//-------- VARIABLE 'i' type ptr ='normal'

//-------- ident 'i' bloc 'main' valeur '' / type 'int'  'PASPOINTEUR'

//-------- TYPE VARIABLE 'word'

//------ INSTRUCTION AFFECTATION 167b00 17afe0

//-- SOUS INSTRUCTION BLOC 1

//

//

//---- Index instruction =2 main

//---- INSTRUCTION FOR

//------ INSTRUCTION FOR(AFF1;EXP;INST1)LISTINST

//------ INIT

//------ =

// TYPE = word

            set expr_word_main, 1000

//-------- ATOME 1000 OP = 0 TYPE = 43/ENTIER

            mov expr_aff_word_main, expr_word_main

// TYPE VARIABLE=int NOM = 'main_i' DIM = 0

            mov main_i, expr_aff_word_main // aff 3

//-------- VARIABLE 'i' type ptr ='normal'

//-------- ident 'i' bloc 'main' valeur '' / type 'int'  'PASPOINTEUR'

//-------- TYPE VARIABLE 'word'

            jmp eval_cond_main_for_2

main_for_2:

//------ DEBUT CODE CORPS DU FOR

//

//

//-------- Index instruction =1 main

//-------- INSTRUCTION BLOC

//---------- BLOC VIDE

//------ FIN CODE CORPS DU FOR

continue_main_for_2:

//------ EVOLUTION VARIABLE DU FOR

//------ -- DECREMENT

// TYPE VARIABLE=int NOM = 'main_i' DIM = 0

            set expr_g_word_main, 1

            sub main_i, main_i, expr_g_word_main

            mov expr_word_main, main_i

//-------- VARIABLE 'i' type ptr ='normal'

//-------- ident 'i' bloc 'main' valeur '' / type 'int'  'PASPOINTEUR'

//-------- TYPE VARIABLE 'word'

//------ EVALUATION CONDITION

eval_cond_main_for_2:

// TYPE = byte

            set expr_byte_main, 0

//---------- ATOME 0 OP = 0 TYPE = 43/ENTIER

// TYPED = byte

            mov expr_d_byte_main, expr_byte_main

//PUSH context expr_pile_byte_main

            replace  expr_pile_byte_main, expr_pile_byte_main, expr_ptr_pile_byte_main, expr_d_byte_main

            set inc_main, 1

            add expr_ptr_pile_byte_main, expr_ptr_pile_byte_main, inc_main

// TYPE VARIABLE=int NOM = 'main_i' DIM = 0

            mov expr_word_main, main_i // aff 1

//---------- VARIABLE 'i' type ptr ='normal'

//---------- ident 'i' bloc 'main' valeur '' / type 'int'  'PASPOINTEUR'

//---------- TYPE VARIABLE 'word'

//POP context expr_pile_byte_main

            set inc_main, 1

            sub expr_ptr_pile_byte_main, expr_ptr_pile_byte_main, inc_main

            index expr_d_byte_main, expr_pile_byte_main, expr_ptr_pile_byte_main

// TYPE = word

            mov expr_g_word_main, expr_word_main

//-------- TYPE VARIABLE d='byte' g='word'

// TYPE_RESULTANT word

//-------- OPERATEUR 17/ '>'

            mov expr_d_word_main, expr_d_byte_main

            cmp GT, expr_byte_main, expr_g_word_main, expr_d_word_main

//------ SAUT si EXPRESSION VRAI

            brcmp GT, main_for_2, expr_byte_main, 0

break_main_for_2:

endt

 // }

// End of task main()

// End of program

 

Pattern of ‘switch’

 

To be completed

Pattern of ‘do repeat’

 

To be completed

Pattern of ‘return’

 

To be completed

Pattern of ‘arrsize’

 

To be completed

Pattern of ‘arrinit’

 

To be completed

Pattern of ‘arrsubset’

 

To be completed

Pattern of ‘arrbuild’

 

To be completed

Pattern of ‘precedes’

 

To be completed

Pattern of ‘label’

 

To be completed

Pattern of ‘goto’

 

The ‘goto’ instruction follows the following pattern :

 

jmp main_switch_315_label_test1

            code …

main_switch_315_label_test1:

 

Sample of code :

 

task main()

 {

            goto test1;

           

test1 :

}

Pattern of ‘inline’

 

To be completed

Pattern of ‘acquire’

 

To be completed

Pattern of ‘release’

 

To be completed

 

__________________________________________________________________________________________________________________________________________________________

 

7 - Libraries

 

Below the list of libraries that are currently created.  These libraries are not completed  yet and all “defines” are not defined yet ( eg. #define  MOTOR_A 0x00

#define  MOTOR_B 0x01,  #define  MOTOR_C 0x02  in the motor lib) as well. This work is to be continued !!! if someone wants to give a hand J, you are welcome !

 

The principle is to have a set of libraries which defines a list of COP functions mapped on low level libraries. Below an example which illustrates the use of parameters and the inline instructions.

 

/*******************************/

/* this function rotates motor */

/* forward                     */

/*******************************/

void COP_RotateMotorOnFwd(byte *motors,int power)

 {

            inline "OnFwd(COP_RotateMotorOnFwd_motors,COP_RotateMotorOnFwd_power)";

 }

 

Name of the library

Function

File ( click on it to download )

Comments

display.cop.lib

void COP_SetScreenMode(void)

void COP_DrawText(int x, int y,char *string)

COP_TextOut(sint x, sint y, long cls, char *text)

COP_NumOut(sint x, sint y, long cls,slong number)

COP_PointOut(sint x, sint y,long cls)

COP_LineOut(sint x1, sint y1, sint x2, sint y2, long cls)

COP_RectOut(sint x, sint y, sint width, sint height, long cls)

COP_CircleOut(sint x, sint y, byte radius, long cls)

libraries\display.cop.lib.txt

 

 

Few functions to display information on or graphics on the screen of the NXT.

 

Defines and functions to be completed.

file.cop.lib

byte COP_Fopen(char *name,char *mode)

byte COP_FopenWrite(char *name)

byte COP_FopenRead(char *name)

long COP_Fread(byte handle,mod char *buffer,long length)

long COP_Fwrite(byte handle,char *buffer,long length)

void COP_Fclose(byte handle)

libraries\file.cop.lib.txt

Few functions to manage  files in  the NXT. I’ve not really understood the behaviours of these functions.

 

Defines and functions to be completed.

motor.cop.lib

void COP_RotateMotorOnFwd(byte *motors,int power)

void COP_RotateMotorOnRev(byte *motors,int power)

void COP_RotateMotorOnFwdSync(byte *motors,int power,schar turnpct)

void COP_RotateMotorOnRevSync(byte *motors,int power,schar turnpct)

void COP_RotateMotorStop(byte *motors)

void COP_RotateMotorCoast(byte *motors)

void COP_RotateMotor(byte *motors,int power, sint angle)

void COP_RotateMotorEx(byte *motors,int power, sint angle, char turnpct, schar bsync)

libraries\motor.cop.lib.txt

Few functions to manage motors.

 

Defines and functions to be completed.

sensor.cop.lib

void COP_InitSensors(void)

void COP_SetSensorModeSound_pct(void)

void COP_SetSensorModeSound_raw(void)

void COP_SetSensorModeLight_pct(void)

void COP_SetSensorModeLight_raw(void)

void COP_SetSensorModeUltraSonic_pct(void)

void COP_SetSensorModeUltraSonic_raw(void)

int COP_ReadSoundDetector(void)

int COP_ReadUltraSonicDetector(void)

int COP_ReadLightDetector(void)

int COP_ReadTouchDetector(void)

void COP_ResetTouchDetector(void)

void COP_ResetSoundDetector(void)

void COP_ResetLightDetector(void)

void COP_ResetUltraSonicDetector(void)

libraries\sensor.cop.lib.txt

Few functions to manage sensors.

 

Defines and functions to be completed.

sound.cop.lib

void COP_SoundPlayTone(int freq,int time,byte loop,byte volume)

new : byte COP_SoundGetState(void)

new : byte COP_SoundSetState(byte state, byte flags)

new : byte COP_SoundPlayFile(char *name,byte loop,byte volume)

libraries\sound.cop.lib.txt

Only one function to manage sound.

 

 

string.cop.lib

void COP_NumtoString(int value,mod char *string)

int COP_Strlen(char *src)

void COP_Strcpy(mod char *tab,char *src)

void COP_Strcat(mod char *dest,char *src1, char *src2)

libraries\string.cop.lib.txt

Few functions to manipulate strings.

 

Defines and functions to be completed.

system.cop.lib

void COP_Wait(int time)

void COP_Malloc(mod char *tab,int size)

libraries\system.cop.lib.txt

Few system functions.

 

Defines and functions to be completed.

 

__________________________________________________________________________________________________________________________________________________________

 

8 - Example of COP sources

 

Below a table which points on example of COP files. The purpose of some of them is to test the detection error of the COP compiler or to test that the generated code works correctly.

 

Name of file

COP source file ( click on it to download )

NBC compiled file ( click on it to download )

Comments

aaa_code_expr.cop.txt

ex_sources\aaa_code_expr.cop.txt

ex_sources\aaa_code_expr.cop.nbc

This program tests a simple exepression.

aaa_code_for.cop.txt

ex_sources\aaa_code_for.cop.txt

ex_sources\aaa_code_for.cop.nbc

This program is for testing the ‘for’ loop.

aaa_code_if.cop.txt

ex_sources\aaa_code_if.cop.txt

ex_sources\aaa_code_if.cop.nbc

This source is only for testing the ‘if’ instruction. It doesn’t have a “smart” behaviour if downloaded in the NXT robot.

ess_neg.cop.txt

ex_sources\ess_neg.cop.txt

ex_sources\ess_neg.cop.nbc

This program tests that negative values of counters work correctly.

essai.cop.txt

ex_sources\essai.cop.txt

ex_sources\essai.cop.nbc

This source is only for testing the syntax parser. It doesn’t have a “smart” behaviour if downloaded in the NXT robot.

essai_aff.cop.txt

ex_sources\essai_aff.cop.txt

ex_sources\essai_aff.cop.nbc

Small program to test decrementation of counter in a ‘for’ loop.

essai_arrxxx.cop.txt

ex_sources\essai_arrxxx.cop.txt

ex_sources\essai_arrxxx.cop.nbc

This program is only for testing :

               arrsize,arrinit,arrsubset,arrbuild

essai_chaine1.cop.txt

ex_sources\essai_chaine1.cop.txt

ex_sources\essai_chaine1.cop.nbc

This program is for testing comparison of strings.

essai_diese.cop.txt

ex_sources\essai_diese.cop.txt

 

This source is only for testing the lexical parser.

essai_et_ou.cop.txt

ex_sources\essai_et_ou.cop.txt

ex_sources\essai_et_ou.cop.nbc

This source is only to test ‘&&’ and ‘||’ operators.

essai_et_ou_simp.cop.txt

ex_sources\essai_et_ou_simp.cop.txt

ex_sources\essai_et_ou_simp.cop.nbc

This source is only to test ‘&&’ and ‘||’ operators as well.

essai_fichier.cop.txt

ex_sources\essai_fichier.cop.txt

ex_sources\essai_fichier.cop.nbc

This source is for testing  the file library.

essai_fonction.cop.txt

ex_sources\essai_fonction.cop.txt

ex_sources\essai_fonction.cop.nbc

This source is only for testing the syntax parser. It doesn’t have a “smart” behaviour if downloaded in the NXT robot. It focuses on the calls of function.

essai_fonction1.cop.txt

ex_sources\essai_fonction1.cop.txt

 

This source is only for testing the syntax parser. It doesn’t have a “smart” behaviour if downloaded in the NXT robot. It focuses on the calls of function.

essai_graphic.cop.txt

ex_sources\essai_graphic.cop.txt

ex_sources\essai_graphic.cop.nbc

This source is for testing the graphic file library.

essai_librairie.cop.txt

ex_sources\essai_librairie.cop.txt

ex_sources\essai_librairie.cop.nbc

This source is for testing the motor and sensor libraries.

essai_librairie_def.cop.txt

ex_sources\essai_librairie_def.cop.txt

ex_sources\essai_librairie_def.cop.nbc

The same as above but with defines (eg.  MOTOR_A )

essai_mutex.cop.txt

ex_sources\essai_mutex.cop.txt

ex_sources\essai_mutex.cop.nbc

This source is for testing mutexes.

essai_not.cop.txt

ex_sources\essai_not.cop.txt

ex_sources\essai_not.cop.nbc

This source is only to test !’ (=not) operator.

essai_struc.cop.txt

ex_sources\essai_struc.cop.txt

ex_sources\essai_struc.cop.nbc

This source is only for testing the syntax parser. It doesn’t have a “smart” behaviour if downloaded in the NXT robot. It focuses on arrays and structures.

essai_tab.cop.txt

ex_sources\essai_tab.cop.txt

ex_sources\essai_tab.cop.nbc

This program is for testing multi-dimensionnal arrays.

essai_tableau.cop.txt

ex_sources\essai_tableau.cop.txt

ex_sources\essai_tableau.cop.nbc

This program is for testing assignment of arrays.

essai_taches.cop.txt

ex_sources\essai_taches.cop.txt

ex_sources\essai_taches.cop.nbc

This program is for testing launch of tasks.

essai-for.cop.txt

ex_sources\essai-for.cop.txt

ex_sources\essai-for.cop.nbc

This program is for testing the ‘for’ loop.

essai-switch.cop.txt

ex_sources\essai-switch.cop.txt

ex_sources\essai-switch.cop.nbc

This program is for testing the ‘switch’ instruction.

essai_while.cop.txt

ex_sources\essai_while.cop.txt

ex_sources\essai_while.cop.nbc

This program is for testing the ‘while’ instruction;

essai-test-struct.cop.txt

ex_sources\essai_test_struct.cop.txt

ex_sources\essai_test_struct.cop.nbc

This program is for testing structures, array of structures.

essai-tab3.cop.txt

ex_sources\essai_tab3.cop.txt

ex_sources\essai_tab3.cop.nbc

This program is for testing which index is itself an array, eg. t[y[x]];

essai_return.cop.txt

ex_sources\essai_return.cop.txt

ex_sources\essai_return.cop.nbc

This program is for testing the return instruction.

essai_fonction_simple.cop.txt

ex_sources\essai_fonction_simple.cop.txt

ex_sources\essai_fonction_simple.cop.nbc

This program is for testing simple function calls where parameters are modified.

essai_sound.cop.txt

ex_sources\essai_sound.cop.txt

ex_sources\essai_sound.cop.nbc

This program is for testing the “Sound” library.

 

__________________________________________________________________________________________________________________________________________________________

 

9 - Errors

 

Below, find the specification of errors which can be dectected by COP compiler. Label of each error is meant to help the user to fix errors ( lexical, syntax, and semantic ).

 

Format of an error :

-------> module D:\DELTA\lcc1\source\essai_fonction1.cop.txt line 21 ::

[Fatal Error #SX2190: Variable or function identifier is not defined] token = fonction_lib

 

module in which the error is detected :  D:\DELTA\lcc1\source\essai_fonction1.cop.txt

line in the compiled module : 21

number of the error : #SX2190

Label of the error :  Variable or function identifier is not defined

Current  parsed token : fonction_lib

 

These errors can be divided into 3 categories :

 

-         LeXical error : LX####, detected in PASS 1 ( pre-processing ) and PASS2 ( lexical parsing )

-         SyntaX error : SX####, detected in PASS 3 ( syntax parsing )

-         Code Generation error : GC#### in PASS 4 ( code generation )

 

To help the debug, the C function in which errors are detected, is specified.

In red, find additional information about errors.

 

 

 LX0001 "Fatal Error #LX0001: Allocation Memory Error"

 LX0010 "Fatal Error #LX0010: Allocation Memory Error"

 LX0020 "Fatal Error #LX0020: Lexical parsing Error"

 LX0030 "Fatal Error #LX0030: Lexical parsing Error"

 LX0040 "Fatal Error #LX0040: Missing\" as end of the string"

            Eg. string

 LX0050 "Fatal Error #LX0050: Lexical parsing Error"

 LX0060 "Fatal Error #LX0060: Double defintion of Define\n  lexical parsing of '%s' line =%d '%s' = '%s' \n already defined '%s' line '%d' '%s' = '%s'"

 LX0070 "Fatal Error #LX0070: Lexical parsing Error during parsing of 'define'"                   

 LX0080 "Fatal Error #LX0080: File %s doesn't exist "

 LX0090 "Fatal Error #LX0090: File %s doesn't exist for parsing of 'define' "

 

ajout_variable()

 

 SX0001 "Fatal Error #SX0001: Double declaration of a variable"

            Eg.

                        int a,b;

                        int b;

 SX0010 "Fatal Error #SX0010: Unknown type of variable"   ^

            Eg.

                        Spock a,b,c; and Spoke is not defined.

 

ajout_type()

 

 SX0020 "Fatal Error #SX0030: Double declaration of a structure"

            Eg.

                        struct COORD

 {

                                   int x;

                                   int y;  

 };

struct COORD

 {

                                   int xx;

                                   int yy;

 };

 SX0030 "Fatal Error #SX0030: Unknown structure, internal inconsistency of the compiler"

 SX0040 "Fatal Error #SX0040: Double declaration of field in the same structure"

            Eg.

                        struct COORD

 {

                                   int x;

                                   int x;  

 };

 

 

detecte_fonction()

 

 SX0050 "Fatal Error #SX0050: Unexpected end of file in the global variable zone"

 SX0060 "Fatal Error #SX0060: Unexpected end of file in the global variable zone"

 SX0070 "Fatal Error #SX0070: Unexpected end of file in the global variable zone"

 SX0080 "Fatal Error #SX0080: Unexpected end of file in the global variable zone"

 SX0090 "Fatal Error #SX0090: Identifier or pointer (*) expected"

 SX0100 "Fatal Error #SX0100: Unexpected end of file in the global variable zone"

 SX0110 "Fatal Error #SX0110: Unexpected end of file in the global variable zone"

 SX0120 "Fatal Error #SX0120: Unexpected end of file in the global variable zone"

 SX0130 "Fatal Error #SX0130: Unexpected end of file in the global variable zone"

 

void analyse_variable()

 

 SX0140 "Fatal Error #SX0140: Unexpected end of file in the variable zone"                         

 SX0150 "Fatal Error #SX0150: Unexpected end of file in the variable zone"                            

 SX0160 "Fatal Error #SX0160: Identifier of variable or '*' (pointer) expected "  

 SX0170 "Fatal Error #SX0170: Unexpected end of file in the variable zone"                            

 SX0180 "Fatal Error #SX0180: Indentifier of variable or '*' (pointer) expected"  

 SX0190 "Fatal Error #SX0190: Unexpected end of file in the variable zone"                            

 SX0200 "Fatal Error #SX0200: Identifier of variable is expected"                                          

 SX0210 "Fatal Error #SX0210: Unexpected end of file in the variable zone"                            

 SX0220 "Fatal Error #SX0220: ';' or ',' or '[' is expected"     

            Eg.

                        int a,b;

                        char c

                        int z;   

 SX0230 "Fatal Error #SX0230: Integer expected"                                        

 SX0240 "Fatal Error #SX0240: dimension of array exceeds the limit ( >10 ) "

            Eg.

                        int a[8][8] [8] [8] [8] [8] [8] [8] [8] [8] [8];     

 SX0250 "Fatal Error #SX0250: Unexpected end of file in the variable zone"                            

 SX0260 "Fatal Error #SX0260: ']' is expected"         

            E.g

                        int b[10;                                                                                                       

 SX0270 "Fatal Error #SX0270: Unexpected end of file in the variable zone"                           

 SX0280 "Fatal Error #SX0280: Unexpected end of file in the variable zone"             

 SX0290 "Fatal Error #SX0290: Integer or string expected "  

 SX0300 "Fatal Error #SX0300: Bad initialization of an integer to a bad type of variable ( different from char/byte/int/long) "

            E.g

                        int  a = “toto”;

 SX0310 "Fatal Error #SX0310: Bad initialization of a negative value to a non signed type ( char, int, long ) "

 SX0320 "Fatal Error #SX0320: Value exceeds the capacity of the char or byte "      

            Eg.      

                        byte a = 65535; 

 SX0330 "Fatal Error #SX0330: Value exceeds the capacity of the schar "                              

 SX0340 "Fatal Error #SX0340: Value exceeds the capacity of the int "                                            

 SX0350 "Fatal Error #SX0350: Value exceeds the capacity of the sint "                               

 SX0360 "Fatal Error #SX0360: Value exceeds the capacity of the long "                              

 SX0370 "Fatal Error #SX0370: Value exceeds the capacity of the slong "                              

 SX0380 "Fatal Error #SX0380: Bad initialization of a float "                                                             

 SX0390 "Fatal Error #SX0390: Bad initialisation of a string to a non string type of variable"

 SX0400 "Fatal Error #SX0400: Bad initialization of a string to an array which dimension is above 1 "

            Eg.      

                        char t[10][10] = “kirk”;

 SX0410 "Fatal Error #SX0410: Bad initialization of a string which length exceeds the size of the array of char "

 SX0420 "Fatal Error #SX0420: Unexpected end of file in the variable zone"               

 SX0430 "Fatal Error #SX0430: ',' is expected "                                                       

 SX0440 "Fatal Error #SX0440: Unexpected end of file in the variable zone"             

 SX0450 "Fatal Error #SX0450: Identifier of sructure is expected "                                       

            Eg.

                        struct

                                   {

                                               int a;

                                   }

 SX0460 "Fatal Error #SX0460: Unexpected end of file in the variable zone"             

 SX0470 "Fatal Error #SX0470: '[' is expected "                                                       

 SX0480 "Fatal Error #SX0480: Too many fileds in the definition of the structure "

 SX0490 "Fatal Error #SX0490: Unexpected end of file in the variable zone"               

 SX0500 "Fatal Error #SX0500: Unexpected end of file in the variable zone"             

 SX0510 "Fatal Error #SX0510: Erreur Fatale #S0048 : identifier of field or '*' (pointer) is expected "

 SX0520 "Fatal Error #SX0520: Unexpected end of file in the variable zone"             

 SX0530 "Fatal Error #SX0530: Erreur Fatale #S0050 : identifier of filed or '*' (pointer) is expected "

 SX0540 "Fatal Error #SX0540: Unexpected end of file in the variable zone"             

 SX0550 "Fatal Error #SX0550: Identifier of field is expected "                     

 SX0560 "Fatal Error #SX0560: Unexpected end of file in the variable zone"             

 SX0570 "Fatal Error #SX0570: ';' or ',' or '[' is expected "    

 SX0580 "Fatal Error #SX0580: Integer is expected "                                               

 SX0590 "Fatal Error #SX0590: Dimension of array exceeds the limit ( >10 ) "                     

 SX0600 "Fatal Error #SX0600: Unexpected end of file in the variable zone" 

 SX0610 "Fatal Error #SX0610: ']' is expected "                                           

 SX0620 "Fatal Error #SX0620: ',' is expected "                                           

 SX0630 "Fatal Error #SX0630: Unexpected end of file in the variable zone"             

 SX0640 "Fatal Error #SX0640: Bad definition of structure, no field defined" 

 SX0650 "Fatal Error #SX0650: Unexpected end of file in the variable zone" 

 SX0660 "Fatal Error #SX0660: ';' is expected "                                                       

 SX0670 "Fatal Error #SX0670: Syntax Error in the variale zone "                 

 

compatibilite_type()

 

 SX0675 "Warning Error #SX0675: Types not compatible in expression "                             

 

nouvelle_expression()

 

 SX0680 "Fatal Error #SX0680: Allocation Memory Error"                                                                          

 SX0690 "Fatal Error #SX0690: Types not compatible in expression "                                              

 SX0700 "Fatal Error #SX0700: Unknown Function in the expression "                                              

 SX0710 "Fatal Error #SX0710: Unknown type in the expression "                           

 

analyse_synt_variable_recursive()

 

 SX0720 "Fatal Error #SX0720: Unexpected end of file in the variable zone"             

 SX0730 "Fatal Error #SX0730: Allocation Memory Error"                                                                            

 SX0740 "Fatal Error #SX0740: The number of dimension of array exceeds the declared dimension"

 SX0750 "Fatal Error #SX0750: Unexpected end of file in the variable zone"             

 SX0760 "Fatal Error #SX0760: ']' is expected "                                                                                                      

 SX0770 "Fatal Error #SX0770: Unexpected end of file in the variable zone"             

 SX0780 "Fatal Error #SX0780: Dimension(s) is/are missing in the use of an array "

 SX0790 "Fatal Error #SX0790: Unexpected end of file in the variable zone"             

 SX0800 "Fatal Error #SX0800: Allocation Memory Error"                                                                          

 SX0810 "Fatal Error #SX0810: The number of dimension of array exceeds the declared dimension"

 SX0820 "Fatal Error #SX0820: Unexpected end of file in the variable zone"             

 SX0830 "Fatal Error #SX0830: ']' is expected "                                                                                                      

 SX0840 "Fatal Error #SX0840: Unexpected end of file in the variable zone"             

 SX0850 "Fatal Error #SX0850: Dimension(s) is/are missing in the use of an array as field"

 SX0860 "Fatal Error #SX0860: Unexpected end of file in the variable zone"               

 SX0870 "Fatal Error #SX0870: This variable or field is not an array "                                   

 SX0880 "Fatal Error #SX0880: The type of this variable is not a structure "              

 SX0890 "Fatal Error #SX0890: Unexpected end of file in the variable zone"             

 SX0900 "Fatal Error #SX0900: An identifier of a field of a structure is expected "

 SX0910 "Fatal Error #SX0910: Identifier of field is not declared "                

 SX0920 "Fatal Error #SX0920: Allocation Memory Error"                                                  

 SX0930 "Fatal Error #SX0930: Identifier of field is not declared "                

 SX0940 "Fatal Error #SX0940: Allocation Memory Error"                                                              

 SX0950 "Fatal Error #SX0950: Unexpected end of file in the variable zone"             

 

analyse_synt_variable()

 

 SX0960 "Fatal Error #SX0960: Identifier of variable is not declared "                                  

 SX0970 "Fatal Error #SX0970: Allocation Memory Error"                                                                          

 

analyse_synt_fonction()

 

 SX0980 "Fatal Error #SX0980: Unexpected end of file in the expression/function"      

 SX0990 "Fatal Error #SX0990: '(' is expected in the function call"                                          

 SX1000 "Fatal Error #SX1000: Unexpected end of file in the expression/function"    

 SX1010 "Fatal Error #SX1010: Unexpected end of file in the expression/function"    

 SX1020 "Fatal Error #SX1020: ',' or ')' is expected in the function call "                   

 

analyse_fonction_ou_variable()

 

 SX1030 "Fatal Error #SX1030: Unexpected end of file in the ++/-- pattern"                

 SX1040 "Fatal Error #SX1040: Unexpected end of file in the expression"                              

 SX1050 "Fatal Error #SX1050: Variable or function is not declared in the expression "

 

analyse_indirection()

 

 SX1060 "Fatal Error #SX1060: Unexpected end of file in the *(ptr+index) pattern"                                     

 SX1070 "Fatal Error #SX1070: Identifier of pointer is expected in the *(ptr + index) pattern "          

 SX1080 "Fatal Error #SX1080: The pointer is not declared in the *(ptr + index ) pattern"                

 SX1090 "Fatal Error #SX1090: The variable is not a pointer in the *(ptr+ index ) pattern "               

 SX1100 "Fatal Error #SX1100: Unexpected end of file in the *(ptr+index) pattern"                                     

 SX1110 "Fatal Error #SX1110: '+' is expected in the *(ptr + index ) pattern"                                                          

 SX1120 "Fatal Error #SX1120: Unexpected end of file in the *(ptr+index) pattern"                                     

 SX1130 "Fatal Error #SX1130: ')' is expected in the *(ptr + index) pattern"                                                 

 

analyse_atome()

 

 SX1140 "Fatal Error #SX1140: Unexpected end of file in the expression pattern"     

 SX1150 "Fatal Error #SX1150: Unexpected end of file in the expression pattern"     

 SX1160 "Fatal Error #SX1160: Unexpected end of file in the expression pattern"     

 SX1170 "Fatal Error #SX1170: Unexpected end of file in the expression pattern"     

 SX1180 "Fatal Error #SX1180: Unexpected end of file in the expression pattern"     

 SX1190 "Fatal Error #SX1190: Unexpected end of file in the expression pattern"     

 

analyse_atome_neg()

 

 SX1200 "Fatal Error #SX1200: Unexpected end of file in the 'neg' pattern"

 

analyse_atome_non()

 

 SX1210 "Fatal Error #SX1210: Unexpected end of file in the 'not' pattern"

 

analyse_recursive_shr_shl()

 

 SX1220 "Fatal Error #SX1220: Unexpected end of file in the 'shr'/'shl' pattern"

 

analyse_recursive()

 

 SX1230 "Fatal Error #SX1230: Unexpected end of file in the expression pattern"

 

analyse_recursive_expression_arithmetique()

 

 SX1240 "Fatal Error #SX1240: Unexpected end of file in the arithmetic operator  pattern"

 

analyse_recursive_expression_comparaison()

 

 SX1250 "Fatal Error #SX1250: Unexpected end of file in the comparison operator pattern" 

 

analyse_recursive_expression_logique_et()

 

 SX1260 "Fatal Error #SX1260: Unexpected end of file in the logical operator && pattern"

 

analyse_recursive_expression_logique_ou()

 

 SX1270 "Fatal Error #SX1270: Unexpected end of file in the logical operator || pattern"

 

 

analyse_affectation()

 

 SX1280 "Fatal Error #SX1280: Unexpected end of file in the assignment pattern"

 SX1290 "Fatal Error #SX1290: Unexpected end of file in the assignment pattern"

 SX1300 "Fatal Error #SX1300: Unexpected end of file in the assignment pattern"

 SX1310 "Fatal Error #SX1310: '=' is expected "                                                                                           

 SX1320 "Fatal Error #SX1320: Unexpected end of file in the assignment pattern"

 SX1330 "Fatal Error #SX1330: ')' is not expected"                                                  

 SX1340 "Fatal Error #SX1340: ';' is not expected"                                                              

 SX1350 "Fatal Error #SX1350: Allocation Memory Error"               

 

analyse_if()

 

 SX1360 "Fatal Error #SX1360: Unexpected end of file in the 'if' pattern"         

 SX1370 "Fatal Error #SX1370: '(' is expected in the 'if' pattern"                   

 SX1380 "Fatal Error #SX1380: Unexpected end of file in the 'if' pattern"      

 SX1390 "Fatal Error #SX1390: ')' is expected in the 'if' pattern "                  

 SX1400 "Fatal Error #SX1400: Unexpected end of file in the 'if' pattern"

 SX1410 "Fatal Error #SX1410: Unexpected end of file in the 'if' pattern"

 

analyse_for()

 

 SX1420 "Fatal Error #SX1420: Unexpected end of file in the 'for' pattern"

 SX1430 "Fatal Error #SX1430: '(' is expected in the 'for' pattern "

 SX1440 "Fatal Error #SX1440: Unexpected end of file in the 'for' pattern"

 SX1450 "Fatal Error #SX1450: Unexpected end of file in the 'for' pattern"

 SX1460 "Fatal Error #SX1460: Unexpected end of file in the 'for' pattern"

 SX1470 "Fatal Error #SX1470: ';' is expected in the 'for' pattern"

 SX1480 "Fatal Error #SX1480: Unexpected end of file in the 'for' pattern"

 SX1490 "Fatal Error #SX1490: ';' is expected in the 'for pattern"   

 SX1500 "Fatal Error #SX1500: Unexpected end of file in the 'for' pattern"

 SX1510 "Fatal Error #SX1510: Unexpected end of file in the 'for' pattern"

 SX1520 "Fatal Error #SX1520: Unexpected end of file in the 'for' pattern"

 SX1530 "Fatal Error #SX1530: ')' is expected in the 'for' pattern"

 SX1540 "Fatal Error #SX1540: Unexpected end of file in the 'for' pattern"

 

analyse_do_while()

 

 SX1550 "Fatal Error #SX1550: Unexpected end of file in the 'while' pattern"

 SX1560 "Fatal Error #SX1560: 'while' is expected in the 'while' pattern"    

 SX1570 "Fatal Error #SX1570: Unexpected end of file in the 'while' pattern"

 SX1580 "Fatal Error #SX1580: '(' is expected in the 'while' pattern"      

 SX1590 "Fatal Error #SX1590: Unexpected end of file in the 'while' pattern"

 SX1600 "Fatal Error #SX1600: ')' is expected in the 'while' pattern"             

 SX1610 "Fatal Error #SX1610: Unexpected end of file in the 'while' pattern"

 SX1620 "Fatal Error #SX1620: ';' is expected in hte 'while' pattern"              

 SX1630 "Fatal Error #SX1630: Unexpected end of file in the 'while' pattern"

 

analyse_goto()

 

 SX1640 "Fatal Error #SX1640: Unexpected end of file in the 'goto' pattern" 

 SX1650 "Fatal Error #SX1650: Unexpected end of file in the 'goto' pattern"             

 SX1660 "Fatal Error #SX1660: ';' is expected in the 'goto' pattern"                                                  

 SX1670 "Fatal Error #SX1670: Unexpected end of file in the 'goto' pattern"                         

 SX1680 "Fatal Error #SX1680: identifier of label expected in the 'goto' pattern "      

 

analyse_return()

 

 SX1690 "Fatal Error #SX1690: 'return' in an inappropriate body ( function only )"

 SX1700 "Fatal Error #SX1700: Unexpected end of file in the 'return' pattern"              

 SX1710 "Fatal Error #SX1710: '(' is expected in the 'return' pattern "                         

 SX1720 "Fatal Error #SX1720: Unexpected end of file in the 'return' pattern"           

 SX1730 "Fatal Error #SX1730: ')' expected in the 'return' pattern"                           

 SX1740 "Fatal Error #SX1740: Unexpected end of file in the 'return' pattern"              

 SX1750 "Fatal Error #SX1750: Unexpected end of file in the 'return' pattern"           

 

analyse_break()

 

 SX1760 "Fatal Error #SX1760: Incorrect use of 'break', no 'while' or 'for' loop" 

 SX1765 "Fatal Error #SX1765: Unexpected end of file in the 'break' pattern"     

 SX1770 "Fatal Error #SX1770: ';' is expected in the 'break' pattern "                                   

 SX1780 "Fatal Error #SX1780: Unexpected end of file in the 'break' pattern"                       

 

analyse_continue()

 

 SX1790 "Fatal Error #SX1790: Incorrect use of 'continue', no 'while' or 'for' loop"

 SX1800 "Fatal Error #SX1800: Unexpected end of file in the 'continue' pattern"                     

 SX1810 "Fatal Error #SX1810: ';' is expected "                                                                                                      

 SX1820 "Fatal Error #SX1820: Unexpected end of file in the 'continue' pattern"                   

 

analyse_switch()

 

 SX1830 "Fatal Error #SX1830: Unexpected end of file in the 'switch' pattern"          

 SX1840 "Fatal Error #SX1840: '{' is expected in the 'switch' pattern"                       

 SX1850 "Fatal Error #SX1850: Unexpected end of file in the 'switch' pattern"          

 SX1855 "Fatal Error #SX1855: 'case' or 'default' is expected in the 'switch' pattern"

 SX1857 "Fatal Error #SX1857: Unexpected end of file in the 'switch' pattern"                      

 SX1860 "Fatal Error #SX1860: Unexpected end of file in the 'switch' pattern"                      

 SX1870 "Fatal Error #SX1870: ':' is expected after 'case' or 'default' in the 'switch' pattern"

 SX1880 "Fatal Error #SX1880: Unexpected end of file in the 'switch' pattern"                      

 SX1890 "Fatal Error #SX1890: Unexpected end of file in the 'switch' pattern"                      

 SX1900 "Fatal Error #SX1900: ';' is expected in the 'switch' pattern"                        

 SX1910 "Fatal Error #SX1910: Unexpected end of file in the 'switch' pattern"                      

 SX1920 "Fatal Error #SX1920: Unexpected end of file in the 'switch' pattern"                      

 SX1930 "Fatal Error #SX1930: ';' is expected after 'case' or 'default' in the 'switch' pattern"

 SX1940 "Fatal Error #SX1940: Unexpected end of file in the 'switch' pattern"                      

 SX1950 "Fatal Error #SX1950: Number of 'case' too important in the 'switch' pattern"         

 SX1960 "Fatal Error #SX1960: Unexpected end of file in the 'switch' pattern"                      

 

analyse_exit()

 

 SX1970 "Fatal Error #SX1970: Unexpected end of file in the 'exit' pattern"

 SX1980 "Fatal Error #SX1980: '(' is expected in the 'exit' pattern"

 SX1990 "Fatal Error #SX1990: Unexpected end of file in the 'exit' pattern"

 SX2000 "Fatal Error #SX2000: ')' is expected in the 'exit' pattern"

 SX2010 "Fatal Error #SX2010: Unexpected end of file in the 'exit' pattern"

 SX2020 "Fatal Error #SX2020: ';' is expected in the 'exit' pattern"

 SX2030 "Fatal Error #SX2030: Unexpected end of file in the 'exit' pattern"

 

 

analyse_precedes()

 

 SX2040 "Fatal Error #SX2040: Unexpected end of file in the 'precedes' pattern"

 SX2050 "Fatal Error #SX2050: Too many tasks in the 'precede' pattern"

 SX2060 "Fatal Error #SX2060: Unexpected end of file in the 'precedes' pattern"

 SX2070 "Fatal Error #SX2070: ',' or ';' is expected in the 'precedes' pattern"

 SX2080 "Fatal Error #SX2080: Unexpected end of file in the 'precedes' pattern"

 SX2090 "Fatal Error #SX2090: Identifier of 'task' is expected "

 SX2100 "Fatal Error #SX2100: Unexpected end of file in the 'precedes' pattern"

 

analyse_lident()

 

 SX2110 "Fatal Error #SX2110: Unexpected end of file in the 'Identifier' pattern ( label, variable, function )"

 SX2120 "Fatal Error #SX2120: Unexpected end of file in the 'Identifier' pattern ( label, variable, function )"

 SX2130 "Fatal Error #SX2130: Unexpected end of file in the 'Identifier' pattern ( label, variable, function )"

 SX2140 "Fatal Error #SX2140: Unexpected end of file in the 'Identifier' pattern ( label, variable, function )"

 SX2150 "Fatal Error #SX2150: Unexpected end of file in the 'Identifier' pattern ( label, variable, function )"

 SX2160 "Fatal Error #SX2160: ';' is expected after assignment"                                                                  

 SX2170 "Fatal Error #SX2170: Unexpected end of file in the 'Assignment' pattern"                                      

 SX2180 "Fatal Error #SX2180: Indirection '*' or '**' of function doesn't exist "                                           

 SX2190 "Fatal Error #SX2190: Variable or function identifier is not defined"                                               

 SX2200 "Fatal Error #SX2200: ')' is expected"                                                                                                       

 SX2210 "Fatal Error #SX2210: Unexpected end of file in the call of function"                                                          

 SX2220 "Fatal Error #SX2220: ';' is expected after the call of function"                                                       

 SX2230 "Fatal Error #SX2230: Unexpected end of file in the call of function"                                                                                  

 

analyse_pointeur()

 

 SX2240 "Fatal Error #SX2240: Unexpected end of file in the '*(variable+index)' pattern"                                                                

 SX2250 "Fatal Error #SX2250: ';' is expected after assignment "                                                                                                     

 SX2260 "Fatal Error #SX2260: ';' is expected after assignment "                                                                                                                                        

 SX2270 "Fatal Error #SX2270: Unexpected end of file in the 'Assignment' pattern"                                                                           

 SX2280 "Fatal Error #SX2280: Allocation Memory Error"                                                                                                                                                            

 

analyse_inline()

 

 SX2290 "Fatal Error #SX2290: Unexpected end of file in the 'inline' pattern"                                                                                                  

 SX2300 "Fatal Error #SX2300: nbc instruction is expected in the 'inline' pattern"                                                                                

 SX2310 "Fatal Error #SX2310: Unexpected end of file in the 'inline' pattern"                                                                                                 

 SX2320 "Fatal Error #SX2320: ';' is expected in the 'inline' pattern"                                                                                                               

 SX2340 "Fatal Error #SX2340: Unexpected end of file in the 'inline' pattern"                                                                                                

 

analyse_acquire()

 

 SX2350 "Fatal Error #SX2350: Unexpected end of file in the 'acquire' pattern"                    

 SX2360 "Fatal Error #SX2360: '(' is expected in the 'acquire' pattern"                      

 SX2370 "Fatal Error #SX2370: Unexpected end of file in the 'acquire' pattern"                    

 SX2380 "Fatal Error #SX2380: Mutex Identifier is expected in the 'acquire' pattern"

 SX2390 "Fatal Error #SX2390: Unexpected end of file in the 'acquire' pattern"                    

 SX2400 "Fatal Error #SX2400: ')' is expected in the 'acquire' pattern"                                  

 SX2410 "Fatal Error #SX2410: Unexpected end of file in the 'acquire' pattern"                    

 SX2420 "Fatal Error #SX2420: ';' is expected in the 'acquire' pattern"                                  

 SX2430 "Fatal Error #SX2430: Unexpected end of file in the 'acquire' pattern"                    

 

analyse_release()

 

 SX2440 "Fatal Error #SX2440: Unexpected end of file in the 'release' pattern "                    

 SX2450 "Fatal Error #SX2450: '(' is expected in the 'release' pattern "                     

 SX2460 "Fatal Error #SX2460: Unexpected end of file in the 'release' pattern"                     

 SX2470 "Fatal Error #SX2470: Mutex Identifier in the 'release' pattern"                   

 SX2480 "Fatal Error #SX2480: Unexpected end of file in the 'release' pattern"                     

 SX2490 "Fatal Error #SX2490: ')' is expected in the in the 'release' pattern"             

 SX2500 "Fatal Error #SX2500: Unexpected end of file in the 'release' pattern"                     

 SX2510 "Fatal Error #SX2510: ';' is expected in the 'release' pattern"                                  

 SX2520 "Fatal Error #SX2520: Unexpected end of file in the 'release' pattern"                     

 

analyse_arrsize()

 

 SX2530 "Fatal Error #SX2530: Unexpected end of file in the 'arrsize' pattern "                        

 SX2540 "Fatal Error #SX2540: '(' is expected in the 'arrsize' pattern"                       

 SX2560 "Fatal Error #SX2560: Unexpected end of file in the 'arrsize' pattern "                        

 SX2570 "Fatal Error #SX2570: Identifier of array is expected in the 'arrsize' pattern"

 SX2580 "Fatal Error #SX2580: Unexpected end of file in the 'arrsize' pattern "                        

 SX2590 "Fatal Error #SX2590: ',' is expected in the 'arrsize' pattern"                       

 SX2600 "Fatal Error #SX2600: Unexpected end of file in the 'arrsize' pattern "                        

 SX2610 "Fatal Error #SX2610: Identifier of array is expected in the 'arrsize' pattern"

 SX2620 "Fatal Error #SX2620: Unexpected end of file in the 'arrsize' pattern "                        

 SX2630 "Fatal Error #SX2630: ')' is expected in the 'arrsize' pattern"                       

 SX2640 "Fatal Error #SX2640: Unexpected end of file in the 'arrsize' pattern "                      

 SX2650 "Fatal Error #SX2650: ';' is expected in the 'arrsize' pattern"                       

 SX2660 "Fatal Error #SX2660: Unexpected end of file in the 'arrsize' pattern "                        

 SX2670 "Fatal Error #SX2670: Identifier of array not defined in the 'arrsize' pattern"

 SX2680 "Fatal Error #SX2680: the identifier '%s' size is not declared in the 'arrsize' pattern" 

 SX2690 "Fatal Error #SX2690: the identifier '%s' array is not declared in the 'arrsize' pattern"

 SX2700 "Fatal Error #SX2700: the type of the identifier '%s' size is not an integer in the 'arrsize' pattern "

 

analyse_arrinit()

 

 SX2710 "Fatal Error #SX2710: Unexpected end of file in the 'arrinit' pattern "          

 SX2720 "Fatal Error #SX2720: '(' is expected in the 'arrinit' pattern "                       

 SX2730 "Fatal Error #SX2730: Unexpected end of file in the 'arrinit' pattern "          

 SX2740 "Fatal Error #SX2740: Identifier of array is expected in the 'arrinit' pattern "

 SX2750 "Fatal Error #SX2750: Unexpected end of file in the 'arrinit' pattern " 

 SX2760 "Fatal Error #SX2760: ',' is expected in the 'arrinit' pattern "                        

 SX2770 "Fatal Error #SX2770: Unexpected end of file in the 'arrinit' pattern " 

 SX2780 "Fatal Error #SX2780: ',' is expected in the 'arrinit' pattern "                        

 SX2790 "Fatal Error #SX2790: Unexpected end of file in the 'arrinit' pattern " 

 SX2800 "Fatal Error #SX2800: ')' is expected in the 'arrinit' pattern "            

 SX2810 "Fatal Error #SX2810: Unexpected end of file in the 'arrinit' pattern " 

 SX2820 "Fatal Error #SX2820: ';' is expected in the 'arrinit' pattern "            

 SX2830 "Fatal Error #SX2830: Unexpected end of file in the 'arrinit' pattern " 

 SX2840 "Fatal Error #SX2840: the identifier '%s' array is not declared in the 'arrinit' pattern"                                                           

 SX2850 "Fatal Error #SX2850: the identifier '%s' array is not an array or a pointer (*) in the 'arrinit' pattern"            

 

analyse_arrsubset()

 

 SX2860 "Fatal Error #SX2860: Unexpected end of file in the 'arrsubset' pattern "                            

 SX2870 "Fatal Error #SX2870: '(' is expected in the 'arrsubset' pattern "                                          

 SX2880 "Fatal Error #SX2880: Unexpected end of file in the 'arrsubset' pattern "                 

 SX2890 "Fatal Error #SX2890: Identifier of array is expected in the 'arrsubset' pattern "       

 SX3000 "Fatal Error #SX3000: Unexpected end of file in the 'arrsubset' pattern "                 

 SX3010 "Fatal Error #SX3010: ',' is expected in the 'arrsubset' pattern"                               

 SX3020 "Fatal Error #SX3020: Unexpected end of file in the 'arrsubset' pattern "                 

 SX3030 "Fatal Error #SX3030: Identifier of array is expected in the 'arrsubset' pattern"        

 SX3040 "Fatal Error #SX3040: Unexpected end of file in the 'arrsubset' pattern "                 

 SX3050 "Fatal Error #SX3050: ',' is expected in the 'arrsubset' pattern "                              

 SX3060 "Fatal Error #SX3060: Unexpected end of file in the 'arrsubset' pattern "                 

 SX3070 "Fatal Error #SX3070: ',' is expected in the 'arrsubset' pattern "                              

 SX3080 "Fatal Error #SX3080: Unexpected end of file in the 'arrsubset' pattern "                 

 SX3090 "Fatal Error #SX3090: ')' is expected in the 'arrsubset' pattern "                              

 SX3100 "Fatal Error #SX3100: Unexpected end of file in the 'arrsubset' pattern "                 

 SX3110 "Fatal Error #SX3110: ';' is expected in the 'arrsubset' pattern"                               

 SX3120 "Fatal Error #SX3120: Unexpected end of file in the 'arrsubset' pattern "                 

 SX3130 "Fatal Error #SX3130: the identifier '%s' src array is not declared in the 'arrsubset' pattern"

 SX3140 "Fatal Error #SX3140: the identifier '%s' dst array is not declared in the 'arrsubset' pattern"

 SX3150 "Fatal Error #SX3150: the identifier '%s' src array is not an array or pointer (*) in the 'arrsubset' pattern"

 SX3160 "Fatal Error #SX3160: the identifier '%s' dst array is not an array or pointer (*) in the 'arrsubset' pattern"

 

analyse_arrbuild()

 

 SX3170 "Fatal Error #SX3170: Unexpected end of file in the 'arrbuild' pattern "

 SX3180 "Fatal Error #SX3180: '(' is expected in the 'arrbuild' pattern "                                            

 SX3190 "Fatal Error #SX3190: Unexpected end of file in the 'arrbuild' pattern "                   

 SX3200 "Fatal Error #SX3200: Too many identifiers in the 'arrbuild' pattern "                                  

 SX3210 "Fatal Error #SX3210: Identifier of array is expected in the 'arrbuild' pattern "         

 SX3220 "Fatal Error #SX3220: Unexpected end of file in the 'arrbuild' pattern "                   

 SX3230 "Fatal Error #SX3230: Unexpected end of file in the 'arrbuild' pattern "                   

 SX3240 "Fatal Error #SX3240: ')' is expected in the arrbuild 'pattern' "                                

 SX3250 "Fatal Error #SX3250: Unexpected end of file in the 'arrbuild' pattern "                   

 SX3260 "Fatal Error #SX3260: ';' is expected in the 'arrbuild' pattern "                                

 SX3270 "Fatal Error #SX3270: Unexpected end of file in the 'arrbuild' pattern "                   

 SX3280 "Fatal Error #SX3280: the identifier '%s' size is not declared in the 'arrbuild' pattern"                                  

 SX3290 "Fatal Error #SX3290: the identifier '%s' array is not an array or pointer (*) in the 'arrbuild' pattern"           

 

analyse_liste_instruction()

 

 SX3300 "Fatal Error #SX3300: Unexpected end of file in the 'list of instructions' pattern "

 SX3310 "Fatal Error #SX3310: Unexpected end of file in the 'list of instructions' pattern "

 SX3320 "Fatal Error #SX3320: Allocation Memory Error"                                                                                                             

 SX3340 "Fatal Error #SX3340: Bad format of instruction "

 SX3350 "Fatal Error #SX3350: Allocation Memory Error"   

 SX3360 "Fatal Error #SX3360: Bad format of instruction"

 

analyse_fonction()

 

 SX3370 "Fatal Error #SX3370: Unexpected end of file in the 'function type' pattern "               

 SX3380 "Fatal Error #SX3380: Unexpected end of file in the 'function type' pattern "                       

 SX3390 "Fatal Error #SX3390: An identifier of type is expected in the 'function' pattern "     

 SX3400 "Fatal Error #SX3400: The returned type is not defined in the 'function' pattern " 

 SX3410 "Fatal Error #SX3410: Unexpected end of file in the 'function' pattern "       

 SX3420 "Fatal Error #SX3420: A pointer (*) or a pointer of pointer (**) is expected "            

 SX3430 "Fatal Error #SX3430: Unexpected end of file in the 'function type' pattern "                       

 SX3440 "Fatal Error #SX3440: A pointer (*) or a pointer of pointer (**) is expected "                    

 SX3450 "Fatal Error #SX3450: Unexpected end of file in the 'function type' pattern "                                   

 SX3460 "Fatal Error #SX3460: ')' is expected in the 'function' pattern"                                 

 SX3470 "Fatal Error #SX3470: Unexpected end of file in the 'function type' pattern "                                   

 SX3480 "Fatal Error #SX3480: The returned type is not defined in the 'function' pattern"                  

 SX3490 "Fatal Error #SX3490: The returned type is not defined in the 'function' pattern"                  

 SX3500 "Fatal Error #SX3500: Unexpected end of file in the 'function type' pattern "                                              

 SX3510 "Fatal Error #SX3510: An identifier of function is expected in the 'function' pattern"            

 SX3520 "Fatal Error #SX3520: Double declaration of function in the 'function' pattern"                    

 SX3530 "Fatal Error #SX3530: Unexpected end of file in the 'function type' pattern "                                   

 SX3540 "Fatal Error #SX3540: '(' is expected in the 'function (argument) pattern"                                        

 SX3550 "Fatal Error #SX3550: Unexpected end of file in the 'function(argument)' pattern "                          

 SX3560 "Fatal Error #SX3560: Unexpected end of file in the 'function(mod argument)' pattern "                  

 SX3570 "Fatal Error #SX3570: The type of the argument is not defined in the 'function(argument) pattern"

 SX3580 "Fatal Error #SX3580: Unexpected end of file in the 'function(argument)' pattern "                          

 SX3590 "Fatal Error #SX3590: A pointer (*) or a pointer of pointer (**) is expected in the 'function' pattern "

 SX3600 "Fatal Error #SX3600: Unexpected end of file in the 'function(argument)' pattern "                                      

 SX3610 "Fatal Error #SX3610: An identifier of argument or a pointer of pointer (**) is expected in the 'function' pattern"

 SX3620 "Fatal Error #SX3620: Unexpected end of file in the 'function(argument)' pattern "              

 SX3630 "Fatal Error #SX3630: An identifier of argument is expected in the 'function' pattern"                      

 SX3640 "Fatal Error #SX3640: Unexpected end of file in the 'function(argument)' pattern "                          

 SX3650 "Fatal Error #SX3650: A ',' or ')' is expected in the 'function' pattern"                     

 SX3660 "Fatal Error #SX3660: Unexpected end of file in the 'function' pattern "                   

 SX3670 "Fatal Error #SX3670: A '{' is expected as a begin of the body of the function"                              

 SX3680 "Fatal Error #SX3680: A '}' is expected as an end of body of the function"

 

analyse_mutex()

 

 SX3690 "Fatal Error #SX3690: Unexpected end of file in the 'mutex' pattern "                     

 SX3700 "Fatal Error #SX3700: An identifier of mutex is expected in the 'mutex' pattern"

 SX3710 "Fatal Error #SX3710: Double declaration of mutex '%s', module '%s' - line '%d' / module '%s' - line '%d' "

 SX3720 "Fatal Error #SX3720: ',' or ';' is expected in the 'mutex' pattern"                                        

 SX3730 "Fatal Error #SX3730: ',' is expected in the 'mutex' pattern" 

 

 

analyse_tache()

 

 SX3740 "Fatal Error #SX3740: Unexpected end of file in the 'task' pattern "            

 SX3750 "Fatal Error #SX3750: Identifier of task is expected "                                                                    

 SX3760 "Fatal Error #SX3760: Unexpected end of file in the 'task' pattern "                        

 SX3770 "Fatal Error #SX3770: '(' is expected in the 'task' pattern "                          

 SX3780 "Fatal Error #SX3780: Unexpected end of file in the 'task' pattern "                                   

 SX3790 "Fatal Error #SX3810: ')' is expected in the 'task' pattern"                                      

 SX3800 "Fatal Error #SX3800: Unexpected end of file in the 'task' pattern "                        

 SX3810 "Fatal Error #SX3810: A '{' is expected as a begin of the body of the task"              

 SX3820 "Fatal Error #SX3820: A '}' is expected as an end of body of the task"                              

 

 

 

 GC0001 "Fatal Error #GC0001: Internal error, value of the Stack Pointer dedicated to Loops exceed the limit  (>1000)"

 GC0020 "Fatal Error #GC0020: Internal error, negative value of the Stack Pointer dedicated to Loops  (<-1) "

 GC0030 "Fatal Error #GC0030: Internal error, negative value of the Stack Pointer dedicated to Loops  (<0) "

 GC0040 "Fatal Error #GC0040: bloc=%s variable=%s type=%s dimension of the expression %d is incorrect"

 GC0050 "Fatal Error #GC0050: bloc=%s variable=%s type=%s dimension of the expression %d is incorrect"

 GC0060 "Fatal Error #GC0060: bloc=%s variable=%s type=%s expression not compliant with '++'"

 GC0070 "Fatal Error #GC0070: bloc=%s variable=%s type=%s expression not compliant with '--'"

 GC0080 "Fatal Error #GC0080: bloc=%s typeg=%s typed=%s typer=%s "

 GC0090 "Fatal Error #GC0090: bloc=%s type=%s not compliant with the types of operator 'SHL' "

 GC0100 "Fatal Error #GC0100: bloc=%s type=%s not compliant with the types of operator 'SHR' "

 GC0110 "Fatal Error #GC0110: bloc=%s type=%s not compliant with the types of operator 'MUL' "

 GC0120 "Fatal Error #GC0120: bloc=%s type=%s not compliant with the types of operator 'DIV' "

 GC0130 "Fatal Error #GC0130: bloc=%s type=%s not compliant with the types of operator'MODULO' "

 GC0140 "Fatal Error #GC0140: bloc=%s type=%s not compliant with the types of operator 'PLUS' "

 GC0150 "Fatal Error #GC0150: bloc=%s type=%s not compliant with the types of operator 'MINUS' "

 GC0160 "Fatal Error #GC0160: bloc=%s type=%s not compliant with the types of operator '<' "

 GC0170 "Fatal Error #GC0170: bloc=%s type=%s not compliant with the types of operator '>' "

 GC0180 "Fatal Error #GC0180: bloc=%s type=%s not compliant with the types of operator '<=' "

 GC0190 "Fatal Error #GC0190: bloc=%s type=%s not compliant with the types of operator '>=' "

 GC0200 "Fatal Error #GC0200: bloc=%s type=%s not compliant with the types of operator '|' "

 GC0210 "Fatal Error #GC0210: bloc=%s type=%s not compliant with the types of operator '&' "

 GC0220 "Fatal Error #GC0220: bloc=%s type=%s not compliant with the types of operator '!' "

 GC0230 "Fatal Error #GC0230: bloc=%s type=%s not compliant with the types of operator '- unaire' "

 GC0240 "Fatal Error #GC0240: bloc=%s type=%s not compliant with the types of operator '++' "

 GC0250 "Fatal Error #GC0250: bloc=%s type=%s not compliant with the types of operator '--' "

 GC0260 "Fatal Error #GC0260: bloc=%s function '%s' is not defined "

 GC0270 "Fatal Error #GC0270: bloc=%s fonction '%s' missing parameter(s) %d/%d "

 GC0280 "Fatal Error #GC0280: bloc=%s function '%s' types '%s' not compliant with the type '%s' of parameter '%s' "

 GC0290 "Fatal Error #GC0290: bloc=%s function'%s', type of the variable '%s' not compliant with the type '%s' of parameter '%s' "

 GC0300 "Fatal Error #GC0300: bloc=%s type=%s not compliant in the instruction 'while'"

 GC0310 "Fatal Error #GC0310: bloc=%s type=%s not compliant in the instruction 'for' (initialization)"

 GC0320 "Fatal Error #GC0320: bloc=%s type=%s not compliant in the instruction 'for' (test)"

 GC0330 "Fatal Error #GC0330: bloc=%s type=%s not compliant in the instruction 'for' (increment)"

 GC0340 "Fatal Error #GC0340: bloc=%s type=%s not compliant in the instruction 'if'"

 GC0350 "Fatal Error #GC0350: Goto '%s' is not defined in function/task = '%s'"

 GC0360 "Fatal Error #GC0360: Double definition of label '%s' in function/task = '%s'"

 GC0370 "Fatal Error #GC0370: Unknown task '%s' used as parameter by 'precede' in '%s'"

 GC0380 "Fatal Error #GC0380: bloc=%s type=%s bad type for the 'switch'"

 GC0390 "Fatal Error #GC0390: bloc=%s type=%s bad type for the 'switch'"

 GC0400 "Fatal Error #GC0400: bloc '%s' - Unknown mutex '%s' in the call of 'Acquire()'"

 GC0410 "Fatal Error #GC0410: bloc '%s' - Unknown mutex '%s' in the call of 'Release()'"

 GC0420 "Fatal Error #GC0420: bloc=%s type=%s not compliant with the type of the parameter 'size' "

 GC0430 "Fatal Error #GC0430: bloc=%s type=%s not compliant with the type of the parameter 'index' "

 GC0440 "Fatal Error #GC0440: bloc=%s type=%s not compliant with the type of the parameter 'length' "

 GC0450 "Fatal Error #GC0450: Unknow function '%s'"

 GC0460 "Fatal Error #GC0460: Functionn '%s', returns a bad type '%s' : '%s'"

 GC0470 "Fatal Error #GC0470: Function '%s', returns a bad type '%s' : '%s'"

 GC0480 "Fatal Error #GC0480: Incorrect assignment of a void type to the variable '%s' "

 GC0490 "Fatal Error #GC0490: Incorrect assignment of a void type to the variable '%s' "

 GC0500 "Fatal Error #GC0500: Failure of the creation of the '.nbc' file"

__________________________________________________________________________________________________________________________________________________________

 

10 – Download section : sources, files and executable 

 

Download this zip file to get the entire binairy, library and examples of COP sources : package

 

Below the C sources of the COP compiler.

 

Name of file

File ( click on it to download )

Type

Comments

cop.c

C_sources\cop.c

.C source

Main module which manages GUI and calls to other modules

lexical.c

C_sources\lexical.c

.C source

Lexical parsing

syntaxique.c

C_sources\syntaxique.c

.C source

Syntaxical parsing

genere_code.c

C_sources\genere_code.c

.C source

Generation of COP codes

delta_encrier.h

C_sources\delta_encrier.h

.H source

Defines and C structures

cop.exe

compiled_file\cop.exe

.EXE executable

Executable file

 

__________________________________________________________________________________________________________________________________________________________

 

11 – Fixed bugs

 

version 1.1 ( 21st August 2007 )

-         modified parameters are now correctly generated, eg. f(x); and void f(mod int y) {}

-         parameters which are passed by reference are now correctly generated, eg. int t[10]; f(t); and void f(mod int *a) {}

-         pointer are now coorectly generated,eg. *(t+index) = y;

-         now, the compiler generates codes only if functions are called.

 

__________________________________________________________________________________________________________________________________________________________

 

12 – Annexes

 

12.1 genere_instruction() function :

 

 

void genere_instruction(INSTRUCTION *inst,char *bloc)

  {

              char *rtype,*rtype1,*rtype2;

 

              monte();

 

 

            /*  printf("\n instruction %s %d",bloc,inst->type_instruction);*/

 

              if(inst==NULL)

               {

                                     /*if(traceaff==1) printf("\n%s FEUILLE ",affiche);*/

       }

              else

               {

 

                           if(etat_trace2==1) fprintf(file_code,"\n//\n//\n//%s Index instruction =%d %s", affiche,((char *)inst-(char *)&tab_instruction[0])/sizeof(INSTRUCTION),inst->bloc);

 

                           switch(inst->type_instruction)

                             {

                                               case INST_INLINE:

                                                  {

                                                              if(etat_trace2==1) fprintf(file_code,"\n//%s INLINE ", affiche);

                                                              fprintf(file_code,"\n\t%s", inst->instruction.sinline);

                                                  }break;

                                               case INST_IF :

                                                           {

                                                                                   if(etat_trace2==1) fprintf(file_code,"\n//%s INSTRUCTION IF ", affiche);

 

                                                                                   genere_inst_if(inst,bloc);

                                                           }break;

                                               case INST_FOR :

                                                           {

                                                                                    if(etat_trace2==1) fprintf(file_code,"\n//%s INSTRUCTION FOR ", affiche);

                                                                                   genere_inst_for(inst,bloc);

                                                           }break;

                                               case INST_DO_REPEAT :

                                                           {

                                                                                  if(etat_trace2==1) fprintf(file_code,"\n//%s DO WHILE ", affiche);

                                                                                  genere_inst_do_while(inst,bloc);

                                                           }break;

                                               case INST_SWITCH :

                                                           {

                                                                       int i;

 

                                                                       if(etat_trace2==1) fprintf(file_code,"\n//%s__________________________________________________________________________________",affiche);

                                                                       if(etat_trace2==1) fprintf(file_code,"\n//%s INSTRUCTION SWITCH ",affiche);

                                                                       if(etat_trace2==1) fprintf(file_code,"\n//%s INSTRUCTION EXPRESSION ",affiche);

 

                                                                       if(inst->instruction.sswitch.nb_case>0)

                                                                                  {

                                                                                              rtype=genere_recursif(inst->instruction.sswitch.expression,0,bloc,NULL);

 

                                                                                              if(recherche_atome(rtype)==-1)

                                                                                                          {

                                                                                                                      char libelle[200];

 

                                                                                                                      sprintf(libelle,"\nErreur Fatale #GC0050 : bloc=%s type=%s affectation switch inadaptee",

                                                                                                                                                                     bloc,rtype);

                                                                                                                      message_erreur(libelle);

                                                                                                          }

 

                                                                                              fprintf(file_code,"\n\tmov expr_switch_%d, expr_%s_%s",inst->index,rtype,bloc);

                                                                                              fprintf(file_code,"\n//%s CORPS SWITCH NB CASE = %d ",affiche,inst->instruction.sswitch.nb_case);

                                                                                  }

                                                                       else if(etat_trace2==1) fprintf(file_code,"\n//%s CORPS SWITCH VIDE",affiche);

 

                                                                       for(i=0;i<inst->instruction.sswitch.nb_case;i++)

                                                                        {

                                                                                  int j;

 

                                                                                  monte();

 

                                                                                  if(etat_trace2==1) fprintf(file_code,"\n//%s case/default %d",affiche,i);

 

                                                                                  if(inst->instruction.sswitch.type_case[i]==TYPE_CASE_CASE)

                                                                                              {

                                                                                                          if(etat_trace2==1) fprintf(file_code,"\n//%s CASE ",affiche);

                                                                                              }

                                                                                  else

                                                                                              {

                                                                                                          if(etat_trace2==1) fprintf(file_code,"\n//%s DEFAULT ",affiche);

                                                                                              }

 

                                                                                  monte();

 

                                                                                  if(inst->instruction.sswitch.expression_case[i]==NULL)

                                                                                              {

                                                                                                          if(etat_trace2==1) fprintf(file_code,"\n//%s EXPRESSION VIDE",affiche);

                                                                                      }

                                                                                  else

                                                                                              {

                                                                                                          if(etat_trace2==1) fprintf(file_code,"\n//%s EXPRESSION CASE #%d",affiche,i+1);

                                                                                                          rtype1=genere_recursif(inst->instruction.sswitch.expression_case[i],0,bloc,NULL);

 

                                                                                                          if(recherche_atome(rtype1)==-1)

                                                                                                                      {

                                                                                                                                 char libelle[200];

 

                                                                                                                                 sprintf(libelle,"\nErreur Fatale #GC0051 : bloc=%s type=%s affectation switch inadaptee",

                                                                                                                                                                     bloc,rtype1);

                                                                                                                                  message_erreur(libelle);

                                                                                                                      }

/* correctif 14-04-07 */

                                                                                                          fprintf(file_code,"\n\tmov expr_sdword_%s, expr_%s_%s ",

                                                                                                                                 bloc,rtype1,bloc);

/* correctif 14-04-07 */

                                                                                                          fprintf(file_code,"\n\tbrcmp NEQ, %s_switch_%d_case_%d, expr_switch_%d, expr_%s_%s ",

                                                                                                                                 inst->bloc,inst->index,i+1,inst->index,"sdword",bloc);

                                                                                              }

 

                                                                                  descend();

 

                                                                                  if(inst->instruction.sswitch.cases[i]==NULL)

                                                                                              {

                                                                                                          if(etat_trace2==1) fprintf(file_code,"\n//%s INSTRUCTION VIDE",affiche);

                                                                                                          for(j=i+1;j<inst->instruction.sswitch.nb_case;j++)

                                                                                                                      if(inst->instruction.sswitch.cases[j]!=NULL) break;

                                                                                                          fprintf(file_code,"\n\tjmp bloc_%s_switch_%d_case_%d",inst->bloc,inst->index,j);

                                                                                              }

                                                                                  else

                                                                                              {

                                                                                                          if(etat_trace2==1) fprintf(file_code,"\n//%s INSTRUCTION DU CASE #%d",affiche,i+1);

                                                                                                          fprintf(file_code,"\nbloc_%s_switch_%d_case_%d:",inst->bloc,inst->index,i);

                                                                                                          genere_instruction(inst->instruction.sswitch.cases[i],bloc);

                                                                                              }

 

                                                                                   if(inst->instruction.sswitch.break_or_not[i]==1)

                                                                                               {

                                                                                                          if(etat_trace2==1) fprintf(file_code,"\n//%s BREAK",affiche);

 

                                                                                                          fprintf(file_code,"\n\tjmp %s_switch_%d_case_%d",inst->bloc,inst->index,inst->instruction.sswitch.nb_case);

                                                                                               }

                                                                                  else

                                                                                              if(etat_trace2==1) fprintf(file_code,"\n//%s PAS DE BREAK",affiche);

 

                                                                                  if((inst->instruction.sswitch.type_case[i]==TYPE_CASE_DEFAULT)&&

                                                                                     (inst->instruction.sswitch.break_or_not[i]==0))

                                                                                              {

                                                                                                          fprintf(file_code,"\n\tjmp %s_switch_%d_case_%d",inst->bloc,inst->index,inst->instruction.sswitch.nb_case);

                                                                                              }

 

                                                                                  descend();

 

                                                                                  fprintf(file_code,"\n%s_switch_%d_case_%d:",inst->bloc,inst->index,i+1);

                                                                        }

 

                                                                       /*fprintf(file_code,"\n%s_switch_%d_case_%d:",inst->bloc,inst->index,inst->instruction.sswitch.nb_case);*/

 

                                                                       if(inst->instruction.sswitch.nb_case==0)  {if(etat_trace2==1) fprintf(file_code,"\n//%s CORPS SWITCH VIDE ",affiche);}

                                                                       if(etat_trace2==1) fprintf(file_code,"\n//%s__________________________________________________________________________________",affiche);

 

                                                           }break;

                                               case INST_LABEL :

                                                           {

                                                                                  if(etat_trace2==1) fprintf(file_code,"\n//%s INSTRUCTION LABEL '%s' ", affiche,inst->instruction.slabel);

                                                                                  fprintf(file_code,"\n%s_switch_%d_label_%s:",inst->bloc,inst->index,inst->instruction.slabel);

                                                           }break;

                                               case INST_GOTO :

                                                           {

                                                                                  int index;

 

                                                                                  if(etat_trace2==1) fprintf(file_code,"\n//%s INSTRUCTION GOTO '%s'", affiche,inst->instruction.sgoto);

                                                                                  index=rechercher_index_label(inst->bloc,inst->instruction.sgoto);

                                                                                  fprintf(file_code,"\n\tjmp %s_switch_%d_label_%s",inst->bloc,index,inst->instruction.sgoto);

                                                           }break;

                                               case INST_ACQUIRE :

                                                           {

                                                                                  int index;

 

                                                                                  if(etat_trace2==1) fprintf(file_code,"\n//%s INSTRUCTION ACQUIRE '%s'", affiche,inst->instruction.smutex_acquire);

 

                                                                                  index=rechercher_index_mutex(inst->instruction.smutex_acquire);

 

                                                                                   if(index==-1)

                                                                                              {

                                                                                                          char libelle[200];

 

                                                                                                          sprintf(libelle,"\nErreur Fatale #GC9200 : bloc '%s' - mutex '%s' de la primitive Acquire inconnu",

                                                                                                                                                                     inst->bloc,inst->instruction.smutex_acquire);

                                                                                                          message_erreur(libelle);

                                                                                              }

 

                                                                                  fprintf(file_code,"\n\tacquire %s",inst->instruction.smutex_acquire);

                                                           }break;

                                               case INST_RELEASE :

                                                           {

                                                                                  int index;

 

                                                                                  if(etat_trace2==1) fprintf(file_code,"\n//%s INSTRUCTION RELEASE '%s'", affiche,inst->instruction.smutex_release);

 

                                                                                  index=rechercher_index_mutex(inst->instruction.smutex_release);

 

                                                                                  if(index==-1)

                                                                                              {

                                                                                                          char libelle[200];

 

                                                                                                          sprintf(libelle,"\nErreur Fatale #GC9300 : bloc '%s' - mutex '%s' de la primitive Release inconnu",

                                                                                                                                                                     inst->bloc,inst->instruction.smutex_release);

                                                                                                  message_erreur(libelle);

                                                                                              }

 

                                                                                  fprintf(file_code,"\n\trelease %s",inst->instruction.smutex_release);

                                                           }break;

 

 

 

                                               case INST_ARRSIZE:

                                                           {

                                                                                  int index_label;

                                                                                  int index_size;

                                                                                  char prefixe_label[MAX_IDENT];

                                                                                  char prefixe_size[MAX_IDENT];

 

                                                                                  index_label=recherche_variable(inst->instruction.sarrsize.label,inst->bloc);

                                                                                  index_size =recherche_variable(inst->instruction.sarrsize.size,inst->bloc);

 

                                                                                  if(etat_trace2==1) fprintf(file_code,"\n//%s INSTRUCTION ARRSIZE label='%s' size='%s'", affiche,

                                                                                              inst->instruction.sarrsize.label,inst->instruction.sarrsize.size);

 

                                                                                  if(strcmp(program.vg[index_label].bloc,"0")==0)

                                                                                                          strcpy(prefixe_label,"globale");

                                                                                  else

                                                                                                          strcpy(prefixe_label,program.vg[index_label].bloc);

 

                                                                                  if(strcmp(program.vg[index_size].bloc,"0")==0)

                                                                                                          strcpy(prefixe_size,"globale");

                                                                                  else

                                                                                                          strcpy(prefixe_size,program.vg[index_size].bloc);

 

                                                                                  fprintf(file_code,"\n\tarrsize %s_%s, %s_%s",

                                                                                              prefixe_size,inst->instruction.sarrsize.size,

                                                                                              prefixe_label,inst->instruction.sarrsize.label);

 

                                                           }break;

                                               case INST_ARRINIT:

                                                           {

                                                                                  SEXPRESSION *expression_value_ptr;

                                                                                  SEXPRESSION *expression_size_ptr;

                                                                                  int index_label;

                                                                                  char prefixe_label[MAX_IDENT];

                                                                                  char *rtype_value,*rtype_size;

                                                                                  int  ind;

 

                                                                                   expression_value_ptr=inst->instruction.sarrinit.expression_value_ptr;

                                                                                  expression_size_ptr=inst->instruction.sarrinit.expression_size_ptr;

 

                                                                                  index_label=recherche_variable(inst->instruction.sarrinit.label,inst->bloc);

 

                                                                                  if(strcmp(program.vg[index_label].bloc,"0")==0)

                                                                                                          strcpy(prefixe_label,"globale");

                                                                                  else

                                                                                                          strcpy(prefixe_label,program.vg[index_label].bloc);

 

                                                                                  if(etat_trace2==1) fprintf(file_code,"\n//%s INSTRUCTION ARRINIT label='%s'", affiche,

                                                                                              inst->instruction.sarrinit.label);

 

                                                                                  rtype_value=genere_recursif(expression_value_ptr,0,bloc,NULL);

                                                                                  fprintf(file_code,"\n\tmov %s_%s_%s, %s_%s_%s",

                                                                                                                                                "value",rtype_value,bloc,

                                                                                                                                                "expr", rtype_value,bloc);

 

                                                                                  rtype_size=genere_recursif(expression_size_ptr,0,bloc,NULL);

 

/* contrôle de la comptabilité du type à réaliser */

                                                                                  ind=recherche_atome(rtype_size);

                                                                                  if((ind!=TBYTE)&&(ind!=TWORD)&&(ind!=TDWORD))

                                                                                    {

                                                                                                          char libelle[200];

 

                                                                                                          sprintf(libelle,"\nErreur Fatale #GC10001 : bloc=%s type=%s incompatible avec le champ size ",

                                                                                                                      bloc,rtype_size);

                                                                                                          message_erreur(libelle);

                                                                                    }

 

                                                                                  fprintf(file_code,"\n\tmov %s_%s_%s, %s_%s_%s",

                                                                                                                                                "size","word",bloc,

                                                                                                                                                "expr",rtype_size,bloc);

 

                                                                                  fprintf(file_code,"\n\tarrinit %s_%s, %s_%s_%s, %s_%s_%s",

                                                                                              prefixe_label,inst->instruction.sarrinit.label,

                                                                                              "value",rtype_value,bloc,

                                                                                              "size","word",bloc);

 

                                                           }break;

                                               case INST_ARRSUBSET:

                                                           {

                                                                                  int index_src;

                                                                                  int index_dst;

                                                                                  char prefixe_src[MAX_IDENT];

                                                                                  char prefixe_dst[MAX_IDENT];

                                                                                  SEXPRESSION *expression_index_ptr;

                                                                                  SEXPRESSION *expression_length_ptr;

                                                                                  char *rtype_index,*rtype_length;

                                                                                  int ind;

 

                                                                                  expression_index_ptr=inst->instruction.sarrsubset.expression_index_ptr;

                                                                                  expression_length_ptr=inst->instruction.sarrsubset.expression_length_ptr;

 

                                                                                  index_src=recherche_variable(inst->instruction.sarrsubset.label_src,inst->bloc);

                                                                                  index_dst=recherche_variable(inst->instruction.sarrsubset.label_dst,inst->bloc);

 

                                                                                  if(etat_trace2==1) fprintf(file_code,"\n//%s INSTRUCTION ARRSUBSET src ='%s' dst='%s'", affiche,

                                                                                              inst->instruction.sarrsubset.label_src,inst->instruction.sarrsubset.label_dst);

 

                                                                                  if(strcmp(program.vg[index_src].bloc,"0")==0)

                                                                                                          strcpy(prefixe_src,"globale");

                                                                                  else

                                                                                                          strcpy(prefixe_src,program.vg[index_src].bloc);

 

                                                                                  if(strcmp(program.vg[index_dst].bloc,"0")==0)

                                                                                                          strcpy(prefixe_dst,"globale");

                                                                                  else

                                                                                                          strcpy(prefixe_dst,program.vg[index_dst].bloc);

 

                                                                                  rtype_index=genere_recursif(expression_index_ptr,0,bloc,NULL);

/* contrôle de la comptabilité du type à réaliser */

                                                                                  ind=recherche_atome(rtype_index);

                                                                                  if((ind!=TBYTE)&&(ind!=TWORD)&&(ind!=TDWORD))

                                                                                    {

                                                                                                          char libelle[200];

 

                                                                                                          sprintf(libelle,"\nErreur Fatale #GC10002 : bloc=%s type=%s incompatible avec le champ index ",

                                                                                                                      bloc,rtype_index);

                                                                                                          message_erreur(libelle);

                                                                                    }

 

                                                                                  fprintf(file_code,"\n\tmov %s_%s_%s, %s_%s_%s",

                                                                                                                                                "index","word",bloc,

                                                                                                                                                "expr", rtype_index,bloc);

 

                                                                                  rtype_length=genere_recursif(expression_length_ptr,0,bloc,NULL);

/* contrôle de la comptabilité du type à réaliser */

                                                                                  ind=recherche_atome(rtype_length);

                                                                                  if((ind!=TBYTE)&&(ind!=TWORD)&&(ind!=TDWORD))

                                                                                    {

                                                                                                          char libelle[200];

 

                                                                                                          sprintf(libelle,"\nErreur Fatale #GC10003 : bloc=%s type=%s incompatible avec le champ length ",

                                                                                                                      bloc,rtype_length);

                                                                                                          message_erreur(libelle);

                                                                                    }

 

                                                                                  fprintf(file_code,"\n\tmov %s_%s_%s, %s_%s_%s",

                                                                                                                                                "length","word",bloc,

                                                                                                                                                "expr", rtype_length,bloc);

 

                                                                                  fprintf(file_code,"\n\tarrsubset %s_%s, %s_%s, %s_%s_%s, %s_%s_%s",

                                                                                              prefixe_dst,inst->instruction.sarrsubset.label_dst,

                                                                                              prefixe_src,inst->instruction.sarrsubset.label_src,

                                                                                              "index","word",bloc,

                                                                                              "length","word",bloc);

 

                                                           }break;

                                               case INST_ARRBUILD:

                                                           {

                                                                                  int i;

 

                                                                                  if(etat_trace2==1) fprintf(file_code,"\n//%s INSTRUCTION ARRBUILD %d", affiche,

                                                                                              inst->instruction.sarrbuild.nb_tab);

 

                                                                                  fprintf(file_code,"\n\tarrbuild ");

 

                                                                                  for(i=0;i<inst->instruction.sarrbuild.nb_tab;i++)

                                                                                              {

                                                                                                          int index_src;

                                                                                                          char prefixe_src[MAX_IDENT];

 

                                                                                                          index_src=recherche_variable(inst->instruction.sarrbuild.label[i],inst->bloc);

 

                                                                                                          if(strcmp(program.vg[index_src].bloc,"0")==0)

                                                                                                                      strcpy(prefixe_src,"globale");

                                                                                                          else

                                                                                                                      strcpy(prefixe_src,program.vg[index_src].bloc);

 

                                                                                                          if(i>0) fprintf(file_code,",");

 

                                                                                                          fprintf(file_code,"%s_%s ",prefixe_src,inst->instruction.sarrbuild.label[i]);

                                                                                              }

 

                                                           }break;

 

 

 

 

                                               case INST_RETURN :

                                                           {

                                                                                  SEXPRESSION *exp;

                                                                                  int type;

                                                                                  int j,k,l;

                                                                                  char *rtype,*type_ret,*typer;

 

                                                                                   exp=inst->instruction.sreturn.expression_ptr;

                                                                                  type=inst->instruction.sreturn.exp;

 

                                                                                   if(etat_trace2==1) fprintf(file_code,"\n//%s__________________________________________________________________________________",affiche);

                                                                                  if(etat_trace2==1) fprintf(file_code,"\n//%s INSTRUCTION RETURN ",affiche);

                                                                                  if(type==1)

                                                                                              {

                                                                                                          rtype=genere_recursif(exp,0,bloc,NULL);

 

                                                                                                          for(j=0;j<nb_fonction;j++)

                                                                                                                      if(strcmp(bloc,tab_fonction[j].ident_fonction)==0) break;

 

                                                                                                          if(j==nb_fonction)

                                                                                                           {

                                                                                                                      char libelle[200];

 

                                                                                                                      sprintf(libelle,"\nErreur Fatale #GC0200 : fonction inconnue '%s'",bloc);

                                                                                                                      message_erreur(libelle);

                                                                                                           }

 

                                                                                                          type_ret=convertit_type_gen(tab_fonction[j].type_variable_retournee_ptr->type,0);

 

                                                                                                          typer=calcul_type_resultant(type_ret,rtype);

 

                                                                                                          k=recherche_atome(typer);

                                                                                                          l=recherche_atome(type_ret);

 

                                                                                                          if(recherche_atome(type_ret)==-1)

                                                                                                                      {

                                                                                                                                 if(strcmp(rtype,type_ret)!=0)

                                                                                                                                             {

                                                                                                                                                         char libelle[200];

 

                                                                                                                                                         sprintf(libelle,"\nErreur Fatale #GC0201 : fonction '%s', type retourne incompatible '%s' : '%s'",

                                                                                                                                                                     bloc,rtype,type_ret);

                                                                                                                                                         message_erreur(libelle);

                                                                                                                                             }

                                                                                                                      }

                                                                                                          else

                                                                                                                      if(k!=l)

                                                                                                                                 {

                                                                                                                                                         char libelle[200];

 

                                                                                                                                                         sprintf(libelle,"\nErreur Fatale #GC0202 : fonction '%s', type retourne incompatible '%s' : '%s'",

                                                                                                                                                                     bloc,rtype,type_ret);

                                                                                                                                                         message_erreur(libelle);

                                                                                                                                 }

 

                                                                                                          if(strcmp(type_ret,rtype)!=0) /* on ne genere ce code que si les types sont différents */

                                                                                                                      fprintf(file_code,"\n\tmov expr_%s_%s, expr_%s_%s",type_ret,bloc,rtype,bloc);

                                                                                              }

                                                                                  else {if(etat_trace2==1) fprintf(file_code,"\n//%s  RETURN VIDE ",affiche);}

 

                                                                           fprintf(file_code,"\n\tjmp return_%s",bloc);

 

                                                                                  if(etat_trace2==1) fprintf(file_code,"\n//%s__________________________________________________________________________________",affiche);

                                                           }break;

                                               case INST_EXIT:

                                                   {

                                                                       monte();

 

                                                                       if(etat_trace2==1) fprintf(file_code,"\n//%s INSTRUCTION EXIT()", affiche);

 

                                                                       fprintf(file_code,"\n\tstop 1");

 

                                                                       descend();

                                                           }break;

                                               case INST_PRECEDES:

                                                           {

                                                             int i;

                                                             int index;

 

                                                             if(inst->instruction.sprecedes.nb_label>0)

                                                              {

 

                                                                           monte();

                                                                                   if(etat_trace2==1) fprintf(file_code,"\n//%s__________________________________________________________________________________",affiche);

                                                                                  if(etat_trace2==1) fprintf(file_code,"\n//%s INSTRUCTION PRECEDES ",affiche);

                                                                                  for(i=0;i<inst->instruction.sprecedes.nb_label;i++)

                                                                                              {

                                                                                                          if(etat_trace2==1) fprintf(file_code,"\n//%s tache = '%s' ",affiche,&inst->instruction.sprecedes.label[i][0]);

                                                                                              }

 

                                                                                  fprintf(file_code,"\n\tprecedes ");

 

                                                                                  for(i=0;i<inst->instruction.sprecedes.nb_label;i++)

                                                                                              {

                                                                                                          rechercher_tache(&inst->instruction.sprecedes.label[i][0],inst->bloc);

                                                                                                          fprintf(file_code,"%s ",&inst->instruction.sprecedes.label[i][0]);

                                                                                              }

 

                                                                                   if(etat_trace2==1) fprintf(file_code,"\n//%s__________________________________________________________________________________",affiche);

                                                                           descend();

                                                              }

 

                                                           }break;

                                               case INST_BREAK    :

                                                           {

                                                                       INSTRUCTION *inst_boucle;

 

                                                                       monte();

                                                                                  if(etat_trace2==1) fprintf(file_code,"\n//%s INSTRUCTION BREAK => SAUT SORTIE DE BOUCLE ", affiche);

 

                                                                       inst_boucle=consulte_boucle();

 

                                                                       if(inst_boucle->type_instruction==INST_FOR)

                                                                                               fprintf(file_code,"\n\tjmp break_%s_for_%d",inst_boucle->bloc,inst_boucle->index);

                                                                       else if(inst_boucle->type_instruction==INST_DO_REPEAT)

                                                                                               fprintf(file_code,"\n\tjmp break_%s_do_while_%d",inst_boucle->bloc,inst_boucle->index);

 

                                                                       descend();

                                                           }break;

                                               case INST_CASE :

                                                           {

                                                                                  if(etat_trace2==1) fprintf(file_code,"\n//%s INSTRUCTION CASE ", affiche);

                                                           }break;

                                               case INST_CONTINUE :

                                                           {

                                                                       INSTRUCTION *inst_boucle;

 

                                                                       monte();

                                                                                  if(etat_trace2==1) fprintf(file_code,"\n//%s INSTRUCTION CONTINUE => SAUT DEBUT DE BOUCLE ", affiche);

 

                                                                       inst_boucle=consulte_boucle();

 

                                                                       if(inst_boucle->type_instruction==INST_FOR)

                                                                                               fprintf(file_code,"\n\tjmp continue_%s_for_%d",inst_boucle->bloc,inst_boucle->index);

                                                                       else if(inst_boucle->type_instruction==INST_DO_REPEAT)

                                                                                               fprintf(file_code,"\n\tjmp %s_do_while_%d",inst_boucle->bloc,inst_boucle->index);

                                                                       descend();

                                                           }break;

                                               case INST_AFFECTATION :

                                                           {

                                                                       char                 *rtype1,*rtype2,*rtype;

                                                                       SEXPRESSION *exp1;

                                                                       SVARIABLE *suivant;

                                                                       int                    dim,type;

 

                                                                       monte();

 

/*                                            printf("\naff %lx",inst->instruction.saffectation);*/

                                                                                  if(inst->instruction.saffectation->type_affectation==AFF_PTR)

                                                                                              {

                                               /*printf("\n A");*/

                                                                                                          if(etat_trace2==1) fprintf(file_code,"\n//%s = AFF POINTEUR ",affiche);

                                               /*printf("\n B");*/

                                                                                                          rtype1=genere_recursif(inst->instruction.saffectation->valeur_affectee,0,bloc,NULL);

                                               /*printf("\n C");*/

                                                                                                          if(strcmp(rtype1,"void")==0)

                                                                                                                      {

                                                                                                                                 char libelle[200];

 

                                                                                                                                 sprintf(libelle,"\nErreur Fatale #GC0400 : affectation d'un type 'void' à la variable '%s' ",

                                                                                                                                                                     inst->instruction.saffectation->variable->feuille.svariable.ident_variable);

                                                                                                                                  message_erreur(libelle);

                                                                                                                      }

                                               /*printf("\n D");*/

                                                                                                          exp1=inst->instruction.saffectation->valeur_affectee;

                                               /*printf("\n E");*/

                                                                                                          type=exp1->type;

                                               /*printf("\n F");*/

                                                                                                          fprintf(file_code,"\n\tmov expr_aff_%s_%s, expr_%s_%s // affectation 0",rtype1,bloc,rtype1,bloc);

                                               /*printf("\n G");*/

                                                                                                          rtype2=genere_recursif(inst->instruction.saffectation->variable,1,bloc,rtype1);

                                               /*printf("\n H");*/

                                                                                                          rtype=calcul_type_resultant(rtype1,rtype2);

                                               /*printf("\n I");*/

                                                                                              }

                                                                                  else if(inst->instruction.saffectation->type_affectation==AFF_EXP)

                                                                                              {

                                                                                                          if(etat_trace2==1) fprintf(file_code,"\n//%s = AFF VARIABLE SIMPLE ",affiche);

                                                                                                          rtype1=genere_recursif(inst->instruction.saffectation->valeur_affectee,0,bloc,NULL);

 

                                                                                                          if(strcmp(rtype1,"void")==0)

                                                                                                                      {

                                                                                                                                 char libelle[200];

 

                                                                                                                                 sprintf(libelle,"\nErreur Fatale #GC0300 : affectation d'un type 'void' à la variable '%s' ",

                                                                                                                                                                     inst->instruction.saffectation->variable->feuille.svariable.ident_variable);

                                                                                                                                  message_erreur(libelle);

                                                                                                                      }

 

                                                                                                          exp1=inst->instruction.saffectation->valeur_affectee;

                                                                                                          type=exp1->type;

 

                                                                                                          if(type==EXP_VARIABLE) /* c'est une variable */

                                                                                                                      {

                                                                                                                                 suivant=exp1->feuille.svariable.suivant;

                                                                                                                                 dim=exp1->feuille.svariable.variable_ptr->type_variable_ptr->nb_dimension;

                                                                                                                                 /*printf("\n suivant=%lx d=%d",suivant,dim);*/

 

                                                                                                                                 if((suivant==NULL)&&(dim>0)) /* affectation d'un tableau */

                                                                                                                                             {

                                               /* à corriger si tableau d'atome, tab en trop */

                                                                                                                                                         int ind_tab;

 

                                                                                                                                                         ind_tab=recherche_tab_atome(rtype1);

 

                                                                                                                                                         if(ind_tab==-1)

                                                                                                                                                                     fprintf(file_code,"\n\tmov expr_aff_%s_tab_%s, expr_%s_tab_%s // affectation 1",rtype1,bloc,rtype1,bloc);

                                                                                                                                                         else

                                                                                                                                                                     fprintf(file_code,"\n\tmov expr_aff_%s_%s, expr_%s_%s // affectation 1 tab d'atome",rtype1,bloc,rtype1,bloc);

                                                                                                                                             }

                                                                                                                                 else /* ce n'est pas un tableau */

                                                                                                                                             fprintf(file_code,"\n\tmov expr_aff_%s_%s, expr_%s_%s // affectation 2",rtype1,bloc,rtype1,bloc);

                                                                                                                      }

                                                                                                          else /* c'est une expression */

                                                                                                                      fprintf(file_code,"\n\tmov expr_aff_%s_%s, expr_%s_%s // affectation 3 ",rtype1,bloc,rtype1,bloc);

 

                                                                                                          rtype2=genere_recursif(inst->instruction.saffectation->variable,1,bloc,rtype1);

                                                                                                          rtype=calcul_type_resultant(rtype1,rtype2);

                                                                                              }

                                                                                  else if(inst->instruction.saffectation->type_affectation==AFF_INC)

                                                                                              {

                                                                                                          if(etat_trace2==1) fprintf(file_code,"\n//%s ++ INCREMENTATION ",affiche);

                                                                                                          genere_recursif(inst->instruction.saffectation->variable,2,bloc,NULL);

                                                                                              }

                                                                                  else if(inst->instruction.saffectation->type_affectation==AFF_DEC)

                                                                                              {

                                                                                                          if(etat_trace2==1) fprintf(file_code,"\n//%s -- DECREMENTATION ",affiche);

                                                                                                          genere_recursif(inst->instruction.saffectation->variable,3,bloc,NULL);

                                                                                              }

 

                                                                                  /*fprintf(file_code,"\n\tmov expr_d_word, expr_word");*/

 

                                                                                  if(etat_trace2==1) fprintf(file_code,"\n//%s INSTRUCTION AFFECTATION %lx %lx",

                                                                                              affiche,

                                                                                              inst->instruction.saffectation->variable,

                                                                                              inst->instruction.saffectation->valeur_affectee);

 

 

 

                                                                                  /*fprintf(file_code,"\n\tmov expr_word,expr_d_word");*/

 

                                                                       descend();

                                                           }break;

                                               case INST_FONCTION :

                                                           {

                                                                       monte();

 

                                                                       if(etat_trace2==1) fprintf(file_code,"\n//%s INSTRUCTION FONCTION ", affiche);

 

                                                                       genere_recursif(inst->instruction.sfonction,0,bloc,NULL);

 

                                                                       descend();

 

                                                           }break;

                                               case INST_BLOC :

                                                           {

                                                                                  int i;

 

                                                                                  if(etat_trace2==1) fprintf(file_code,"\n//%s INSTRUCTION BLOC ", affiche);

 

                                                                                  monte();

 

                                                                                  if(inst->instruction.sbloc.nb_instruction==0)

                                                                                              {

                                                                                                          if(etat_trace2==1) fprintf(file_code,"\n//%s BLOC VIDE ", affiche);

                                                                                      }

                                                                                  else

                                                                                              {

                                                                                                          if(etat_trace2==1) fprintf(file_code,"\n//%s LISTE INSTRUCTION BLOC nb_inst %d", affiche,inst->instruction.sbloc.nb_instruction);

 

                                                                                                          for(i=0;i< inst->instruction.sbloc.nb_instruction;i++)

                                                                                                          {

                                                                                                                      if(etat_trace2==1) fprintf(file_code,"\n//%s SOUS INSTRUCTION BLOC %d", affiche,i);

                                                                                                                      genere_instruction(inst->instruction.sbloc.liste_instruction[i],bloc);

                                                                                                          }

                                                                                              }

 

                                                                                  descend();

                                                           }break;

                             }

               }

 

              descend();

  }