Tuesday, July 12, 2011

Magnificalc Ecosystem Part 1: ExprTreeLib in JavaScript

I am pleased to announce that ExprTreeLib has been completely rewritten in JavaScript so it is now portable from web to desktop to mobile! Yippee! ExprTreeLib in JavaScript looks and feels somewhat similar to its Java counterpart, except that it takes less code to do something useful with JavaScript.
Here are some more updates for the Magnificalc Ecosystem:
  • PEGJS is used to generate the parser. The PEGJS version of the grammar was adapted from the ANTLR3 grammar and now fits better in the PEG style.
  • Appcelerator Titanium (http://developer.appcelerator.com) will now be used as the desktop and mobile app development tool. The JavaScript code will be run in Titanium on Android and in the browser for the web.
  • The Dojo Toolkit (http://dojotoolkit.org) is Magnificalc's official JavaScript toolkit. Dojo's libraries like Dijit, dojox.gfx, and the Editor packages make it quite desirable! Dojo is built on a rock-solid cross-browser core, so I never have to worry about browser compatibility issues, except when using HTML5 features.
  • The server side will be built with Django, Orbited, and MorbidQ. That way, plugins and saved settings will be "pushed" to the web application while it is loading (!), allowing for a completely asynchronous load.
Hope you're excited for what comes next! Part 2, the GraphGen tool, is already in development!

Thursday, June 23, 2011

Magnificalc as an Ecosystem

I would like to announce a change of direction for Magnificalc as a project. Magnificalc will no longer be strictly about developing an Android app and reusable libraries. Magnificalc will now have the following vision:

  • A modular advanced graphing calculator, accessible across platforms
  • Used as a teaching tool
  • Synchronization across device boundaries

Synchronization will be implemented as decentralized as possible to avoid the possibility of central ownership of user data. The plugins and history for any given user will be synced to a cloud server (backend pending), then one will be able to access their data anywhere: on their Android device, their desktop computer, or the web.

Appcelerator Titanium may power this new vision by allowing JavaScript code for the web to be reused! A version of exprtreelib for JavaScript is in development now.

Thursday, June 16, 2011

Announcing exprtreelib release

Today, after nearly two months of work, I am pleased to announce the release of Magnificalc's first and most essential component, exprtreelib! exprtreelib performs the following functions:
  • Parsing of expressions
  • Construction of expression trees
  • Representation of expressions as trees
exprtreelib consists of a main entry class: the ExpressionParser, and classes to represent parts of an expression, namely Expression, Term, and Factor. The following types of factor are supported:
  • Constant
  • Variable (with attached coefficient)
  • Function
  • Subexpression
All factors contain an associated exponent field, which is a factor itself.

An implementation of a symbol table using a Rudolf Bayer red-black tree (1972) is included in the library. The symbol table is a required argument to the isAbstract and evaluate methods of interface INode.

The parser is written with ANTLRv3, and the objects are written in Java. The unit tests are written with the ScalaTest BDD framework.

To get the source and compile it, visit the project site at http://moosna-saltlakecity.github.com/exprtreelib! Happy coding!

Wednesday, June 8, 2011

Oops! Decision made too quickly.

Well, after experimenting with Adobe AIR/Flex 4.5, I discovered that the requirements of my app could not be attained with AIR on Android. I must support Android Eclair and up on as low as ARM6 devices at 600MHz! AIR cannot do that for me, therefore, I am switching back to Java, with Maven3 as my build tool. Sorry, I got too excited when I posted my last post! Follow this blog to get more updates on Magnificalc's progress!

Friday, June 3, 2011

Moving to Adobe Flex 4.5

Hey everyone,

Today I'm pleased to announce that Magnificalc is being rewritten in ActionScript3 for Adobe Flex 4.5! This will make Magnificalc runnable over the web (with Flash Player), on the desktop (with AIR for desktop), and on mobile (AIR 2.6 for Android, AIR for BlackBerry).

Now, one may be asking, "what about iOS? AIR now supports iOS!" Well, AIR on iOS does not support dynamic loading of code, which will make Magnificalc an actual modular calculator. Without this support, Magnificalc's goal of modularity is made impossible. Therefore, iOS will not be supported.

The exprtreelib project has been renamed flexprtreelib to fit the new transition, and the Magnificalc parser grammer now compiles to AS3 through ANTLR3's ActionScript target. This transition has been easy and painless. AS3's syntax is similar enough to Scala's that there is really no learning curve.

Saturday, May 28, 2011

Magnificalc Update for May 2011

It's been a while since I last posted something to the devlog, so I thought I'd better get back to it. Anyway, I have learned ANTLRv3 and decided that ANTLR is a much better option than a homegrown parser. Therefore, I now have an implementation of a parser written in ANTLR. One of the challenges associated with the new ANTLR-based implementation is tree generation. I have elected to produce a tree manually rather than using ANTLR's built-in tree-production capabilities. Producing a tree manually requires many low-level functions to be added to the parser class, but it works. It's kinda ugly to read though.
This version of the parser now produces trees like this one: Expression -> Term -> Factor -> (Numeric | Variable | Subexpression in parentheses | Function). This is much higher-level than the old parser, which parsed out BinaryOperator, UnaryOperator, Variable, and Constant nodes. Now, everything is a factor, contained in a term, contained in an expression. Evaluation works like the following:
   Expression.evaluate(st:SymbolTable) = {
var runningTotal = 0;
foreach (term in terms) {
runningTotal += term.evaluate(st)
}
}
Term.evaluate(st:SymbolTable) = {
var runningTotal = 1;
foreach (factor in factors) {
runningTotal *= factor.evaluate(st)
}
}

Of course, the actual evaluation is more complex because the code switches based on whether a term or factor is declared as "inverse". In that case, it subtracts or divides the term or factor from the running total.

Wednesday, April 27, 2011

How-to In Scala: Share Implicit Type Conversions between Classes and Objects

In Scala, one of the most powerful features is implicit type conversions. The article at http://www.codecommit.com/blog/scala/scala-for-java-refugees-part-6 does a pretty good job of explaining implicits. Essentially, you can define functions for the compiler to automatically insert to convert between two types and you can then use one type of object as another. It is extremely powerful!
One of the challenges with implicits is that they must be declared in a type. You cannot declare a "global implicit" conversion to be used across all code compiled with it. Therefore, it would seem that you must redeclare implicits in every class that you want to use them in.
Actually, you don't. You can place them in a common trait, the Scala equivalent of Java's interface. A trait implements mixins, which (in Java terms) are like not-completely-abstract classes. This enables pseudo-multiple inheritance to be used in Scala! Example (taken from exprtreelib code):

// ExpressionNodeTypes.scala; org.nathanmoos.magnificalc.exprtreelib
trait Implicits
{
implicit def closure2Function[T <: { def apply(x:Double):Double }](closure:T) = new Function() {
override def evaluate(x:Double):Double = closure.apply(x)
}
}
...
object Functions
{
...
def register(name:String, func:Function) = ...
...
}
// InternalFunctions.scala; org.nathanmoos.magnificalc.exprtreelib.functions
object InternalFunctions extends Implicits
{
...
def registerAll() = {
Functions.register("ln", log _)
Functions.register("log", log10 _)
Functions.register("sqrt", sqrt _)
Functions.register("sin", sin _)
Functions.register("cos", cos _)
Functions.register("tan", tan _)
Functions.register("csc", csc _)
Functions.register("sec", sec _)
Functions.register("cot", cot _)
Functions.register("sinh", sinh _)
Functions.register("cosh", cosh _)
Functions.register("tanh", tanh _)
Functions.register("acos", acos _)
Functions.register("asin", asin _)
Functions.register("atan", atan _)
}
}
Example 2:
object MyNewFunctions extends BaseClass with Implicits
{
def plusFour(arg:Double):Double = arg + 4

def registerAll() = {
Functions.register("plusFour", plusFour _)
}
}
This example, while quite useless, demonstrates that the new Implicits trait can be used to share implicit type conversions across classes. Look for more in this new series: How-to in Scala!