aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoshua Rahm <joshua.rahm@colorado.edu>2015-01-27 18:40:32 -0700
committerJoshua Rahm <joshua.rahm@colorado.edu>2015-01-27 18:40:32 -0700
commit5f3fb9afece2125cbeba79d61a8d88460b7878d7 (patch)
treeb0e1e60bae9927a9449561bf7fe9431a54d12be9
downloadLegacyQBar-5f3fb9afece2125cbeba79d61a8d88460b7878d7.tar.gz
LegacyQBar-5f3fb9afece2125cbeba79d61a8d88460b7878d7.tar.bz2
LegacyQBar-5f3fb9afece2125cbeba79d61a8d88460b7878d7.zip
initial commit
-rwxr-xr-xhello.qbar8
-rwxr-xr-xinstaller/README.txt1
-rwxr-xr-xinstaller/install.sh36
-rw-r--r--installer/qbar/lib/JavaCommon.jarbin0 -> 28273 bytes
-rw-r--r--installer/qbar/lib/QBarInterpreter.jarbin0 -> 102851 bytes
-rw-r--r--installer/qbar/lib/endorsed/io.jarbin0 -> 40141 bytes
-rw-r--r--installer/qbar/lib/endorsed/mysql-connector-java-5.1.16-bin.jarbin0 -> 786484 bytes
-rw-r--r--installer/qbar/lib/endorsed/mysql.jarbin0 -> 11115 bytes
-rwxr-xr-xinstaller/qbar/qbar.sh3
-rw-r--r--installer/qbar/qbar/io/BufferedReader.qbar62
-rw-r--r--installer/qbar/qbar/io/File.qbar10
-rw-r--r--installer/qbar/qbar/io/Reader.qbar24
-rw-r--r--installer/qbar/qbar/lang/Math.qbar84
-rw-r--r--installer/qbar/qbar/lang/Maybe.qbar16
-rw-r--r--installer/qbar/qbar/lang/System.qbar11
-rwxr-xr-xinstaller/qbar_package.tgzbin0 -> 902804 bytes
-rw-r--r--project/JavaCommon/.classpath6
-rw-r--r--project/JavaCommon/.project17
-rw-r--r--project/JavaCommon/build.xml48
-rw-r--r--project/JavaCommon/common_build.xml18
-rw-r--r--project/JavaCommon/src/.project17
-rw-r--r--project/JavaCommon/src/com/modulus/access/ArrayFunction.java24
-rw-r--r--project/JavaCommon/src/com/modulus/common/TwoTypeBean.java44
-rw-r--r--project/JavaCommon/src/com/modulus/common/collections/ArrayStack.java101
-rw-r--r--project/JavaCommon/src/com/modulus/common/collections/BaseModelData.java29
-rw-r--r--project/JavaCommon/src/com/modulus/common/collections/Collections2.java28
-rw-r--r--project/JavaCommon/src/com/modulus/common/collections/Grid.java35
-rw-r--r--project/JavaCommon/src/com/modulus/common/collections/IntMap.java84
-rw-r--r--project/JavaCommon/src/com/modulus/common/collections/MArrays.java180
-rw-r--r--project/JavaCommon/src/com/modulus/common/collections/ModelData.java9
-rw-r--r--project/JavaCommon/src/com/modulus/common/collections/Stack.java57
-rw-r--r--project/JavaCommon/src/com/modulus/common/collections/UpdateableGrid.java21
-rw-r--r--project/JavaCommon/src/com/modulus/common/strings/Tokenizer.java48
-rw-r--r--project/JavaCommon/src/com/modulus/console/InputReader.java9
-rw-r--r--project/JavaCommon/src/com/modulus/dataread/expressions/AbstractStatement.java125
-rw-r--r--project/JavaCommon/src/com/modulus/dataread/expressions/ExpressionParser.java5
-rw-r--r--project/JavaCommon/src/com/modulus/dataread/expressions/ExpressionPart.java136
-rw-r--r--project/JavaCommon/src/com/modulus/dataread/expressions/FlowStatement.java3
-rw-r--r--project/JavaCommon/src/com/modulus/dataread/expressions/LineNumberException.java25
-rw-r--r--project/JavaCommon/src/com/modulus/dataread/expressions/ParseRules.java84
-rw-r--r--project/JavaCommon/src/com/modulus/dataread/expressions/Statement.java105
-rw-r--r--project/JavaCommon/src/com/modulus/dataread/expressions/StatementFactory.java28
-rw-r--r--project/JavaCommon/src/com/modulus/dataread/expressions/StatementFormatter.java26
-rw-r--r--project/JavaCommon/src/com/modulus/dataread/expressions/StatementTreeParser.java21
-rw-r--r--project/JavaCommon/src/com/modulus/dataread/expressions/impl/AbstractParseRules.java197
-rw-r--r--project/JavaCommon/src/com/modulus/dataread/expressions/impl/CBasedParseRules.java57
-rw-r--r--project/JavaCommon/src/com/modulus/dataread/expressions/impl/FormatStatement.java52
-rw-r--r--project/JavaCommon/src/com/modulus/dataread/expressions/impl/SimpleExpressionParser.java139
-rw-r--r--project/JavaCommon/src/com/modulus/dataread/expressions/impl/SimpleStatement.java19
-rw-r--r--project/JavaCommon/src/com/modulus/dataread/expressions/impl/SimpleStatementTreeParser.java162
-rw-r--r--project/JavaCommon/src/com/modulus/dataread/expressions/impl/StatementParser.java5
-rw-r--r--project/QBarInterpreter/.classpath7
-rw-r--r--project/QBarInterpreter/.project17
-rw-r--r--project/QBarInterpreter/TestQBFile.qbar7
-rw-r--r--project/QBarInterpreter/TestQBFile.qbcbin0 -> 38687 bytes
-rw-r--r--project/QBarInterpreter/TestQBFile2.qbar60
-rw-r--r--project/QBarInterpreter/build.xml74
-rw-r--r--project/QBarInterpreter/completions.txt1
l---------project/QBarInterpreter/qbar1
-rwxr-xr-xproject/QBarInterpreter/qbar.sh36
-rw-r--r--project/QBarInterpreter/qbar_lang/io/BufferedReader.qbar62
-rw-r--r--project/QBarInterpreter/qbar_lang/io/File.qbar10
-rw-r--r--project/QBarInterpreter/qbar_lang/io/IO.qbar12
-rw-r--r--project/QBarInterpreter/qbar_lang/io/Reader.qbar24
-rw-r--r--project/QBarInterpreter/qbar_lang/lang/Math.qbar131
-rw-r--r--project/QBarInterpreter/qbar_lang/lang/Maybe.qbar4
-rw-r--r--project/QBarInterpreter/qbar_lang/lang/System.qbar29
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/core/NaturalFunctions.java376
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/core/QBArray.java26
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/core/QBConstructor.java46
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/core/QBFile.java36
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/core/QBFunction.java131
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/core/QBNamespace.java161
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/core/QBObject.java89
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/core/QBReference.java19
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/core/QBStruct.java137
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/core/QBSyntheticFunction.java338
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/core/QBSyntheticStruct.java68
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/core/QBSyntheticUtilityNamespace.java38
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/core/QBUtilityNamespace.java22
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/core/Type.java5
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/core/compile/ByteOps.java21
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/core/exceptions/ExecutionException.java23
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/core/exceptions/ParseException.java32
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/core/interpreter/CompiledReader.java13
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/core/interpreter/CompressedReader.java13
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/core/interpreter/Main.java217
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/core/interpreter/QBInteractiveInterpreter.java113
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/core/interpreter/QBInterpreter.java193
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/core/interpreter/QBInterpreterReader.java7
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/core/interpreter/QBJarLoader.java49
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/core/interpreter/SourceReader.java13
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/core/interpreter/TransparentFunction.java24
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/core/parser/AnnotationReader.java7
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/core/parser/ByteOperation.java43
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/core/parser/Core.java78
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/core/parser/ExpressionCompiler.java62
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/core/parser/ExpressionPuller.java160
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/core/parser/ExpressionSpaceTokenizer.java106
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/core/parser/IfThenElseFunctionFactory.java16
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/core/parser/ListConstructorFactory.java160
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/core/parser/QBExpressionParser.java341
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/core/parser/QBFileType.java37
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/core/parser/QBParser.java307
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/core/parser/QBParser.java.bak98
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/core/parser/stmt/QBStatement.java127
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/core/parser/stmt/QBStatements.java37
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/core/primitive/QBChar.java69
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/core/primitive/QBDouble.java71
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/core/primitive/QBInt.java111
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/core/primitive/QBPrimitive.java122
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/integration/QBWrappedClass.java68
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/integration/QBWrappedConstructor.java53
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/integration/QBWrappedMethod.java95
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/integration/QBWrappedObject.java160
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/integration/QBWrappedUtilityNamespace.java20
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/lang/IfThenElseFunction.java41
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/lang/ListConstructor.java17
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/lang/QBArrayList.java98
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/lang/QBArrayListConstructor.java29
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/lang/QBFunctionList.java54
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/lang/QBFunctionListConstructor.java18
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/lang/QBFunctionListFunction.java66
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/lang/QBIterator.java124
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/lang/QBLazyRangeList.java92
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/lang/QBLazyRangeListConstructor.java65
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/lang/QBList.java160
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/lang/QBListFactory.java5
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/lang/QBListIterator.java30
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/lang/QBMath.java243
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/lang/QBMaybe.java59
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/lang/QBString.java111
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/lang/QBSubList.java77
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/lang/QBSyntheticIterator.java31
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/lang/QBSystem.java11
-rw-r--r--project/QBarInterpreter/src/com/modulus/qbar/lang/Test.java11
-rwxr-xr-xqbar-installer.tgzbin0 -> 903864 bytes
137 files changed, 8594 insertions, 0 deletions
diff --git a/hello.qbar b/hello.qbar
new file mode 100755
index 0000000..a18e8de
--- /dev/null
+++ b/hello.qbar
@@ -0,0 +1,8 @@
+#!/usr/bin/qbar
+Import qbar/lang/System.qbar;
+
+let main = do {
+ for [ 0 .. ] -> i {
+ System.printStrLn( "" ++ i ++ ".)" );
+ }
+}
diff --git a/installer/README.txt b/installer/README.txt
new file mode 100755
index 0000000..b621bb5
--- /dev/null
+++ b/installer/README.txt
@@ -0,0 +1 @@
+To install it is very simple, just run installer.sh
diff --git a/installer/install.sh b/installer/install.sh
new file mode 100755
index 0000000..c0c47e3
--- /dev/null
+++ b/installer/install.sh
@@ -0,0 +1,36 @@
+#!/bin/bash
+
+if [ `whoami` != root ] ; then
+ echo "Woah! Not so fast, need to be root!"
+ exit 1
+fi
+
+if [ -d /usr/lib/qbar ] ; then
+ echo "Wait, qbar is already installed, or at least the directory is still there (/usr/lib/qbar)"
+
+ echo "Would you like to reinstall it? [Y/n]"
+ read input
+
+ while [[ ($input != Y && $input != n) ]] ; do
+ echo "Y or n"
+ read input
+ done
+
+ if [ $input == n ] ; then
+ exit 0
+ else
+ rm -rv /usr/lib/qbar
+ rm -v /usr/bin/qbar
+ fi
+fi
+
+tar -xzvf qbar_package.tgz
+mv -v qbar/ /usr/lib/
+
+# ---------- Time to install the binary into the right directory ------------
+cd /usr/bin
+
+# need to sym-link to qbar, then we should be good.
+ln -sv /usr/lib/qbar/qbar.sh qbar
+chmod +x qbar
+
diff --git a/installer/qbar/lib/JavaCommon.jar b/installer/qbar/lib/JavaCommon.jar
new file mode 100644
index 0000000..604c670
--- /dev/null
+++ b/installer/qbar/lib/JavaCommon.jar
Binary files differ
diff --git a/installer/qbar/lib/QBarInterpreter.jar b/installer/qbar/lib/QBarInterpreter.jar
new file mode 100644
index 0000000..a95ecb1
--- /dev/null
+++ b/installer/qbar/lib/QBarInterpreter.jar
Binary files differ
diff --git a/installer/qbar/lib/endorsed/io.jar b/installer/qbar/lib/endorsed/io.jar
new file mode 100644
index 0000000..38cb62e
--- /dev/null
+++ b/installer/qbar/lib/endorsed/io.jar
Binary files differ
diff --git a/installer/qbar/lib/endorsed/mysql-connector-java-5.1.16-bin.jar b/installer/qbar/lib/endorsed/mysql-connector-java-5.1.16-bin.jar
new file mode 100644
index 0000000..e62f2cb
--- /dev/null
+++ b/installer/qbar/lib/endorsed/mysql-connector-java-5.1.16-bin.jar
Binary files differ
diff --git a/installer/qbar/lib/endorsed/mysql.jar b/installer/qbar/lib/endorsed/mysql.jar
new file mode 100644
index 0000000..023d025
--- /dev/null
+++ b/installer/qbar/lib/endorsed/mysql.jar
Binary files differ
diff --git a/installer/qbar/qbar.sh b/installer/qbar/qbar.sh
new file mode 100755
index 0000000..31d7033
--- /dev/null
+++ b/installer/qbar/qbar.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+java -jar /usr/lib/qbar/lib/QBarInterpreter.jar -p /usr/lib/qbar $@
diff --git a/installer/qbar/qbar/io/BufferedReader.qbar b/installer/qbar/qbar/io/BufferedReader.qbar
new file mode 100644
index 0000000..0b5c382
--- /dev/null
+++ b/installer/qbar/qbar/io/BufferedReader.qbar
@@ -0,0 +1,62 @@
+Import qbar/io/Reader.qbar;
+Import qbar/lang/Maybe.qbar;
+Import qbar/lang/System.qbar;
+
+Namespace BufferedReader {
+ Incorporate Reader;
+
+ Struct BufferedReader extends Reader {
+ let new BufferedReader( reader ) = do {
+ this.init( reader );
+
+ if reader isa Reader {
+ this.reader <- reader;
+ } else {
+ this.reader <- new Reader( reader );
+ }
+
+ this.buffer <- [];
+ this.bufSize <- 4096;
+ this.bufCur <- 0;
+ this.dbg <- 1;
+
+ System.printStrLn( "START" );
+
+ this.readBuffer();
+ }
+
+ let read = do {
+ if this.bufCur == this.bufSize {
+ this.readBuffer();
+ this.bufCur <- 0;
+ }
+
+ yeild <- this.buffer#this.bufCur;
+ this.bufCur <- this.bufCur + 1;
+
+ return yeild;
+ }
+
+ let readBuffer = do {
+ System.printStrLn( "Reading Buffer " ++ this.dbg );
+ this.buffer <- this.readBytes( this.bufSize );
+ this.dbg <- this.dbg + 1;
+ }
+
+ let readLine = do {
+ str <- "" ++ "";
+
+ i <- 0;
+ while ( i <- this.read() ) != 10 {
+ if i == -1 {
+ return if str.length == 0 then Maybe.new Null()
+ else Maybe.new Maybe( str );
+ }
+
+ str +< i as Character;
+ }
+
+ return Maybe.new Maybe(str);
+ }
+ }
+} \ No newline at end of file
diff --git a/installer/qbar/qbar/io/File.qbar b/installer/qbar/qbar/io/File.qbar
new file mode 100644
index 0000000..3f848aa
--- /dev/null
+++ b/installer/qbar/qbar/io/File.qbar
@@ -0,0 +1,10 @@
+-{
+ This namespace has several native methods
+ that are used to help dealing with file operations.
+}-
+Namespace File {
+ -{
+ Incorporates com.modulus.qbar.io.IOTools class
+ }-
+ Incorporate Native com.modulus.qbar.io.IOTools;
+} \ No newline at end of file
diff --git a/installer/qbar/qbar/io/Reader.qbar b/installer/qbar/qbar/io/Reader.qbar
new file mode 100644
index 0000000..3522adf
--- /dev/null
+++ b/installer/qbar/qbar/io/Reader.qbar
@@ -0,0 +1,24 @@
+Namespace Reader {
+ Struct Reader {
+ -- some kind of instream
+ let new Reader( instream ) = this.init( instream );
+
+ let init( instream ) = this.instream <- instream;
+
+ let close = this.instream.close();
+
+ let mark = this.instream.mark();
+
+ let reset = this.instream.reset();
+
+ let read = this.instream.read();
+
+ let readBytes(n) = this.instream.readBytes(n);
+
+ let skip(n) = this.instream.skip();
+
+ let available = this.instream.available();
+
+ let nextChar = this.read() as Character;
+ }
+} \ No newline at end of file
diff --git a/installer/qbar/qbar/lang/Math.qbar b/installer/qbar/qbar/lang/Math.qbar
new file mode 100644
index 0000000..965c123
--- /dev/null
+++ b/installer/qbar/qbar/lang/Math.qbar
@@ -0,0 +1,84 @@
+-{
+ Math namespace, this holds many
+ useful functions for anytime
+ math computations.
+
+ This namespace includes aliases
+ of all the functions in java.lang.Math
+ and also includes some extra series
+ functions.
+ }-
+Namespace QBMath {
+
+ -- need to include the native java class
+ Incorporate Native java.lang.Math;
+
+ -{
+ The constructor of QBMath creates some
+ of the basic series that QBMath uses.
+ }-
+ let construct = do {
+
+
+ -- the `this` is negated all too often
+ -{
+ The series list for pascal's
+ triangle.
+ }-
+ this.pascalSeries <- [ n | if n <= 0 then [1]
+ else if n == 1 then [ 1, 1 ]
+ else QBMath.pascalTriangle( this#(n-1) ) ];
+
+ -{
+ The series list for the fibonacci
+ series
+ }-
+ this.fibonacciSeries <- [ n | if n < 2 then n
+ else this#( n - 1 ) + this#(n - 2) ];
+
+ -{
+ The series list for the
+ factorial series.
+ }-
+ this.factorialSeries <- [ n | if n <= 1 then 1
+ else n * this#(n - 1) ];
+ }
+
+ -{
+ The pascal function takes
+ a list and uses that list
+ to generate what would be
+ the next list in the pascal
+ series.
+ }-
+ let pascalTriangle( lastList ) = do {
+ ret <- [1];
+
+ for [ 0 .. lastList.length - 2 ] -> n {
+ ret +< lastList#n + lastList#(n+1);
+ }
+
+ ret +< 1;
+ return ret;
+ }
+
+ -{
+ Directly accesses the factorialSeries
+ get function.
+
+ @return the factorial of `n` (`n!`)
+ }-
+ let factorial( n ) = this.factorialSeries # n;
+
+ -{
+ @return the `n`<sup>th</sup> number
+ in the fibonacci series.
+ }-
+ let fibonacci( n ) = this.fibonacciSeries # n;
+
+ -{
+ @return the `n`<sup>th</sup> list in
+ pascal's triangle list.
+ }-
+ let pascal( n ) = this.pascalList # n;
+} \ No newline at end of file
diff --git a/installer/qbar/qbar/lang/Maybe.qbar b/installer/qbar/qbar/lang/Maybe.qbar
new file mode 100644
index 0000000..5b4e37d
--- /dev/null
+++ b/installer/qbar/qbar/lang/Maybe.qbar
@@ -0,0 +1,16 @@
+Import qbar/lang/System.qbar;
+
+Namespace Maybe {
+ Struct Maybe {
+ let new Null = this.null <- 1;
+
+ let new Maybe( obj ) = do {
+ this.obj <- obj;
+ this.null <- 0;
+ }
+
+ let isNull = this.null;
+
+ let getObj = this.obj;
+ }
+} \ No newline at end of file
diff --git a/installer/qbar/qbar/lang/System.qbar b/installer/qbar/qbar/lang/System.qbar
new file mode 100644
index 0000000..6b04d59
--- /dev/null
+++ b/installer/qbar/qbar/lang/System.qbar
@@ -0,0 +1,11 @@
+
+-{
+ This namespace holds many raw and basic
+ functions that the user may want to use.
+
+ This Namespace is for the most part native.
+ }-
+Namespace System {
+ -- incorporate the native QBSystem class
+ Incorporate Native com.modulus.qbar.lang.QBSystem;
+} \ No newline at end of file
diff --git a/installer/qbar_package.tgz b/installer/qbar_package.tgz
new file mode 100755
index 0000000..2d6d4a6
--- /dev/null
+++ b/installer/qbar_package.tgz
Binary files differ
diff --git a/project/JavaCommon/.classpath b/project/JavaCommon/.classpath
new file mode 100644
index 0000000..fb50116
--- /dev/null
+++ b/project/JavaCommon/.classpath
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/project/JavaCommon/.project b/project/JavaCommon/.project
new file mode 100644
index 0000000..0e6dc5d
--- /dev/null
+++ b/project/JavaCommon/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>JavaCommon</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/project/JavaCommon/build.xml b/project/JavaCommon/build.xml
new file mode 100644
index 0000000..cc80037
--- /dev/null
+++ b/project/JavaCommon/build.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- ======================================================================
+ Apr 5, 2011 7:08:11 PM
+
+ JavaCommon
+ Common resources shared by all java projects
+
+ jrahm
+ ====================================================================== -->
+<project name="JavaCommon" default="build">
+
+ <import file="common_build.xml" />
+
+ <path id="project.class.path">
+ <fileset dir="${lib.dir}" includes="**/*.jar" />
+ </path>
+
+ <target name="lib" description="Builds The Lib Direrctory">
+ <mkdir dir="${lib.dir}" />
+
+ <copy todir="${lib.dir}" >
+ <fileset dir="lib" includes="**/*.jar" />
+ </copy>
+ </target>
+
+ <target name="compile" depends="lib">
+ <mkdir dir="${bin.dir}" />
+ <javac srcdir="${src.dir}" includes="**" encoding="utf-8" destdir="${bin.dir}">
+ <classpath refid="project.class.path" />
+ </javac>
+ </target>
+
+ <target name="package" depends="compile" >
+ <mkdir dir="${lib.dir}"/>
+ <jar basedir="${bin.dir}" destfile="${lib.dir}/${ant.project.name}.jar" />
+ </target>
+
+ <target name="doc">
+ <mkdir dir="${doc.dir}" />
+ <javadoc sourcepath="${src.dir}" destdir="${doc.dir}" />
+ </target>
+
+ <target name="build" depends="package" />
+
+ <target name="clean">
+ <delete dir="bin"/>
+ </target>
+</project>
diff --git a/project/JavaCommon/common_build.xml b/project/JavaCommon/common_build.xml
new file mode 100644
index 0000000..c41aade
--- /dev/null
+++ b/project/JavaCommon/common_build.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- ======================================================================
+ Apr 5, 2011 11:04:12 PM
+
+ project
+ description
+
+ jrahm
+ ====================================================================== -->
+<project name="BuildCommon" >
+
+ <property name="lib.dir" value="../../../build/java_libs"/>
+ <property name="bin.dir" value="classes" />
+ <property name="src.dir" value="src" />
+ <property name="doc.dir" value="../../../build/java_libs/doc"/>
+ <property name="endorsed.dir" value="../../../build/qbar/lib/endorsed"/>
+
+</project>
diff --git a/project/JavaCommon/src/.project b/project/JavaCommon/src/.project
new file mode 100644
index 0000000..9fdd004
--- /dev/null
+++ b/project/JavaCommon/src/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>JavaExtendedAPI</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/project/JavaCommon/src/com/modulus/access/ArrayFunction.java b/project/JavaCommon/src/com/modulus/access/ArrayFunction.java
new file mode 100644
index 0000000..89ce636
--- /dev/null
+++ b/project/JavaCommon/src/com/modulus/access/ArrayFunction.java
@@ -0,0 +1,24 @@
+package com.modulus.access;
+
+/**
+ * Any kind of function that takes an array of type <code>E</code>
+ * and returns an object of type <code>T</code>.
+ *
+ * Usually, the return type and the argument types are the same type.
+ *
+ * @author jrahm
+ *
+ * @param <T> the return type of this function
+ * @param <E> the argument type of the function
+ */
+public interface ArrayFunction< T, E > {
+
+ /**
+ * Executes this function using the arguments <code>args</code>
+ * and returns an object of type <code>T</code>
+ *
+ * @param args the arguments to execute this function with.
+ * @return some value of type <code>T</code>
+ */
+ public T execute( E[] args );
+}
diff --git a/project/JavaCommon/src/com/modulus/common/TwoTypeBean.java b/project/JavaCommon/src/com/modulus/common/TwoTypeBean.java
new file mode 100644
index 0000000..28e1e41
--- /dev/null
+++ b/project/JavaCommon/src/com/modulus/common/TwoTypeBean.java
@@ -0,0 +1,44 @@
+package com.modulus.common;
+
+/**
+ * Class that simply holds two different (or same) object
+ * types. It is a rough implementation of what a tuple can be
+ * considered
+ *
+ * @author jrahm
+ *
+ * @param <T> type of object 1
+ * @param <E> type of object 2
+ */
+public class TwoTypeBean<T, E> {
+ private T obj1;
+ private E obj2;
+
+ /**
+ * Creates a new TwoTypeBean from the two
+ * objects.
+ *
+ * @param obj1 object 1
+ * @param obj2 object 2
+ */
+ public TwoTypeBean(T obj1, E obj2){
+ this.obj1 = obj1;
+ this.obj2 = obj2;
+ }
+
+ /**
+ * Returns the first object
+ * @return the first object
+ */
+ public T getObject1(){
+ return obj1;
+ }
+
+ /**
+ * Returns the second object
+ * @return the second object
+ */
+ public E getObject2(){
+ return obj2;
+ }
+}
diff --git a/project/JavaCommon/src/com/modulus/common/collections/ArrayStack.java b/project/JavaCommon/src/com/modulus/common/collections/ArrayStack.java
new file mode 100644
index 0000000..17dfcb1
--- /dev/null
+++ b/project/JavaCommon/src/com/modulus/common/collections/ArrayStack.java
@@ -0,0 +1,101 @@
+package com.modulus.common.collections;
+
+import java.io.Serializable;
+
+/**
+ * Class which uses an array to be used to
+ * implement a stack.
+ *
+ * This class is most efficient for
+ * nearly every purpose.
+ *
+ * @author jrahm
+ *
+ * @param <T> the type this stack holds
+ */
+public class ArrayStack<T> implements Stack<T>, Serializable{
+
+ private Object[] arr;
+ private int pointer = -1;
+
+ /**
+ * Creates a new ArrayStack with a
+ * default starting size of 10
+ */
+ public ArrayStack(){
+ this(10);
+ }
+
+ /**
+ * Creates a new ArrayStack with
+ * a default starting size of <code>size</code>
+ * @param size
+ */
+ public ArrayStack( int size ){
+ arr = new Object[size];
+ }
+
+ /**
+ * Ensures that this ArrayStack has enough space
+ * to store <code>size</code> number of elements.
+ *
+ * @param size the number of elements needed to store
+ */
+ public void ensureSize( int size ){
+
+ if(arr.length > size)
+ return;
+
+ Object[] tmp = new Object[size*2];
+ for ( int i = 0;i < arr.length; i ++ ){
+ tmp[i] = arr[i];
+ }
+
+ arr = tmp;
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return pointer == -1;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public T peek() {
+ return (T)arr[pointer];
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public T pop() {
+ return (T) arr[ pointer -- ];
+ }
+
+ @Override
+ public void push(T obj) {
+ pointer ++;
+ this.ensureSize(pointer);
+ arr[pointer] = obj;
+ }
+
+ @Override
+ public int size() {
+ return pointer + 1;
+ }
+
+ @Override
+ public void clear(){
+ pointer = 0;
+ }
+
+ @Override
+ public String toString(){
+ StringBuffer buf = new StringBuffer("[");
+
+ for( int i = pointer; i >= 1; i --)
+ buf.append(arr[i] + ", ");
+
+ buf.append(arr[0] + "]");
+ return buf.toString();
+ }
+}
diff --git a/project/JavaCommon/src/com/modulus/common/collections/BaseModelData.java b/project/JavaCommon/src/com/modulus/common/collections/BaseModelData.java
new file mode 100644
index 0000000..250f980
--- /dev/null
+++ b/project/JavaCommon/src/com/modulus/common/collections/BaseModelData.java
@@ -0,0 +1,29 @@
+package com.modulus.common.collections;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+public class BaseModelData<T> implements ModelData<T>{
+ private Map<Object, T> map = new HashMap<Object, T>();
+
+ @Override
+ public T get(Object key) {
+ return map.get(key);
+ }
+
+ @Override
+ public Object[] keys() {
+ Set<Object> keys = map.keySet();
+
+ return keys.toArray( new Object[keys.size()] );
+ }
+
+ @Override
+ public void set(Object key, Object obj) {
+ // TODO Auto-generated method stub
+
+ }
+
+
+}
diff --git a/project/JavaCommon/src/com/modulus/common/collections/Collections2.java b/project/JavaCommon/src/com/modulus/common/collections/Collections2.java
new file mode 100644
index 0000000..65bcc60
--- /dev/null
+++ b/project/JavaCommon/src/com/modulus/common/collections/Collections2.java
@@ -0,0 +1,28 @@
+package com.modulus.common.collections;
+
+public class Collections2 {
+
+ static public Integer[] rangeAsObjects(int start, int stop)
+ {
+ Integer[] result = new Integer[stop-start];
+
+ for(int i=0;i<stop-start;i++)
+ result[i] = start+i;
+
+ return result;
+ }
+
+ static public int[] range(int start, int stop)
+ {
+ int[] result = new int[stop-start];
+
+ for(int i=0;i<stop-start;i++)
+ result[i] = start+i;
+
+ return result;
+ }
+
+ static public int[] range(int stop){
+ return range(0, stop);
+ }
+}
diff --git a/project/JavaCommon/src/com/modulus/common/collections/Grid.java b/project/JavaCommon/src/com/modulus/common/collections/Grid.java
new file mode 100644
index 0000000..817a36c
--- /dev/null
+++ b/project/JavaCommon/src/com/modulus/common/collections/Grid.java
@@ -0,0 +1,35 @@
+package com.modulus.common.collections;
+
+/**
+ * Interface describing an immutable grid interface.
+ *
+ * @author jrahm
+ *
+ * @param <T> the type of object this grid holds
+ */
+public interface Grid<T> {
+ /**
+ * Returns the object stored in
+ * row <code>row</code> and column
+ * <code>col</code>
+ *
+ * @param row the row of the object
+ * @param col the column of the object
+ * @return the object stored in that row and column
+ */
+ public T get(int row, int col);
+
+ /**
+ * Returns the number of columns in this grid
+ *
+ * @return the number of columns in this grid
+ */
+ public int numberOfColumns();
+
+ /**
+ * Returns the number of columns in this grid.
+ *
+ * @return the number of columns in this grid
+ */
+ public int numberOfRows();
+}
diff --git a/project/JavaCommon/src/com/modulus/common/collections/IntMap.java b/project/JavaCommon/src/com/modulus/common/collections/IntMap.java
new file mode 100644
index 0000000..558cd9f
--- /dev/null
+++ b/project/JavaCommon/src/com/modulus/common/collections/IntMap.java
@@ -0,0 +1,84 @@
+package com.modulus.common.collections;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+public class IntMap<T> implements Map<Integer, T> {
+ private List<T> list = new ArrayList<T>();
+
+ @Override
+ public void clear() {
+ this.list.clear();
+ }
+
+ @Override
+ public boolean containsKey(Object arg0) {
+ if( arg0 instanceof Integer)
+ return ((Integer) arg0) < this.list.size();
+
+ return false;
+ }
+
+ @Override
+ public boolean containsValue(Object arg0) {
+ return list.contains(arg0);
+ }
+
+ @Override
+ public Set<java.util.Map.Entry<Integer, T>> entrySet() {
+ throw new RuntimeException("Not Implemented (At The Moment)");
+ }
+
+ @Override
+ public T get(Object arg0) {
+ try{
+ return list.get( (Integer)arg0 );
+ } catch(ClassCastException e){
+ return null;
+ }
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return list.isEmpty();
+ }
+
+ @Override
+ public Set<Integer> keySet() {
+ return new HashSet<Integer>( Arrays.asList( Collections2.rangeAsObjects(0, list.size()) ) );
+ }
+
+ @Override
+ public T put(Integer arg0, T arg1) {
+ return list.set(arg0, arg1);
+ }
+
+ @Override
+ public void putAll(Map<? extends Integer, ? extends T> arg0) {
+ throw new RuntimeException("Not Implemented At the Moment");
+ }
+
+ @Override
+ public T remove(Object arg0) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public int size() {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ @Override
+ public Collection<T> values() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+}
diff --git a/project/JavaCommon/src/com/modulus/common/collections/MArrays.java b/project/JavaCommon/src/com/modulus/common/collections/MArrays.java
new file mode 100644
index 0000000..08d9540
--- /dev/null
+++ b/project/JavaCommon/src/com/modulus/common/collections/MArrays.java
@@ -0,0 +1,180 @@
+package com.modulus.common.collections;
+
+import java.lang.reflect.Array;
+import java.util.AbstractList;
+import java.util.List;
+
+public class MArrays {
+ public static int indexOf( Object[] objs , Object obj, int start ){
+ for ( int i = start; i < objs.length; i ++)
+ if(objs[i].equals(obj))
+ return i;
+ return -1;
+ }
+
+ public static int lastIndexOf( Object[] objs , Object obj, int end ){
+ for ( int i = end; i >= 0; i --)
+ if(objs[i].equals(obj))
+ return i;
+ return -1;
+ }
+
+ public static int indexOf( Object[] objs, Object obj ){
+ return indexOf( objs, obj, 0 );
+ }
+
+ public static int lastIndexOf( Object[] objs, Object obj ){
+ return lastIndexOf( objs, obj, objs.length - 1 );
+ }
+
+ public static String concat(String[] args, int off, int len, String sep){
+ StringBuffer buf = new StringBuffer();
+ int lastDex = len + off;
+
+ for(int i = off;i < lastDex-1;i++)
+ buf.append(args[i] + sep);
+ buf.append(args[lastDex-1]);
+
+ return buf.toString();
+ }
+
+ public static String concat(String[] args, int off, String sep){
+ return concat(args, off, args.length-off, sep);
+ }
+
+ public static String concat(String[] args, String sep){
+ return concat(args, 0, args.length, sep);
+ }
+
+ public static String concat(String[] args, int off){
+ return concat(args, off, "");
+ }
+
+ public static String concat(String[] args){
+ return concat(args, "");
+ }
+
+ public static String concat(String[] args, int off, int len){
+ return concat(args, off, len, "");
+ }
+
+ public static List<Byte> asList( final byte[] bytes ){
+ return new AbstractList<Byte>() {
+
+ @Override
+ public Byte get(int arg0) {
+ return bytes[arg0];
+ }
+
+ @Override
+ public int size() {
+ return bytes.length;
+ }
+ };
+ }
+
+ public static List<Character> asList( final char[] chars ){
+ return new AbstractList<Character>() {
+
+ @Override
+ public Character get(int arg0) {
+ return chars[arg0];
+ }
+
+ @Override
+ public int size() {
+ return chars.length;
+ }
+ };
+ }
+
+ public static List<Integer> asList( final int[] ints ){
+ return new AbstractList<Integer>() {
+
+ @Override
+ public Integer get(int arg0) {
+ return ints[arg0];
+ }
+
+ @Override
+ public int size() {
+ return ints.length;
+ }
+ };
+ }
+
+ public static List<Long> asList( final long[] longs ){
+ return new AbstractList<Long>() {
+
+ @Override
+ public Long get(int arg0) {
+ return longs[arg0];
+ }
+
+ @Override
+ public int size() {
+ return longs.length;
+ }
+ };
+ }
+
+ public static List<Double> asList( final double[] doubles ){
+ return new AbstractList<Double>() {
+
+ @Override
+ public Double get(int arg0) {
+ return doubles[arg0];
+ }
+
+ @Override
+ public int size() {
+ return doubles.length;
+ }
+ };
+ }
+
+ public static List<Float> asList( final float[] floats ){
+ return new AbstractList<Float>() {
+
+ @Override
+ public Float get(int arg0) {
+ return floats[arg0];
+ }
+
+ @Override
+ public int size() {
+ return floats.length;
+ }
+ };
+ }
+
+ public static List<Short> asList( final short[] shorts ){
+ return new AbstractList<Short>() {
+
+ @Override
+ public Short get(int arg0) {
+ return shorts[arg0];
+ }
+
+ @Override
+ public int size() {
+ return shorts.length;
+ }
+ };
+ }
+
+ public static List<Boolean> asList( final boolean[] bools ){
+ return new AbstractList<Boolean>() {
+
+ @Override
+ public Boolean get(int arg0) {
+ return bools[arg0];
+ }
+
+ @Override
+ public int size() {
+ return bools.length;
+ }
+ };
+ }
+}
diff --git a/project/JavaCommon/src/com/modulus/common/collections/ModelData.java b/project/JavaCommon/src/com/modulus/common/collections/ModelData.java
new file mode 100644
index 0000000..245015b
--- /dev/null
+++ b/project/JavaCommon/src/com/modulus/common/collections/ModelData.java
@@ -0,0 +1,9 @@
+package com.modulus.common.collections;
+
+public interface ModelData<T> {
+ public T get(Object key);
+
+ public void set(Object key, T obj);
+
+ public Object[] keys();
+}
diff --git a/project/JavaCommon/src/com/modulus/common/collections/Stack.java b/project/JavaCommon/src/com/modulus/common/collections/Stack.java
new file mode 100644
index 0000000..1d2c36c
--- /dev/null
+++ b/project/JavaCommon/src/com/modulus/common/collections/Stack.java
@@ -0,0 +1,57 @@
+package com.modulus.common.collections;
+
+/**
+ * Class defines a better used stack than what is
+ * in the java api. This stack is an interface
+ * with many different implementations.
+ *
+ * @author jrahm
+ *
+ * @param <T> the type this stack stores
+ */
+public interface Stack<T> {
+ /**
+ * Removes and returns the element that is on
+ * the top of the stack.
+ *
+ * @return the element which is on the top of the stack.
+ */
+ public T pop();
+
+ /**
+ * Places object <code>obj</code> on the top of
+ * the stack
+ *
+ * @param obj the object to push on the stack.
+ */
+ public void push(T obj);
+
+ /**
+ * Returns the object on the top of the stack
+ * but does <b>not</b> remove it.
+ *
+ * @return the object on the top of the stack
+ */
+ public T peek();
+
+ /**
+ * Returns the number of elements in this
+ * stack.
+ *
+ * @return the number of elements in this stack.
+ */
+ public int size();
+
+ /**
+ * Returns true of this stack has no elements,
+ * returns false otherwise.
+ *
+ * @return true it this stack has no elements, false otherwise
+ */
+ public boolean isEmpty();
+
+ /**
+ * Empties the stack.
+ */
+ public void clear();
+}
diff --git a/project/JavaCommon/src/com/modulus/common/collections/UpdateableGrid.java b/project/JavaCommon/src/com/modulus/common/collections/UpdateableGrid.java
new file mode 100644
index 0000000..a48ee31
--- /dev/null
+++ b/project/JavaCommon/src/com/modulus/common/collections/UpdateableGrid.java
@@ -0,0 +1,21 @@
+package com.modulus.common.collections;
+
+/**
+ * Interface that extends grid to make a grid
+ * mutable.
+ *
+ * @author jrahm
+ *
+ * @param <T> the type this grid holds
+ */
+public interface UpdateableGrid<T> extends Grid<T>{
+ /**
+ * sets the reference in row <code>row</code> and column <code>col</code>
+ * to <code>obj</code>
+ *
+ * @param row the row
+ * @param col the column
+ * @param obj the object
+ */
+ public void set(int row, int col, T obj);
+}
diff --git a/project/JavaCommon/src/com/modulus/common/strings/Tokenizer.java b/project/JavaCommon/src/com/modulus/common/strings/Tokenizer.java
new file mode 100644
index 0000000..80363cd
--- /dev/null
+++ b/project/JavaCommon/src/com/modulus/common/strings/Tokenizer.java
@@ -0,0 +1,48 @@
+package com.modulus.common.strings;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Class that tokenizes strings based on which groups
+ * the characters fit into.
+ *
+ * If the group is -1, then that tells the tokenizer to
+ * not include those tokens and instead delete the characters
+ * that belong to that group in the process of splitting.
+ *
+ * @author jrahm
+ *
+ */
+public abstract class Tokenizer {
+
+ public String[] tokenize(String str){
+ if(str.length() == 0)
+ return new String[]{};
+
+ List<String> tokens = new ArrayList<String>();
+ StringBuffer buffer = new StringBuffer();
+
+ int curGroup = groupOf(str.charAt(0));
+ for(int i = 0;i < str.length();i++){
+ char ch = str.charAt(i);
+
+ int temp = groupOf(ch);
+ if(temp != curGroup && curGroup != -1){
+ curGroup = temp;
+ tokens.add(buffer.toString());
+
+ buffer = new StringBuffer();
+ }
+
+ if(temp != -1)
+ buffer.append(ch);
+ }
+ tokens.add(buffer.toString());
+
+ return tokens.toArray(new String[tokens.size()]);
+ }
+
+ public abstract int groupOf(char ch);
+}
diff --git a/project/JavaCommon/src/com/modulus/console/InputReader.java b/project/JavaCommon/src/com/modulus/console/InputReader.java
new file mode 100644
index 0000000..0cda313
--- /dev/null
+++ b/project/JavaCommon/src/com/modulus/console/InputReader.java
@@ -0,0 +1,9 @@
+package com.modulus.console;
+
+public class InputReader {
+ private StringBuffer buffer = new StringBuffer();
+
+ public String getBuffer(){
+ return buffer.toString();
+ }
+}
diff --git a/project/JavaCommon/src/com/modulus/dataread/expressions/AbstractStatement.java b/project/JavaCommon/src/com/modulus/dataread/expressions/AbstractStatement.java
new file mode 100644
index 0000000..c2ec699
--- /dev/null
+++ b/project/JavaCommon/src/com/modulus/dataread/expressions/AbstractStatement.java
@@ -0,0 +1,125 @@
+package com.modulus.dataread.expressions;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * this class outlines a rough diagram of what a statement
+ * looks like. The major importance is how it already
+ * correctly implements the tree fasion that statements
+ * should in theory be ordered in.
+ *
+ * @author jrahm
+ *
+ */
+public abstract class AbstractStatement implements Statement, Serializable{
+ private static final long serialVersionUID = -6717726729821743941L;
+ private Collection<Statement> children;
+ private int line = -1;
+
+ /**
+ * the header of this statement.
+ */
+ protected String header;
+
+ /**
+ * Creates a new AbstractStatement with the
+ * default header being an empty string.
+ */
+ public AbstractStatement(){
+ this.children = new ArrayList<Statement>();
+ this.header = "";
+ }
+
+ @Override
+ public void addChild(Statement child) {
+ this.children.add(child);
+ }
+
+ @Override
+ public Statement[] getChildren() {
+ return children.toArray(new Statement[children.size()]);
+ }
+
+ @Override
+ public String getHeader() {
+ return header;
+ }
+
+ @Override
+ public void removeChild(Statement child) {
+ this.children.remove(child);
+ }
+
+ @Override
+ public String toString(){
+ return toString(0);
+ }
+
+ public String toString( int recur ){
+ StringBuffer buffer = new StringBuffer();
+ String tab = "";
+ for(int i = 0;i < recur;i++)
+ tab += '\t';
+
+
+ buffer.append(tab + header);
+
+ if(children.size() > 0){
+ buffer.append("{\n");
+ for(Statement child : children){
+ buffer.append(child.toString( recur + 1 ) + "\n");
+ }
+ buffer.append(tab + "}");
+ } else{
+ buffer.append(";");
+ }
+
+ return buffer.toString();
+ }
+
+ @Override
+ public Statement getChildByHeader(String header){
+
+ for(Statement child : children){
+ String chHeader = child.getHeader();
+
+ if(chHeader.equals(header))
+ return child;
+ }
+
+ return null;
+ }
+
+ @Override
+ public Statement[] getChildrenByHeader(String header){
+ List<Statement> ret = new ArrayList<Statement>();
+
+ for(Statement child : children){
+ String chHeader = child.getHeader();
+
+ if(chHeader.equals(header))
+ ret.add(child);
+ }
+
+ return ret.toArray(new Statement[ret.size()]);
+ }
+
+ public int getLineNumber(){
+ return line;
+ }
+
+ public void setLineNumber(int line){
+ this.line = line;
+ }
+
+ public boolean hasChildren(){
+ return !children.isEmpty();
+ }
+
+ public void clearChildren(){
+ this.children.clear();
+ }
+}
diff --git a/project/JavaCommon/src/com/modulus/dataread/expressions/ExpressionParser.java b/project/JavaCommon/src/com/modulus/dataread/expressions/ExpressionParser.java
new file mode 100644
index 0000000..c62243a
--- /dev/null
+++ b/project/JavaCommon/src/com/modulus/dataread/expressions/ExpressionParser.java
@@ -0,0 +1,5 @@
+package com.modulus.dataread.expressions;
+
+public interface ExpressionParser {
+ ExpressionPart parseExpressions( String exp );
+}
diff --git a/project/JavaCommon/src/com/modulus/dataread/expressions/ExpressionPart.java b/project/JavaCommon/src/com/modulus/dataread/expressions/ExpressionPart.java
new file mode 100644
index 0000000..bf4e8d8
--- /dev/null
+++ b/project/JavaCommon/src/com/modulus/dataread/expressions/ExpressionPart.java
@@ -0,0 +1,136 @@
+package com.modulus.dataread.expressions;
+
+/**
+ * This class is used to help to assemble the code into more
+ * readable code for the computer, it sets the system based on
+ * a more of a stack-ish way so the virtual machine can linearly
+ * push/pop arguments and call functions.
+ *
+ * @author jrahm
+ *
+ */
+public abstract class ExpressionPart {
+
+ // Null if function is global
+ private ExpressionPart caller;
+ private ExpressionPart[] args;
+
+ private String function;
+ private boolean primary = false;
+
+ private ExpressionPart(){}
+
+ /**
+ * This creates a new Expression part meant to handle multi-part
+ * expressions such as expressions with parenthesis, functions
+ * inside of functions and so on.
+ *
+ * Q-Bar is set up to be very functional, to the point where every entity is made
+ * of functions being called on arguments and such.
+ *
+ * @param caller the caller of the function (null if the function is global)
+ * @param function the function to be called
+ * @param args the arguments of the function
+ * @return an expression part that describes this layout
+ */
+ public static ExpressionPart makePrimaryExpressionPart( ExpressionPart caller, String function, ExpressionPart[] args ){
+ ExpressionPart ths = new ExpressionPart(){
+ private String compile;
+ @Override
+ public String compilePart() {
+
+ if( compile == null ){
+ StringBuffer buf = new StringBuffer();
+ ExpressionPart caller = this.getCaller();
+
+ // else
+ // buf.append( "$global$" );
+ for(ExpressionPart part : this.getArgs()){
+ buf.append(' ');
+ buf.append( part.compilePart() );
+ }
+
+ if(caller != null)
+ buf.append( " " + caller.compilePart() );
+
+ buf.append(' ');
+ if(this.getFunction().trim().length() > 0){
+ if(caller != null){
+ // \u00FF is the marker for what is an instance function
+ buf.append( "\u00FF" + this.getFunction() );
+ }
+ else{
+ // \u00FE is the marker for a global function
+ buf.append( "\u00FE" + this.getFunction() );
+ }
+ }
+ compile = buf.toString().replaceAll("\\s+", " ");
+ }
+
+ return compile;
+ }
+ };
+
+ ths.caller = caller;
+ ths.function = function;
+ ths.args = args;
+
+ ths.primary = true;
+
+ return ths;
+ }
+
+ /**
+ * This method returns an expression part that is made entirely up
+ * of one single variable name. On a side note, these parts are the
+ * recursive base case for the compilation.
+ *
+ * The name of the variable is stored in the function value, as a variable
+ * name can be thought of as a function that returns that point in
+ * memory.
+ *
+ * @param name the name of the variable.
+ * @return A base case ExpressionPart
+ */
+ public static ExpressionPart makeExpressionPart( String name ){
+ ExpressionPart ths = new ExpressionPart(){
+ @Override
+ public String compilePart() {
+ return this.getFunction();
+ }
+ };
+ ths.function = name;
+
+ return ths;
+ }
+
+ /**
+ * @return the caller
+ */
+ public ExpressionPart getCaller() {
+ return caller;
+ }
+
+ /**
+ * @return the args
+ */
+ public ExpressionPart[] getArgs() {
+ return args;
+ }
+
+ /**
+ * @return the function
+ */
+ public String getFunction() {
+ return function;
+ }
+
+ /**
+ * @return the primary
+ */
+ public boolean isPrimary() {
+ return primary;
+ }
+
+ public abstract String compilePart();
+}
diff --git a/project/JavaCommon/src/com/modulus/dataread/expressions/FlowStatement.java b/project/JavaCommon/src/com/modulus/dataread/expressions/FlowStatement.java
new file mode 100644
index 0000000..df51f2b
--- /dev/null
+++ b/project/JavaCommon/src/com/modulus/dataread/expressions/FlowStatement.java
@@ -0,0 +1,3 @@
+package com.modulus.dataread.expressions;
+
+public enum FlowStatement { WHILE, FOR, IF, ELSE, RETURN, NONE }
diff --git a/project/JavaCommon/src/com/modulus/dataread/expressions/LineNumberException.java b/project/JavaCommon/src/com/modulus/dataread/expressions/LineNumberException.java
new file mode 100644
index 0000000..29cb0a1
--- /dev/null
+++ b/project/JavaCommon/src/com/modulus/dataread/expressions/LineNumberException.java
@@ -0,0 +1,25 @@
+package com.modulus.dataread.expressions;
+
+public class LineNumberException extends RuntimeException{
+ private int line;
+
+ public LineNumberException( int line ) {
+ super();
+ this.line = line;
+ }
+
+ public LineNumberException(String message, int line) {
+ super(message + " line " + line);
+ this.line = line;
+ }
+
+ public LineNumberException(String message, Throwable cause, int line) {
+ super(message + " line " + line, cause);
+ this.line = line;
+ }
+
+ public int getLine(){
+ return line;
+ }
+
+}
diff --git a/project/JavaCommon/src/com/modulus/dataread/expressions/ParseRules.java b/project/JavaCommon/src/com/modulus/dataread/expressions/ParseRules.java
new file mode 100644
index 0000000..a48f3b9
--- /dev/null
+++ b/project/JavaCommon/src/com/modulus/dataread/expressions/ParseRules.java
@@ -0,0 +1,84 @@
+package com.modulus.dataread.expressions;
+
+/**
+ * Interface defines a set of rules used to parse
+ * text files. These rules include such rules like
+ * in string or folder start and end etc.
+ *
+ * @author jrahm
+ *
+ */
+public interface ParseRules {
+ /**
+ * First formats the code to make
+ * life much easier for the parser.
+ *
+ * This should be the first method to be
+ * called at all times.
+ */
+ void format();
+
+ /**
+ * Signals these parse rules that the user has read the character at
+ * the point <code>off</code> of which the parser dictates how much
+ * code to skip.
+ *
+ * @param off point in the code which was read
+ * @return how many characters the parser should skip.
+ */
+ int read( int off );
+
+ /**
+ * Returns true if the parser is in quotes, false otherwise.
+ *
+ * @return true if the parser is in quotes, false otherwuse.
+ */
+ boolean inQuotes();
+
+ /**
+ * Returns true if the parser is in a
+ * comment or not.
+ *
+ * @return true if the parser is in a
+ * comment or not.
+ */
+ boolean inComment();
+
+ /**
+ * returns true if at position <code>off</code>
+ * a folder is being opened.
+ *
+ * @param off the position in the code
+ * @return true if at position <code>off</code> a
+ * folder is being opened.
+ */
+ boolean openFolder( int off );
+
+ /**
+ * returns true if at position <code>off</code>
+ * a folder is being closed in the code.
+ *
+ * @param off the position of the parser
+ * @return if a folder is being closed at position <code>off</code>
+ */
+ boolean closeFolder( int off );
+
+ /**
+ * returns true if a statement is terminated at position <code>off</code>
+ *
+ * @param off the position in the code.
+ * @return true if a statement is terminated at position <code>off</code>
+ */
+ boolean statementTerminated( int off );
+
+ /**
+ * Returns the code which these parse rules are using.
+ * @return the code which these parse rules are using.
+ */
+ String getCode();
+
+ /**
+ * Returns the line number of this reader
+ */
+ int getLineNumber();
+}
diff --git a/project/JavaCommon/src/com/modulus/dataread/expressions/Statement.java b/project/JavaCommon/src/com/modulus/dataread/expressions/Statement.java
new file mode 100644
index 0000000..27df480
--- /dev/null
+++ b/project/JavaCommon/src/com/modulus/dataread/expressions/Statement.java
@@ -0,0 +1,105 @@
+package com.modulus.dataread.expressions;
+
+/**
+ * This interface is used to store interpreted
+ * information from a text file in a way that
+ * most represents a tree. for easy parsing
+ * for an interpreter or compiler.
+ *
+ * @author jrahm
+ *
+ */
+public interface Statement {
+
+ /**
+ * Returns the child statements of this class
+ *
+ * @return the child statements of this class
+ */
+ Statement[] getChildren();
+
+ /**
+ * Adds a child statement to this Statement
+ *
+ * @param child the child statement to add
+ */
+ void addChild(Statement child);
+
+ /**
+ * Removes a child statement from this Statement object
+ *
+ * @param child this child to remove from this statement
+ */
+ void removeChild(Statement child);
+
+ /**
+ * Sets the header for this statement object
+ *
+ * @param header the header for this statement.
+ */
+ void setHeader(String header);
+
+ /**
+ * returns the header for this statement object
+ * @return
+ */
+ String getHeader();
+
+ /**
+ * side effect method to get nicely formatted printouts
+ * of the statement class.
+ * @param recur
+ * @return
+ */
+ String toString( int recur );
+
+ /**
+ * Returns the child of this Statement that has
+ * the header <code>header</code>. If there is no
+ * child with that header, then the method should
+ * then return <code>null</code>. If there are multiple
+ * children with the same header, then the first one should
+ * be returned. If all children with that header should be
+ * returned, then use the <code>getChildrenByHeader</code> method.
+ *
+ * @param header the header of the child to return
+ * @return a child with the header <code>header</code>
+ */
+ Statement getChildByHeader(String header);
+
+ /**
+ * Returns an array of children of this Statement that have
+ * the header <code>header</code>. If no children have that header,
+ * then an empty array is returned.
+ *
+ * @param header the header of the children to return.
+ * @return an array of children that have the header <code>header</code>
+ */
+ Statement[] getChildrenByHeader(String header);
+
+ /**
+ * Returns the line number that this statement starts on.
+ * @return the line number that this statement starts on.
+ */
+ int getLineNumber();
+
+ /**
+ * Sets the line number that this statement
+ * starts on.
+ *
+ * @param line the line this statement starts on.
+ */
+ void setLineNumber(int line);
+
+ /**
+ * Returns true if this statement has children, false otherwise.
+ *
+ * @return true if this statement has children.
+ */
+ boolean hasChildren();
+
+ /**
+ * Deletes all children from this statement
+ */
+ void clearChildren();
+} \ No newline at end of file
diff --git a/project/JavaCommon/src/com/modulus/dataread/expressions/StatementFactory.java b/project/JavaCommon/src/com/modulus/dataread/expressions/StatementFactory.java
new file mode 100644
index 0000000..16da8aa
--- /dev/null
+++ b/project/JavaCommon/src/com/modulus/dataread/expressions/StatementFactory.java
@@ -0,0 +1,28 @@
+package com.modulus.dataread.expressions;
+
+import java.util.Map;
+
+/**
+ * Interface describes how an object is supposed to
+ * generate statements. This class is to be used int tandem
+ * with the ExpressionParser interface to generate
+ * Statements of a specific type;
+ *
+ * @author jrahm
+ *
+ * @param <T> the type of statement this StatementFactory creates
+ */
+public interface StatementFactory<T extends Statement> {
+
+ /**
+ * Creates a new statement with the type <code>T</code> based
+ * on what the parameters contain.
+ *
+ * The parameters contain useful information about where the parser
+ * currently is and how to create the new statement.
+ *
+ * @param params the parameters
+ * @return a new statement of type <code>T</code> based off of the parameters.
+ */
+ T generateStatement(Map<String, Object> params);
+}
diff --git a/project/JavaCommon/src/com/modulus/dataread/expressions/StatementFormatter.java b/project/JavaCommon/src/com/modulus/dataread/expressions/StatementFormatter.java
new file mode 100644
index 0000000..8070034
--- /dev/null
+++ b/project/JavaCommon/src/com/modulus/dataread/expressions/StatementFormatter.java
@@ -0,0 +1,26 @@
+package com.modulus.dataread.expressions;
+
+import java.io.Serializable;
+
+/**
+ * Classes that implement this interface are used
+ * to format string before they become a part of
+ * a statement.
+ *
+ * These classes are the classes responsible for making
+ * sure the headers are formatted in such a way that they might
+ * be easy to parse.
+ *
+ * @author jrahm
+ */
+public interface StatementFormatter extends Serializable{
+ /**
+ * Given the String <code>header</code> as a header of a statement,
+ * format it so it can easily be parsed by custom parsing
+ * techniques.
+ *
+ * @param header the header to parse
+ * @return a formatted version of the header.
+ */
+ String formatHeader(String header);
+}
diff --git a/project/JavaCommon/src/com/modulus/dataread/expressions/StatementTreeParser.java b/project/JavaCommon/src/com/modulus/dataread/expressions/StatementTreeParser.java
new file mode 100644
index 0000000..854d4d2
--- /dev/null
+++ b/project/JavaCommon/src/com/modulus/dataread/expressions/StatementTreeParser.java
@@ -0,0 +1,21 @@
+package com.modulus.dataread.expressions;
+
+/**
+ * Interface which describes how an expression parser
+ * will handle information from an interpreter file.
+ *
+ * @author jrahm
+ *
+ * @param S the statement type which is used to create this class
+ */
+public interface StatementTreeParser {
+
+ /**
+ * Parse a block of code into statements using the statement factory <code>factory</code>
+ * to generate the statements to use.
+ * @param <T> the type of statement to use.
+ * @param factory the factory to generate the statements
+ * @return a Statement of type <code>T</code> that represents the code parsed
+ */
+ <T extends Statement> Statement parseStatements(StatementFactory<T> factory);
+}
diff --git a/project/JavaCommon/src/com/modulus/dataread/expressions/impl/AbstractParseRules.java b/project/JavaCommon/src/com/modulus/dataread/expressions/impl/AbstractParseRules.java
new file mode 100644
index 0000000..ebdb2dc
--- /dev/null
+++ b/project/JavaCommon/src/com/modulus/dataread/expressions/impl/AbstractParseRules.java
@@ -0,0 +1,197 @@
+package com.modulus.dataread.expressions.impl;
+
+import com.modulus.dataread.expressions.ParseRules;
+
+/**
+ * Class which implements ParseRules with rules
+ * of a language which is very close to the C Programming
+ * Language and others based off it.
+ *
+ * @author jrahm
+ */
+public abstract class AbstractParseRules implements ParseRules{
+ private static final String w = "\\s";
+
+ private int lineNumber = 0;
+ /*
+ * the code this class will follow
+ */
+ private String code;
+ /*
+ * value which tells this class
+ * if it is in quotes or not.
+ */
+ private boolean inQuotes = false;
+
+ /*
+ * value which dictates if the parser
+ * is in comments.
+ */
+ private boolean inComments = false;
+
+ /*
+ * this tells if the parser is in
+ * a comment delimited by '//'
+ */
+ private boolean inLineComment = false;
+ /**
+ * Constructs a new CBasedParseRules object with <code>code</code>
+ * as the code which is being parsed.
+ *
+ * @param code the code to be parsed.
+ */
+ public AbstractParseRules(String code){
+ this.code = code;
+ format();
+
+ deleteComments();
+ }
+
+ @Override
+ public boolean closeFolder(int off) {
+
+ return code.startsWith(this.getCloseFolderString(), off);
+ }
+
+ @Override
+ public boolean inComment() {
+ return inComments || inLineComment;
+ }
+
+ @Override
+ public boolean inQuotes() {
+ return inQuotes;
+ }
+
+ @Override
+ public boolean openFolder(int off) {
+ return code.startsWith( this.getOpenFolderString(), off );
+ }
+
+ /*
+ * this is where most of the logic
+ * goes for this class, this method is
+ * what dictates the flow of the parser
+ * and whether or not the parser is in
+ * quotes or comments etc.
+ *
+ * @see com.modulus.dataread.expressions.ParseRules#read(int)
+ */
+ @Override
+ public int read(int off) {
+ // Here we will handle to see if the parser
+ // has run into a string literal.
+
+ // System.out.print( code.charAt(off) );
+ if(code.charAt(off) == '"'){
+ if( off == 0 || code.charAt(off - 1) != '\\' ){
+ inQuotes = !inQuotes;
+ }
+ }
+
+ return 1;
+ }
+
+ public boolean statementTerminated( int off ){
+ boolean tmp = code.startsWith( this.getStatementTerminatingCharacter(), off ) && !inQuotes();
+
+ // if(tmp) {
+ // System.out.printf("%s\t%s\t%s\n", code.substring(off), off, inQuotes );
+ // }
+
+ return tmp;
+ }
+
+ @Override
+ public void format() {
+ // for most C-based languages white space can just be
+ // Truncated like so.
+ // this.code = this.code.replaceAll(w+"+\n"+w+"+", "\n");
+ this.code = this.code.replace('\n', '\u0088');
+ // this.code = this.code.replaceAll(w+"+", " ");
+ // this.code = this.code.replaceAll(w+"*\\}"+w+"*", "}");
+ // this.code = this.code.replaceAll(w+"*;"+w+"*", ";");
+ StringBuffer total = new StringBuffer();
+
+ int i = 0;
+ int old = 0;
+
+ boolean inQuotes = false;
+
+ while( i != this.code.length() ) {
+ old = i;
+ i = code.indexOf('"', i+1);
+
+ if( i == -1 )
+ i = this.code.length();
+
+ String sub = code.substring(old, i);
+
+ if(!inQuotes) {
+ sub = sub.replaceAll(w+"+", " ");
+ sub = sub.replaceAll(w+"*\\}"+w+"*", "}");
+ sub = sub.replaceAll(w+"*;"+w+"*", ";");
+ }
+
+ total.append(sub);
+
+ inQuotes = !inQuotes;
+ }
+ total.append( code.substring(old) );
+
+ code = total.toString();
+ //this.code = this.code.replaceAll("[^;]\\}", ";}");
+
+ // System.out.println("Format: " + this.code);
+ }
+
+ public String getCode(){
+ return code.replace('\u0088', '\n');
+ }
+
+ @Override
+ public int getLineNumber() {
+ return lineNumber;
+ }
+
+ private void deleteComments(){
+ StringBuffer code2 = new StringBuffer();
+
+ for( int i = 0;i < code.length(); i ++){
+ if(code.startsWith( this.getCommentOpen(), i )){
+ while(!code.startsWith( this.getCommentClose(), i)){
+ if(code.charAt(i) == '\u0088')
+ code2.append(code.charAt(i));
+ i ++;
+ }
+ i += this.getCommentClose().length();
+ }
+
+ if(code.startsWith( this.getLineCommentDelimeter(), i)){
+ while(code.charAt(i) != '\u0088'){
+ i++;
+ }
+ }
+
+ code2.append( code.charAt(i) );
+ }
+
+ code = code2.toString();
+ }
+
+ public abstract String getOpenFolderString();
+
+ public abstract String getCloseFolderString();
+
+ public abstract String getStatementTerminatingCharacter();
+
+ public abstract String getStringDelimiter();
+
+ public abstract String getEscapeSequence();
+
+ public abstract String getCommentOpen();
+
+ public abstract String getCommentClose();
+
+ public abstract String getLineCommentDelimeter();
+}
diff --git a/project/JavaCommon/src/com/modulus/dataread/expressions/impl/CBasedParseRules.java b/project/JavaCommon/src/com/modulus/dataread/expressions/impl/CBasedParseRules.java
new file mode 100644
index 0000000..33dad25
--- /dev/null
+++ b/project/JavaCommon/src/com/modulus/dataread/expressions/impl/CBasedParseRules.java
@@ -0,0 +1,57 @@
+package com.modulus.dataread.expressions.impl;
+
+public class CBasedParseRules extends AbstractParseRules{
+
+ public CBasedParseRules(String code) {
+ super(code);
+ }
+
+ @Override
+ public String getOpenFolderString() {
+ // TODO Auto-generated method stub
+ return "{";
+ }
+
+ @Override
+ public String getCloseFolderString() {
+ // TODO Auto-generated method stub
+ return "}";
+ }
+
+ @Override
+ public String getStatementTerminatingCharacter() {
+ // TODO Auto-generated method stub
+ return ";";
+ }
+
+ @Override
+ public String getStringDelimiter() {
+ // TODO Auto-generated method stub
+ return "\"";
+ }
+
+ @Override
+ public String getEscapeSequence() {
+ // TODO Auto-generated method stub
+ return "\\";
+ }
+
+ @Override
+ public String getCommentOpen() {
+ // TODO Auto-generated method stub
+ return "/*";
+ }
+
+ @Override
+ public String getCommentClose() {
+ // TODO Auto-generated method stub
+ return "*/";
+ }
+
+ @Override
+ public String getLineCommentDelimeter() {
+ // TODO Auto-generated method stub
+ return "//";
+ }
+
+} \ No newline at end of file
diff --git a/project/JavaCommon/src/com/modulus/dataread/expressions/impl/FormatStatement.java b/project/JavaCommon/src/com/modulus/dataread/expressions/impl/FormatStatement.java
new file mode 100644
index 0000000..8a4b3ad
--- /dev/null
+++ b/project/JavaCommon/src/com/modulus/dataread/expressions/impl/FormatStatement.java
@@ -0,0 +1,52 @@
+package com.modulus.dataread.expressions.impl;
+
+import com.modulus.dataread.expressions.AbstractStatement;
+import com.modulus.dataread.expressions.StatementFormatter;
+
+/**
+ * This class that extends AbstractStatement will first
+ * format its header before it sets the actual header to
+ * what the user sends, using a statement formatter.
+ *
+ * @author jrahm
+ *
+ */
+public class FormatStatement extends AbstractStatement{
+ private static final long serialVersionUID = -4973798175965745298L;
+ private StatementFormatter formatter;
+
+ /**
+ * This creates a new Statement with <code>formatter</code>
+ * as the default formatter for this Statement.
+ *
+ * @param formatter the formatter for this statement
+ */
+ public FormatStatement(StatementFormatter formatter){
+ this.formatter = formatter;
+ }
+
+ protected FormatStatement(){
+ }
+
+ @Override
+ public void setHeader(String header) {
+ this.header = formatter.formatHeader(header);
+ }
+
+ /**
+ * Returns the formatter for this Statement
+ * @return the formatter for this Statement
+ */
+ public StatementFormatter getFormatter(){
+ return formatter;
+ }
+
+ /**
+ * Sets the formatter for this statement
+ * @param formatter the formatter for this statement
+ */
+ public void setFormatter(StatementFormatter formatter){
+ this.formatter = formatter;
+ }
+
+}
diff --git a/project/JavaCommon/src/com/modulus/dataread/expressions/impl/SimpleExpressionParser.java b/project/JavaCommon/src/com/modulus/dataread/expressions/impl/SimpleExpressionParser.java
new file mode 100644
index 0000000..22f1be5
--- /dev/null
+++ b/project/JavaCommon/src/com/modulus/dataread/expressions/impl/SimpleExpressionParser.java
@@ -0,0 +1,139 @@
+package com.modulus.dataread.expressions.impl;
+
+import com.modulus.common.TwoTypeBean;
+import com.modulus.dataread.expressions.StatementTreeParser;
+import com.modulus.dataread.expressions.ParseRules;
+import com.modulus.dataread.expressions.Statement;
+import com.modulus.dataread.expressions.StatementFactory;
+
+/**
+ * This simple expression parser is meant not to do anything fancy
+ * all it does is break up the file into a tree based on the folders
+ * in the file.
+ *
+ * @author jrahm
+ *
+ */
+public class SimpleExpressionParser implements StatementTreeParser{
+ /*
+ * used by methods to keep track of
+ * the number of lines
+ */
+ private int line = 0;
+ /*
+ * The rules to parse by
+ */
+ private ParseRules rules;
+
+ /**
+ * Creates a new <code>SimpleExpressionParser</code> based
+ * off of the rules that was given to it.
+ *
+ * @param rules the rules to parse by
+ */
+ public SimpleExpressionParser(ParseRules rules){
+ this.rules = rules;
+ }
+
+ @Override
+ public <T extends Statement> Statement parseStatements(StatementFactory<T> factory) {
+ // set the line counter to 1
+ this.line = 1;
+ return recurParseStatement(factory, 0).getObject1();
+ }
+
+ /*
+ * Setup a recursive parser to
+ * return a tree of statements
+ */
+ private <T extends Statement> TwoTypeBean<T, Integer> recurParseStatement(StatementFactory<T> factory, int off){
+ // System.out.println(" parseStatements");
+ final String code = rules.getCode();
+
+ // statement which will be returned in the end,
+ // this statement is the parent of all the other
+ // statements
+ T ret = factory.generateStatement(null);
+ int i = off;
+
+
+ // start an iteration through the
+ // string
+ for( ;i < code.length(); i ++ ){
+
+ // if the next character is a new line character,
+ // the increment the line counter
+ if(code.charAt(i) == '\n')
+ line ++;
+
+ // check to see if the rules say that here a statement
+ // is to be terminated
+ if( rules.statementTerminated(i) ){
+
+ // if so, then it is time to manifest a new statement
+ // header is equal to the substring of the code from
+ // off to i
+ String header = code.substring(off, i);
+
+ // create a new child from the type provided
+ T child = factory.generateStatement(null);
+
+ // set the line number to what it should be
+ child.setLineNumber( this.line );
+
+ // set the header
+ child.setHeader( header );
+
+ // we are done with creating this beam, so it is time to
+ // return it
+ return new TwoTypeBean<T, Integer>(child, i);
+ }
+
+ // if the rules say that at this point,
+ // a folder is opened, then it is time to
+ // use recursion to implement a tree.
+ else if ( rules.openFolder(i) ){
+
+ // the header is from off to when the
+ // folder is being closed
+ String header = code.substring(off, i);
+
+ // set the header
+ ret.setHeader(header);
+
+ // set the line number
+ ret.setLineNumber(line);
+
+ // it is time to increment i by the
+ // amount the rules say to.
+ i += rules.read(i);
+
+ // while the folder is not closed
+ while( !rules.closeFolder(i) ){
+
+ // read the next statement
+ TwoTypeBean<T, Integer> bean = recurParseStatement(factory, i);
+
+ // the second object is the offset
+ //that the previous call terminated with
+ i = bean.getObject2();
+
+ // add this child to the main bean
+ ret.addChild(bean.getObject1());
+
+ // increment the incrementer by how
+ // much the rules say to
+ i += rules.read(i);
+ }
+
+ // When finished reading this file, it is time
+ // to return the main bean.
+ return new TwoTypeBean<T, Integer>(ret, i);
+ }
+ }
+
+ // System.out.println(" /parseStatements");
+ return new TwoTypeBean<T, Integer>(ret, i);
+ }
+
+}
diff --git a/project/JavaCommon/src/com/modulus/dataread/expressions/impl/SimpleStatement.java b/project/JavaCommon/src/com/modulus/dataread/expressions/impl/SimpleStatement.java
new file mode 100644
index 0000000..f32cfca
--- /dev/null
+++ b/project/JavaCommon/src/com/modulus/dataread/expressions/impl/SimpleStatement.java
@@ -0,0 +1,19 @@
+package com.modulus.dataread.expressions.impl;
+
+import com.modulus.dataread.expressions.AbstractStatement;
+
+public class SimpleStatement extends AbstractStatement {
+ private static final long serialVersionUID = -8730515046885236907L;
+
+ public SimpleStatement(){}
+
+ public SimpleStatement(String string) {
+ super();
+ this.setHeader(string);
+ }
+
+ @Override
+ public void setHeader(String header) {
+ this.header = header;
+ }
+}
diff --git a/project/JavaCommon/src/com/modulus/dataread/expressions/impl/SimpleStatementTreeParser.java b/project/JavaCommon/src/com/modulus/dataread/expressions/impl/SimpleStatementTreeParser.java
new file mode 100644
index 0000000..70ebd95
--- /dev/null
+++ b/project/JavaCommon/src/com/modulus/dataread/expressions/impl/SimpleStatementTreeParser.java
@@ -0,0 +1,162 @@
+package com.modulus.dataread.expressions.impl;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.Map;
+
+import com.modulus.common.TwoTypeBean;
+import com.modulus.dataread.expressions.LineNumberException;
+import com.modulus.dataread.expressions.StatementFormatter;
+import com.modulus.dataread.expressions.StatementTreeParser;
+import com.modulus.dataread.expressions.ParseRules;
+import com.modulus.dataread.expressions.Statement;
+import com.modulus.dataread.expressions.StatementFactory;
+
+/**
+ * This simple expression parser is meant not to do anything fancy
+ * all it does is break up the file into a tree based on the folders
+ * in the file.
+ *
+ * @author jrahm
+ *
+ */
+public class SimpleStatementTreeParser implements StatementTreeParser{
+
+ /*
+ * used by methods to keep track of
+ * the number of lines
+ */
+ private int line = 0;
+ /*
+ * The rules to parse by
+ */
+ private ParseRules rules;
+
+ /**
+ * Creates a new <code>SimpleExpressionParser</code> based
+ * off of the rules that was given to it.
+ *
+ * @param rules the rules to parse by
+ */
+ public SimpleStatementTreeParser(ParseRules rules){
+ this.rules = rules;
+ }
+
+ @Override
+ public <T extends Statement> Statement parseStatements(StatementFactory<T> factory) {
+ // set the line counter to 1
+ this.line = 0;
+ return recurParseStatement(factory, 0).getObject1();
+ }
+
+ /*
+ * Setup a recursive parser to
+ * return a tree of statements
+ */
+ private <T extends Statement> TwoTypeBean<T, Integer> recurParseStatement(StatementFactory<T> factory, int off){
+ try{
+ // System.out.println(" parseStatements");
+ final String code = rules.getCode();
+
+ // statement which will be returned in the end,
+ // this statement is the parent of all the other
+ // statements
+ T ret = factory.generateStatement(null);
+ int i = off;
+ int n = 0;
+
+ // start an iteration through the
+ // string
+ for( ;i < code.length(); n++, i += rules.read(i) ){
+ // if the next character is a new line character,
+ // the increment the line counter
+ // System.out.println( i );
+ if(code.charAt(i) == '\n'){
+ line ++;
+ // that is all a new line does;
+ continue;
+ }
+
+ // check to see if the rules say that here a statement
+ // is to be terminated
+ if( rules.statementTerminated(i) ){
+
+ // if so, then it is time to manifest a new statement
+ // header is equal to the substring of the code from
+ // off to i
+ String header = code.substring(off, i);
+
+ // create a new child from the type provided
+ T child = factory.generateStatement(null);
+
+ // set the header
+ child.setHeader( header );
+
+ // set the line number to what it should be
+ child.setLineNumber( this.line );
+
+ // we are done with creating this beam, so it is time to
+ // return it
+ return new TwoTypeBean<T, Integer>(child, i);
+ }
+
+ // if the rules say that at this point,
+ // a folder is opened, then it is time to
+ // use recursion to implement a tree.
+ else if ( rules.openFolder(i) ){
+
+ // the header is from off to when the
+ // folder is being closed
+ String header = code.substring(off, i);
+
+ // set the header
+ ret.setHeader(header);
+
+ // set the line number
+ ret.setLineNumber(line);
+
+ // it is time to increment i by the
+ // amount the rules say to.
+ i += rules.read(i);
+
+ // while the folder is not closed
+ while( !rules.closeFolder(i) ){
+
+ // read the next statement
+ TwoTypeBean<T, Integer> bean = recurParseStatement(factory, i);
+
+ // the second object is the offset
+ //that the previous call terminated with
+ i = bean.getObject2();
+
+ // add this child to the main bean
+ ret.addChild(bean.getObject1());
+
+ // increment the incrementer by how
+ // much the rules say to
+ i += rules.read(i);
+
+ while(code.charAt(i) == '\n'){
+ line ++;
+ i++;
+ }
+ }
+
+ // When finished reading this file, it is time
+ // to return the main bean.
+ return new TwoTypeBean<T, Integer>(ret, i);
+ }
+
+ }
+
+ // System.out.println(" /parseStatements");
+ return new TwoTypeBean<T, Integer>(ret, i);
+ } catch( Exception e ){
+ throw new LineNumberException("Sytax error", e, line);
+ }
+ }
+
+}
diff --git a/project/JavaCommon/src/com/modulus/dataread/expressions/impl/StatementParser.java b/project/JavaCommon/src/com/modulus/dataread/expressions/impl/StatementParser.java
new file mode 100644
index 0000000..7a91585
--- /dev/null
+++ b/project/JavaCommon/src/com/modulus/dataread/expressions/impl/StatementParser.java
@@ -0,0 +1,5 @@
+package com.modulus.dataread.expressions.impl;
+
+public class StatementParser {
+
+}
diff --git a/project/QBarInterpreter/.classpath b/project/QBarInterpreter/.classpath
new file mode 100644
index 0000000..039e0d8
--- /dev/null
+++ b/project/QBarInterpreter/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry combineaccessrules="false" kind="src" path="/JavaCommon"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/project/QBarInterpreter/.project b/project/QBarInterpreter/.project
new file mode 100644
index 0000000..cc15c0c
--- /dev/null
+++ b/project/QBarInterpreter/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>QBarInterpreter</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/project/QBarInterpreter/TestQBFile.qbar b/project/QBarInterpreter/TestQBFile.qbar
new file mode 100644
index 0000000..9c258bc
--- /dev/null
+++ b/project/QBarInterpreter/TestQBFile.qbar
@@ -0,0 +1,7 @@
+Import qbar/io/IO;
+Import qbar/lang/System;
+
+let main = do {
+ test <- "Hello; World";
+ System.printStrLn( test );
+} \ No newline at end of file
diff --git a/project/QBarInterpreter/TestQBFile.qbc b/project/QBarInterpreter/TestQBFile.qbc
new file mode 100644
index 0000000..9d9d8d3
--- /dev/null
+++ b/project/QBarInterpreter/TestQBFile.qbc
Binary files differ
diff --git a/project/QBarInterpreter/TestQBFile2.qbar b/project/QBarInterpreter/TestQBFile2.qbar
new file mode 100644
index 0000000..bbf58ee
--- /dev/null
+++ b/project/QBarInterpreter/TestQBFile2.qbar
@@ -0,0 +1,60 @@
+Incorporate Native com.modulus.qbar.lang.QBSystem;
+Import Native java.lang.Math as JavaMath;
+-{
+ This part of this file is just used to
+ test some of the common mathematical series.
+}-
+
+Namespace Test {
+ let construct = do {
+ this.x <- 5;
+ }
+}
+
+Namespace Series {
+ Struct Temp {
+ let new Temp() = do {
+ this.tmp <- Series.new Temp2();
+ }
+
+ let new Temp2() = do {
+ this.i <- 5;
+ }
+ }
+
+ let construct = do {
+
+ this.factorial <- [ n | if n <= 1 then 1 else n * this # (n - 1) ];
+
+ this.fibonacci <- [ n | if n < 2 then n else this # (n - 1) + this # ( n - 2 ) ];
+
+ this.collatz <- [ n | if n <= 1 then 0
+ else if n % 2 == 0 then 1 + this # (n div 2)
+ else 1 + this # (n * 3 + 1) ];
+
+ this.pascalsTriangle <- [ n | if n <= 0 then [ 1 ]
+ else if n == 1 then [ 1, 1 ]
+ else Series.pascalFromList( this # (n-1) ) ];
+ }
+
+ let pascal( n ) = this.pascalsTriangle # n;
+
+ let pascalFromList( last ) = do {
+ tmp <- [ 1 ];
+
+ for [ 0 .. last.length - 2 ] -> n {
+ tmp +< last # n + last # (n + 1);
+ }
+
+ tmp +< 1;
+ return tmp;
+ }
+
+ let test = Test.x;
+}
+Incorporate Series;
+
+let main = do {
+ -- printStrLn( "This is the JavaMath.cos(15) call: " ++ JavaMath.cos(15) );
+ printStrLn( "Test: " ++ test() );
+} \ No newline at end of file
diff --git a/project/QBarInterpreter/build.xml b/project/QBarInterpreter/build.xml
new file mode 100644
index 0000000..f86b527
--- /dev/null
+++ b/project/QBarInterpreter/build.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- ======================================================================
+ Apr 5, 2011 10:02:29 PM
+
+ QBarInterpreter
+ description
+
+ jrahm
+ ====================================================================== -->
+<project name="QBarInterpreter" default="build">
+ <import file="../JavaCommon/common_build.xml"/>
+
+ <property name="prj.src.dir" value="src" />
+ <property name="prj.bin.dir" value="bin" />
+
+ <path id="project.class.path">
+ <fileset dir="${lib.dir}" includes="**/*.jar" />
+ </path>
+
+ <description>
+ description
+ </description>
+
+ <!-- =================================
+ target: build
+ ================================= -->
+
+ <!-- - - - - - - - - - - - - - - - - -
+ target: lib
+ - - - - - - - - - - - - - - - - - -->
+ <target name="lib">
+ <mkdir dir="${lib.dir}"/>
+ <copy todir="${lib.dir}" >
+ <fileset dir="lib" includes="**/*.jar" />
+ </copy>
+ </target>
+
+ <target name="compile" depends="lib">
+ <mkdir dir="${prj.bin.dir}" />
+ <javac srcdir="${prj.src.dir}" destdir="${prj.bin.dir}" includes="**" encoding="utf-8" >
+ <classpath refid="project.class.path" />
+ </javac>
+ </target>
+
+ <target name="package" depends="compile">
+ <mkdir dir="${lib.dir}"/>
+ <copy todir="${lib.dir}">
+ <fileset file="qbar" />
+ </copy>
+ <manifestclasspath property="lib.list" jarfile="${lib.dir}/CommonJava.jar">
+ <classpath refid="project.class.path"/>
+ </manifestclasspath>
+
+
+ <jar basedir="${prj.bin.dir}" destfile="${lib.dir}/${ant.project.name}.jar" >
+ <manifest>
+ <attribute name="Main-Class"
+ value="com.modulus.qbar.core.interpreter.Main"/>
+ <attribute name="Class-Path" value="${lib.list}" />
+ </manifest>
+ </jar>
+ </target>
+
+ <target name="doc">
+ <mkdir dir="${doc.dir}" />
+ <javadoc sourcepath="${prj.src.dir}" destdir="${doc.dir}" />
+ </target>
+
+ <target name="build" depends="package,clean" />
+ <target name="clean" >
+ <delete dir="bin">
+ </delete>
+ </target>
+</project>
diff --git a/project/QBarInterpreter/completions.txt b/project/QBarInterpreter/completions.txt
new file mode 100644
index 0000000..bd56bd2
--- /dev/null
+++ b/project/QBarInterpreter/completions.txt
@@ -0,0 +1 @@
+if then else Import Static Native Incorporate as let and or xor not while for else do isa where return Struct new this Namespace
diff --git a/project/QBarInterpreter/qbar b/project/QBarInterpreter/qbar
new file mode 120000
index 0000000..703cd45
--- /dev/null
+++ b/project/QBarInterpreter/qbar
@@ -0,0 +1 @@
+qbar_lang \ No newline at end of file
diff --git a/project/QBarInterpreter/qbar.sh b/project/QBarInterpreter/qbar.sh
new file mode 100755
index 0000000..1b150f7
--- /dev/null
+++ b/project/QBarInterpreter/qbar.sh
@@ -0,0 +1,36 @@
+#!/bin/sh
+interpret=0;
+
+is_interpreted() {
+ for i in $@ ; do
+ if [ "$i" == "-i" ] ; then
+ interpret=1;
+ break
+ fi
+ done;
+}
+
+is_interpreted;
+
+if [ $interpret ] ; then
+ qb_dir=/home/`whoami`/
+ if [ ! -e $qb_dir ] ; then
+ history="";
+ else
+ qb_dir=$qb_dir/.qbar
+ if [ ! -e $qb_dir ] ; then
+ mkdir $qb_dir
+ fi
+
+ qb_hist_file=$qb_dir/qb_history
+ if [ ! -e $qb_hist_file ] ; then
+ touch $qb_hist_file
+ fi
+
+ history="-H $qb_hist_file"
+ fi
+
+ rlwrap $history -c -f /usr/lib/qbar/aux/completions.txt java -jar /usr/lib/qbar/lib/QBarInterpreter.jar -p /usr/lib/qbar $@
+else
+ java -jar /usr/lib/qbar/lib/QBarInterpreter.jar -p /usr/lib/qbar $@
+fi
diff --git a/project/QBarInterpreter/qbar_lang/io/BufferedReader.qbar b/project/QBarInterpreter/qbar_lang/io/BufferedReader.qbar
new file mode 100644
index 0000000..0b5c382
--- /dev/null
+++ b/project/QBarInterpreter/qbar_lang/io/BufferedReader.qbar
@@ -0,0 +1,62 @@
+Import qbar/io/Reader.qbar;
+Import qbar/lang/Maybe.qbar;
+Import qbar/lang/System.qbar;
+
+Namespace BufferedReader {
+ Incorporate Reader;
+
+ Struct BufferedReader extends Reader {
+ let new BufferedReader( reader ) = do {
+ this.init( reader );
+
+ if reader isa Reader {
+ this.reader <- reader;
+ } else {
+ this.reader <- new Reader( reader );
+ }
+
+ this.buffer <- [];
+ this.bufSize <- 4096;
+ this.bufCur <- 0;
+ this.dbg <- 1;
+
+ System.printStrLn( "START" );
+
+ this.readBuffer();
+ }
+
+ let read = do {
+ if this.bufCur == this.bufSize {
+ this.readBuffer();
+ this.bufCur <- 0;
+ }
+
+ yeild <- this.buffer#this.bufCur;
+ this.bufCur <- this.bufCur + 1;
+
+ return yeild;
+ }
+
+ let readBuffer = do {
+ System.printStrLn( "Reading Buffer " ++ this.dbg );
+ this.buffer <- this.readBytes( this.bufSize );
+ this.dbg <- this.dbg + 1;
+ }
+
+ let readLine = do {
+ str <- "" ++ "";
+
+ i <- 0;
+ while ( i <- this.read() ) != 10 {
+ if i == -1 {
+ return if str.length == 0 then Maybe.new Null()
+ else Maybe.new Maybe( str );
+ }
+
+ str +< i as Character;
+ }
+
+ return Maybe.new Maybe(str);
+ }
+ }
+} \ No newline at end of file
diff --git a/project/QBarInterpreter/qbar_lang/io/File.qbar b/project/QBarInterpreter/qbar_lang/io/File.qbar
new file mode 100644
index 0000000..3f848aa
--- /dev/null
+++ b/project/QBarInterpreter/qbar_lang/io/File.qbar
@@ -0,0 +1,10 @@
+-{
+ This namespace has several native methods
+ that are used to help dealing with file operations.
+}-
+Namespace File {
+ -{
+ Incorporates com.modulus.qbar.io.IOTools class
+ }-
+ Incorporate Native com.modulus.qbar.io.IOTools;
+} \ No newline at end of file
diff --git a/project/QBarInterpreter/qbar_lang/io/IO.qbar b/project/QBarInterpreter/qbar_lang/io/IO.qbar
new file mode 100644
index 0000000..ad6a3cc
--- /dev/null
+++ b/project/QBarInterpreter/qbar_lang/io/IO.qbar
@@ -0,0 +1,12 @@
+-{
+ This namespace has several native methods
+ that are used to help dealing with file operations.
+}-
+
+@infix << 30;
+Namespace IO {
+ -{
+ Incorporates com.modulus.qbar.io.IOTools class
+ }-
+ Incorporate Native com.modulus.qbar.io.IOTools;
+} \ No newline at end of file
diff --git a/project/QBarInterpreter/qbar_lang/io/Reader.qbar b/project/QBarInterpreter/qbar_lang/io/Reader.qbar
new file mode 100644
index 0000000..3522adf
--- /dev/null
+++ b/project/QBarInterpreter/qbar_lang/io/Reader.qbar
@@ -0,0 +1,24 @@
+Namespace Reader {
+ Struct Reader {
+ -- some kind of instream
+ let new Reader( instream ) = this.init( instream );
+
+ let init( instream ) = this.instream <- instream;
+
+ let close = this.instream.close();
+
+ let mark = this.instream.mark();
+
+ let reset = this.instream.reset();
+
+ let read = this.instream.read();
+
+ let readBytes(n) = this.instream.readBytes(n);
+
+ let skip(n) = this.instream.skip();
+
+ let available = this.instream.available();
+
+ let nextChar = this.read() as Character;
+ }
+} \ No newline at end of file
diff --git a/project/QBarInterpreter/qbar_lang/lang/Math.qbar b/project/QBarInterpreter/qbar_lang/lang/Math.qbar
new file mode 100644
index 0000000..77416b2
--- /dev/null
+++ b/project/QBarInterpreter/qbar_lang/lang/Math.qbar
@@ -0,0 +1,131 @@
+Import qbar/lang/System;
+
+-{
+ Math namespace, this holds many
+ useful functions for anytime
+ math computations.
+
+ This namespace includes aliases
+ of all the functions in java.lang.Math
+ and also includes some extra series
+ functions.
+ }-
+Namespace Math {
+
+ -- need to include the native java class
+ Incorporate Native com.modulus.qbar.lang.QBMath;
+
+ -{
+ The constructor of QBMath creates some
+ of the basic series that QBMath uses.
+ }-
+ let construct = do {
+
+
+ -- the `this` is negated all too often
+ -{
+ The series list for pascal's
+ triangle.
+ }-
+ this.pascalSeries <- [ n | if n <= 0 then [1]
+ else if n == 1 then [ 1, 1 ]
+ else QBMath.pascalTriangle( this#(n-1) ) ];
+
+ -{
+ The series list for the fibonacci
+ series
+ }-
+ this.fibonacciSeries <- [ n | if n < 2 then n
+ else this#( n - 1 ) + this#(n - 2) ];
+
+ -{
+ The series list for the
+ factorial series.
+ }-
+ this.factorialSeries <- [ n | if n <= 1 then 1
+ else n * this#(n - 1) ];
+
+ this.dx <- 0.00000000001;
+ }
+
+ -{
+ The pascal function takes
+ a list and uses that list
+ to generate what would be
+ the next list in the pascal
+ series.
+ }-
+ let pascalTriangle( lastList ) = do {
+ ret <- [1];
+
+ for [ 0 .. lastList.length - 2 ] -> n {
+ ret +< lastList#n + lastList#(n+1);
+ }
+
+ ret +< 1;
+ return ret;
+ }
+
+ -{
+ Directly accesses the factorialSeries
+ get function.
+
+ @return the factorial of `n` (`n!`)
+ }-
+ let factorial( n ) = this.factorialSeries # n;
+
+ -{
+ @return the `n`<sup>th</sup> number
+ in the fibonacci series.
+ }-
+ let fibonacci( n ) = this.fibonacciSeries # n;
+
+ -{
+ @return the `n`<sup>th</sup> list in
+ pascal's triangle list.
+ }-
+ let pascal( n ) = this.pascalList # n;
+
+ -{
+ @return a function that is a rough derivative
+ of the original that was passed. This function
+ uses the `dx` defined in the Math namespace.
+
+ The Function will inherently round to three decimal places.
+ }-
+ let derivative( func ) = do {
+ let tmp(x) = roundN( ( func(x + this.dx) + ( 0 - func(x) ) ) / this.dx, 3 );
+
+ return tmp;
+ }
+
+ -{
+ @return a function that is a rough derivative
+ of the original that was passed. This function
+ takes a function, the percision of `dx` and an
+ integer value of how many decimals to round to.
+ }-
+ let derivativedx( func, dx, round ) = do {
+ let tmp(x) = roundN( ( func(x + this.dx) + ( 0 - func(x) ) ) / dx, round );
+
+ return tmp;
+ }
+
+ let integral( func ) = do {
+ lst <- [ n | if this.abs( n ) <= this.dx then func( n ) * this.dx
+ else ( func( n ) +
+
+ ( if n < 0 then this#( n + dx )
+ else this#( n - dx ) ) ) * this.dx ];
+ return lst;
+ }
+
+ -{
+ @return a number that has been rounded
+ to `n` decimal places.
+ }-
+ let roundN( x, n ) = do {
+ pow <- 10.0 ^ n;
+ return Math.round( x * pow ) / pow;
+ }
+} \ No newline at end of file
diff --git a/project/QBarInterpreter/qbar_lang/lang/Maybe.qbar b/project/QBarInterpreter/qbar_lang/lang/Maybe.qbar
new file mode 100644
index 0000000..fa97265
--- /dev/null
+++ b/project/QBarInterpreter/qbar_lang/lang/Maybe.qbar
@@ -0,0 +1,4 @@
+Namespace Maybe {
+ Incorporate Native com.modulus.qbar.lang.QBMaybe;
+}
+
diff --git a/project/QBarInterpreter/qbar_lang/lang/System.qbar b/project/QBarInterpreter/qbar_lang/lang/System.qbar
new file mode 100644
index 0000000..d0836e7
--- /dev/null
+++ b/project/QBarInterpreter/qbar_lang/lang/System.qbar
@@ -0,0 +1,29 @@
+Import qbar/io/IO.qbar;
+
+-{
+ This namespace holds many raw and basic
+ functions that the user may want to use.
+
+ This Namespace is for the most part native.
+ }-
+Namespace System {
+ -- incorporate the native QBSystem class
+ Incorporate Native com.modulus.qbar.lang.QBSystem;
+
+ let construct = do {
+ this.out <- IO.getStdOut();
+ this.in <- IO.getStdIn();
+ this.err <- IO.getStdErr();
+
+ this.bufferedIn <- IO.new BufferedReader( this.in );
+ }
+
+ let printStrLn( str ) =
+ this.out.printStrLn( str );
+
+ let printStr( str ) =
+ this.out.printStr( str );
+
+ let readLine =
+ this.bufferedIn.readLine();
+} \ No newline at end of file
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/core/NaturalFunctions.java b/project/QBarInterpreter/src/com/modulus/qbar/core/NaturalFunctions.java
new file mode 100644
index 0000000..4a3e040
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/core/NaturalFunctions.java
@@ -0,0 +1,376 @@
+package com.modulus.qbar.core;
+
+import com.modulus.qbar.core.primitive.QBChar;
+import com.modulus.qbar.core.primitive.QBDouble;
+import com.modulus.qbar.core.primitive.QBInt;
+import com.modulus.qbar.core.primitive.QBPrimitive;
+
+public class NaturalFunctions {
+ public static final QBFunction ADD = new QBFunction(2) {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -458278389954945664L;
+
+ @Override
+ public QBObject execute(QBObject[] args) {
+ QBPrimitive obj2 = (QBPrimitive) args[0];
+ QBPrimitive obj1 = (QBPrimitive) args[1];
+
+ return new QBDouble( obj1.doubleValue() + obj2.doubleValue() );
+ }
+ };
+
+ public static final QBFunction SUB = new QBFunction(2) {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 8875619169775793806L;
+
+ @Override
+ public QBObject execute(QBObject[] args) {
+ QBPrimitive obj2 = (QBPrimitive) args[0];
+ QBPrimitive obj1 = (QBPrimitive) args[1];
+
+ return new QBDouble( obj1.doubleValue() - obj2.doubleValue() );
+ }
+ };
+
+ public static final QBFunction MUL = new QBFunction(2) {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -5397892833871103232L;
+
+ @Override
+ public QBObject execute(QBObject[] args) {
+ QBPrimitive obj2 = (QBPrimitive) args[0];
+ QBPrimitive obj1 = (QBPrimitive) args[1];
+
+ return new QBDouble( obj1.doubleValue() * obj2.doubleValue() );
+ }
+ };
+
+ public static final QBFunction DIV = new QBFunction(2) {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 6929787162778332248L;
+
+ @Override
+ public QBObject execute(QBObject[] args) {
+ QBPrimitive obj2 = (QBPrimitive) args[0];
+ QBPrimitive obj1 = (QBPrimitive) args[1];
+
+ return new QBDouble( obj1.doubleValue() / obj2.doubleValue() );
+ }
+ };
+
+ public static final QBFunction DIVI = new QBFunction(2) {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 6929787162778332248L;
+
+ @Override
+ public QBObject execute(QBObject[] args) {
+ QBPrimitive obj2 = (QBPrimitive) args[0];
+ QBPrimitive obj1 = (QBPrimitive) args[1];
+
+ if(obj2 instanceof QBDouble)
+ return new QBDouble( obj1.doubleValue() / obj2.doubleValue() );
+
+ return new QBInt( obj1.intValue() / obj2.intValue() );
+ }
+ };
+
+ public static final QBFunction ADDI = new QBFunction(2) {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -458278389954945664L;
+
+ @Override
+ public QBObject execute(QBObject[] args) {
+ QBPrimitive obj2 = (QBPrimitive) args[0];
+ QBPrimitive obj1 = (QBPrimitive) args[1];
+
+ if(obj2 instanceof QBDouble)
+ return new QBDouble( obj1.doubleValue() + obj2.doubleValue() );
+
+ return new QBInt( obj1.intValue() + obj2.intValue() );
+ }
+ };
+
+ public static final QBFunction SUBI = new QBFunction(2) {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 8875619169775793806L;
+
+ @Override
+ public QBObject execute(QBObject[] args) {
+ QBPrimitive obj2 = (QBPrimitive) args[0];
+ QBPrimitive obj1 = (QBPrimitive) args[1];
+
+ if(obj2 instanceof QBDouble)
+ return new QBDouble( obj1.doubleValue() - obj2.doubleValue() );
+
+ return new QBInt( obj1.intValue() - obj2.intValue() );
+ }
+ };
+
+ public static final QBFunction MULI = new QBFunction(2) {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -5397892833871103232L;
+
+ @Override
+ public QBObject execute(QBObject[] args) {
+ QBPrimitive obj2 = (QBPrimitive) args[0];
+ QBPrimitive obj1 = (QBPrimitive) args[1];
+
+ if(obj2 instanceof QBDouble)
+ return new QBDouble( obj1.doubleValue() * obj2.doubleValue() );
+
+ return new QBInt( obj1.intValue() * obj2.intValue() );
+ }
+ };
+
+ public static final QBFunction POWI = new QBFunction(2) {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 5551940214654416862L;
+
+ @Override
+ public QBObject execute(QBObject[] args) {
+ QBPrimitive obj2 = (QBPrimitive) args[0];
+ QBPrimitive obj1 = (QBPrimitive) args[1];
+
+ if(obj2 instanceof QBDouble)
+ return new QBDouble( Math.pow(obj1.doubleValue(), obj2.doubleValue()) );
+
+ return new QBInt( (int) Math.pow(obj1.intValue(), obj2.intValue()) );
+ }
+ };
+
+
+ public static final QBFunction POW = new QBFunction(2) {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 5551940214654416862L;
+
+ @Override
+ public QBObject execute(QBObject[] args) {
+ QBPrimitive obj2 = (QBPrimitive) args[0];
+ QBPrimitive obj1 = (QBPrimitive) args[1];
+
+ return new QBDouble( Math.pow(obj1.doubleValue(), obj2.doubleValue()) );
+ }
+ };
+
+ public static final QBFunction AND = new QBFunction(2) {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -2549738198868255228L;
+
+ @Override
+ public QBObject execute(QBObject[] args) {
+ QBInt obj2 = (QBInt) args[0];
+ QBInt obj1 = (QBInt) args[1];
+
+ return new QBInt( obj1.intValue() & obj2.intValue() );
+ }
+ };
+
+ public static final QBFunction OR = new QBFunction(2) {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -4783153883428278962L;
+
+ @Override
+ public QBObject execute(QBObject[] args) {
+ QBInt obj2 = (QBInt) args[0];
+ QBInt obj1 = (QBInt) args[1];
+
+ return new QBDouble( obj1.intValue() | obj2.intValue() );
+ }
+ };
+
+ public static final QBFunction MOD = new QBFunction(2) {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -4919278872817004237L;
+
+ @Override
+ public QBObject execute(QBObject[] args) {
+ QBPrimitive obj2 = (QBPrimitive) args[0];
+ QBPrimitive obj1 = (QBPrimitive) args[1];
+
+ return new QBDouble( obj1.doubleValue() % obj2.doubleValue() );
+ }
+ };
+
+ public static final QBFunction MODI = new QBFunction(2) {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -4919278872817004237L;
+
+ @Override
+ public QBObject execute(QBObject[] args) {
+ QBPrimitive obj2 = (QBPrimitive) args[0];
+ QBPrimitive obj1 = (QBPrimitive) args[1];
+
+ if(obj2 instanceof QBDouble)
+ return new QBDouble( obj1.doubleValue() % obj2.doubleValue() );
+
+ return new QBInt( obj1.intValue() % obj2.intValue() );
+ }
+ };
+
+ public static final QBFunction XOR = new QBFunction(2) {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -1376100825702322135L;
+
+ @Override
+ public QBObject execute(QBObject[] args) {
+ QBInt obj2 = (QBInt) args[0];
+ QBInt obj1 = (QBInt) args[1];
+
+ return new QBInt( obj1.intValue() ^ obj2.intValue() );
+ }
+ };
+
+ public static final QBFunction NOT = new QBFunction(1) {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -2508035483288699515L;
+
+ @Override
+ public QBObject execute(QBObject[] args) {
+ QBInt obj2 = (QBInt) args[0];
+
+ return new QBInt( ~obj2.intValue() );
+ }
+ };
+
+ public static final QBFunction GT = new QBFunction(2) {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -3405854489760677489L;
+
+ @Override
+ public QBObject execute(QBObject[] args) {
+ QBPrimitive obj2 = (QBPrimitive) args[0];
+ QBPrimitive obj1 = (QBPrimitive) args[1];
+
+ return new QBInt( obj1.compareTo(obj2) == 1 ? 1 : 0 );
+ }
+ };
+
+ public static final QBFunction LT = new QBFunction(2) {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -3758428556267202922L;
+
+ @Override
+ public QBObject execute(QBObject[] args) {
+ QBPrimitive obj2 = (QBPrimitive) args[0];
+ QBPrimitive obj1 = (QBPrimitive) args[1];
+
+ return new QBInt( obj1.compareTo(obj2) == -1 ? 1 : 0 );
+ }
+ };
+
+ public static final QBFunction EQ = new QBFunction(2) {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -3756644511236409624L;
+
+ @Override
+ public QBObject execute(QBObject[] args) {
+ QBPrimitive obj2 = (QBPrimitive) args[0];
+ QBPrimitive obj1 = (QBPrimitive) args[1];
+
+ return new QBInt( obj1.compareTo(obj2) == 0 ? 1 : 0 );
+ }
+ };
+
+ public static final QBFunction LTE = new QBFunction(2) {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -8301307408804643494L;
+
+ @Override
+ public QBObject execute(QBObject[] args) {
+ QBPrimitive obj2 = (QBPrimitive) args[0];
+ QBPrimitive obj1 = (QBPrimitive) args[1];
+
+ return new QBInt( obj1.compareTo(obj2) <= 0 ? 1 : 0 );
+ }
+ };
+
+ public static final QBFunction GTE = new QBFunction(2) {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -3805394859773545337L;
+
+ @Override
+ public QBObject execute(QBObject[] args) {
+ QBPrimitive obj2 = (QBPrimitive) args[0];
+ QBPrimitive obj1 = (QBPrimitive) args[1];
+
+ return new QBInt( obj1.compareTo(obj2) >= 0 ? 1 : 0 );
+ }
+ };
+
+ public static final QBFunction NE = new QBFunction(2) {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -5958431913044160689L;
+
+ @Override
+ public QBObject execute(QBObject[] args) {
+ QBPrimitive obj2 = (QBPrimitive) args[0];
+ QBPrimitive obj1 = (QBPrimitive) args[1];
+
+ return new QBInt( obj1.compareTo(obj2) != 0 ? 1 : 0 );
+ }
+ };
+
+ public static final QBFunction AS = new QBFunction(2){
+
+ @Override
+ public QBObject execute(QBObject[] args) {
+ QBStruct obj2 = (QBStruct) args[0];
+ QBPrimitive obj1 = (QBPrimitive) args[1];
+
+ if( obj2 == QBInt.struct )
+ return new QBInt( obj1.intValue() );
+
+ else if(obj2 == QBDouble.struct )
+ return new QBDouble( obj1.doubleValue() );
+
+ else if(obj2 == QBChar.struct)
+ return new QBChar( obj1.charValue() );
+
+ throw new RuntimeException("Exhauseted all options");
+ }
+ };
+}
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/core/QBArray.java b/project/QBarInterpreter/src/com/modulus/qbar/core/QBArray.java
new file mode 100644
index 0000000..b03154e
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/core/QBArray.java
@@ -0,0 +1,26 @@
+package com.modulus.qbar.core;
+
+public class QBArray extends QBObject{
+ /**
+ *
+ */
+ private static final long serialVersionUID = -5554983175051078215L;
+ private QBObject[] arr;
+
+ public QBArray(int len){
+ super( QBStruct.array );
+ this.arr = new QBObject[len];
+ }
+
+ public void set(int idx, QBObject obj){
+ this.arr[idx] = obj;
+ }
+
+ public QBObject get(int idx){
+ return this.arr[idx];
+ }
+
+ public int getLength(){
+ return arr.length;
+ }
+}
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/core/QBConstructor.java b/project/QBarInterpreter/src/com/modulus/qbar/core/QBConstructor.java
new file mode 100644
index 0000000..e3759d7
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/core/QBConstructor.java
@@ -0,0 +1,46 @@
+package com.modulus.qbar.core;
+
+import com.modulus.common.collections.ArrayStack;
+import com.modulus.common.collections.Stack;
+import com.modulus.qbar.core.parser.QBParser;
+import com.modulus.qbar.core.parser.stmt.QBStatement;
+
+public class QBConstructor extends QBSyntheticFunction{
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1795350337497901352L;
+ private QBStruct struct;
+ private Stack<QBObject> thses = new ArrayStack<QBObject>();
+
+ public QBConstructor(QBStatement code, QBStruct struct, QBParser parser) {
+ super(code, parser);
+
+ this.struct = struct;
+ this.setGlobal(true);
+ }
+
+ public QBStruct getObjectStruct(){
+ return struct;
+ }
+
+
+ @Override
+ public QBObject execute( QBObject[] arr ){
+ QBObject ths = new QBObject(struct);
+ this.thses.push(ths);
+ super.execute(arr);
+ this.thses.pop();
+ return ths;
+ }
+
+ @Override
+ public QBObject get(String str){
+
+ if(str.equals("this"))
+ return thses.peek();
+
+ return super.get(str);
+ }
+}
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/core/QBFile.java b/project/QBarInterpreter/src/com/modulus/qbar/core/QBFile.java
new file mode 100644
index 0000000..94b8a63
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/core/QBFile.java
@@ -0,0 +1,36 @@
+package com.modulus.qbar.core;
+
+import java.io.File;
+
+import com.modulus.qbar.core.interpreter.Main;
+
+public class QBFile {
+ private static String[] extensions = new String[]{"", ".qbz", ".qbc", ".qbar"};
+ public static File getQBFile( String filename ){
+ String[] folders = Main.getPath();
+
+ if( folders == null )
+ folders = new String[]{};
+
+ File file = new File(filename);
+
+ for(String path : folders){
+
+ for(String str : extensions) {
+ if(file.exists()) {
+ Main.debug(QBFile.class, " Found File " + file + " on the classpath!");
+ return file;
+ }
+
+
+ file = new File(path, filename + str);
+ // Main.debug(QBFile.class, " Looking for File " + file.getAbsolutePath() + " on the classpath.");
+ }
+ }
+
+ if(!file.exists())
+ throw new RuntimeException("The file: " + filename + " cannot be found on the classpath!");
+
+ return file;
+ }
+}
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/core/QBFunction.java b/project/QBarInterpreter/src/com/modulus/qbar/core/QBFunction.java
new file mode 100644
index 0000000..398e21a
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/core/QBFunction.java
@@ -0,0 +1,131 @@
+package com.modulus.qbar.core;
+
+import com.modulus.access.ArrayFunction;
+import com.modulus.common.collections.Stack;
+import com.modulus.qbar.core.parser.ByteOperation;
+
+public abstract class QBFunction extends QBObject implements ArrayFunction< QBObject, QBObject >{
+ /**
+ *
+ */
+ private static final long serialVersionUID = -7422585311092161908L;
+
+ private boolean global;
+
+ public static final QBStruct functionStruct = new QBStruct("function"){
+ /**
+ *
+ */
+ private static final long serialVersionUID = -2742542386017721944L;
+
+ @Override
+ public QBObject newInstance() {
+ return this;
+ }
+ };
+
+ protected QBObject returnedValue;
+
+ private int argc;
+
+ public QBFunction( int argc ) {
+ super(functionStruct);
+ this.argc = argc;
+ }
+
+ public int getArgc(){
+ return argc;
+ }
+
+ public String getName(){
+ return this.toString();
+ }
+
+ @Override
+ public abstract QBObject execute(QBObject[] args);
+
+ protected void setGlobal( boolean global ){
+ this.global = global;
+ }
+
+ protected void setArgc( int argc ){
+ this.argc = argc;
+ }
+
+ public boolean isGlobal(){
+ return global;
+ }
+
+ /**
+ * Relatively low level function call that pushes the object
+ * it returned onto the stack.
+ * @param func the function to call
+ * @param stack the stack to call it on
+ */
+ public static void callFunction( QBFunction func, Stack<QBObject> stack ){
+ int argc = func.getArgc();
+ QBObject[] nextArgs = new QBObject[ argc ];
+
+ for( int i = 0; i < argc; i ++ ){
+ //System.out.println(func + " argc: " + argc + " i: " + i );
+ nextArgs[ argc - i - 1 ] = stack.pop();
+ }
+
+ stack.push( func.execute(nextArgs) );
+ }
+
+ /*
+ * Very, very low level computation, deals with all
+ * of the individual statements that need to be executed.
+ */
+ public void exec( ByteOperation[] arr, Stack<QBObject> stack){
+// System.out.println(Arrays.toString(arr));
+ if(arr == null)
+ return;
+
+ for( ByteOperation op : arr ){
+ switch( op.getOperator() ){
+ case CALLG:
+ //System.out.println(op.getArg().toString());
+ callFunction( (QBFunction)this.get(op.getArg().toString()), stack);
+ break;
+ case CALL:
+ QBObject caller = stack.peek();
+
+ if(caller instanceof QBUtilityNamespace)
+ stack.pop();
+ //System.out.println("CALL " + caller);
+ callFunction( (QBFunction)caller.get(op.getArg().toString()), stack);
+ break;
+ case PUSH:
+ String[] str = (String[]) op.getArgs();
+
+ stack.push( this.hardGet(str) );
+ break;
+ case PUSHO:
+ QBObject obj = (QBObject) op.getArg();
+ stack.push(obj);
+ break;
+
+ case STO:
+ QBObject pop = stack.peek();
+ this.hardSet((String[]) op.getArgs(), pop);
+ break;
+
+ case ITR:
+ QBObject popped = stack.peek();
+ String name = op.getArg().toString();
+ stack.push(popped.iterator(name, this));
+
+ }
+ }
+
+ // this method does not return via the stack, but pops the value
+ // into a holder to help prevent stack memory leaks.
+ returnedValue = stack.pop();
+ }
+
+ public QBObject getReturnedValue(){
+ return returnedValue;
+ }
+}
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/core/QBNamespace.java b/project/QBarInterpreter/src/com/modulus/qbar/core/QBNamespace.java
new file mode 100644
index 0000000..82a66d9
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/core/QBNamespace.java
@@ -0,0 +1,161 @@
+package com.modulus.qbar.core;
+
+import java.io.Serializable;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Class is the very root of all the interpreter classes.
+ * a QBNamespace is anything that has the ability to store variables
+ * including QBObjects and Functions.
+ *
+ * @author jrahm
+ *
+ */
+public class QBNamespace implements Serializable{
+ /**
+ *
+ */
+ private static final long serialVersionUID = -102581163781603724L;
+
+ private QBNamespace superNamespace;
+ private String name = super.toString();
+ // The map this namespace delegates,
+ // This map can be of different types
+ // like a HashTable.
+ private Map<String, QBObject> map;
+
+ /**
+ * Creates a new QBNamespace with the map <code>map</code>
+ * @param map
+ */
+ public QBNamespace( Map<String, QBObject> map ){
+ this( map, null );
+ }
+
+ public QBNamespace( Map<String, QBObject> map, QBNamespace sup){
+ this.map = map;
+ this.superNamespace = sup;
+ }
+
+ /**
+ * Sets the object with the name <code>name</code>
+ * to the specific <code>QBObject obj</code>
+ *
+ * @param name the name of the variable to set
+ * @param obj the object to set that name equal to.
+ */
+ public void set(String name, QBObject obj){
+ this.map.put(name, obj);
+ }
+
+ /**
+ * Returns the object that is referenced by the
+ * string <code>name</code> from this Namespace
+ *
+ * @param name the name of the object to retrieve
+ * @return the object referenced as <code>name</code>
+ */
+ public QBObject get(String name){
+ // System.out.println("THIS: " + this);
+ QBObject obj = this.map.get(name);
+
+ if(obj == null && superNamespace != null)
+ obj = superNamespace.get(name);
+
+ if(obj == null)
+ throw new RuntimeException("The variable: " + name + " does not exist in the current namespace. " + this);
+
+ return obj;
+ }
+
+ /**
+ * Returns the object that is referenced by the
+ * string <code>name</code> from this Namespace
+ *
+ * This version of the function will not error
+ * if the object is not found
+ *
+ * @param name the name of the object to retrieve
+ * @return the object referenced as <code>name</code>
+ */
+ public QBObject getNoError(String name){
+ QBObject obj = this.map.get(name);
+
+ if(obj == null && superNamespace != null)
+ obj = superNamespace.getNoError(name);
+
+ return obj;
+ }
+
+ public QBNamespace getSuper(){
+ return this.superNamespace;
+ }
+
+ public void setSuper( QBNamespace sup ){
+ this.superNamespace = sup;
+ }
+
+ public String toString2(){
+ StringBuffer buf = new StringBuffer();
+ for( String key : this.map.keySet() ){
+ buf.append(key + ":\t");
+ buf.append( this.get(key) + "\n");
+ }
+
+ return buf.toString();
+ }
+
+ public Set<String> getKeySet(){
+ return map.keySet();
+ }
+
+ public boolean hasKey( String key ){
+ return map.containsKey(key);
+ }
+
+ public QBObject hardGet(String[] args){
+ QBNamespace cur = this;
+
+ for(int i = 0;i < args.length - 1;i ++)
+ cur = cur.get(args[i]);
+
+ return cur.get(args[args.length - 1]);
+ }
+
+ public void hardSet(String[] args, QBObject obj){
+ QBNamespace cur = this;
+
+ for(int i = 0;i < args.length - 1;i ++)
+ cur = cur.get(args[i]);
+
+ cur.set(args[args.length - 1], obj);
+ }
+
+ /**
+ * Incorporates two namespaces and
+ * makes them clients to one and other,
+ * so that if something is added to one,
+ * then it is added to the other.
+ *
+ * @param other the other namespace
+ */
+ public void incoporate( QBNamespace other ){
+ load( other );
+ // make the other one your bitch
+ other.map = this.map;
+ }
+
+ /**
+ * Same as incorporates, except that in this case,
+ * the two namespaces remain sovereign and do not
+ * become clients.
+ *
+ * @param other the other namespace
+ */
+ public void load( QBNamespace other ){
+ for (String key : other.getKeySet() ){
+ this.set(key, other.get(key));
+ }
+ }
+}
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/core/QBObject.java b/project/QBarInterpreter/src/com/modulus/qbar/core/QBObject.java
new file mode 100644
index 0000000..c187c12
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/core/QBObject.java
@@ -0,0 +1,89 @@
+package com.modulus.qbar.core;
+
+import java.util.Hashtable;
+
+import com.modulus.qbar.integration.QBWrappedObject;
+import com.modulus.qbar.lang.QBIterator;
+import com.modulus.qbar.lang.QBSyntheticIterator;
+
+public class QBObject extends QBNamespace implements Cloneable{
+ /**
+ *
+ */
+ private static final long serialVersionUID = -3738912814141895851L;
+ private QBStruct struct;
+
+
+ public QBObject( QBStruct struct ){
+ super( new Hashtable<String, QBObject>(), struct );
+ this.struct = struct;
+ }
+
+ public QBStruct getStruct(){
+ return struct;
+ }
+
+ protected void setStruct(QBStruct struct){
+ this.struct = struct;
+ }
+
+ public Object getWrapped(){
+ // throw new RuntimeException("The type: " + struct.getName() + " is not of native origin.");
+ return this;
+ }
+// @Override
+// public void setSuper(QBNamespace sup){
+// new Exception().printStackTrace();
+// super.setSuper(sup);
+// }
+
+ public QBObject clone(){
+ try {
+ return (QBObject) super.clone();
+ } catch (CloneNotSupportedException e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ public QBIterator<?> iterator(String varName, QBNamespace sup){
+ QBFunction iterator = (QBFunction) this.get("iterator");
+
+ if(iterator == null)
+ return null;
+
+ QBIterator<?> ret;
+
+ QBObject obj = iterator.execute(new QBObject[]{this});
+
+ if(!(obj instanceof QBIterator))
+ ret = new QBSyntheticIterator(this, obj);
+ else
+ ret = (QBIterator<?>) obj;
+
+ ret.setVariableName(varName);
+ ret.setVariableNmspce(sup);
+
+ return ret;
+ }
+
+ public static long totalTime = 0;
+ public QBObject get(String name){
+ long t1 = System.currentTimeMillis();
+ try{
+ QBObject ret = super.get(name);
+ long t2 = System.currentTimeMillis();
+ totalTime += (t2 -t1);
+ return ret;
+ } catch(Exception e){
+ throw new RuntimeException("The variable: " + name + " does not exist for object: " + this);
+ }
+
+ }
+
+ public String toString(){
+ String tmp = super.toString();
+
+ return (struct == null ? "QBObject" : struct.getName()) + tmp.substring(tmp.indexOf("@"));
+ }
+}
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/core/QBReference.java b/project/QBarInterpreter/src/com/modulus/qbar/core/QBReference.java
new file mode 100644
index 0000000..c8fa0f5
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/core/QBReference.java
@@ -0,0 +1,19 @@
+package com.modulus.qbar.core;
+
+public class QBReference extends QBObject {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 4662929761631550702L;
+ private String str;
+
+ public QBReference(String str) {
+ super(null);
+ this.str = str;
+ }
+
+ public String getString(){
+ return str;
+ }
+
+}
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/core/QBStruct.java b/project/QBarInterpreter/src/com/modulus/qbar/core/QBStruct.java
new file mode 100644
index 0000000..66935d4
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/core/QBStruct.java
@@ -0,0 +1,137 @@
+package com.modulus.qbar.core;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.modulus.qbar.core.interpreter.QBInterpreter;
+import com.modulus.qbar.integration.QBWrappedObject;
+
+
+public class QBStruct extends QBObject{
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1271467629591493953L;
+
+ private List<QBStruct> superStruct = new ArrayList<QBStruct>();
+
+
+
+ public static final QBStruct clazz = new QBStruct(){
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1915609768305262326L;
+
+ @Override
+ public QBObject newInstance() {
+ return this;
+ }
+ };
+ public static final QBStruct array = new QBStruct("Array"){
+ /**
+ *
+ */
+ private static final long serialVersionUID = -6966880297599366521L;
+
+ @Override
+ public QBObject newInstance() {
+ return this;
+ }
+ };
+
+ static{
+ clazz.name = "Class";
+ clazz.pack = "core";
+
+ clazz.setStruct(clazz);
+ clazz.setSuper( QBInterpreter.instance().getGlobalNamespace() );
+ }
+
+ private String name;
+ private String pack;
+
+ private QBStruct(){ super(null); init(); };
+
+ protected QBStruct(boolean nill) { super(clazz); init(); };
+ public QBStruct(String name){
+ super(clazz);
+ this.name = name;
+
+ QBInterpreter.instance().getGlobalNamespace().set(name, this);
+ init();
+ }
+
+ public QBStruct(String name, QBStruct sup){
+ super(clazz);
+ this.name = name;
+
+ this.load(sup);
+ this.superStruct.add(sup);
+
+ QBInterpreter.instance().getGlobalNamespace().set(name, this);
+ init();
+ }
+
+ public String getName(){
+ return name;
+ }
+
+ public String getPackage(){
+ return pack;
+ }
+
+ public void setName(String name){
+ this.name = name;
+ }
+
+ public QBObject newInstance(){
+ return null;
+ }
+
+ public String toString(){
+ return name;
+ }
+
+ public void addSuperStruct( QBStruct sup ){
+ this.superStruct.add(sup);
+ this.load(sup);
+ }
+
+ private void init(){
+ this.set("getType", new QBFunction(1) {
+ private static final long serialVersionUID = -278677571392736723L;
+
+ @Override
+ public QBObject execute(QBObject[] args) {
+ return this;
+ }
+ });
+
+ this.set("isa", new QBFunction(2){
+ private static final long serialVersionUID = 3535644877614653590L;
+
+ @Override
+ public QBObject execute(QBObject[] args) {
+ QBObject ths = args[1];
+ QBStruct struct = (QBStruct) args[0];
+
+ return QBWrappedObject.wrap( ths.getStruct().instanceOf(struct) );
+ }
+
+ });
+
+
+ }
+
+ public boolean instanceOf(QBStruct struct) {
+ if( this == struct )
+ return true;
+
+ for( QBStruct sup : superStruct )
+ if( sup.instanceOf(struct) )
+ return true;
+
+ return false;
+ }
+}
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/core/QBSyntheticFunction.java b/project/QBarInterpreter/src/com/modulus/qbar/core/QBSyntheticFunction.java
new file mode 100644
index 0000000..fc8b317
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/core/QBSyntheticFunction.java
@@ -0,0 +1,338 @@
+package com.modulus.qbar.core;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.modulus.common.collections.ArrayStack;
+import com.modulus.common.collections.Stack;
+import com.modulus.dataread.expressions.FlowStatement;
+import com.modulus.dataread.expressions.Statement;
+import com.modulus.qbar.core.exceptions.ParseException;
+import com.modulus.qbar.core.interpreter.QBInterpreter;
+import com.modulus.qbar.core.parser.ByteOperation;
+import com.modulus.qbar.core.parser.QBParser;
+import com.modulus.qbar.core.parser.stmt.QBStatement;
+import com.modulus.qbar.core.primitive.QBPrimitive;
+import com.modulus.qbar.lang.QBIterator;
+
+public class QBSyntheticFunction extends QBFunction{
+ private Stack<QBNamespace> namespaceCalls = new ArrayStack<QBNamespace>();
+ /**
+ *
+ */
+ private static final long serialVersionUID = 2890479116324397754L;
+ private QBStatement code;
+ private String name;
+ private String[] args;
+ private Map<String, QBObject> namespaceTemplate = new HashMap<String,QBObject>();
+ private QBObject defaultThis;
+
+ private Map<String, QBObject> subs = new HashMap<String, QBObject>();
+
+ public QBSyntheticFunction( QBStatement code, QBParser parser ){
+ super( -1 );
+ this.code = code;
+
+ namespaceCalls.push(new QBNamespace(namespaceTemplate));
+ parse(parser);
+ }
+
+ public void parse(QBParser parser){
+ String header = code.getHeader(); // should return header, e.g. let someFunction(a,b,c) = do
+
+ if(!header.startsWith("let")){
+ throw new ParseException("Invalid Syntax For Function, expected `let`", code);
+ }
+
+ // this means that code is a one-line function and we need to break it up
+ if( !code.hasChildren() ){
+ String[] arr = header.split("=", 2);
+ header = arr[0] + " = ";
+
+ QBStatement onlyChild = new QBStatement(QBParser.formatter);
+ onlyChild.setLineNumber(code.getLineNumber());
+ onlyChild.setHeader(arr[1]);
+
+
+ code.addChild(onlyChild);
+ code.setHeader(header);
+ }
+
+ this.args = chompArgs( header );
+ this.name = chompName( header );
+
+ for( Statement stmt : code.getChildren() ){
+ String expression = stmt.getHeader();
+
+ //System.out.println("EXPPRS: "+expression);
+
+ stmt.setHeader(expression);
+
+ parser.readStatement( stmt, this );
+ }
+ }
+
+ /*
+ * Return the args of a function
+ */
+ private String[] chompArgs(String header){
+ // System.out.println(header);
+ int idx1 = header.indexOf('(');
+ int idx2 = header.lastIndexOf(')');
+
+ if(idx1 == idx2 && idx1 == -1){
+ return new String[]{"this"};
+ } else if( idx1 == -1 || idx2 == -1){
+ throw new ParseException("Syntax Error", code);
+ }
+ // should parse header, like the a,b,c part of
+ // let someFunction(a,b,c) = do
+ String args = header.substring( idx1 + 1, idx2 ).trim();
+
+ // split the arguments into string[], trimming all unnecessary whitespace
+ String[] ret = (args + ",this").split("\\s*,\\s*");
+
+
+ return ret;
+ }
+
+ /*
+ * return the name of the function
+ */
+ static private String chompName(String header){
+ // given header is to the effect of, `let someFunction(a,b,c) = do`
+
+ // Chop the `let` from the string
+ header = header.substring(3);
+ int idx = header.indexOf('(');
+ if(idx == -1)
+ idx = header.indexOf('=');
+ // get the name
+ return header.substring(0, idx).trim();
+ }
+
+ private boolean ifBit;
+// private QBObject returnedValue;
+
+ @Override
+ public QBObject execute(QBObject[] args) {
+ // System.out.println("Executing: " + this.getName());
+ QBNamespace layer = new QBNamespace(new HashMap<String, QBObject>());
+ layer.setSuper(this.getSuper());
+
+ for( String str : subs.keySet() ) {
+ QBObject clone = subs.get(str).clone();
+ layer.set(str, clone);
+ clone.setSuper(layer);
+ }
+
+ // System.out.println(layer.toString2());
+ //System.out.println("push");
+ namespaceCalls.push(layer);
+
+ mapArgs( args );
+ Stack<QBObject> stack = QBInterpreter.instance().getStack();
+ Statement[] statements = code.getChildren();
+ // System.out.println(Arrays.toString(statements));
+ execute(statements, stack);
+
+ //System.out.println("pop");
+ namespaceCalls.pop();
+ return stack.pop();
+ }
+
+ /**
+ * Guts of the exection process, when it operates on this low of of level
+ */
+ public void execute(Statement[] statements, Stack <QBObject> stack){
+ QBStatement exe = null;
+ Map<QBStatement, QBIterator> iterators = new HashMap<QBStatement, QBIterator>();
+ Stack<QBStatement> toProcess = new ArrayStack<QBStatement>();
+ try{
+ // push all of the statements onto the stack
+ // the pushAll method pushes the statements on backwards
+ pushAll(statements, toProcess);
+
+ // execute the statements
+ while(!toProcess.isEmpty()){
+
+ //if(toProcess.size() == 1 && namespaceCalls.size() == 2)
+ // System.out.println("Processing: " + toProcess.peek().getHeader() + " :: " + namespaceCalls.size() );
+ // get the next statement to execute
+ exe = toProcess.peek(); // look at the statement
+ // System.out.println("EXE " + exe + ", " + exe.getFlowStatement());
+ // is there some kind of a flow statement attached with this function?
+ FlowStatement flow = exe.getFlowStatement();
+
+ if( flow == FlowStatement.FOR){
+ QBIterator<?> iter = iterators.get(exe);
+
+ if(iter == null){
+ ByteOperation[] ops = exe.getOperations();
+ exec(ops, stack);
+ iter = (QBIterator<?>) returnedValue;
+
+ iterators.put(exe, iter);
+ }
+
+ if(!iter.hasNext()){
+ toProcess.pop();
+ iterators.put(exe, null);
+ } else{
+ iter.next();
+ pushAll( exe.getChildren(), toProcess );
+ }
+ }
+ // if and whiles are very similar, the only difference being that one repeats and the other does not
+ else if(flow == FlowStatement.IF || flow == FlowStatement.WHILE){
+
+ // if statements do not repeat
+ if(flow == FlowStatement.IF)
+ toProcess.pop(); // pop it off to make it not repeat.
+
+ // these are the operations
+ ByteOperation[] ops = exe.getOperations();
+
+ // execute the operations
+ exec(ops, stack);
+
+ // the method exec pops what it returns in returnedValue;
+ QBObject obj = returnedValue;
+
+ // check to see if the boolean evaluated to true
+ if( obj instanceof QBPrimitive &&((QBPrimitive) obj).intValue() > 0){ // TODO fix this to use method in Core
+ pushAll( exe.getChildren(), toProcess );
+ ifBit = true;
+ }
+ // if not
+ else{
+ // when the while statement is false, it is time to move on
+ if(flow == FlowStatement.WHILE){
+ toProcess.pop();
+ } else{
+ ifBit = false;
+ }
+ }
+ } else if( flow == FlowStatement.ELSE){
+ // just pop it
+ toProcess.pop();
+
+ // if the if bit was false
+ if( !ifBit ){
+
+ // push all the children
+ pushAll( exe.getChildren(), toProcess );
+ }
+ }
+ // if there is a return statement stop right now
+ else if ( flow == FlowStatement.RETURN ){
+ toProcess.pop();
+ exec( exe.getOperations(), stack );
+
+ stack.push( returnedValue );
+ return;
+ }
+ // if there is no flow, then just pop and execute.
+ else {
+ toProcess.pop();
+ exec( exe.getOperations(), stack );
+ }
+ }
+
+ // if this is the end, then it is time just to return the value that was executed by the last command,
+ // this means that if there is no return statement, then the last command becomes the return statement.
+ stack.push( returnedValue );
+ } catch(RuntimeException e){
+ e.printStackTrace();
+ throw new ParseException(e.getMessage(), e, exe);
+ }
+ }
+
+ /*
+ * This function pushes all of the elements in an array
+ * onto the stack in reverse order.
+ */
+ private void pushAll( Statement[] arr, Stack<QBStatement> toProcess ){
+ for ( int i = arr.length - 1; i >= 0; i --){
+ toProcess.push( (QBStatement) arr[i]);
+ }
+ }
+
+
+
+
+
+
+ private void mapArgs(QBObject[] args){
+
+ for( int i = 0;i < args.length; i ++){
+ this.set(this.args[i], args[i]);
+ }
+
+ if( defaultThis != null )
+ this.set("this", defaultThis);
+ }
+
+ @Override
+ public int getArgc(){
+ return this.args.length;
+ }
+
+ @Override
+ public String getName(){
+ return name;
+ }
+
+ public String toString2(){
+ return code.toString();
+ }
+
+ @Override
+ public void setGlobal( boolean global ){
+ super.setGlobal(global);
+
+ if( global ){
+ if(args[args.length - 1].equals("this")){
+ String[] next = new String[args.length - 1];
+ System.arraycopy(this.args, 0, next, 0, args.length - 1);
+ args = next;
+ } else if(!args[args.length - 1].equals("this")){
+ String[] next = new String[args.length + 1];
+ System.arraycopy(this.args, 0, next, 0, args.length);
+ next[args.length] = "this";
+ args = next;
+ }
+ }
+
+ }
+
+ @Override
+ public void setSuper( QBNamespace space){
+ super.setSuper(space);
+ // System.out.println("Setting Space To " + space);
+
+ if( space instanceof QBObject && !(space instanceof QBUtilityNamespace)){
+ setGlobal(false);
+ } else {
+ setGlobal(true);
+ }
+
+ if(space instanceof QBUtilityNamespace){
+ this.defaultThis = (QBObject) space;
+ }
+ }
+
+ @Override
+ public QBObject get(String name){
+ return namespaceCalls.peek().get(name);
+ }
+
+ @Override
+ public void set(String name, QBObject obj){
+ namespaceCalls.peek().set(name, obj);
+ }
+
+ public void addSubObject( String name, QBObject obj ){
+ this.subs.put(name, obj);
+ }
+}
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/core/QBSyntheticStruct.java b/project/QBarInterpreter/src/com/modulus/qbar/core/QBSyntheticStruct.java
new file mode 100644
index 0000000..d76a8ae
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/core/QBSyntheticStruct.java
@@ -0,0 +1,68 @@
+package com.modulus.qbar.core;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+import com.modulus.dataread.expressions.Statement;
+import com.modulus.qbar.core.exceptions.ParseException;
+import com.modulus.qbar.core.interpreter.QBInterpreter;
+import com.modulus.qbar.core.parser.QBParser;
+import com.modulus.qbar.lang.QBArrayList;
+import com.modulus.qbar.lang.QBList;
+
+public class QBSyntheticStruct extends QBStruct{
+ private static final long serialVersionUID = -1080935988322343396L;
+ // This maps an instance variable to its default value, if the struct is null
+ // the instance will be null defaultly
+ // private Map<String, QBStruct> instanceVars = new HashMap<String, QBStruct>();
+ private Statement code;
+
+ public QBSyntheticStruct( Statement code, QBParser parser, QBNamespace sup ) {
+ super(false);
+
+ this.setSuper(sup);
+ this.code = code;
+ if( !code.getHeader().startsWith("Struct") ){
+ throw new ParseException("Syntax error while creating struct, expected `Struct`", code);
+ }
+ // code header should be in the form of `Struct someStruct = `
+
+ String[] split = code.getHeader().split("\\s+");
+
+ if( code.getHeader().contains("extends") ){
+ QBList supers = new QBArrayList();
+ this.set( "supers", supers );
+
+ String header = code.getHeader();
+ String ext = header.split("\\s+extends\\s+")[1];
+
+ String[] extending = ext.split("\\s*,\\s*");
+ Collections.reverse(Arrays.asList(extending));
+
+ for(String s : extending){
+ QBStruct obj = (QBStruct) get(s);
+ this.addSuperStruct(obj);
+
+ supers.add(obj);
+ }
+ }
+
+ String name = split[1];
+
+ this.setName(name);
+
+ for(Statement child : code.getChildren())
+ parser.readStatement(child, this);
+ }
+
+ @Override
+ public QBObject newInstance() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public String toString(){
+ return code.toString();
+ }
+
+}
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/core/QBSyntheticUtilityNamespace.java b/project/QBarInterpreter/src/com/modulus/qbar/core/QBSyntheticUtilityNamespace.java
new file mode 100644
index 0000000..8153ae8
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/core/QBSyntheticUtilityNamespace.java
@@ -0,0 +1,38 @@
+package com.modulus.qbar.core;
+
+import com.modulus.dataread.expressions.Statement;
+import com.modulus.qbar.core.parser.QBParser;
+
+public class QBSyntheticUtilityNamespace extends QBUtilityNamespace {
+ private static final long serialVersionUID = 1941492008845020291L;
+
+ private String name;
+
+ public QBSyntheticUtilityNamespace(Statement stat, QBParser parser, QBNamespace superNamespace) {
+ String header = stat.getHeader();
+ this.setSuper(superNamespace);
+ // chop off `Namespace`
+ name = header.substring(9).trim();
+
+ for(Statement child : stat.getChildren())
+ parser.readStatement(child, this);
+
+ this.set("this", this);
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public void construct() {
+ QBObject obj = this.getNoError("construct");
+ if( obj instanceof QBFunction ){
+ ((QBFunction) obj).execute( new QBObject[]{} );
+ }
+ }
+
+
+
+}
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/core/QBUtilityNamespace.java b/project/QBarInterpreter/src/com/modulus/qbar/core/QBUtilityNamespace.java
new file mode 100644
index 0000000..7728327
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/core/QBUtilityNamespace.java
@@ -0,0 +1,22 @@
+package com.modulus.qbar.core;
+
+public abstract class QBUtilityNamespace extends QBObject{
+ private static final long serialVersionUID = -5228021096385368069L;
+
+ public QBUtilityNamespace() {
+ super( new QBStruct("Namespace") );
+ }
+
+ public QBUtilityNamespace( QBStruct struct ){
+ super(struct);
+ }
+
+ public abstract String getName();
+
+ public abstract void construct();
+
+ public void setStruct( QBStruct struct ){
+ super.setStruct(struct);
+ }
+
+}
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/core/Type.java b/project/QBarInterpreter/src/com/modulus/qbar/core/Type.java
new file mode 100644
index 0000000..1e5d224
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/core/Type.java
@@ -0,0 +1,5 @@
+package com.modulus.qbar.core;
+
+public interface Type {
+ public Type getSuper();
+}
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/core/compile/ByteOps.java b/project/QBarInterpreter/src/com/modulus/qbar/core/compile/ByteOps.java
new file mode 100644
index 0000000..88fbf0c
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/core/compile/ByteOps.java
@@ -0,0 +1,21 @@
+package com.modulus.qbar.core.compile;
+/**
+ * The simple byte code operators needed to
+ * run these simple functions.
+ *
+ * @author jrahm
+ *
+ */
+
+/*
+ * STOre
+ * CALL
+ * PUSH
+ * PUSH Object
+ * PUSH Hard Find
+ * PUSH Reference
+ * POP
+ * CALL Global
+ * IToRator
+ */
+public enum ByteOps { STO, CALL, PUSH, PUSHO, PUSHHF, PUSHR, POP, CALLG, ITR }
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/core/exceptions/ExecutionException.java b/project/QBarInterpreter/src/com/modulus/qbar/core/exceptions/ExecutionException.java
new file mode 100644
index 0000000..fd898ac
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/core/exceptions/ExecutionException.java
@@ -0,0 +1,23 @@
+package com.modulus.qbar.core.exceptions;
+
+public class ExecutionException extends RuntimeException{
+ private static final long serialVersionUID = 5108754994935394009L;
+
+ public ExecutionException() {
+ super();
+ }
+
+ public ExecutionException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public ExecutionException(String message) {
+ super(message);
+ }
+
+ public ExecutionException(Throwable cause) {
+ super(cause);
+ }
+
+
+}
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/core/exceptions/ParseException.java b/project/QBarInterpreter/src/com/modulus/qbar/core/exceptions/ParseException.java
new file mode 100644
index 0000000..58c5c4b
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/core/exceptions/ParseException.java
@@ -0,0 +1,32 @@
+package com.modulus.qbar.core.exceptions;
+
+import com.modulus.dataread.expressions.Statement;
+
+public class ParseException extends RuntimeException{
+ private static final long serialVersionUID = 5108754994935394009L;
+ private int line;
+ public ParseException(Statement stmt) {
+ super();
+ line = stmt.getLineNumber();
+ }
+
+ public ParseException(String message, Throwable cause, Statement stmt) {
+ super(message + " Line: " + stmt.getLineNumber() + "\n" + "Near: " + stmt.getHeader(), cause);
+ line = stmt.getLineNumber();
+ }
+
+ public ParseException(String message, Statement stmt) {
+ super(message + " Line: " + stmt.getLineNumber()+ "\n" + "Near: " + stmt.getHeader());
+ line = stmt.getLineNumber();
+ }
+
+ public ParseException(Throwable cause, Statement stmt) {
+ super(cause);
+ line = stmt.getLineNumber();
+ }
+
+ public int getLineNumber(){
+ return line;
+ }
+
+}
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/core/interpreter/CompiledReader.java b/project/QBarInterpreter/src/com/modulus/qbar/core/interpreter/CompiledReader.java
new file mode 100644
index 0000000..8c7b8a1
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/core/interpreter/CompiledReader.java
@@ -0,0 +1,13 @@
+package com.modulus.qbar.core.interpreter;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+public class CompiledReader implements QBInterpreterReader {
+
+ @Override
+ public QBInterpreter readFromStream(InputStream in) throws IOException, ClassNotFoundException {
+ return QBInterpreter.readInterpreter(in);
+ }
+
+}
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/core/interpreter/CompressedReader.java b/project/QBarInterpreter/src/com/modulus/qbar/core/interpreter/CompressedReader.java
new file mode 100644
index 0000000..dffe06c
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/core/interpreter/CompressedReader.java
@@ -0,0 +1,13 @@
+package com.modulus.qbar.core.interpreter;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+public class CompressedReader implements QBInterpreterReader {
+
+ @Override
+ public QBInterpreter readFromStream(InputStream in) throws IOException, ClassNotFoundException {
+ return QBInterpreter.readInterpreterCompressed(in);
+ }
+
+}
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/core/interpreter/Main.java b/project/QBarInterpreter/src/com/modulus/qbar/core/interpreter/Main.java
new file mode 100644
index 0000000..cda942f
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/core/interpreter/Main.java
@@ -0,0 +1,217 @@
+package com.modulus.qbar.core.interpreter;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import com.modulus.dataread.expressions.Statement;
+import com.modulus.qbar.core.QBFile;
+import com.modulus.qbar.core.QBFunction;
+import com.modulus.qbar.core.QBObject;
+import com.modulus.qbar.core.parser.AnnotationReader;
+import com.modulus.qbar.core.parser.QBExpressionParser;
+import com.modulus.qbar.core.parser.QBFileType;
+import com.modulus.qbar.core.parser.QBParser;
+import com.modulus.qbar.integration.QBWrappedObject;
+
+public class Main {
+ private static String[] clsPath;
+ private static boolean compile;
+ private static boolean zip;
+ private static boolean debug;
+ private static boolean interactive;
+ private static String file;
+ private static String[] progArgs;
+ public static void main(String[] args){
+ try{
+ if(args.length == 0){
+ printHelp();
+ return;
+ }
+
+ parseArgs(args);
+
+ File f = file == null ? null : QBFile.getQBFile( file );
+
+ if(f != null && f.isDirectory()) {
+ System.out.println("Cannot execute on directory!");
+ printHelp();
+
+ return;
+ }
+
+ QBParser.addAnnotationReader( new AnnotationReader() {
+
+ @Override
+ public void readAnnotation(Statement stmt) {
+ String header = stmt.getHeader().substring(1);
+ if(header.startsWith("infix")){
+ header = header.substring(5).trim();
+
+ String[] headers = header.split("\\s+");
+ int prec = 30;
+ String op;
+
+ if(headers.length == 2){
+ prec = Integer.parseInt(headers[1]);
+ }
+
+ op = headers[0];
+ QBExpressionParser.mapOp(op, prec);
+ }
+ }
+ });
+
+ // System.out.println("Hello?");
+
+ if( compile ){
+ compile(f, zip);
+ } else if(interactive) {
+ QBInteractiveInterpreter interpreter = new QBInteractiveInterpreter();
+ interpreter.startInterpreter();
+ } else{
+ go(f);
+ }
+
+ } catch(Exception e){
+ e.printStackTrace();
+ }
+ }
+
+ public static void go( File f ) throws Exception{
+ QBInterpreter interpreter = openFile(f);
+
+ long time = 0, time2 = 0;
+ if(debug){
+ System.out.println("Namespace: " + interpreter.getGlobalNamespace().toString2());
+ time = System.currentTimeMillis();
+ }
+
+ QBFunction func = (QBFunction) interpreter.getGlobalNamespace().get("main");
+ QBObject finish = func.execute(new QBObject[]{});
+
+ if(debug){
+ time2 = System.currentTimeMillis();
+ System.out.println("Result: " + finish);
+ System.out.println("Total time: " + (time2 - time) / 1000.0 + " seconds");
+
+ System.out.println("Time spent on one method: " + QBObject.totalTime / 1000.0 + " seconds");
+ }
+ }
+
+ public static void compile( File f, boolean zip ) throws Exception{
+ QBInterpreter interpreter = openFile(f);
+
+ String str = f.getName();
+ int idx = str.lastIndexOf('.');
+ if (idx >= 0) {
+ str = str.substring(0,idx);
+ }
+
+ if(zip) {
+ str += ".qbz";
+ } else {
+ str += ".qbc";
+ }
+
+ File newFile = new File(str);
+ OutputStream out = new FileOutputStream(newFile);
+
+ if( zip ) {
+ interpreter.writeSelfCompressed(out);
+ } else {
+ interpreter.writeSelf(out);
+ }
+ }
+
+ private static void parseArgs(String[] args) {
+ List<String> path = new ArrayList<String>();
+
+ path.add(".");
+
+ for( int i = 0; i < args.length; i++) {
+ String str = args[i];
+ if(str.startsWith("-")) {
+ if(str.equals("-p") || str.equals("--path")) {
+ if( i == args.length ) {
+ System.err.println("--path takes 1 argument");
+ System.exit(1);
+ }
+
+ String pathArg = args[ ++i ];
+ String[] paths = pathArg.split(";");
+ path.addAll( Arrays.asList(paths) );
+ } else if( str.equals("-c") || str.equals("--compile") ){
+ if(compile)
+ warn("compiling already enabled");
+
+ compile = true;
+ } else if( str.equals("-z") || str.equals("--zip") ){
+ if(compile)
+ warn("compiling already enabled");
+ if(zip)
+ warn("zipping already enabled");
+
+ compile = true;
+ zip = true;
+ } else if( str.equals("--debug") ){
+ debug = true;
+ } else if( str.equals("-i") ) {
+ interactive = true;
+ } else {
+ System.err.println("Illegal option " + str);
+ }
+ } else {
+ progArgs = new String[ args.length - i ];
+ System.arraycopy(args, i, progArgs, 0, progArgs.length);
+ file = progArgs[0];
+ break;
+ }
+ }
+
+ clsPath = path.toArray(new String[path.size()]);
+ }
+
+ private static void printHelp() {
+ System.out.println("QBarInterpreter v. 0.028 BETA (More Like DELTA)\nUsage: qbar [ -p [CLASSPATH] ] [FILENAME]\nExecutes a qbar " +
+ "file using the classpath defined as the search path for modules\n\nInterpreter executes the `main` function of" +
+ " the file.\nOptions:\n\n\t-p : add a path to the classpath\n\t-c : compile source file\n\t-z : compile source file and zip it\n\t--debug : enable debugging mode (for development)" + "\n\nAuthor: Josh Rahm");
+ }
+
+ public static void warn(String str){
+ System.out.println("[Warn] " + str);
+ }
+
+ public static QBInterpreter openFile( File f ) throws Exception{
+ QBFileType type = QBFileType.getFileType( f.getName() );
+ return type.getReader().readFromStream( new FileInputStream(f) );
+ }
+
+ public static String[] getPath() {
+ return clsPath;
+ }
+
+ public static void debug(Class<?> cls, String str){
+ if( debug ){
+ System.out.println("[DEBUG] - " + cls.getSimpleName() + " - " + str);
+ }
+ }
+
+ public static void prettyThrow( RuntimeException e ){
+ if( debug ) {
+ throw e;
+ }
+
+ List<String> lines = new ArrayList<String>();
+ List<String> messages = new ArrayList<String>();
+
+ Exception cur = e;
+ while( cur != null ) {
+ messages.add("cur");
+ }
+ }
+}
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/core/interpreter/QBInteractiveInterpreter.java b/project/QBarInterpreter/src/com/modulus/qbar/core/interpreter/QBInteractiveInterpreter.java
new file mode 100644
index 0000000..d748d40
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/core/interpreter/QBInteractiveInterpreter.java
@@ -0,0 +1,113 @@
+package com.modulus.qbar.core.interpreter;
+
+import java.io.BufferedReader;
+import java.io.Console;
+import java.io.IOException;
+import java.io.InputStreamReader;
+
+import com.modulus.dataread.expressions.Statement;
+import com.modulus.qbar.core.QBObject;
+import com.modulus.qbar.core.QBSyntheticFunction;
+import com.modulus.qbar.core.parser.ByteOperation;
+import com.modulus.qbar.core.parser.QBParser;
+import com.modulus.qbar.core.parser.stmt.QBStatement;
+import com.modulus.qbar.lang.QBMaybe;
+
+public class QBInteractiveInterpreter extends QBInterpreter{
+ private BufferedReader console;
+ private QBParser parser;
+ private QBStatement alwaysSuper = new QBStatement( QBParser.formatter );
+ public static void main(String[] args) {
+ QBInteractiveInterpreter interpreter = new QBInteractiveInterpreter();
+ interpreter.startInterpreter();
+ }
+
+ public QBInteractiveInterpreter(){
+ super();
+
+ alwaysSuper.setHeader("let tmp = do");
+
+ console = new BufferedReader( new InputStreamReader( System.in ) );
+ this.parser = new QBParser( this );
+ }
+
+ public void startInterpreter(){
+ while(true){
+ try{
+ TransparentFunction func = readStatement();
+ QBObject ret = func.execute(new QBObject[]{});
+
+ if( ret == null )
+ ret = QBMaybe.new$0x20Null();
+
+ System.out.println("?: " + ret);
+ this.getGlobalNamespace().set("ans", ret);
+
+ } catch(Exception e){
+ e.printStackTrace();
+ }
+ }
+ }
+
+ private int depth = 0;
+ public TransparentFunction readStatement() throws Exception{
+ System.out.print(">>> ");
+ StringBuffer tot = new StringBuffer();
+
+ tot.append(readLine());
+ while(tot.length() == 0){
+ System.out.print(">>> ");
+ tot.append(readLine());
+ }
+
+ while( depth > 0 ) {
+ System.out.print("... ");
+ tot.append(readLine());
+ }
+
+ QBStatement sup = alwaysSuper.clone();
+ sup.clearChildren();
+ QBStatement tmp;
+
+ try{
+ tmp = parser.parseCode(tot.toString());
+ } catch( RuntimeException e ) {
+ tmp = parser.parseCode( tot.toString() + ";" );
+ }
+
+ for( Statement stmt : tmp.getChildren()){
+ sup.addChild(stmt);
+ }
+
+ return new TransparentFunction(sup, parser, this);
+ }
+
+ public String readLine() throws IOException{
+ String ret = console.readLine();
+
+ if( ret == null ) {
+ System.out.println("Goodbye.");
+ System.exit(0);
+ }
+
+ int quotes = 0;
+
+ for( int i = 0;i < ret.length();i++) {
+ if(ret.charAt(i) == '"')
+ quotes ++;
+
+ if(quotes % 2 == 1)
+ continue;
+
+ if(ret.charAt(i) == '{') {
+ depth ++;
+ } else if( ret.charAt(i) == '}') {
+ depth --;
+ }
+ }
+
+ return ret;
+ }
+
+
+}
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/core/interpreter/QBInterpreter.java b/project/QBarInterpreter/src/com/modulus/qbar/core/interpreter/QBInterpreter.java
new file mode 100644
index 0000000..448a901
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/core/interpreter/QBInterpreter.java
@@ -0,0 +1,193 @@
+package com.modulus.qbar.core.interpreter;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+import java.io.Serializable;
+import java.net.MalformedURLException;
+import java.util.zip.GZIPInputStream;
+import java.util.zip.GZIPOutputStream;
+
+import com.modulus.common.collections.Stack;
+import com.modulus.qbar.core.QBFunction;
+import com.modulus.qbar.core.QBNamespace;
+import com.modulus.qbar.core.QBObject;
+import com.modulus.qbar.core.QBStruct;
+import com.modulus.qbar.core.QBUtilityNamespace;
+import com.modulus.qbar.core.parser.Core;
+import com.modulus.qbar.core.parser.QBParser;
+import com.modulus.qbar.core.primitive.QBChar;
+import com.modulus.qbar.core.primitive.QBDouble;
+import com.modulus.qbar.core.primitive.QBInt;
+import com.modulus.qbar.core.primitive.QBPrimitive;
+
+public class QBInterpreter implements Serializable{
+ /**
+ *
+ */
+ private static final long serialVersionUID = 3717481804592061086L;
+ private static QBInterpreter instance;
+ private Core core;
+ private transient QBParser parser;
+ private QBJarLoader loader;
+
+ private static class QBThread extends Thread{
+ private QBInterpreter instance;
+
+ public QBThread( QBInterpreter cur ){
+ this.instance = cur;
+ }
+
+ public QBInterpreter instance(){
+ return instance;
+ }
+ }
+
+ public QBThread run(){
+
+ QBThread thread = new QBThread(this){
+ public void run(){
+ QBFunction main = (QBFunction) core.getGlobalNamespace().get("main");
+ main.execute(new QBObject[]{});
+ }
+ };
+
+
+ thread.start();
+ return thread;
+ }
+
+ public static QBInterpreter instance(){
+ Thread t = Thread.currentThread();
+
+ if( t instanceof QBThread )
+ return ((QBThread) t).instance();
+
+ return instance;
+ }
+
+ public QBInterpreter( String code ){
+ try {
+ loader = new QBJarLoader("/usr/lib/qbar/lib/endorsed");
+ } catch (MalformedURLException e) {
+ e.printStackTrace();
+ }
+
+ parser = new QBParser( this );
+
+ instance = this;
+
+ this.core = parser.getSystemCore();
+ loadLang();
+
+ parser.parseCode(code);
+
+
+ parser.resetCore();
+
+ this.getGlobalNamespace().set("Null", new QBObject(null));
+ ((QBUtilityNamespace) this.getGlobalNamespace()).setStruct( new QBStruct("NamespaceUtility") );
+
+
+ }
+
+ protected QBInterpreter(){
+ try {
+ loader = new QBJarLoader("/usr/lib/qbar/lib/endorsed");
+ } catch (MalformedURLException e) {
+ e.printStackTrace();
+ }
+
+ instance = this;
+ this.core = new Core();
+
+ loadLang();
+ this.getGlobalNamespace().set("Null", new QBObject(null));
+ ((QBUtilityNamespace) this.getGlobalNamespace()).setStruct( new QBStruct("NamespaceUtility") );
+ }
+
+ public QBNamespace getGlobalNamespace(){
+ return core.getGlobalNamespace();
+ }
+
+ public Stack<QBObject> getStack(){
+ return core.getStack();
+ }
+
+ public void merge(QBInterpreter other){
+ this.core.merge(other.core);
+ }
+ public void writeSelf( OutputStream out ) throws IOException{
+ this.core.writeSelf( out );
+ }
+
+ public static QBInterpreter readInterpreter( InputStream in ) throws IOException, ClassNotFoundException{
+ QBInterpreter ret = new QBInterpreter();
+
+ ret.parser = new QBParser( ret );
+ ret.core = new Core();
+
+ ret.core.readSelf( in );
+
+ return ret;
+ }
+
+ public void writeSelfCompressed(final OutputStream out) throws IOException{
+ GZIPOutputStream zipOut = new GZIPOutputStream(out);
+ writeSelf(zipOut);
+ }
+
+ public static QBInterpreter readInterpreterFromSource( InputStream in ) throws IOException{
+ BufferedReader reader = new BufferedReader( new InputStreamReader( in ) );
+ StringBuffer buf = new StringBuffer();
+
+ String line;
+ boolean begin = true;
+ while((line = reader.readLine()) != null){
+ if(begin && line.startsWith("#"))
+ continue;
+
+ buf.append(line + "\n");
+
+ if(begin && line.trim() != "")
+ begin = false;
+ }
+
+ QBInterpreter old = instance();
+ QBInterpreter interpreter = new QBInterpreter(buf.toString());
+
+ if(old != null)
+ instance = old;
+
+ return interpreter;
+ }
+
+ public static QBInterpreter readInterpreterCompressed( InputStream in ) throws IOException, ClassNotFoundException{
+ GZIPInputStream zipIn = new GZIPInputStream(in);
+ return readInterpreter(zipIn);
+ }
+
+ private void loadLang(){
+ QBNamespace global = core.getGlobalNamespace();
+
+ global.set(QBInt.struct.getName(), QBInt.struct);
+ global.set(QBDouble.struct.getName(), QBDouble.struct);
+ global.set(QBChar.struct.getName(), QBChar.struct);
+ global.set(QBPrimitive.struct.getName(), QBPrimitive.struct);
+
+ }
+
+ public QBParser getParser() {
+ return parser;
+ }
+
+ public ClassLoader getClassLoader() {
+ return loader.getLoader();
+ }
+
+}
+
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/core/interpreter/QBInterpreterReader.java b/project/QBarInterpreter/src/com/modulus/qbar/core/interpreter/QBInterpreterReader.java
new file mode 100644
index 0000000..b9e18f1
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/core/interpreter/QBInterpreterReader.java
@@ -0,0 +1,7 @@
+package com.modulus.qbar.core.interpreter;
+
+import java.io.InputStream;
+
+public interface QBInterpreterReader{
+ QBInterpreter readFromStream( InputStream in ) throws Exception;
+}
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/core/interpreter/QBJarLoader.java b/project/QBarInterpreter/src/com/modulus/qbar/core/interpreter/QBJarLoader.java
new file mode 100644
index 0000000..a02c438
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/core/interpreter/QBJarLoader.java
@@ -0,0 +1,49 @@
+package com.modulus.qbar.core.interpreter;
+
+import java.io.File;
+import java.io.FilenameFilter;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+import java.util.List;
+
+public class QBJarLoader {
+ private ClassLoader loader;
+
+ public QBJarLoader( String dir ) throws MalformedURLException{
+ this( new File(dir) );
+ }
+
+ public QBJarLoader( File dir ) throws MalformedURLException{
+ loader = new URLClassLoader( listJarUrls(dir), ClassLoader.getSystemClassLoader() );
+ }
+
+ public void load(){
+ }
+
+ public ClassLoader getLoader(){
+ return loader;
+ }
+
+ private URL[] listJarUrls( File dir ) throws MalformedURLException{
+ if( dir.isFile() ){
+ return new URL[]{ dir.toURI().toURL() };
+ } else {
+ File[] files = dir.listFiles( new FilenameFilter() {
+
+ @Override
+ public boolean accept(File dir, String name) {
+ return name.endsWith(".jar");
+ }
+ });
+
+ URL[] ret = new URL[ files.length ];
+
+ for( int i = 0;i < files.length; i ++)
+ ret[i] = files[i].toURI().toURL();
+
+ return ret;
+ }
+ }
+}
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/core/interpreter/SourceReader.java b/project/QBarInterpreter/src/com/modulus/qbar/core/interpreter/SourceReader.java
new file mode 100644
index 0000000..db0e204
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/core/interpreter/SourceReader.java
@@ -0,0 +1,13 @@
+package com.modulus.qbar.core.interpreter;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+public class SourceReader implements QBInterpreterReader {
+
+ @Override
+ public QBInterpreter readFromStream(InputStream in) throws IOException {
+ return QBInterpreter.readInterpreterFromSource(in);
+ }
+
+}
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/core/interpreter/TransparentFunction.java b/project/QBarInterpreter/src/com/modulus/qbar/core/interpreter/TransparentFunction.java
new file mode 100644
index 0000000..7400f88
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/core/interpreter/TransparentFunction.java
@@ -0,0 +1,24 @@
+package com.modulus.qbar.core.interpreter;
+import com.modulus.qbar.core.QBObject;
+import com.modulus.qbar.core.QBSyntheticFunction;
+import com.modulus.qbar.core.parser.QBParser;
+import com.modulus.qbar.core.parser.stmt.QBStatement;
+
+public class TransparentFunction extends QBSyntheticFunction {
+ private QBInteractiveInterpreter ths;
+ public TransparentFunction(QBStatement code, QBParser parser, QBInteractiveInterpreter ths) {
+ super(code, parser);
+ this.ths = ths;
+ }
+
+ @Override
+ public QBObject get( String name ){
+ return ths.getGlobalNamespace().get( name );
+ }
+
+ @Override
+ public void set( String name, QBObject obj ) {
+ ths.getGlobalNamespace().set(name, obj);
+ }
+
+} \ No newline at end of file
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/core/parser/AnnotationReader.java b/project/QBarInterpreter/src/com/modulus/qbar/core/parser/AnnotationReader.java
new file mode 100644
index 0000000..45b6b0a
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/core/parser/AnnotationReader.java
@@ -0,0 +1,7 @@
+package com.modulus.qbar.core.parser;
+
+import com.modulus.dataread.expressions.Statement;
+
+public interface AnnotationReader {
+ void readAnnotation( Statement stmt );
+}
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/core/parser/ByteOperation.java b/project/QBarInterpreter/src/com/modulus/qbar/core/parser/ByteOperation.java
new file mode 100644
index 0000000..20e7cae
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/core/parser/ByteOperation.java
@@ -0,0 +1,43 @@
+package com.modulus.qbar.core.parser;
+
+import java.io.Serializable;
+import java.util.Arrays;
+
+import com.modulus.qbar.core.compile.ByteOps;
+
+public class ByteOperation implements Serializable{
+ /**
+ *
+ */
+ private static final long serialVersionUID = 8120121479968460423L;
+ private ByteOps operator;
+ private Object[] args = {null};
+
+ public ByteOperation(ByteOps op, Object arg){
+ this.operator = op;
+ this.args = new Object[]{arg};
+ }
+
+ public ByteOperation(ByteOps op, Object[] args){
+ this.operator = op;
+
+ if(args.length > 0)
+ this.args = args;
+ }
+
+ public ByteOps getOperator(){
+ return operator;
+ }
+
+ public Object[] getArgs(){
+ return args;
+ }
+
+ public Object getArg(){
+ return args[0];
+ }
+
+ public String toString(){
+ return operator.toString() + " " + Arrays.toString(args);
+ }
+}
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/core/parser/Core.java b/project/QBarInterpreter/src/com/modulus/qbar/core/parser/Core.java
new file mode 100644
index 0000000..a10c530
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/core/parser/Core.java
@@ -0,0 +1,78 @@
+package com.modulus.qbar.core.parser;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+import java.io.Serializable;
+import java.util.HashMap;
+
+import com.modulus.common.collections.ArrayStack;
+import com.modulus.common.collections.Stack;
+import com.modulus.qbar.core.QBNamespace;
+import com.modulus.qbar.core.QBObject;
+import com.modulus.qbar.core.QBStruct;
+import com.modulus.qbar.core.QBUtilityNamespace;
+import com.modulus.qbar.core.primitive.QBPrimitive;
+
+public class Core implements Serializable{
+ /**
+ *
+ */
+ private static final long serialVersionUID = 2963257754134148521L;
+ private QBUtilityNamespace globalNamespace;
+ private Stack<QBObject> stack;
+
+ public Core(){
+ this.globalNamespace = new QBUtilityNamespace( null ){
+ private static final long serialVersionUID = 3278462104573891204L;
+ private String name = "Global";
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public void construct() {
+ }
+
+ };
+
+ this.stack = new ArrayStack<QBObject>();
+ }
+
+ public QBNamespace getGlobalNamespace(){
+ return globalNamespace;
+ }
+
+ public Stack<QBObject> getStack(){
+ return stack;
+ }
+
+ public void merge(Core other){
+ this.globalNamespace.incoporate( other.getGlobalNamespace() );
+ }
+
+ public static boolean QBObjectIsTrue(QBObject obj){
+ return obj instanceof QBPrimitive && ((QBPrimitive) obj).intValue() != 0;
+ }
+
+ public void writeSelf(OutputStream out) throws IOException {
+ ObjectOutputStream oout = new ObjectOutputStream(out);
+
+
+ oout.writeObject( globalNamespace );
+ oout.flush();
+ oout.close();
+ }
+
+ public void readSelf(InputStream in) throws IOException, ClassNotFoundException {
+ ObjectInputStream oin = new ObjectInputStream(in);
+ Object ret = oin.readObject();
+
+ oin.close();
+
+ this.globalNamespace = (QBUtilityNamespace) ret;
+ }
+}
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/core/parser/ExpressionCompiler.java b/project/QBarInterpreter/src/com/modulus/qbar/core/parser/ExpressionCompiler.java
new file mode 100644
index 0000000..7a62366
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/core/parser/ExpressionCompiler.java
@@ -0,0 +1,62 @@
+package com.modulus.qbar.core.parser;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.modulus.dataread.expressions.ExpressionPart;
+import com.modulus.qbar.core.compile.ByteOps;
+import com.modulus.qbar.core.primitive.QBDouble;
+import com.modulus.qbar.core.primitive.QBInt;
+
+public class ExpressionCompiler {
+ private QBExpressionParser parser = new QBExpressionParser();
+ public ExpressionCompiler(){
+
+ }
+
+ public ByteOperation[] compile( String expression ){
+// System.out.println("EXP: "+expression);
+ List<ByteOperation> ret = new ArrayList<ByteOperation>();
+
+ ExpressionPart part = parser.parseExpressions(expression);
+ String compiled = part.compilePart();
+
+ String[] split = compiled.split("\\s+");
+
+ for ( String str : split ){
+ if(str.length() > 0){
+ if (str.startsWith("<-",1) ){
+ ByteOperation tmp = ret.remove(ret.size()-1);
+ ret.add( new ByteOperation(ByteOps.STO, tmp.getArgs() ) );
+ } else if (str.startsWith("->",1) ){
+ ByteOperation tmp = ret.remove(ret.size()-1);
+ ret.add( new ByteOperation(ByteOps.ITR, tmp.getArgs() ) );
+ } else if(str.charAt(0) == '\u00FF'){
+ ret.add( new ByteOperation(ByteOps.CALL, str.substring(1)) );
+ } else if(str.charAt(0) == '\u00FE'){
+ ret.add( new ByteOperation(ByteOps.CALLG, str.substring(1)) );
+ } else {
+
+ if( Character.isDigit( str.charAt(0) ) || (str.charAt(0) == '-' && str.length() > 1 && Character.isDigit(str.charAt(1)) )) {
+ if(str.contains(".") || str.endsWith("d")){
+ if(str.endsWith("d"))
+ str = str.substring(0, str.length() - 1);
+ double dval = Double.parseDouble(str);
+ ret.add(new ByteOperation( ByteOps.PUSHO, new QBDouble(dval) ));
+ } else{
+ if(str.endsWith("i"))
+ str = str.substring(0, str.length() - 1);
+ int dval = Integer.parseInt(str);
+ ret.add(new ByteOperation( ByteOps.PUSHO, new QBInt(dval) ));
+ }
+
+ } else {
+ ret.add( new ByteOperation( ByteOps.PUSH, str.split("\\.") ) );
+ }
+ }
+ }
+ }
+
+ return ret.toArray( new ByteOperation[ret.size()] );
+ }
+}
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/core/parser/ExpressionPuller.java b/project/QBarInterpreter/src/com/modulus/qbar/core/parser/ExpressionPuller.java
new file mode 100644
index 0000000..9618881
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/core/parser/ExpressionPuller.java
@@ -0,0 +1,160 @@
+package com.modulus.qbar.core.parser;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.modulus.common.collections.MArrays;
+import com.modulus.qbar.core.QBFunction;
+import com.modulus.qbar.core.QBNamespace;
+import com.modulus.qbar.core.interpreter.QBInterpreter;
+import com.modulus.qbar.lang.QBString;
+
+public class ExpressionPuller {
+ public static void main(String[] args){
+ String str = "\"Hello, World!\"";
+
+ str = pullStrings(str);
+ System.out.println(str);
+ }
+
+ public static String pullLists(String expression, QBNamespace sup, QBParser parser){
+ String tmp;
+
+ while(!(tmp = replaceOneList(expression, sup, parser)).equals(expression))
+ expression = replaceOneList(tmp, sup, parser);
+
+ return expression;
+ }
+
+ public static String pullStrings(String expression){
+ List<Integer> points = new ArrayList<Integer>();
+ points.add(0);
+
+ for(int i = 0;i < expression.length();i++){
+ if(expression.charAt(i) == '"' && !(i > 0 && expression.charAt(i-1) == '\\') ){
+ int stamp = i;
+ i++;
+ while(expression.charAt(i) != '"'){
+ if(expression.charAt(i) == '\\')
+ i++; // skip the next character
+ i++;
+ }
+
+ points.add( stamp );
+ points.add( i+1 );
+ }
+ }
+ points.add( expression.length() );
+
+ StringBuffer total = new StringBuffer();
+ boolean inString = false;
+ for(int i = 1;i < points.size();i++){
+ int i1 = points.get(i-1);
+ int i2 = points.get(i);
+ // System.out.println("("+i1+", "+i2+")");
+ if(!inString){
+ total.append( expression.substring(i1, i2) );
+ } else{
+ String exp = expression.substring(i1+1, i2-1);
+ int hash = exp.hashCode();
+
+ String name = "$string$"+Math.abs(hash);
+ total.append(name);
+
+ QBString str = new QBString(exp, true);
+ QBInterpreter.instance().getGlobalNamespace().set(name, str);
+ }
+
+ inString = !inString;
+ }
+
+ return total.toString();
+ }
+
+ public static String pullIfThenElse( String[] exp, QBNamespace sup ){
+ exp = fixIfThenElseParts(exp);
+
+
+ int thenIdx = MArrays.indexOf(exp, "then");
+ String ifPart = MArrays.concat(exp, 1, thenIdx-1, " ");
+
+ int elseIdx = MArrays.indexOf(exp, "else");
+ String thenPart = MArrays.concat(exp, thenIdx+1, elseIdx-thenIdx-1, " ");
+ // System.out.println("Pull If Then Else EXP: " + Arrays.toString(exp) + " $ " + elseIdx);
+ String elsePart = MArrays.concat(exp, elseIdx+1, " ");
+
+ QBFunction func = IfThenElseFunctionFactory.makeIfThenElse(ifPart, thenPart, elsePart);
+
+ if(sup != null)
+ func.setSuper(sup);
+
+ String name = "$if$then$else"+ Math.abs((ifPart+elsePart+thenPart).hashCode());
+ QBInterpreter.instance().getGlobalNamespace().set(name, func);
+
+ return name + "()";
+ }
+
+ public static String replaceOneList(String exp, QBNamespace sup, QBParser parser){
+ if(!exp.contains("["))
+ return exp;
+
+ int off = exp.indexOf('[') + 1;
+ off = off == 0 ? 1 : off;
+
+ int bracket = 1;
+ int i;
+
+ for(i = off;bracket != 0 && i < exp.length();i++){
+ if(exp.charAt(i) == '[')
+ bracket ++;
+ else if(exp.charAt(i) == ']')
+ bracket --;
+ }
+
+ String start = exp.substring(0, off-1);
+ String end = exp.substring(i);
+
+ String middle = exp.substring(off-1, i);
+
+ int hash = Math.abs(middle.hashCode());
+ String name = "$list$constructor$"+hash;
+
+ QBFunction func = ListConstructorFactory.makeNewQBListConstructor(middle, sup, parser);
+ QBNamespace global = QBInterpreter.instance().getGlobalNamespace();
+
+ global.set(name, func);
+
+ return start+ name + "()" + end;
+ }
+
+ private static String[] fixIfThenElseParts(String[] ifthenelse){
+ ArrayList<String> strs = new ArrayList<String>();
+
+ for(String s : ifthenelse){
+ if(s.startsWith("if") && s.length() > 2 && !Character.isLetterOrDigit(s.charAt(2))){
+ String str1 = s.substring(0,2);
+ String str2 = s.substring(2);
+
+ strs.add(str1);
+ strs.add(str2);
+ } else if(s.startsWith("then") && s.length() > 4 && !Character.isLetterOrDigit(s.charAt(4))){
+ String str1 = s.substring(0,4);
+ String str2 = s.substring(4);
+
+ strs.add(str1);
+ strs.add(str2);
+ } else if(s.startsWith("else") && s.length() > 4 && !Character.isLetterOrDigit(s.charAt(4))){
+ String str1 = s.substring(0,4);
+ String str2 = s.substring(4);
+
+ strs.add(str1);
+ strs.add(str2);
+ } else{
+ strs.add(s);
+ }
+ }
+
+ return strs.toArray( new String[strs.size()] );
+ }
+
+}
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/core/parser/ExpressionSpaceTokenizer.java b/project/QBarInterpreter/src/com/modulus/qbar/core/parser/ExpressionSpaceTokenizer.java
new file mode 100644
index 0000000..884a2e8
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/core/parser/ExpressionSpaceTokenizer.java
@@ -0,0 +1,106 @@
+package com.modulus.qbar.core.parser;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ExpressionSpaceTokenizer {
+ public static String[] tokenize( String str ){
+ // String Buffer that builds each part of the array
+ StringBuffer cur = new StringBuffer();
+
+ // the list that will be returned in the end
+ List<String> ret = new ArrayList<String>();
+
+ // the level of the parenthesis
+ int parenLevel = 0;
+
+ // loop through the string one by one to split the sections
+ for( int i = 0;i < str.length(); i++){
+ Character ch = str.charAt(i);
+ // check to see if the character is a whitespace char or not
+ boolean whitespace = Character.isWhitespace(ch);
+
+ // see if the character is a symbol or not
+ boolean symbol = isSymbol(ch) ;
+
+ // this will tell the parser if there is a paren that closes a statement
+ boolean close = false;
+
+ // If the character is '(' then we increase the parenthasis
+ if(ch == '('){
+ parenLevel ++;
+ } else if(str.charAt(i) == ')'){
+ // if it is ')' then mark a closing statement (This will make sense at the end)
+ close = true;
+ }
+
+ // if the string is one of these things, then it is time
+ // to split the string.
+ if((whitespace || symbol) && parenLevel == 0){
+
+ // the current string is cut and trimmed
+ String curstr = cur.toString().trim();
+
+ // forget adding the string if it is empty
+ if(curstr.length() > 0)
+ ret.add(curstr);
+
+ // reset the buffer.
+ cur = new StringBuffer();
+
+ // If the character is a symbol, add all following symbols as well
+ if(symbol){
+
+ // add all following symbols
+ while(isSymbol(ch) && i < str.length()){
+ // System.out.println("CHAR "+ch);
+ cur.append(ch);
+ i++;
+ ch = str.charAt(i);
+ }
+
+ // a little redundant, but necessary
+ if(ch == '('){
+ parenLevel ++;
+ } else if(str.charAt(i) == ')'){
+ close = true;
+ }
+
+ curstr = cur.toString().trim();
+ if(curstr.length() > 0)
+ ret.add(curstr);
+ cur = new StringBuffer();
+ }
+
+ // finally add the current character
+ cur.append( ch );
+ } else{
+ cur.append( str.charAt(i) );
+ }
+
+ if(parenLevel < 0){
+ throw new RuntimeException("Expected '('");
+ }
+
+ // here is the part where the close boolean comes in
+ if(close)
+ parenLevel --;
+
+
+ }
+
+ if(parenLevel > 0)
+ throw new RuntimeException("Expected ')'");
+
+ String curstr = cur.toString().trim();
+
+ if(curstr.length() > 0)
+ ret.add(curstr);
+
+ return ret.toArray(new String[ret.size()]);
+ }
+
+ private static boolean isSymbol( char ch ){
+ return !Character.isDigit(ch) && !Character.isLetter(ch) && !Character.isWhitespace(ch) && ch != '(' && ch != ')' && ch != '.' && ch != '$';
+ }
+}
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/core/parser/IfThenElseFunctionFactory.java b/project/QBarInterpreter/src/com/modulus/qbar/core/parser/IfThenElseFunctionFactory.java
new file mode 100644
index 0000000..8c7531e
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/core/parser/IfThenElseFunctionFactory.java
@@ -0,0 +1,16 @@
+package com.modulus.qbar.core.parser;
+
+import com.modulus.qbar.core.QBFunction;
+import com.modulus.qbar.lang.IfThenElseFunction;
+
+public class IfThenElseFunctionFactory {
+ private static ExpressionCompiler compiler = new ExpressionCompiler();
+
+ public static QBFunction makeIfThenElse(String ifPart, String thenPart, String elsePart){
+ ByteOperation[] ifArr = compiler.compile(ifPart);
+ ByteOperation[] thenArr = compiler.compile(thenPart);
+ ByteOperation[] elseArr = compiler.compile(elsePart);
+
+ return new IfThenElseFunction(ifArr, thenArr, elseArr);
+ }
+}
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/core/parser/ListConstructorFactory.java b/project/QBarInterpreter/src/com/modulus/qbar/core/parser/ListConstructorFactory.java
new file mode 100644
index 0000000..f6cc787
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/core/parser/ListConstructorFactory.java
@@ -0,0 +1,160 @@
+package com.modulus.qbar.core.parser;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import com.modulus.qbar.core.QBFunction;
+import com.modulus.qbar.core.QBNamespace;
+import com.modulus.qbar.core.exceptions.ExecutionException;
+import com.modulus.qbar.lang.QBArrayListConstructor;
+import com.modulus.qbar.lang.QBFunctionListConstructor;
+import com.modulus.qbar.lang.QBFunctionListFunction;
+import com.modulus.qbar.lang.QBLazyRangeListConstructor;
+
+public abstract class ListConstructorFactory {
+ private static final ExpressionCompiler compiler = new ExpressionCompiler();
+
+ // DO NOT CUT OUT THE MIDDLE, THE PASSED STRING SHOUDL STILL HAVE THE BRACKETS
+ public static QBFunction makeNewQBListConstructor(String code, QBNamespace sup, QBParser parser){
+ code = code.substring(1, code.length()-1);
+ code = ExpressionPuller.pullLists(code, sup, parser);
+ if(code.contains(".."))
+ return makeForLazyRangeList(code, sup);
+
+ else if(code.contains("|")){
+ if(code.contains("->")){}
+ else{
+ return makeFunctionList(code, sup, parser);
+ }
+ }
+
+ return makeForStandardArrayList(code, sup, parser);
+ }
+
+ private static QBFunction makeFunctionList(String code, QBNamespace sup, QBParser parser) {
+ String[] split = code.split("\\|");
+
+ if(split.length != 2)
+ throw new ExecutionException("Error parsing function list, invalid syntax, expected [index|<something with index here>]");
+
+ String var = split[0].trim();
+ String exp = split[1].trim();
+
+
+
+ QBNamespace tmp = parser.getCurrentCompilingNamespace();
+ QBFunctionListFunction func = new QBFunctionListFunction();
+ parser.setCurrentCompilingNamespace(func);
+
+ ByteOperation[] compiled = compiler.compile(exp);
+
+ parser.setCurrentCompilingNamespace(tmp);
+ func.setVar(var);
+ func.setCommand(compiled);
+
+ QBFunction ret = new QBFunctionListConstructor(func);
+
+ if(sup != null)
+ ret.setSuper(sup);
+
+ return ret;
+ }
+
+ private static QBFunction makeForStandardArrayList(String code,
+ QBNamespace sup, QBParser parser) {
+ QBFunction ret;
+ // System.out.println("CODE " + code);
+ if(code.length() > 0){
+ String[] exps = splitComma(code);
+ // System.out.println("EXPS: " + Arrays.toString(exps));
+
+ ByteOperation[][] operations = new ByteOperation[exps.length][];
+
+ for(int i = 0;i < exps.length;i++){
+ exps[i] = ExpressionPuller.pullLists(exps[i], sup, parser);
+ operations[i] = compiler.compile(exps[i]);
+ }
+
+ ret = new QBArrayListConstructor(operations);
+ } else{
+ ret = new QBArrayListConstructor(new ByteOperation[][]{});
+ }
+ if(sup != null)
+ ret.setSuper(sup);
+
+ return ret;
+ }
+
+ // NOW THE BRACKETS CAN BE CUT
+ private static QBFunction makeForLazyRangeList(String code, QBNamespace sup){
+ String[] split = code.split("\\s*\\.\\.\\s*");
+
+ if(split.length > 2 || split.length < 1)
+ throw new ExecutionException("Error executing, syntax error on list");
+
+ String[] change = splitComma(split[0]);
+ String num;
+
+ if(split.length > 1)
+ num = split[1];
+ else
+ num = "";
+
+ //System.out.println("SPLIT: " + Arrays.toString(split) + "\nCHANGE: " + Arrays.toString(change) + "\nNUM: " + num);
+
+ ByteOperation[] start = compiler.compile(change[0]);
+ ByteOperation[] second = change.length > 1 ? compiler.compile(change[1]) : null;
+ ByteOperation[] end = num.length() > 0 ? compiler.compile(num) : null;
+
+ QBFunction ret = new QBLazyRangeListConstructor(start, second, end);
+
+ if(sup != null)
+ ret.setSuper(sup);
+
+ return ret;
+ }
+
+ private static final String[] splitComma(String str){
+ int bracket = 0;
+ int brace = 0;
+ int paren = 0;
+ ArrayList<String> ret = new ArrayList<String>();
+
+ StringBuffer buf = new StringBuffer();
+ for(int i = 0;i < str.length();i++){
+ if(str.charAt(i) == ','){
+ if( bracket == paren && brace == paren && paren == 0){
+ ret.add(buf.toString());
+ buf = new StringBuffer();
+ } else{
+ buf.append(str.charAt(i));
+ }
+ } else{
+ switch((int)str.charAt(i)){
+ case (int)'[':
+ bracket ++;
+ break;
+ case (int)'{':
+ brace++;
+ break;
+ case (int)'(':
+ paren ++;
+ break;
+ case (int)']':
+ bracket --;
+ break;
+ case (int)'}':
+ brace--;
+ break;
+ case (int)')':
+ paren --;
+ }
+
+ buf.append(str.charAt(i));
+ }
+ }
+ ret.add(buf.toString());
+
+ return ret.toArray(new String[ret.size()]);
+ }
+}
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/core/parser/QBExpressionParser.java b/project/QBarInterpreter/src/com/modulus/qbar/core/parser/QBExpressionParser.java
new file mode 100644
index 0000000..46fc826
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/core/parser/QBExpressionParser.java
@@ -0,0 +1,341 @@
+package com.modulus.qbar.core.parser;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+import com.modulus.common.collections.MArrays;
+import com.modulus.dataread.expressions.ExpressionParser;
+import com.modulus.dataread.expressions.ExpressionPart;
+import com.modulus.qbar.core.interpreter.QBInterpreter;
+import com.modulus.qbar.lang.QBList;
+
+/**
+ * This class is most of the guts for compiling the source code
+ * into a hybrid of interpreted and byte code, this is used to promote
+ * a high degree of efficiency as well as maintain a high level
+ * of programming.
+ *
+ * From here, the resulting code can then be fed into an interpreter
+ * to be interpreted using a stack and heap, like most of the other
+ * programming languages.
+ *
+ * This class is the main part of the language.
+ *
+ * @author jrahm
+ *
+ */
+public class QBExpressionParser implements ExpressionParser{
+ private static Map<Integer, List<String> > operatorPrecedence = new HashMap<Integer, List<String>>();
+
+ /*
+ * Need to puting some of the `natural` functions
+ * with their respective precedence related to one and other.
+ */
+ static{
+ QBList.init();
+ mapOp("#", 9); // POW
+ mapOp("as", 9); // POW
+ mapOp("isa", 9); // POW
+
+ mapOp("^", 10); // POW
+ mapOp("*", 20); // MUL
+ mapOp("/", 20); // DIV
+ mapOp("div", 20); // DIVI
+ mapOp("%", 20); // MOD
+ mapOp("+", 30); // ADD
+ mapOp("++", 30); // ADD
+ mapOp("-", 30); // SUB
+
+ mapOp("<", 128); // STO
+ mapOp(">", 128); // STO
+ mapOp("<=", 128); // STO
+ mapOp(">=", 128); // STO
+ mapOp("==", 128); // STO
+ mapOp("!=", 128); // STO
+
+ mapOp("not", 512); // STO
+ mapOp("xor", 512); // STO
+ mapOp("or", 512); // STO
+ mapOp("and", 512); // STO
+
+ mapOp("<-", 1024); // STO
+ mapOp("->", 1024); // STO
+ }
+
+ public static void main(String[] args){
+ QBExpressionParser parser = new QBExpressionParser();
+ ExpressionPart exp = parser.parseExpressions("4 + 5 - (if (5+1) then (4+2) else (3+3))");
+ System.out.println(exp.compilePart());
+ }
+
+ @Override
+ public ExpressionPart parseExpressions(String exp) {
+ String[] strs = ExpressionSpaceTokenizer.tokenize(exp);
+ return parseExpressions(strs, QBInterpreter.instance().getParser() );
+ }
+
+ /**
+ * This function further parses from a String[], unlike its
+ * counterpart which uses just a String to parse.
+ *
+ * @param exp the expression to parse
+ * @return an ExpressionPart that represents this code
+ */
+ public ExpressionPart parseExpressions (String[] exp, QBParser parser) {
+ exp = fixArray(exp);
+ // System.out.println("EXPS: " + Arrays.toString(exp));
+ if(exp[0].startsWith("if")){
+ if( (exp[0].length() > 2 && !Character.isLetterOrDigit( exp[0].charAt(2) )) || exp[0].length() == 2){
+ String name = ExpressionPuller.pullIfThenElse(exp, parser.getCurrentCompilingNamespace());
+ exp = new String[]{name};
+ }
+ }
+
+// if(exp[0].equals("if")){
+// int thenIdx = MArrays.indexOf(exp, "then");
+// String ifPart = MArrays.concat(exp, 1, thenIdx-1);
+//
+// int elseIdx = MArrays.indexOf(exp, "else");
+// String thenPart = MArrays.concat(exp, thenIdx+1, elseIdx-thenIdx-1);
+//
+// String elsePart = MArrays.concat(exp, elseIdx+1);
+//
+// ExpressionPart ifExpPart = parseExpressions(ifPart);
+// ExpressionPart thenExpPart = parseExpressions(thenPart);
+// ExpressionPart elseExpPart = parseExpressions(elsePart);
+//
+// ExpressionPart totalIf = ExpressionPart.makePrimaryExpressionPart(null, "if", new ExpressionPart[]{ifExpPart});
+// ExpressionPart totalThen = ExpressionPart.makePrimaryExpressionPart(totalIf, "then", new ExpressionPart[]{thenExpPart});
+// ExpressionPart total = ExpressionPart.makePrimaryExpressionPart(totalThen, "else", new ExpressionPart[]{elseExpPart});
+//
+// return total;
+// }
+
+
+ // Go though all of the operators in order from their respective order of operations.
+ for( String[] ops : operators() ){
+
+ int idx = -1;
+ // Some operators have the same precedence, so we need to deal with that
+ for( String op : ops ) {
+ idx = Math.max(idx, MArrays.lastIndexOf(exp, op));
+ }
+
+ // if we found one of these opeartors, then we
+ // need to deal with it.
+ if( idx != -1 ){
+ // get the function (thats easy, it is what we just found)
+ String function = exp[idx];
+
+ // get all stuff before and after this point
+ // the first is the caller and the second is the
+ // argument believe me it works because
+ // 3 * 4 / 6 + 1 * 2 - 3 ^ 2 * 2 = (3 * 4 / 6 + 1 * 2) - (3 ^ 2 * 2)
+ String[] before = Arrays.copyOfRange(exp, 0, idx);
+ String[] after = Arrays.copyOfRange(exp, idx + 1, exp.length);
+
+ // now, using recursion we make the expression parts out of them
+ ExpressionPart part1 = parseExpressions( before, parser );
+ ExpressionPart part2 = parseExpressions( after, parser );
+
+ if(function.equals("->")){
+ ExpressionPart tmp = part1;
+ part1 = part2;
+ part2 = tmp;
+ }
+ // now put the whole thing together, and you now have a mess
+ return ExpressionPart.makePrimaryExpressionPart(part1, function, new ExpressionPart[]{part2} );
+ }
+
+
+ }
+
+ // If there are no more "Binary Functions"
+ // what is left must be grouped or it must be a function
+ if( exp.length == 1 ){
+ String str = exp[0];
+ if( completelySurrounded(str) ){
+ String middle = str.substring(1, str.length() - 1);
+ return parseExpressions(middle);
+ }
+ // This must then be a function
+ else if(str.endsWith(")")){
+
+ // this function will get the last index of a dot ('.') that is outside parenthesis
+ // the dot is used to determine if the function is being called by an object
+ int dotIdx = lastDotIndex(str);
+
+ // now we find the index that the arguments start on
+ int idx = str.indexOf('(',dotIdx);
+
+ // check to make sure there is one.
+ if( idx < 0 ){
+ throw new RuntimeException("Expected '('");
+ }
+
+ // from here it is pretty straight forward to get the function,
+ // caller and parameters.
+ String function = str.substring(0, idx);
+ String args = str.substring(idx + 1, str.length() - 1);
+ String caller = null;
+
+ // if there is not dot, then there is no caller and the function is global
+ if( dotIdx >= 0 ){
+ caller = function.substring( 0, dotIdx );
+ function = function.substring( dotIdx + 1 );
+ }
+
+ // now use recursion to build the parts and make a new part.
+ ExpressionPart part1 = caller !=null ? parseExpressions(caller) : null;
+ ExpressionPart[] parts = parseParams(args);
+
+ return ExpressionPart.makePrimaryExpressionPart(part1, function, parts);
+
+ }
+
+ else{
+ // This is the base case, the very bottom of the ladder, this is where all
+ // that is left is some entity that has no function.
+ return ExpressionPart.makeExpressionPart(exp[0]);
+ }
+ }
+
+ throw new RuntimeException("Syntax Error");
+ }
+
+ private ExpressionPart[] parseParams( String params ){
+ params = params.trim();
+ if(params.length() == 0)
+ return new ExpressionPart[]{};
+
+ String[] split = splitParam(params);
+ ExpressionPart[] parts = new ExpressionPart[split.length];
+
+ for ( int i = 0;i < split.length; i++ ){
+ parts[i] = parseExpressions(split[i]);
+ }
+
+ // Might need this
+ //Collections.reverse( Arrays.asList(parts) );
+ return parts;
+ }
+
+ private static String[] splitParam( String params ){
+ int paramIdx = 0;
+ StringBuffer cur = new StringBuffer();
+ List<String> ret = new ArrayList<String>();
+
+ for( int i = 0;i < params.length(); i++){
+ char ch = params.charAt(i);
+ if(ch == '(')
+ paramIdx ++;
+
+ else if( ch == ')' )
+ paramIdx --;
+
+ if( paramIdx < 0 )
+ throw new RuntimeException("Expected '('");
+
+ if( ch == ',' && paramIdx == 0 ){
+ ret.add(cur.toString());
+ cur = new StringBuffer();
+ } else{
+ cur.append(ch);
+ }
+ }
+
+ ret.add(cur.toString());
+
+ return ret.toArray(new String[ret.size()]);
+ }
+
+ private String[] fixArray(String[] exp){
+ List<String> arr = new ArrayList<String>();
+ boolean last = true;
+ for(int i = 0;i < exp.length;i ++){
+ if( isDigit(exp[i]) ){
+ last = true;
+ } else{
+ if(!last && exp[i].equals("-")){
+ exp[i+1] = "-" + exp[i+1];
+ exp[i] = "";
+ }
+
+ last = false;
+ }
+ if(exp[i].length() > 0)
+ arr.add(exp[i]);
+ }
+
+ return arr.toArray(new String[arr.size()]);
+ }
+
+ private boolean isDigit(String exp){
+ return Pattern.matches("(\\d|\\w|\\.)+",exp);
+ }
+
+ public static void mapOp(String op, Integer prec){
+ List<String> lst = operatorPrecedence.get(prec);
+
+ if(lst == null){
+ lst = new ArrayList<String>();
+ operatorPrecedence.put(prec, lst);
+ }
+
+ lst.add(op);
+ }
+
+ private static List<String[]> operators(){
+ List<String[]> lst = new ArrayList<String[]>();
+ Collection<Integer> keys = operatorPrecedence.keySet();
+ List<Integer> keyList = new ArrayList<Integer>();
+
+ keyList.addAll(keys);
+ Collections.sort(keyList);
+ Collections.reverse(keyList);
+
+ for (Integer i : keyList){
+ List<String> temp = operatorPrecedence.get(i);
+ lst.add( temp.toArray( new String[temp.size()] ));
+ }
+
+ return lst;
+ }
+
+ private static boolean completelySurrounded( String str ){
+ int paramIdx = 0;
+ for( int i = 0;i < str.length(); i++ ){
+ if(str.charAt(i) == '(')
+ paramIdx ++;
+ else if (str.charAt(i) == ')')
+ paramIdx --;
+
+ if( paramIdx == 0 )
+ return false;
+ }
+
+ return true;
+ }
+
+ private static int lastDotIndex( String str ){
+ int paramIndex = 0;
+
+ for( int i = str.length()-1;i >= 0;i--){
+ if(str.charAt(i) == ')')
+ paramIndex --;
+ else if(str.charAt(i) == '(')
+ paramIndex ++;
+ else if(str.charAt(i) == '.' && paramIndex == 0)
+ return i;
+ }
+
+ return -1;
+ }
+
+}
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/core/parser/QBFileType.java b/project/QBarInterpreter/src/com/modulus/qbar/core/parser/QBFileType.java
new file mode 100644
index 0000000..da78219
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/core/parser/QBFileType.java
@@ -0,0 +1,37 @@
+package com.modulus.qbar.core.parser;
+
+import com.modulus.qbar.core.interpreter.CompiledReader;
+import com.modulus.qbar.core.interpreter.CompressedReader;
+import com.modulus.qbar.core.interpreter.QBInterpreterReader;
+import com.modulus.qbar.core.interpreter.SourceReader;
+
+public enum QBFileType {
+ SOURCE(".qbar", new SourceReader()),
+ COMPILED(".qbc", new CompiledReader()),
+ GZIPPED(".qbz", new CompressedReader());
+
+ private String ext;
+ private QBInterpreterReader reader;
+
+ QBFileType(String ext, QBInterpreterReader reader){
+ this.ext = ext;
+ this.reader = reader;
+ }
+
+ public String getExtention(){
+ return ext;
+ }
+
+ public QBInterpreterReader getReader(){
+ return this.reader;
+ }
+
+ public static QBFileType getFileType(String file){
+ for( QBFileType type : QBFileType.values() )
+ if(file.endsWith(type.getExtention()))
+ return type;
+
+
+ return SOURCE;
+ }
+}
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/core/parser/QBParser.java b/project/QBarInterpreter/src/com/modulus/qbar/core/parser/QBParser.java
new file mode 100644
index 0000000..5054a1b
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/core/parser/QBParser.java
@@ -0,0 +1,307 @@
+package com.modulus.qbar.core.parser;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import com.modulus.dataread.expressions.Statement;
+import com.modulus.dataread.expressions.StatementFactory;
+import com.modulus.dataread.expressions.StatementFormatter;
+import com.modulus.dataread.expressions.impl.CBasedParseRules;
+import com.modulus.dataread.expressions.impl.SimpleStatementTreeParser;
+import com.modulus.qbar.core.QBConstructor;
+import com.modulus.qbar.core.QBFile;
+import com.modulus.qbar.core.QBFunction;
+import com.modulus.qbar.core.QBNamespace;
+import com.modulus.qbar.core.QBStruct;
+import com.modulus.qbar.core.QBSyntheticFunction;
+import com.modulus.qbar.core.QBSyntheticStruct;
+import com.modulus.qbar.core.QBSyntheticUtilityNamespace;
+import com.modulus.qbar.core.QBUtilityNamespace;
+import com.modulus.qbar.core.exceptions.ParseException;
+import com.modulus.qbar.core.interpreter.Main;
+import com.modulus.qbar.core.interpreter.QBInterpreter;
+import com.modulus.qbar.core.parser.stmt.QBStatement;
+import com.modulus.qbar.core.parser.stmt.QBStatements;
+import com.modulus.qbar.integration.QBWrappedClass;
+import com.modulus.qbar.integration.QBWrappedUtilityNamespace;
+
+public class QBParser {
+ private static Set<Object> alreadyImported = new HashSet<Object>();
+
+ private Core systemCore = new Core();
+ private SimpleStatementTreeParser treeParser;
+ private static List<AnnotationReader> annotationReaders = new ArrayList<AnnotationReader>();
+ private QBNamespace currentCompilingNamespace;
+ private QBInterpreter thisInterpreter;
+ private Map<QBStruct, String> waitingListForExtending = new HashMap<QBStruct, String>();
+
+ public QBParser( QBInterpreter interpreter ){
+ thisInterpreter = interpreter;
+ }
+
+ public static final StatementFormatter formatter = new StatementFormatter() {
+ private static final long serialVersionUID = 9033830509672123664L;
+
+ @Override
+ public String formatHeader(String header) {
+ header = header.replaceAll("\\s+", " "); // only one space in needed
+ header = header.trim(); // trim it to look better
+ header = header.replaceAll("\\s+\\(", "("); // remove spaces before parenthasis
+
+ return header;
+ }
+ };
+
+ public static final StatementFactory<QBStatement> PARSER_STATEMENT_FACTORY = new StatementFactory<QBStatement>() {
+
+ @Override
+ public QBStatement generateStatement(Map<String, Object> params) {
+ return new QBStatement(formatter);
+ }
+
+ };
+
+
+ public QBStatement parseCode( String code ){
+ // FIXME big use of bandaid
+ code = "Namespace global{\n" + code + "\n}";
+ CBasedParseRules rules = new CBasedParseRules(code){
+ @Override
+ public String getCommentOpen() {
+ return "-{";
+ }
+
+ @Override
+ public String getCommentClose() {
+ return "}-";
+ }
+
+ @Override
+ public String getLineCommentDelimeter() {
+ return "--";
+ }
+ };
+
+ treeParser = new SimpleStatementTreeParser(rules);
+
+ QBStatement statements = (QBStatement) treeParser.parseStatements( PARSER_STATEMENT_FACTORY);
+
+ for(Statement stmt : statements.getChildren() ){
+ if(stmt.getHeader().startsWith("@")){
+ readAnnotation( stmt );
+ } else{
+ readStatement(stmt, systemCore.getGlobalNamespace());
+ }
+ }
+
+ return statements;
+ }
+
+ public static void readAnnotation(Statement stmt) {
+ for(AnnotationReader annotReader : annotationReaders)
+ annotReader.readAnnotation(stmt);
+ }
+
+ public static void addAnnotationReader(AnnotationReader reader){
+ annotationReaders.add(reader);
+ }
+
+ public void readStatement( Statement stat, QBNamespace nmspce ){
+ //System.out.println("HEADER " + stat.getHeader());
+ currentCompilingNamespace = nmspce;
+
+ if(stat instanceof QBStatement)
+ ((QBStatement) stat).compile( this );
+
+ try{
+ if(QBStatements.stmtIsImport(stat)){
+ Main.debug(QBParser.class, "Importing Stuff!");
+ try {
+ importStuff(stat, nmspce);
+ } catch (IOException e) {
+ e.printStackTrace();
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ }
+ } else if(QBStatements.stmtIsLoad(stat)){
+ try {
+ loadStuff(stat, nmspce);
+ } catch (IOException e) {
+ e.printStackTrace();
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ }
+ } else if( QBStatements.stmtIsConstructor(stat) ){
+ stat.setHeader( stat.getHeader().replaceAll("new\\s+", "new\\$0x20") );
+ QBSyntheticFunction constructor = new QBConstructor((QBStatement) stat, (QBStruct) nmspce, this);
+ constructor.setSuper(nmspce);
+ systemCore.getGlobalNamespace().set(constructor.getName(), constructor);
+ } else if( QBStatements.stmtIsFunction(stat) ){
+ QBFunction func = createFunction(stat, nmspce);
+
+ if(nmspce instanceof QBSyntheticFunction) {
+ ((QBSyntheticFunction) nmspce).addSubObject( func.getName(), func);
+ } else {
+ nmspce.set(func.getName(), func);
+ }
+ } else if( QBStatements.stmtIsClass(stat) ){
+ QBStruct struct = new QBSyntheticStruct(stat, this, nmspce);
+
+ if(nmspce instanceof QBSyntheticFunction) {
+ ((QBSyntheticFunction) nmspce).addSubObject( struct.getName(), struct);
+ } else {
+ nmspce.set(struct.getName(), struct);
+ }
+ } else if( QBStatements.stmtIsNamespace(stat)){
+ QBUtilityNamespace utilNamespace = new QBSyntheticUtilityNamespace(stat, this, nmspce);
+ utilNamespace.construct();
+
+ if(nmspce instanceof QBSyntheticFunction) {
+ ((QBSyntheticFunction) nmspce).addSubObject( utilNamespace.getName(), utilNamespace);
+ } else {
+ nmspce.set(utilNamespace.getName(), utilNamespace);
+ }
+ }
+ } catch(Exception e){
+ e.printStackTrace();
+ throw new ParseException(stat);
+ }
+ }
+
+ public QBFunction createFunction(Statement stat, QBNamespace nmspce) {
+ QBFunction func = new QBSyntheticFunction((QBStatement) stat, this);
+ func.setSuper(nmspce);
+ return func;
+ }
+
+ public QBFunction createInteractiveFunction(Statement stat, QBNamespace nmspce) {
+ QBFunction func = new QBSyntheticFunction((QBStatement) stat, this);
+ func.setSuper(nmspce);
+ return func;
+ }
+
+ private void importStuff(Statement importStmt, QBNamespace nmspce) throws IOException, ClassNotFoundException{
+ String[] headers = importStmt.getHeader().split("\\s+", 3);
+
+ String next = headers[1];
+ if(next.equals("Native"))
+ importNative( headers[2], nmspce );
+
+ else
+ importStandard(headers[1]);
+ }
+
+ private void loadStuff(Statement importStmt, QBNamespace nmspce) throws IOException, ClassNotFoundException{
+ String[] headers = importStmt.getHeader().split("\\s+", 3);
+
+ String next = headers[1];
+ if(next.equals("Native"))
+ loadNative( headers[2], nmspce );
+
+ else
+ loadStandard(headers[1], nmspce);
+ }
+
+ private void loadStandard(String string, QBNamespace ns) {
+ // System.out.println("Incorporating: " + ns);
+ ns.incoporate( ns.get(string) );
+ }
+
+ private void loadNative(String clazz, QBNamespace nmspce) throws ClassNotFoundException {
+ QBNamespace tmp = importNative(clazz, nmspce);
+
+ nmspce.incoporate(tmp);
+ }
+
+ private void importStandard(String file) throws IOException, ClassNotFoundException{
+
+
+ File f = QBFile.getQBFile(file);
+
+ if(alreadyImported.contains(f.getAbsolutePath())){
+ Main.debug(this.getClass(), f.getAbsolutePath() + " is already imported!");
+ return;
+ }
+ alreadyImported.add(f.getAbsolutePath());
+
+ QBFileType type = QBFileType.getFileType(file);
+ QBInterpreter interpreter = null;
+ FileInputStream in = new FileInputStream(f);
+
+ // TODO fix to use enum to read
+ switch(type){
+ case SOURCE:
+ interpreter = QBInterpreter.readInterpreterFromSource( in );
+ break;
+
+ case COMPILED:
+ interpreter = QBInterpreter.readInterpreter( in );
+ break;
+
+ case GZIPPED:
+ interpreter = QBInterpreter.readInterpreterCompressed( in );
+ }
+
+ QBInterpreter.instance().merge(interpreter);
+ }
+
+ private QBNamespace importNative(String clazz, QBNamespace nmspce) throws ClassNotFoundException{
+ Pattern p = Pattern.compile("\\s+as\\s+");
+ Matcher m = p.matcher(clazz);
+
+ String name = clazz.substring(clazz.lastIndexOf('.') + 1);
+
+ if( m.find() ){
+ String[] split = clazz.split("\\s+as\\s+");
+ clazz = split[0];
+
+ name = split[1];
+ }
+
+ Class<?> cls = thisInterpreter.getClassLoader().loadClass(clazz);//Class.forName(clazz);
+ QBWrappedUtilityNamespace utilityNamespace = new QBWrappedUtilityNamespace( name );
+
+ QBStruct struct = QBWrappedClass.wrapClass(cls, utilityNamespace);
+ struct.setSuper(nmspce);
+
+ utilityNamespace.set(struct.getName(), struct);
+ nmspce.set(utilityNamespace.getName(), utilityNamespace);
+
+ return utilityNamespace;
+ }
+
+
+ public Core getSystemCore(){
+ return systemCore;
+ }
+
+ public void resetCore(){
+ systemCore = new Core();
+ }
+
+ public void setCurrentCompilingNamespace(
+ QBNamespace currentCompilingNamespace) {
+ this.currentCompilingNamespace = currentCompilingNamespace;
+ }
+
+ public QBNamespace getCurrentCompilingNamespace() {
+ return currentCompilingNamespace == null ? systemCore.getGlobalNamespace() : currentCompilingNamespace;
+ }
+
+ public void insertIntoWaiting(QBStruct struct, String other){
+ waitingListForExtending.put(struct, other);
+ }
+
+ public QBInterpreter getInterpreter(){
+ return this.thisInterpreter;
+ }
+}
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/core/parser/QBParser.java.bak b/project/QBarInterpreter/src/com/modulus/qbar/core/parser/QBParser.java.bak
new file mode 100644
index 0000000..09bc3fa
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/core/parser/QBParser.java.bak
@@ -0,0 +1,98 @@
+package com.modulus.qbar.core.parser;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import com.modulus.dataread.expressions.ParseRules;
+import com.modulus.dataread.expressions.Statement;
+import com.modulus.dataread.expressions.StatementFactory;
+import com.modulus.dataread.expressions.StatementFormatter;
+import com.modulus.dataread.expressions.impl.CBasedParseRules;
+import com.modulus.dataread.expressions.impl.FormatStatement;
+import com.modulus.dataread.expressions.impl.SimpleExpressionParser;
+import com.modulus.qbar.core.QBClass;
+import com.modulus.qbar.core.QBFunction;
+import com.modulus.qbar.core.QBStruct;
+import com.modulus.qbar.core.exceptions.ExecutionException;
+
+/**
+ * This class is responsible for parsing all of the information
+ * that is held in a single Q-Bar source file.
+ *
+ * @author jrahm
+ *
+ */
+public class QBParser {
+ /**
+ * Formatter that formats all of the statements when they
+ * are created by the factory
+ */
+ public static final StatementFormatter formatter = new StatementFormatter() {
+ @Override
+ public String formatHeader(String header) {
+ return header.trim();
+ }
+ };
+
+ /**
+ * Generates all of the statements to be parsed by the
+ * ExpressionParser.
+ */
+ public static final StatementFactory<FormatStatement> statementFactory = new StatementFactory<FormatStatement>() {
+
+ @Override
+ public FormatStatement generateStatement(Map<String, Object> params) {
+ return new FormatStatement(formatter);
+ }
+ };
+
+ /**
+ * Parses the code from some source.
+ * @param code the code from the source
+ */
+ public void parseCode(String code) {
+ ParseRules cRules = new CBasedParseRules(code);
+ SimpleExpressionParser parser = new SimpleExpressionParser(cRules);
+
+ Statement node = parser.parseStatements( statementFactory );
+ Statement[] stmts = node.getChildren();
+ }
+
+ /**
+ * This method parses a class from a statement
+ * @param stmt the statement that holds the class
+ * @return the class that was parsed from this statement
+ */
+ public QBClass parseClass(Statement stmt){
+ Statement[] children = stmt.getChildrenByHeader("Struct");
+ QBStruct struct = new QBStruct();
+
+ for(int i = 0;i < children.length;i++){
+ Statement child = children[i];
+
+ String name = child.getHeader();
+ struct.addInstanceVariable(name);
+
+ if(name.startsWith("Class")){
+ if(!name.endsWith("{")){
+ throw new ExecutionException("`Class' is a reserved word and may not be used as a variable name");
+ }
+
+ QBClass parsed = parseClass(child);
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Parses a function from a statement.
+ *
+ * @param stmt the statement to parse the function from
+ * @return the function that was parsed from this statement.
+ */
+ public QBFunction parseFunction(Statement stmt){
+ return new QBFunction(stmt);
+ }
+}
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/core/parser/stmt/QBStatement.java b/project/QBarInterpreter/src/com/modulus/qbar/core/parser/stmt/QBStatement.java
new file mode 100644
index 0000000..8c66cef
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/core/parser/stmt/QBStatement.java
@@ -0,0 +1,127 @@
+package com.modulus.qbar.core.parser.stmt;
+
+import java.io.Serializable;
+import java.util.Arrays;
+import java.util.Collection;
+
+import com.modulus.dataread.expressions.FlowStatement;
+import com.modulus.dataread.expressions.Statement;
+import com.modulus.dataread.expressions.StatementFormatter;
+import com.modulus.dataread.expressions.impl.FormatStatement;
+import com.modulus.qbar.core.exceptions.ParseException;
+import com.modulus.qbar.core.parser.ByteOperation;
+import com.modulus.qbar.core.parser.ExpressionCompiler;
+import com.modulus.qbar.core.parser.ExpressionPuller;
+import com.modulus.qbar.core.parser.QBParser;
+
+/**
+ * This class implements a statement that translates
+ * itself into more computer-readable code automatically.
+ * It is guaranteed that all of the children of this
+ * statement will be QBStatements as well, so it is safe to
+ * cast.
+ *
+ * @author jrahm
+ *
+ */
+public class QBStatement extends FormatStatement implements Cloneable{
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1707466197323482810L;
+
+ private static Collection<String> excludedHeaders = Arrays.asList("Struct", "let", "Namespace", "Import", "Incorporate");
+
+ private ByteOperation[] byteOps;
+ private FlowStatement flow = FlowStatement.NONE;
+
+ public QBStatement(StatementFormatter format){
+ super(format);
+ }
+
+ public ByteOperation[] getOperations(){
+ return byteOps;
+ }
+
+ public FlowStatement getFlowStatement(){
+ return flow;
+ }
+
+ private void p_compile(QBParser parser){
+ try{
+
+ String header = this.getHeader();
+ header = ExpressionPuller.pullStrings(header);
+
+ header = ExpressionPuller.pullLists(header, parser.getCurrentCompilingNamespace(), parser);
+
+ header = header.replaceAll("new\\s+", "new\\$0x20");
+ for( FlowStatement stmt : FlowStatement.values() ){
+ if( header.startsWith(stmt.toString().toLowerCase()) ){
+ if(!(stmt == FlowStatement.IF && header.contains("then"))){
+ flow = stmt;
+
+
+ header = header.substring(stmt.toString().length()).trim();
+ if(stmt == FlowStatement.ELSE){
+ byteOps = new ByteOperation[]{};
+ return;
+ }
+
+ break;
+ }
+ }
+ }
+
+ ExpressionCompiler comp = new ExpressionCompiler();
+ byteOps = comp.compile(header);
+ } catch( RuntimeException e ){
+ throw new ParseException(e.getMessage(), e, this);
+ }
+ }
+ @Override
+ public void setLineNumber(int line){
+ //System.out.println(this.getHeader() + " : " + line);
+ super.setLineNumber(line);
+ }
+ @Override
+ public void setHeader( String header ){
+
+ super.setHeader( header );
+ if(this.getHeader().startsWith("}"))
+ throw new RuntimeException("} as first character of header!");
+
+ }
+
+ public void compile( QBParser parser ){
+ if(shouldCompile())
+ p_compile( parser );
+
+ for(Statement stmt : getChildren()){
+ if(stmt instanceof QBStatement){
+ QBStatement qbStmt = (QBStatement) stmt;
+ qbStmt.compile( parser );
+ }
+ }
+ }
+
+ private boolean shouldCompile(){
+
+
+ for(String s : excludedHeaders)
+ if(this.getHeader().startsWith(s))
+ return false;
+ return true;
+ }
+
+ public QBStatement clone(){
+ try {
+ return (QBStatement) super.clone();
+ } catch (CloneNotSupportedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ throw new RuntimeException(e);
+ }
+ }
+
+}
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/core/parser/stmt/QBStatements.java b/project/QBarInterpreter/src/com/modulus/qbar/core/parser/stmt/QBStatements.java
new file mode 100644
index 0000000..0047c33
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/core/parser/stmt/QBStatements.java
@@ -0,0 +1,37 @@
+package com.modulus.qbar.core.parser.stmt;
+
+import com.modulus.dataread.expressions.Statement;
+
+public class QBStatements {
+ static public boolean stmtIsNamespace( Statement stmt ){
+ return stmt.getHeader().startsWith("Namespace");
+ }
+ static public boolean stmtIsFunction( Statement stmt ){
+ return stmt.getHeader().startsWith("let");
+ }
+
+ static public boolean stmtIsClass( Statement stmt ){
+ return stmt.getHeader().startsWith("Struct");
+ }
+
+ static public boolean stmtIsConstructor( Statement stmt ){
+ // constructors have the word `new` come after the `let` declaration
+ // as in let new Object(a,b,c) = do . . .
+
+ // A constructor does not nessecarily have to take the name of the object
+ if(!stmtIsFunction(stmt)){
+ return false;
+ }
+ String header = stmt.getHeader();
+ header = header.substring(3).trim();
+ return header.startsWith("new");
+ }
+
+ static public boolean stmtIsImport( Statement stmt ){
+ return stmt.getHeader().startsWith("Import");
+ }
+
+ static public boolean stmtIsLoad( Statement stmt ){
+ return stmt.getHeader().startsWith("Incorporate");
+ }
+}
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/core/primitive/QBChar.java b/project/QBarInterpreter/src/com/modulus/qbar/core/primitive/QBChar.java
new file mode 100644
index 0000000..4fe9802
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/core/primitive/QBChar.java
@@ -0,0 +1,69 @@
+package com.modulus.qbar.core.primitive;
+
+import com.modulus.qbar.core.QBObject;
+import com.modulus.qbar.core.QBStruct;
+
+/**
+ * Class that represents the
+ * Q-Bar primitive value char
+ */
+ /*
+ * this class was generated by the python script
+ * 'generate_primitives.py
+ * @PythonGenerated
+ */
+public class QBChar extends QBPrimitive{
+ /**
+ *
+ */
+ private static final long serialVersionUID = 3811922090207258658L;
+ private char value;
+ public final static QBStruct struct = new QBStruct("Character", QBPrimitive.struct) {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public QBObject newInstance() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+ };
+ /**
+ * Constructs a new QBarChar that wraps
+ * the type char
+ */
+ public QBChar( char value ){
+ this.value = value;
+ }
+
+ @Override
+ public int intValue(){
+ return (int) this.value;
+ }
+
+ @Override
+ public double doubleValue(){
+ return (double) this.value;
+ }
+
+ @Override
+ public char charValue(){
+ return (char) this.value;
+ }
+
+ public String toString(){
+ return Character.toString(value);
+ }
+
+ public Number getValueNumber(){
+ return (int)value;
+ }
+
+ @Override
+ public Object getWrapped(){
+ return value;
+ }
+}
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/core/primitive/QBDouble.java b/project/QBarInterpreter/src/com/modulus/qbar/core/primitive/QBDouble.java
new file mode 100644
index 0000000..148b24e
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/core/primitive/QBDouble.java
@@ -0,0 +1,71 @@
+package com.modulus.qbar.core.primitive;
+
+import com.modulus.qbar.core.QBObject;
+import com.modulus.qbar.core.QBStruct;
+
+/**
+ * Class that represents the
+ * Q-Bar primitive value double
+ */
+ /*
+ * this class was generated by the python script
+ * 'generate_primitives.py
+ * @PythonGenerated
+ */
+public class QBDouble extends QBPrimitive{
+ /**
+ *
+ */
+ private static final long serialVersionUID = -2590117898914328610L;
+ private double value;
+
+ public final static QBStruct struct = new QBStruct("Double", QBPrimitive.struct) {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public QBObject newInstance() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+ };
+
+ /**
+ * Constructs a new QBarDouble that wraps
+ * the type double
+ */
+ public QBDouble( double value ){
+ this.value = value;
+ }
+
+ @Override
+ public int intValue(){
+ return (int) this.value;
+ }
+
+ @Override
+ public double doubleValue(){
+ return (double) this.value;
+ }
+
+ @Override
+ public char charValue(){
+ return (char) this.value;
+ }
+
+ public String toString(){
+ return Double.toString(value);
+ }
+
+ public Number getValueNumber(){
+ return value;
+ }
+
+ @Override
+ public Object getWrapped(){
+ return value;
+ }
+}
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/core/primitive/QBInt.java b/project/QBarInterpreter/src/com/modulus/qbar/core/primitive/QBInt.java
new file mode 100644
index 0000000..c8f5452
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/core/primitive/QBInt.java
@@ -0,0 +1,111 @@
+package com.modulus.qbar.core.primitive;
+
+import com.modulus.qbar.core.NaturalFunctions;
+import com.modulus.qbar.core.QBObject;
+import com.modulus.qbar.core.QBStruct;
+
+/**
+ * Class that represents the
+ * Q-Bar primitive value int
+ */
+ /*
+ * this class was generated by the python script
+ * 'generate_primitives.py
+ * @PythonGenerated
+ */
+public class QBInt extends QBPrimitive{
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+ private int value;
+ public final static QBStruct struct = new QBStruct("Integer", QBPrimitive.struct) {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public QBObject newInstance() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+ };
+ public static final QBInt TRUE = new QBInt(1);
+ public static final QBInt FALSE = new QBInt(0);
+ static{
+ struct.set("and", NaturalFunctions.AND);
+ struct.set("or", NaturalFunctions.OR);
+ struct.set("xor", NaturalFunctions.XOR);
+
+ // just adding these to speed up the process, after all
+ // integers must run as fast as possible, but these would
+ // still be in the super struct.
+ struct.set("+", NaturalFunctions.ADDI);
+ struct.set("-", NaturalFunctions.SUBI);
+ struct.set("*", NaturalFunctions.MULI);
+ struct.set("%", NaturalFunctions.MODI);
+ struct.set("/", NaturalFunctions.DIV);
+ struct.set("div", NaturalFunctions.DIVI);
+ struct.set("^", NaturalFunctions.POWI);
+
+ struct.set(">", NaturalFunctions.GT);
+ struct.set("<", NaturalFunctions.LT);
+ struct.set("==", NaturalFunctions.EQ);
+ struct.set("!=", NaturalFunctions.NE);
+ struct.set(">=", NaturalFunctions.GTE);
+ struct.set("<=", NaturalFunctions.LTE);
+
+ struct.set("add", NaturalFunctions.ADDI);
+ struct.set("subtract", NaturalFunctions.SUBI);
+ struct.set("multiply", NaturalFunctions.MULI);
+ struct.set("modulo", NaturalFunctions.MODI);
+ struct.set("divide", NaturalFunctions.DIV);
+ struct.set("power", NaturalFunctions.POWI);
+ struct.set("divideInteger", NaturalFunctions.DIVI);
+
+ struct.set("greaterThan", NaturalFunctions.GT);
+ struct.set("lessThan", NaturalFunctions.LT);
+ struct.set("equalTo", NaturalFunctions.EQ);
+ struct.set("notEqualTo", NaturalFunctions.NE);
+ struct.set("greaterThanOrEqualTo", NaturalFunctions.GTE);
+ struct.set("lessThanOrEqualTo", NaturalFunctions.LTE);
+ }
+ /**
+ * Constructs a new QBarInt that wraps
+ * the type int
+ */
+ public QBInt( int value ){
+ super(struct);
+ this.value = value;
+ }
+
+ @Override
+ public int intValue(){
+ return (int) this.value;
+ }
+
+ @Override
+ public double doubleValue(){
+ return (double) this.value;
+ }
+
+ @Override
+ public char charValue(){
+ return (char) this.value;
+ }
+
+ public String toString(){
+ return Integer.toString(value);
+ }
+
+ public Number getValueNumber(){
+ return value;
+ }
+
+ @Override
+ public Object getWrapped(){
+ return value;
+ }
+}
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/core/primitive/QBPrimitive.java b/project/QBarInterpreter/src/com/modulus/qbar/core/primitive/QBPrimitive.java
new file mode 100644
index 0000000..d5a7070
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/core/primitive/QBPrimitive.java
@@ -0,0 +1,122 @@
+package com.modulus.qbar.core.primitive;
+
+import java.math.BigDecimal;
+
+import com.modulus.qbar.core.NaturalFunctions;
+import com.modulus.qbar.core.QBObject;
+import com.modulus.qbar.core.QBStruct;
+import com.modulus.qbar.core.exceptions.ExecutionException;
+
+/**
+ * Class that describes very natural and primitive
+ * objects in the Q-Bar language.
+ *
+ * @author jrahm
+ *
+ */
+public abstract class QBPrimitive extends QBObject implements Comparable<QBPrimitive>{
+ /**
+ *
+ */
+ private static final long serialVersionUID = -3882060949668211170L;
+ public static final QBStruct struct = new QBStruct("Primitive") {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -93702214222801325L;
+
+ @Override
+ public QBObject newInstance() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+ };
+
+ static{
+ struct.set("+", NaturalFunctions.ADD);
+ struct.set("-", NaturalFunctions.SUB);
+ struct.set("*", NaturalFunctions.MUL);
+ struct.set("%", NaturalFunctions.MOD);
+ struct.set("/", NaturalFunctions.DIV);
+ struct.set("^", NaturalFunctions.POW);
+
+ struct.set(">", NaturalFunctions.GT);
+ struct.set("<", NaturalFunctions.LT);
+ struct.set("==", NaturalFunctions.EQ);
+ struct.set("!=", NaturalFunctions.NE);
+ struct.set(">=", NaturalFunctions.GTE);
+ struct.set("<=", NaturalFunctions.LTE);
+
+ struct.set("add", NaturalFunctions.ADD);
+ struct.set("subtract", NaturalFunctions.SUB);
+ struct.set("multiply", NaturalFunctions.MUL);
+ struct.set("modulo", NaturalFunctions.MOD);
+ struct.set("divide", NaturalFunctions.DIV);
+ struct.set("power", NaturalFunctions.POW);
+
+ struct.set("greateThan", NaturalFunctions.GT);
+ struct.set("lessThan", NaturalFunctions.LT);
+ struct.set("equalTo", NaturalFunctions.EQ);
+ struct.set("notEqualTo", NaturalFunctions.NE);
+ struct.set("greaterThanOrEqualTo", NaturalFunctions.GTE);
+ struct.set("lessThanOrEqualTo", NaturalFunctions.LTE);
+
+ struct.set("as", NaturalFunctions.AS);
+ }
+ /**
+ * Constructs a simple new QBPrimitive object
+ */
+ public QBPrimitive() {
+ super( struct );
+ }
+
+ protected QBPrimitive( QBStruct struct ){
+ super(struct);
+ }
+
+ @Override
+ public void set(String str, QBObject obj){
+ throw new ExecutionException("Attempting to assign primitive member");
+ }
+
+ protected void setSafe( String str, QBObject obj ){
+ super.set(str, obj);
+ }
+
+ /**
+ * Gets the integer value of this primitive value
+ * @return the integer value of this primitive value;
+ */
+ public abstract int intValue();
+
+ /**
+ * Gets the double value of this primitive value
+ * @return the double value of this primitive value
+ */
+ public abstract double doubleValue();
+
+ /**
+ * Gets the char value of this primitive value
+ * @return the char value of this primitive value
+ */
+ public abstract char charValue();
+
+ /**
+ * Returns the value of this QBPrimitive as a number
+ * @return the value of this QBPrimitive as a number
+ */
+ public abstract Number getValueNumber();
+
+ @Override
+ public int compareTo(QBPrimitive other){
+ return (int) Math.signum( this.getValueNumber().doubleValue() - other.getValueNumber().doubleValue() );
+ }
+
+ public static QBPrimitive forNumber(Number num){
+ if( num instanceof Double || num instanceof Float || num instanceof BigDecimal )
+ return new QBDouble(num.doubleValue());
+
+ return new QBInt(num.intValue());
+ }
+}
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/integration/QBWrappedClass.java b/project/QBarInterpreter/src/com/modulus/qbar/integration/QBWrappedClass.java
new file mode 100644
index 0000000..01d6a9f
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/integration/QBWrappedClass.java
@@ -0,0 +1,68 @@
+package com.modulus.qbar.integration;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.HashMap;
+import java.util.Map;
+
+import com.modulus.qbar.core.QBFunction;
+import com.modulus.qbar.core.QBNamespace;
+import com.modulus.qbar.core.QBObject;
+import com.modulus.qbar.core.QBStruct;
+
+public class QBWrappedClass extends QBStruct{
+ private static final long serialVersionUID = -4889124451749124731L;
+ private static final Map<Class<?>, QBWrappedClass> wrappedClasses = new HashMap<Class<?>, QBWrappedClass>();
+
+ public static QBStruct wrapClass(Class<?> clazz, QBNamespace nmspce){
+ QBWrappedClass ret = wrappedClasses.get(clazz);
+
+
+ if(ret == null){
+ ret = new QBWrappedClass(clazz, nmspce);
+ wrappedClasses.put(clazz, ret);
+ }
+
+ return ret;
+ }
+
+ private QBWrappedClass(Class<?> toWrap, QBNamespace nmspce) {
+ super("");
+ String name = toWrap.getName();
+ this.setName(name.substring(name.lastIndexOf('.') + 1));
+
+ Method[] methods = toWrap.getMethods();
+
+ for( Method m : methods){
+ int mod = m.getModifiers();
+ int argc = m.getParameterTypes().length;
+ if(!Modifier.isStatic(mod)){
+ argc += 1;
+ }
+
+ QBFunction func = new QBWrappedMethod(toWrap, m.getName(), argc);
+
+
+ if(Modifier.isStatic(mod)){
+ String methodName = m.getName();
+
+ if(methodName.startsWith("new$0x20")){
+ methodName = methodName.substring(8);
+ methodName = "new$0x20" + methodName;
+ }
+
+ nmspce.set(methodName, func);
+ } else {
+ this.set(m.getName(), func);
+ }
+ }
+
+ Constructor<?>[] constructors = toWrap.getConstructors();
+ if(constructors.length > 0){
+ QBWrappedConstructor toAdd = new QBWrappedConstructor(constructors[0].getParameterTypes().length, toWrap);
+ nmspce.set( "new$0x20" + this.getName(), toAdd);
+ }
+ }
+
+}
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/integration/QBWrappedConstructor.java b/project/QBarInterpreter/src/com/modulus/qbar/integration/QBWrappedConstructor.java
new file mode 100644
index 0000000..354ba2a
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/integration/QBWrappedConstructor.java
@@ -0,0 +1,53 @@
+package com.modulus.qbar.integration;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+import com.modulus.qbar.core.QBFunction;
+import com.modulus.qbar.core.QBObject;
+
+public class QBWrappedConstructor extends QBFunction{
+ /**
+ *
+ */
+ private static final long serialVersionUID = -3025785234264500875L;
+ private transient Constructor<?> wrapped;
+
+ private Class<?> clazz;
+
+ public QBWrappedConstructor(int argc, Constructor<?> wrapped) {
+ super(argc);
+ this.wrapped = wrapped;
+ }
+
+ public QBWrappedConstructor(int argc, Class<?> clazz){
+ super(argc);
+ this.clazz = clazz;
+ }
+
+ private void setup(){
+ Constructor<?>[] constructors = this.clazz.getConstructors();
+ this.wrapped = constructors[0];
+ }
+
+ @Override
+ public QBObject execute(QBObject[] args) {
+ try{
+ if(wrapped == null)
+ setup();
+
+ Object[] objs = new Object[args.length];
+
+ for( int i = 0;i < objs.length; i ++){
+ objs[i] = args[i].getWrapped();
+ }
+
+ Object ret = wrapped.newInstance( objs );
+ return QBWrappedObject.wrap(ret);
+ } catch( Exception e ){
+ throw new RuntimeException("Failed to Create new Instance of " + wrapped.getClass());
+ }
+ }
+
+}
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/integration/QBWrappedMethod.java b/project/QBarInterpreter/src/com/modulus/qbar/integration/QBWrappedMethod.java
new file mode 100644
index 0000000..479e504
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/integration/QBWrappedMethod.java
@@ -0,0 +1,95 @@
+package com.modulus.qbar.integration;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+import com.modulus.qbar.core.QBFunction;
+import com.modulus.qbar.core.QBObject;
+
+public class QBWrappedMethod extends QBFunction{
+ private transient Method wrapped;
+ private boolean isStatic;
+
+ private String methodName;
+ private Class<?> clazz;
+
+ public QBWrappedMethod(Method toWrap) {
+ super(toWrap.getParameterTypes().length);
+ this.wrapped = toWrap;
+
+ isStatic = Modifier.isStatic(toWrap.getModifiers());
+
+ if(!isStatic){
+ this.setArgc(this.getArgc() + 1);
+ }
+ }
+
+ public QBWrappedMethod( Class<?> clazz, String methodName, int argc ){
+ super( argc );
+
+ this.clazz = clazz;
+ this.methodName = methodName;
+ }
+
+ // since java is sometimes annoying and will not let you serialize Methods,
+ // we need to send the information and generate them on the fly
+ private void setup(){
+ Method[] methods = this.clazz.getMethods();
+
+ for(Method method : methods ){
+ if(method.getName().equals(methodName)){
+ this.wrapped = method;
+ break;
+ }
+ }
+
+ isStatic = Modifier.isStatic(this.wrapped.getModifiers());
+ }
+
+ @Override
+ public QBObject execute(QBObject[] args){
+ try {
+ if(wrapped == null)
+ setup();
+
+ if(isStatic){
+ return executeStatic(args);
+ } else{
+ Object[] objs = new Object[args.length - 1];
+ Object caller =args[args.length - 1].getWrapped();
+
+ for( int i = 0;i < args.length-1; i++){
+ // System.out.println("args["+i+"]: " + args[i] + " wrap: " + args[i].getWrapped());
+ objs[i] = args[i].getWrapped();
+ }
+
+ // System.out.println("Method " + wrapped + "\nargs: " + Arrays.toString(objs) + "\nargs2: " + Arrays.toString(args));
+ return QBWrappedObject.wrap(wrapped.invoke(caller, objs));
+ }
+ } catch (IllegalArgumentException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (IllegalAccessException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (InvocationTargetException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+
+ return null;
+ }
+
+ private QBObject executeStatic(QBObject[] args) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException{
+ Object[] objs = new Object[args.length];
+ for( int i = 0;i < objs.length; i++){
+ objs[i] = args[i].getWrapped();
+ }
+ // System.out.println(Arrays.toString(objs) + " " + this.getArgc() + "\n\t" + wrapped);
+
+ return QBWrappedObject.wrap(wrapped.invoke(null, objs));
+ }
+
+}
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/integration/QBWrappedObject.java b/project/QBarInterpreter/src/com/modulus/qbar/integration/QBWrappedObject.java
new file mode 100644
index 0000000..29a5641
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/integration/QBWrappedObject.java
@@ -0,0 +1,160 @@
+package com.modulus.qbar.integration;
+
+import java.util.Arrays;
+import java.util.List;
+
+import com.modulus.common.collections.MArrays;
+import com.modulus.qbar.core.QBObject;
+import com.modulus.qbar.core.interpreter.QBInterpreter;
+import com.modulus.qbar.core.primitive.QBChar;
+import com.modulus.qbar.core.primitive.QBDouble;
+import com.modulus.qbar.core.primitive.QBInt;
+import com.modulus.qbar.lang.QBArrayList;
+import com.modulus.qbar.lang.QBList;
+import com.modulus.qbar.lang.QBMaybe;
+public class QBWrappedObject extends QBObject{
+ /**
+ *
+ */
+ private static final long serialVersionUID = 400259956418357800L;
+ private Object wrapped;
+
+ private QBWrappedObject(Object wrapped) {
+ super( QBWrappedClass.wrapClass(wrapped.getClass(), QBInterpreter.instance().getGlobalNamespace()) );
+ this.wrapped = wrapped;
+ }
+
+ public Object getWrapped(){
+ return wrapped;
+ }
+
+ public static QBObject wrap(Object invoke) {
+ if(invoke == null){
+ return new QBMaybe.Maybe(null);
+ }
+
+ if(invoke instanceof QBObject) {
+ return (QBObject) invoke;
+ }
+
+ if ( invoke instanceof Object[] ){
+ return fromList(
+ Arrays.asList((Object[]) invoke)
+ );
+ }
+
+ if ( invoke instanceof byte[] ){
+ List<Byte> lst = MArrays.asList((byte[]) invoke);
+ return fromList(
+ lst
+ );
+ }
+
+ if ( invoke instanceof int[] ){
+ return fromList(
+ MArrays.asList((int[]) invoke)
+ );
+ }
+
+ if ( invoke instanceof short[] ){
+ return fromList(
+ MArrays.asList((short[]) invoke)
+ );
+ }
+
+ if ( invoke instanceof long[] ){
+ return fromList(
+ MArrays.asList((long[]) invoke)
+ );
+ }
+
+ if ( invoke instanceof boolean[] ){
+ return fromList(
+ MArrays.asList((boolean[]) invoke)
+ );
+ }
+
+ if ( invoke instanceof char[] ){
+ return fromList(
+ MArrays.asList((char[]) invoke)
+ );
+ }
+
+ if ( invoke instanceof double[] ){
+ return fromList(
+ MArrays.asList((double[]) invoke)
+ );
+ }
+
+ if ( invoke instanceof float[] ){
+ return fromList(
+ MArrays.asList((float[]) invoke)
+ );
+ }
+
+ if( invoke instanceof List<?> ){
+ return fromList( (List<?>) invoke );
+ }
+
+ if(invoke instanceof Double || invoke instanceof Float){
+ return new QBDouble(((Number) invoke).doubleValue());
+ }
+
+ if(invoke instanceof Number){
+ return new QBInt(((Number) invoke).intValue());
+ }
+
+ if(invoke instanceof Boolean){
+ return new QBInt(((Boolean) invoke) ? 1 : 0);
+ }
+
+ if(invoke instanceof Character){
+ return new QBChar((Character)invoke);
+ }
+
+ return new QBWrappedObject(invoke);
+ }
+
+ public static long timeSpent = 0;
+ private static QBObject fromList(final List<?> invoke) {
+ QBList tmp = new QBList() {
+
+ @Override
+ public double size() {
+ return invoke.size();
+ }
+
+ @Override
+ public void remove(QBObject obj) {
+ invoke.remove(obj);
+ }
+
+ @Override
+ public QBList realSubList(int off, int len) {
+ return (QBList) QBWrappedObject.wrap( invoke.subList(off, off+len) );
+ }
+
+ @Override
+ public void insert(int idx, QBObject obj) {
+ }
+
+ @Override
+ public QBObject get(int idx) {
+ return QBWrappedObject.wrap( invoke.get(idx) );
+ }
+
+ @Override
+ public QBObject add(QBObject obj) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+ };
+ // timeSpent += (t2 - t1);
+ return tmp;
+ }
+
+ public String toString(){
+ return wrapped.toString();
+ }
+
+}
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/integration/QBWrappedUtilityNamespace.java b/project/QBarInterpreter/src/com/modulus/qbar/integration/QBWrappedUtilityNamespace.java
new file mode 100644
index 0000000..ce14bb2
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/integration/QBWrappedUtilityNamespace.java
@@ -0,0 +1,20 @@
+package com.modulus.qbar.integration;
+
+import com.modulus.qbar.core.QBUtilityNamespace;
+
+public class QBWrappedUtilityNamespace extends QBUtilityNamespace{
+ private static final long serialVersionUID = -2579384501097845702L;
+ private String name;
+
+ public QBWrappedUtilityNamespace(String name){
+ this.name = name;
+ }
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public void construct() {
+ }
+}
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/lang/IfThenElseFunction.java b/project/QBarInterpreter/src/com/modulus/qbar/lang/IfThenElseFunction.java
new file mode 100644
index 0000000..8efbc5e
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/lang/IfThenElseFunction.java
@@ -0,0 +1,41 @@
+package com.modulus.qbar.lang;
+
+import com.modulus.common.collections.Stack;
+import com.modulus.qbar.core.QBFunction;
+import com.modulus.qbar.core.QBObject;
+import com.modulus.qbar.core.interpreter.QBInterpreter;
+import com.modulus.qbar.core.parser.ByteOperation;
+import com.modulus.qbar.core.primitive.QBPrimitive;
+
+public class IfThenElseFunction extends QBFunction {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 6694512700264765780L;
+ private ByteOperation[] ifPart, thenPart, elsePart;
+
+
+ public IfThenElseFunction(ByteOperation[] ifPart,
+ ByteOperation[] thenPart, ByteOperation[] elsePart) {
+ super(0);
+ this.ifPart = ifPart;
+ this.thenPart = thenPart;
+ this.elsePart = elsePart;
+ }
+
+
+ @Override
+ public QBObject execute(QBObject[] args) {
+ Stack<QBObject> stack = QBInterpreter.instance().getStack();
+ this.exec(ifPart, stack);
+
+ if(returnedValue instanceof QBPrimitive && ((QBPrimitive) returnedValue).intValue() != 0){
+ this.exec(thenPart, stack);
+ return returnedValue;
+ } else{
+ this.exec(elsePart, stack);
+ return returnedValue;
+ }
+ }
+
+}
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/lang/ListConstructor.java b/project/QBarInterpreter/src/com/modulus/qbar/lang/ListConstructor.java
new file mode 100644
index 0000000..2a89159
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/lang/ListConstructor.java
@@ -0,0 +1,17 @@
+package com.modulus.qbar.lang;
+
+import com.modulus.qbar.core.QBFunction;
+import com.modulus.qbar.core.QBObject;
+
+public abstract class ListConstructor extends QBFunction{
+
+ public ListConstructor() {
+ super(0);
+ }
+
+ public QBList execute(QBObject[] args){
+ return makeList();
+ }
+
+ protected abstract QBList makeList();
+}
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/lang/QBArrayList.java b/project/QBarInterpreter/src/com/modulus/qbar/lang/QBArrayList.java
new file mode 100644
index 0000000..c7ef64a
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/lang/QBArrayList.java
@@ -0,0 +1,98 @@
+package com.modulus.qbar.lang;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.modulus.qbar.core.QBFunction;
+import com.modulus.qbar.core.QBObject;
+import com.modulus.qbar.core.QBStruct;
+
+public class QBArrayList extends QBList{
+ private List<QBObject> values = new ArrayList<QBObject>();
+
+ public final static QBStruct arrayListStruct = new QBStruct("ArrayList");
+ public static final QBFunction APPEND = new QBFunction(2) {
+
+ @Override
+ public QBObject execute(QBObject[] args) {
+ QBArrayList lst = (QBArrayList)args[1];
+
+ return lst.append(args[0]);
+ }
+ };
+
+ static{
+ arrayListStruct.addSuperStruct(QBList.list);
+ arrayListStruct.set("++", APPEND);
+ }
+
+
+ public QBArrayList(QBObject[] objs){
+ super(arrayListStruct);
+ for( QBObject obj : objs )
+ values.add(obj);
+ }
+
+ public QBArrayList(QBObject[] objs, QBStruct struct){
+ super(struct);
+ for( QBObject obj : objs )
+ values.add(obj);
+ }
+
+ public QBArrayList() {
+ this( new QBObject[]{} );
+ }
+
+ public void insert(int index, QBObject element) {
+ values.add(index, element);
+ }
+
+ public QBObject add(QBObject e) {
+ values.add(e);
+ return this;
+ }
+
+ public void remove(QBObject arg0) {
+ values.remove(arg0);
+ }
+
+ public QBObject get(int idx){
+ if(idx < 0)
+ return values.get(values.size()+idx);
+
+ return values.get(idx);
+ }
+
+ public double size() {
+ return values.size();
+ }
+
+ public QBArrayList append(QBObject obj){
+ QBArrayList ret = new QBArrayList(new QBObject[]{});
+
+ ret.values.addAll(this.values);
+
+ if(obj instanceof QBArrayList)
+ ret.values.addAll(((QBArrayList) obj).values);
+
+ return ret;
+ }
+
+ public String toString(){
+ return values.toString();
+ }
+
+ public Object getWrapped(){
+ return values;
+ }
+
+ @Override
+ public QBList realSubList(int off, int len) {
+ QBArrayList ret = new QBArrayList();
+
+ for( int i = off, a = 0; a < len;i ++, a ++)
+ ret.add( this.get(i) );
+
+ return ret;
+ }
+}
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/lang/QBArrayListConstructor.java b/project/QBarInterpreter/src/com/modulus/qbar/lang/QBArrayListConstructor.java
new file mode 100644
index 0000000..a67e3a8
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/lang/QBArrayListConstructor.java
@@ -0,0 +1,29 @@
+package com.modulus.qbar.lang;
+
+import com.modulus.common.collections.Stack;
+import com.modulus.qbar.core.QBObject;
+import com.modulus.qbar.core.interpreter.QBInterpreter;
+import com.modulus.qbar.core.parser.ByteOperation;
+
+public class QBArrayListConstructor extends ListConstructor{
+ private ByteOperation[][] expressions;
+
+
+ public QBArrayListConstructor(ByteOperation[][] exp){
+ this.expressions = exp;
+ }
+ @Override
+ protected QBList makeList() {
+ QBObject[] objs = new QBObject[expressions.length];
+ Stack<QBObject> stack = QBInterpreter.instance().getStack();
+
+ for(int i = 0;i < expressions.length;i++){
+ this.exec( expressions[i], stack);
+ objs[i] = returnedValue;
+ }
+
+ QBList arr = new QBArrayList(objs);
+ return arr;
+ }
+
+}
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/lang/QBFunctionList.java b/project/QBarInterpreter/src/com/modulus/qbar/lang/QBFunctionList.java
new file mode 100644
index 0000000..1af40ca
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/lang/QBFunctionList.java
@@ -0,0 +1,54 @@
+package com.modulus.qbar.lang;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.modulus.qbar.core.QBFunction;
+import com.modulus.qbar.core.QBObject;
+import com.modulus.qbar.core.primitive.QBInt;
+
+public class QBFunctionList extends QBList{
+ private static final long serialVersionUID = -6236925720933913879L;
+ private Map<Integer, QBObject> listPart = new HashMap<Integer, QBObject>();
+ private QBFunction func;
+
+ public QBFunctionList(QBFunction func){
+ this.func = func;
+ }
+
+ @Override
+ public QBObject add(QBObject obj) {
+ return this;
+ }
+
+ @Override
+ public void remove(QBObject obj) {
+
+ }
+
+ @Override
+ public QBObject get(int idx) {
+ QBObject tmp = listPart.get(idx);
+
+ if(tmp == null)
+ listPart.put(idx, tmp = func.execute(new QBObject[]{new QBInt(idx), this}));
+
+ return tmp;
+ }
+
+ @Override
+ public double size() {
+ return Double.POSITIVE_INFINITY;
+ }
+
+ @Override
+ public void insert(int idx, QBObject obj) {
+ listPart.put(idx, obj);
+ }
+
+ @Override
+ public QBList realSubList(int off, int len) {
+ throw new RuntimeException("Sub-list type not supported for FunctionList.");
+ }
+
+}
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/lang/QBFunctionListConstructor.java b/project/QBarInterpreter/src/com/modulus/qbar/lang/QBFunctionListConstructor.java
new file mode 100644
index 0000000..cb0a626
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/lang/QBFunctionListConstructor.java
@@ -0,0 +1,18 @@
+package com.modulus.qbar.lang;
+
+import com.modulus.qbar.core.QBFunction;
+
+public class QBFunctionListConstructor extends ListConstructor{
+ private static final long serialVersionUID = 5847772733369552908L;
+ private QBFunction func;
+
+ public QBFunctionListConstructor(QBFunction func){
+ this.func = func;
+ }
+
+ @Override
+ protected QBList makeList() {
+ QBList lst = new QBFunctionList(func);
+ return lst;
+ }
+}
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/lang/QBFunctionListFunction.java b/project/QBarInterpreter/src/com/modulus/qbar/lang/QBFunctionListFunction.java
new file mode 100644
index 0000000..80d8667
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/lang/QBFunctionListFunction.java
@@ -0,0 +1,66 @@
+package com.modulus.qbar.lang;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.modulus.common.collections.ArrayStack;
+import com.modulus.common.collections.Stack;
+import com.modulus.qbar.core.QBFunction;
+import com.modulus.qbar.core.QBNamespace;
+import com.modulus.qbar.core.QBObject;
+import com.modulus.qbar.core.interpreter.QBInterpreter;
+import com.modulus.qbar.core.parser.ByteOperation;
+
+public class QBFunctionListFunction extends QBFunction{
+ private static final long serialVersionUID = 1123773383702904111L;
+ private ByteOperation[] command;
+ private String var;
+ private static Map<String, QBObject> namespaceTemplate = new HashMap<String,QBObject>();
+ private Stack<QBNamespace> namespaceCalls = new ArrayStack<QBNamespace>();
+
+ public QBFunctionListFunction( ){
+ super(2);
+ namespaceCalls.push(new QBNamespace(namespaceTemplate));
+ }
+
+ public ByteOperation[] getCommand() {
+ return command;
+ }
+
+ public void setCommand(ByteOperation[] command) {
+ this.command = command;
+ }
+
+ public String getVar() {
+ return var;
+ }
+
+ public void setVar(String var) {
+ this.var = var;
+ }
+
+ @Override
+ public QBObject execute(QBObject[] args){
+ QBNamespace tmp = new QBNamespace(new HashMap<String, QBObject>());
+ tmp.setSuper(this.getSuper());
+
+ namespaceCalls.push(tmp);
+ this.set(var, args[0]);
+ this.set("this", args[1]);
+ Stack<QBObject> stack = QBInterpreter.instance().getStack();
+
+ exec(command, stack);
+ namespaceCalls.pop();
+ return returnedValue;
+ }
+
+ @Override
+ public QBObject get(String name){
+ return namespaceCalls.peek().get(name);
+ }
+
+ @Override
+ public void set(String name, QBObject obj){
+ namespaceCalls.peek().set(name, obj);
+ }
+}
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/lang/QBIterator.java b/project/QBarInterpreter/src/com/modulus/qbar/lang/QBIterator.java
new file mode 100644
index 0000000..251e6f3
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/lang/QBIterator.java
@@ -0,0 +1,124 @@
+package com.modulus.qbar.lang;
+
+import java.util.Iterator;
+
+import com.modulus.qbar.core.QBFunction;
+import com.modulus.qbar.core.QBNamespace;
+import com.modulus.qbar.core.QBObject;
+import com.modulus.qbar.core.QBStruct;
+import com.modulus.qbar.core.primitive.QBInt;
+
+public abstract class QBIterator<T extends QBObject> extends QBObject implements Iterator<QBObject>{
+ /**
+ *
+ */
+ private static final long serialVersionUID = -8496833881500665535L;
+ private String variableName;
+ private T iterable;
+
+ public static final QBStruct ITERATOR = new QBStruct("Iterator");
+
+ public static final QBFunction hasNext = new QBFunction(1){
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -7059204966992996830L;
+
+ @Override
+ public QBObject execute(QBObject[] args) {
+ QBObject obj = args[0];
+ QBIterator iter = (QBIterator) obj;
+
+ return iter.hasNext() ? new QBInt(1) : new QBInt(0);
+ }
+
+ };
+
+ public static final QBFunction next = new QBFunction(1){
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 9165087060843674645L;
+
+ @Override
+ public QBObject execute(QBObject[] args) {
+ QBObject obj = args[0];
+
+ @SuppressWarnings("unchecked")
+ QBIterator<QBObject> iter = (QBIterator<QBObject>) obj;
+
+ return iter.next();
+ }
+
+ };
+
+ static{
+ ITERATOR.set("hasNext", hasNext);
+ ITERATOR.set("next", next);
+ }
+
+ private QBNamespace variableNmspce;
+
+ public QBIterator(T iterable) {
+ super(ITERATOR);
+ this.iterable = iterable;
+ }
+
+ @Override
+ public QBObject get(String str){
+ QBNamespace sup = this.getSuper();
+
+ if(sup == null)
+ return null;
+
+ return sup.get(str);
+ }
+
+ @Override
+ public void set(String str, QBObject obj){
+ QBNamespace sup = this.getSuper();
+
+ if( this.variableName.equals(str) && sup != null)
+ variableNmspce.set(str, obj);
+
+ else
+ super.set(str, obj);
+ }
+
+ @Override
+ public void remove() {
+ throw new RuntimeException("Not Implemented");
+ }
+
+ public void setVariableName(String variableName) {
+ this.variableName = variableName;
+ }
+
+ public String getVariableName() {
+ return variableName;
+ }
+
+ public T getIterable() {
+ return iterable;
+ }
+
+ protected abstract QBObject nextObject();
+
+ public QBObject next(){
+
+ QBObject ret = nextObject();
+ this.set(this.getVariableName(), ret);
+
+ return ret;
+ }
+
+ public void setVariableNmspce(QBNamespace variableNmspce) {
+ this.variableNmspce = variableNmspce;
+ }
+
+ public QBNamespace getVariableNmspce() {
+ return variableNmspce;
+ }
+}
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/lang/QBLazyRangeList.java b/project/QBarInterpreter/src/com/modulus/qbar/lang/QBLazyRangeList.java
new file mode 100644
index 0000000..5f35496
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/lang/QBLazyRangeList.java
@@ -0,0 +1,92 @@
+package com.modulus.qbar.lang;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.modulus.qbar.core.QBObject;
+import com.modulus.qbar.core.primitive.QBDouble;
+import com.modulus.qbar.core.primitive.QBInt;
+import com.modulus.qbar.core.primitive.QBPrimitive;
+
+public class QBLazyRangeList extends QBList{
+ private static final long serialVersionUID = -782755006057179634L;
+ private QBPrimitive startValue;
+ private QBPrimitive endValue;
+ private QBPrimitive changeValue;
+
+ private boolean isIntegers;
+ private boolean isInfinite;
+
+ //private List<QBPrimitive> items = new ArrayList<QBPrimitive>();
+
+ public QBLazyRangeList(QBPrimitive startValue, QBPrimitive endValue,
+ QBPrimitive changeValue) {
+ super();
+ this.startValue = startValue;
+ this.endValue = endValue;
+ this.changeValue = changeValue;
+
+ if(endValue == null)
+ isInfinite = true;
+
+ if(changeValue == null)
+ this.changeValue = new QBInt(1);
+
+ if(this.changeValue instanceof QBInt && this.startValue instanceof QBInt)
+ isIntegers = true;
+
+ }
+
+ @Override
+ public QBObject add(QBObject obj) {
+ return this;
+ }
+
+ @Override
+ public void remove(QBObject obj) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public QBPrimitive get(int idx) {
+ if(idx < 0)
+ idx = (int) (this.size() + idx);
+
+ if( isIntegers )
+ {
+ int ret = startValue.intValue() + idx * changeValue.intValue();
+ if( this.isInfinite || ret <= endValue.intValue() )
+ return new QBInt(ret);
+ else
+ throw new ArrayIndexOutOfBoundsException("The index: " + idx + " is out of range for " + this + "\nMax value is: " + endValue + " got " + ret);
+ } else{
+ double ret = startValue.doubleValue() + idx * changeValue.doubleValue();
+ if( this.isInfinite || ret <= endValue.doubleValue() )
+ return new QBDouble(ret);
+ else
+ throw new ArrayIndexOutOfBoundsException("The index: " + idx + " is out of range for " + this + "\nMax value is: " + endValue + " got " + ret);
+ }
+ }
+
+ @Override
+ public double size() {
+ if(isInfinite)
+ return Double.POSITIVE_INFINITY;
+
+ else
+ return Math.abs(endValue.doubleValue() - startValue.doubleValue()) / changeValue.doubleValue() + 1;
+ }
+
+ @Override
+ public void insert(int idx, QBObject obj) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public QBList realSubList(int off, int len) {
+ return new QBLazyRangeList(get(off), get(off + len), changeValue);
+ }
+
+}
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/lang/QBLazyRangeListConstructor.java b/project/QBarInterpreter/src/com/modulus/qbar/lang/QBLazyRangeListConstructor.java
new file mode 100644
index 0000000..5465515
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/lang/QBLazyRangeListConstructor.java
@@ -0,0 +1,65 @@
+package com.modulus.qbar.lang;
+
+import com.modulus.common.collections.Stack;
+import com.modulus.qbar.core.QBObject;
+import com.modulus.qbar.core.interpreter.QBInterpreter;
+import com.modulus.qbar.core.parser.ByteOperation;
+import com.modulus.qbar.core.primitive.QBDouble;
+import com.modulus.qbar.core.primitive.QBInt;
+import com.modulus.qbar.core.primitive.QBPrimitive;
+
+public class QBLazyRangeListConstructor extends ListConstructor{
+ private static final long serialVersionUID = -3617305937103054888L;
+
+ private ByteOperation[] start;
+ private ByteOperation[] second;
+ private ByteOperation[] end;
+
+ public QBLazyRangeListConstructor(ByteOperation[] start,
+ ByteOperation[] second, ByteOperation[] end) {
+ super();
+ this.start = start;
+ this.second = second;
+ this.end = end;
+ }
+
+ @Override
+ protected QBList makeList() {
+ Stack<QBObject> stack = QBInterpreter.instance().getStack();
+
+ QBPrimitive startValue;
+ if(start == null){
+ startValue = null;
+ } else{
+ exec( start, stack );
+ startValue = (QBPrimitive) returnedValue;
+ }
+
+ QBPrimitive secondValue;
+ if(second == null){
+ secondValue = null;
+ } else {
+ exec( second, stack );
+ secondValue = (QBPrimitive) returnedValue;
+ }
+
+ QBPrimitive endValue;
+ if(end == null){
+ endValue = null;
+ } else{
+ exec( end, stack );
+ endValue = (QBPrimitive) returnedValue;
+ }
+
+ double change = secondValue == null ? 1 : secondValue.doubleValue() - startValue.doubleValue();
+
+ QBPrimitive changeValue;
+ if(change % 1 == 0 && startValue instanceof QBInt)
+ changeValue = new QBInt((int)change);
+ else
+ changeValue = new QBDouble(change);
+
+ return new QBLazyRangeList(startValue, endValue, changeValue);
+ }
+
+}
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/lang/QBList.java b/project/QBarInterpreter/src/com/modulus/qbar/lang/QBList.java
new file mode 100644
index 0000000..8e3ed8f
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/lang/QBList.java
@@ -0,0 +1,160 @@
+package com.modulus.qbar.lang;
+
+import com.modulus.qbar.core.QBFunction;
+import com.modulus.qbar.core.QBObject;
+import com.modulus.qbar.core.QBStruct;
+import com.modulus.qbar.core.parser.QBExpressionParser;
+import com.modulus.qbar.core.primitive.QBDouble;
+import com.modulus.qbar.core.primitive.QBInt;
+
+public abstract class QBList extends QBObject implements Cloneable{
+ /**
+ *
+ */
+ private static final long serialVersionUID = -3820130303027533210L;
+
+ static final public QBStruct list = new QBStruct("list");
+
+ static final public QBFunction ADD = new QBFunction(2) {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1966242605460532062L;
+
+ @Override
+ public QBObject execute(QBObject[] args) {
+ QBList ths = (QBList)args[1];
+ ths.add(args[0]);
+ return ths;
+ }
+ };
+
+ static final public QBFunction INSERT = new QBFunction(3) {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -4254176176696884954L;
+
+ @Override
+ public QBObject execute(QBObject[] args) {
+ QBList ths = (QBList)args[2];
+ ths.insert( ((QBInt)args[1]).intValue(), args[0] );
+ return ths;
+ }
+ };
+
+ static final public QBFunction REMOVE = new QBFunction(2) {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -5952990904494730121L;
+
+ @Override
+ public QBObject execute(QBObject[] args) {
+ QBList ths = (QBList)args[1];
+ ths.remove( args[0] );
+ return ths;
+ }
+ };
+
+ static final public QBFunction GET = new QBFunction(2) {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -4826771802410960653L;
+
+ @Override
+ public QBObject execute(QBObject[] args) {
+ QBList ths = (QBList)args[1];
+ return ths.get(((QBInt) args[0]).intValue());
+ }
+ };
+
+ static final public QBFunction ITERATOR = new QBFunction(2) {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 3915900913102253534L;
+
+ @Override
+ public QBObject execute(QBObject[] args) {
+ QBIterator<QBList> ret = new QBListIterator( (QBList)args[0] );
+ return ret;
+ }
+ };
+
+ static final public QBFunction SUBLIST = new QBFunction(3) {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 3915900913102253534L;
+
+ @Override
+ public QBObject execute(QBObject[] args) {
+ QBList ths = (QBList) args[2];
+ int off = ((QBInt) args[0]).intValue();
+ int len = ((QBInt) args[1]).intValue();
+
+ return new QBSubList(ths, off, len);
+ }
+ };
+
+
+ public static void init(){
+ list.set("add", ADD);
+ list.set("remove", REMOVE);
+ list.set("insert", INSERT);
+ list.set("get", GET);
+
+ list.set("#", GET);
+ list.set("+<", ADD);
+ list.set("-<", REMOVE);
+
+ list.set("iterator", ITERATOR);
+ list.set("subList", SUBLIST);
+
+ QBExpressionParser.mapOp("#", 9);
+ QBExpressionParser.mapOp("+<", 1024);
+ QBExpressionParser.mapOp("-<", 1024);
+ }
+
+ public QBList() {
+ super(list);
+ }
+
+ public QBList(QBStruct struct) {
+ super(struct);
+ }
+
+ @Override
+ public QBObject get(String name){
+ if(name.equals("length")){
+ double size = size();
+
+ if( Double.isInfinite(size) || Double.isNaN(size) || size %1 != 0)
+ return new QBDouble(size());
+
+ return new QBInt((int)size());
+ }
+
+ return super.get(name);
+ }
+
+ abstract public QBList realSubList( int off, int len );
+
+ abstract public QBObject add(QBObject obj);
+
+ abstract public void remove(QBObject obj);
+
+ abstract public QBObject get(int idx);
+
+ abstract public double size();
+
+ abstract public void insert(int idx, QBObject obj);
+
+// abstract public QBList concat( QBList other );
+}
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/lang/QBListFactory.java b/project/QBarInterpreter/src/com/modulus/qbar/lang/QBListFactory.java
new file mode 100644
index 0000000..99a5269
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/lang/QBListFactory.java
@@ -0,0 +1,5 @@
+package com.modulus.qbar.lang;
+
+public class QBListFactory {
+
+}
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/lang/QBListIterator.java b/project/QBarInterpreter/src/com/modulus/qbar/lang/QBListIterator.java
new file mode 100644
index 0000000..97a4254
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/lang/QBListIterator.java
@@ -0,0 +1,30 @@
+package com.modulus.qbar.lang;
+
+import com.modulus.qbar.core.QBObject;
+
+public class QBListIterator extends QBIterator<QBList> {
+ private static final long serialVersionUID = 8306618418948706270L;
+ int index = 0;;
+ public QBListIterator(QBList lst){
+ super(lst);
+
+ if(lst == null)
+ throw new RuntimeException("How the Hell is this NULL?");
+ }
+
+ @Override
+ public boolean hasNext() {
+ QBList iterable = this.getIterable();
+ return index < iterable.size();
+ }
+
+ @Override
+ protected QBObject nextObject() {
+ QBList lst = this.getIterable();
+
+ QBObject ret = lst.get(index ++);
+
+ return ret;
+ }
+
+}
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/lang/QBMath.java b/project/QBarInterpreter/src/com/modulus/qbar/lang/QBMath.java
new file mode 100644
index 0000000..33ae016
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/lang/QBMath.java
@@ -0,0 +1,243 @@
+package com.modulus.qbar.lang;
+
+public class QBMath {
+ public static double abs(double o0){
+ return Math.abs(o0);
+ }
+ /**
+ *@see Math#sin
+ */
+ public static double sin(double o0){
+ return Math.sin(o0);
+ }
+ /**
+ *@see Math#cos
+ */
+ public static double cos(double o0){
+ return Math.cos(o0);
+ }
+ /**
+ *@see Math#tan
+ */
+ public static double tan(double o0){
+ return Math.tan(o0);
+ }
+ /**
+ *@see Math#atan2
+ */
+ public static double atan2(double o0, double o1){
+ return Math.atan2(o0, o1);
+ }
+ /**
+ *@see Math#sqrt
+ */
+ public static double sqrt(double o0){
+ return Math.sqrt(o0);
+ }
+ /**
+ *@see Math#log
+ */
+ public static double log(double o0){
+ return Math.log(o0);
+ }
+ /**
+ *@see Math#log10
+ */
+ public static double log10(double o0){
+ return Math.log10(o0);
+ }
+ /**
+ *@see Math#pow
+ */
+ public static double pow(double o0, double o1){
+ return Math.pow(o0, o1);
+ }
+ /**
+ *@see Math#exp
+ */
+ public static double exp(double o0){
+ return Math.exp(o0);
+ }
+ /**
+ *@see Math#min
+ */
+ public static double min(double o0, double o1){
+ return Math.min(o0, o1);
+ }
+ /**
+ *@see Math#max
+ */
+ public static double max(double o0, double o1){
+ return Math.max(o0, o1);
+ }
+ /**
+ *@see Math#scalb
+ */
+ public static double scalb(double o0, int o1){
+ return Math.scalb(o0, o1);
+ }
+ /**
+ *@see Math#getExponent
+ */
+ public static int getExponent(double o0){
+ return Math.getExponent(o0);
+ }
+ /**
+ *@see Math#signum
+ */
+ public static double signum(double o0){
+ return Math.signum(o0);
+ }
+ /**
+ *@see Math#asin
+ */
+ public static double asin(double o0){
+ return Math.asin(o0);
+ }
+ /**
+ *@see Math#acos
+ */
+ public static double acos(double o0){
+ return Math.acos(o0);
+ }
+ /**
+ *@see Math#atan
+ */
+ public static double atan(double o0){
+ return Math.atan(o0);
+ }
+ /**
+ *@see Math#toRadians
+ */
+ public static double toRadians(double o0){
+ return Math.toRadians(o0);
+ }
+ /**
+ *@see Math#toDegrees
+ */
+ public static double toDegrees(double o0){
+ return Math.toDegrees(o0);
+ }
+ /**
+ *@see Math#cbrt
+ */
+ public static double cbrt(double o0){
+ return Math.cbrt(o0);
+ }
+ /**
+ *@see Math#IEEEremainder
+ */
+ public static double IEEEremainder(double o0, double o1){
+ return Math.IEEEremainder(o0, o1);
+ }
+ /**
+ *@see Math#ceil
+ */
+ public static double ceil(double o0){
+ return Math.ceil(o0);
+ }
+ /**
+ *@see Math#floor
+ */
+ public static double floor(double o0){
+ return Math.floor(o0);
+ }
+ /**
+ *@see Math#rint
+ */
+ public static double rint(double o0){
+ return Math.rint(o0);
+ }
+ /**
+ *@see Math#round
+ */
+ public static long round(double o0){
+ return Math.round(o0);
+ }
+ /**
+ *@see Math#random
+ */
+ public static double random(){
+ return Math.random();
+ }
+ /**
+ *@see Math#ulp
+ */
+ public static double ulp(double o0){
+ return Math.ulp(o0);
+ }
+ /**
+ *@see Math#ulp
+ */
+ public static float ulp(float o0){
+ return Math.ulp(o0);
+ }
+ /**
+ *@see Math#sinh
+ */
+ public static double sinh(double o0){
+ return Math.sinh(o0);
+ }
+ /**
+ *@see Math#cosh
+ */
+ public static double cosh(double o0){
+ return Math.cosh(o0);
+ }
+ /**
+ *@see Math#tanh
+ */
+ public static double tanh(double o0){
+ return Math.tanh(o0);
+ }
+ /**
+ *@see Math#hypot
+ */
+ public static double hypot(double o0, double o1){
+ return Math.hypot(o0, o1);
+ }
+ /**
+ *@see Math#expm1
+ */
+ public static double expm1(double o0){
+ return Math.expm1(o0);
+ }
+ /**
+ *@see Math#log1p
+ */
+ public static double log1p(double o0){
+ return Math.log1p(o0);
+ }
+ /**
+ *@see Math#copySign
+ */
+ public static double copySign(double o0, double o1){
+ return Math.copySign(o0, o1);
+ }
+ /**
+ *@see Math#nextAfter
+ */
+ public static double nextAfter(double o0, double o1){
+ return Math.nextAfter(o0, o1);
+ }
+ /**
+ *@see Math#nextUp
+ */
+ public static double nextUp(double o0){
+ return Math.nextUp(o0);
+ }
+
+ /**
+ * returns PI
+ */
+ public static double getPI(){
+ return Math.PI;
+ }
+
+ /**
+ * returns E
+ */
+ public static double getE(){
+ return Math.E;
+ }
+}
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/lang/QBMaybe.java b/project/QBarInterpreter/src/com/modulus/qbar/lang/QBMaybe.java
new file mode 100644
index 0000000..c0f4a0c
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/lang/QBMaybe.java
@@ -0,0 +1,59 @@
+package com.modulus.qbar.lang;
+
+import com.modulus.qbar.core.QBFunction;
+import com.modulus.qbar.core.QBObject;
+import com.modulus.qbar.core.QBStruct;
+import com.modulus.qbar.core.exceptions.ExecutionException;
+import com.modulus.qbar.integration.QBWrappedObject;
+public class QBMaybe {
+ public static class Maybe extends QBObject{
+
+ public static final QBStruct struct = new QBStruct("Maybe");
+
+ static{
+ struct.set("getValue", new QBFunction(1){
+ @Override
+ public QBObject execute(QBObject[] args) {
+ Maybe ths = (Maybe)args[args.length-1];
+ return QBWrappedObject.wrap(ths.getValue());
+ }
+ });
+
+ struct.set("isNull", new QBFunction(1){
+ @Override
+ public QBObject execute(QBObject[] args) {
+ Maybe ths = (Maybe)args[args.length-1];
+ return QBWrappedObject.wrap(ths.isNull());
+ }
+ });
+ }
+
+ public Maybe(QBObject value) {
+ super(struct);
+ this.value = value;
+ }
+
+ private QBObject value;
+
+
+ public QBObject getValue(){
+ if(isNull()){
+ throw new ExecutionException("Attempted te get value of Null Type Maybe!");
+ }
+
+ return value;
+ }
+
+ public boolean isNull(){
+ return value == null;
+ }
+ }
+
+ public static QBObject new$0x20Maybe(QBObject obj){
+ return new Maybe(obj);
+ }
+
+ public static QBObject new$0x20Null(){
+ return new Maybe(null);
+ }
+}
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/lang/QBString.java b/project/QBarInterpreter/src/com/modulus/qbar/lang/QBString.java
new file mode 100644
index 0000000..4e931f8
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/lang/QBString.java
@@ -0,0 +1,111 @@
+package com.modulus.qbar.lang;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.modulus.qbar.core.QBObject;
+import com.modulus.qbar.core.QBStruct;
+import com.modulus.qbar.core.exceptions.ParseException;
+import com.modulus.qbar.core.primitive.QBChar;
+
+public class QBString extends QBArrayList {
+
+ public static final QBStruct string = new QBStruct("String", QBList.list){
+
+ };
+
+ private static Map<String, String> escapes = new HashMap<String, String>();
+
+ static{
+ string.addSuperStruct(QBArrayList.arrayListStruct);
+
+ escapes.put("\\n", "\n");
+ escapes.put("\\\\", "\\");
+ escapes.put("\\r", "\r");
+ escapes.put("\\t", "\t");
+ escapes.put("\\\"", "\"");
+ escapes.put("\\'", "'");
+ }
+
+ public QBString(QBChar[] objs) {
+ super(objs, string);
+ }
+
+ public QBString(String str, boolean parse){
+ this( dynamicCast(str,parse) );
+ }
+
+ @Override
+ public String getWrapped(){
+ StringBuffer buf = new StringBuffer();
+
+ for(int i = 0;i < this.size();i++)
+ buf.append( this.get(i) );
+
+ return buf.toString();
+ }
+
+ private static QBChar[] dynamicCast(String str, boolean parse){
+ if(parse)
+ str = parseString(str);
+
+ char[] chars = str.toCharArray();
+ QBChar[] chars2 = new QBChar[chars.length];
+
+ for(int i =0 ;i < chars.length;i++)
+ chars2[i] = new QBChar(chars[i]);
+
+ return chars2;
+ }
+
+ public String toString(){
+ return this.getWrapped();
+ }
+
+ @Override
+ public QBArrayList append(QBObject obj){
+ String str1 = this.toString();
+ String str2 = obj.toString();
+
+ return new QBString(str1 + str2, false);
+ }
+
+ @Override
+ public QBObject add(QBObject obj){
+ String str = obj.toString();
+
+ for(int i = 0;i < str.length();i++){
+ super.add( new QBChar(str.charAt(i)) );
+ }
+
+ return this;
+ }
+
+ private static String parseString(String str){
+ StringBuffer buf = new StringBuffer();
+ boolean escaped = false;
+ for( int i = 0;i < str.length();i ++){
+ if(str.startsWith("\\", i)){
+ for ( String key : escapes.keySet() ){
+ // System.out.printf("str.startsWith( %s, %s )\n", key, i);
+ if( str.startsWith(key, i) ){
+ buf.append( escapes.get(key) );
+ i++;
+
+ escaped = true;
+ break;
+ }
+ }
+ }
+
+ if(!escaped){
+ buf.append(str.charAt(i));
+ } else {
+ escaped = false;
+ }
+ }
+
+ return buf.toString();
+ }
+
+}
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/lang/QBSubList.java b/project/QBarInterpreter/src/com/modulus/qbar/lang/QBSubList.java
new file mode 100644
index 0000000..45e9a92
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/lang/QBSubList.java
@@ -0,0 +1,77 @@
+package com.modulus.qbar.lang;
+
+import com.modulus.qbar.core.QBObject;
+
+public class QBSubList extends QBList {
+ private static final long serialVersionUID = 8841750568883987599L;
+ private QBList original;
+ private boolean originalIsOriginal = true;
+
+ private int offset;
+ private int length;
+
+ public QBSubList(QBList original, int offset, int length) {
+ super();
+ this.original = original;
+ this.offset = offset;
+ this.length = length;
+ }
+
+ private void checkOriginal(){
+ if(originalIsOriginal){
+ original = original.realSubList(offset, length);
+ originalIsOriginal = false;
+ }
+ }
+
+ @Override
+ public QBObject add(QBObject obj) {
+ checkOriginal();
+ return original.add(obj);
+ }
+
+ @Override
+ public void remove(QBObject obj) {
+ checkOriginal();
+ original.remove(obj);
+ }
+
+ @Override
+ public QBObject get(int idx) {
+ if(originalIsOriginal) {
+ return original.get(idx + offset);
+ } else {
+ return original.get(idx);
+ }
+ }
+
+ @Override
+ public double size() {
+ if( originalIsOriginal )
+ return this.length;
+ return original.size();
+ }
+
+ @Override
+ public void insert(int idx, QBObject obj) {
+ checkOriginal();
+ original.insert(idx, obj);
+ }
+
+ @Override
+ public QBList realSubList(int off, int len) {
+ return original.realSubList(off + offset, len);
+ }
+
+ public String toString(){
+ StringBuffer buf = new StringBuffer("[");
+
+ for( int i = 0;i < this.size(); i ++)
+ buf.append( this.get(i).toString() + ", ");
+
+ buf.deleteCharAt(buf.length()-1);
+ buf.deleteCharAt(buf.length()-1);
+
+ return buf.toString() + "]";
+ }
+}
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/lang/QBSyntheticIterator.java b/project/QBarInterpreter/src/com/modulus/qbar/lang/QBSyntheticIterator.java
new file mode 100644
index 0000000..0fdfed5
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/lang/QBSyntheticIterator.java
@@ -0,0 +1,31 @@
+package com.modulus.qbar.lang;
+
+import com.modulus.qbar.core.QBFunction;
+import com.modulus.qbar.core.QBObject;
+import com.modulus.qbar.core.parser.Core;
+
+public class QBSyntheticIterator extends QBIterator<QBObject>{
+ private static final long serialVersionUID = -1890206471197459684L;
+ private QBFunction next;
+ private QBFunction hasNext;
+ private QBObject wrapped;
+
+ public QBSyntheticIterator(QBObject iterable, QBObject wrapped) {
+ super(iterable);
+
+ this.wrapped = wrapped;
+ this.next = (QBFunction) wrapped.get("next");
+ this.hasNext = (QBFunction) wrapped.get("hasNext");
+ }
+
+ @Override
+ public boolean hasNext() {
+ return Core.QBObjectIsTrue( hasNext.execute( new QBObject[]{wrapped} ) );
+ }
+
+ @Override
+ protected QBObject nextObject() {
+ return next.execute( new QBObject[]{wrapped} );
+ }
+
+}
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/lang/QBSystem.java b/project/QBarInterpreter/src/com/modulus/qbar/lang/QBSystem.java
new file mode 100644
index 0000000..86649a7
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/lang/QBSystem.java
@@ -0,0 +1,11 @@
+package com.modulus.qbar.lang;
+
+public class QBSystem {
+ public static int time(){
+ return (int) System.currentTimeMillis();
+ }
+
+ public static void exit( int status ){
+ System.exit( status );
+ }
+}
diff --git a/project/QBarInterpreter/src/com/modulus/qbar/lang/Test.java b/project/QBarInterpreter/src/com/modulus/qbar/lang/Test.java
new file mode 100644
index 0000000..6935fe1
--- /dev/null
+++ b/project/QBarInterpreter/src/com/modulus/qbar/lang/Test.java
@@ -0,0 +1,11 @@
+package com.modulus.qbar.lang;
+
+public class Test {
+ public static void printNum( Number num ){
+ System.out.println(num);
+ }
+
+ public static void printStrLn(String str){
+ System.out.println(str);
+ }
+}
diff --git a/qbar-installer.tgz b/qbar-installer.tgz
new file mode 100755
index 0000000..2ad6ad3
--- /dev/null
+++ b/qbar-installer.tgz
Binary files differ