KonScript - Scripting Parser
Published 07/07/2012
📝 This project is from 2012, I’ve chosen to keep it here as a reminder of my progress and growth.
This is KonScript, a basic script parser created for performing fundamental logical operations. I developed it long before I had any formal knowledge of programming languages or design principles. I’ve chosen to keep it here as a reminder of my progress and growth.
The original goal of this project was to develop a domain-specific language that could execute various Java functions in order, with different parameters based on the script. Today, I would use DSLBuilder to achieve the same goal.
Functions (“outcall” Operators)
To extend KScript you’ll have to add your own “outcall” operators to create your own functions.
- print
<object val>
Prints a message to the console. - memory
<object val>
Clears the memory cache and resets it to the new value. - store
<memory index> <object val>
Stores the value into the specified memory index. - goto
<goto line>
Goes to the specified line. - ifeq
<object val> <object val> <goto line> <goto line>
Checks if the first value equals the second value. If so, goes to the first goto line; if not, goes to the second goto line. - ifne
<object val> <object val> <goto line> <goto line>
Checks if the first value is not equal to the second value. If so, goes to the first goto line; if not, goes to the second goto line. - ifgt
<object val> <object val> <goto line> <goto line>
Checks if the first value is greater than the second value. If so, goes to the first goto line; if not, goes to the second goto line. - iflt
<object val> <object val> <goto line> <goto line>
Checks if the first value is less than the second value. If so, goes to the first goto line; if not, goes to the second goto line.
Operators
- memory
<address>
Loads a value from the specified memory address. - +
Adds to the existing string (requires a check for integer values). - –
Converts strings to integers and performs subtraction. - ++
Converts strings to integers and performs addition.
KonScript Source Code
public class KonScript {
/*
* Used for parsing then executing scripts
*/
public static void runScript(String fileName) throws Exception {
loadScript(fileName);
doScript();
}
/*
* This is the actual script, it contains all of the content for the script to be ran
*/
private static ArrayList<String> script;
/*
* This is used as the virtual memory for the script, it allows loading to/from memory
*/
private static ArrayList<String> memory;
/*
* This method loads the script into the array
*/
private static void loadScript(String fileName) throws Exception {
script = new ArrayList<String>();
BufferedReader reader = new BufferedReader(new FileReader(fileName));
String contents;
while ((contents = reader.readLine()) != null) {
script.add(contents);
}
reader.close();
}
/*
* All of the actual logic behind the scripting language is here
*
* Functions are handled here
*/
private static void doScript() {
if(!script.isEmpty()) {
for(int line = 0; line < script.size(); line++) {
if(script.get(line).startsWith("#")) {
continue;
}
String[] argument = script.get(line).split("\t");
if(argument[0].equals("end")) {
break;
}
if(argument[0].startsWith("memory")) {
int limit = Integer.parseInt(argument[1]);
memory = new ArrayList<String>(limit);
for(int i = 0; i < limit; i++) {
memory.add("");
}
}
if(argument[0].startsWith("print")) {
System.out.println(parseOperators(argument[1]));
}
if(argument[0].startsWith("store")) {
memory.set(Integer.parseInt(argument[1]), parseOperators(argument[2]));
}
if(argument[0].startsWith("goto")) {
line = Integer.parseInt(argument[1]) -2;
}
if(argument[0].startsWith("ifeq")) {
if(parseOperators(argument[1]).equals(parseOperators(argument[2]))) {
line = Integer.parseInt(argument[3]) -2;
} else {
line = Integer.parseInt(argument[4]) -2;
}
}
if(argument[0].startsWith("ifne")) {
if(!parseOperators(argument[1]).equals(parseOperators(argument[2]))) {
line = Integer.parseInt(argument[3]) -2;
} else {
line = Integer.parseInt(argument[4]) -2;
}
}
if(argument[0].startsWith("ifgt")) {
if(Integer.parseInt(parseOperators(argument[1])) > Integer.parseInt((parseOperators(argument[2])))) {
line = Integer.parseInt(argument[3]) -2;
} else {
line = Integer.parseInt(argument[4]) -2;
}
}
if(argument[0].startsWith("iflt")) {
if(Integer.parseInt(parseOperators(argument[1])) < Integer.parseInt((parseOperators(argument[2])))) {
line = Integer.parseInt(argument[3]) -2;
} else {
line = Integer.parseInt(argument[4]) -2;
}
}
}
} else {
System.out.println("[ERROR]: Script is empty");
}
}
/*
* This is used to parse operators
*/
private static String parseOperators(String value) {
StringTokenizer st = new StringTokenizer(value,"_");
String finalValue = ""; //acts as the buffer
int flag = 0;
while (st.hasMoreTokens()) {
String currentToken = st.nextToken();
/* Pre-Defined Value */
if(currentToken.startsWith("\"")) {
currentToken = currentToken.substring(1,currentToken.length()-1);
} else {
/* Outcall Operators */
if(currentToken.startsWith("memory")) {
currentToken = memory.get(Integer.parseInt(currentToken.substring("memory".length())));
} else if(currentToken.startsWith("times")) {
currentToken = "" + (int) (System.currentTimeMillis() / 1000) % 60 ;
} else
/* Operators */
if(currentToken.equals("+")) {
} else if(currentToken.equals("--")) {
} else if(currentToken.equals("++")) {
} else {
throw new RuntimeException("Cannot find that operator");
}
}
/* Operator Flags */
if(flag == 1) {
finalValue += currentToken;
flag = 0;
} else if(flag == 2) {
finalValue = ""+(Integer.parseInt(finalValue) - Integer.parseInt(currentToken));
flag = 0;
} else if(flag == 3) {
finalValue = ""+ (Integer.parseInt(finalValue) + Integer.parseInt(currentToken));
flag = 0;
}
/* Operators */
else if(currentToken.equals("+")) {
flag = 1;
} else if(currentToken.equals("--")) {
flag = 2;
} else if(currentToken.equals("++")) {
flag = 3;
} else {
finalValue += currentToken;
}
}
return finalValue;
}
}
Hello World.ks
A simple Hello World
print "Hello World"
Hello World From Memory.ks
A more complicated Hello World
memory 1
store 0 "Hello World"
print memory0
Hello World Delayed.ks
Waits 5 seconds and prints “Hello World”
memory 1
store 0 times
ifgt times_--_memory0 "5" 11 10
print "Hello World"
end
for.ks
This is meant to show-case the two operations of addition inside a for loop using String concatenation and Integer addition.
memory 1
#append to a String
store 0 memory0_+_"1"
print memory0
ifeq memory0 "1111111" 11 13
print "Memory reached: "_+_memory0
goto 15
goto 8
#add to an Integer
memory 1
store 0 "0"
store 0 memory0_++_"1"
print memory0
ifeq memory0 "5" 20 22
print "Memory reached: "_+_memory0
end
goto 17