top of page

T COMPILER

The T Compiler has been developped using lex and yacc tools (actually flex and bison).

 

For new comers, lex generates a lexical analyzer that performs pattern-matching on text. On its side, yacc reads a grammar specification and generates a parser for it. This parser consists of a set of routines which are invoked when a specific pattern is found by the lexical analyzer.

 

Despite it is not mandatory to go deep inside the T Compiler processing, it helps to understand why a program written in T Language generates more or less programming steps. Thus, it may help to optimize a program that first doesn't fit in memory.

 

 

VARIABLES FROM INSIDE

 

As a general rule, the T Compiler maps each variable to a TI59 register.

 

Let's consider the following declarations:

 

double value;

double *pointer;

 

double values[5];

double *pointers[10];

 

According to the above rule, such declarations will trigger the following register assignments:

 

// Variable       Scope    Register    Content

// value          main        00       Value

// pointer        main        01       Address

// values[0]      main        02       Value

// values[1]      main        03       Value

// values[2]      main        04       Value

// values[3]      main        05       Value

// values[4]      main        06       Value

// pointers[0]    main        07       Address

// pointers[1]    main        08       Address

// pointers[2]    main        09       Address

// pointers[3]    main        10       Address

// pointers[4]    main        11       Address

// pointers[5]    main        12       Address

// pointers[6]    main        13       Address

// pointers[7]    main        14       Address

// pointers[8]    main        15       Address

// pointers[9]    main        16       Address

 

Keep in mind a declaration doesn't generate any programming step: it is just a simple mapping between a variable identifier and a register in the calculator.

 

On the opposite, using a variable is step consuming. For instance, value = value + 1 will generate RCL 00 + 1 = STO 00.

 

As a variable may contain the address of another variable, statements like pointer = &value or pointers[5] = &values[1] are also valid. They will generate the following register assignments and steps:

 

// Variable       Scope    Register    Content

// values[(0)]    main        17       Address

// pointers[(5)]  main        18       Address

 

0 STO 01                 // pointer = &value

7 STO 18 5 SUM 18        // Computes pointers[5] address (7 + 5 = 12) and stores it in register 18

2 STO 17 1 SUM 17        // Computes values[1]   address (2 + 1 = 3)  and stores it in register 17

RCL 17 STO 2nd Ind 18    // Recalls register 17 (3) and stores it in register contained in register 18 (12)

 

As you can see, access to an array requires a dynamic index computation. It is made from the array base address plus the index value (that may be far more complex than a simple integer value). As a drawback, this computation generates additional steps and increases memory consumption (registers 17 and 18 are now used). Therefore array usage must be as limited as possible.

 

 

SUBROUTINES FROM INSIDE

 

The T Language defines two types of reusable code:

  • Functions which accept arguments passed by value and return a value.

  • Procedures which accept arguments passed by value or by reference but don't return any value.

 

As a general rule, the declaration of an argument triggers a new register assignment whatever the passing mode.

 

Anyway, there is an important difference at the call:

  • An argument passed by value sees its value copied to this register.

  • An argument passed by reference sees its address copied to this register.

 

Let's come back to the following program:

 

double myFunction(double var)

{

    var=var+1;

    return var;

}

 

void myProcedure(double *var)

{

    *var=*var+1;

}

 

void main()

{

    double a;

    double b;

 

    a=1;

    b=myFunction(a);

    display(a);        // Will display 1

    display(b);        // Will display 2

 

    myProcedure(&a);

    display(a);        // Will display 2

}

 

First, here is the mapping between variables and registers:

 

// Variable    Scope          Register    Content

// var         myFunction        00       Value

// var         myProcedure       01       Address

// a           main              02       Value

// b           main              03       Value

 

And then, the steps generated by the T Compiler:

 

2nd Lbl -

    RCL 00 + 1 = STO 00

    RCL 00

    INV SBR

 

 

2nd Lbl (

    RCL 2nd Ind 01 + 1 = STO 2nd Ind 01

    INV SBR

 

 

2nd Lbl R/S

    1 STO 02

    RCL 02 STO 00 SBR - STO 03

    RCL 02 R/S

    RCL 03 R/S

 

 

    2 STO 01 SBR (

    RCL 02 R/S

    INV SBR

 

 

CONTROL STRUCTURES FROM INSIDE

 

With the TI59, if implementation is made a little bit upside down: the test itself doesn't deal with the if but with the else clause (due to the jump that comes right after the comparison). This makes the test reading a little bit difficult.

 

a==b, a!=b, a<=b, a>b tests are implemented with the following pattern:

 

a x><t

b test C

    instructions...

    GTO D

2nd Lbl C

    instructions...

2nd Lbl D

 

 

a>=b and a<b tests are implemented with another pattern:

 

b x><t

a test C

    instructions...

    GTO D

2nd Lbl C

    instructions...

2nd Lbl D

 

 

The while implementation is based on a if statement. It uses the following pattern:

 

2nd Lbl C

a x><t

b test D

    instructions...

    GTO C

2nd Lbl D

 

 

T COMPILER OUTPUT

 

Assuming you submit a file named program.c, the T Compiler will generate two output files:

  • A file named program.ti59 that contains all AOS instructions and a register/step/label report.

  • A file named program.step that contains all AOS instructions, unindented and numbered.

 

For the quadratic equation example, the .ti59 file looks like this:

 

SBR R/S

R/S

RST

 

2nd Lbl R/S

    2nd Lbl A

        R/S STO 00 R/S

    2nd Lbl B

        R/S STO 01 R/S

    2nd Lbl C

        R/S STO 02

    // Compute delta

    RCL 01 * RCL 01 - 4 * RCL 00 * RCL 02 = STO 03

    0 x><t

    RCL 03 INV 2nd x>=t -             

        // Real solutions

        (RCL 01 +/- - RCL 03 sqrt) / (2 * RCL 00) = R/S

        (RCL 01 +/- + RCL 03 sqrt) / (2 * RCL 00) = R/S

        GTO (

    2nd Lbl -

        // No solutions

        99999999 R/S

    2nd Lbl (

    INV SBR

 

// Resources status

// ----------------

 

// T Compiler V1.0.2

 

// Required partioning is 10 registers (1 2nd Op 17) and 880 steps

 

// 4 registers used out of 10 (6 left)

 

// 98 steps used out of 880 (782 left)

 

// 2 common labels used out of 77 (75 left)

 

// Variable    Scope    Register    Content

// a           main        00       Value    

// b           main        01       Value    

// c           main        02       Value    

// delta       main        03       Value    

 

// Module: main    Label: 2nd Lbl R/S

// Argument    Scope    Register    Content

 

 

 

On its side, the .step file looks like that:

 

000 71 SBR

001 91 R/S

002 91 R/S

003 81 RST

004 76 2nd Lbl

005 91 R/S

006 76 2nd Lbl

007 11 A

008 91 R/S

009 42 STO

010 00 00

011 91 R/S

012 76 2nd Lbl

013 12 B

014 91 R/S

015 42 STO

016 01 01

017 91 R/S

018 76 2nd Lbl

019 13 C

020 91 R/S

021 42 STO

022 02 02

023 43 RCL

024 01 01

025 65 *

026 43 RCL

027 01 01

028 75 -

029 04 4

030 65 *

031 43 RCL

032 00 00

033 65 *

034 43 RCL

035 02 02

036 95 =

037 42 STO

038 03 03

039 00 0

040 32 x><t

041 43 RCL

042 03 03

043 22 INV

044 77 2nd x>=t

045 75 -

046 53 (

047 43 RCL

048 01 01

049 94 +/-

050 75 -

051 43 RCL

052 03 03

053 34 sqrt

054 54 )

055 55 /

056 53 (

057 02 2

058 65 *

059 43 RCL

060 00 00

061 54 )

062 95 =

063 91 R/S

064 53 (

065 43 RCL

066 01 01

067 94 +/-

068 85 +

069 43 RCL

070 03 03

071 34 sqrt

072 54 )

073 55 /

074 53 (

075 02 2

076 65 *

077 43 RCL

078 00 00

079 54 )

080 95 =

081 91 R/S

082 61 GTO

083 53 (

084 76 2nd Lbl

085 75 -

086 09 9

087 09 9

088 09 9

089 09 9

090 09 9

091 09 9

092 09 9

093 09 9

094 91 R/S

095 76 2nd Lbl

096 53 (

097 92 INV SBR

 

SCOPE & CONTENT

The scope of a variable is the place where this variable is known. It may be either local to a function/procedure or global to a program.

 

On top, a variable has a specific content. It is either a value - any number - or an address (a register number where to find a value)

myFunction(double var)

Variable var is mapped to register 00 which contains the argument's value. Direct use of register 00 is possible.

CALL TO myFunction

Variable a value (RCL 02) is copied to var (register 00) in myFunction.

CALL TO myProcedure

Variable a address (02) is copied to

var (register 01) in myProcedure.

myProcedure(double *var)

Variable var is mapped to register 01 which contains the argument's address. Indirect use of register 01 is required.

COMPARISONS (1)

The value to compare (a)

is swapped with tb is compared to t using the following AOS instructions:

  • a==b: INV 2nd x=t

  • a!=b:     2nd x=t

  • a<=b: INV 2nd x>=t

  • a>b :     2nd x>=t

VARIABLES_FROM_INSIDE
SUBROUTINES_FROM_INSIDE
CONTROLS_FROM_INSIDE
T_COMPILER_OUTPUT
AOS INSTRUCTIONS

In the .ti59 file, AOS instructions are formated according to the program logic and comments are still present.

 

This view helps to understand the T Compiler translation.

RESOURCES STATUS

This report gives useful information about:

  • The split required between registers and steps.

  • The number of available registers in the packet of 10.

  • The number of available steps.

  • The number of available common labels.

 

Obviously, none of these values should be negative. Otherwise, it would mean the program cannot fit in memory.

AOS INSTRUCTIONS

In the .step file, AOS instructions are numbered and displayed with their code.

 

This view helps to type in the program and to check errors.

QUADRATIC_EQUATION_OUTPUT
WANT TO TRY?
COMPARISONS (2)

The value to be compared (b)

is swapped with ta is compared to t using the following AOS instructions:

  • a>=b: INV 2nd x>=t

  • a<b:      2nd x>=t

bottom of page