pattern matching, ranges, ternary operator, rock progress

by 'n ddrylliog

By popular demand, and out of tiredness to write endless if/elseif/else chains, I added pattern matching today to ooc.

Here’s a few code examples of how it works

classify: func (x: Int) {
  match x {
    case 0 => "Zero" println()
    case 1 => "One" println()
    case   => "Neither one, neither zero" println()
  }
}

Note that, unlike C/C++/Java’s switch, you don’t need to break at the end of a case, and there’s no way to fallthrough (yet)
There is no ‘default’ keyword, an empty case will always match.

Now a neat trick which is used in PHP also: match actually compares the match-variable and the case-variables, so you can write things like

classify: func (x: Int) {
  match true {
    case x < 0 => "Strictly negative" println()
    case x > 0 => "Strictly positive" println()
    case       => "Zero" println()
  }
}

By default, an empty match is equivalent to a match true. Also, instead of making actual actions you can use match as an expression, for example

classify: func (x: Int) {
  match {
    case x < 0 => "Strictly negative"
    case x > 0 => "Strictly positive"
    case       => "Zero"
  } println()
}

Also eventually added because of everyone whining it wasn’t there, the ternary operator:

printf("Is true true ? %s\n", true ? "hell yeah." : "wtf?")

As you can notice, it has the classic ?: syntax from C/C++/Java. To avoid syntax clashes, declarations are forbidden inside a ?: (otherwise the colon ‘:’ would be ambiguous)

‘lang/Range’ has been added to the SDK. Since it’s a very basic data structure, it’s been implemented as a cover, for speed. A range literal such as min..max will be transformed into a Range new(min, max). Also, there’s a new method in lang/Int, named ‘in’, which returns true if an int is contained in a range passed as an argument

// let’s assume we’re in a class with the member ’size: SizeT’
checkIndex: func (index: SizeT) {
  match {
    case index in (0..size) => return // alright
    case => Exception new(This, "Index " + index + " out of range (0, " + size + ")") throw()
  }
}

(Note: here we use the lang/Exception class, which is currently a fake implementation of exceptions, e.g. it pretty prints the error message with the class name (thus the ‘This’ passed as a parameter), and divides by zero so the program crashes and it’s easy to debug it via gdb and get a stack trace. Don’t forget to compile with -g ;) Real exceptions are coming soon)

As for rock, our bootstrapping attempt (an ooc compiler written in ooc), we’re making great progress! The code is quite clean, much nicer to read than Java’s, and it can already read and tokenize its own source code! I’m now working on a flexible parser, which would take its syntax definitions from simple text files (and yes – it really sounds like meta). Anyway, stay tuned by following rock on github.