@require and @include done.

This commit is contained in:
Onoshko Dan 2014-05-22 01:01:32 +07:00
parent 744ecd3a8e
commit fb8ccc644f
9 changed files with 174 additions and 28 deletions

View File

@ -87,7 +87,7 @@ ColaScript is a language that compiles in JavaScript. This language is similar t
### Compiler
- `@require`
@require "./library/jquery.js", "./library/underscore.js"
@require "./library/jquery.js" "./library/underscore.js"
- `@use`

View File

@ -292,7 +292,14 @@ async.eachLimit(files, 1, function (file, cb) {
is_js : ARGS.j
});
if (!ARGS.j) TOPLEVEL = TOPLEVEL.toJavaScript({ main_bindiing: !ARGS.n });
if (!ARGS.j) TOPLEVEL = TOPLEVEL.toJavaScript({
main_binding: !ARGS.n,
parser: {
filename : file,
expression : ARGS.expr,
is_js : ARGS.j
}
});
} catch(ex) {
if (ex instanceof Cola.JS_Parse_Error) {
sys.error("Parse error at " + file + ":" + ex.line + "," + ex.col);
@ -416,7 +423,7 @@ function getOptions(x, constants) {
var ast;
try {
ast = Cola.parse(x, { expression: true, is_js: ARGS.j });
if (!ARGS.j) ast = ast.toJavaScript({ main_bindiing: !ARGS.n });
if (!ARGS.j) ast = ast.toJavaScript({ main_binding: !ARGS.n, parser: { expression: true, is_js: ARGS.j } });
} catch(ex) {
if (ex instanceof Cola.JS_Parse_Error) {
sys.error("Error parsing arguments in: " + x);

View File

@ -1,7 +1,9 @@
// `main` functions may binding to a onload event
// Functions can defined without `function` keyword, with and without `type`
main(){
@require './sugar.min.js'
main(){
@require './sugar.min.js'
// Unary operators
// Two variants of `isset` operator. Which is better?
bool _seted = true, _empty;
@ -103,12 +105,7 @@ main(){
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
firstName, secondName, age, country, skills, petName
};
}

View File

@ -462,7 +462,7 @@ Cola.AST_Continue = Cola.DEFNODE("Continue", null, {
/* -----[ IF ]----- */
Cola.AST_If = Cola.DEFNODE("If", "condition alternative", {
Cola.AST_If = Cola.DEFNODE("If", "condition alternative inline", {
$documentation: "A `if` statement",
$propdoc: {
condition: "[AST_Node] the `if` condition",

View File

@ -1356,16 +1356,18 @@ Cola.Parser.prototype.function_ = function(ctor, type) {
});
};
Cola.Parser.prototype.if_ = function () {
var cond = this.parenthesised(), body = this.statement(), belse = null;
Cola.Parser.prototype.if_ = function (inline) {
var cond = this.parenthesised(), body = (inline && !this.is_js ? this.expression(true) : this.statement()), belse = null;
if (this.is("keyword", "else")) {
this.next();
belse = this.statement();
if (inline && !this.is_js) belse = this.is("keyword", "if") ? (this.next(), this.if_(true)) : this.expression(true);
else belse = this.statement();
}
return new Cola.AST_If({
condition : cond,
body : body,
alternative : belse
alternative : belse,
inline : inline
});
};
@ -1670,6 +1672,25 @@ Cola.Parser.prototype.expr_atom = function(allow_calls) {
func.end = this.prev();
return this.subscripts(func, allow_calls);
}
if (this.is("keyword", "if") && !this.is_js) {
this.next();
var f = this.if_(true), s = f;
/*while (true) {
if (s.body instanceof Cola.AST_BlockStatement && s.body.body.length != 1 ||
!(s.body instanceof Cola.AST_BlockStatement) && !(s.body instanceof Cola.AST_SimpleStatement)) this.unexpected(s.body.start);
if (s.alternative instanceof Cola.AST_If) s = f;
else if (s.alternative == null) break;
else {
if (s.alternative instanceof Cola.AST_BlockStatement && s.alternative.body.length != 1 ||
!(s.alternative instanceof Cola.AST_BlockStatement) && !(s.alternative instanceof Cola.AST_SimpleStatement)) this.unexpected(s.alternative.start);
break;
}
}*/
return f;
}
if (this.is("keyword", "switch") && !this.is_js) {
this.next();
var swtch = {
@ -1680,8 +1701,7 @@ Cola.Parser.prototype.expr_atom = function(allow_calls) {
}, _this = this;
swtch.body.forEach(function(branch){
if (branch.body.length > 1) _this.unexpected(branch.body[1].start);
else if (branch.body[0] && branch.body[0] instanceof Cola.AST_Var) _this.unexpected(branch.body[0].start);
if (branch.body.length != 1 || !(branch.body[0] instanceof Cola.AST_SimpleStatement)) _this.unexpected(branch.start);
});
return new Cola.AST_Switch(swtch);
@ -1863,9 +1883,9 @@ Cola.Parser.prototype.object_ = Cola.Parser.embed_tokens(function(is_template, i
}
}
if (!this.is_js && !this.is("punc",":")) {
if (is_object === true) this.unexpected();
is_object = false;
val = new Cola.AST_Noop();
//if (is_object === true) this.unexpected();
//is_object = false;
val = new Cola.AST_SymbolRef({ name : name });
} else {
this.expect(":");

View File

@ -83,9 +83,8 @@ Cola.TreeTransformer.prototype.__proto__ = new Cola.TreeWalker;
var r = node.transform(tw, true);
r = r instanceof Array
? Cola.MAP.splice(r)
: r;
if (!r) r = Cola.MAP.continue();
else if (r instanceof Array) r = Cola.MAP.splice(r);
return r;
});

View File

@ -43,10 +43,18 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){
options = Cola.defaults(options, {
main_binding : true,
main_event : 'DOMContentLoaded'
main_event : 'DOMContentLoaded',
parser : {},
std : true
});
var $_cola_ast = Cola.parse(Cola.$_cola, { is_js : true }), $_cola_hash = {}, _this,
var $_cola_ast = Cola.parse(Cola.$_cola, { is_js : true }),
$_cola_hash = {},
_this,
required = [], required_hash = {},
tt = new Cola.TreeTransformer(function(node, descend, in_list){
var newNode, props = {}, parent = this.parent();
node = node.clone();
@ -1517,6 +1525,50 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){
});
} else
/*
var o = if(a) 'start'; else 'finish';
to
var o = (function(){
if(a) return 'start'; else return 'finish';
}).apply(this, arguments);
*/
if(node instanceof Cola.AST_If && node.inline && !(parent instanceof Cola.AST_If && parent.inline)){
var s = node;
while (true) {
s.inline = false;
s.body = new Cola.AST_Return({
value : s.body
});
if (s.alternative instanceof Cola.AST_If) s = s.alternative;
else if (s.alternative == null) break;
else {
s.alternative = new Cola.AST_Return({
value : s.alternative
});
break;
}
}
props = {
expression : new Cola.AST_Function({
type : "dynamic",
body : [node],
argnames : []
}),
property : "apply"
}
node = new Cola.AST_Call({
args : [new Cola.AST_SymbolRef({ name : "this" }), new Cola.AST_SymbolRef({ name : "arguments" })],
expression : new Cola.AST_Dot(props)
});
} else
/*
var o = switch {
case b < 10: f(b);
@ -1535,7 +1587,7 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){
node.body.forEach(function(branch){
if(!branch.body.length) return;
branch.body[0] = new Cola.AST_Return({
value : branch.body[0] instanceof Cola.AST_SimpleStatement ? branch.body[0].body : branch.body[0]
value : branch.body[0].body
});
});
@ -1691,6 +1743,55 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){
*/
if(node instanceof Cola.AST_RegExp && (node.value.indexOf('\n') != -1 || /\/[\w]*x[\w]*$/.test(node.value))){
node.value = node.value.replace(/[\r\n\s]/g,'').replace(/(\/[\w]*)x([\w]*$)/, '$1$2');
} else
if(node instanceof Cola.AST_Command && node.name == "include"){
var included = [];
node.args.forEach(function(file){
if (file.type != "string") Cola.Parser.prototype.unexpected.call(Cola.Parser.prototype, file);
else file = file.value;
options.parser.is_js = /\.js$/.test(file);
options.parser.filename = file;
var tl = Cola.parse(Cola.getSource(file), options.parser);
if (options.parser.is_js) tl = tl.toJavaScript({
main_binding : options.main_binding,
main_event : options.main_event,
parser : options.parser,
std : false
});
included = included.concat(tl.body);
});
return included;
} else
if(node instanceof Cola.AST_Command && node.name == "require"){
node.args.forEach(function(file){
if (file.type != "string") Cola.Parser.prototype.unexpected.call(Cola.Parser.prototype, file);
else file = file.value;
if (required_hash[file]) return;
required_hash[file] = true;
options.parser.is_js = /\.js$/.test(file);
options.parser.filename = file;
var tl = Cola.parse(Cola.getSource(file), options.parser);
if (options.parser.is_js) tl = tl.toJavaScript({
main_binding : options.main_binding,
main_event : options.main_event,
parser : options.parser,
std : false
});
required = required.concat(tl.body);
});
return false;
}
if(node instanceof Array){
@ -1705,7 +1806,9 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){
_this = this.transform(tt);
for(var i in $_cola_hash) if($_cola_hash.hasOwnProperty(i))
_this.body = required.concat(_this.body);
if(options.std) for(var i in $_cola_hash) if($_cola_hash.hasOwnProperty(i))
_this.body.unshift($_cola_ast.body[i]);
return _this;

View File

@ -122,6 +122,7 @@ Cola.MAP = (function(){
var val = f(a[i], i);
var is_last = val instanceof Last;
if (is_last) val = val.v;
if (val instanceof Continue) return false;
if (val instanceof AtTop) {
val = val.v;
if (val instanceof Splice) {
@ -156,10 +157,12 @@ Cola.MAP = (function(){
MAP.at_top = function(val) { return new AtTop(val) };
MAP.splice = function(val) { return new Splice(val) };
MAP.last = function(val) { return new Last(val) };
MAP.continue = function() { return new Continue() };
var skip = MAP.skip = {};
function AtTop(val) { this.v = val };
function Splice(val) { this.v = val };
function Last(val) { this.v = val };
function Continue() { };
return MAP;
})();
@ -341,3 +344,10 @@ Cola.clone = function (item) {
Cola.nodeCompare = function(_a, _b){
return _a.__proto__ === _b.__proto__ && _a.start.pos === _b.start.pos && _a.end.pos === _b.end.pos;
};
Cola.getSource = function(url){
var xhr = new XMLHttpRequest;
xhr.open('GET', url, false);
xhr.send();
return xhr.responseText;
};

View File

@ -40,6 +40,10 @@ Cola.AST_Node.warn_function = function(txt) {
sys.error("WARN: " + txt);
};
Cola.getSource = function(file) {
return fs.readFileSync(path.join(process.cwd(), file), "utf8");
};
// XXX: perhaps we shouldn't export everything but heck, I'm lazy.
for (var i in Cola) {
if (Cola.hasOwnProperty(i)) {
@ -83,7 +87,13 @@ exports.minify = function(files, options) {
is_js : options.is_js
});
if (!options.is_js) toplevel = toplevel.toJavaScript({ main_binding : options.main_binding });
if (!options.is_js) toplevel = toplevel.toJavaScript({
main_binding: options.main_binding,
parser: {
filename: options.fromString ? "?" : file,
is_js : options.is_js
}
});
});
}