GlassCalc 2 Update


As great as Mathieu Jacques’s MTParser is, it only supports double-precision floating point numbers and it only works with .NET through a COM interface, which means I have less control over the parser and I have to register the dll.  Therefore, GlassCalc 2 will feature a new parser which I am writing from the ground up. I call this new parser GCParser. I am awesome at naming things.

Here is a fairly technical description of how GCParser will work:

Design Goals of GCParser

  • The parser will operate on objects deriving from GCObject. This is a completely generic class, and in fact, the only function a GCObject must have converts the object to a string so it can be displayed.
  • GCParser will have two types of GCObject out-of-the-metaphorical-box: numbers and arrays. Arrays are lists of GCObjects. This means GCParser will support vector operations, and since you can make arrays of arrays, probably matrix operations too.
  • The syntax for arrays should be familiar to anyone who has programmed in C or JavaScript. a = [1, 2, 3] is a 3-element array. a[0] retrieves the first element of the array.
  • GCObjects can have properties and functions. For instance, arrays will have x, y, and z properties to make 3d vector operations easy. [1, 2, 3].x will return 1. Also, [2, 3, 1].sort() would return [1, 2, 3].
  • GCParser will be able to operate on multiple types at once. For instance, when executing 2 * [3, 4] the parser would search for a Multiply function taking two arguments of types GCNumber and GCArray. This expression would evaluate to [6, 8]. If no function was found, the parser would throw a type error.
  • GCParser will be extensible. Extensions will be able to define not only constants and functions, but new GCObject types as well. For instance, a complex numbers extension could define a GCComplexNumber class, functions for operating on complex numbers, and a constant i. Since the parser will only create numbers and arrays normally, the extension would also need to define a constructor function, Complex(real, imag), to make complex numbers. If the extension defined functions for adding/multiplying numbers and complex numbers together, the expression 1 + 2i would also work. The parser would interpret this as (number: 1) + ((number: 2) * (complex: 0 + i)).
  • I haven’t figured out how this would work yet, but I want GCParser to support expressions like [1, 2, 3].sort((a,b) => b<a). This would send a predicate function to the sort function telling it how to sort—in this case, sort descending. Likewise, Sum(n => 0.5^n, 1, 50) would sum 0.5n from n = 1 to 50.
  • Parsing occurs in three stages: tokenization, parsing and evaluation. Tokenization takes the expression and figures out what all the individual parts mean. It also generates a structure which the syntax highlighter can use instead of the convoluted regular expression system GlassCalc currently uses. Parsing takes the tokenized expression and converts it into a binary tree of operations. Evaluation traverses the tree, running each operation until it gets a final result. Parsing and evaluation will not run on the UI thread, so the program won’t freeze up if you run a long calculation.

Things That Are Not Design Goals of GCParser

  • Be really fast.

tl;dr Version

  • GlassCalc 2 will have a new parser. It will be magic, rainbows and unicorns. It will calculate just about anything.
  • If it can’t calculate something, you can probably write an extension so it can.

So, when will it be done? Eventually. I have the tokenizer mostly complete. I am waiting for .NET 4.5 to be released before I start work on the UI, as I will make use of its new asynchronous stuff.