[Home]Interpreter/NanoInterpreter

Robo Home | Interpreter | Changes | Preferences | AllPages

/*
 * NanoInterpreter by Kinsen Choy
 * http://robowiki.net/cgi-bin/robowiki?Kinsen
 */

import robocode.AdvancedRobot;
import robocode.ScannedRobotEvent;

public class NanoInterpreter extends AdvancedRobot
{
    /*
     * Command	    Usage
     * CMD_SET	    CMD_SET [Index] [Value]
     * CMD_IF	    CMD_IF [Location] [Condition]
     * -------
     * CMD_CALL     CMD_CALL [# Parameters] [Parameters...] [Class Name] [Method Name]
     *              [Object Index (0: Robot, 1: Event)]
     * CMD_VAR_VAL  CMD_VAR_VAL [Index]
     * CMD_SUBTRACT CMD_SUBTRACT [Value0] [Value1]
     * CMD_DIVIDE   CMD_DIVIDE [Value0] [Value1]
     *
     * Only the first two commands can start a "line" of commands
     * Numbers that represent a command must be an integer and numbers representing a number must be a double (e.g. 0.0)
     * CMD_IF will set the interpreter location at the [Location]th token (delimited by spaces) if [Condition] == 0D
     * CMD_VAR_VAL gets the value stored at [Index]
     */
    
    private static final int ARRAY_SIZE = 8192; // 2 ^ 13
    
    private static final int CMD_SET = -1;
    private static final int CMD_CALL = 0;
    private static final int CMD_VAR_VAL = 1;
    private static final int CMD_SUBTRACT = 2;
    
    // Hidden commands:
    // CMD_IF
    // CMD_DIVIDE
    
    private static final String COMMANDS[] =
            ""
            .split(" ");
    private static int myInstruction;
    
    private static final int RUN_START = 0;
    private static final int SCANNED_START = 0;
    
    private static double myVariables[] = new double[ARRAY_SIZE];
    private static Object myObjects[];
    
    public void run()
    {
        (myObjects = new Object[2])[0] = this;
        
        /*setAdjustGunForRobotTurn(true);
        setAdjustRadarForGunTurn(true);
        setAdjustRadarForRobotTurn(true);*/
        executeCommands(RUN_START);
    }
    
    public void onScannedRobot(ScannedRobotEvent e)
    {
        myObjects[1] = e;
        executeCommands(SCANNED_START);
    }
    
    private static String getNext()
    {
        return COMMANDS[myInstruction++];
    }
    
    private static void executeCommands(int startIndex)
    {
        myInstruction = startIndex;
        try
        {
            while(true)
            {
                // 2 codesize used to maintain prefix convention
                int command = Integer.parseInt(getNext());
                int value0 = (int) getNextValue();
                double value1 = getNextValue();
                if (command == CMD_SET)
                {
                    myVariables[value0] = value1;
                }
                // Default to CMD_IF
                // For goto use CMD_IF [Location] 0.0
                else
                {
                    //double value0 = getNextValue();
                    if (value1 == 0D)
                    {
                        myInstruction = value0;
                    }
                }
            }
        }
        catch (Exception ex)
        {
            // This should occur whenever there is no more code to execute
            // OR if there is syntax error in the code being interpreted
            //ex.printStackTrace();
        }
    }
    
    private static double getNextValue()
    {
        String command = getNext();
        try
        {
            int nextInt;
            if ((nextInt = Integer.parseInt(command)) == CMD_CALL)
            {
                // Syntax: [# Parameters] [Parameters] [Class Name] [Method Name] [Object Index]
                // Since there is no try-catch block dedicated to the method call,
                // CMD_CALL is returned if the method returns null
                //try
                {
                    Class classes[] = new Class[(int) getNextValue()];
                    Object objects[] = new Object[classes.length];
                    for (int i = 0; i < classes.length; i++)
                    {
                        classes[i] = double.class;
                        objects[i] = Double.valueOf(getNextValue());
                    }
                    return ((Number) Class.forName(getNext()).getMethod(getNext(), classes).invoke
                            (myObjects[(int) getNextValue()], objects)).doubleValue();
                }
                //catch (NullPointerException ex)
                //{
                //}
                //catch (Exception ex)
                //{
                //ex.printStackTrace();
                //}
                //return 0D;
            }
            
            double value0 = getNextValue();
            if (nextInt == CMD_VAR_VAL)
            {
                return myVariables[(int) value0];
            }
            
            if (nextInt == CMD_SUBTRACT)
            {
                return value0 - getNextValue();
            }
            //if (nextInt == CMD_DIVIDE)
            return value0 / getNextValue();
        }
        catch (Exception ex)
        {
            //ex.printStackTrace();
            // Integer.parseInt(getNext()) consumes the double so it has to go back
            return Double.parseDouble(command);
        }
    }
}


Download the compiler here (zip containing entire NetBeans project): http://www.geocities.com/seakinsen1/robocode/NanoInterpreter.zip


Robo Home | Interpreter | Changes | Preferences | AllPages
Edit text of this page | View other revisions
Last edited June 15, 2007 6:12 EST by ppp-71-138-52-250.dsl.sndg02.pacbell.net (diff)
Search: