FAUST compiler  0.9.9.6b8
Functions | Variables
boxtype.cpp File Reference

A simple type system for block diagram expressions. The type of a block diagram is defined by a number of inputs and outputs. More...

#include <stdio.h>
#include <string.h>
#include "boxes.hh"
#include "ppbox.hh"
#include "prim2.hh"
#include "xtended.hh"
Include dependency graph for boxtype.cpp:

Go to the source code of this file.

Functions

static bool infereBoxType (Tree t, int *inum, int *onum)
 Infere the type (number of inputs and outputs) of a box.
bool getBoxType (Tree box, int *inum, int *onum)
 Return the type (number of inputs and outputs) of a box or false if undefined.

Variables

Tree BOXTYPEPROP = tree(symbol("boxTypeProp"))

Detailed Description

A simple type system for block diagram expressions. The type of a block diagram is defined by a number of inputs and outputs.

Author:
Yann Orlarey
Version:
1.0
Date:
2003

Definition in file boxtype.cpp.


Function Documentation

bool getBoxType ( Tree  box,
int *  inum,
int *  onum 
)

Return the type (number of inputs and outputs) of a box or false if undefined.

Parameters:
boxthe box we want to know the type
inumthe place to return the number of inputs
onumthe place to return the number of outputs
Returns:
true if type is defined, false if undefined

Definition at line 63 of file boxtype.cpp.

References cons(), Node::getInt(), getProperty(), hd(), infereBoxType(), isNil(), nil, CTree::node(), setProperty(), tl(), and tree().

Referenced by applyList(), boxlistOutputs(), eval2double(), eval2int(), generateDiagramSchema(), getBoxInputsAndOutputs(), infereBoxType(), isBoxNumeric(), main(), mapGetEqName(), numericBoxSimplification(), and propagate().

{
    Tree t;
    if (getProperty(box, BOXTYPEPROP, t)) {
        
        if (isNil(t)) {
            return false;
        } else {
            *inum = hd(t)->node().getInt();
            *onum = tl(t)->node().getInt();
            return true;
        }
        
    } else {
    
        if (infereBoxType(box, inum, onum)) {
            setProperty(box, BOXTYPEPROP, cons(tree(*inum), tree(*onum)));
            return true;
        } else {
            setProperty(box, BOXTYPEPROP, nil);
            return false;
        }
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bool infereBoxType ( Tree  t,
int *  inum,
int *  onum 
) [static]

Infere the type (number of inputs and outputs) of a box.

The box expression is assumed to be in 'propagation normal form' that is to have been evaluated and residual abstractions to have been converted to symbolic boxes (using a2sb()).

Parameters:
boxthe box we want to know the type
inumthe place to return the number of inputs
onumthe place to return the number of outputs
Returns:
true if the box expression has a type

Definition at line 101 of file boxtype.cpp.

References xtended::arity(), ffarity(), getBoxType(), getUserData(), isBoxButton(), isBoxCheckbox(), isBoxCut(), isBoxEnvironment(), isBoxFConst(), isBoxFFun(), isBoxFVar(), isBoxHBargraph(), isBoxHGroup(), isBoxHSlider(), isBoxInt(), isBoxMerge(), isBoxNumEntry(), isBoxPar(), isBoxPatternVar(), isBoxPrim0(), isBoxPrim1(), isBoxPrim2(), isBoxPrim3(), isBoxPrim4(), isBoxPrim5(), isBoxReal(), isBoxRec(), isBoxSeq(), isBoxSlot(), isBoxSplit(), isBoxSymbolic(), isBoxTGroup(), isBoxVBargraph(), isBoxVGroup(), isBoxVSlider(), isBoxWire(), max(), and Automaton::s.

Referenced by getBoxType().

{
    Tree a, b, ff, l, s;
    //Tree abstr, genv, vis, lenv;
    
    xtended* p = (xtended*) getUserData(t);

    if (p)                      { *inum = p->arity(); *onum = 1; }
    else if (isBoxInt(t))       { *inum = 0; *onum = 1; } 
    else if (isBoxReal(t))      { *inum = 0; *onum = 1; } 
    else if (isBoxWire(t))      { *inum = 1; *onum = 1; }
    else if (isBoxCut(t))       { *inum = 1; *onum = 0; } 

    else if (isBoxSlot(t))          { *inum = 0; *onum = 1; }
    else if (isBoxSymbolic(t,s,b))  { if (!getBoxType(b, inum, onum)) return false; *inum += 1; } 
    
    else if (isBoxPatternVar(t,a))  { return false; }

    else if (isBoxPrim0(t))     { *inum = 0; *onum = 1; }
    else if (isBoxPrim1(t))     { *inum = 1; *onum = 1; } 
    else if (isBoxPrim2(t))     { *inum = 2; *onum = 1; } 
    else if (isBoxPrim3(t))     { *inum = 3; *onum = 1; } 
    else if (isBoxPrim4(t))     { *inum = 4; *onum = 1; } 
    else if (isBoxPrim5(t))     { *inum = 5; *onum = 1; } 
        
    else if (isBoxFFun(t,ff))   { *inum = ffarity(ff); *onum = 1; } 
    else if (isBoxFConst(t))    { *inum = 0; *onum = 1; } 
    else if (isBoxFVar(t))      { *inum = 0; *onum = 1; } 
    
    else if (isBoxButton(t))    { *inum = 0; *onum = 1; } 
    else if (isBoxCheckbox(t))  { *inum = 0; *onum = 1; } 
    else if (isBoxVSlider(t))   { *inum = 0; *onum = 1; } 
    else if (isBoxHSlider(t))   { *inum = 0; *onum = 1; } 
    else if (isBoxNumEntry(t))  { *inum = 0; *onum = 1; } 
    else if (isBoxVGroup(t,l,a)){ return getBoxType(a, inum, onum); }
    else if (isBoxHGroup(t,l,a)){ return getBoxType(a, inum, onum); }
    else if (isBoxTGroup(t,l,a)){ return getBoxType(a, inum, onum); }
    
    else if (isBoxVBargraph(t))     { *inum = 1; *onum = 1; } 
    else if (isBoxHBargraph(t))     { *inum = 1; *onum = 1; } 

    else if (isBoxSeq(t, a, b)) {
        
        int u,v,x,y;
        if (!getBoxType(a, &u, &v)) return false;
        if (!getBoxType(b, &x, &y)) return false;

        if (v != x) {
            cerr    << "Error in sequential composition (A:B)" << endl
                    << "The number of outputs (" << v << ") of A = " << boxpp(a) << endl
                    << "must be equal to the number of inputs (" << x << ") of B : " << boxpp(b) << endl;
            exit(1);
        } else {
            *inum = u; *onum = y;
        }

    } else if (isBoxPar(t, a, b)) {
        
        int u,v,x,y;
        if (!getBoxType(a, &u, &v)) return false;
        if (!getBoxType(b, &x, &y)) return false;

        *inum = u+x; *onum = v+y;

    } else if (isBoxSplit(t, a, b)) {
        
        int u,v,x,y;
        if (!getBoxType(a, &u, &v)) return false;
        if (!getBoxType(b, &x, &y)) return false;

        if (v == 0) {
            cerr    << "Connection error in : " << boxpp(t) << endl
                    << "The first expression : " << boxpp(a) << " has no outputs" << endl;
            exit(1);
        }
        
        if (x == 0) {
            cerr    << "Connection error in : " << boxpp(t) << endl
                    << "The second expression : " << boxpp(b) << " has no inputs" << endl;
            exit(1);
        }
         
        if (x % v != 0) {
            cerr    << "Connection error in : " << boxpp(t) << endl
                    << "The number of outputs " << v
                    << " of the first expression should be a divisor of the number of inputs " << x
                    << " of the second expression" << endl;
            exit(1);
        }
        
        *inum = u; *onum = y;

    } else if (isBoxMerge(t, a, b)) {
        
        int u,v,x,y;
        if (!getBoxType(a, &u, &v)) return false;
        if (!getBoxType(b, &x, &y)) return false;

        if (v == 0) {
            cerr    << "Connection error in : " << boxpp(t) << endl
                    << "The first expression : " << boxpp(a) << " has no outputs" << endl;
            exit(1);
        }
        
        if (x == 0) {
            cerr    << "Connection error in : " << boxpp(t) << endl
                    << "The second expression : " << boxpp(b) << " has no inputs" << endl;
            exit(1);
        }
        
        if (v % x != 0) { 
            cerr    << "Connection error in : " << boxpp(t) << endl
                    << "The number of outputs " << v
                    << " of the first expression should be a multiple of the number of inputs " << x
                    << " of the second expression" << endl;
            exit(1);
        }

        *inum = u; *onum = y;

    } else if (isBoxRec(t, a, b)) {
        
        int u,v,x,y;
        if (!getBoxType(a, &u, &v)) return false;
        if (!getBoxType(b, &x, &y)) return false;
        if ( (x > v) | (y > u) ) { 
            cerr    << "Connection error in : " << boxpp(t) << endl;
            if (x > v) cerr << "The number of outputs " << v 
                            << " of the first expression should be greater or equal \n  to the number of inputs " << x 
                            << " of the second expression" << endl;
            if (y > u) cerr << "The number of inputs " << u
                            << " of the first expression should be greater or equal \n  to the number of outputs " << y
                            << " of the second expression" << endl;
            exit(1);
        }
        *inum = max(0,u-y); *onum = v;
        
    } else if (isBoxEnvironment(t)) {
        cerr << "Connection error : an environment is not a block-diagram : " << boxpp(t) << endl;
        exit(1);
    } else {
        cerr << "boxType() internal error : unrecognized box expression " << boxpp(t) << endl;
        exit(1);
    }
    return true;
}   

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

Tree BOXTYPEPROP = tree(symbol("boxTypeProp"))

Definition at line 50 of file boxtype.cpp.