Skip to content
Noel Quintos edited this page Aug 5, 2015 · 32 revisions

Welcome to the Cmple wiki!

The Idea

A language that is as easy to use as python but the speed of C. This language will be called Cmple (pronounced 'simple') whose syntax is a mix between C (in terms of variable declaration) and python (everything else). A translator to C, called cmple2c, would translate the Cmple code to C and then, compiled using C compiler. In other words, Cmple provides the abstraction where you could code rapidly and have less mistakes, which then gets translated to C syntax using cmple2c. Then you compile the resulting C-code.

Functionality and features are borrowed from various programming languages (Nim, Julia, Python, C) to allow better abstraction and ease of use.

Why Another Language?

Nim is the nearest to my liking but I still find it too complicated. Nim is like Pascal and my preference is C in terms of simplicity.

Attempts are made to make coding and typing easier. For example, to comment a code, typing '//' or ''' is so much easier compared to typing /* */. Also, python-like expressiveness is attempted and cymple2c will do the hard work of translating them to equivalent C code.

At this point, no code has been written yet. I am cataloguing the desired features and how they will be translated to the equivalent C-code

Delimiters

Blocks are grouped by indentation, python-style. The following Cmple statement

if 2 < x < 111 < x*x
     z = 5
     y = 0
else
     z = -22
     y = 22

will be translated to this equivalent C statement

if (2 < x && x < 111 && 111 < x*x) {
    z = 5;
    y = 0;
}
else {
    z = -22;
    y = 22;
}  

Notice that unlike python, no need for ':' at the if line.

Comments

Use '//' to designate comments as follows:

// this is a comment  
x = 4 // another comment  

Use ''' for longer comments as follows:

'''  
   This is a longer comment  
   spanning several lines  
'''  

cmple2c will simply ignore these comments. None of these comments will appear in the translated C code.

Variable and Function Declaration

Functions are always declared in C-syle and will not be modified by cmple2c

int f(int x, float y)  

Variables need not be declared if it could be derived somewhere else.

x = f(5, 3.4) // no need to declare x

Since we know that f() returns an int, the cmple2c would automatically create the declaration for you as follows:

int x; // <- automatically created by the translator  
x = f(5, 3.4);  

The first assignment will be used as the basis for making declaration

Functions pointers are also automatically declared for each defined functions when function names appear on the right hand side of the assignment operator (=). This is needed so that functions may be passed as parameter. The following cmple code:

int f(int x, float y)
    return x/y

g = f
print g(10, 5.0) // will print 2.0

will be translated into:

int f(int x, float y) {
    return x/y;
}

typedef int (*_cmple_f_i_f)(int, float); // function pointer type definition added
_cmple_f_i_f g = &f;                     // function pointer declaration and address of operator added
print g(10, 5.0);

cmple2c keeps a dictionary of typedef signatures for all defined function and make appropriate declarations. The format is that it starts with '_cmple_f' followed by the argument data type - 'f' for float, 'i' for int, etc. This would allow it to easily find a match given function signature.

The following function declaration is also allowed:

int g(int x, y, float z)

This is equivalent to:

int g(int x, int y, float z)

Function Call - named arguments and default values

cmple code:

int f(int m, int x=1, int y=2)
  return x+y+m

z = f(11)
print z // prints 14

z = f(4, 5)
print z // prints 11

z = f(10, y=5, x=7)
print z // prints 22

v = 10
z = f(40, y=v)
print z // prints 51

This is translated to:

#include <stdio.h>

typedef struct f_struct {
    int m;
    int x;
    int y;
} f_struct;

#define f(...) f((f_struct){.m=0,.x=1,.y=2, __VA_ARGS__})

int (f)(f_struct r) {
    return r.x+r.y+r.m;
}

int main() {                                                                     
    int z;

    z = f(.m=11);
    printf("%d\n", z);

    z = f(.m=4, .x=5);
    printf("%d\n", z);

    z = f(.m=10,.y=5,.x=7);
    printf("%d\n", z);

    int v = 10;
    z = f(.m=40,.y=v);
    printf("%d\n", z);
}

Note that:

  • passed argument is wrapped in a struct which is automatically defined
  • a function wrapper is created that will intercept the call and re-invoke the original function.
  • x and y are replaced with '.x' and '.y', respectively in the function call
  • x and y are replaced with r.x and r.y in the function itself
  • This will allow a call like z = f() but this error will be detected when running cmple2c.

Functions in Different Forms

Style 1. As a Mathematical Expression

int f(float x, float y, float z) = x*x - 4*y + z

or more simply,

int f(float x, y, z) = x*x - 4*y + z

Style 2. Typical function definition

int f(float x, y, z)
    return x*x - 4*y + z

Style 3. Last calculation is returned by default if the function returns a value

int f(float x, y, z)
    x*x - 4*y + z

Style 4. Result variable exists by default having the same data type as the returned value and is automatically returned. Doing an explicit return is still allowed but not necessary.

int f(float x, y, z)
    result = x*x - 4*y + z

Once the 'result' variable is used in a function, its value would be returned instead of the last calculation as in Style 3.

NEVER use 'result' variable in your function other than to store the value that you intend to return. You cannot override this variable for anything other than that.

Styles 1, 2 and 3 will be translated as:

int f(float x, float y, float z) {
    return x*x - 4*y + z;
}

Style 4 will be translated as:

int f(float x, float y, float z) {
    int result;
    result = x*x - 4*y + z;
    return result;

Classes

Here is an example of cmple class

class Person
    int total_count = 0 // class variable
    init(int age, str name)
        int age = age  // instance variables
        str name = name
        ++total_count

    int multiply_age_by(int n) = age * n

// How to use the class
p = Person(12, 'John')
ten_times_age = p.multiply_age_by(10)
print 'total_count = %s', Person.total_count 

This is translated to C as:

int Person_multiply_age_by(Person *p, int n) {
    return p.age * n;
}

typedef int (*cmple_Person_multiply_age_by_Person_i)(Person *, int);
int Person_total_count = 0;
typedef struct Person {
    int age;
    char *name;
    cmple_Person_multiply_age_by_Person_i multiply_age_by = &Person_multiply_age_by
} Person;

Person *Person_init(int age, char *name) {
    Person *p = malloc(sizeof(Person));
    char *_name = malloc(sizeof(char) * strlen(name));
    p.name = _name;
    p.age = age;
    return p;
Clone this wiki locally