views:

85

answers:

2

So I have this compiler class that compiles some .mjava files but others it fails on and wondering if anyone can help me figure out why. I have two methods that break for two different files. The first consts.mjava file I try to compile is:

// demo of true local and global variables
int glob0;
int glob1;
final int two = 2;
final int three = 3;
main() {
    int loc1;
    int loc2;
    int loc3;
    final int four = 4;
    glob0 = three;
    //print("glob0=", glob0, "\n");
    loc1 = glob0*two+1;
    glob1 = glob0*loc1;
    loc2  = glob1+1;
    loc3 = glob1*loc2/four;
    print("glob0=", glob0, " (should be 3)\n");
    print("glob1=", glob1, " (should be 21)\n");
    print("loc1=",  loc1,  " (should be 7)\n");
    print("loc2=",  loc2,  " (should be 22)\n");
    print("loc3=",  loc3,  " (should be 115)\n");
}

When I try to compile this with my compiler class it breaks here:

private void compileFactor() {

    if (isIdent(theToken)) {
        String ident = theToken;
        theToken = t.token();            
        IdentInfo theInfo = symTable.lookup(ident);


        boolean its_a_variable = theInfo.isVar();  ***//Breaks Here for consts.mjava Null Exception***
        int theAddr; 
        boolean isGlobal = theInfo.getIsGlobal();
        int constValue;
        int theNumber = 0;

        if (its_a_variable) {   // pld12: CHANGE THIS!!
                 theAddr = theInfo.getAddr(); 
                 isGlobal = theInfo.getIsGlobal();
                 if (theAddr == -1) t.error("undeclared identifier used in expr: "+ident);
                 if (isGlobal) cs.emit(Machine.LOAD, theAddr);
                 else cs.emit(Machine.LOADF, theAddr);
        } else {
                 constValue = theInfo.getValue();
                 if (constValue == 0) 
                        t.error("undeclared identifier used in expr: "+ident);
                 else {
                          cs.emitLOADINT(theNumber);
                 }
                }
            } else if (isNumber(theToken)) {
                int theNumber = new Integer(theToken).intValue();
                cs.emitLOADINT(theNumber);
                theToken = t.token();
            } else if (equals(theToken, "(")) {  
                accept("(");
                compileExpr();
                accept(")");
            }
        }

The next locs.mjava file I try to run breaks on this method:

private void compileIdentStmt() {
        String ident = theToken;
        boolean isGlobal = true;
        int location = 0;
        int entryPoint = 0;
        IdentInfo varInfo = null;
        if (!isIdent(ident)) t.error("expected identifier, got " + theToken);
        theToken = t.token();
        if (equals(theToken, "=")) {    
            accept("=");

            varInfo = symTable.lookup(ident);
            if (varInfo.isVar() == true) {      ***//Breaks Here on locs.mjava: Null Exception***
                location = varInfo.getAddr();        
                isGlobal = varInfo.getIsGlobal();    
            }

            /*
            if (varInfo==null) {
                location = GHack(ident);
                isGlobal = true;
            }
            if (location == -1) {
                location = LHack(ident);
                isGlobal = false;
            }
            /* */
            compileExpr();
            if (isGlobal) cs.emit(Machine.STOR, location);
            else cs.emit(Machine.STORF, location);      
            accept(";");
        } else if (equals(theToken, "(")) {     
                         varInfo = symTable.lookup(ident);

             if (varInfo.isProc() == true) {  
                entryPoint = varInfo.getEntryPoint();
                dprint("call to function " + ident + "; generating JSR to location " + entryPoint);
                accept("(");
            }
            /* 
            if (!equals(theToken, ")")) {   
                compileExpr();
                while (equals(theToken, ",")) {
                    accept(",");
                    compileExpr();
                }
            }
            /* */
            accept(")");
            accept(";");
            cs.emit(Machine.JSR, entryPoint);
        } else t.error("expected \"=\" or \"(\", got " + theToken);
    }

I will even supply my lookup method from my symTable() to help:

public IdentInfo lookup(String ident) {
        IdentInfo ii;
        if (HMLocal != null) {
            ii = HMLocal.get(ident);
            if (ii != null) {
                return ii;
            }
            ii = HMGlobal.get(ident);
            if (ii != null) {
                return ii;
            }
        }
        return null;
    }
+1  A: 

If you're getting NullPointerExceptions then it's because theInfo and varInfo are null in your examples.

John Topley
+1  A: 

After

IdentInfo theInfo = symTable.lookup(ident);

you should check if theInfo is null before trying to work with it, since your lookup method clearly states it can return null.

chburd