- Use inline `isset` expression instead function. status: done - Use inline `is`. status: done - `some is NaN` to `isNaN(some)`. status: done - operator `?` instead `isset`. status: done - rename runtime prefix `$_cola` to `_ColaRuntime$$`. status: done - dotal names of refs: done
322 lines
9.4 KiB
HTML
322 lines
9.4 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<title>ColaScript Playground</title>
|
|
<script src="./utils.js"></script>
|
|
<script src="./ast.js"></script>
|
|
<script src="./parse.js"></script>
|
|
<script src="./transform.js"></script>
|
|
<script src="./scope.js"></script>
|
|
<script src="./output.js"></script>
|
|
<script src="./compress.js"></script>
|
|
<script src="./sourcemap.js"></script>
|
|
<script src="./mozilla-ast.js"></script>
|
|
<script src="./translate.js"></script>
|
|
<script src="./std.js"></script>
|
|
<script src="./typecheck.js"></script>
|
|
<style>
|
|
|
|
body {
|
|
padding: 0;
|
|
margin: 0;
|
|
line-height: 100%;
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
|
|
.triple textarea {
|
|
width: 33.333%;
|
|
}
|
|
|
|
.double textarea {
|
|
width: 50%;
|
|
}
|
|
|
|
textarea {
|
|
-moz-box-sizing: border-box;
|
|
box-sizing: border-box;
|
|
height: 100%;
|
|
font-size: 15px;
|
|
float: left;
|
|
font-family: "Andale Mono";
|
|
padding: 0 5px 26px 5px;
|
|
background-color: #272A32;
|
|
color: #D6D7D9;
|
|
}
|
|
|
|
#controls {
|
|
position: fixed;
|
|
bottom: 0;
|
|
left: 0;
|
|
height: 25px;
|
|
width: 100%;
|
|
}
|
|
|
|
#controls .m {
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
-moz-box-sizing: border-box;
|
|
box-sizing: border-box;
|
|
margin: 2px 0 0 2px;
|
|
}
|
|
|
|
#controls .bg {
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
background-color: white;
|
|
opacity: 0.8;
|
|
}
|
|
|
|
#lenstat {
|
|
float: right;
|
|
margin: 2px 10px;
|
|
}
|
|
|
|
</style>
|
|
</head>
|
|
<body class="triple">
|
|
<textarea id="source" onkeyup="compile()">// `main` functions may binding to a onload event
|
|
// Functions can defined without `function` keyword, with and without `type`
|
|
main(){
|
|
|
|
// Unary operators
|
|
// Two variants of `isset` operator. Which is better?
|
|
bool _seted = true, _empty;
|
|
console.log("`_seted` is", _seted?? ? "seted" : "empty");
|
|
console.log("`_empty` is", isset _empty ? "seted" : "empty");
|
|
|
|
// `clone` operator
|
|
Array _first = [584], _second = clone _first;
|
|
_first.push(404);
|
|
console.log("`_first`:",_first,"`_second`:",_second);
|
|
|
|
// Binary operators
|
|
// `pow` operator
|
|
console.log("5 ** 3 =", 5 ** 3);
|
|
|
|
// `modulo` operator
|
|
console.log("10 %% 4 = ", 10 %% 4);
|
|
|
|
// `isset` conditional assignment
|
|
int a, b = 4;
|
|
console.log("`a` is", a, ", now `a` is", a ?= b);
|
|
console.log("`a` is", a, ", now `a` still", a ?= 584);
|
|
|
|
// `isset` binary conditional
|
|
int x, y = 5;
|
|
console.log("`x` is", x, ", `y` is", y, ", x ? y = ", x ? y), x = 1;
|
|
console.log("`x` is", x, ", `y` is", y, ", x ? y = ", x ? y);
|
|
|
|
// `is` operator
|
|
console.log("'hello'", "hello" is String ? "is" : "isnt", "`String`");
|
|
|
|
// `isnt` operator
|
|
console.log("'goodby'", "goodby" isnt Number ? "isnt" : "is", "`Number`");
|
|
|
|
// Boolean alternatives
|
|
console.log("`yes` and `no`", yes is Boolean && no is Boolean ? "is" : "isnt", "`Boolean`");
|
|
console.log("`on` and `off`", on is Boolean && off is Boolean ? "is" : "isnt", "`Boolean`");
|
|
|
|
// Strings
|
|
// New quotes symbol, multi-lining and templating
|
|
console.log(`
|
|
|
|
Hello!
|
|
My name is ColaScript, and i know who you are }:->
|
|
User agent: @{navigator.userAgent}
|
|
Vendor: {{navigator.vendor}}
|
|
|
|
`);
|
|
|
|
// Raw strings
|
|
console.log(r"\n \r \t some@email.ru");
|
|
|
|
// Multiline RegExp's
|
|
RegExp isEmail = /
|
|
([\w-\.]+)
|
|
@
|
|
((?:[\w]+\.)+)
|
|
([a-zA-Z]{2,4})
|
|
/;
|
|
String email = r'some@email.ru';
|
|
console.log("@email {{ isEmail.test(email) ? "is" : "isnt" }} valid email adress");
|
|
|
|
// Arrays
|
|
// Empty getter and setter ( pushing )
|
|
Array arr = [2, 4, 8, 16, 32];
|
|
console.log("Last element of `arr` is", arr[]), arr[] = 64;
|
|
console.log("Now last element of `arr` is", arr[]);
|
|
|
|
// Splice assignment
|
|
arr[2..4] = [3, 2, 1];
|
|
console.log("`arr` is", arr);
|
|
|
|
// Range
|
|
console.log("`[0..10]` is", [0..10]);
|
|
|
|
// Calling function
|
|
Object pro;
|
|
console.log(pro = Profile(
|
|
"Dan", "Green", "Russia",
|
|
"HTML5", "JavaScript", "Dart", "PHP", "CSS3", "LESS", "Qt",
|
|
age : 19,
|
|
petName : "Felix"
|
|
));
|
|
|
|
// Cascade operator
|
|
pro
|
|
..firstName += "iil"
|
|
..secondName = "Onoshko"
|
|
..skills:
|
|
..[1] = "JS";
|
|
;
|
|
|
|
console.log(pro);
|
|
}
|
|
|
|
// Functions
|
|
// Named, positional and splated arguments, with default values.
|
|
// Arrow functions.
|
|
Object Profile(String firstName, String secondName, String country = "Russia", Array skills..., age:, petName: "Tux"){
|
|
skills.forEach((val) => val == "JavaScript" && console.log("JavaScript - It Awesome!"));
|
|
return {
|
|
firstName : firstName,
|
|
secondName : secondName,
|
|
age : age,
|
|
country : country,
|
|
skills : skills,
|
|
petName : petName
|
|
};
|
|
}
|
|
|
|
main();</textarea>
|
|
<textarea id="translation"></textarea>
|
|
<textarea id="result"></textarea>
|
|
<div id="controls">
|
|
<div class="bg"> </div>
|
|
<div class="m">
|
|
<button id="exec" onclick="exec()">Execute</button>
|
|
<button onclick="benchmarkTranslate()">Benchmark Translation</button>
|
|
<button onclick="benchmarkResult()">Benchmark Result</button>
|
|
<input type="checkbox" id="is_js" onclick="compile()">
|
|
<label for="is_js">js parser</label>
|
|
<input type="checkbox" id="main_binding" onclick="compile()">
|
|
<label for="main_binding">`main` binding</label>
|
|
<input type="checkbox" id="compressed" onclick="changeClass()">
|
|
<label for="compressed">compressed</label>
|
|
<span id="lenstat"></span>
|
|
</div>
|
|
</body>
|
|
<script>
|
|
var sourceArea = document.getElementById("source"),
|
|
translationArea = document.getElementById("translation"),
|
|
resultArea = document.getElementById("result"),
|
|
isjs = document.getElementById("is_js"),
|
|
mainbinding = document.getElementById("main_binding"),
|
|
compressed = document.getElementById("compressed"),
|
|
source;
|
|
//localStorage.clear();
|
|
if(!localStorage.source) localStorage.source = source = sourceArea.value;
|
|
else sourceArea.value = source = localStorage.source;
|
|
isjs.checked = localStorage.isjs == "t";
|
|
mainbinding.checked = localStorage.mainbinding == "t";
|
|
compressed.checked = localStorage.compressed == "t";
|
|
|
|
function changeClass(){
|
|
document.body.className = compressed.checked ? "triple" : "double";
|
|
localStorage.compressed = compressed.checked ? "t" : "f";
|
|
}
|
|
|
|
function compile(){
|
|
source = sourceArea.value;
|
|
localStorage.source = source;
|
|
localStorage.isjs = isjs.checked ? "t" : "f";
|
|
localStorage.mainbinding = mainbinding.checked ? "t" : "f";
|
|
|
|
stream = new Cola.OutputStream({ beautify : true, comments : true });
|
|
compressor = new Cola.Compressor({ is_js : isjs.checked });
|
|
|
|
try {
|
|
// 1. compile
|
|
ast = Cola.parse(source, { is_js : isjs.checked });
|
|
if(!isjs.checked) ast = ast.toJavaScript({ main_binding : mainbinding.checked });
|
|
ast.print(stream);
|
|
translationArea.value = stream.toString();
|
|
|
|
// 2. compress
|
|
ast.figure_out_scope();
|
|
ast = ast.transform(compressor);
|
|
|
|
// 3. mangle
|
|
ast.figure_out_scope();
|
|
ast.compute_char_frequency();
|
|
ast.mangle_names({ sort : true, toplevel : true });
|
|
|
|
stream = new Cola.OutputStream();
|
|
ast.print(stream);
|
|
resultArea.value = stream.toString();
|
|
} catch(e){
|
|
translationArea.value = '';
|
|
resultArea.value = '';
|
|
|
|
throw e;
|
|
}
|
|
|
|
document.querySelector('#lenstat').innerHTML = sourceArea.value.length+" : "+translationArea.value.length+" : "+resultArea.value.length;
|
|
}
|
|
|
|
function benchmarkResult(){
|
|
console.time("Result");
|
|
eval(resultArea.value);
|
|
console.timeEnd("Result");
|
|
}
|
|
|
|
function benchmarkTranslate(){
|
|
console.time("Translation");
|
|
eval(translationArea.value);
|
|
console.timeEnd("Translation");
|
|
}
|
|
|
|
function exec(){
|
|
eval.call(window, translationArea.value);
|
|
}
|
|
|
|
function Translate(){
|
|
stream = new Cola.OutputStream({ beautify : true });
|
|
translate(Cola.parse(source, null, isjs.checked)).print(stream);
|
|
return stream.toString();
|
|
}
|
|
|
|
function Test(){
|
|
var ast;
|
|
|
|
try {
|
|
// 1. compile
|
|
ast = Cola.parse(source, { is_js : isjs.checked });
|
|
if(!isjs.checked) ast = ast.toJavaScript({ main_binding : mainbinding.checked });
|
|
|
|
// 3. mangle
|
|
ast.figure_out_scope();
|
|
//ast.compute_char_frequency();
|
|
//ast.mangle_names({ sort : true, toplevel : true });
|
|
|
|
return ast;
|
|
} catch(e){
|
|
throw e;
|
|
}
|
|
}
|
|
|
|
changeClass();
|
|
compile();
|
|
</script>
|
|
</html>
|