简体   繁体   中英

Assistance Required, Developing Java Based Scripting Language?

I have just begun working on a programming language called XScript. It is designed so that I can run it from a Java application, but also re-program it through a java application. The idea being so that I can create virtual computers in games or a program that develops itself over time. So far I have the following code. I understand there may need to be an alteration to the name due to proprietary software, but for now it is fine.

The Artificial Main Class:

import com.x.lang.XLoader;


public class Main {
    public static void main(String[] args) {
        XLoader xl = new XLoader();

        xl.exec("/Users/Nathan/Desktop/XScript/test.xls");
    }
}

The XLoader (Loads and executes the XScript):

package com.x.lang;

import java.io.File;

import com.x.lang.object.XObject;

public class XLoader {
    XObject xo;
    public String fileLocation;

    public void exec(String fl) {
        fileLocation = fl;

        XObject xo = new XObject(new File(fileLocation));
        xo.exec();
    }
}

The XCommandHub Where the Language Key Functions are Stored:

package com.x.lang;

import com.x.lang.keyword.Print;
import com.x.lang.keyword.Set;
import com.x.lang.object.XCommand;
import com.x.lang.object.XObject;

public class XCommandHub {
    public XCommand xc[] = new XCommand[2];

    public XCommandHub(XObject x) {
            xc[0] = new Print(x);
        xc[1] = new Set(x);
    }
    public XCommand getCommand(String s) {
        for (int i = 0; i < 2; i++) {
            if (xc[i].getCommandName() == s) {
                return xc[i];
            }
        }
        return null;
    }
}

The XCommand Class Defining The Keywords:

package com.x.lang.object;

public abstract class XCommand {
    private String commandName;
    public XObject xobject;

    public XCommand (String cn, XObject x) {
        commandName = cn;
        commandName += ": ";
        xobject = x;
    }
    public abstract void exec(XVar xv);

    public String getCommandName() {
        return commandName;
    }
}

The XVar Class Defining All Variables:

package com.x.lang.object;

public class XVar {
    private String var1;
    public String name;

    public XVar(String s) {
        var1 = s;
    }
    public String getStringValue() {
        if (this.var1 != null) {
            return var1;
        }
        return " ";
    }
    public int getIntValue() {
        if (this.var1 != null) {
            return Integer.parseInt(var1);
        }
        return 0;
    }
    public void setName(String s) {
        name = s;
    }
}

The XObject Class Actual Executing the Commands:

package com.x.lang.object;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;

import com.x.lang.XCommandHub;

public class XObject {
    public XVar xvars[] = new XVar[150];
    public int varCount = 0;
    public File f;
    XCommandHub x;

    public XObject (File file) {
            f = file;
        x = new XCommandHub(this);
    }
    public void addVar(XVar var, String name) {
        xvars[varCount] = var;
        xvars[varCount].setName(name);
        varCount++;
    }
    public XVar getVar(String varName) {
        for (int i = 0; i < varCount; i++) {
            if (xvars[i].name == varName) {
                return xvars[i];
            }
        }
        return null;
    }
    public void exec() {
        try (BufferedReader br = new BufferedReader(new FileReader(f))) {
            String sCurrentLine;

            while ((sCurrentLine = br.readLine()) != null) {
                for (int i = 0; i < 2; i++) {
                    if (sCurrentLine.startsWith(x.xc[i].getCommandName()))
                    try {
                        x.getCommand(x.xc[i].getCommandName()).exec(new XVar(sCurrentLine.split(": ")[1]));
                    } catch (ArrayIndexOutOfBoundsException e) {
                        x.getCommand(x.xc[i].getCommandName()).exec(new XVar(" "));
                    }
                }
            }
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }
}

The Two Classes Defining The Commands I Have Programmed So Far:

package com.x.lang.keyword;

import com.x.lang.object.XCommand;
import com.x.lang.object.XObject;
import com.x.lang.object.XVar;

public class Print extends XCommand {
    public Print(XObject x) {
        super("print", x);
    }
    @Override
    public void exec(XVar xv) {
        if (xv.getStringValue().startsWith("%")) {
            try {
                System.out.println(xobject.getVar(xv.getStringValue().substring(1)).getStringValue());
            } catch (NullPointerException e) {
                System.out.println(xv.getStringValue());
            }
        }
        else {
            System.out.println(xv.getStringValue());
        }
    }
}


package com.x.lang.keyword;

import com.x.lang.object.XCommand;
import com.x.lang.object.XObject;
import com.x.lang.object.XVar;

public class Set extends XCommand {
    public Set(XObject x) {
        super("set", x);
    }
    @Override
    public void exec(XVar xv) {
        String[] add = xv.getStringValue().split("=");
        xobject.addVar(new XVar(add[1]), add[0]);
    }
}

From what I have programmed so far I have tried to give the user the ability to print a variable that they have declared in the code. A basic .xls (X Language Script) might look something like this:

set: x=Hello StackOverflow
print: This was programmed in XScript!
print: 
print: %x

However, there is a NullPointerException in the print class when I try and retrieve the variable x from the array. The program returns "%x" rather than "Hello StackOverflow", because I have deliberately caught the exception, however I do not know how it came about in the first place.

Thanks Doctor_N

Your code will never find the variable it is looking for:

public XVar getVar(String varName) {
    for (int i = 0; i < varCount; i++) {
        if (xvars[i].name == varName) {
            return xvars[i];
        }
    }

    return null;
}

This function will almost always return null since you are comparing strings using == and not using .equals . == compares references (memory addresses) and it is highly unlikely that the parameter and the string you are comparing against will point to the same location. Due to this, you almost always return null .

Because of that, this line will always cause a NullPointerException :

System.out.println(xobject.getVar(xv.getStringValue().substring(1)).getStringValue());

This is because you are effectively calling getStringValue() on null .

I suggest changing the if to:

if(xvars[i] != null && xvars[i].name.equals(varName)) {
    ...
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM