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
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.
#ooc-lang freeimage bindings: http://bit.ly/2UJ4s7
#ooc_lang libdispatch bindings: http://bit.ly/O2Omd
Fun with version blocks http://paste.pocoo.org/show/151214/ shows the ooc object model flexibility once again!
@minnowcoder Do you have examples of 'more involved pattern matching' ? The match is a regular ooc match comparing classes..
Fun with fake variable-length argument lists: http://paste.pocoo.org/show/151147/ (code in comments = future syntax)