Charm (programming language)

Last updated
Charm
Paradigm Structured programming
Designed by P. Nowosad
First appeared1996
OS RISC OS
Website charm.qu-bit.co.uk
Influenced by
RTL/2, C, Pascal

Charm is a computer programming language devised in the early 1990s with similarities to the RTL/2, Pascal and C languages in addition to containing some unique features of its own. The Charm language is defined by a context-free grammar amenable to being processed by recursive descent parser as described in seminal books on compiler design. [1] [2]

Contents

A set of Charm tools including a compiler, assembler and linker was made available for Acorn's RISC OS platform. [3] Charm reworked for RISC OS platforms has subsequently been reviewed in Archive magazine. [4]

Charm is further described in the e-book Programming in Charm on the Raspberry Pi. [5]

Grammar

The definition of the Charm grammar in Backus–Naur form along with descriptive examples of Charm constructs is defined on the Charm language page. [6]

The language is block structured, with each block being introduced by a language keyword that is descriptive of the operation being performed in the block e.g. for, while, repeat (iteration), case, if (selection). Each block is enclosed by { and } delimiters. Additionally language lines within a block are normally indented for clarity, though this not required as white space is ignored.

Each grammatically conforming text represents a collection of executable code and associated data which can be used by a Charm tool set as a component when assembling a program that can be run under an operating system utilising the services it provides to do useful work such as data processing or interacting with users through a graphical user interface (GUI).

Data types

Charm is a strongly typed language, but does allow some implicit conversions between numeric and floating point types. The following basic variable types are supported:

  • int – integers
  • char – characters
  • boolean – boolean values (true or false)
  • real – floating point numbers

Data aggregates of the same type may be declared and statically initialised using the array keyword, and these may be multidimensional. Aggregates of different types may be declared using the record keyword, and it is allowable for such a declaration to define a union of record fields that overlay each other in terms of storage allocation. Modules may also aggregate a mixture of static and dynamic data members. Instances of both records and modules (dynamic content only) can be instantiated on the stack, or on the heap via the new operator. Modules may also define a constructor ~new procedure to initialise dynamic data and corresponding ~delete deconstructor procedure to release resources in a similar manner to the C++ language.

Referencing

Data or procedures within the scope of a module may be made global to the final application by using the export keyword. If a module wishes to reference a procedure or data from another Charm module, it does so using the import keyword. Modules may contain instance based member variables which are accessible through procedures declared with the dynamic keyword through the implicit first parameter this pointer.

References to data constructs and procedures may be made using the ref keyword. These can be dereferenced using the val keyword. When using reference variables, comparison operators are available to check whether two reference variables refer to the same item of data ( :=: ) or whether the data they point to is the same ( = ).

Example

The original classic Hello world program written in Charm is:

    ext proc write_string (ref array char);     module hello;         ent proc start ();             write_string ("Hello world");         end_proc;     end_module; 

and the equivalent latest version following evolutionary syntactic language changes is:

    import lib.Out;     module Hello     {         export proc ~start ()         {             Out.vdu.str ("Hello world"). nl();         }     } 

Tool set

Tool set implementations are expected to provide a compiler and an assembler to generate object files from Charm source code and assembler source code, which can then be linked together along with library and run time support files to generate an executable program.

At the time of writing only one Charm tool set installation is available (free of charge) for download. The tools are themselves written in the Charm language, and the source code is available under the terms of the GNU General Public License. They run on RISC OS PCs and platforms with ARM CPUs (such as the Raspberry Pi) and on emulators for RISC OS which are hosted on Windows or Linux platforms (such as RPCEmu). Code generation for hardware assisted double precision floating point operations is supported for platforms based on ARM chips that support the VFP version 2 coprocessor architecture.

Compiler

The Charm compiler is a recursive descent single pass compiler which parses Charm source code to generate quadruples of the form result := lhs op rhs in an intermediate language that supports arithmetic, logical and flow of control operations. Data is stored in temporaries which are assigned to registers and memory locations in the back end of the compiler. Two back ends are currently in existence, one generating Motorola 68000 assembly language, and the other generating ARM architecture. [7]

The quadruple output from the hello world example is:

       param   l1$        call    write_string[proc (ref array char) void]

and the assembler output is:

string"hello"xdef_startalign_startxref_write_stringstmfdsp!,{rp}adrr0,_l1$bl_write_stringldmfdsp!,{pc}addressalign_l1$string"Hello world"directend

In more recent releases of Charm, the I/O procedures have been split into their own modules In and Out. Other standard library procedures are organised into a set of records with procedure references as fields. As part of this reorganisation, the write_string method is now invoked through the run time library module Out via static member reference .vdu as procedure str i.e. in the hello world example above write_string ("Hello world") becomes Out.vdu.str ("Hello world").

Assembler

The assembler accepts instruction mnemonics, data declarations and directives and constructs an object file containing information readily understandable by the CPU of the target processor, in particular code instructions coded in binary.

Assembler listing of @.arm.hello
0000:6D795F6D 0000:E92D4000 0004: 000C:EBFFFFFE 0010:E8BD8000 0000:48656C6C 
string"hello"xdef_startalign_startxref_write_stringstmfdsp!,{rp}adrr0,_l1$bl_write_stringldmfdsp!,{pc}addressalign_l1$string"Hello world"directend

Linker

One and only one of the Charm modules linked to form an executable program must contain a procedure matching one of the signatures:

   export proc ~start ()    export proc ~start (int argc, ref array ref array char argv)

This is analogous to the main function in the C and Java languages. Here argc contains the number of parameters passed on the command line and argv contains a reference to an array of argc + 1 strings (one string per positional parameter in order and a terminating nil).

In addition, modules may optional contain static startup and shutdown procedures invoked during program startup and shutdown that match the signatures:

   export proc ~startup ()    export proc ~shutdown ()

The linker adds any necessary header information required by the operating system in order to execute the program, and ensures the run time library assembler support code is run which sets up the run time environment (data and stack pointers) and passes control to the start procedure of the application.

A map file showing the names of all modules linked to form the program along with global data and code references is optionally produced which can be used by debuggers and profilers.

Related Research Articles

<span class="mw-page-title-main">Pascal (programming language)</span> Programming language

Pascal is an imperative and procedural programming language, designed by Niklaus Wirth as a small, efficient language intended to encourage good programming practices using structured programming and data structuring. It is named in honour of the French mathematician, philosopher and physicist Blaise Pascal.

OCaml is a general-purpose, multi-paradigm programming language which extends the Caml dialect of ML with object-oriented features. OCaml was created in 1996 by Xavier Leroy, Jérôme Vouillon, Damien Doligez, Didier Rémy, Ascánder Suárez, and others.

<span class="mw-page-title-main">BBC BASIC</span> Version of the BASIC programming language

BBC BASIC is a version of the BASIC programming language released in 1981 as the native programming language for the BBC Micro home/personal computer, providing a standardized language for a UK computer literacy project of the BBC. It was written mainly by Sophie Wilson.

<span class="mw-page-title-main">Modula-3</span>

Modula-3 is a programming language conceived as a successor to an upgraded version of Modula-2 known as Modula-2+. While it has been influential in research circles it has not been adopted widely in industry. It was designed by Luca Cardelli, James Donahue, Lucille Glassman, Mick Jordan, Bill Kalsow and Greg Nelson at the Digital Equipment Corporation (DEC) Systems Research Center (SRC) and the Olivetti Research Center (ORC) in the late 1980s.

<span class="mw-page-title-main">Oberon-2</span>

Oberon-2 is an extension of the original Oberon programming language that adds limited reflection and object-oriented programming facilities, open arrays as pointer base types, read-only field export, and reintroduces the FOR loop from Modula-2.

The syntax of the C programming language is the set of rules governing writing of software in the C language. It is designed to allow for programs that are extremely terse, have a close relationship with the resulting object code, and yet provide relatively high-level data abstraction. C was the first widely successful high-level language for portable operating-system development.

<span class="mw-page-title-main">ALGOL 68</span> Programming language

ALGOL 68 is an imperative programming language that was conceived as a successor to the ALGOL 60 programming language, designed with the goal of a much wider scope of application and more rigorously defined syntax and semantics.

In computer programming, an entry point is the place in a program where the execution of a program begins, and where the program has access to command line arguments.

In mathematics and in computer programming, a variadic function is a function of indefinite arity, i.e., one which accepts a variable number of arguments. Support for variadic functions differs widely among programming languages.

In some programming languages, const is a type qualifier that indicates that the data is read-only. While this can be used to declare constants, const in the C family of languages differs from similar constructs in other languages in being part of the type, and thus has complicated behavior when combined with pointers, references, composite data types, and type-checking. In other languages, the data is not in a single memory location, but copied at compile time on each use. Languages which utilize it include C, C++, D, JavaScript, Julia, and Rust.

C++/CLI is variant of the C++ programming language, modified for Common Language Infrastructure. It has been part of Visual Studio 2005 and later, and provides interoperability with other .NET languages such as C#. Microsoft created C++/CLI to supersede Managed Extensions for C++. In December 2005, Ecma International published C++/CLI specifications as the ECMA-372 standard.

IP Pascal is an implementation of the Pascal programming language using the IP portability platform, a multiple machine, operating system and language implementation system. It implements the language "Pascaline", and has passed the Pascal Validation Suite.

<span class="mw-page-title-main">C Sharp (programming language)</span> Multi-paradigm (object-oriented) programming language

C# is a general-purpose, high-level multi-paradigm programming language. C# encompasses static typing, strong typing, lexically scoped, imperative, declarative, functional, generic, object-oriented (class-based), and component-oriented programming disciplines.

Charm++ is a parallel object-oriented programming paradigm based on C++ and developed in the Parallel Programming Laboratory at the University of Illinois at Urbana–Champaign. Charm++ is designed with the goal of enhancing programmer productivity by providing a high-level abstraction of a parallel program while at the same time delivering good performance on a wide variety of underlying hardware platforms. Programs written in Charm++ are decomposed into a number of cooperating message-driven objects called chares. When a programmer invokes a method on an object, the Charm++ runtime system sends a message to the invoked object, which may reside on the local processor or on a remote processor in a parallel computation. This message triggers the execution of code within the chare to handle the message asynchronously.

ALGOL 68RS is the second ALGOL 68 compiler written by I. F. Currie and J. D. Morrison, at the Royal Signals and Radar Establishment (RSRE). Unlike the earlier ALGOL 68-R, it was designed to be portable, and implemented the language of the Revised Report.

Protel stands for "Procedure Oriented Type Enforcing Language". It is a programming language created by Nortel Networks and used on telecommunications switching systems such as the DMS-100. Protel-2 is the object-oriented version of Protel.

This article describes the syntax of the C# programming language. The features described are compatible with .NET Framework and Mono.

Modula-2 is a structured, procedural programming language developed between 1977 and 1985/8 by Niklaus Wirth at ETH Zurich. It was created as the language for the operating system and application software of the Lilith personal workstation. It was later used for programming outside the context of the Lilith.

In computer programming, a function or subroutine is a sequence of program instructions that performs a specific task, packaged as a unit. This unit can then be used in programs wherever that particular task should be performed.

Nim is a general-purpose, multi-paradigm, statically typed, compiled systems programming language, designed and developed by a team around Andreas Rumpf. Nim is designed to be "efficient, expressive, and elegant", supporting metaprogramming, functional, message passing, procedural, and object-oriented programming styles by providing several features such as compile time code generation, algebraic data types, a foreign function interface (FFI) with C, C++, Objective-C, and JavaScript, and supporting compiling to those same languages.

References

  1. ISBN D-201-10073-8 Aho, Ullman Principles of Compiler Design
  2. ISBN D-201-10194-7 Aho, Sethi, Ullman Compilers Principles, Techniques and Tools
  3. Wade, Stephen (June 1996). "Charm or trinket?". Acorn User. pp. 50–51. Retrieved 28 August 2021.
  4. Wraith, Gavin (January 2012). "The Charm language: a review". Archive. Vol. 23, no. 4. p. 13. Retrieved 2021-08-28.
  5. June 2013 Kindle e-book Charm Programming on the Raspberry Pi
  6. Charm RISC OS, language page
  7. ISBN   0-9512579-0-0 Peter Cockerell ARM Assembly Language Programming