Archive for the ‘Ashlar/Cornerstone’ Category
Script: Write out ASM Code to generate Java class November 5, 2010 | 03:10 pm

Edit: Updated version of the script here.


Here’s a nifty little Groovy script to write out the ASM code to generate a given Java class.

#!/usr/bin/env groovy
 
import org.objectweb.asm.util.ASMifierClassVisitor as V
import org.objectweb.asm.ClassReader as R
 
@Grab(group='asm', module='asm-all', version='[3.3,)')
private class JustHereForGrab {}
 
new R(new File(this.args[0]).newInputStream()).accept(new V(new PrintWriter(System.out)), 0)

You will have to update your ~/.groovy/grapeConfig.xml file to point to a repo with ASM in it. I’ve posted my grapeConfig.xml at http://repo.smokejumperit.com/grapeConfig.xml.

Ashlar Infrastructure is in Play August 22, 2010 | 06:14 pm

Ashlar‘s infrastructure is now live. Basically, we have a compiler and a runtime (ashlarc and ashlar, respectively). Ashlar compiles code down to a component (JAR + properly configured metadata). When Ashlar executes, it loads the component (OSGi install + processing), checks the metadata for any additional components required, fetches those additional components via Ivy, and loads them. Only after all that is done does it invoke the component (OSGi start + processing), which fires off any module in the component with code to execute.

So, in short, you don’t have to muck about with the classpath in Ashlar: we resolve that automatically. If you need to do fancy Ivy stunts, you can muck about with ~/.ashlar/ivy.settings. If you don’t want to think about Ivy or if you mess up your ivy.settings, Ashlar will automatically generate an appropriate one.

We’ve got ashlar and ashlarc. I’d like two other programs eventually: ashlard to deploy components to a local Ivy repository that Ashlar uses, and ashlarx to be a REPL and execute scripts.

For testing, I’m using Cuke4Duke by way of my gradle-plugins. The functional tests act on the actual distribution: the very same code that will be zipped up to make a release. So I can’t get into a situation where the tests pass as long as I’m in the context of a unit test case, but compiled code bombed out on us.

As for the language itself: at this point, all the language can do is print out integers and rational numbers. Not terribly exciting. But the language itself is where the attention is going next: first, some rudimentary type-checking; then, mathematical operations.

Things are about to get a bit slower, because now that I’ve got to this point, I’m shifting some of my free-time focus back to other pending projects. But it’s a pretty exciting place to be.

Ashlar and Assumptions August 17, 2010 | 08:47 pm

A few years back, I started exploring programming language implementations. Generally, I wanted to understand the kind of decisions and trade-offs that programming language designers make: specifically, I was curious as to why Scala made some of the decisions that they did, and so I went down the road of trying to build a language that “fixed” what I perceived to be issues in Scala. That language was called Cornerstone.

After a while, I discovered that there are good reasons why Scala does things the way it does. In those “fixes”, what I was asking for was basically having my cake and eating it, too. Cornerstone was born of naiveté, and so while it was a wonderful educational opportunity, it was a stillborn language.

With lessons learned, I reconsidered my approach and started in on a new language, Ashlar. In my free time this summer, as a counter-balance to the pastoral/ministerial work I was doing, I cranked on Ashlar. It’s still just getting started, but a big hurdle has been crossed: the runtime is up and running, and the compiler infrastructure is in place. The functional test of printing “Hello, World” has gone from red to green. By request, I’ve added a bit of a description up on the Ashlar wiki, so go check it out.

In particular, there is an extensive conversation about the assumptions of Ashlar. Let me know what you think about that: I’m very curious.

Open Source Journaling: Cornerstone February 11, 2009 | 08:48 am

I did another brief update to Cornerstone last night. When parsing floating point numbers, I was doing a parse of an integer, then the dot, then a series of digits, and gluing it all together afterwards. Fred Medlin at the Java Hack Night pointed out that was silly, and I should should parse the value directly as a regex. I went one step further, and jacked the BigDecimal String constructor’s BNF, but encoded as a regex.

So the number parsing now looks like this:

  def float_number : Parser[BigDecimal] = (rawFloat <~ ("F"|"f"))
 
  def integer_number : Parser[BigInteger] = (rawInteger <~ ("Z"|"z"))
 
  def rational_number : Parser[CSRational] = (
    (rawFloat ^^ { new CSRational(_) }) |
    fraction |
    (rawInteger ^^ { new CSRational(_) })
  )
 
  def fraction : Parser[CSRational] = (
    ((rawInteger <~ "/") ~ rawNonzeroNatural) ^^ {
      case x ~ y => new CSRational(x,y)
    }
  )
 
  def rawInteger: Parser[BigInteger] = (
    ((opt("+") ~> """[01-9]+""".r) |
      """[-]?[01-9]+""".r) ^^ { new BigInteger(_) }
  )
 
  def rawNonzeroNatural : Parser[BigInteger] = (
    (opt("+") ~> """[1-9][01-9]*""".r) ^^ { new BigInteger(_) }
  )
 
  def rawFloat : Parser[BigDecimal] = (
    """[-+]?\d*\.\d+([eE][+-]?\d+)?""".r ^^ { new BigDecimal(_) }
  )

As you can see, Cornerstone has only 3 kinds of numbers: integers, floats, and rationals. Rationals are the default, with integers and floats being signaled by suffixes on the numbers (“Z”/”z” and “F”/”f”, respectively). I’m still trying to decide, but I may go with 5 numeric types at the end of the day: long integers (“z”), BigIntegers (“Z”), double-precision floats (“f”), BigDecimals (“F”), and arbitrary-precision rationals (un-suffixed).

Open Source Journaling: Cornerstone February 6, 2009 | 12:53 am

I was a bit fried and looking to escape from work, so I played around with Cornerstone a bit tonight. The key focus right now has been the parser of Cornerstone, which is written in Scala.

In Cornerstone, there are what I’m calling the “mirror operators”[1]. Like OCaml, Haskell, and Scala, the user can define operators. In Cornerstone, one of these operators is “[“, or “[” followed by some arbtirary sequence of symbols. So these are potential operators:
[ foo ]
[| foo |]
[|> foo <|]

I was trying to figure out how to get a the parser combinator library to express that “mirrored” concept, and someone pointed me to the (undocumented) into construct: http://paste.pocoo.org/show/102878/. So I went to town on that.

The resulting code looks like this:

  def mirrorCreate(given:CSParser.~[CSExpression,Operator]):Parser[MirrorExpression] = given match {
    case outr ~ Operator(sym) => {
      val mirrored = StringUtils.replaceChars(StringUtils.reverse(sym), """<>{}[]/""", """><}{][/""")
      return (opt(ws) ~> expression <~ opt(ws) <~ (mirrored + "]") ^^ {
        MirrorExpression(Operator("[" + sym), Operator(mirrored + "]"), outr, _)
      })
    }
  }
 
  def mirror_apply : Parser[MirrorExpression] = positioned(
    ((expression ~ (opt(ws) ~> "[" ~> operator)) into mirrorCreate)
  )

I ran into a problem while writing up this code — I needed to import Commons-Lang, but for reasons that still escape me, Scala was freaking out because there was another package that used the word “lang”. So I ended up having to use the (undocumented) _root_ construct:

import _root_.cstone.lang.CSRational
import java.math.BigInteger
import java.math.BigDecimal
import _root_.org.apache.commons.lang._

Thanks to #scala on FreeNode for tipping me off to both these undocumented features.

The only other interesting thing is that I was a bit bummed to discover case statements need explicit match calls on them. In OCaml, I can write something like the following:

let f = function |1 -> ... |2 -> .... |_ ->  ...

But there’s no such beast in Scala. I tried leaving off the given match in the code above, and the compiler bombed out on me. Bad times.

Next up for Cornerstone is implementing operator precedence in the parser. There’s a kinda half-assed implementation of operators which worked for the moment. I really want to wrap a lot of unit tests around the operator precedence stuff, though, because it’s tricky.

[1]Brian actually came up with this idea, which I think is somewhat brilliant.