CS 3723
 Programming Languages 
   Tiny® Extensions  


Overview: This page shows several of ways that the Tiny® project might be extended. The main message is that modest extensions can be surprisingly easy. See Tiny® (double version) for the version we implemented.


Extended Grammar: Below is a grammar with a few modest extensions.

Grammar for Extended Tiny® language
M  −−−>  { ( S  |  D ) }  '$'
S  −−−>  I  |  W  |  A  |  P  |  C  |  G
D  −−−>  '(' id '(' [ id { ',' id } ] ')'  S { S } E ')'
I  −−−>  '[' E '?' S { S } ':' S { S } ']'  |  '[' E '?' S { S } ']'
W  −−−>  '{' E '?' S { S } '}'
A  −−−>  lower-case '=' E ';'
P  −−−>  '<'  E  ';'
G  −−−>  '>'  id ';'
C  −−−>  '<' ( 'B'  | 'T' | 'N' ) ';'
E  −−−>  Q [ ('&' | '|') Q ]
Q  −−−>  R [ ('<' | '>' | '<=' | '>=' | '==' | '!=' ) R ]
R  −−−>  T { ('+' | '-') T }
T  −−−>  U { ('*' | '/' | '%' | '@') U }
U  −−−>  F '^' U | F
F  −−−>  '(' E ')' | ('+' | '-' | '!') F  |  id  |  double  |
           id '(' [ E { ',' E } ] ')' )
id −−−>  letter  { letter | digit }
double −−−> (standard double syntax)

Just to help with understanding, here is the intuitive meaning of each of the above non-terminals:

SymbolMeaning
MMain Program
SStatement
DFunction Definition
IIf-Then-[Else] Statement
WWhile Statement
AAssignment Statement
PPut or Print (integer)
CPrint Character
 
SymbolMeaning
GGet (integer)
EExpression (logical or arithmetic)
QRelational Expression (no | or &)
RArithmetic Expression (no rel ops)
TTerm (without + or -)
UUgly Term (without * / % @)
FFactor

The grammar above has added:

  • identifiers and constant doubles.
  • relational operators: '<', '>', '<=', '>=', '==', '!='
  • logical operators, '&', '|', '!', and
  • functions with parameters: here is an example of a defined function and its use:

    Function Example
    # definition
    (a (x, y) x = x/2; y = 2*y+1; x+y)
    # x and y above are formal parameters
    
    # use: u = 9; z = a(u+1, 4); # u+1 and 4 above are actual parameters # z has value (((9+1)/2)+(2*4+1) = 14

The grammar gives the CF-syntax, but one also has to worry about:

  • The semantics of any proposed extensions, and
  • How such extensions might be implemented.


Scanner and Symbol Table: Now we need an actual scanner. And the token returned at each scan can't be just a single character, but it must be a struct or class returning the type of token as well as, for identifiers and constant doubles, a pointer to an entry in a table. We need more than trivial static storage allocation.


New Operators: Relational and Logical: The semantics of these new operators is just what you would expect, the same as with normal languages. Keep in mind that for equal and not-equal, the floats must satisfy these exactly.

Implementation is surprisingly simple. First keep the convention that a zero double is false and all non-zero doubles are true. Add to this the idea that the result of any of the new operators will be either 0.0 or 1.0. This means that the old if-then and while constructs will work as before. The blue code below implements <=. The other relations and logical operators are similar.

Test of <= operator
MIPS code: ble.s Output of runs
# implement relational op <=
main:   addu    $s7, $ra, $zero
        la      $s1, M
# start of <= test: c = (a <= b)
# Read 'a' as double
        li      $v0, 7
        syscall
        s.d     $f0, 80($s1)
# Read 'b' as double
        li      $v0, 7
        syscall
        s.d     $f0, 88($s1)
# want to do c = (a <= b)
        l.d     $f2, 80($s1)  # a
        l.d     $f4, 88($s1)  # b
        l.d     $f6, 8($s1)   # res = 1.0
        c.le.d  $f2, $f4      # a <= b ?
        bc1t    Rel01
        l.d     $f6, 0($s1)   # res = 0.0
Rel01:
        s.d     $f6, 96($s1)  # res in c
# Print 'c'
        li      $v0, 3
        l.d     $f12, 96($s1)
        syscall
# Print NewL as ASCII char
        li      $v0, 4
        la      $a0, NewL
        syscall
# end of <= test
        addu    $ra, $s7, $zero
        jr      $ra
        .data
        .align  3
M:      .double 0.,1.,2.,3.,4.,5.,6.
        .double 7.,8.,9. # constants
        .space  208  # variables a to z
        .space  1000 # 125 temporaries
NewL:   .asciiz "\n"
# end of program
% spim ble.s
1
2
1

% spim ble.s 2 2 1
% spim ble.s 2 1 0
% spim ble.s 0 0 1
% spim ble.s -4 -1 1
% spim ble.s -2 5 1
% spim ble.s -3 -7 0
% spim ble.s 7 -2 0


Functions: Functions present both semantic and implementations problems.

Semantic Problems and Questions:

  • Let's assume we stick with only doubles and have no declarations.
  • Should allow arbitrary expression for the actual parameter, which is passed by value to the formal parameter.
  • I would propose having the formal parameters and any variables appearing in the function body to be "local variables", whose scope is limited to the function body.
  • This language is so simple, it's probably reasonable to allow the function definition anywhere, and not restricted to before the use, but one could do that if it made the implementation easier.
  • Recursion will come for free with the implementation strategy proposed below.
  • In the grammar, there is a required final expression, and that will be returned.

Implementation: The page Activation Records illustrates the implementation of a recursive functions in MIPS, using a special stack and "activation records" on the stack for function calls. In addition to other problems, all the data except for addresses would have to adapted to doubles, but still it would be complex but not hard.


Arrays: One would need to decide on a syntax, including some kind of declaration. Implementation wouldn't be hard, since one just uses the array index (times 8 for doubles) as an offset from the start of the array.

(Revision date: 2014-11-03. Please use ISO 8601, the International Standard.)