UglifyJS/README.md

527 lines
10 KiB
Markdown
Raw Normal View History

2014-04-15 12:22:58 +00:00
![logo](http://trigen.pro/colalogo.png)
2014-05-29 18:14:09 +00:00
ColaScript is a language that compiles in JavaScript. This language is similar to Dart, CoffeeScript, Python and PHP, with some original ideas. Compiler based on [UglifyJS2](https://github.com/mishoo/UglifyJS2). You can play with language [here](http://develop.trigen.pro/cola/).
2014-05-27 12:10:44 +00:00
2014-05-29 16:28:08 +00:00
Installation
2014-05-27 12:10:44 +00:00
===
2014-05-29 16:28:08 +00:00
Firstly, make sure you have installed the latest version of [node.js](http://nodejs.org/)
(You may need to restart your computer after this step).
From NPM for use as a command line app:
npm install cola-script -g
From NPM for programmatic use:
npm install cola-script
From Git:
git clone git://github.com/TrigenSoftware/ColaScript.git
cd ColaScript
npm link .
2014-05-29 16:28:08 +00:00
Use it same as in [UglifyJS2](https://github.com/mishoo/UglifyJS2), except:
2014-05-27 12:10:44 +00:00
-j, --js, --javascript Work with JavaScript (by default Cola will
expect ColaScript). [boolean]
-n, --no-main-binding Disable `main` binding. [boolean]
Simple example of usage:
cola main.cola -o main.min.js -m -c
In browser
===
2014-05-29 16:28:08 +00:00
In developing is more comfortable to compile the code directly in your browser, for this add `browser-cola.js` to `your.html` code:
2014-05-27 12:10:44 +00:00
<script src="path/to/browser-cola.js"></script>
Now you can run your Cola-Code:
<script type="text/colascript" src="path/to/your.cola"></script>
2014-05-29 16:28:08 +00:00
If `your.cola` depends on other scripts in `your.html`,it's better to notice `browser-cola` about it:
2014-05-27 12:10:44 +00:00
<script type="text/colascript" src="angular.min.js"></script>
<script type="text/colascript" src="path/to/your.cola"></script>
Overview
===
2014-05-28 18:11:43 +00:00
### Need to know
2014-05-27 12:10:44 +00:00
- not always valid-javascript is valid-colascript
- semicolon is always required
- in present time typing is just syntax
2014-05-28 18:11:43 +00:00
### Variables
2014-05-29 16:28:08 +00:00
You can set any type which you want in current version , to tell you the truth it's not so good. In future we will have static typing.
2014-05-27 12:10:44 +00:00
var num = 1; // valid JavaScript
int i, j = 3;
String str = `someString`; // yes, you can use ` quotes
In ColaScript, like in CoffeScript, exists boolean-aliases:
yes == on == true;
2014-05-29 18:33:48 +00:00
no == off == false;
2014-05-27 12:10:44 +00:00
2014-05-28 18:11:43 +00:00
### Strings
2014-05-27 12:10:44 +00:00
We have templating! We can paste variable in string:
2014-05-27 12:10:44 +00:00
console.log("my login in twitter \@@twLogin");
2014-05-29 16:28:08 +00:00
Also we can paste expression in this way:
2014-05-27 12:10:44 +00:00
console.log("length of my name @{ name.length }");
and this way:
console.log("first letter in my name is {{ name[0] }}");
2014-05-29 16:28:08 +00:00
It is still possible to use raw strings:
2014-05-27 12:10:44 +00:00
console.log(r"\n\r\t@raw");
Any string in ColaScript is multiline:
console.log("
List1:
- Write code
- Drink tea
- Watch Instagram
List2
* Write code
* Read Habrahabr
* Listen music
");
align goes by closing-quote.
2014-05-28 18:11:43 +00:00
### RegExps
2014-05-27 12:10:44 +00:00
Modifer `x` skips whitespaces and new-line same as if you use multiline RegExp:
RegExp url = /
^
(https?:\/\/)?
([\w\.]+)
\.([a-z]{2,6}\.?)
(\/[\w\.]*)*\/?
$/;
2014-05-28 18:11:43 +00:00
### Arrays
2014-05-29 16:28:08 +00:00
Most of array features were taken from CoffeeScript:
2014-05-27 12:10:44 +00:00
Array arr = [0..9]; // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
// same as
Array arr = [0...10];
arr[0..2] = [584, 404]; // [584, 404, 3, 4, 5, 6, 7, 8, 9]
2014-05-29 18:33:48 +00:00
console.log(arr[0..2]); // [584, 404, 3]
2014-05-27 12:10:44 +00:00
2014-05-29 16:28:08 +00:00
one feature was taken from PHP:
2014-05-27 12:10:44 +00:00
arr[] = 22; // [584, 404, 3, 4, 5, 6, 7, 8, 9, 22]
absolutely new feature is:
console.log(arr[]); // 22
2014-05-28 18:11:43 +00:00
### Functions
2014-05-29 16:28:08 +00:00
You have opportunity to declarate functions without `function` keyword, with type and without it:
2014-05-27 12:10:44 +00:00
function f1(){
}
void f2(){
}
2014-05-28 18:11:43 +00:00
f3(){
2014-05-27 12:10:44 +00:00
}
2014-05-29 16:28:08 +00:00
From Dart we have borrowed arrow-functions:
2014-05-27 12:10:44 +00:00
helloString(name) => "Hello @name!";
Arguments have `positional` or `named` types and can have default value:
hello(String name:) => console.log("Hello @name!");
hello(name: 'dangreen'); // Hello dangreen!
hello(name: "World") => console.log("Hello @name!");
hello(); // Hello World!
// or
hello(String name = "World") => console.log("Hello @name!");
hello('dangreen'); // Hello dangreen!
hello(); // Hello World!
As in CoffeScript we can declare `splated` argument
info(name, skills...){
console.log("My name is @name, my skills:");
skills.forEach((skill) => console.log("@skill,"));
}
All `main` functions in root namespace will bind on `DOMContentLoaded` event:
// lib.cola
main(){
console.log('Hello World from lib.cola!');
}
// main.cola
@require "lib.cola";
main(){
console.log('Hello World!');
}
2014-05-28 18:11:43 +00:00
### Operators
- `isset` operator:
2014-05-27 12:10:44 +00:00
bool a = true, b;
console.log(isset a ? "seted" : "not seted"); // seted
console.log(isset b ? "seted" : "not seted"); // not seted
2014-04-19 18:04:21 +00:00
2014-05-27 12:10:44 +00:00
- `clone` of variable:
2014-04-19 18:04:21 +00:00
2014-05-27 12:10:44 +00:00
Array a = [], b = clone a;
2014-04-19 18:04:21 +00:00
b[0] = 584; // a == []
if object have method `__clone__`, object will be copied with it.
2014-05-27 12:10:44 +00:00
- Math.pow operator:
2014-04-15 12:22:58 +00:00
int pow = 5 ** 2; // 25
2014-05-27 12:10:44 +00:00
- CoffeeScript's modulo operator:
2014-05-28 18:11:43 +00:00
Array nums = [0..9];
console.log(nums[4 %% nums.length]); // 4
console.log(nums[14 %% nums.length]); // 4
2014-04-15 12:22:58 +00:00
2014-05-27 12:10:44 +00:00
- Existential assignment from CoffeeScript:
2014-05-28 18:11:43 +00:00
defaults(Object input, Object defaults){
for(int key in defaults) input[key] ?= defaults[key];
return input;
}
console.log(defaults({
compress: true
}, {
compress: false,
mangle: false
})); // { compress: true, mangle: false }
2014-04-15 12:22:58 +00:00
2014-05-28 18:11:43 +00:00
- Existential operator:
2014-05-28 18:11:43 +00:00
int a, b = 3;
2014-04-15 12:22:58 +00:00
2014-05-28 18:11:43 +00:00
console.log(a ? b); // 3
2014-04-15 12:22:58 +00:00
a = 11;
2014-05-28 18:11:43 +00:00
console.log(a ? b); // 11
2014-04-15 12:22:58 +00:00
2014-05-28 18:11:43 +00:00
- Binary operator `is`:
2014-04-15 12:22:58 +00:00
bool isRegExp = /[^\d]+/g is RegExp; // true
2014-05-29 16:28:08 +00:00
- Binary operator `isnt`:
2014-04-15 12:22:58 +00:00
bool isntString = 3.14 isnt String; // true
2014-05-28 18:11:43 +00:00
### Constructions
2014-05-29 16:28:08 +00:00
In ColaScript you can use those syntax with object, in way not to repeat var names:
2014-04-15 12:22:58 +00:00
2014-05-28 18:11:43 +00:00
String name = "dangreen";
int age = 19;
String about = "
Web programmer, NSTU student.
";
Object info = { name, age, about };
2014-04-15 12:22:58 +00:00
2014-05-28 18:11:43 +00:00
Also you can use `destructuring assignment`:
2014-04-15 12:22:58 +00:00
2014-05-28 18:11:43 +00:00
int a = 2, b = 3;
// swap
[a, b] = [b, a];
// with object
{ name, age, about, friends : [firstFriend] } = info;
// with array
[firstSkill, ..., lastSkill] = skills;
2014-05-29 16:28:08 +00:00
From Dart we have taken `cascade operator`:
2014-05-28 18:11:43 +00:00
document.querySelector("#myelement").style
..fontSize = "16px"
..color = "black";
2014-05-29 16:28:08 +00:00
but we have made some modification:
2014-05-28 18:11:43 +00:00
document.querySelector("#myelement")
..style:
..fontSize = "16px"
..color = "black";
..innerHTML = "Hello World!";
2014-04-15 12:22:58 +00:00
2014-05-28 18:11:43 +00:00
As in CoffeeScript, you can use `chained comprassions`:
2014-04-15 12:22:58 +00:00
2014-05-28 18:11:43 +00:00
if( 1 < x < 100 ) console.log("x E ( 1 ; 100 )");
2014-04-15 12:22:58 +00:00
2014-05-28 18:11:43 +00:00
`inline conditions`:
2014-04-15 12:22:58 +00:00
2014-05-28 18:11:43 +00:00
String name =
if (sex == "male") "Dan"
else if (sex == "female") "Dasha"
else "none";
`inline switch` and `switch without expression`:
String grade = switch {
when score < 60: 'F'
when score < 70: 'D'
when score < 80: 'C'
when score < 90: 'B'
default: 'A'
}
2014-05-29 16:28:08 +00:00
As you see, you can use keyword `when`, it's like `case`, but if the condition is satisfied, `switch` will `break`.
2014-05-28 18:11:43 +00:00
### Compiler commands
- `@require`, pushed required code to front
2014-04-15 12:22:58 +00:00
2014-05-21 18:01:32 +00:00
@require "./library/jquery.js" "./library/underscore.js"
2014-04-15 12:22:58 +00:00
2014-05-28 18:11:43 +00:00
- `@include`, insert included code on `@include` place
2014-05-22 15:44:11 +00:00
@include "./app/my.js"
2014-05-28 18:11:43 +00:00
- `@use`, enable one of mods
2014-04-15 12:22:58 +00:00
2014-05-19 17:29:01 +00:00
@use strict
2014-05-28 18:11:43 +00:00
@use asm
2014-05-19 17:29:01 +00:00
@use closure
2014-05-28 18:11:43 +00:00
2014-05-29 16:28:08 +00:00
`@use closure` wrapping code in closure:
2014-05-28 18:11:43 +00:00
// cola
@use closure
NgModule app = angular.module('app', []);
// js
(function(){
2014-05-29 18:15:37 +00:00
var app = angular.module('app', []);
2014-05-28 18:11:43 +00:00
})();
Also you can use multiple closures in one file:
@use closure {
int a = 123;
}
@use closure {
int a = 321;
}
2014-04-15 12:22:58 +00:00
2014-05-28 18:11:43 +00:00
2014-05-29 16:28:08 +00:00
Future plans
2014-05-28 18:11:43 +00:00
===
- static typing
2014-05-29 15:38:41 +00:00
- Compiler command `@import` to import modules ( AMD, CommonJS... )
// node.js
@import 'fs' as fs
@import dirname from 'path'
String code = fs.readFileSync(dirname(filePath) + "/main.cola", "utf8");
2014-05-29 11:15:06 +00:00
- set parameters to calling function
$(".btn").on("click", () use (context: myContext){
this; // myContext
});
2014-04-15 12:22:58 +00:00
- classes
class A {
private int a = 123;
protected var o = {};
readonly String about = "class";
A(a){
about = "some else";
}
static Hello() => "hello!";
public String about() => about;
}
class B extends A {
B(){
parent();
about += "!";
}
B.anotherConstructor(){
about = "ups!";
}
get some => "some " + about;
set some(val) => about += val;
}
2014-05-28 18:11:43 +00:00
- classes and typing with templates
class A<T> {
// ...
}
Array<int> arr = [0...10];
Object<String, String> obj = { name: "Eric" };
- singletones
2014-04-15 12:22:58 +00:00
singleton S { // in fact this is object
int x = 45;
String s = "txt";
say(some){
alert(some);
}
int operator[](int index) => index + 584;
operator[]=(int index, int val) => x = index + val;
}
2014-05-28 18:11:43 +00:00
- injectors
2014-04-15 12:22:58 +00:00
injector String {
String replaceAll(a, b){
String res = this;
while(res.indexOf(a) != -1) res = res.replace(a, b);
return res;
}
}
2014-05-29 16:28:08 +00:00
- declaration function by objects' property
2014-04-15 12:22:58 +00:00
String String::replaceAll(a, b){
String res = this;
while(res.indexOf(a) != -1) res = res.replace(a, b);
return res;
}
2014-05-28 18:11:43 +00:00
// or
Object data = someData;
int data.getFriendsCount() => this.friends.length;
- destructed function arguments
2014-05-29 11:25:22 +00:00
test({String name, String login, String photoUrl}){
console.log(name, login, photoUrl);
}
2014-05-28 18:11:43 +00:00
- ES6 `for`
2014-05-29 11:25:22 +00:00
for({String name, String login, String photoUrl} in usesr){
2014-05-28 18:11:43 +00:00
2014-05-29 11:25:22 +00:00
}
2014-05-28 18:11:43 +00:00
2014-05-29 11:25:22 +00:00
for(name of names){
2014-05-28 18:11:43 +00:00
2014-05-29 11:25:22 +00:00
}
2014-05-28 18:11:43 +00:00
- asm.js native syntax, for example
// cola
// ...
@use asm
int f(double j){
int i = 1;
return i;
}
// js
// ...
"use asm";
function f(j){
j = +j;
var i = 1|0;
return i|0;
}
2014-05-29 16:28:08 +00:00
- Plugin API to make native syntax for libraries and frameworks
2014-05-28 18:11:43 +00:00
class MyComponent extends PolymerComponent {
String tagname = "my-component";
ready(){
// ...
}
}
to
Polymer('my-component', {
ready: function(){
// ...
}
});
2014-05-29 11:15:06 +00:00
2014-05-29 15:38:41 +00:00
- Compiler command `@use plugin "path/to/plugin.cola"`
2014-05-29 11:15:06 +00:00
- write documentation of tokenizer/parser methods
- HTML and CSS stuff
String width = 12px;
String div = <div class="inline">
<h1>Example of Embedded HTML</h1>
</div>;
by default it will parsed as `String`, but it may be handled by Plugins.