The Story: Speaking Other Languages

Arsslen Idadi
The Startup
Published in
5 min readSep 20, 2020

You live a new life for every language you speak. If you know only one language, you live only once.

Czech proverb

I will not talk about spoken language by humans here, programming languages define ways to express what we want the computer to do and show it how it can do it.

Back in November 2015 and right after finishing the Ghostblade project I was looking for a new challenge, then finally, the time has come for me to create my own programming language from scratch. During the summer of 2015, I read the specifications of the C# language and I got deep into some concepts like type inference and generics. How they actually work and how OOP operates in depth. This experience was conducted for a test language called V# or Rava, the programming language draft was similar to C# but it included a lot more.

When a friend came to me and told me he was writing an operating system using assembly 16 bits and how it is difficult to do. I sensed a challenge in it, Why not create a programming language from scratch, influenced by OOP languages and C/C++ targetting Intel 16 bits processors?

The answer to that question was the Vatu project, kickstarted in December 2015 and finished in February 2016. The language syntax was written using EBNF syntax (Gold parser), the output of this tool is a DFA Lexer and an LALR parser. So I constructed the AST, added the semantic analyzer, created the assembly 16 bits code generator, added the optimizer and finished with a linker.

The programming language was object-oriented, it supported pointers, delegates, generics, operators overload, interrupt definition, multiple calling convention support, extension methods, polymorphism, custom calling convention for system calls and had a feature that never existed in any other programming language: the ability to define custom operators (unary/binary) that the parser nor the lexer knew.

The project was hosted on Github and it had successfully achieved the desired goal, a sample kernel was written using the language.

A sample kernel code:

default asm {
"[org 0]";
"start:";
"mov ax,cs";
"mov ds,ax";
"mov es,ax";
"mov ax,0x7000";
"mov ss,ax";
"mov sp,ss";
}
namespace std;
enum CONSOLE_COLORS{
BLUE = 1,
GREEN = 2,
RED = 4
};
struct XA{
int a;
byte b;
};
typedef enum CONSOLE_COLORS CCOLORS;
// get char
byte getc(){
byte c = 0;
asm{
"mov ah, 0";
"int 0x16 ; wait for keypress";
"mov [BP-1], al";
"mov ah, 0x0E";
"int 0x10 ; otherwise, print out the character!";
}

return c;
}
// put char
void putc(byte c){
asm{
"xor cx,cx";
"xor dx,dx";
"xor bx,bx";
}
asm{ "mov byte al, [BP+4]";
"mov ah, 0x0E";
"int 0x10 ; otherwise, print out the character!";
}
}
// print null terminated string
void print(string msg){
int i = 0;
asm{
"xor cx,cx";
"xor dx,dx";
"xor bx,bx";
"xor ax,ax";
}
// 0 end of string
byte c;
while(msg[i] != 0)
{
c = msg[i];
asm{
"mov byte al, [BP-3]";
"mov ah, 0x0E";
"int 0x10";
}
i++;
}
} void cls()
{
asm{
"xor cx,cx";
"xor dx,dx";
"xor bx,bx";
"mov ax, 0x0003";
"int 0x10";
}
}
void lnprint(string msg){
asm{
"mov al, 0xA";
"mov ah, 0x0E";
"int 0x10 ; otherwise, print out the character!";
"mov al, 0x0D";
"mov ah, 0x0E";
"int 0x10 ; otherwise, print out the character!";
}
print(msg);
} void println(string msg){ print(msg);
asm{
"mov al, 0xA";
"mov ah, 0x0E";
"int 0x10 ; otherwise, print out the character!";
"mov al, 0x0D";
"mov ah, 0x0E";
"int 0x10 ; otherwise, print out the character!";
}
}
void getstring(string buff){
byte cc = 0;
int i = 0;
cc = getc();
while(cc != 0x0D){
buff[i] = cc;
i++;
cc = getc();
}
buff[i] = 0;
}
void print_color(string msg, byte color)
{
int i = 0;
byte c = 0;
asm{
"mov ax,0xb800";
"mov gs,ax";
"push word gs"; // save gs
"mov bx,0";
"mov si,[BP+6]";
"mov ch,[BP+4]";
}
loop{asm{
"lodsb" ;
"or al,al";
"jz done";
"mov byte [gs:bx],al";
"mov byte [gs:bx+1],ch";
"add bx,2";
}
}
done:
asm{
"pop word gs";
}
}namespace String;
use std;
override bool operator ==(string b, string a)
{
for(;*a == *b;) {
if(*a == 0)
return true;
a++;
b++;
}

return false;
}
override bool operator >(string a, string b)
{
for(;*a == *b;) {
if(*a == 0)
return false;
a++;
b++;
}
if(*a > *b)
return true;
return false;
}
override bool operator <(string a, string b)
{
for(;*a == *b;) {
if(*a == 0)
return false;
a++;
b++;
}
if(*a < *b)
return true;
return false;
}
override string operator +(string a, string b)
{
int i = 0;
int j = 0;
while(a[i] != 0)
i++;
while(b[j] != 0){
a[i] = b[j];
j++;
i++;
}
a[i] = 0;
return a;} uint strlen(string a)
{
uint i = 0;
while(a[i] != 0)
i++;
return i;
}
void tostring(bool v)
{
if(v == true)
print("TRUE");
else
print("FALSE");
}
void tostring(uint a){
if(a < 10)
putc((byte)(a+48));
else{
tostring(a / 10);
putc(48+(byte)(a % 10));
}
}
void reverse(string str, int length)
{
uint start = 0;
uint end;
end = length - 1;
while (start < end)
{
str[start] <> str[end];
start++;
end--;
}
}
namespace OPERATIONS;
use std;
use String;
bool isdigit(byte c)
{
if(c >= 48 && c <= 57)
return true;
else return false;
}
uint a2u(string s)
{
int i = 0;
uint num=0;
while(s[i] != 0)
{
if(isdigit(s[i]) == true)
num=(uint)((s[i])-'0')+num*10;
else
println("Not a number");
i++;

}
return num;
}
private string prompt = ">>";
private string NM_msg = "Type a number : ";
private string buff = "00000"; // 5 digits number
private string OP_msg = "Type an operator (+,-,*,/): ";
const string OP_PL = "+";
const string OP_MI = "-";
const string OP_MUL = "*";
const string OP_DIV = "/";
void operate(){
uint a = 0;
uint b = 0;
uint r = 0;
lnprint(NM_msg);
lnprint(prompt);
getstring(buff);
a = a2u(buff);
lnprint(NM_msg);
lnprint(prompt);
getstring(buff);
b = a2u(buff);
lnprint(OP_msg);
lnprint(prompt);
getstring(buff);
if(OP_PL == buff)
r = a+b;
else if(OP_MI == buff)
r = a-b;
else if(OP_DIV == buff)
r = a/b;
else if(OP_MUL == buff)
r = a * b;
else
lnprint("Unknown Operator only (+,*,-,/) are allowed");
lnprint("RESULT : ");
tostring(r);


}namespace VTOS;
use std;
use String;
use OPERATIONS;
const string prompt = ">";
string input = "000000000000000000000000000000000000000000000000000000000";
const string hello_cmd = "hello";
const string about_cmd = "about";
const string op_cmd = "oper";
const string op_help = "help";
const string op_sd = "shutdown";
const string op_res = "restart";
const string op_swap = "s";
const string help_msg = "oper : Operation, help : Help, hello : Hello World, about : About, shutdown, restart";
const string about_text = "This os is a simple demo written to test Vatu compiler";
struct XA* buffer[5]; void restart() {
asm{
"int 0x19";
}
}
void shutdown() {
asm{
"mov ax, 0x1000";
"mov ax, ss";
"mov sp, 0xf000";
"mov ax, 0x5307";
"mov bx, 0x0001";
"mov cx, 0x0003";
"int 0x15";
}
}
interrupt 0x86
{
uint dest;
dest = AX;
if(dest == 1)
shutdown();
else if(dest == 2)
restart();
}
interrupt 0
{
lnprint("Division par zero");
}
void printA(string a) extends string
{
print("Your message was ");
lnprint(a);
print("HGJ");
}
void Hello() static extends void
{
lnprint(" Hello from extend ");
}
entry void main()
{
cls();
print_color("Welcome to Vatu OS Kernel", CONSOLE_COLORS.BLUE);
lnprint("Write your command : ");

loop{
lnprint(prompt);
getstring(input);
if(hello_cmd == input)
lnprint("Hello, from Vatu OS");
else if(about_cmd == input)
lnprint(about_text);
else if(op_cmd == input)
operate();
else if(op_help == input){
lnprint(help_msg);
op_help.printA();
void::Hello();
}
else if(op_sd == input){
AX = 1;
interrupt 0x86;
}
else if(op_res == input)
{
AX = 2;
asm{"int 86h";}
} else
lnprint("Unknown command");

}
}

Vatu was a dream come true and again the harmonic convergence made it happen.

To be continued…

--

--