Skip to content

Exception handling and some other new language features

Latest
Compare
Choose a tag to compare
@rochus-keller rochus-keller released this 20 May 10:31
· 64 commits to master since this release

Based on practical experience and discussions with other developers, this release officially adds the following new elements to the language.

Exception Handling

See here for a discussion and derivation.
See here for the specs.
Here is an example as implemented in this release:

module ExceptionExample
  type Exception = record end
  proc Print(in str: array of char)
    var e: pointer to Exception 
  begin
    println(str)
    new(e)
    raise(e)
    println("this is not printed")
  end Print
  var res: pointer to anyrec
begin
  pcall(res, Print, "Hello World")
  case res of
  | Exception: println("got Exception")
  | anyrec: println("got anyrec")
  | nil: println("no exception")
  else
    println("unknown exception")
    // could call raise(res) here to propagate the exception
  end
end ExceptionExample

Source code directives and conditional compilation

Oberon+ uses a syntax as suggested in the Oakwood guidelines.
See here for the specs.
Here is an example as implemented in this release:

<* AAA+ *>
<* BBB- *>
<* if AAA then *>
  println("compiled for AAA")
<* elsif BBB & ~CCC then *> 
  println("compiled for BBB & ~CCC")
<* else *> 
  println("something else")
<* end *> 

Variable length arrays (VLA)

In contrast to array pointers allocated with new(), variable length arrays (VLA) can be allocated on the stack instead of the heap, which makes them attractive to low-resource embedded applications where dynamic memory allocation is not feasible.
Here is an example as implemented in this release:

module VlaExample
  proc Test(n, m: integer)
    var i,j: integer; a: array var n, m of integer
  begin
    for i := 0 to n -1 do
      for j := 0 to m-1 do
        a[i,j] := i*j*2
      end
    end
    println(a[2,3])
  end Test
begin
  Test(4,5)
end VlaExample

Non-local access

Oberon+ now also supports access to outer parameters and local variables from nested procedures (non-local access), as it was available in original Oberon and Oberon-2, but removed in Oberon-07.
Previous versions of Oberon+ followed Oberon-07 and didn’t support this feature, mostly because the "classic" implementation by "static links" doesn’t fit CIL/ECMA-335 or C99 backends; this version of Oberon+ supports an implementation based on hidden var parameters, which is feasible with the mentioned backends.
With this addition Oberon+ is now fully backwards compatible, i.e. each valid Oberon, Oberon-2 or Oberon-07 program is also a valid Oberon+ program.
Here is an example as implemented in this release:

module NlaExample
  proc Outer()
    var a,b,c: integer
    proc Mid1( i: integer )
      var d: integer
      proc Inner( i: integer )
      begin
        a := a + i; d := i
        Mid2(11)
      end Inner
    begin
      b := b + i
      Inner(12)
    end Mid1
    proc Mid2( i: integer )
    begin
      c := c + i
    end Mid2
  begin
    a := 0; b := 0; c := 0 
    Mid1( 13 ) // calls Inner -> Mid2
    Mid2( 14 )
    println(a) // 12
    println(b) // 13
    println(c) // 11 + 14 = 25
  end Outer
begin
  Outer
end NlaExample

Precompiled versions

Here are the pre-compiled versions of the IDE (download, unpack/mount and run, no installation requried):

http://software.rochus-keller.ch/OberonIDE_win32.zip

http://software.rochus-keller.ch/OberonIDE_win64.zip

http://software.rochus-keller.ch/OberonIDE_macOS_x64.dmg

http://software.rochus-keller.ch/OberonIDE_linux_i386.tar.gz

http://software.rochus-keller.ch/OberonIDE_linux_x86_64.tar.gz

See also https://github.com/rochus-keller/Oberon/blob/master/README.md and http://oberon-lang.ch/.