New: @ref and @deref in Objective-J 2.0.

This commit is contained in:
Alexander Ljungberg committed 2013-03-10 12:17:43 +00:00
1 parent 5fac631f6f
commit 34faf362d1
3 files changed
+84 -3

No files matched your search

+52 -1
View File
@@ -348,7 +348,7 @@ Program: function(node, st, c) {
for (var i = 0; i < node.body.length; ++i) {
c(node.body[i], st, "Statement");
}
CONCAT(st.compiler.jsBuffer,st.compiler.source.substring(st.compiler.lastPos, node.end));
CONCAT(st.compiler.jsBuffer, st.compiler.source.substring(st.compiler.lastPos, node.end));
// Check maybe warnings
var maybeWarnings = st.maybeWarnings();
if (maybeWarnings) for (var i = 0; i < maybeWarnings.length; i++) {
@@ -405,6 +405,37 @@ VariableDeclaration: function(node, scope, c) {
}
},
AssignmentExpression: function(node, st, c) {
if (node.left.type === "Dereference") {
// @deref(x) = z -> x(z) etc
CONCAT(st.compiler.jsBuffer, st.compiler.source.substring(st.compiler.lastPos, node.start));
// Output the dereference function, "(...)(z)"
CONCAT(st.compiler.jsBuffer, "(");
// What's being dereferenced could itself be an expression, such as when dereferencing a deref.
st.compiler.lastPos = node.left.expr.start;
c(node.left.expr, st, "Expression");
CONCAT(st.compiler.jsBuffer, st.compiler.source.substring(st.compiler.lastPos, node.left.expr.end));
CONCAT(st.compiler.jsBuffer, ")(");
// Now "(x)(...)". We have to manually expand +=, -=, *= etc.
if (node.operator !== "=") {
// Output the whole .left, not just .left.expr.
st.compiler.lastPos = node.left.start;
c(node.left, st, "Expression");
CONCAT(st.compiler.jsBuffer, st.compiler.source.substring(st.compiler.lastPos, node.left.end));
CONCAT(st.compiler.jsBuffer, " " + node.operator.substring(0, 1) + " ");
}
st.compiler.lastPos = node.right.start;
c(node.right, st, "Expression");
CONCAT(st.compiler.jsBuffer, st.compiler.source.substring(st.compiler.lastPos, node.right.end));
CONCAT(st.compiler.jsBuffer, ")");
st.compiler.lastPos = node.end;
return;
}
var saveAssignment = st.assignment;
st.assignment = true;
c(node.left, st, "Expression");
@@ -833,6 +864,26 @@ SelectorLiteralExpression: function(node, st, c) {
CONCAT(st.compiler.jsBuffer, "\")");
st.compiler.lastPos = node.end;
},
Reference: function(node, st, c) {
CONCAT(st.compiler.jsBuffer, st.compiler.source.substring(st.compiler.lastPos, node.start));
CONCAT(st.compiler.jsBuffer, "function(__input) { if (arguments.length) return ");
CONCAT(st.compiler.jsBuffer, node.element.name);
CONCAT(st.compiler.jsBuffer, " = __input; return ");
CONCAT(st.compiler.jsBuffer, node.element.name);
CONCAT(st.compiler.jsBuffer, "; }");
st.compiler.lastPos = node.end;
},
Dereference: function(node, st, c) {
// @deref(y) -> y()
// @deref(@deref(y)) -> y()()
CONCAT(st.compiler.jsBuffer, st.compiler.source.substring(st.compiler.lastPos, node.start));
st.compiler.lastPos = node.expr.start;
c(node.expr, st, "Expression");
CONCAT(st.compiler.jsBuffer, st.compiler.source.substring(st.compiler.lastPos, node.expr.end));
CONCAT(st.compiler.jsBuffer, "()");
st.compiler.lastPos = node.end;
},
Literal: function(node, st, c) {
if (node.raw && node.raw.charAt(0) === "@")
{
+24 -2
View File
@@ -274,6 +274,7 @@ if (!exports.acorn) {
var _end = {keyword: "end"}, _import = {keyword: "import", afterImport: true};
var _action = {keyword: "action"}, _selector = {keyword: "selector"}, _class = {keyword: "class"}, _global = {keyword: "global"};
var _dictionaryLiteral = {keyword: "{"}, _arrayLiteral = {keyword: "["};
var _ref = {keyword: "ref"}, _deref = {keyword: "deref"};
// Objective-J keywords
@@ -302,7 +303,8 @@ if (!exports.acorn) {
// Map Objective-J "@" keyword names to token types.
var objJAtKeywordTypes = {"implementation": _implementation, "outlet": _outlet, "accessors": _accessors, "end": _end,
"import": _import, "action": _action, "selector": _selector, "class": _class, "global": _global};
"import": _import, "action": _action, "selector": _selector, "class": _class, "global": _global,
"ref": _ref, "deref": _deref};
// Punctuation token types. Again, the `type` property is purely for debugging.
@@ -1174,7 +1176,7 @@ if (!exports.acorn) {
// to.
function checkLVal(expr) {
if (expr.type !== "Identifier" && expr.type !== "MemberExpression")
if (expr.type !== "Identifier" && expr.type !== "MemberExpression" && expr.type !== "Dereference")
raise(expr.start, "Assigning to rvalue");
if (strict && expr.type === "Identifier" && isStrictBadIdWord(expr.name))
raise(expr.start, "Assigning to " + expr.name + " in strict mode");
@@ -1924,6 +1926,26 @@ if (!exports.acorn) {
expect(_parenR, "Expected closing ')' after selector");
return finishNode(node, "SelectorLiteralExpression");
case _ref:
var node = startNode();
next();
expect(_parenL, "Expected '(' after '@ref'");
node.element = parseIdent(node, _parenR);
expect(_parenR, "Expected closing ')' after ref");
return finishNode(node, "Reference");
case _deref:
var node = startNode();
next();
expect(_parenL, "Expected '(' after '@deref'");
node.expr = parseExpression(true, true);
expect(_parenR, "Expected closing ')' after deref");
if (node.expr.type !== "Identifier" && node.expr.type !== "MemberExpression" && node.expr.type !== "Reference" && node.expr.type !== "Dereference")
raise(node, "Dereference of " + node.expr.type);
return finishNode(node, "Dereference");
default:
unexpected();
}
+8
View File
@@ -228,6 +228,14 @@ if (!exports.acorn) {
exports.SelectorLiteralExpression = ignore;
exports.Reference = function(node, st, c) {
c(node.element, st, "Identifier");
}
exports.Dereference = function(node, st, c) {
c(node.expr, st, "Expression");
}
// A custom walker that keeps track of the scope chain and the
// variables defined in it.
function makeScope(prev) {