Skip to content

Latest commit

 

History

History
284 lines (208 loc) · 4.45 KB

spec.md

File metadata and controls

284 lines (208 loc) · 4.45 KB

CokeScript Language Specification

You can assume CokeScript is JavaScript with a Python like syntax. Some elements from Ruby might appear as well.

Language basics

Variable and scoping

Variable are simply declared without type

a = 1
a = 2
def test()
  a = 3

Generates

var a = 1;
a = 2;
function test() {
  var a = 3;
}

CokeScript notion of scope is by function. You can assign explicitly to a higher scope by using an eplicit assign :=.

a = 2
def test()
  a := 3

Generates

var a = 2;
function test() {
  a = 3;
}

Functions and lambda

All following forms are valid ways to declare functions

a = def
  return 1

def function_name(a, b=1 + 1)
  return a + b

def(a, b=1 + 1)
  return a + b

def lambda_name(a, b) a + b

def(a, b) a + b

Assignement Unpacking

Assignement can unpack positionnal values

def test()
  return 1, 1 + 1, 2

obj = {}
obj.first, obj.toto, other = test()

hello, world = "something", "else"

Generates

var obj, other, hello, world;
function test() {
  return [1, 1 + 1, 2];
}

obj = {};
var __unpack1 = test();
obj.first = __unpack1[0];
obj.toto = __unpack1[1];
other = __unpack1[2];

var __unpack2 = ["something", "else"];
hello = __unpack2[0];
world = __unpack2[1];

Assignement Mapping

Assignement to object literal can map attributes to different objects

great = {}
language = {name: " JavaScript"}

# map attribute greeting to great, and name to language
{greeting: great, name: language} = {greeting: "Hello! ", name: "CoffeScript"}
great.greeting + language.name

Generates

var great, language;
great = {};
language = {name: " JavaScript"};

// map attribute greeting to great, and name to language
var __unpack1 = {greeting: "Hello! ", name: "CoffeScript"};
great.greeting = __unpack1.greeting;
language.name = __unpack1.name;
great.greeting + language.name;

Loops

Both Objects and Arrays are iterable using the same type of loop.

for value in iterable
  console.log(value)

for index, value in iterable
  console.log(index, value)

i = 10
while i > 0
  i--

Conditionnal

if false or 2 < 0
  1
elseif true and 0
  2
else
  3

a = "Elephant" if weight > 1000 else "Mouse"

can_be_tamed = "Yes" if a == "Elephant"

Generates

var a, can_be_tamed;
if(false || 2 < 0) {
  1;
} else if(true && 0) {
  2;
} else {
  3;
}

a = weight > 1000 ? "Elephant" : "Mouse";

can_be_tamed = a === "Elephant" ? "Yes" : undefined;

Strings

Strings can be interpolated ruby style

data = {
  h: "Hello",
  w: "world"
}

string = "#{data.d}
#{data.w}"

Generates

var data;
var string;
data = {
  h: "Hello",
  w: "world"
};

string = "" + data.d + "\n" + data.w + "";

Try / Catch / Throw

Simply mirror JavaScript

try
  something_wrong()
catch(e)
  console.log(e)
  throw new Error("Something else")

Regular expression

Are identical to JavaScript

"Abc".match(/abc/i)

Classes

class Animal()
  
  def constructor(name)
    this.name = name

class Tiger(Animal)

  def eat()
    return "Meat"

Pass

Like python empty blocks are not allowed but you can use the pass keyword.

if 1 == 2
  pass

Generates

if(1 === 2) {
  
}

Virtual DOM

By adding 2 keywords and a special function declared with dom CokeScript can generate virtual DOM objects using the virtual-dom library. This quite useful and be used like JSX from React to create HTML components that can be updated with DOM diff.

dom generateVirtualDom(links)
  <ul className="nav">
    for index, content in links
      <li className="cls#{index}">
        =content

Generates

function generateVirtualDom(links) {
  var __c1 = [];
  var __c2, __index1, __keys1, index, content, __c3, __tmp;
  __c2 = [];
    __keys1 = Object.keys(links);
    for(__index1 = 0; __index1 < __keys1.length; __index1++) {
      index = __keys1[__index1];
      content = links[__keys1[__index1]];
      __c3 = [];
        __tmp = content; __tmp instanceof Array ? (__c3 = __c3.concat(__tmp)) : __c3.push(String(__tmp));
      __c2.push(virtual.h("li", {attributes: {className: "cls" + index + ""}}, __c3));
    }
  __c1.push(virtual.h("ul", {attributes: {className: "nav"}}, __c2));
  return __c1;
}