modules are done

This commit is contained in:
Dan Onoshko 2014-12-31 03:18:16 +07:00
parent 45da7bde29
commit d87a5db0fd
9 changed files with 670 additions and 195 deletions

View File

@ -390,16 +390,14 @@ Future plans
_ColaRuntime$$updateProperty(Math, "rand", { _ColaRuntime$$updateProperty(Math, "rand", {
get: function rand() { get: function rand() {
return 123; return 123;
}, }
configurable: true
}); });
_ColaRuntime$$updateProperty(Math, "rand", { _ColaRuntime$$updateProperty(Math, "rand", {
set: function rand() { set: function rand() {
var val = arguments[0] !== undefined ? arguments[0] : _ColaRuntime$$error("Argument `val` is required!"); var val = arguments[0] !== undefined ? arguments[0] : _ColaRuntime$$error("Argument `val` is required!");
return console.log(val); return console.log(val);
}, }
configurable: true
}); });
- operator `?.`. status: done - operator `?.`. status: done
@ -424,12 +422,13 @@ Future plans
- var modificators. status: done - var modificators. status: done
readonly int Math.Pi = 3.14; const int Math.Pi = 3.14;
list of modificators list of modificators
* static: vars, funcs, getters and setters in class * static: vars, funcs, getters and setters in classes
* const: vars * const: vars, props
* covert: vars, funcs, getters and setters in class and objects * covert: vars, funcs, getters and setters in classes and objects, props
* export: vars, funcs, classes, singletones
- classes. status: done - classes. status: done
@ -464,7 +463,7 @@ Future plans
set some(val) => about += val; set some(val) => about += val;
} }
- singletones - singletones. status: done
singleton S { // in fact this is object singleton S { // in fact this is object
int x = 45; int x = 45;
@ -478,18 +477,40 @@ Future plans
operator[]=(int index, int val) => x = index + val; operator[]=(int index, int val) => x = index + val;
} }
- injectors
injector String { - Compiler command `@import` to import modules ( CommonJS ), status: done
String replaceAll(a, b){
String res = this; @import 'sugar'
while(res.indexOf(a) != -1) res = res.replace(a, b); @import 'fs' as fs
return res; @import dirname from 'path'
} @import print as echo, prompt as ask, test from 'mylib'
}
- add `observe` modificator. String code = fs.readFileSync(dirname(filePath) + "/main.cola", "utf8");
echo("hello!");
- Compiler command `@export` to export modules ( CommonJS ), status: done
Object hash = {};
Array users = [];
@export hash as _, users
@export each as forEach from "underscore"
@export "mylib"
- `await` operator (only with Promise support)
String name = await getNameFromServer(id);
console.log(name);
to
getNameFromServer(id).then(function(_ColaRuntime$$fulfilled, _ColaRuntime$$rejected) {
if (_ColaRuntime$$rejected) throw _ColaRuntime$$rejected;
String name = __ColaRuntime$$fulfilled;
console.log(name);
});
- static typing - static typing
- `@use` expressions - `@use` expressions
@ -540,15 +561,6 @@ Future plans
} }
- 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");
- write documentation of tokenizer/parser methods - write documentation of tokenizer/parser methods
- more informative exceptions - more informative exceptions
- better source maps - better source maps

View File

@ -1,4 +1,4 @@
#! /usr/bin/env node #!/usr/bin/env node
// -*- js -*- // -*- js -*-
"use strict"; "use strict";
@ -20,6 +20,8 @@ with whitespace and comments discarded. To achieve compression and\n\
mangling you need to use `-c` and `-m`.\ mangling you need to use `-c` and `-m`.\
") ")
.describe("j", "Work with JavaScript (by default Cola will expect ColaScript).") .describe("j", "Work with JavaScript (by default Cola will expect ColaScript).")
.describe("n", "Enable compilation for node.")
.describe("k", "Path to packages.json (packages.json by default).")
.describe("source-map", "Specify an output file where to generate source map.") .describe("source-map", "Specify an output file where to generate source map.")
.describe("source-map-root", "The path to the original source to be included in the source map.") .describe("source-map-root", "The path to the original source to be included in the source map.")
.describe("source-map-url", "The path to the source map to be added in //# sourceMappingURL. Defaults to the value passed with --source-map.") .describe("source-map-url", "The path to the source map to be added in //# sourceMappingURL. Defaults to the value passed with --source-map.")
@ -27,7 +29,7 @@ mangling you need to use `-c` and `-m`.\
.describe("in-source-map", "Input source map, useful if you're compressing JS that was generated from some other original code.") .describe("in-source-map", "Input source map, useful if you're compressing JS that was generated from some other original code.")
.describe("screw-ie8", "Pass this flag if you don't care about full compliance with Internet Explorer 6-8 quirks (by default Cola will try to be IE-proof).") .describe("screw-ie8", "Pass this flag if you don't care about full compliance with Internet Explorer 6-8 quirks (by default Cola will try to be IE-proof).")
.describe("expr", "Parse a single expression, rather than a program (for parsing JSON)") .describe("expr", "Parse a single expression, rather than a program (for parsing JSON)")
.describe("n", "Disable `main` binding.") .describe("i", "ignore `main` binding.")
.describe("p", "Skip prefix for original filenames that appear in source maps. \ .describe("p", "Skip prefix for original filenames that appear in source maps. \
For example -p 3 will drop 3 directories from file names and ensure they are relative paths. \ For example -p 3 will drop 3 directories from file names and ensure they are relative paths. \
You can also specify -p relative, which will make Cola figure out itself the relative paths between original sources, \ You can also specify -p relative, which will make Cola figure out itself the relative paths between original sources, \
@ -69,7 +71,9 @@ You need to pass an argument to this option to specify the name that your module
.alias("j", "js") .alias("j", "js")
.alias("j", "javascript") .alias("j", "javascript")
.alias("n", "no-main-binding") .alias("n", "node")
.alias("k", "packages")
.alias("i", "ignore-main-binding")
.alias("p", "prefix") .alias("p", "prefix")
.alias("o", "output") .alias("o", "output")
.alias("v", "verbose") .alias("v", "verbose")
@ -81,6 +85,7 @@ You need to pass an argument to this option to specify the name that your module
.alias("V", "version") .alias("V", "version")
.alias("e", "enclose") .alias("e", "enclose")
.string("k")
.string("source-map") .string("source-map")
.string("source-map-root") .string("source-map-root")
.string("source-map-url") .string("source-map-url")
@ -94,8 +99,9 @@ You need to pass an argument to this option to specify the name that your module
.string("p") .string("p")
.boolean("j") .boolean("j")
.boolean("expr")
.boolean("n") .boolean("n")
.boolean("expr")
.boolean("i")
.boolean("source-map-include-sources") .boolean("source-map-include-sources")
.boolean("screw-ie8") .boolean("screw-ie8")
.boolean("export-all") .boolean("export-all")
@ -293,7 +299,9 @@ async.eachLimit(files, 1, function (file, cb) {
}); });
if (!ARGS.j) TOPLEVEL = TOPLEVEL.toJavaScript({ if (!ARGS.j) TOPLEVEL = TOPLEVEL.toJavaScript({
main_binding: !ARGS.n, main_binding: !ARGS.i,
is_node: ARGS.n,
modules: Cola.getPackages(ARGS.k),
path: path.dirname(file), path: path.dirname(file),
parser: { parser: {
expression : ARGS.expr, expression : ARGS.expr,
@ -423,7 +431,15 @@ function getOptions(x, constants) {
var ast; var ast;
try { try {
ast = Cola.parse(x, { expression: true, is_js: ARGS.j }); ast = Cola.parse(x, { expression: true, is_js: ARGS.j });
if (!ARGS.j) ast = ast.toJavaScript({ main_binding: !ARGS.n, parser: { expression: true, is_js: ARGS.j } }); if (!ARGS.j) ast = ast.toJavaScript({
main_binding: !ARGS.i,
is_node: ARGS.n,
modules: Cola.getPackages(ARGS.k),
parser: {
expression: true,
is_js: ARGS.j
}
});
} catch(ex) { } catch(ex) {
if (ex instanceof Cola.JS_Parse_Error) { if (ex instanceof Cola.JS_Parse_Error) {
sys.error("Error parsing arguments in: " + x); sys.error("Error parsing arguments in: " + x);

View File

@ -310,10 +310,12 @@ Cola.AST_Scope = Cola.DEFNODE("Scope", "directives variables functions uses_with
}, },
}, Cola.AST_Block); }, Cola.AST_Block);
Cola.AST_Toplevel = Cola.DEFNODE("Toplevel", "globals language", { Cola.AST_Toplevel = Cola.DEFNODE("Toplevel", "globals language requiredModules", {
$documentation: "The toplevel scope", $documentation: "The toplevel scope",
$propdoc: { $propdoc: {
globals: "[Object/S] a map of name -> SymbolDef for all undeclared names", globals: "[Object/S] a map of name -> SymbolDef for all undeclared names",
language: "[String] JavaScript or ColaScript",
requiredModules: "[Object] modules required in this code"
}, },
wrap_enclose: function(arg_parameter_pairs) { wrap_enclose: function(arg_parameter_pairs) {
var self = this; var self = this;
@ -378,7 +380,7 @@ Cola.AST_Toplevel = Cola.DEFNODE("Toplevel", "globals language", {
} }
}, Cola.AST_Scope); }, Cola.AST_Scope);
Cola.AST_Class = Cola.DEFNODE("Class", "name extends", { Cola.AST_Class = Cola.DEFNODE("Class", "name extends mods", {
$iscola: true, $iscola: true,
$documentation: "Base class for classes", $documentation: "Base class for classes",
$propdoc: { $propdoc: {
@ -394,7 +396,7 @@ Cola.AST_Class = Cola.DEFNODE("Class", "name extends", {
} }
}, Cola.AST_Scope); }, Cola.AST_Scope);
Cola.AST_Singleton = Cola.DEFNODE("Singleton", "name", { Cola.AST_Singleton = Cola.DEFNODE("Singleton", "name mods", {
$iscola: true, $iscola: true,
$documentation: "Base class for singletons", $documentation: "Base class for singletons",
$propdoc: { $propdoc: {
@ -408,20 +410,6 @@ Cola.AST_Singleton = Cola.DEFNODE("Singleton", "name", {
} }
}, Cola.AST_Scope); }, Cola.AST_Scope);
Cola.AST_Injector = Cola.DEFNODE("Injector", "name", {
$iscola: true,
$documentation: "Base class for injectors",
$propdoc: {
name: "[AST_SymbolInjector] the name of this injector"
},
_walk: function(visitor) {
return visitor._visit(this, function(){
this.name._walk(visitor);
Cola.walk_body(this, visitor);
});
}
}, Cola.AST_Scope);
Cola.AST_Lambda = Cola.DEFNODE("Lambda", "name argnames uses_arguments", { Cola.AST_Lambda = Cola.DEFNODE("Lambda", "name argnames uses_arguments", {
$documentation: "Base class for functions", $documentation: "Base class for functions",
$propdoc: { $propdoc: {
@ -984,11 +972,6 @@ Cola.AST_SymbolSingleton = Cola.DEFNODE("SymbolSingleton", null, {
$documentation: "Symbol defining a singleton", $documentation: "Symbol defining a singleton",
}, Cola.AST_SymbolDeclaration); }, Cola.AST_SymbolDeclaration);
Cola.AST_SymbolInjector = Cola.DEFNODE("SymbolInjector", null, {
$iscola: true,
$documentation: "Symbol defining an injector",
}, Cola.AST_SymbolDeclaration);
Cola.AST_SymbolFunarg = Cola.DEFNODE("SymbolFunarg", "type", { Cola.AST_SymbolFunarg = Cola.DEFNODE("SymbolFunarg", "type", {
$documentation: "Symbol naming a function argument", $documentation: "Symbol naming a function argument",
}, Cola.AST_SymbolVar); }, Cola.AST_SymbolVar);

View File

@ -2,6 +2,13 @@
<html> <html>
<head> <head>
<title>ColaScript Playground</title> <title>ColaScript Playground</title>
<script type="text/packages-json">
{
"underscore" : "/components/jashkenas/underscore/1.7.0/underscore.js",
"uid" : "/components/matthewmueller-uid@0.0.2/index.js",
"fmt" : "/components/yields-fmt@0.1.0/index.js"
}
</script>
<script src="./utils.js"></script> <script src="./utils.js"></script>
<script src="./ast.js"></script> <script src="./ast.js"></script>
<script src="./parse.js"></script> <script src="./parse.js"></script>
@ -89,7 +96,7 @@
</style> </style>
</head> </head>
<body class="triple"> <body class="triple">
<textarea id="source" onkeyup="compile()">// `main` functions may binding to a onload event <textarea id="source">// `main` functions may binding to a onload event
// Functions can defined without `function` keyword, with and without `type` // Functions can defined without `function` keyword, with and without `type`
main(){ main(){
@ -215,6 +222,8 @@ main();</textarea>
<label for="is_js">js parser</label> <label for="is_js">js parser</label>
<input type="checkbox" id="main_binding" onclick="compile()"> <input type="checkbox" id="main_binding" onclick="compile()">
<label for="main_binding">`main` binding</label> <label for="main_binding">`main` binding</label>
<input type="checkbox" id="is_node" onclick="compile()">
<label for="is_node">node</label>
<input type="checkbox" id="compressed" onclick="changeClass()"> <input type="checkbox" id="compressed" onclick="changeClass()">
<label for="compressed">compressed</label> <label for="compressed">compressed</label>
<span id="version">v0.6.0</span> <span id="version">v0.6.0</span>
@ -222,18 +231,37 @@ main();</textarea>
</div> </div>
</body> </body>
<script> <script>
function debounce(func, wait, immediate) {
var timeout;
return function() {
var context = this, args = arguments;
var later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
};
var sourceArea = document.getElementById("source"), var sourceArea = document.getElementById("source"),
translationArea = document.getElementById("translation"), translationArea = document.getElementById("translation"),
resultArea = document.getElementById("result"), resultArea = document.getElementById("result"),
isjs = document.getElementById("is_js"), isjs = document.getElementById("is_js"),
mainbinding = document.getElementById("main_binding"), mainbinding = document.getElementById("main_binding"),
isnode = document.getElementById("is_node"),
compressed = document.getElementById("compressed"), compressed = document.getElementById("compressed"),
source; source;
sourceArea.onkeyup = debounce(compile, 600);
//localStorage.clear(); //localStorage.clear();
if(!localStorage.source) localStorage.source = source = sourceArea.value; if(!localStorage.source) localStorage.source = source = sourceArea.value;
else sourceArea.value = source = localStorage.source; else sourceArea.value = source = localStorage.source;
isjs.checked = localStorage.isjs == "t"; isjs.checked = localStorage.isjs == "t";
mainbinding.checked = localStorage.mainbinding == "t"; mainbinding.checked = localStorage.mainbinding == "t";
isnode.checked = localStorage.isnode == "t";
compressed.checked = localStorage.compressed == "t"; compressed.checked = localStorage.compressed == "t";
function changeClass(){ function changeClass(){
@ -246,6 +274,7 @@ main();</textarea>
localStorage.source = source; localStorage.source = source;
localStorage.isjs = isjs.checked ? "t" : "f"; localStorage.isjs = isjs.checked ? "t" : "f";
localStorage.mainbinding = mainbinding.checked ? "t" : "f"; localStorage.mainbinding = mainbinding.checked ? "t" : "f";
localStorage.isnode = isnode.checked ? "t" : "f";
stream = new Cola.OutputStream({ beautify : true, comments : true }); stream = new Cola.OutputStream({ beautify : true, comments : true });
compressor = new Cola.Compressor({ is_js : isjs.checked }); compressor = new Cola.Compressor({ is_js : isjs.checked });
@ -253,7 +282,7 @@ main();</textarea>
try { try {
// 1. compile // 1. compile
ast = Cola.parse(source, { is_js : isjs.checked }); ast = Cola.parse(source, { is_js : isjs.checked });
if(!isjs.checked) ast = ast.toJavaScript({ main_binding : mainbinding.checked }); if(!isjs.checked) ast = ast.toJavaScript({ main_binding : mainbinding.checked, modules : Cola.getPackages(), is_node : isnode.checked });
ast.print(stream); ast.print(stream);
translationArea.value = stream.toString(); translationArea.value = stream.toString();

View File

@ -49,7 +49,7 @@
!this.Cola && (this.Cola = {}); !this.Cola && (this.Cola = {});
Cola.KEYWORDS = 'break case catch const continue debugger default delete do else finally for function if in instanceof new return switch throw try typeof var void while with'; Cola.KEYWORDS = 'break case catch const continue debugger default delete do else finally for function if in instanceof new return switch throw try typeof var void while with';
Cola.cKEYWORDS = Cola.KEYWORDS.replace(' void', '') + ' static covert get set when clone is isnt class extends singleton injector'; Cola.cKEYWORDS = Cola.KEYWORDS.replace(' void', '') + ' static covert export get set when clone is isnt class extends singleton';
Cola.KEYWORDS_ATOM = 'false null true'; Cola.KEYWORDS_ATOM = 'false null true';
Cola.cKEYWORDS_ATOM = Cola.KEYWORDS_ATOM + ' on yes off no'; Cola.cKEYWORDS_ATOM = Cola.KEYWORDS_ATOM + ' on yes off no';
@ -770,7 +770,7 @@ Cola.cUNARY_PREFIX = Cola.makePredicate([
"+" "+"
]); ]);
Cola.cVARS_MODIFICATORS = Cola.makePredicate([ "const", "covert", "static" ]); Cola.cVARS_MODIFICATORS = Cola.makePredicate([ "const", "covert", "static", "export" ]);
Cola.UNARY_POSTFIX = Cola.makePredicate([ "--", "++" ]); Cola.UNARY_POSTFIX = Cola.makePredicate([ "--", "++" ]);
Cola.cUNARY_POSTFIX = Cola.makePredicate([ "--", "++", "?" ]); Cola.cUNARY_POSTFIX = Cola.makePredicate([ "--", "++", "?" ]);
@ -859,6 +859,8 @@ Cola.Parser = function ($TEXT, options) {
this.dumps = []; this.dumps = [];
this.dumpi = -1; this.dumpi = -1;
this.requiredModules = [];
if(this.is_js){ if(this.is_js){
this.UNARY_PREFIX = Cola.UNARY_PREFIX; this.UNARY_PREFIX = Cola.UNARY_PREFIX;
this.PRECEDENCE = Cola.PRECEDENCE; this.PRECEDENCE = Cola.PRECEDENCE;
@ -892,6 +894,7 @@ Cola.Parser.prototype.parse = function () {
toplevel = new Cola.AST_Toplevel({ start: start, body: body, end: end }); toplevel = new Cola.AST_Toplevel({ start: start, body: body, end: end });
} }
toplevel.language = _this.is_js ? 'js' : 'cola'; toplevel.language = _this.is_js ? 'js' : 'cola';
toplevel.requiredModules = _this.requiredModules;
return toplevel; return toplevel;
})(); })();
}; };
@ -1037,6 +1040,16 @@ Cola.Parser.prototype.statement = Cola.Parser.embed_tokens(function() {
this.next(); this.next();
} }
if(!this.is_js && this.is("keyword", "class")){
this.next();
return this.class_(mods);
}
if(!this.is_js && this.is("keyword", "singleton")){
this.next();
return this.singleton_(mods);
}
if(!this.is_js && this.is("keyword", "function")){ if(!this.is_js && this.is("keyword", "function")){
this.next(); this.next();
return this.function_(Cola.AST_Defun, false, mods); return this.function_(Cola.AST_Defun, false, mods);
@ -1108,6 +1121,8 @@ Cola.Parser.prototype.statement = Cola.Parser.embed_tokens(function() {
if(!this.is_js && mods.length != 0 && this.is("name")) if(!this.is_js && mods.length != 0 && this.is("name"))
return tmp = this.var_(false, false, mods), this.semicolon(), tmp; return tmp = this.var_(false, false, mods), this.semicolon(), tmp;
if(!this.is_js && mods.length) this.unexpected();
if(this.is("name")) return this.next_is("punc", ":") if(this.is("name")) return this.next_is("punc", ":")
? this.labeled_statement() ? this.labeled_statement()
: this.simple_statement(); : this.simple_statement();
@ -1115,7 +1130,7 @@ Cola.Parser.prototype.statement = Cola.Parser.embed_tokens(function() {
case "punc": case "punc":
switch (this.S.token.value) { switch (this.S.token.value) {
case "@": case "@":
if (!this.is_js && this.next_is("name")) if (!this.is_js && (this.next_is("name") || this.next_is("keyword")))
return new Cola.AST_Command({ return new Cola.AST_Command({
name : this.next().value, name : this.next().value,
args : (function(name){ args : (function(name){
@ -1129,6 +1144,106 @@ Cola.Parser.prototype.statement = Cola.Parser.embed_tokens(function() {
} }
this.next(); this.next();
} else } else
if (name == 'import') {
var lib = false, component = false, as = false;
this.next();
if (this.is("string")) {
lib = this.S.token.value;
if (this.next_is("name", "as")) {
this.next(); this.next();
if (!this.is("name")) this.unexpected();
as = this.S.token.value;
}
args.push([lib, component, as]);
} else
if (this.is("name")) {
while (!this.S.token.nlb && !this.is("eof")) {
component = this.S.token.value;
this.next();
if (this.is("name", "as")) {
this.next();
if (!this.is("name")) this.unexpected();
as = this.S.token.value;
this.next();
} else as = component;
args.push([lib, component, as]);
if (this.is("punc", ",")) this.next();
else break;
}
if (!this.is("name", "from")) this.unexpected();
this.next();
if (!this.is("string")) this.unexpected();
lib = this.S.token.value;
args.forEach(function(args) {
args[0] = lib;
});
} else this.unexpected();
if (!this.peek().nlb && !this.next_is("eof")) this.unexpected();
this.next();
Cola.push_uniq(this.requiredModules, lib);
} else
if (name == 'export') {
var lib = false, component = false, as = false;
this.next();
if (this.is("string")) {
lib = this.S.token.value;
args.push([lib, component, as]);
} else
if (this.is("name")) {
while (!this.S.token.nlb && !this.is("eof")) {
component = this.S.token.value;
if (!this.peek().nlb) this.next();
if (this.is("name", "as")) {
this.next();
if (!this.is("name")) this.unexpected();
as = this.S.token.value;
this.next();
} else as = component;
args.push([lib, component, as]);
if (this.is("punc", ",")) this.next();
else break;
}
if (this.is("name", "from")) {
this.next();
if (!this.is("string")) this.unexpected();
lib = this.S.token.value;
args.forEach(function(args) {
args[0] = lib;
});
}
} else this.unexpected();
if (!this.peek().nlb && !this.next_is("eof")) this.unexpected();
this.next();
if (lib) Cola.push_uniq(this.requiredModules, lib);
} else
if (name == 'use') { if (name == 'use') {
this.next(); this.next();
@ -1203,9 +1318,6 @@ Cola.Parser.prototype.statement = Cola.Parser.embed_tokens(function() {
case "singleton": case "singleton":
return this.singleton_(); return this.singleton_();
case "injector":
return this.injector_();
case "function": case "function":
return this.function_(Cola.AST_Defun); return this.function_(Cola.AST_Defun);
@ -1440,9 +1552,12 @@ Cola.Parser.prototype.for_in = function (init) {
}); });
}; };
Cola.Parser.prototype.class_ = function(){ Cola.Parser.prototype.class_ = function(mods){
if(this.S.in_class) if(this.S.in_class)
this.token_error(this.prev(), "You can define class, singleton or injector only in root scope."); this.token_error(this.prev(), "You can define class or singleton only in root scope.");
if (mods && (mods.length > 1 || mods[0] && mods[0] != "export"))
this.token_error(this.prev(), "Class and singleton can have only `export` modificator.");
this.S.in_class = true; this.S.in_class = true;
@ -1461,6 +1576,7 @@ Cola.Parser.prototype.class_ = function(){
return new Cola.AST_Class({ return new Cola.AST_Class({
name: name, name: name,
extends: extends_, extends: extends_,
mods: mods || [],
body: (function(loop, labels){ body: (function(loop, labels){
++_this.S.in_function; ++_this.S.in_function;
_this.S.in_directives = true; _this.S.in_directives = true;
@ -1510,9 +1626,12 @@ Cola.Parser.prototype.class_ = function(){
}); });
}; };
Cola.Parser.prototype.singleton_ = function(){ Cola.Parser.prototype.singleton_ = function(mods){
if(this.S.in_class) if(this.S.in_class)
this.token_error(this.prev(), "You can define class, singleton or injector only in root scope."); this.token_error(this.prev(), "You can define class or singleton only in root scope.");
if (mods && (mods.length > 1 || mods[0] && mods[0] != "export"))
this.token_error(this.prev(), "Class and singleton can have only `export` modificator.");
this.S.in_class = true; this.S.in_class = true;
@ -1523,6 +1642,7 @@ Cola.Parser.prototype.singleton_ = function(){
return new Cola.AST_Singleton({ return new Cola.AST_Singleton({
name: name, name: name,
mods: mods || [],
body: (function(loop, labels){ body: (function(loop, labels){
++_this.S.in_function; ++_this.S.in_function;
_this.S.in_directives = true; _this.S.in_directives = true;
@ -1545,7 +1665,7 @@ Cola.Parser.prototype.singleton_ = function(){
_this.token_error(member.start, "Constructor can't have modificators."); _this.token_error(member.start, "Constructor can't have modificators.");
if(member.argnames.length) if(member.argnames.length)
_this.token_error(member.start, "Singleton's and injector's constructor can't have arguments."); _this.token_error(member.start, "Singleton's constructor can't have arguments.");
if(mconstr) if(mconstr)
_this.token_error(member.start, "Main constructor can be defined only one time"); _this.token_error(member.start, "Main constructor can be defined only one time");
@ -1563,59 +1683,6 @@ Cola.Parser.prototype.singleton_ = function(){
}); });
}; };
Cola.Parser.prototype.injector_ = function(){
if(this.S.in_class)
this.token_error(this.prev(), "You can define class, singleton or injector only in root scope.");
this.S.in_class = true;
var _this = this,
name = this.is("name") ? this.as_symbol(Cola.AST_SymbolInjector) : this.unexpected();
this.S.class_name = name.name;
return new Cola.AST_Injector({
name: name,
body: (function(loop, labels){
++_this.S.in_function;
_this.S.in_directives = true;
_this.S.in_loop = 0;
_this.S.labels = [];
var tmp, a = _this.block_();
--_this.S.in_function;
_this.S.in_loop = loop;
_this.S.labels = labels;
var mconstr = false;
a.forEach(function(member){
if(member instanceof Cola.AST_Defun && member.name instanceof Cola.AST_SymbolDefun && member.name.name == _this.S.class_name){
if(member.type != "dynamic")
_this.token_error(member.start, "Constructor can't have returned type.");
if(member.mods.length != 0)
_this.token_error(member.start, "Constructor can't have modificators.");
if(mconstr)
_this.token_error(member.start, "Main constructor can be defined only one time");
if(member.argnames.length)
_this.token_error(member.start, "Singleton's and injector's constructor can't have arguments.");
mconstr = true;
} else if(member instanceof Cola.AST_Defun && member.name instanceof Cola.AST_Dot && member.mods.indexOf("static") != -1){
_this.token_error(member.start, "Unexpected `static` modificator.");
}
});
_this.S.in_class = false;
_this.S.class_name = false;
return a;
})(this.S.in_loop, this.S.labels)
});
};
Cola.Parser.prototype.as_funcarg = function(splatedexist) { Cola.Parser.prototype.as_funcarg = function(splatedexist) {
var name = this.as_symbol(Cola.AST_SymbolFunarg), type = name, argtype = 'positional', defval = new Cola.AST_Noop, required = true; var name = this.as_symbol(Cola.AST_SymbolFunarg), type = name, argtype = 'positional', defval = new Cola.AST_Noop, required = true;
@ -1666,15 +1733,16 @@ Cola.Parser.prototype.function_ = function(ctor, type, mods) {
if(!this.S.in_class){ if(!this.S.in_class){
if(name instanceof Cola.AST_Symbol){ if(name instanceof Cola.AST_Symbol){
if(mods.length != 0) if(mods.length > 1 || mods[0] && mods[0] != "export")
this.token_error(name.start, "Function definition outside of class can't contain any modifer"); this.token_error(name.start, "Function definition outside of class can contain only `export` modifer");
} }
else { else {
if(mods.length != 0 && mods.indexOf("static") != -1) if(mods.length != 0 && (mods.indexOf("static") != -1 || mods.indexOf("export") != -1))
this.token_error(name.start, "Prop definition can't contain `static` modifer"); this.token_error(name.start, "Prop definition can't contain `static` and `export` modifers");
} }
} } else if (mods.indexOf("export") != -1)
this.token_error(name.start, "Invalid `export` modifer");
if (in_statement && !name) if (in_statement && !name)
this.unexpected(); this.unexpected();
@ -1851,6 +1919,9 @@ Cola.Parser.prototype.vardefs = function (no_in, in_const, type, mods) {
if (mods && mods.indexOf("static") != -1 && (!(last.name instanceof Cola.AST_Symbol) || !this.S.in_class)) if (mods && mods.indexOf("static") != -1 && (!(last.name instanceof Cola.AST_Symbol) || !this.S.in_class))
this.token_error(last.start, "Unexpected `static` modificator."); this.token_error(last.start, "Unexpected `static` modificator.");
if (mods && mods.indexOf("export") != -1 && (!(last.name instanceof Cola.AST_Symbol) || this.S.in_class))
this.token_error(last.start, "Unexpected `export` modificator.");
if (!this.is("punc", ",")) if (!this.is("punc", ","))
break; break;
this.next(); this.next();
@ -2434,10 +2505,16 @@ Cola.Parser.prototype.subscripts = function(expr, allow_calls) {
} }
if (allow_calls && this.is("punc", "(")) { if (allow_calls && this.is("punc", "(")) {
this.next(); this.next();
var _this = this;
return this.subscripts(new Cola.AST_Call({ return this.subscripts(new Cola.AST_Call({
start : start, start : start,
expression : expr, expression : expr,
args : this.expr_list(")", false, false, !this.is_js), args : (function(args){
if (expr instanceof Cola.AST_Symbol && expr.name == "require" && args[0] instanceof Cola.AST_String)
Cola.push_uniq(_this.requiredModules, args[0].value);
return args;
})(this.expr_list(")", false, false, !this.is_js)),
end : this.prev() end : this.prev()
}), true); }), true);
} }

View File

@ -141,6 +141,7 @@ Cola._ColaRuntime$$updateProperty = function _ColaRuntime$$updateProperty(_objec
var _dprops = Object.getOwnPropertyDescriptor(_object, _propname) || {}; var _dprops = Object.getOwnPropertyDescriptor(_object, _propname) || {};
for(var key in _props) for(var key in _props)
if(_props.hasOwnProperty(key)) _dprops[key] = _props[key]; if(_props.hasOwnProperty(key)) _dprops[key] = _props[key];
_dprops.configurable = true;
return Object.defineProperty(_object, _propname, _dprops); return Object.defineProperty(_object, _propname, _dprops);
}; };
Cola._ColaRuntime$$updateProperty.i = 14; Cola._ColaRuntime$$updateProperty.i = 14;
@ -152,14 +153,58 @@ Cola._ColaRuntime$$proto = function _ColaRuntime$$proto(_proto) {
}; };
Cola._ColaRuntime$$proto.i = 15; Cola._ColaRuntime$$proto.i = 15;
Cola._ColaRuntime$$arguments_def = { i : 16 }; Cola._ColaRuntime$$rootImport = function _ColaRuntime$$rootImport(module) {
var g = typeof window == "undefined" ? global : window;
Cola.$_cola = for (var i in module)
if (module.hasOwnProperty(i)) g[i] = module[i];
};
Cola._ColaRuntime$$rootImport.i = 16;
Cola._ColaRuntime$$commonWrapper = function(modules, cache, ids) {
function require(name) {
if (cache[name]) return cache[name].exports;
if (modules[name]) return call(name);
throw new Error('Cannot find module "' + name + '"');
}
require.cola = true;
require.cache = cache;
require.modules = modules;
function call(id) {
var module = cache[id] = {
exports: {}
};
modules[id].call(module.exports, function(moduleName) {
var dependencies = ids[moduleName];
return require(dependencies ? dependencies : moduleName);
}, module, module.exports);
return module.exports;
}
require(0);
};
Cola._ColaRuntime$$commonWrapper.i = 17;
Cola._ColaRuntime$$rootExport = function _ColaRuntime$$rootExport(exports, module) {
for (var i in module)
if (module.hasOwnProperty(i)) exports[i] = module[i];
};
Cola._ColaRuntime$$rootExport.i = 18;
Cola._ColaRuntime$$arguments_def = { i : 19 };
Cola._ColaRuntime =
Cola._ColaRuntime$$is + Cola._ColaRuntime$$isnt + Cola._ColaRuntime$$modulo + Cola._ColaRuntime$$isset + Cola._ColaRuntime$$is + Cola._ColaRuntime$$isnt + Cola._ColaRuntime$$modulo + Cola._ColaRuntime$$isset +
Cola._ColaRuntime$$isntset + Cola._ColaRuntime$$clone + Cola._ColaRuntime$$array_last + Cola._ColaRuntime$$array_range + Cola._ColaRuntime$$isntset + Cola._ColaRuntime$$clone + Cola._ColaRuntime$$array_last + Cola._ColaRuntime$$array_range +
Cola._ColaRuntime$$array_asplice + Cola._ColaRuntime$$func_named_args + Cola._ColaRuntime$$func_set_named_args + Cola._ColaRuntime$$error + Cola._ColaRuntime$$array_asplice + Cola._ColaRuntime$$func_named_args + Cola._ColaRuntime$$func_set_named_args + Cola._ColaRuntime$$error +
Cola._ColaRuntime$$array_negate_access + Cola._ColaRuntime$$array_modulo_access + Cola._ColaRuntime$$updateProperty + Cola._ColaRuntime$$array_negate_access + Cola._ColaRuntime$$array_modulo_access + Cola._ColaRuntime$$updateProperty +
Cola._ColaRuntime$$proto + Cola._ColaRuntime$$proto + Cola._ColaRuntime$$rootImport + "(" + Cola._ColaRuntime$$commonWrapper + ")([],{},{});" + Cola._ColaRuntime$$rootExport +
"var arguments;"; "var arguments;";
Cola.Compressor.StdFuncs = { Cola.Compressor.StdFuncs = {

View File

@ -187,7 +187,7 @@ Cola.Constructions.IsntSet = function(node, ext){
}; };
/* /*
{{length}} <= {{name}}.length ? [].slice.call({{name}}, {{pos}}, $_cola{{uid}}i = {{name}}.length - {{after}}) : ($_cola{{uid}}i = {{pos}}, []) {{length}} <= {{name}}.length ? [].slice.call({{name}}, {{pos}}, _ColaRuntime$${{uid}}i = {{name}}.length - {{after}}) : (_ColaRuntime$${{uid}}i = {{pos}}, [])
*/ */
Cola.Constructions.SplatedConditional = function(name, uid, pos, after, length){ Cola.Constructions.SplatedConditional = function(name, uid, pos, after, length){
@ -214,7 +214,7 @@ Cola.Constructions.SplatedConditional = function(name, uid, pos, after, length){
new Cola.AST_Number({ value : pos }), // pos new Cola.AST_Number({ value : pos }), // pos
new Cola.AST_Assign({ new Cola.AST_Assign({
operator : '=', operator : '=',
left : new Cola.AST_SymbolRef({ name : "$_cola" + uid + "i" }), left : new Cola.AST_SymbolRef({ name : "_ColaRuntime$$" + uid + "i" }),
right : new Cola.AST_Binary({ right : new Cola.AST_Binary({
operator : '-', operator : '-',
left : new Cola.AST_Dot({ left : new Cola.AST_Dot({
@ -229,7 +229,7 @@ Cola.Constructions.SplatedConditional = function(name, uid, pos, after, length){
alternative : new Cola.AST_Seq({ alternative : new Cola.AST_Seq({
car : new Cola.AST_Assign({ car : new Cola.AST_Assign({
operator : '=', operator : '=',
left : new Cola.AST_SymbolRef({ name : "$_cola" + uid + "i" }), left : new Cola.AST_SymbolRef({ name : "_ColaRuntime$$" + uid + "i" }),
right : new Cola.AST_Number({ value : pos }) // pos right : new Cola.AST_Number({ value : pos }) // pos
}), }),
cdr : new Cola.AST_Array({ elements : [] }) cdr : new Cola.AST_Array({ elements : [] })
@ -242,7 +242,7 @@ Cola.Constructions.SplatedConditional = function(name, uid, pos, after, length){
or or
{{name}}[$_cola{{uid}}i + {{after}}] {{name}}[_ColaRuntime$${{uid}}i + {{after}}]
*/ */
Cola.Constructions.ValueWithOffset = function(name, uid, cond, pos, after){ Cola.Constructions.ValueWithOffset = function(name, uid, cond, pos, after){
@ -253,7 +253,7 @@ Cola.Constructions.ValueWithOffset = function(name, uid, cond, pos, after){
? new Cola.AST_Number({ value : pos }) ? new Cola.AST_Number({ value : pos })
: new Cola.AST_Binary({ : new Cola.AST_Binary({
operator : "+", operator : "+",
left : new Cola.AST_SymbolRef({ name : "$_cola" + uid + "i" }), left : new Cola.AST_SymbolRef({ name : "_ColaRuntime$$" + uid + "i" }),
right : new Cola.AST_Number({ value : after }) right : new Cola.AST_Number({ value : after })
}) })
}); });
@ -536,6 +536,24 @@ Cola.DefFunWithMods = function(func, mods){
}); });
}; };
Cola.PushModuleToCommonWrapper = function(module, commonWrapper, name, id) {
commonWrapper.body.args[0].elements.push(new Cola.AST_Function({
body : module.body,
argnames : [
new Cola.AST_SymbolFunarg({ name : "require" }),
new Cola.AST_SymbolFunarg({ name : "module" }),
new Cola.AST_SymbolFunarg({ name : "exports" })
]
}));
if (!name || !id) return;
commonWrapper.body.args[2].properties.push(new Cola.AST_ObjectKeyVal({
key : name,
value : new Cola.AST_Number({ value : id })
}));
};
Cola.AST_Toplevel.prototype.toJavaScript = function(options){ Cola.AST_Toplevel.prototype.toJavaScript = function(options){
if(this.language == 'js') return this; if(this.language == 'js') return this;
@ -545,16 +563,19 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){
main_binding : true, main_binding : true,
main_event : 'DOMContentLoaded', main_event : 'DOMContentLoaded',
parser : {}, parser : {},
std : true, is_node : false,
path : "" std_hash : {},
path : "",
modules : {},
root : true
}); });
var _ColaRuntime$$ast = Cola.parse(Cola.$_cola, { is_js : true }), var _ColaRuntime$$ast = Cola.parse(Cola._ColaRuntime, { is_js : true }),
_ColaRuntime$$hash = {}, _ColaRuntime$$hash = options.std_hash,
_this, _this = this,
required = [], required_hash = {}, required = [], required_hash = {}, exports = [],
tt = new Cola.TreeTransformer(function(node, descend, in_list){ tt = new Cola.TreeTransformer(function(node, descend, in_list){
var newNode, props = {}, parent = this.parent(); var newNode, props = {}, parent = this.parent();
@ -572,17 +593,26 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){
console.log("hello world"); console.log("hello world");
}, false); }, false);
or node
(function main(){
console.log("hello world");
})();
*/ */
if(options.main_binding && parent instanceof Cola.AST_Toplevel && node instanceof Cola.AST_Defun && node.name instanceof Cola.AST_SymbolDefun && node.name.name == "main"){ if(options.main_binding && parent instanceof Cola.AST_Toplevel && node instanceof Cola.AST_Defun && node.name instanceof Cola.AST_SymbolDefun && node.name.name == "main"){
node.name = new Cola.AST_SymbolLambda(node.name); node.name = new Cola.AST_SymbolLambda(node.name);
node = new Cola.AST_Function(node); node = new Cola.AST_Function(node);
props = { props = !options.is_node ? {
args : [new Cola.AST_String({ value : options.main_event }), node, new Cola.AST_False()], args : [new Cola.AST_String({ value : options.main_event }), node, new Cola.AST_False()],
expression : new Cola.AST_Dot({ expression : new Cola.AST_Dot({
property : 'addEventListener', property : 'addEventListener',
expression : new Cola.AST_SymbolRef({ name : 'window' }) expression : new Cola.AST_SymbolRef({ name : 'window' })
}) })
} : {
args : [],
expression : node
}; };
node = new Cola.AST_SimpleStatement({ node = new Cola.AST_SimpleStatement({
@ -1107,7 +1137,7 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){
to to
const num - 1; const num = 1;
Object.defineProperty(obj, "num", { value: 0, enumerable: true }); Object.defineProperty(obj, "num", { value: 0, enumerable: true });
*/ */
@ -1117,10 +1147,13 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){
if(def.name instanceof Cola.AST_SymbolVar){ if(def.name instanceof Cola.AST_SymbolVar){
defCache.push(def); defCache.push(def);
} else if(def.value || node.mods.indexOf("covert") != -1){ } else if(def.value || node.mods.indexOf("covert") != -1){
if(defCache.length != 0 && (!node.mods || node.mods.length == 0 || node.mods.indexOf("const") != -1 && node.mods.length == 1)){ if(defCache.length != 0){
newNode.push(node.mods.length == 1 ? new Cola.AST_Const(node) : node.clone()); newNode.push(node.mods.length == 1 ? new Cola.AST_Const(node) : node.clone());
newNode[newNode.length - 1].definitions = defCache.map(function(def){ newNode[newNode.length - 1].definitions = defCache.map(function(def){
def.name = new Cola.AST_SymbolConst(def.name); if (node.mods && node.mods.indexOf("const") != -1)
def.name = new Cola.AST_SymbolConst(def.name);
if (node.mods && node.mods.indexOf("export") != -1)
exports.push(def.name.name);
return def; return def;
}); });
defCache = []; defCache = [];
@ -1130,18 +1163,23 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){
while(!(texpr.expression instanceof Cola.AST_Symbol || texpr.expression instanceof Cola.AST_Constant)) texpr = texpr.expression; while(!(texpr.expression instanceof Cola.AST_Symbol || texpr.expression instanceof Cola.AST_Constant)) texpr = texpr.expression;
if(texpr.expression instanceof Cola.AST_Symbol && !(texpr.expression instanceof Cola.AST_This)) texpr.expression = new Cola.AST_SymbolRef(texpr.expression); if(texpr.expression instanceof Cola.AST_Symbol && !(texpr.expression instanceof Cola.AST_This)) texpr.expression = new Cola.AST_SymbolRef(texpr.expression);
newNode.push(Cola.DefPropWithMods(def, node.mods)); newNode[newNode.length - 1] = new Cola.AST_SimpleStatement({ newNode.push(Cola.DefPropWithMods(def, node.mods));
newNode[newNode.length - 1] = new Cola.AST_SimpleStatement({
body : newNode[newNode.length - 1] body : newNode[newNode.length - 1]
}); });
} }
}); });
if(defCache.length != 0 && (!node.mods || node.mods.length == 0 || node.mods.indexOf("const") != -1 && node.mods.length == 1)){ if(defCache.length != 0){
newNode.push(node.mods && node.mods.length == 1 ? new Cola.AST_Const(node) : node.clone()); newNode.push(node.mods && node.mods.indexOf("const") != -1 ? new Cola.AST_Const(node) : node.clone());
newNode[newNode.length - 1].definitions = defCache.map(function(def){ newNode[newNode.length - 1].definitions = defCache.map(function(def){
def.name = new Cola.AST_SymbolConst(def.name); if (node.mods && node.mods.indexOf("const") != -1)
def.name = new Cola.AST_SymbolConst(def.name);
if (node.mods && node.mods.indexOf("export") != -1)
exports.push(def.name.name);
return def; return def;
}); });
defCache = []; defCache = [];
} }
@ -1297,6 +1335,9 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){
newNode = []; newNode = [];
node.name = new Cola.AST_SymbolRef(node.name); node.name = new Cola.AST_SymbolRef(node.name);
if (node.mods.length)
exports.push(node.name.name);
pre_constructor = new Cola.AST_Defun({ pre_constructor = new Cola.AST_Defun({
mods : ["covert"], mods : ["covert"],
type : "dynamic", type : "dynamic",
@ -1652,33 +1693,37 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){
to to
Test(){ Test Test = ((){
this.pre_constructor(); Test(){
this.pre_constructor();
alert("test") alert("test")
this.post_constructor(); this.post_constructor();
} }
Test::pre_constructor(){ Test::pre_constructor(){
const int this.i = 123; const int this.i = 123;
} }
Test::post_constructor(){ Test::post_constructor(){
queryAll("ul li a").forEach((el) => queryAll("ul li a").forEach((el) =>
el.onclick = () => console.log("click") el.onclick = () => console.log("click")
); );
} }
covert String Test::method1() => console.log("method"); covert String Test::method1() => console.log("method");
get Test::getter() => i; get Test::getter() => i;
set Test::setter(int val) => console.log(val); set Test::setter(int val) => console.log(val);
Test::selfExample(){ Test::selfExample(){
var self = this; var self = this;
query("*").onclick = () => console.log(self); query("*").onclick = () => console.log(self);
} }
return new Test();
}))();
*/ */
if(node instanceof Cola.AST_Singleton){ if(node instanceof Cola.AST_Singleton){
@ -1688,6 +1733,9 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){
newNode = []; newNode = [];
node.name = new Cola.AST_SymbolRef(node.name); node.name = new Cola.AST_SymbolRef(node.name);
if (node.mods.length)
exports.push(node.name.name);
pre_constructor = new Cola.AST_Defun({ pre_constructor = new Cola.AST_Defun({
mods : ["covert"], mods : ["covert"],
type : "dynamic", type : "dynamic",
@ -2208,7 +2256,7 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){
skiped = true; skiped = true;
defs.push(new Cola.AST_VarDef({ defs.push(new Cola.AST_VarDef({
type : "int", type : "int",
name : new Cola.AST_SymbolVar({ name : "$_cola" + uid + "i" }), name : new Cola.AST_SymbolVar({ name : "_ColaRuntime$$" + uid + "i" }),
value : null value : null
})); }));
el.splated = undefined; el.splated = undefined;
@ -2236,7 +2284,7 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){
new Cola.AST_Number({ value : j }), new Cola.AST_Number({ value : j }),
new Cola.AST_Assign({ new Cola.AST_Assign({
operator : '=', operator : '=',
left : new Cola.AST_SymbolVar({ name : "$_cola" + uid + "i" }), left : new Cola.AST_SymbolVar({ name : "_ColaRuntime$$" + uid + "i" }),
right : new Cola.AST_Binary({ right : new Cola.AST_Binary({
operator : '-', operator : '-',
left : new Cola.AST_Dot({ left : new Cola.AST_Dot({
@ -2251,7 +2299,7 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){
alternative : new Cola.AST_Seq({ alternative : new Cola.AST_Seq({
car : new Cola.AST_Assign({ car : new Cola.AST_Assign({
operator : '=', operator : '=',
left : new Cola.AST_SymbolRef({ name : "$_cola" + uid + "i" }), left : new Cola.AST_SymbolRef({ name : "_ColaRuntime$$" + uid + "i" }),
right : new Cola.AST_Number({ value : j }) right : new Cola.AST_Number({ value : j })
}), }),
cdr : new Cola.AST_Array({ elements : [] }) cdr : new Cola.AST_Array({ elements : [] })
@ -2270,7 +2318,7 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){
? new Cola.AST_Number({ value : j }) ? new Cola.AST_Number({ value : j })
: new Cola.AST_Binary({ : new Cola.AST_Binary({
operator : "+", operator : "+",
left : new Cola.AST_SymbolRef({ name : "$_cola" + uid + "i" }), left : new Cola.AST_SymbolRef({ name : "_ColaRuntime$$" + uid + "i" }),
right : new Cola.AST_Number({ value : k++ }) right : new Cola.AST_Number({ value : k++ })
}) })
}) })
@ -2279,7 +2327,7 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){
skiped = true; skiped = true;
defs.push(new Cola.AST_VarDef({ defs.push(new Cola.AST_VarDef({
type : "int", type : "int",
name : new Cola.AST_SymbolVar({ name : "$_cola" + uid + "i" }), name : new Cola.AST_SymbolVar({ name : "_ColaRuntime$$" + uid + "i" }),
value : new Cola.AST_Binary({ value : new Cola.AST_Binary({
operator : '-', operator : '-',
left : new Cola.AST_Dot({ left : new Cola.AST_Dot({
@ -2299,7 +2347,7 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){
? new Cola.AST_Number({ value : j }) ? new Cola.AST_Number({ value : j })
: new Cola.AST_Binary({ : new Cola.AST_Binary({
operator : "+", operator : "+",
left : new Cola.AST_SymbolRef({ name : "$_cola" + uid + "i" }), left : new Cola.AST_SymbolRef({ name : "_ColaRuntime$$" + uid + "i" }),
right : new Cola.AST_Number({ value : k++ }) right : new Cola.AST_Number({ value : k++ })
}) })
}), uid + "_"); }), uid + "_");
@ -2368,7 +2416,7 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){
skiped = true; skiped = true;
defs.push(new Cola.AST_VarDef({ defs.push(new Cola.AST_VarDef({
type : "int", type : "int",
name : new Cola.AST_SymbolVar({ name : "$_cola" + uid + "i" }), name : new Cola.AST_SymbolVar({ name : "_ColaRuntime$$" + uid + "i" }),
value : null value : null
})); }));
el.name.splated = undefined; el.name.splated = undefined;
@ -2379,7 +2427,7 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){
skiped = true; skiped = true;
defs.push(new Cola.AST_VarDef({ defs.push(new Cola.AST_VarDef({
type : "int", type : "int",
name : new Cola.AST_SymbolVar({ name : "$_cola" + uid + "i" }), name : new Cola.AST_SymbolVar({ name : "_ColaRuntime$$" + uid + "i" }),
value : null value : null
})); }));
el.splated = undefined; el.splated = undefined;
@ -2402,7 +2450,7 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){
skiped = true; skiped = true;
defs.push(new Cola.AST_VarDef({ defs.push(new Cola.AST_VarDef({
type : "int", type : "int",
name : new Cola.AST_SymbolVar({ name : "$_cola" + uid + "i" }), name : new Cola.AST_SymbolVar({ name : "_ColaRuntime$$" + uid + "i" }),
value : new Cola.AST_Binary({ value : new Cola.AST_Binary({
operator : '-', operator : '-',
left : new Cola.AST_Dot({ left : new Cola.AST_Dot({
@ -2503,7 +2551,7 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){
skiped = true; skiped = true;
defs.push(new Cola.AST_VarDef({ defs.push(new Cola.AST_VarDef({
type : "int", type : "int",
name : new Cola.AST_SymbolVar({ name : "$_cola" + uid + "i" }), name : new Cola.AST_SymbolVar({ name : "_ColaRuntime$$" + uid + "i" }),
value : null value : null
})); }));
el.splated = undefined; el.splated = undefined;
@ -2522,7 +2570,7 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){
skiped = true; skiped = true;
defs.push(new Cola.AST_VarDef({ defs.push(new Cola.AST_VarDef({
type : "int", type : "int",
name : new Cola.AST_SymbolVar({ name : "$_cola" + uid + "i" }), name : new Cola.AST_SymbolVar({ name : "_ColaRuntime$$" + uid + "i" }),
value : new Cola.AST_Binary({ value : new Cola.AST_Binary({
operator : '-', operator : '-',
left : new Cola.AST_Dot({ left : new Cola.AST_Dot({
@ -2870,9 +2918,15 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){
if (!options.parser.is_js) tl = tl.toJavaScript({ if (!options.parser.is_js) tl = tl.toJavaScript({
main_binding : options.main_binding, main_binding : options.main_binding,
main_event : options.main_event, main_event : options.main_event,
is_node : options.is_node,
parser : options.parser, parser : options.parser,
path : Cola.dirname(options.parser.filename), path : Cola.dirname(options.parser.filename),
std : false std_hash : options.std_hash,
root : false
});
tl.requiredModules.forEach(function(moduleName){
Cola.push_uniq(_this.requiredModules, moduleName);
}); });
included = included.concat(tl.body); included = included.concat(tl.body);
@ -2894,9 +2948,15 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){
if (!options.parser.is_js) tl = tl.toJavaScript({ if (!options.parser.is_js) tl = tl.toJavaScript({
main_binding : options.main_binding, main_binding : options.main_binding,
main_event : options.main_event, main_event : options.main_event,
is_node : options.is_node,
parser : options.parser, parser : options.parser,
path : Cola.dirname(options.parser.filename), path : Cola.dirname(options.parser.filename),
std : false std_hash : options.std_hash,
root : false
});
tl.requiredModules.forEach(function(moduleName){
Cola.push_uniq(_this.requiredModules, moduleName);
}); });
required = required.concat(tl.body); required = required.concat(tl.body);
@ -2905,6 +2965,146 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){
return false; return false;
} else } else
if(node instanceof Cola.AST_Command && node.name == "import"){
if (node.args.length == 1) {
newNode = new Cola.AST_SimpleStatement({
start : node.start,
end : node.end,
body : new Cola.AST_Call({
args : [new Cola.AST_String({ value: node.args[0][0] })],
expression : new Cola.AST_SymbolRef({ name : 'require' })
})
});
if (node.args[0][2])
newNode = new Cola.AST_Const({
start : node.start,
end : node.end,
type : "dynamic",
definitions : [new Cola.AST_VarDef({
type : "dynamic",
name : new Cola.AST_SymbolVar({ name: node.args[0][2] }),
value : newNode.body
})]
}); else {
_ColaRuntime$$hash[Cola._ColaRuntime$$rootImport.i] = true;
newNode.body = new Cola.AST_Call({
args : [newNode.body],
expression : new Cola.AST_SymbolRef({ name : '_ColaRuntime$$rootImport' })
});
}
if (node.args[0][1])
newNode.definitions[0].value = new Cola.AST_Dot({
expression : newNode.definitions[0].value,
property : node.args[0][1]
});
} else {
newNode = [new Cola.AST_Var({
start : node.start,
end : node.end,
type : "dynamic",
definitions : [new Cola.AST_VarDef({
type : "dynamic",
name : new Cola.AST_SymbolVar({ name: '_ColaRuntime$$tmp' }),
value : new Cola.AST_Call({
args : [new Cola.AST_String({ value: node.args[0][0] })],
expression : new Cola.AST_SymbolRef({ name : 'require' })
})
})]
})];
newNode.push(new Cola.AST_Const({
start : node.start,
end : node.end,
type : "dynamic",
definitions : []
}));
node.args.forEach(function(args) {
newNode[1].definitions.push(new Cola.AST_VarDef({
type : "dynamic",
name : new Cola.AST_SymbolVar({ name: args[2] }),
value : new Cola.AST_Dot({
expression : new Cola.AST_SymbolRef({ name: '_ColaRuntime$$tmp' }),
property : args[1]
})
}));
});
}
node = newNode;
} else
if(node instanceof Cola.AST_Command && node.name == "export"){
if (node.args.length == 1 && !node.args[0][1]) {
_ColaRuntime$$hash[Cola._ColaRuntime$$rootExport.i] = true;
newNode = new Cola.AST_SimpleStatement({
start : node.start,
end : node.end,
body : new Cola.AST_Call({
args : [new Cola.AST_String({ value: node.args[0][0] })],
expression : new Cola.AST_SymbolRef({ name : 'require' })
})
});
newNode.body = new Cola.AST_Call({
args : [new Cola.AST_SymbolRef({ name : 'exports' }), newNode.body],
expression : new Cola.AST_SymbolRef({ name : '_ColaRuntime$$rootExport' })
});
} else
if (node.args[0][0]) {
newNode = [new Cola.AST_Var({
start : node.start,
end : node.end,
type : "dynamic",
definitions : [new Cola.AST_VarDef({
type : "dynamic",
name : new Cola.AST_SymbolVar({ name: '_ColaRuntime$$tmp' }),
value : new Cola.AST_Call({
args : [new Cola.AST_String({ value: node.args[0][0] })],
expression : new Cola.AST_SymbolRef({ name : 'require' })
})
})]
})];
node.args.forEach(function(args) {
newNode.push(new Cola.AST_SimpleStatement({ body : new Cola.AST_Assign({
operator : '=',
left : new Cola.AST_Dot({
expression : new Cola.AST_SymbolRef({ name : "exports" }),
property : args[2]
}),
right : new Cola.AST_Dot({
expression : new Cola.AST_SymbolRef({ name : "_ColaRuntime$$tmp" }),
property : args[1]
})
})}));
});
} else {
newNode = [];
node.args.forEach(function(args) {
newNode.push(new Cola.AST_SimpleStatement({ body : new Cola.AST_Assign({
operator : '=',
left : new Cola.AST_Dot({
expression : new Cola.AST_SymbolRef({ name : "exports" }),
property : args[2]
}),
right : new Cola.AST_SymbolRef({ name : args[1] })
})}));
});
}
node = newNode;
} else
if (node instanceof Cola.AST_Command && node.name == "use") { if (node instanceof Cola.AST_Command && node.name == "use") {
if (node.args[0] == "closure") { if (node.args[0] == "closure") {
props = new Cola.AST_Function({ props = new Cola.AST_Function({
@ -2931,6 +3131,9 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){
node = new Cola.AST_Directive({ value : "use " + node.args[0] }); node = new Cola.AST_Directive({ value : "use " + node.args[0] });
} }
if (node instanceof Cola.AST_Defun && node.mods && node.mods.indexOf("export") != -1)
exports.push(node.name.name);
if(node instanceof Array){ if(node instanceof Array){
_this = this; _this = this;
@ -2943,10 +3146,66 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){
}); });
_this = this.transform(tt); _this = this.transform(tt);
_this.body = required.concat(_this.body); _this.body = required.concat(_this.body);
if(options.std){ exports.forEach(function(name) {
_this.body.push(new Cola.AST_SimpleStatement({ body : new Cola.AST_Assign({
operator : '=',
left : new Cola.AST_Dot({
expression : new Cola.AST_SymbolRef({ name : "exports" }),
property : name
}),
right : new Cola.AST_SymbolRef({ name : name })
})}));
});
if (options.root && !options.is_node) {
var commonWrapper = _ColaRuntime$$ast.body[17].clone(), moduleId = 1;
Cola.PushModuleToCommonWrapper(_this, commonWrapper);
(function handleModules(modules){
if (!modules.length) return;
var requiredModules = [];
modules.forEach(function(moduleName) {
var file = [options.modules[moduleName]];
if (!file[0]) file = Cola.tryGetRequiredSource(moduleName);
if (!file) return;
options.parser.is_js = /\.js$/.test(file[0]);
options.parser.filename = Cola.notRoot(file[0]) ? options.path + "/" + file[0] : file[0];
if (!file[1]) file[1] = Cola.getSource(options.parser.filename);
var tl = Cola.parse(file[1], options.parser);
if (!options.parser.is_js) tl = tl.toJavaScript({
main_binding : options.main_binding,
main_event : options.main_event,
is_node : options.is_node,
parser : options.parser,
path : Cola.dirname(options.parser.filename),
std_hash : options.std_hash,
root : false
});
Cola.PushModuleToCommonWrapper(tl, commonWrapper, moduleName, moduleId++);
tl.requiredModules.forEach(function(moduleName){
if (!Cola.push_uniq(_this.requiredModules, moduleName)) return;
requiredModules.push(moduleName);
});
});
handleModules(requiredModules);
})(_this.requiredModules.slice());
_this.body = [commonWrapper];
}
if (options.root) {
for(var i in _ColaRuntime$$hash) if(_ColaRuntime$$hash.hasOwnProperty(i)) for(var i in _ColaRuntime$$hash) if(_ColaRuntime$$hash.hasOwnProperty(i))
_this.body.unshift(_ColaRuntime$$ast.body[i]); _this.body.unshift(_ColaRuntime$$ast.body[i]);
} }

View File

@ -43,17 +43,74 @@
!this.Cola && (this.Cola = {}); !this.Cola && (this.Cola = {});
if (typeof window != "undefined") {
Cola.getSource = function (url) { Cola.getSource = function (url) {
var xhr = new XMLHttpRequest; var xhr = new XMLHttpRequest;
xhr.open('GET', url, false); xhr.open('GET', url, false);
xhr.send(); xhr.send();
return xhr.responseText; return xhr.status == 200
? xhr.responseText
: "";
}; };
Cola.dirname = function (dir) { Cola.dirname = function (dir) {
return dir.replace(/\/[^\/]*$/, ""); return dir.replace(/\/[^\/]*$/, "");
}; };
Cola.getPackages = function() {
var packages = document.querySelector('script[type="text/packages-json"]');
if (packages) {
return JSON.parse(packages.innerHTML);
}
packages = document.querySelector('script[type="text/packages-json"][src]');
if (packages) {
return JSON.parse(Cola.getSource(packages.src));
}
if (packages = Cola.getSource("/packages.json")) {
return JSON.parse(packages);
}
return {};
};
} else {
var path = require("path");
var fs = require("fs");
Cola.getSource = function(file) {
try {
return fs.readFileSync(Cola.notRoot(file)
? path.join(process.cwd(), file)
: file, "utf8");
} catch(e) {
return "";
}
};
Cola.getPackages = function(path) {
if (!path) path = "packages.json";
return Cola.getSource(path);
};
Cola.dirname = path.dirname;
}
Cola.tryGetRequiredSource = function(src) {
var source;
if (source = Cola.getSource(src)) return [src, source];
if (source = Cola.getSource(src + ".cola")) return [src, source];
if (source = Cola.getSource(src + ".js")) return [src, source];
return false;
};
Cola.notRoot = function (path) { Cola.notRoot = function (path) {
return path[0] != "/" && !/^http/.test(path); return path[0] != "/" && !/^http/.test(path);
}; };
@ -86,7 +143,6 @@ Cola.bootstrap = function () {
if (Cola.bootstraped) return; if (Cola.bootstraped) return;
Cola.bootstraped = true; Cola.bootstraped = true;
//var source = "";
Array.prototype.forEach.call(document.querySelectorAll('script[type="text/colascript"][src]'), Array.prototype.forEach.call(document.querySelectorAll('script[type="text/colascript"][src]'),
function(script){ function(script){
if (/\.js$/.test(script.src)) eval.call(window, Cola.getSource(script.src)); if (/\.js$/.test(script.src)) eval.call(window, Cola.getSource(script.src));
@ -231,8 +287,8 @@ Cola.MAP = (function(){
})(); })();
Cola.push_uniq = function (array, el) { Cola.push_uniq = function (array, el) {
if (array.indexOf(el) < 0) if (array.indexOf(el) < 0) return array.push(el), true;
array.push(el); return false;
}; };
Cola.string_template = function (text, props) { Cola.string_template = function (text, props) {

View File

@ -40,12 +40,6 @@ Cola.AST_Node.warn_function = function(txt) {
sys.error("WARN: " + txt); sys.error("WARN: " + txt);
}; };
Cola.getSource = function(file) {
return fs.readFileSync(Cola.notRoot(file) ? path.join(process.cwd(), file) : file, "utf8");
};
Cola.dirname = path.dirname;
// XXX: perhaps we shouldn't export everything but heck, I'm lazy. // XXX: perhaps we shouldn't export everything but heck, I'm lazy.
for (var i in Cola) { for (var i in Cola) {
if (Cola.hasOwnProperty(i)) { if (Cola.hasOwnProperty(i)) {
@ -65,6 +59,8 @@ exports.translate = function(files, options) {
output : null, output : null,
compress : {}, compress : {},
is_js : false, is_js : false,
is_node : false,
modules : {},
main_binding : true, main_binding : true,
path : false path : false
}); });
@ -92,6 +88,8 @@ exports.translate = function(files, options) {
if (!options.is_js) toplevel = toplevel.toJavaScript({ if (!options.is_js) toplevel = toplevel.toJavaScript({
main_binding: options.main_binding, main_binding: options.main_binding,
is_node: options.is_node,
modules: options.modules,
path: options.path || path.dirname(file), path: options.path || path.dirname(file),
parser: { parser: {
is_js : options.is_js is_js : options.is_js