Vishap Oberon Compiler

Make it as simple as possible, but not simpler — A. Einstein

Oberon-2 Compiler, Libraries and Tooling

Vishap Oberon Compiler

Vishaps are dragons from the Armenian Highlands. We named the project 'Vishap' due to the long-standing tradition between dragons and compilers.

Vishap Oberon Compiler

Oberon is a general-purpose programming language first published in 1987 by Niklaus Wirth and the latest member of the Wirthian family of ALGOL-like languages (Euler, ALGOL W, Pascal, Modula, and Modula-2).

Oberon's design goals are

Oberon is designed around the following principles:

Make it as simple as possible, but not simpler.

– Albert Einstein

Perfection is finally attained not when there is no longer anything to add, but when there is no longer anything to take away.

– Antoine de Saint-Exupéry

To learn more about Oberon, check examples.

Vishap Oberon Compiler

Ѵishap Oberon is a free and open source (GPLv3) implementation of the Oberon-2 language and libraries for use on conventional operating systems.

Vishaps Oberon Compiler (voc) uses a C backend (gcc, clang, tcc or msc) to compile Oberon programs under Unix, Mac or Windows. Vishap Oberon includes libraries from the Ulm, oo2c and Ofront Oberon compilers, as well as default libraries complying with the Oakwood Guidelines for Oberon-2 compilers.

Vishap Oberon Compiler runs on

Work on native backends for x86_64(amd64) and arm64(aarch64) is in progress.

Examples

Hello, World!

hello.Mod

MODULE hello;
IMPORT Out;
BEGIN
  Out.String("Hello, World"); Out.Ln
END hello.
        

$ voc -m hello.Mod 
hello.Mod  Compiling hello.  Main program.  380 chars.

$ ./hello  Hello, World

Basic Arithmetic

Arithmetic.Mod

MODULE arithmetic;
IMPORT Out;

VAR
  a, b, result: INTEGER;
(* This is a comment, by the way :) *)
BEGIN
  a := 15;
  b := 5;

  result := a + b;
  Out.Int(result, 0); Out.Ln;

  result := a * b;
  Out.Int(result, 0); Out.Ln;

  result := a DIV b;
  Out.Int(result, 0); Out.Ln;
END arithmetic.
        

$ voc -m Arithmetic.Mod 
Arithmetic.Mod  Compiling arithmetic.  Main program.  718 chars.

$ ./arithmetic  20 75 3

Procedures

Proc.Mod

MODULE Procedures;
IMPORT Out;

(*
  Comments can be multi-line

  Add takes in `a` and `b` integers, and returns an integer

  (* comments can also be nested, unlike most other languages *)
*)
PROCEDURE Add(a, b: INTEGER): INTEGER;
BEGIN
  RETURN a + b;
END Add;

BEGIN
  Out.Int(Add(3, 7), 0); Out.Ln; (* Output: 10 *)
END Procedures.
        

$ voc -m Proc.Mod 
Proc.Mod  Compiling Procedures.  Main program.  495 chars.

$ ./Procedures 10

Pass by Value vs Reference

ValVsRef.Mod

MODULE ValVsRef;
IMPORT Out;

VAR
  number: INTEGER;


PROCEDURE IncrementValue(i: INTEGER);
BEGIN
  i := i + 1;
  Out.String("During IncrementValue (pass by value),           in function scope: "); Out.Int(i, 0); Out.Ln;
END IncrementValue;

PROCEDURE IncrementByReference(VAR i: INTEGER);
BEGIN
  i := i + 1;
  Out.String("During IncrementByReference (pass by reference), in function scope: "); Out.Int(i, 0); Out.Ln;
END IncrementByReference;

BEGIN
  (* Pass by Value *)
  number := 5;
  Out.String("Initial value of number: "); Out.Int(number, 0); Out.Ln;

  IncrementValue(number);
  Out.String("After  IncrementValue (pass by value),           in main scope: "); Out.Int(number, 0); Out.Ln;

  (* Pass by Reference *)
  IncrementByReference(number);
  Out.String("After  IncrementByReference (pass by reference), in main scope: "); Out.Int(number, 0); Out.Ln;
END ValVsRef.
        

$ voc -m ValVsRef.Mod 
ValVsRef.Mod  Compiling ValVsRef.  Main program.  1320 chars.

$ ./ValVsRef  Initial value of number: 5 During IncrementValue (pass by value),           in function scope: 6 After  IncrementValue (pass by value),           in main scope: 5 During IncrementByReference (pass by reference), in function scope: 6 After  IncrementByReference (pass by reference), in main scope: 6

Records and Type Extension

Students.Mod

MODULE Students;
IMPORT Out;

TYPE
  Person = RECORD
    name: ARRAY 32 OF CHAR;
    age: INTEGER;
  END;

  Student = RECORD(Person)
    id: INTEGER;
  END;

VAR
  s0: Student;

BEGIN
  s0.name := "John Doe";
  s0.age  := 42;
  s0.id   := 1337;
  Out.String(s0.name); Out.Ln;
  Out.Int(s0.age, 0);  Out.Ln;
  Out.Int(s0.id, 0);   Out.Ln;
END Students.
        

$ voc -m Students.Mod 
Students.Mod  Compiling Students.  Main program.  1075 chars.

$ ./Students  John Doe 42 1337

Resources

Timeline