things to keep in mind:
class, cover, interface, implement, func, abstract, extends, from, this, super, new, const, final, static, include, import, use, extern, inline, proto, break, continue, fallthrough, operator, if, else, for, while, do, switch, case, as, in, version, return, true, false, null, default
(note: things like 'new', and 'this' aren't really keywords, they are proper functions and variables, but it's still useful they stand out in syntax highlighting, for readability. Also a few other keywords aren't implemented yet, but reserved.)
+, -, *, /, +=, -=, *=, /=, =, :=, ==, !=, !, %, ?, >, <, >=, ⇐, &&, ||, &, |, ^, ., ~, .., », «, »>, «<, »=, «=, »>=, «⇐
(note, '.' is the chaining operator in ooc, not the 'member access' one. To access a member of an object, just whitespace is needed as in Io, e.g. "dog name", or "dog barf()")
(Note about 'This': it refers to the current type being defined, e.g. a clone method would be defined like clone: func → This { /* return a copy */ })
(Note 2: some types above are redundant, some will be deprecated soon, but coloring all of them can't harm.)
include header1, path/header2 include ./mylocalheader import my/package/MyModule import my/package/[MyModule1, MyModule2] use mylib, mylib2
No backslashes, even on windows.
// single-line comment /* multi-line comment */ /** oocdoc comment (a-la javadoc/doxygen), with @tags */
myFunction() myFunction(arg1, arg2) myObject doThing() MyClass callStaticMethod()
i: Int // variable declaration i = 3 : Int // variable declaration + assignment i := 3 // variable declassignment. (the type is guessed) a, b, c: Int // declare three variables // useful for bitfields: OPTION1 = 1, OPTION2 = 2, OPTION3 = 4, OPTION4 = 8 : const Int
3.14 as Int // casting
add: func (a: Int, b: Int) -> Int {
return a + b
}
add: func (a, b: Int) -> Int { a + b } // multi-decl, and return is optional.
exit: extern func // no '->' = void func, extern = defined elsewhere
Animal: class {
name: String
age := 0
/** Simple constructor with a member-assign-argument */
init: func (=name) {}
// equivalent to
// init: func (name: String) { this name = name }
/** Another constructor, we need to choose a suffix, here 'withAge' */
init: func ~withAge (.name, =age) {
this(name) // call another constructor
}
// equivalent to
// init: func (name: String, age: Int) { this(name); this age = age }
/** An abstract function, should be implemented by child classes */
shout: abstract func
// note: if we have no arguments, we don't need parenthesis
// (heh, that's what the 'func' keyword is for!)
}
Dog: class extends Animal {
shout: func {
"Woof, woof!" println()
}
}
Ant: class {
total = 0 : static Int
init: func { total += 1 }
getTotal: static func -> Int { total }
}
main: func {
list := ArrayList<Ant>
for(i in 0..20) {
list add(Ant new())
}
printf("Created %d ants in total!\n", Ant getTotal())
}
// this translates to a simple typedef
Int: cover from int
// typedef here..
String: cover from Char* {
// and define the String_println(String this) function here. (in C)
println: func {
printf("%s\n", this)
}
}
Button: cover from GtkButton extends Window {
// inheritance works almost the same as with classes, e.g.
// you can call methods from its super-cover
}
// Compound cover =)
Color4f : cover {
r, g, b, a: Float
}
Message: class {
content: String
}
Printable: interface {
print: func
}
implement Printable for Message {
print: func {
content println()
}
}
operator + (left, right: String) -> String {
// note: this is a horrible implementation, but it's just for the example
return strcat(strdup(left), right)
}
main: func {
ptr := gc_malloc(Int size) as Int*
ptr@ = 42
printf("ptr's value is %d\n", ptr@)
add(ptr, 3)
printf("ptr's value is now %d\n", ptr@)
}
add: func(ptr: Int*, value: Int) {
ptr@ += value
}
main: func {
ptr := gc_malloc(Int size) as Int* // alloc an int on the heap
ptr@ = 42
printf("ptr's value is %d\n", ptr@)
add(ptr, 3)
printf("ptr's value is now %d\n", ptr@)
}
add: func(ptr: Int@, value: Int) {
ptr += value
}
main: func {
number := 42 // alloc an int on the stack
printf("number is %d\n", number)
add(number&, 3)
printf("number is now %d\n", number)
}
add: func(ptr: Int@, value: Int) {
ptr += value
}
for(i in 0..10) {
printf("%d, ", i)
}
also, for collections
list := ArrayList<Int> new() .add(1) .add(2) .add(3)
for(i in list) {
printf("%d, ", i)
}
Can also be a decl before the 'in', e.g.
for(i: UInt in 0..10) {
printf("%d, ", i)
}
action: Func // a dumb function pointer
doThing: func {
"Oh, really?" println()
}
action = doThing
action() // call action, thus call doThing
applyOperator: func(operator: Func (Int, Int) -> Int, left, right: Int) {
return operator(left, right)
}
add: func (left, right: Int) { left + right }
sub: func (left, right: Int) { left - right }
mul: func (left, right: Int) { left * right }
div: func (left, right: Int) { left / right }
printf("1 + 2 = %d\n", applyOperator(add, 1, 2))
printf("10 - 5 = %d\n", applyOperator(sub, 10, 5))
printf("6 * 7 = %d\n", applyOperator(mul, 6, 7))
printf("10 / 2 = %d\n", applyOperator(div, 10, 2))
list := ArrayList<Int> new() list add(1) .add(2) .add(3)
butt := Button new()
butt connect("clicked", func { "Button clicked!" println() })
printType: func <T> (param: T) {
printf("Got param of type %s and size %d\n", T name, T size)
if(T == Int) printf("It's an Int! and its value is %d\n", param as Int)
else if(T == Char) printf("It's a char! and its value is '%c'\n", param as Char)
}
printType('c')
printType(42)
prints:
Got param of type Char and size 1 It's a char! and its value is 'c' Got param of type Int and size 4 It's an Int! and its value is 42
Container: class <T> {
content: T
init: func(=content)
get: func -> T { content }
set: func(=content)
}
main: func {
cont1 := Container<Int> new(42)
number := cont1 get()
printf("number is an %s, and its value is %d\n", number class name, number)
cont2 := Container<String> new("Hi, world!")
message := cont2 get()
printf("message is a %s, and its value is %s\n", message class name, message)
}
prints:
number is an Int, and its value is 42 message is a String, and its value is Hi, world!
mark := stdin readLine() toInt()
match mark {
case 0 => println("Oh, that's bad.")
case 1 =>
// there can be several statements
mark = 3
println("There, I helped you a little")
case 2 =>
println("So you like middles?")
case => // default case
println("Now what is that value?")
}
Note: there is a 'fallthrough' reserved keyword, which isn't implemented yet.
match can be used as an expression:
hello := match 42 { case 42 => "Hello!" }
match without an expression is the equivalent of match true {}
isPositive: func (i: Int) -> Int {
return match {
case (i > 0) => 1
case (i < 0) => -1
case => 0
}
}
(parenthesis added for readability, but not actually needed)
Math: class {
PI := const static 3.14159
}
Container: class {
content: Pointer
/** inline keyword: same meaning as C */
getContent: inline func -> Pointer { content }
}
/** proto keyword adds function prototypes int the generated C file, e.g. when you're missing a header. */
usleep: extern proto func -> Int
c_exit extern(exit) func
main: func {
c_exit(); // translates to exit() in C
}
for member functions (ie. methods)
include stdlib
String: cover from char* {
length: extern(strlen) func -> Int
}
"blah" length() toString() println()
prints '4'
arr := [1, 2, 3] // array of ints, typed Int*
// the type is determined by the first element
arr2 := [1 as UInt, 2, 3] // typed UInt*
// this is invalid:
Dog: class {}
arr3 := [1, 2, 3, Dog new()] // error, incompatible type
about
blog
docs
community
downloads
Starting soon this month is the Google Summer of Code (GSOC). ooc-lang.org will apply. We need your ideas! http://bit.ly/bKHTRE
From now on, the mailing list will be used more frequently, big decisions will happen there - have your say, subscribe http://bit.ly/bnHuEY
@Dubhead I updated the instructions here http://ooc-lang.org/downloads and there http://ooc-lang.org/setup - hope it's clearer
Till we have'em automated, here's a j/ooc nightbuild http://bit.ly/aDc05q rock is on the way to compile itself. exciting times!
rock has version blocks, more and more sdk classes compile. Soon j/ooc and rock's sdk will merge.
rock has preliminary support for interfaces. mixins and namespaced imports are coming up soon! killer, simple syntax as usual.
for the first time, rock, a 10k SLOC pure ooc codebase, compiles under Win32, and produces executables with gcc. party?
blogpost! gtksourceview highlighting for ooc – gedit & anjuta, rock progress, sudoku solver http://bit.ly/dt0GI1
#ooc_lang for the web! fastcgi bindings by joshthecoder: http://bit.ly/9AcGCa
discount bindings (markdown text to html library) for @ooc_lang by @zenhob http://bit.ly/5dg2K7 coolness!
rock has constructors, half generics, operator overloads on the way. commit frenzy! http://bit.ly/5M8syC
finalizers in j/ooc, meta-classes in rock, yajit, deadlogger, woot, oos, arbitrary precision arithmetic http://bit.ly/5kHIcZ
The ooc blog is online again, thanks @aguspiza for reporting the problem!
@aguspiza Ow. Investigating, thanks for reporting!
yajit works again! check it out: http://github.com/nddrylliog/yajit (special thanks to fredreichbier & showstopper)
rock (ooc compiler in ooc) compiles classes and covers =) don't try it at home yet, though - it's still highly experimental
@alejandrocrosa Hmmm, rtfm? http://docs.ooc-lang.org/ooc-slim/executable-size.html ;)
@arvennard The C++ object model is too complex. And the C syntax has many drawbacks. ooc is, imho, much more readable/light/flexible.
(continued)... that change will allow very nice array and map literals, and other data structs will be usable easily too. Stay tuned.
SubProcess new() now takes an ArrayList<String> instead of String*. (breaking change). ArrayList and HashMap will be BasicTypes soon.