2
votes

I am creating a compiler for my own programming language for creating bots in Minecraft as the semester project at my university. So far I have successfully created a parser with ANTLR, created my own Abstract Syntax Tree structure and used ANTLR visitors to create the AST. I am in the contextual analysis phase, and I am currently creating symbol tables and have the structure under control. My SymbolTable class looks like this:

public class SymbolTable {
    private HashMap<String, Symbol> ST = new HashMap<>();
    public SymbolTable parent;
    public LinkedList<SymbolTable> children = new LinkedList<>();
    public String kind;
    public String id;

    public SymbolTable(String kind, String id){
        this.kind = kind;
        this.id = id;
    }

    public void put(String id, Symbol val){
        ST.put(id, val);
    }

    public Symbol get(String id){
        if(ST.containsKey(id)) {
            return ST.get(id);
        }
        else{
            try {
                return parent.get(id);
            }
            catch(NullPointerException e){
                return null;
            }
        }
    }

    public boolean contains(String id){
        if(ST.containsKey(id)) {
            return true;
        }
        else{
            if(parent == null){
                return false;
            }
            return parent.contains(id);
        }
    }

    public String prettyPrint(){
        String st = "(TABLE " + this.kind + " " + this.id + " " + ST.toString();

        for(SymbolTable nst : children){
            st = st.concat(" " + nst.prettyPrint());
        }

        st = st.concat(")");

        return st;
    }

    public boolean isFunction(){
        if(this.kind == "fun"){
            return true;
        }
        else if(!(this.parent == null)){
            return this.parent.isFunction();
        }
        else{
            return false;
        }
    }
}

Putting variables and functions into the symbol table is no problem; I use my visitor methods for that, like this:

@Override
public Symbol visitStrVarCond(StrVarCondNode node){ return new StringSymbol("var", "string", node.val); }

However, as far as I understand, the value of the symbols in the symbol table (for instance the value of variables, or the return value of a function) also needs to be present in the symbol table. This is no problem as well, and this is something I can already do.

My problem, though, is:

Some of the values the programmer might use, is unknown at compile-time. They are only known at run-time of a given program. For example: The current position of the player, the specific item in an inventory slot, etc. My language has events, so for example if a programmer wants the bot to mine untill a specific block is detected, they could write it like this:

event block(12:0)
    // do stuff
end event

This specific event, the block event, contains variables for stuff like position of the block. However, this is not known at compile-time. How do I take things like this into account, when inserting values into the symbol tables?

1

1 Answers

1
votes

However, as far as I understand, the value of the symbols in the symbol table (for instance the value of variables, or the return value of a function) also needs to be present in the symbol table.

The location of the symbols in the symbol table needs to be present there - classically in the form of stack offset. The actual values are generally unknown at compile-time.

For an example, think of something like x = y. The purpose of the symbol table is to allow the compiler to know what the types of x and y are for type validation (in applicable languages), and to know the address operands of the "load" and "store" instructions it will emit. But it can generate the output code just fine without knowing what the actual value stored in x is.