private ArrayList<Function> computation() throws Exception
    {
        Function main = new Function();
        globals = new GlobalMemoryRegion();
        ArrayList<Function> rval = new ArrayList<Function>();
        env.enter();
        if(scan.sym == Token.main) {
            scan.next();
            // variable declarations shouldn't actually cause any SSA
            // to be emited, but will be stored in env
            while(scan.sym == Token.var || scan.sym == Token.array) {
                // these are global variables, but could be optimized to become main local variables.
                currentFunction = main;
                varDecl(true);
            }
            while(scan.sym == Token.function || scan.sym == Token.procedure) {
                rval.add(funcDecl());
            }
            // at this point, we can examine our environment for which
            // globals have been used in other functions,
            env.freezeGlobals();
            if(scan.sym == Token.opencurly) {
                inMain = true;  // we are now parsing the main procedure
                currentBB = new BasicBlock(null);
                currentJoinBlock = null;
                currentFunction = main;
                main.name = idTable.addToTable("__MAIN__");
                main.entryPoint = currentBB;
                rval.add(main);
                scan.next();
                statSequence();
                if(!currentBB.hasFinalEnd()) {
                    currentBB.addInstruction(new End());
                }
                if(scan.sym == Token.closecurly) {
                    scan.next();
                    if(scan.sym == Token.period) {
                        scan.next();
                        env.exit();
                        return rval;
                    } else {
                        throw new Exception("Computation: no '.' ending program");
                    }
                } else {
                    throw new Exception("Computation: no '}' ending the statSequence");
                }
            } else {
                throw new Exception("Computation: no '{' starting the statSequence");
            }
        } else {
            throw new Exception("Computation: no 'main'");
        }
    }