Three weeks ago, I was working on the implementation of an interpreted language, written in C#. The new language is called Mass (dedicated to @MArtinSaliaS):
The current solution has three projects: a class library, its tests, and a console program, mass.exe, that launches Mass programs
You can run a hello.ms:
The classic Hello world source code:
An example with classes and objects
class Person define initialize(firstname, lastname) self.firstname = firstname self.lastname = lastname end define getName() return self.lastname + ", " + self.firstname end end adam = new Person("Adam", "TheFirst") println(adam.getName())
An example with access to .NET types and objects:
dirinfo = new System.IO.DirectoryInfo(".") for fileinfo in dirinfo.GetFiles() println(fileinfo.Name) end
The idea is to have a dynamic language that leverages an underlying language provided with a rich class library and ecosystem, like in AjSharp and other of my projects. Before Mass, I was working on:
- Implementing Python in C# (see PythonSharp)
- Implementing Ruby in C# (see RubySharp)
Then, with Mass, I deliberately wanted to avoid:
- Multiple commands in the same line (I discarded ‘;’ like in Ruby)
- Syntax based in spaces and indentation (Python discarded)
- Base values and classes (integers, strings, lists, etc…) having a crowd of methods (like Ruby and Python). No, Mass prefers to expose and use the underlying language/class library.
Then, I wanted:
- Syntax based in lines: each command has its own line. No command separation
- Syntax based in keywords: the end of a command list is marked with ‘end’, no braces
- As far as possible, only one way to do something, instead of the many ways motto a la Perl
- Complete keywords, then ‘define’ instead of ‘def’
- Simple inheritance at classes. But Mass could be expressive without written classes, using native classes from .NET framework and other libraries. It could be used as an scripting language.
- Explicit setting of variables that are out of the local scope (a topic for next posts)
- Module by file, with a require that automatically searches in directories, a la NodeJs/CommonJs. Notably, Mass can consume node_modules folder, so Mass module can be published and installed using NPM!
- Package manager, using NPM. You can use package.json to declare the dependencies, and publish new modules at NPM (using ‘mass-‘ as the suggested namespace).
In upcoming posts, I will write more details about implementation, guiding design ideas, examples. But now, you can see the code and the test examples at public repo. And yes, all was written by baby steps, using TDD.
Angel “Java” Lopez